コード例 #1
0
    def __init__(self, rtyper, classdef):
        AbstractClassRepr.__init__(self, rtyper, classdef)
        # This is the Repr for a reference to the class 'classdef' or
        # any subclass.  In the simple case, the lowleveltype is just
        # ootype.Class.  If we need to store class attributes, we use a
        # "meta" class where the attributes are defined, and the class
        # reference is a reference to an instance of this meta class.
        extra_access_sets = self.rtyper.class_pbc_attributes.get(classdef, {})
        has_class_attributes = bool(extra_access_sets)
        if self.classdef is not None:
            self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
            meta_base_type = self.rbase.lowleveltype
            baseclass_has_meta = meta_base_type != ootype.Class
        else:
            baseclass_has_meta = False

        if not has_class_attributes and not baseclass_has_meta:
            self.lowleveltype = ootype.Class  # simple case
        else:
            if self.classdef is None:
                raise TyperError("the root 'object' class should not have"
                                 " class attributes")
            if self.classdef.classdesc.pyobj in standardexceptions:
                raise TyperError("Standard exception class %r should not have"
                                 " class attributes" % (self.classdef.name, ))
            if not baseclass_has_meta:
                meta_base_type = META
            self.lowleveltype = ootype.Instance(self.classdef.name + "_meta",
                                                meta_base_type)
コード例 #2
0
 def _setup_repr(self):
     InstanceRepr._setup_repr(self)
     flds = self.allinstancefields.keys()
     flds.remove('__class__')
     if self.is_parent:
         if flds:
             raise TyperError("%r is a base class of an UnboxedValue,"
                              "so it cannot have fields: %r" %
                              (self.classdef, flds))
     else:
         if len(flds) != 1:
             raise TyperError("%r must have exactly one field: %r" %
                              (self.classdef, flds))
         self.specialfieldname = flds[0]
コード例 #3
0
 def getpbcfield(self, vcls, access_set, attr, llops):
     if (access_set, attr) not in self.pbcfields:
         raise TyperError("internal error: missing PBC field")
     mangled_name, r = self.pbcfields[access_set, attr]
     v_meta = self.fromclasstype(vcls, llops)
     cname = inputconst(ootype.Void, mangled_name)
     return llops.genop('oogetfield', [v_meta, cname], resulttype=r)
コード例 #4
0
ファイル: rclass.py プロジェクト: chyyuu/pygirl
 def rtype_getattr(self, hop):
     v_inst, _ = hop.inputargs(self, ootype.Void)
     s_inst = hop.args_s[0]
     attr = hop.args_s[1].const
     mangled = mangle(attr, self.rtyper.getconfig())
     v_attr = hop.inputconst(ootype.Void, mangled)
     if mangled in self.allfields:
         # regular instance attributes
         self.lowleveltype._check_field(mangled)
         return hop.genop("oogetfield", [v_inst, v_attr],
                          resulttype=hop.r_result.lowleveltype)
     elif mangled in self.allmethods:
         # special case for methods: represented as their 'self' only
         # (see MethodsPBCRepr)
         return hop.r_result.get_method_from_instance(
             self, v_inst, hop.llops)
     elif mangled in self.allclassattributes:
         # class attributes
         if hop.s_result.is_constant():
             return hop.inputconst(hop.r_result, hop.s_result.const)
         else:
             cname = hop.inputconst(ootype.Void, mangled)
             return hop.genop("oosend", [cname, v_inst],
                              resulttype=hop.r_result.lowleveltype)
     elif attr == '__class__':
         if hop.r_result.lowleveltype is ootype.Void:
             # special case for when the result of '.__class__' is constant
             [desc] = hop.s_result.descriptions
             return hop.inputconst(ootype.Void, desc.pyobj)
         else:
             cmeta = inputconst(ootype.Void, "meta")
             return hop.genop('oogetfield', [v_inst, cmeta],
                              resulttype=CLASSTYPE)
     else:
         raise TyperError("no attribute %r on %r" % (attr, self))
コード例 #5
0
def rtype_builtin_hasattr(hop):
    if hop.s_result.is_constant():
        return hop.inputconst(lltype.Bool, hop.s_result.const)
    if hop.args_r[0] == pyobj_repr:
        v_obj, v_name = hop.inputargs(pyobj_repr, pyobj_repr)
        c = hop.inputconst(pyobj_repr, hasattr)
        v = hop.genop('simple_call', [c, v_obj, v_name], resulttype = pyobj_repr)
        return hop.llops.convertvar(v, pyobj_repr, bool_repr)
    raise TyperError("hasattr is only suported on a constant or on PyObject")
