Example #1
0
 def rtyper_makerepr(self, rtyper):
     kind = getkind(self)
     if kind == "type":
         return rclass.get_type_repr(rtyper)
     elif kind == "const":
         return constpyobj_repr
     else:
         return pyobj_repr
Example #2
0
 def rtyper_makerepr(self, rtyper):
     kind = getkind(self)
     if kind == "type":
         return rclass.get_type_repr(rtyper)
     elif kind == "const":
         return constpyobj_repr
     else:
         return pyobj_repr
Example #3
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.
        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
            if llfields is None:
                llfields = []
            attrs = self.classdef.attrs.items()
            attrs.sort()
            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
                    llfields.append((mangled_name, r.lowleveltype))
            #
            # hash() support
            if self.rtyper.needs_hash_support(self.classdef):
                from pypy.rpython import rint
                fields['_hash_cache_'] = 'hash_cache', rint.signed_repr
                llfields.append(('hash_cache', Signed))

            self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
                                         self.gcflavor)
            self.rbase.setup()
            #
            # PyObject wrapper support
            if self.has_wrapper and '_wrapper_' not in self.rbase.allinstancefields:
                fields['_wrapper_'] = 'wrapper', pyobj_repr
                llfields.append(('wrapper', Ptr(PyObject)))

            MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
            if adtmeths is None:
                adtmeths = {}
            if hints is None:
                hints = {}
            if '_immutable_' in self.classdef.classdesc.classdict:
                hints = hints.copy()
                hints['immutable'] = True
            object_type = MkStruct(self.classdef.name,
                                   ('super', self.rbase.object_type),
                                   hints=hints,
                                   adtmeths=adtmeths,
                                   *llfields)
            self.object_type.become(object_type)
            allinstancefields.update(self.rbase.allinstancefields)
        allinstancefields.update(fields)
        self.fields = fields
        self.allinstancefields = allinstancefields
        if self.gcflavor in RTTIFLAVORS:
            attachRuntimeTypeInfo(self.object_type)
Example #4
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.
        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
            if llfields is None:
                llfields = []
            attrs = self.classdef.attrs.items()
            attrs.sort()
            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
                    llfields.append((mangled_name, r.lowleveltype))
            #
            # hash() support
            if self.rtyper.needs_hash_support(self.classdef):
                from pypy.rpython import rint
                fields['_hash_cache_'] = 'hash_cache', rint.signed_repr
                llfields.append(('hash_cache', Signed))

            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 = {}
            if '_immutable_' in self.classdef.classdesc.classdict:
                hints = hints.copy()
                hints['immutable'] = True
            object_type = MkStruct(self.classdef.name,
                                   ('super', self.rbase.object_type),
                                   hints=hints,
                                   adtmeths=adtmeths,
                                   *llfields)
            self.object_type.become(object_type)
            allinstancefields.update(self.rbase.allinstancefields)
        allinstancefields.update(fields)
        self.fields = fields
        self.allinstancefields = allinstancefields
        if self.gcflavor == 'gc':
            attachRuntimeTypeInfo(self.object_type)
Example #5
0
    def rtype_isinstance(self, hop):
        if not hop.args_s[1].is_constant():
            raise TyperError("isinstance() too complicated")
        [classdesc] = hop.args_s[1].descriptions
        classdef = classdesc.getuniqueclassdef()

        class_repr = get_type_repr(self.rtyper)
        instance_repr = self.common_repr()
        v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
        cls = v_cls.value
        answer = self.unboxedclassdef.issubclass(classdef)
        c_answer_if_unboxed = hop.inputconst(lltype.Bool, answer)
        minid = hop.inputconst(lltype.Signed, cls.subclassrange_min)
        maxid = hop.inputconst(lltype.Signed, cls.subclassrange_max)
        return hop.gendirectcall(ll_unboxed_isinstance_const, v_obj, minid,
                                 maxid, c_answer_if_unboxed)
