[pypy-svn] r23805 - in pypy/branch/rpython-ooclassattrs: . lltypesystem ootypesystem ootypesystem/test
nik at codespeak.net
nik at codespeak.net
Wed Mar 1 01:59:53 CET 2006
Author: nik
Date: Wed Mar 1 01:59:39 2006
New Revision: 23805
Modified:
pypy/branch/rpython-ooclassattrs/lltypesystem/lltype.py
pypy/branch/rpython-ooclassattrs/ootypesystem/ootype.py
pypy/branch/rpython-ooclassattrs/ootypesystem/rbuiltin.py
pypy/branch/rpython-ooclassattrs/ootypesystem/rclass.py
pypy/branch/rpython-ooclassattrs/ootypesystem/test/test_oopbc.py
pypy/branch/rpython-ooclassattrs/rclass.py
pypy/branch/rpython-ooclassattrs/rmodel.py
Log:
(pedronis, nik)
work-in-progress class attributes for ootypesystem.
Modified: pypy/branch/rpython-ooclassattrs/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/lltypesystem/lltype.py (original)
+++ pypy/branch/rpython-ooclassattrs/lltypesystem/lltype.py Wed Mar 1 01:59:39 2006
@@ -64,6 +64,8 @@
def __ne__(self, other):
return not (self == other)
+ _is_compatible = __eq__
+
def __hash__(self):
# cannot use saferecursive() -- see test_lltype.test_hash().
# NB. the __cached_hash should neither be used nor updated
@@ -1100,6 +1102,7 @@
return result
def isCompatibleType(TYPE1, TYPE2):
+ return TYPE1._is_compatible(TYPE2)
return TYPE1 == TYPE2
# mark type ADT methods
Modified: pypy/branch/rpython-ooclassattrs/ootypesystem/ootype.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/ootypesystem/ootype.py (original)
+++ pypy/branch/rpython-ooclassattrs/ootypesystem/ootype.py Wed Mar 1 01:59:39 2006
@@ -1,12 +1,23 @@
from pypy.rpython.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char
-from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, Primitive
-from pypy.rpython.lltypesystem.lltype import frozendict
+from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \
+ Primitive, isCompatibleType
+from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType
class OOType(LowLevelType):
- pass
+
+ def _is_compatible(TYPE1, TYPE2):
+ if TYPE1 == TYPE2:
+ return True
+ if isinstance(TYPE1, Instance) and isinstance(TYPE2, Instance):
+ return isSubclass(TYPE1, TYPE2)
+ else:
+ return False
class Class(OOType):
- pass
+
+ def _defl(self):
+ return nullruntimeclass
+
Class = Class()
class Instance(OOType):
@@ -170,7 +181,7 @@
def __setattr__(self, name, value):
self.__getattr__(name)
- if self._TYPE._field_type(name) != typeOf(value):
+ if not isCompatibleType(typeOf(value), self._TYPE._field_type(name)):
raise TypeError("Expected type %r" % self._TYPE._field_type(name))
self.__dict__[name] = value
@@ -333,14 +344,6 @@
c = c._superclass
return None
-def isCompatibleType(TYPE1, TYPE2):
- if TYPE1 == TYPE2:
- return True
- if isinstance(TYPE1, Instance) and isinstance(TYPE2, Instance):
- return isSubclass(TYPE1, TYPE2)
- else:
- return False
-
def ooupcast(INSTANCE, instance):
assert instanceof(instance, INSTANCE)
return instance
Modified: pypy/branch/rpython-ooclassattrs/ootypesystem/rbuiltin.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/ootypesystem/rbuiltin.py (original)
+++ pypy/branch/rpython-ooclassattrs/ootypesystem/rbuiltin.py Wed Mar 1 01:59:39 2006
@@ -40,7 +40,7 @@
v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
if isinstance(v_cls, Constant):
- c_cls = hop.inputconst(ootype.Void, v_cls.value._INSTANCE)
+ c_cls = hop.inputconst(ootype.Void, v_cls.value.class_._INSTANCE)
return hop.genop('instanceof', [v_obj, c_cls], resulttype=ootype.Bool)
else:
raise TyperError("XXX missing impl of isinstance(x, variable)")
Modified: pypy/branch/rpython-ooclassattrs/ootypesystem/rclass.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/ootypesystem/rclass.py (original)
+++ pypy/branch/rpython-ooclassattrs/ootypesystem/rclass.py Wed Mar 1 01:59:39 2006
@@ -8,24 +8,122 @@
from pypy.annotation.pairtype import pairtype
from pypy.tool.sourcetools import func_with_new_name
-CLASSTYPE = ootype.Class
+CLASSTYPE = ootype.Instance("Object_meta", ootype.ROOT,
+ fields={"class_": ootype.Class})
+OBJECT = ootype.Instance("Object", ootype.ROOT,
+ fields={'meta': CLASSTYPE})
+
class ClassRepr(AbstractClassRepr):
def __init__(self, rtyper, classdef):
AbstractClassRepr.__init__(self, rtyper, classdef)
- self.lowleveltype = ootype.Class
+ if self.classdef is not None:
+ self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
+ base_type = self.rbase.lowleveltype
+ self.lowleveltype = ootype.Instance(
+ self.classdef.name + "_meta", base_type)
+ else:
+ # we are ROOT
+ self.lowleveltype = CLASSTYPE
def _setup_repr(self):
- pass # not actually needed?
+ clsfields = {}
+ pbcfields = {}
+ 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, counter in extra_access_sets.items():
+ for attr, s_value in access_set.attrs.items():
+ r = self.rtyper.getrepr(s_value)
+ mangled_name = mangle('pbc%d' % counter, attr)
+ pbcfields[access_set, attr] = mangled_name, r
+ llfields.append((mangled_name, r.lowleveltype))
+
+ self.rbase.setup()
+ ootype.addFields(self.lowleveltype, dict(llfields))
+ #self.clsfields = clsfields
+ self.pbcfields = pbcfields
+ self.meta_instance = None
+
+ def get_meta_instance(self, cast_to_root_meta=True):
+ 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(CLASSTYPE, meta_instance)
+ return meta_instance
- def getruntime(self):
- return getinstancerepr(self.rtyper, self.classdef).lowleveltype._class
+ def setup_meta_instance(self, meta_instance, rsubcls):
+ if self.classdef is None:
+ rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
+ setattr(meta_instance, 'class_', rinstance.lowleveltype._class)
+ else:
+ # setup class attributes: for each attribute name at the level
+ # of 'self', look up its value in the subclass rsubcls
+ def assign(mangled_name, value):
+ if isinstance(value, Constant) and isinstance(value.value, staticmethod):
+ value = Constant(value.value.__get__(42)) # staticmethod => bare function
+ llvalue = r.convert_desc_or_const(value)
+ setattr(meta_instance, mangled_name, llvalue)
+
+ #mro = list(rsubcls.classdef.getmro())
+ #for fldname in self.clsfields:
+ # mangled_name, r = self.clsfields[fldname]
+ # if r.lowleveltype is Void:
+ # continue
+ # value = rsubcls.classdef.classdesc.read_attribute(fldname, None)
+ # if value is not None:
+ # assign(mangled_name, value)
+ # extra PBC attributes
+ for (access_set, attr), (mangled_name, r) in self.pbcfields.items():
+ if rsubcls.classdef.classdesc not in access_set.descs:
+ continue # only for the classes in the same pbc access set
+ if r.lowleveltype is Void:
+ continue
+ attrvalue = rsubcls.classdef.classdesc.read_attribute(attr, None)
+ if attrvalue is not None:
+ assign(mangled_name, attrvalue)
+
+ # then initialize the 'super' portion of the vtable
+ meta_instance_super = ootype.ooupcast(
+ self.rbase.lowleveltype, meta_instance)
+ self.rbase.setup_meta_instance(meta_instance_super, rsubcls)
+
+ getruntime = get_meta_instance
+
+ #def getruntime(self):
+ # return getinstancerepr(self.rtyper, self.classdef).lowleveltype._class
def rtype_issubtype(self, hop):
class_repr = get_type_repr(self.rtyper)
- vlist = hop.inputargs(class_repr, class_repr)
- return hop.genop('subclassof', vlist, resulttype=ootype.Bool)
+ vmeta1, vmeta2 = hop.inputargs(class_repr, class_repr)
+ return hop.gendirectcall(ll_issubtype, vmeta1, vmeta2)
+
+def ll_issubtype(meta1, meta2):
+ class1 = meta1.class_
+ class2 = meta2.class_
+ return ootype.subclassof(class1, class2)
# ____________________________________________________________
@@ -45,14 +143,14 @@
self.baserepr = None
if self.classdef is None:
- self.lowleveltype = ootype.ROOT
+ self.lowleveltype = OBJECT
else:
b = self.classdef.basedef
if b is not None:
self.baserepr = getinstancerepr(rtyper, b)
b = self.baserepr.lowleveltype
else:
- b = ootype.ROOT
+ b = OBJECT
self.lowleveltype = ootype.Instance(classdef.shortname, b, {}, {})
self.prebuiltinstances = {} # { id(x): (x, _ptr) }
@@ -259,7 +357,8 @@
if hop.args_s[0].can_be_none():
return hop.gendirectcall(ll_inst_type, vinst)
else:
- return hop.genop('classof', [vinst], resulttype=ootype.Class)
+ cmeta = inputconst(ootype.Void, "meta")
+ return hop.genop('oogetfield', [vinst, cmeta], resulttype=CLASSTYPE)
def rtype_hash(self, hop):
if self.classdef is None:
@@ -305,15 +404,23 @@
def new_instance(self, llops):
"""Build a new instance, without calling __init__."""
-
- return llops.genop("new",
+ classrepr = getclassrepr(self.rtyper, self.classdef)
+ v_instance = llops.genop("new",
[inputconst(ootype.Void, self.lowleveltype)], self.lowleveltype)
-
+ cmeta = inputconst(ootype.Void, "meta")
+ cmeta_instance = inputconst(CLASSTYPE, classrepr.get_meta_instance())
+ llops.genop("oosetfield", [v_instance, cmeta, cmeta_instance],
+ resulttype=ootype.Void)
+ return v_instance
+
def initialize_prebuilt_instance(self, value, result):
# then add instance attributes from this level
+ classrepr = getclassrepr(self.rtyper, self.classdef)
for mangled, (oot, default) in self.lowleveltype._allfields().items():
if oot is ootype.Void:
llattrvalue = None
+ elif mangled == 'meta':
+ llattrvalue = classrepr.get_meta_instance()
elif mangled == '_hash_cache_': # hash() support
llattrvalue = hash(value)
else:
@@ -370,7 +477,7 @@
def ll_inst_type(obj):
if obj:
- return ootype.classof(obj)
+ return obj.meta
else:
# type(None) -> NULL (for now)
- return ootype.nullruntimeclass
+ return ootype.null(CLASSTYPE)
Modified: pypy/branch/rpython-ooclassattrs/ootypesystem/test/test_oopbc.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/ootypesystem/test/test_oopbc.py (original)
+++ pypy/branch/rpython-ooclassattrs/ootypesystem/test/test_oopbc.py Wed Mar 1 01:59:39 2006
@@ -64,3 +64,20 @@
assert 3 == interpret(f1, [], type_system="ootype")
assert 6 == interpret(f2, [], type_system="ootype")
+def test_classes_attribute():
+ class A:
+ a = 3
+ class B(A):
+ a = 2
+ def f(i):
+ if i == 1:
+ cls = B
+ else:
+ cls = A
+ instance = cls()
+ return cls.a
+ res = interpret(f, [0], type_system='ootype')
+ assert res == 3
+ res = interpret(f, [1], type_system='ootype')
+ assert res == 2
+
Modified: pypy/branch/rpython-ooclassattrs/rclass.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/rclass.py (original)
+++ pypy/branch/rpython-ooclassattrs/rclass.py Wed Mar 1 01:59:39 2006
@@ -71,7 +71,7 @@
if self.classdef.commonbase(subclassdef) != self.classdef:
raise TyperError("not a subclass of %r: %r" % (
self.classdef.name, desc))
- #
+
return getclassrepr(self.rtyper, subclassdef).getruntime()
def convert_const(self, value):
Modified: pypy/branch/rpython-ooclassattrs/rmodel.py
==============================================================================
--- pypy/branch/rpython-ooclassattrs/rmodel.py (original)
+++ pypy/branch/rpython-ooclassattrs/rmodel.py Wed Mar 1 01:59:39 2006
@@ -4,7 +4,7 @@
from pypy.objspace.flow.model import Constant
from pypy.rpython.lltypesystem.lltype import \
Void, Bool, Float, Signed, Char, UniChar, \
- typeOf, LowLevelType, Ptr, PyObject
+ typeOf, LowLevelType, Ptr, PyObject, isCompatibleType
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.error import TyperError, MissingRTypeOperation
@@ -329,7 +329,7 @@
realtype = typeOf(value)
except (AssertionError, AttributeError):
realtype = '???'
- if realtype != lltype:
+ if not isCompatibleType(realtype, lltype):
raise TyperError("inputconst(reqtype = %s, value = %s):\n"
"expected a %r,\n"
" got a %r" % (reqtype, value,
More information about the Pypy-commit
mailing list