コード例 #6
0
 def new_instance(self, llops, classcallhop=None):
     if self.is_parent:
         raise TyperError("don't instantiate %r, it is a parent of an "
                          "UnboxedValue class" % (self.classdef, ))
     if classcallhop is None:
         raise TyperError("must instantiate %r by calling the class" %
                          (self.classdef, ))
     hop = classcallhop
     if not (hop.spaceop.opname == 'simple_call' and hop.nb_args == 2):
         raise TyperError("must instantiate %r with a simple class call" %
                          (self.classdef, ))
     v_value = hop.inputarg(lltype.Signed, arg=1)
     c_one = hop.inputconst(lltype.Signed, 1)
     hop.exception_is_here()
     v2 = hop.genop('int_lshift_ovf', [v_value, c_one],
                    resulttype=lltype.Signed)
     v2p1 = hop.genop('int_add', [v2, c_one], resulttype=lltype.Signed)
     v_instance = hop.genop('cast_int_to_ptr', [v2p1],
                            resulttype=self.lowleveltype)
     return v_instance, False  # don't call __init__
コード例 #7
0
    def get_meta_instance(self, cast_to_root_meta=True):
        if self.lowleveltype == ootype.Class:
            raise TyperError("no meta-instance for class %r" %
                             (self.classdef, ))
        if self.meta_instance is None:
            self.meta_instance = ootype.new(self.lowleveltype)
            self.setup_meta_instance(self.meta_instance, self)

        meta_instance = self.meta_instance
        if cast_to_root_meta:
            meta_instance = ootype.ooupcast(META, meta_instance)
        return meta_instance
コード例 #8
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)
コード例 #9
0
 def rtype_getattr(self, hop):
     if hop.s_result.is_constant():
         return hop.inputconst(hop.r_result, hop.s_result.const)
     v_inst, _ = hop.inputargs(self, ootype.Void)
     s_inst = hop.args_s[0]
     attr = hop.args_s[1].const
     mangled = mangle(attr, self.rtyper.getconfig())
     if mangled in self.allfields:
         # regular instance attributes
         return self.getfield(v_inst,
                              attr,
                              hop.llops,
                              flags=hop.args_s[0].flags)
     elif mangled in self.allmethods:
         # special case for methods: represented as their 'self' only
         # (see MethodsPBCRepr)
         return hop.r_result.get_method_from_instance(
             self, v_inst, hop.llops)
     elif mangled in self.allclassattributes:
         # class attributes
         if hop.s_result.is_constant():
             return hop.inputconst(hop.r_result, hop.s_result.const)
         else:
             cname = hop.inputconst(ootype.Void, mangled)
             return hop.genop("oosend", [cname, v_inst],
                              resulttype=hop.r_result.lowleveltype)
     elif attr == '__class__':
         expected_type = hop.r_result.lowleveltype
         if expected_type is ootype.Void:
             # special case for when the result of '.__class__' is constant
             [desc] = hop.s_result.descriptions
             return hop.inputconst(ootype.Void, desc.pyobj)
         elif expected_type == ootype.Class:
             return hop.genop('classof', [v_inst], resulttype=ootype.Class)
         else:
             assert expected_type == META
             _, meth = v_inst.concretetype._lookup('getmeta')
             assert meth
             c_getmeta = hop.inputconst(ootype.Void, 'getmeta')
             return hop.genop('oosend', [c_getmeta, v_inst],
                              resulttype=META)
     else:
         raise TyperError("no attribute %r on %r" % (attr, self))
コード例 #10
0
def rtype_builtin_isinstance(hop):
    if hop.s_result.is_constant():
        return hop.inputconst(lltype.Bool, hop.s_result.const)
    if hop.args_r[0] == pyobj_repr or hop.args_r[1] == pyobj_repr:
        v_obj, v_typ = hop.inputargs(pyobj_repr, pyobj_repr)
        c = hop.inputconst(pyobj_repr, isinstance)
        v = hop.genop('simple_call', [c, v_obj, v_typ], resulttype = pyobj_repr)
        return hop.llops.convertvar(v, pyobj_repr, bool_repr)        

    if hop.args_s[1].is_constant() and hop.args_s[1].const == list:
        if hop.args_s[0].knowntype != list:
            raise TyperError("isinstance(x, list) expects x to be known statically to be a list or None")
        rlist = hop.args_r[0]
        vlist = hop.inputarg(rlist, arg=0)
        cnone = hop.inputconst(rlist, None)
        return hop.genop('ptr_ne', [vlist, cnone], resulttype=lltype.Bool)

    assert isinstance(hop.args_r[0], rclass.InstanceRepr)
    return hop.args_r[0].rtype_isinstance(hop)