Example #6
0
    def rtype_isinstance(self, hop):
        if not hop.args_s[1].is_constant():
            raise TyperError("isinstance() too complicated")
        [classdesc] = hop.args_s[1].descriptions
        classdef = classdesc.getuniqueclassdef()

        class_repr = get_type_repr(self.rtyper)
        instance_repr = self.common_repr()
        v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
        cls = v_cls.value
        answer = self.unboxedclassdef.issubclass(classdef)
        c_answer_if_unboxed = hop.inputconst(lltype.Bool, answer)
        minid = hop.inputconst(lltype.Signed, cls.subclassrange_min)
        maxid = hop.inputconst(lltype.Signed, cls.subclassrange_max)
        return hop.gendirectcall(ll_unboxed_isinstance_const, v_obj,
                                 minid, maxid, c_answer_if_unboxed)
Example #7
0
 def rtype_issubtype(self, hop):
     class_repr = get_type_repr(self.rtyper)
     v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
     if isinstance(v_cls2, Constant):
         cls2 = v_cls2.value
         # XXX re-implement the following optimization
         ##            if cls2.subclassrange_max == cls2.subclassrange_min:
         ##                # a class with no subclass
         ##                return hop.genop('ptr_eq', [v_cls1, v_cls2], resulttype=Bool)
         ##            else:
         minid = hop.inputconst(Signed, cls2.subclassrange_min)
         maxid = hop.inputconst(Signed, cls2.subclassrange_max)
         return hop.gendirectcall(ll_issubclass_const, v_cls1, minid, maxid)
     else:
         v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
         return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
Example #8
0
 def rtype_issubtype(self, hop):
     class_repr = get_type_repr(self.rtyper)
     v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
     if isinstance(v_cls2, Constant):
         cls2 = v_cls2.value
         # XXX re-implement the following optimization
         ##            if cls2.subclassrange_max == cls2.subclassrange_min:
         ##                # a class with no subclass
         ##                return hop.genop('ptr_eq', [v_cls1, v_cls2], resulttype=Bool)
         ##            else:
         minid = hop.inputconst(Signed, cls2.subclassrange_min)
         maxid = hop.inputconst(Signed, cls2.subclassrange_max)
         return hop.gendirectcall(ll_issubclass_const, v_cls1, minid, maxid)
     else:
         v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
         return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
Example #9
0
    def rtype_isinstance(self, hop):
        class_repr = get_type_repr(hop.rtyper)
        instance_repr = self.common_repr()

        v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
        if isinstance(v_cls, Constant):
            cls = v_cls.value
            # XXX re-implement the following optimization
            #if cls.subclassrange_max == cls.subclassrange_min:
            #    # a class with no subclass
            #    return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj, v_cls)
            #else:
            minid = hop.inputconst(Signed, cls.subclassrange_min)
            maxid = hop.inputconst(Signed, cls.subclassrange_max)
            return hop.gendirectcall(ll_isinstance_const, v_obj, minid, maxid)
        else:
            return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
Example #10
0
    def rtype_isinstance(self, hop):
        class_repr = get_type_repr(hop.rtyper)
        instance_repr = self.common_repr()

        v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
        if isinstance(v_cls, Constant):
            cls = v_cls.value
            # XXX re-implement the following optimization
            #if cls.subclassrange_max == cls.subclassrange_min:
            #    # a class with no subclass
            #    return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj, v_cls)
            #else:
            minid = hop.inputconst(Signed, cls.subclassrange_min)
            maxid = hop.inputconst(Signed, cls.subclassrange_max)
            return hop.gendirectcall(ll_isinstance_const, v_obj, minid, maxid)
        else:
            return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
Example #11
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.
        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
            if llfields is None:
                llfields = []
            attrs = self.classdef.attrs.items()
            attrs.sort()
            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
                    llfields.append((mangled_name, r.lowleveltype))

            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)
            object_type = MkStruct(self.classdef.name,
                                   ('super', self.rbase.object_type),
                                   hints=hints,
                                   adtmeths=adtmeths,
                                   *llfields)
            self.object_type.become(object_type)
            allinstancefields.update(self.rbase.allinstancefields)
        allinstancefields.update(fields)
        self.fields = fields
        self.allinstancefields = allinstancefields
        if self.gcflavor == 'gc':
            attachRuntimeTypeInfo(self.object_type)
