def define_interior_ptrs(cls): from rpython.rtyper.lltypesystem.lltype import Struct, GcStruct, GcArray from rpython.rtyper.lltypesystem.lltype import Array, Signed, malloc S1 = Struct("S1", ('x', Signed)) T1 = GcStruct("T1", ('s', S1)) def f1(): t = malloc(T1) t.s.x = 1 return t.s.x S2 = Struct("S2", ('x', Signed)) T2 = GcArray(S2) def f2(): t = malloc(T2, 1) t[0].x = 1 return t[0].x S3 = Struct("S3", ('x', Signed)) T3 = GcStruct("T3", ('items', Array(S3))) def f3(): t = malloc(T3, 1) t.items[0].x = 1 return t.items[0].x S4 = Struct("S4", ('x', Signed)) T4 = Struct("T4", ('s', S4)) U4 = GcArray(T4) def f4(): u = malloc(U4, 1) u[0].s.x = 1 return u[0].s.x S5 = Struct("S5", ('x', Signed)) T5 = GcStruct("T5", ('items', Array(S5))) def f5(): t = malloc(T5, 1) return len(t.items) T6 = GcStruct("T6", ('s', Array(Signed))) def f6(): t = malloc(T6, 1) t.s[0] = 1 return t.s[0] def func(): return (f1() * 100000 + f2() * 10000 + f3() * 1000 + f4() * 100 + f5() * 10 + f6()) assert func() == 111111 return func
class MultipleUnrelatedFrozenPBCRepr(AbstractMultipleUnrelatedFrozenPBCRepr): """Representation selected for multiple non-callable pre-built constants with no common access set.""" lowleveltype = llmemory.Address EMPTY = Struct('pbc', hints={'immutable': True}) def convert_pbc(self, pbcptr): return llmemory.fakeaddress(pbcptr) def create_instance(self): return malloc(self.EMPTY, immortal=True) def null_instance(self): return llmemory.Address._defl()
def _setup_repr(self): # NOTE: don't store mutable objects like the dicts below on 'self' # before they are fully built, to avoid strange bugs in case # of recursion where other code would uses these # partially-initialized dicts. clsfields = {} pbcfields = {} allmethods = {} if self.classdef is not None: # class attributes llfields = [] attrs = self.classdef.attrs.items() attrs.sort() for name, attrdef in attrs: if attrdef.readonly: s_value = attrdef.s_value s_unboundmethod = self.prepare_method(s_value) if s_unboundmethod is not None: allmethods[name] = True s_value = s_unboundmethod r = self.rtyper.getrepr(s_value) mangled_name = 'cls_' + name clsfields[name] = mangled_name, r llfields.append((mangled_name, r.lowleveltype)) # attributes showing up in getattrs done on the class as a PBC extra_access_sets = self.rtyper.class_pbc_attributes.get( self.classdef, {}) for access_set, (attr, counter) in extra_access_sets.items(): r = self.rtyper.getrepr(access_set.s_value) mangled_name = mangle('pbc%d' % counter, attr) pbcfields[access_set, attr] = mangled_name, r llfields.append((mangled_name, r.lowleveltype)) # self.rbase = getclassrepr(self.rtyper, self.classdef.basedef) self.rbase.setup() kwds = {'hints': {'immutable': True}} vtable_type = Struct('%s_vtable' % self.classdef.name, ('super', self.rbase.vtable_type), *llfields, **kwds) self.vtable_type.become(vtable_type) allmethods.update(self.rbase.allmethods) self.clsfields = clsfields self.pbcfields = pbcfields self.allmethods = allmethods self.vtable = None
class MultipleUnrelatedFrozenPBCRepr(MultipleFrozenPBCReprBase): """For a SomePBC of frozen PBCs that have no common access set. The only possible operation on such a thing is comparison with 'is'.""" lowleveltype = llmemory.Address EMPTY = Struct('pbc', hints={'immutable': True, 'static_immutable': True}) def __init__(self, rtyper): self.rtyper = rtyper self.converted_pbc_cache = {} def convert_desc(self, frozendesc): try: return self.converted_pbc_cache[frozendesc] except KeyError: r = self.rtyper.getrepr(annmodel.SomePBC([frozendesc])) if r.lowleveltype is Void: # must create a new empty structure, as a placeholder pbc = self.create_instance() else: pbc = r.convert_desc(frozendesc) convpbc = self.convert_pbc(pbc) self.converted_pbc_cache[frozendesc] = convpbc return convpbc def convert_pbc(self, pbcptr): return llmemory.fakeaddress(pbcptr) def create_instance(self): return malloc(self.EMPTY, immortal=True) def null_instance(self): return llmemory.Address._defl() def rtype_getattr(_, hop): if not hop.s_result.is_constant(): raise TyperError( "getattr on a constant PBC returns a non-constant") return hop.inputconst(hop.r_result, hop.s_result.const)
def setup_specfunc(self): fields = [] for row in self.uniquerows: fields.append((row.attrname, row.fntype)) kwds = {'hints': {'immutable': True}} return Ptr(Struct('specfunc', *fields, **kwds))
def _setup_repr(self): llfields = self._setup_repr_fields() kwds = {'hints': {'immutable': True}} self.pbc_type.become(Struct('pbc', *llfields, **kwds))
CLASSTYPE = Ptr(OBJECT_VTABLE) OBJECT = GcStruct('object', ('typeptr', CLASSTYPE), hints={ 'immutable': True, 'shouldntbenull': True, 'typeptr': True }, rtti=True) OBJECTPTR = Ptr(OBJECT) OBJECT_VTABLE.become( Struct( 'object_vtable', #('parenttypeptr', CLASSTYPE), ('subclassrange_min', Signed), ('subclassrange_max', Signed), ('rtti', Ptr(RuntimeTypeInfo)), ('name', Ptr(rstr.STR)), ('instantiate', Ptr(FuncType([], OBJECTPTR))), hints={ 'immutable': True, 'static_immutable': True })) # non-gc case NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE)) NONGCOBJECTPTR = Ptr(NONGCOBJECT) OBJECT_BY_FLAVOR = {'gc': OBJECT, 'raw': NONGCOBJECT} LLFLAVOR = {'gc': 'gc', 'raw': 'raw', 'stack': 'raw'} def cast_vtable_to_typeptr(vtable): while typeOf(vtable).TO != OBJECT_VTABLE: