def _setup_repr_final(self): AbstractInstanceRepr._setup_repr_final(self) if self.gcflavor == 'gc': if (self.classdef is not None and self.classdef.classdesc.lookup('__del__') is not None): s_func = self.classdef.classdesc.s_read_attribute('__del__') source_desc = self.classdef.classdesc.lookup('__del__') source_classdef = source_desc.getclassdef(None) source_repr = getinstancerepr(self.rtyper, source_classdef) assert len(s_func.descriptions) == 1 funcdesc, = s_func.descriptions graph = funcdesc.getuniquegraph() self.check_graph_of_del_does_not_call_too_much(graph) FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void) destrptr = functionptr(FUNCTYPE, graph.name, graph=graph, _callable=graph.func) else: destrptr = None OBJECT = OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] self.rtyper.attachRuntimeTypeInfoFunc(self.object_type, ll_runtime_type_info, OBJECT, destrptr) vtable = self.rclass.getvtable() self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO)
def __init__(self, rtyper, classdef, gcflavor='ignored'): AbstractInstanceRepr.__init__(self, rtyper, classdef) self.baserepr = None if self.classdef is None: self.lowleveltype = OBJECT else: b = self.classdef.basedef if b is not None: self.baserepr = getinstancerepr(rtyper, b) b = self.baserepr.lowleveltype else: b = OBJECT if hasattr(classdef.classdesc.pyobj, '_rpython_hints'): hints = classdef.classdesc.pyobj._rpython_hints else: hints = {} hints = self._check_for_immutable_hints(hints) self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints=hints) self.iprebuiltinstances = identity_dict() self.object_type = self.lowleveltype self.gcflavor = gcflavor
def __init__(self, rtyper, classdef, gcflavor='gc'): AbstractInstanceRepr.__init__(self, rtyper, classdef) if classdef is None: self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]] else: ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]] self.object_type = ForwardRef() self.iprebuiltinstances = identity_dict() self.lowleveltype = Ptr(self.object_type) self.gcflavor = gcflavor
def __init__(self, rtyper, classdef, gcflavor='gc'): AbstractInstanceRepr.__init__(self, rtyper, classdef) if classdef is None: self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]] else: ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]] self.object_type = ForwardRef() self.prebuiltinstances = {} # { id(x): (x, _ptr) } self.lowleveltype = Ptr(self.object_type) self.gcflavor = gcflavor
def __init__(self, rtyper, classdef, gcflavor="gc"): AbstractInstanceRepr.__init__(self, rtyper, classdef) if classdef is None: self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]] else: ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]] self.object_type = ForwardRef() self.iprebuiltinstances = identity_dict() self.lowleveltype = Ptr(self.object_type) self.gcflavor = gcflavor
def _setup_repr_final(self): AbstractInstanceRepr._setup_repr_final(self) if self.gcflavor == "gc": if self.classdef is not None and self.classdef.classdesc.lookup("__del__") is not None: s_func = self.classdef.classdesc.s_read_attribute("__del__") source_desc = self.classdef.classdesc.lookup("__del__") source_classdef = source_desc.getclassdef(None) source_repr = getinstancerepr(self.rtyper, source_classdef) assert len(s_func.descriptions) == 1 funcdesc = s_func.descriptions.keys()[0] graph = funcdesc.getuniquegraph() FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void) destrptr = functionptr(FUNCTYPE, graph.name, graph=graph, _callable=graph.func) else: destrptr = None OBJECT = OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] self.rtyper.attachRuntimeTypeInfoFunc(self.object_type, ll_runtime_type_info, OBJECT, destrptr) vtable = self.rclass.getvtable() self.rtyper.type_for_typeptr[vtable._obj] = self.lowleveltype.TO self.rtyper.lltype2vtable[self.lowleveltype.TO] = vtable
def __init__(self, rtyper, classdef, gcflavor='ignored'): AbstractInstanceRepr.__init__(self, rtyper, classdef) self.baserepr = None if self.classdef is None: self.lowleveltype = OBJECT else: b = self.classdef.basedef if b is not None: self.baserepr = getinstancerepr(rtyper, b) b = self.baserepr.lowleveltype else: b = OBJECT if hasattr(classdef.classdesc.pyobj, '_rpython_hints'): hints = classdef.classdesc.pyobj._rpython_hints else: hints = {} self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints = hints) self.prebuiltinstances = {} # { id(x): (x, _ptr) } self.object_type = self.lowleveltype self.gcflavor = gcflavor
def __init__(self, rtyper, classdef, gcflavor='ignored'): AbstractInstanceRepr.__init__(self, rtyper, classdef) self.baserepr = None if self.classdef is None: self.lowleveltype = OBJECT else: b = self.classdef.basedef if b is not None: self.baserepr = getinstancerepr(rtyper, b) b = self.baserepr.lowleveltype else: b = OBJECT if hasattr(classdef.classdesc.pyobj, '_rpython_hints'): hints = classdef.classdesc.pyobj._rpython_hints else: hints = {} hints = self._check_for_immutable_hints(hints) self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints = hints) self.iprebuiltinstances = identity_dict() self.object_type = self.lowleveltype self.gcflavor = gcflavor
def __init__(self, rtyper, classdef, gcflavor='ignored'): AbstractInstanceRepr.__init__(self, rtyper, classdef) self.baserepr = None if self.classdef is None: self.lowleveltype = OBJECT else: b = self.classdef.basedef if b is not None: self.baserepr = getinstancerepr(rtyper, b) b = self.baserepr.lowleveltype else: b = OBJECT if hasattr(classdef.classdesc.pyobj, '_rpython_hints'): hints = classdef.classdesc.pyobj._rpython_hints else: hints = {} self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints=hints) self.prebuiltinstances = {} # { id(x): (x, _ptr) } self.object_type = self.lowleveltype self.gcflavor = gcflavor
def _setup_repr_final(self): if self.classdef is None: return AbstractInstanceRepr._setup_repr_final(self) # we attach methods here and not in _setup(), because we want # to be sure that all the reprs of the input arguments of all # our methods have been computed at this point methods = {} selfattrs = self.classdef.attrs for mangled, (name, s_value) in self.allmethods.iteritems(): methdescs = s_value.descriptions origin = dict([(methdesc.originclassdef, methdesc) for methdesc in methdescs]) if self.classdef in origin: methdesc = origin[self.classdef] else: if name in selfattrs: for superdef in self.classdef.getmro(): if superdef in origin: # put in methods methdesc = origin[superdef] break else: # abstract method methdesc = None else: continue # get method implementation from pypy.rpython.ootypesystem.rpbc import MethodImplementations methimpls = MethodImplementations.get(self.rtyper, s_value) m_impls = methimpls.get_impl(mangled, methdesc, is_finalizer=name == "__del__") methods.update(m_impls) ootype.addMethods(self.lowleveltype, methods) # step 3: provide accessor methods for class attributes that # are really overridden in subclasses. Must be done here # instead of _setup_repr to avoid recursion problems if class # attributes are Instances of self.lowleveltype. for mangled, (s_value, value) in self.classattributes.items(): r = self.rtyper.getrepr(s_value) if value is None: self.attach_abstract_class_attr_accessor(mangled, r.lowleveltype) else: oovalue = r.convert_desc_or_const(value) self.attach_class_attr_accessor(mangled, oovalue) # step 4: do the same with instance fields whose default # values are overridden in subclasses. Not sure it's the best # way to do it. overridden_defaults = {} if self.classdef is not None: for name, constant in self.classdef.classdesc.classdict.iteritems(): # look for the attrdef in the superclasses classdef = self.classdef.basedef attrdef = None while classdef is not None: if name in classdef.attrs: attrdef = classdef.attrs[name] break classdef = classdef.basedef if attrdef is not None and not attrdef.readonly: # it means that the default value for this field # is overridden in this subclass. Record we know # about it repr = self.rtyper.getrepr(attrdef.s_value) oot = repr.lowleveltype mangled = mangle(name, self.rtyper.getconfig()) value = self.classdef.classdesc.read_attribute(name) default = repr.convert_desc_or_const(value) overridden_defaults[mangled] = oot, default ootype.overrideDefaultForFields(self.lowleveltype, overridden_defaults)
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # 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. AbstractInstanceRepr._setup_repr(self) self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields['__class__'] = 'typeptr', get_type_repr(self.rtyper) else: # instance attributes attrs = self.classdef.attrs.items() attrs.sort() myllfields = [] for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = 'inst_' + name fields[name] = mangled_name, r myllfields.append((mangled_name, r.lowleveltype)) # Sort the instance attributes by decreasing "likely size", # as reported by rffi.sizeof(), to minimize padding holes in C. # Fields of the same size are sorted by name (by attrs.sort() # above) just to minimize randomness. def keysize((_, T)): if T is lltype.Void: return None from pypy.rpython.lltypesystem.rffi import sizeof try: return -sizeof(T) except StandardError: return None myllfields.sort(key=keysize) if llfields is None: llfields = myllfields else: llfields = llfields + myllfields self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} hints = self._check_for_immutable_hints(hints) kwds = {} if self.gcflavor == 'gc': kwds['rtti'] = True for name, attrdef in attrs: if not attrdef.readonly and self.is_quasi_immutable(name): llfields.append(('mutate_' + name, OBJECTPTR)) object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields, **kwds) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields
def _setup_repr_final(self): if self.classdef is None: return AbstractInstanceRepr._setup_repr_final(self) # we attach methods here and not in _setup(), because we want # to be sure that all the reprs of the input arguments of all # our methods have been computed at this point methods = {} selfattrs = self.classdef.attrs for mangled, (name, s_value) in self.allmethods.iteritems(): methdescs = s_value.descriptions origin = dict([(methdesc.originclassdef, methdesc) for methdesc in methdescs]) if self.classdef in origin: methdesc = origin[self.classdef] else: if name in selfattrs: for superdef in self.classdef.getmro(): if superdef in origin: # put in methods methdesc = origin[superdef] break else: # abstract method methdesc = None else: continue # get method implementation from pypy.rpython.ootypesystem.rpbc import MethodImplementations methimpls = MethodImplementations.get(self.rtyper, s_value) m_impls = methimpls.get_impl(mangled, methdesc, is_finalizer=name == "__del__") methods.update(m_impls) ootype.addMethods(self.lowleveltype, methods) # step 3: provide accessor methods for class attributes that # are really overridden in subclasses. Must be done here # instead of _setup_repr to avoid recursion problems if class # attributes are Instances of self.lowleveltype. for mangled, (s_value, value) in self.classattributes.items(): r = self.rtyper.getrepr(s_value) if value is None: self.attach_abstract_class_attr_accessor( mangled, r.lowleveltype) else: oovalue = r.convert_desc_or_const(value) self.attach_class_attr_accessor(mangled, oovalue) # step 4: do the same with instance fields whose default # values are overridden in subclasses. Not sure it's the best # way to do it. overridden_defaults = {} if self.classdef is not None: for name, constant in self.classdef.classdesc.classdict.iteritems( ): # look for the attrdef in the superclasses classdef = self.classdef.basedef attrdef = None while classdef is not None: if name in classdef.attrs: attrdef = classdef.attrs[name] break classdef = classdef.basedef if attrdef is not None and not attrdef.readonly: # it means that the default value for this field # is overridden in this subclass. Record we know # about it repr = self.rtyper.getrepr(attrdef.s_value) oot = repr.lowleveltype mangled = mangle(name, self.rtyper.getconfig()) value = self.classdef.classdesc.read_attribute(name) default = repr.convert_desc_or_const(value) overridden_defaults[mangled] = oot, default ootype.overrideDefaultForFields(self.lowleveltype, overridden_defaults)
def _setup_repr(self, llfields=None, hints=None, adtmeths=None): # 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. AbstractInstanceRepr._setup_repr(self) self.rclass = getclassrepr(self.rtyper, self.classdef) fields = {} allinstancefields = {} if self.classdef is None: fields["__class__"] = "typeptr", get_type_repr(self.rtyper) else: # instance attributes attrs = self.classdef.attrs.items() attrs.sort() myllfields = [] for name, attrdef in attrs: if not attrdef.readonly: r = self.rtyper.getrepr(attrdef.s_value) mangled_name = "inst_" + name fields[name] = mangled_name, r myllfields.append((mangled_name, r.lowleveltype)) # Sort the instance attributes by decreasing "likely size", # as reported by rffi.sizeof(), to minimize padding holes in C. # Fields of the same size are sorted by name (by attrs.sort() # above) just to minimize randomness. def keysize((_, T)): if T is lltype.Void: return None from pypy.rpython.lltypesystem.rffi import sizeof try: return -sizeof(T) except StandardError: return None myllfields.sort(key=keysize) if llfields is None: llfields = myllfields else: llfields = llfields + myllfields self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, self.gcflavor) self.rbase.setup() MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] if adtmeths is None: adtmeths = {} if hints is None: hints = {} hints = self._check_for_immutable_hints(hints) kwds = {} if self.gcflavor == "gc": kwds["rtti"] = True for name, attrdef in attrs: if not attrdef.readonly and self.is_quasi_immutable(name): llfields.append(("mutate_" + name, OBJECTPTR)) object_type = MkStruct( self.classdef.name, ("super", self.rbase.object_type), hints=hints, adtmeths=adtmeths, *llfields, **kwds ) self.object_type.become(object_type) allinstancefields.update(self.rbase.allinstancefields) allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields