Пример #1
0
 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)
Пример #2
0
    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
Пример #3
0
 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)
Пример #4
0
    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
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
    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 rpython.rtyper.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)
Пример #8
0
    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 rpython.rtyper.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)
Пример #9
0
    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 rpython.rtyper.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
Пример #10
0
    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 rpython.rtyper.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