Example #12
0
    def _generate_save_block(self, varsforcall, v_unwind_exception, saver):
        conc_types = tuple([v.concretetype for v in varsforcall])
        if conc_types in self.curr_graph_save_blocks:
            return self.curr_graph_save_blocks[conc_types]
        rtyper = self.translator.rtyper
        edata = rtyper.getexceptiondata()
        etype = edata.lltype_of_exception_type
        evalue = edata.lltype_of_exception_value
        inputargs = [copyvar(v) for v in varsforcall]
        v_unwind_exception = copyvar(v_unwind_exception)

        save_state_block = model.Block(inputargs + [v_unwind_exception])
        saveops = LowLevelOpList()
        
        v_exc = gen_cast(saveops, self.unwind_exception_type, v_unwind_exception)
        
        realvarsforcall = [v_exc]
        for v in inputargs:
            realvarsforcall.append(gen_cast(saveops, storage_type(v.concretetype), v))
        
        saveops.genop('direct_call',
                      [model.Constant(saver, lltype.typeOf(saver))] + realvarsforcall,
                      resulttype=lltype.Void)
        save_state_block.operations = saveops

        type_repr = rclass.get_type_repr(rtyper)
        c_unwindexception = model.Constant(
            type_repr.convert_const(code.UnwindException), etype)
        if not hasattr(self.curr_graph.exceptblock.inputargs[0], 'concretetype'):
            self.curr_graph.exceptblock.inputargs[0].concretetype = etype
        if not hasattr(self.curr_graph.exceptblock.inputargs[1], 'concretetype'):
            self.curr_graph.exceptblock.inputargs[1].concretetype = evalue
        save_state_block.closeblock(model.Link(
            [c_unwindexception, v_unwind_exception], 
            self.curr_graph.exceptblock))
        self.translator.rtyper._convert_link(
            save_state_block, save_state_block.exits[0])
        if SAVE_STATISTICS:
            self.stats.saveops += len(save_state_block.operations)
        self.curr_graph_save_blocks[conc_types] = save_state_block
        return save_state_block
Example #13
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 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
Example #14
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 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
Example #15
0
 def convert_desc(self, desc):
     if desc not in self.s_pbc.descriptions:
         raise TyperError("%r not in %r" % (cls, self))
     if self.lowleveltype is Void:
         return desc.pyobj
     return rclass.get_type_repr(self.rtyper).convert_desc(desc)
Example #16
0
 def _instantiate_runtime_class(self, hop, v_class, r_instance):
     classdef = hop.s_result.classdef            
     resulttype = getinstancerepr(hop.rtyper, classdef).lowleveltype
     # convert v_class from META to ootype.Class if necessary:
     v_class = get_type_repr(hop.rtyper).fromclasstype(v_class, hop.llops)
     return hop.genop('runtimenew', [v_class], resulttype=resulttype)
Example #17
0
 def rtype_issubtype(self, hop):
     class_repr = get_type_repr(self.rtyper)
     vmeta1, vmeta2 = hop.inputargs(class_repr, class_repr)
     return hop.gendirectcall(ll_issubclass, vmeta1, vmeta2)
Example #18
0
 def rtype_issubtype(self, hop):
     class_repr = get_type_repr(self.rtyper)
     vmeta1, vmeta2 = hop.inputargs(class_repr, class_repr)
     return hop.gendirectcall(ll_issubclass, vmeta1, vmeta2)
Example #19
0
 def convert_desc(self, desc):
     if desc not in self.s_pbc.descriptions:
         raise TyperError("%r not in %r" % (cls, self))
     if self.lowleveltype is Void:
         return None
     return rclass.get_type_repr(self.rtyper).convert_desc(desc)
Example #20
0
 def rtype_issubtype(self, hop):
     class_repr = get_type_repr(self.rtyper)
     vcls1, vcls2 = hop.inputargs(class_repr, class_repr)
     return hop.genop('subclassof', [vcls1, vcls2], resulttype=ootype.Bool)
Example #21
0
 def rtype_issubtype(self, hop):
     class_repr = get_type_repr(self.rtyper)
     vcls1, vcls2 = hop.inputargs(class_repr, class_repr)
     return hop.genop('subclassof', [vcls1, vcls2], resulttype=ootype.Bool)