コード例 #11
0
def rtype_is_None(robj1, rnone2, hop, pos=0):
    if isinstance(robj1.lowleveltype, Ptr):
        v1 = hop.inputarg(robj1, pos)
        return hop.genop('ptr_iszero', [v1], resulttype=Bool)
    elif robj1.lowleveltype == llmemory.Address:
        v1 = hop.inputarg(robj1, pos)
        cnull = hop.inputconst(llmemory.Address, robj1.null_instance())
        return hop.genop('adr_eq', [v1, cnull], resulttype=Bool)
    elif robj1 == none_frozen_pbc_repr:
        return hop.inputconst(Bool, True)
    elif isinstance(robj1, SmallFunctionSetPBCRepr):
        if robj1.s_pbc.can_be_None:
            v1 = hop.inputarg(robj1, pos)
            return hop.genop('char_eq', [v1, inputconst(Char, '\000')],
                             resulttype=Bool)
        else:
            return inputconst(Bool, False)
    else:
        raise TyperError('rtype_is_None of %r' % (robj1))
コード例 #12
0
    def _setup_repr(self, llfields=None, hints=None):
        if hints:
            self.lowleveltype._hints.update(hints)

        if self.classdef is None:
            self.fields = {}
            self.allfields = {}
            self.allmethods = {}
            self.allclassattributes = {}
            self.classattributes = {}
            return

        if self.baserepr is not None:
            allfields = self.baserepr.allfields.copy()
            allmethods = self.baserepr.allmethods.copy()
            allclassattributes = self.baserepr.allclassattributes.copy()
        else:
            allfields = {}
            allmethods = {}
            allclassattributes = {}

        fields = {}
        nonmangledfields = []
        fielddefaults = {}

        if llfields:
            fields.update(dict(llfields))

        selfattrs = self.classdef.attrs

        for name, attrdef in selfattrs.iteritems():
            mangled = mangle(name, self.rtyper.getconfig())
            if not attrdef.readonly:
                repr = self.rtyper.getrepr(attrdef.s_value)
                allfields[mangled] = repr
                oot = repr.lowleveltype
                fields[mangled] = oot
                nonmangledfields.append(name)
                try:
                    value = self.classdef.classdesc.read_attribute(name)
                    fielddefaults[mangled] = repr.convert_desc_or_const(value)
                except AttributeError:
                    pass
            else:
                s_value = attrdef.s_value
                if isinstance(s_value, annmodel.SomePBC):
                    if len(s_value.descriptions) > 0 and s_value.getKind(
                    ) == description.MethodDesc:
                        # attrdef is for a method
                        if mangled in allclassattributes:
                            raise TyperError(
                                "method overrides class attribute")
                        allmethods[
                            mangled] = name, self.classdef.lookup_filter(
                                s_value)
                        continue
                # class attribute
                if mangled in allmethods:
                    raise TyperError("class attribute overrides method")
                allclassattributes[mangled] = name, s_value

        special_methods = ["__init__", "__del__"]
        for meth_name in special_methods:
            if meth_name not in selfattrs and \
                    self.classdef.classdesc.find_source_for(meth_name) is not None:
                s_meth = self.classdef.classdesc.s_get_value(
                    self.classdef, meth_name)
                if isinstance(s_meth, annmodel.SomePBC):
                    mangled = mangle(meth_name, self.rtyper.getconfig())
                    allmethods[mangled] = meth_name, s_meth
                # else: it's the __init__ of a builtin exception

        ootype.addFields(self.lowleveltype, fields)

        self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef)
        self.rbase.setup()

        for name, attrdef in selfattrs.iteritems():
            if not attrdef.readonly and self.is_quasi_immutable(name):
                name = mangle('mutable_' + name, self.rtyper.getconfig())
                ootype.addFields(self.lowleveltype, {name: OBJECT})

        classattributes = {}
        baseInstance = self.lowleveltype._superclass
        classrepr = getclassrepr(self.rtyper, self.classdef)

        # if this class has a corresponding metaclass, attach
        # a getmeta() method to get the corresponding meta_instance
        if classrepr.lowleveltype != ootype.Class:
            oovalue = classrepr.get_meta_instance()
            self.attach_class_attr_accessor('getmeta', oovalue)

        for classdef in self.classdef.getmro():
            for name, attrdef in classdef.attrs.iteritems():
                if not attrdef.readonly:
                    continue
                mangled = mangle(name, self.rtyper.getconfig())
                if mangled in allclassattributes:
                    selfdesc = self.classdef.classdesc
                    if name not in selfattrs:
                        # if the attr was already found in a parent class,
                        # we register it again only if it is overridden.
                        if selfdesc.find_source_for(name) is None:
                            continue
                        value = selfdesc.read_attribute(name)
                    else:
                        # otherwise, for new attrs, we look in all parent
                        # classes to see if it's defined in a parent but only
                        # actually first used in self.classdef.
                        value = selfdesc.read_attribute(name, None)

                    # a non-method class attribute
                    if not attrdef.s_value.is_constant():
                        classattributes[mangled] = attrdef.s_value, value

        self.fields = nonmangledfields
        self.allfields = allfields
        self.allmethods = allmethods
        self.allclassattributes = allclassattributes
        self.classattributes = classattributes
        # the following is done after the rest of the initialization because
        # convert_const can require 'self' to be fully initialized.

        # step 2: provide default values for fields
        for mangled, impl in fielddefaults.items():
            oot = fields[mangled]
            ootype.addFields(self.lowleveltype, {mangled: (oot, impl)},
                             with_default=True)
