class MultipleFrozenPBCRepr(AbstractMultipleFrozenPBCRepr): """Representation selected for multiple non-callable pre-built constants.""" def __init__(self, rtyper, access_set): self.rtyper = rtyper self.access_set = access_set self.pbc_type = ForwardReference() self.lowleveltype = Ptr(self.pbc_type) self.pbc_cache = {} def _setup_repr(self): llfields = self._setup_repr_fields() kwds = {'hints': {'immutable': True}} self.pbc_type.become(Struct('pbc', *llfields, **kwds)) def create_instance(self): return malloc(self.pbc_type, immortal=True) def null_instance(self): return nullptr(self.pbc_type) def getfield(self, vpbc, attr, llops): mangled_name, r_value = self.fieldmap[attr] cmangledname = inputconst(Void, mangled_name) return llops.genop('getfield', [vpbc, cmangledname], resulttype=r_value)
class MultipleFrozenPBCRepr(MultipleFrozenPBCReprBase): """For a SomePBC of frozen PBCs with a common attribute access set.""" def __init__(self, rtyper, access_set): self.rtyper = rtyper self.access_set = access_set self.pbc_type = ForwardReference() self.lowleveltype = Ptr(self.pbc_type) self.pbc_cache = {} def _setup_repr(self): llfields = self._setup_repr_fields() kwds = {'hints': {'immutable': True, 'static_immutable': True}} self.pbc_type.become(Struct('pbc', *llfields, **kwds)) def create_instance(self): return malloc(self.pbc_type, immortal=True) def null_instance(self): return nullptr(self.pbc_type) def getfield(self, vpbc, attr, llops): mangled_name, r_value = self.fieldmap[attr] cmangledname = inputconst(Void, mangled_name) return llops.genop('getfield', [vpbc, cmangledname], resulttype=r_value) def _setup_repr_fields(self): fields = [] self.fieldmap = {} if self.access_set is not None: attrlist = self.access_set.attrs.keys() attrlist.sort() for attr in attrlist: s_value = self.access_set.attrs[attr] r_value = self.rtyper.getrepr(s_value) mangled_name = mangle('pbc', attr) fields.append((mangled_name, r_value.lowleveltype)) self.fieldmap[attr] = mangled_name, r_value return fields def convert_desc(self, frozendesc): if (self.access_set is not None and frozendesc not in self.access_set.descs): raise TyperError("not found in PBC access set: %r" % (frozendesc, )) try: return self.pbc_cache[frozendesc] except KeyError: self.setup() result = self.create_instance() self.pbc_cache[frozendesc] = result for attr, (mangled_name, r_value) in self.fieldmap.items(): if r_value.lowleveltype is Void: continue try: thisattrvalue = frozendesc.attrcache[attr] except KeyError: if frozendesc.warn_missing_attribute(attr): warning("Desc %r has no attribute %r" % (frozendesc, attr)) continue llvalue = r_value.convert_const(thisattrvalue) setattr(result, mangled_name, llvalue) return result def rtype_getattr(self, hop): if hop.s_result.is_constant(): return hop.inputconst(hop.r_result, hop.s_result.const) attr = hop.args_s[1].const vpbc, vattr = hop.inputargs(self, Void) v_res = self.getfield(vpbc, attr, hop.llops) mangled_name, r_res = self.fieldmap[attr] return hop.llops.convertvar(v_res, r_res, hop.r_result)
class MultipleFrozenPBCRepr(MultipleFrozenPBCReprBase): """For a SomePBC of frozen PBCs with a common attribute access set.""" def __init__(self, rtyper, access_set): self.rtyper = rtyper self.access_set = access_set self.pbc_type = ForwardReference() self.lowleveltype = Ptr(self.pbc_type) self.pbc_cache = {} def _setup_repr(self): llfields = self._setup_repr_fields() kwds = {'hints': {'immutable': True}} self.pbc_type.become(Struct('pbc', *llfields, **kwds)) def create_instance(self): return malloc(self.pbc_type, immortal=True) def null_instance(self): return nullptr(self.pbc_type) def getfield(self, vpbc, attr, llops): mangled_name, r_value = self.fieldmap[attr] cmangledname = inputconst(Void, mangled_name) return llops.genop('getfield', [vpbc, cmangledname], resulttype=r_value) def _setup_repr_fields(self): fields = [] self.fieldmap = {} if self.access_set is not None: attrlist = self.access_set.attrs.keys() attrlist.sort() for attr in attrlist: s_value = self.access_set.attrs[attr] r_value = self.rtyper.getrepr(s_value) mangled_name = mangle('pbc', attr) fields.append((mangled_name, r_value.lowleveltype)) self.fieldmap[attr] = mangled_name, r_value return fields def convert_desc(self, frozendesc): if (self.access_set is not None and frozendesc not in self.access_set.descs): raise TyperError("not found in PBC access set: %r" % (frozendesc,)) try: return self.pbc_cache[frozendesc] except KeyError: self.setup() result = self.create_instance() self.pbc_cache[frozendesc] = result for attr, (mangled_name, r_value) in self.fieldmap.items(): if r_value.lowleveltype is Void: continue try: thisattrvalue = frozendesc.attrcache[attr] except KeyError: if frozendesc.warn_missing_attribute(attr): warning("Desc %r has no attribute %r" % (frozendesc, attr)) continue llvalue = r_value.convert_const(thisattrvalue) setattr(result, mangled_name, llvalue) return result def rtype_getattr(self, hop): if hop.s_result.is_constant(): return hop.inputconst(hop.r_result, hop.s_result.const) attr = hop.args_s[1].const vpbc, vattr = hop.inputargs(self, Void) v_res = self.getfield(vpbc, attr, hop.llops) mangled_name, r_res = self.fieldmap[attr] return hop.llops.convertvar(v_res, r_res, hop.r_result)