コード例 #13
0
ファイル: rclass.py プロジェクト: chyyuu/pygirl
    def _setup_repr(self):
        if self.classdef is None:
            self.allfields = {}
            self.allmethods = {}
            self.allclassattributes = {}
            self.classattributes = {}
            return

        if self.baserepr is not None:
            allfields = self.baserepr.allfields.copy()
            allmethods = self.baserepr.allmethods.copy()
            allclassattributes = self.baserepr.allclassattributes.copy()
        else:
            allfields = {}
            allmethods = {}
            allclassattributes = {}

        fields = {}
        fielddefaults = {}

        selfattrs = self.classdef.attrs

        for name, attrdef in selfattrs.iteritems():
            mangled = mangle(name, self.rtyper.getconfig())
            if not attrdef.readonly:
                repr = self.rtyper.getrepr(attrdef.s_value)
                allfields[mangled] = repr
                oot = repr.lowleveltype
                fields[mangled] = oot
                try:
                    value = self.classdef.classdesc.read_attribute(name)
                    fielddefaults[mangled] = repr.convert_desc_or_const(value)
                except AttributeError:
                    pass
            else:
                s_value = attrdef.s_value
                if isinstance(s_value, annmodel.SomePBC):
                    if len(s_value.descriptions) > 0 and s_value.getKind(
                    ) == description.MethodDesc:
                        # attrdef is for a method
                        if mangled in allclassattributes:
                            raise TyperError(
                                "method overrides class attribute")
                        allmethods[
                            mangled] = name, self.classdef.lookup_filter(
                                s_value)
                        continue
                # class attribute
                if mangled in allmethods:
                    raise TyperError("class attribute overrides method")
                allclassattributes[mangled] = name, s_value

        special_methods = ["__init__", "__del__"]
        for meth_name in special_methods:
            if meth_name not in selfattrs and \
                    self.classdef.classdesc.find_source_for(meth_name) is not None:
                s_meth = self.classdef.classdesc.s_get_value(
                    self.classdef, meth_name)
                if isinstance(s_meth, annmodel.SomePBC):
                    mangled = mangle(meth_name, self.rtyper.getconfig())
                    allmethods[mangled] = meth_name, s_meth
                # else: it's the __init__ of a builtin exception

        #
        # hash() support
        if self.rtyper.needs_hash_support(self.classdef):
            from pypy.rpython import rint
            allfields['_hash_cache_'] = rint.signed_repr
            fields['_hash_cache_'] = ootype.Signed

        ootype.addFields(self.lowleveltype, fields)

        self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef)
        self.rbase.setup()

        methods = {}
        classattributes = {}
        baseInstance = self.lowleveltype._superclass
        classrepr = getclassrepr(self.rtyper, self.classdef)

        for mangled, (name, s_value) in 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)

        for classdef in self.classdef.getmro():
            for name, attrdef in classdef.attrs.iteritems():
                if not attrdef.readonly:
                    continue
                mangled = mangle(name, self.rtyper.getconfig())
                if mangled in allclassattributes:
                    selfdesc = self.classdef.classdesc
                    if name not in selfattrs:
                        # if the attr was already found in a parent class,
                        # we register it again only if it is overridden.
                        if selfdesc.find_source_for(name) is None:
                            continue
                        value = selfdesc.read_attribute(name)
                    else:
                        # otherwise, for new attrs, we look in all parent
                        # classes to see if it's defined in a parent but only
                        # actually first used in self.classdef.
                        value = selfdesc.read_attribute(name, None)

                    # a non-method class attribute
                    if not attrdef.s_value.is_constant():
                        classattributes[mangled] = attrdef.s_value, value

        ootype.addMethods(self.lowleveltype, methods)

        self.allfields = allfields
        self.allmethods = allmethods
        self.allclassattributes = allclassattributes
        self.classattributes = classattributes

        # the following is done after the rest of the initialization because
        # convert_const can require 'self' to be fully initialized.

        # step 2: provide default values for fields
        for mangled, impl in fielddefaults.items():
            oot = fields[mangled]
            ootype.addFields(self.lowleveltype, {mangled: (oot, impl)})