[pypy-svn] r51603 - in pypy/branch/unified-rtti/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/test

arigo at codespeak.net arigo at codespeak.net
Mon Feb 18 20:34:39 CET 2008


Author: arigo
Date: Mon Feb 18 20:34:37 2008
New Revision: 51603

Modified:
   pypy/branch/unified-rtti/pypy/annotation/builtin.py
   pypy/branch/unified-rtti/pypy/rpython/llinterp.py
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py
   pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py
   pypy/branch/unified-rtti/pypy/rpython/rtyper.py
   pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py
Log:
In-progress: fixing lltypesystem.rclass.


Modified: pypy/branch/unified-rtti/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/annotation/builtin.py	(original)
+++ pypy/branch/unified-rtti/pypy/annotation/builtin.py	Mon Feb 18 20:34:37 2008
@@ -455,6 +455,12 @@
     cast_p = lltype.cast_opaque_ptr(PtrT.const, s_p.ll_ptrtype._defl())
     return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
 
+def runtime_type_info(s_p):
+    assert isinstance(s_p, SomePtr), ("runtime_type_info of non-pointer: %r" %
+                                      s_p)
+    res_p = lltype.runtime_type_info(s_p.ll_ptrtype._example())
+    return SomePtr(ll_ptrtype=lltype.typeOf(res_p))
+
 def direct_fieldptr(s_p, s_fieldname):
     assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
     assert s_fieldname.is_constant()
@@ -479,14 +485,6 @@
     assert PtrT.is_constant()
     return SomePtr(ll_ptrtype=PtrT.const)
 
-def getRuntimeTypeInfo(T):
-    assert T.is_constant()
-    return immutablevalue(lltype.getRuntimeTypeInfo(T.const))
-
-def runtime_type_info(s_p):
-    assert isinstance(s_p, SomePtr), "runtime_type_info of non-pointer: %r" % s_p
-    return SomePtr(lltype.typeOf(lltype.runtime_type_info(s_p.ll_ptrtype._example())))
-
 def constPtr(T):
     assert T.is_constant()
     return immutablevalue(lltype.Ptr(T.const))
@@ -498,13 +496,12 @@
 BUILTIN_ANALYZERS[lltype.nullptr] = nullptr
 BUILTIN_ANALYZERS[lltype.cast_pointer] = cast_pointer
 BUILTIN_ANALYZERS[lltype.cast_opaque_ptr] = cast_opaque_ptr
+BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
 BUILTIN_ANALYZERS[lltype.direct_fieldptr] = direct_fieldptr
 BUILTIN_ANALYZERS[lltype.direct_arrayitems] = direct_arrayitems
 BUILTIN_ANALYZERS[lltype.direct_ptradd] = direct_ptradd
 BUILTIN_ANALYZERS[lltype.cast_ptr_to_int] = cast_ptr_to_int
 BUILTIN_ANALYZERS[lltype.cast_int_to_ptr] = cast_int_to_ptr
-BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
-BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
 BUILTIN_ANALYZERS[lltype.Ptr] = constPtr
 
 # ootype

Modified: pypy/branch/unified-rtti/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/llinterp.py	Mon Feb 18 20:34:37 2008
@@ -764,12 +764,6 @@
     def op_gc_restore_exception(self, exc):
         raise NotImplementedError("gc_restore_exception")
 
-    def op_gc_call_rtti_destructor(self, rtti, addr):
-        if hasattr(rtti._obj, 'destructor_funcptr'):
-            d = rtti._obj.destructor_funcptr
-            obptr = addr.ref()
-            return self.op_direct_call(d, obptr)
-
     def op_gc_deallocate(self, TYPE, addr):
         raise NotImplementedError("gc_deallocate")
 

Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py	Mon Feb 18 20:34:37 2008
@@ -53,11 +53,8 @@
                 #else:
                 #    assert cls.__module__ != 'exceptions', (
                 #        "built-in exceptions should not grow attributes")
-        r_inst = rclass.getinstancerepr(rtyper, None)
-        r_inst.setup()
         default_excinst = malloc(self.lltype_of_exception_value.TO,
                                  immortal=True)
-        default_excinst.typeptr = r_inst.rclass.getvtable()
 
         # build the table in order base classes first, subclasses last
         sortedtable = []

Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py	Mon Feb 18 20:34:37 2008
@@ -390,7 +390,7 @@
     'gc_free':              LLOp(),
     'gc_fetch_exception':   LLOp(),
     'gc_restore_exception': LLOp(),
-    'gc_call_rtti_destructor': LLOp(),
+    'gc_runtime_type_info': LLOp(canfold=True),
     'gc_deallocate':        LLOp(),
     'gc_push_alive_pyobj':  LLOp(),
     'gc_pop_alive_pyobj':   LLOp(),

Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py	Mon Feb 18 20:34:37 2008
@@ -988,6 +988,8 @@
                     return adtmeth
                 else:
                     return getter(self)
+        if self._T == RuntimeTypeInfo:
+            return self._obj._getattr(field_name)
         raise AttributeError("%r instance has no field %r" % (self._T,
                                                               field_name))
 
@@ -1003,6 +1005,9 @@
                                     "expects %r\n"
                                     "    got %r" % (self._T, field_name, T1, T2))
                 return
+        if self._T == RuntimeTypeInfo:
+            self._obj._setattr(field_name, val)
+            return
         raise AttributeError("%r instance has no field %r" % (self._T,
                                                               field_name))
 
@@ -1644,6 +1649,7 @@
 
 class _rtti(_parentable):
     _kind = "rtti"
+    destructor_funcptr = None
 
     def __init__(self, initialization=None, parent=None, parentindex=None):
         _parentable.__init__(self, RuntimeTypeInfo)
@@ -1656,7 +1662,23 @@
         if GCTYPE._gckind != 'gc':
             raise TypeError("non-GC type %r cannot have an rtti" % (GCTYPE,))
         self._GCTYPE = GCTYPE
-        self.destructor_funcptr = nullptr(FuncType([Ptr(GCTYPE)], Void))
+
+    def _getattr(self, name):
+        if name == 'destructor_funcptr':
+            return self.destructor_funcptr
+        else:
+            raise AttributeError(name)
+
+    def _setattr(self, name, value):
+        if name == 'destructor_funcptr':
+            T = typeOf(value).TO
+            if (not isinstance(T, FuncType) or len(T.ARGS) != 1
+                or T.RESULT != Void or not isinstance(T.ARGS[0], Ptr)
+                or castable(T.ARGS[0], Ptr(self._GCTYPE)) < 0):
+                raise TypeError("bad type for destructor: %r" % (T,))
+            self.destructor_funcptr = value
+        else:
+            raise AttributeError(name)
 
 
 class _opaque(_parentable):
@@ -1782,16 +1804,15 @@
     return _ptr(PTRTYPE, oddint, solid=True)
 
 def getRuntimeTypeInfo(TYPE, cache=None):
-    """Return the runtime_type_info attached to the GcStruct TYPE.
-    This is typically of type != Ptr(RuntimeTypeInfo) but castable
-    to Ptr(RuntimeTypeInfo).  This raises TypeError if the TYPE has
+    """Return the runtime_type_info attached to the GcStruct TYPE,
+    as a Ptr(RuntimeTypeInfo).  This raises TypeError if the TYPE has
     no runtime_type_info, unless 'cache' is specified; in that case,
     TYPE can be any GC type and a runtime_type_info is created for
     it if it has none and stored in the cache to avoid mutating
     the TYPE.
     """
     if isinstance(TYPE, GcStruct) and hasattr(TYPE, '_rtti'):
-        return top_container(TYPE._rtti)._as_ptr()
+        return TYPE._rtti._as_ptr()
     if cache is None:
         raise TypeError("%r has no runtime_type_info" % (TYPE,))
     try:
@@ -1801,6 +1822,7 @@
         rttiptr._obj._set_gctype(TYPE)
         cache[TYPE] = rttiptr
         return rttiptr
+getRuntimeTypeInfo._annspecialcase_ = 'specialize:memo'
 
 def _install_rtti(STRUCT, runtime_type_info):
     if not isinstance(STRUCT, GcStruct):

Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py	Mon Feb 18 20:34:37 2008
@@ -313,6 +313,9 @@
 ##    assert type(x) is int
 ##    return llmemory.cast_int_to_adr(x)
 
+def op_gc_runtime_type_info(gcptr):
+    return lltype.runtime_type_info(gcptr)
+
 
 def op_unichar_eq(x, y):
     assert isinstance(x, unicode) and len(x) == 1

Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py	Mon Feb 18 20:34:37 2008
@@ -12,8 +12,7 @@
 from pypy.rpython.lltypesystem.lltype import \
      Ptr, Struct, GcStruct, malloc, \
      cast_pointer, cast_ptr_to_int, castable, nullptr, \
-     RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \
-     Array, Char, Void, attachRuntimeTypeInfo, \
+     typeOf, Array, Char, Void, \
      FuncType, Bool, Signed, functionptr, FuncType, PyObject
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
@@ -27,8 +26,7 @@
 #  A root class "object" has:
 #
 #      struct object_vtable {
-#          // struct object_vtable* parenttypeptr;  not used any more
-#          RuntimeTypeInfo * rtti;
+#          RuntimeTypeInfo rtti;      //GC-specific information
 #          Signed subclassrange_min;  //this is also the id of the class itself
 #          Signed subclassrange_max;
 #          array { char } * name;
@@ -45,7 +43,7 @@
 # The type of the instances is:
 #
 #     struct object {       // for the root class
-#         struct object_vtable* typeptr;
+#         some GC-specific fields including a ptr to the vtable
 #     }
 #
 #     struct X {
@@ -55,22 +53,32 @@
 #
 # there's also a nongcobject 
 
-OBJECT_VTABLE = lltype.ForwardReference()
-CLASSTYPE = Ptr(OBJECT_VTABLE)
-OBJECT = GcStruct('object', ('typeptr', CLASSTYPE),
-                  hints = {'immutable': True, 'shouldntbenull': True})
+def ll_gettypeptr(p):
+    rtti = lltype.runtime_type_info(p)
+    return cast_pointer(CLASSTYPE, rtti)
+
+def ll_gettypeptr_nongc(p):
+    return p.typeptr
+
+OBJECT = lltype.GcForwardReference()
 OBJECTPTR = Ptr(OBJECT)
-OBJECT_VTABLE.become(Struct('object_vtable',
-                            #('parenttypeptr', CLASSTYPE),
+OBJECT_VTABLE = Struct('object_vtable',
+                            ('rtti', lltype.RuntimeTypeInfo),
                             ('subclassrange_min', Signed),
                             ('subclassrange_max', Signed),
-                            ('rtti', Ptr(RuntimeTypeInfo)),
                             ('name', Ptr(Array(Char))),
                             ('instantiate', Ptr(FuncType([], OBJECTPTR))),
-                            hints = {'immutable': True}))
+                            hints = {'immutable': True})
+CLASSTYPE = Ptr(OBJECT_VTABLE)
+OBJECT.become(GcStruct('object',
+                       runtime_type_info = malloc(OBJECT_VTABLE,
+                                                  immortal=True),
+                       adtmeths = {'gettypeptr': ll_gettypeptr}))
+
 # non-gc case
-NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE))
-NONGCOBJECTPTR = Ptr(OBJECT)
+NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE),
+                     adtmeths = {'gettypeptr': ll_gettypeptr_nongc})
+NONGCOBJECTPTR = Ptr(NONGCOBJECT)
 
 OBJECT_BY_FLAVOR = {'gc': OBJECT,
                     'raw': NONGCOBJECT}
@@ -80,12 +88,6 @@
             'stack': 'raw',
             }
 
-def cast_vtable_to_typeptr(vtable):
-    while typeOf(vtable).TO != OBJECT_VTABLE:
-        vtable = vtable.super
-    return vtable
-
-
 class ClassRepr(AbstractClassRepr):
     def __init__(self, rtyper, classdef):
         AbstractClassRepr.__init__(self, rtyper, classdef)
@@ -140,32 +142,15 @@
         self.clsfields = clsfields
         self.pbcfields = pbcfields
         self.allmethods = allmethods
-        self.vtable = None
-
-#    def convert_const(self, value):
-#        if not isinstance(value, (type, types.ClassType)):
-#            raise TyperError("not a class: %r" % (value,))
-#        try:
-#            subclassdef = self.rtyper.annotator.getuserclasses()[value]
-#        except KeyError:
-#            raise TyperError("no classdef: %r" % (value,))
-#        if self.classdef is not None:
-#            if self.classdef.commonbase(subclassdef) != self.classdef:
-#                raise TyperError("not a subclass of %r: %r" % (
-#                    self.classdef.cls, value))
-#        #
-#        return getclassrepr(self.rtyper, subclassdef).getvtable()
+        self.vtable = malloc(self.vtable_type, immortal=True)
+        self.vtable_filled = False
 
-    def getvtable(self, cast_to_typeptr=True):
+    def getvtable(self):
         """Return a ptr to the vtable of this type."""
-        if self.vtable is None:
-            self.vtable = malloc(self.vtable_type, immortal=True)
+        if not self.vtable_filled:
             self.setup_vtable(self.vtable, self)
-        #
-        vtable = self.vtable
-        if cast_to_typeptr:
-            vtable = cast_vtable_to_typeptr(vtable)
-        return vtable
+            self.vtable_filled = True
+        return cast_pointer(CLASSTYPE, self.vtable)
     getruntime = getvtable
 
     def setup_vtable(self, vtable, rsubcls):
@@ -174,7 +159,6 @@
         if self.classdef is None:
             # initialize the 'subclassrange_*' and 'name' fields
             if rsubcls.classdef is not None:
-                #vtable.parenttypeptr = rsubcls.rbase.getvtable()
                 vtable.subclassrange_min = rsubcls.classdef.minid
                 vtable.subclassrange_max = rsubcls.classdef.maxid
             else: #for the root class
@@ -182,8 +166,6 @@
                 vtable.subclassrange_max = sys.maxint
             rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
             rinstance.setup()
-            if rinstance.gcflavor == 'gc':
-                vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
             if rsubcls.classdef is None:
                 name = 'object'
             else:
@@ -232,7 +214,9 @@
     #    to self's vtable type."""
 
     def fromtypeptr(self, vcls, llops):
-        """Return the type pointer cast to self's vtable type."""
+        """Return a RuntimeTypeInfo or Ptr(OBJECT_VTABLE) cast
+        to self's vtable type.
+        """
         self.setup()
         castable(self.lowleveltype, vcls.concretetype) # sanity check
         return llops.genop('cast_pointer', [vcls],
@@ -296,15 +280,15 @@
 class InstanceRepr(AbstractInstanceRepr):
     def __init__(self, rtyper, classdef, gcflavor='gc'):
         AbstractInstanceRepr.__init__(self, rtyper, classdef)
+        self.gcflavor = gcflavor
         if classdef is None:
-            self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]]
+            self.object_type = self.get_base_object_type()
         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 _setup_repr(self, llfields=None, hints=None, adtmeths=None):
         # NOTE: don't store mutable objects like the dicts below on 'self'
@@ -315,7 +299,7 @@
         fields = {}
         allinstancefields = {}
         if self.classdef is None:
-            fields['__class__'] = 'typeptr', get_type_repr(self.rtyper)
+            pass
         else:
             # instance attributes
             if llfields is None:
@@ -347,18 +331,18 @@
             if '_immutable_' in self.classdef.classdesc.classdict:
                 hints = hints.copy()
                 hints['immutable'] = True
+            kwds = {'hints': hints,
+                    'adtmeths': adtmeths}
+            if self.gcflavor == 'gc':
+                kwds['runtime_type_info'] = self.rclass.vtable
             object_type = MkStruct(self.classdef.name,
                                    ('super', self.rbase.object_type),
-                                   hints=hints,
-                                   adtmeths=adtmeths,
-                                   *llfields)
+                                   *llfields, **kwds)
             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)
 
     def _setup_repr_final(self):
         if self.gcflavor == 'gc':
@@ -375,12 +359,14 @@
                 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)
+                rtti = lltype.getRuntimeTypeInfo(self.object_type)
+                rtti = cast_pointer(Ptr(lltype.RuntimeTypeInfo), rtti)
+                rtti.destructor_funcptr = destrptr
+
+    def get_base_object_type(self):
+        return OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
+    get_base_object_type._annspecialcase_ = 'specialize:memo'
+
     def common_repr(self): # -> object or nongcobject reprs
         return getinstancerepr(self.rtyper, None, self.gcflavor)
 
@@ -391,6 +377,7 @@
         return cast_pointer(self.lowleveltype, result)
 
     def create_instance(self):
+        self.rclass.getvtable()     # force it to be filled
         return malloc(self.object_type, flavor=self.gcflavor)
 
     def get_ll_hash_function(self):
@@ -434,9 +421,23 @@
                         llattrvalue = r.convert_const(attrvalue)
                 setattr(result, mangled_name, llattrvalue)
         else:
-            # OBJECT part
-            rclass = getclassrepr(self.rtyper, classdef)
-            result.typeptr = rclass.getvtable()
+            # OBJECT part: nothing to fill, unless we are a non-GC instance
+            if self.gcflavor != 'gc':
+                rclass = getclassrepr(self.rtyper, classdef)
+                result.typeptr = rclass.getvtable()
+
+    def gettypeptr(self, vinst, llops):
+        if self.gcflavor == 'gc':
+            v_rtti = llops.genop('gc_runtime_type_info', [vinst],
+                                 resulttype = Ptr(lltype.RuntimeTypeInfo))
+            return llops.genop('cast_pointer', [v_rtti],
+                               resulttype = CLASSTYPE)
+        else:
+            v_base = llops.genop('cast_pointer', [vinst],
+                                 resulttype = NONGCOBJECTPTR)
+            c_typeptr = inputconst(Void, 'typeptr')
+            return llops.genop('getfield', [v_base, c_typeptr],
+                               resulttype = CLASSTYPE)
 
     def getfieldrepr(self, attr):
         """Return the repr used for the given attribute."""
@@ -458,13 +459,16 @@
             return llops.genop('getfield', [vinst, cname], resulttype=r)
         else:
             if self.classdef is None:
-                raise MissingRTypeAttribute(attr)
+                if attr == '__class__':
+                    return self.gettypeptr(vinst, llops)
+                else:
+                    raise MissingRTypeAttribute(attr)
             return self.rbase.getfield(vinst, attr, llops, force_cast=True,
                                        flags=flags)
 
     def setfield(self, vinst, attr, vvalue, llops, force_cast=False,
                  flags={}):
-        """Write the given attribute (or __class__ for the type) of 'vinst'."""
+        """Write the given attribute of 'vinst'."""
         if attr in self.fields:
             mangled_name, r = self.fields[attr]
             cname = inputconst(Void, mangled_name)
@@ -484,17 +488,14 @@
         ctype = inputconst(Void, self.object_type)
         cflags = inputconst(Void, flags)
         vlist = [ctype, cflags]
+        self.rclass.getvtable()     # force it to be filled
         vptr = llops.genop('malloc', vlist,
                            resulttype = Ptr(self.object_type))
-        ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable())
-        self.setfield(vptr, '__class__', ctypeptr, llops)
         # initialize instance attributes from their defaults from the class
         if self.classdef is not None:
             flds = self.allinstancefields.keys()
             flds.sort()
             for fldname in flds:
-                if fldname == '__class__':
-                    continue
                 mangled_name, r = self.allinstancefields[fldname]
                 if r.lowleveltype is Void:
                     continue
@@ -522,10 +523,13 @@
     def rtype_getattr(self, hop):
         attr = hop.args_s[1].const
         vinst, vattr = hop.inputargs(self, Void)
-        if attr == '__class__' and hop.r_result.lowleveltype is Void:
-            # special case for when the result of '.__class__' is a constant
-            [desc] = hop.s_result.descriptions
-            return hop.inputconst(Void, desc.pyobj)
+        if attr == '__class__':
+            if hop.r_result.lowleveltype is Void:
+                # special case for when the result of '.__class__' is a const
+                [desc] = hop.s_result.descriptions
+                return hop.inputconst(Void, desc.pyobj)
+            else:
+                return self.getfield(vinst, '__class__', hop.llops)
         if attr in self.allinstancefields:
             return self.getfield(vinst, attr, hop.llops,
                                  flags=hop.args_s[0].flags)
@@ -549,19 +553,21 @@
         vinst, = hop.inputargs(self)
         return hop.genop('ptr_nonzero', [vinst], resulttype=Bool)
 
-    def ll_str(self, i): # doesn't work for non-gc classes!
+    def ll_str(self, i):
         from pypy.rpython.lltypesystem import rstr
         from pypy.rpython.lltypesystem.ll_str import ll_int2hex
         from pypy.rlib.rarithmetic import r_uint
         if not i:
             return rstr.null_str
-        instance = cast_pointer(OBJECTPTR, i)
+        BASEPTR = Ptr(self.get_base_object_type())
+        instance = cast_pointer(BASEPTR, i)
+        vtable = instance.gettypeptr()
         uid = r_uint(cast_ptr_to_int(i))
-        nameLen = len(instance.typeptr.name)
+        nameLen = len(vtable.name)
         nameString = rstr.mallocstr(nameLen-1)
         i = 0
         while i < nameLen - 1:
-            nameString.chars[i] = instance.typeptr.name[i]
+            nameString.chars[i] = vtable.name[i]
             i += 1
         res =                        rstr.instance_str_prefix
         res = rstr.ll_strconcat(res, nameString)
@@ -667,7 +673,7 @@
 
 # doesn't work for non-gc stuff!
 def ll_type(obj):
-    return cast_pointer(OBJECTPTR, obj).typeptr
+    return cast_pointer(OBJECTPTR, obj).gettypeptr()
 
 def ll_issubclass(subcls, cls):
     return cls.subclassrange_min <= subcls.subclassrange_min <= cls.subclassrange_max
@@ -679,23 +685,20 @@
 def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT
     if not obj:
         return False
-    obj_cls = obj.typeptr
+    obj_cls = obj.gettypeptr()
     return ll_issubclass(obj_cls, cls)
 
 def ll_isinstance_const(obj, minid, maxid):
     if not obj:
         return False
-    return ll_issubclass_const(obj.typeptr, minid, maxid)
+    return ll_issubclass_const(obj.gettypeptr(), minid, maxid)
 
 def ll_isinstance_exact(obj, cls):
     if not obj:
         return False
-    obj_cls = obj.typeptr
+    obj_cls = obj.gettypeptr()
     return obj_cls == cls
 
-def ll_runtime_type_info(obj):
-    return obj.typeptr.rtti
-
 def ll_inst_hash(ins):
     if not ins:
         return 0    # for None
@@ -710,10 +713,10 @@
 
 def ll_inst_type(obj):
     if obj:
-        return obj.typeptr
+        return obj.gettypeptr()
     else:
         # type(None) -> NULL  (for now)
-        return nullptr(typeOf(obj).TO.typeptr.TO)
+        return nullptr(CLASSTYPE.TO)
 
 def ll_both_none(ins1, ins2):
     return not ins1 and not ins2

Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py	Mon Feb 18 20:34:37 2008
@@ -373,8 +373,8 @@
     t2.v = 33
     S2 = GcStruct('S2', ('parent', S1), ('y', Signed), runtime_type_info=t2)
 
-    assert getRuntimeTypeInfo(S1) == t1
-    assert getRuntimeTypeInfo(S2) == t2
+    assert getRuntimeTypeInfo(S1) == t1.base
+    assert getRuntimeTypeInfo(S2) == t2.base.base
 
     x1 = malloc(S1)
     x2 = malloc(S2)
@@ -388,7 +388,7 @@
     py.test.raises(TypeError, getRuntimeTypeInfo, S1bis)
 
     cache = {}
-    assert getRuntimeTypeInfo(S1, cache=cache) == t1
+    assert getRuntimeTypeInfo(S1, cache=cache) == t1.base
     t1bis = getRuntimeTypeInfo(S1bis, cache=cache)
     assert t1bis != t1.base
     assert getRuntimeTypeInfo(S1bis, cache=cache) == t1bis
@@ -402,9 +402,16 @@
                      "destructor_funcptr", 
                      _callable=f)
     pinf = getRuntimeTypeInfo(S)
-    assert pinf._obj.destructor_funcptr == nullptr(FuncType([Ptr(S)], Void))
-    pinf._obj.destructor_funcptr = dp
-    assert pinf._obj.destructor_funcptr == dp
+    assert pinf.destructor_funcptr is None
+    pinf.destructor_funcptr = dp
+    assert pinf.destructor_funcptr == dp
+
+    S1 = GcStruct('s1', ('super', S),
+                  runtime_type_info=malloc(RuntimeTypeInfo, immortal=True))
+    pinf1 = getRuntimeTypeInfo(S1)
+    assert pinf1.destructor_funcptr is None
+    pinf1.destructor_funcptr = dp
+    assert pinf1.destructor_funcptr == dp
 
 def test_flavor_malloc():
     def isweak(p, T):

Modified: pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py	Mon Feb 18 20:34:37 2008
@@ -476,7 +476,7 @@
 def rtype_runtime_type_info(hop):
     assert isinstance(hop.args_r[0], rptr.PtrRepr)
     vlist = hop.inputargs(hop.args_r[0])
-    return hop.genop('runtime_type_info', vlist,
+    return hop.genop('gc_runtime_type_info', vlist,
                      resulttype = hop.r_result.lowleveltype)
 
 BUILTIN_TYPER[lltype.malloc] = rtype_malloc
@@ -484,6 +484,7 @@
 BUILTIN_TYPER[lltype.cast_primitive] = rtype_cast_primitive
 BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer
 BUILTIN_TYPER[lltype.cast_opaque_ptr] = rtype_cast_opaque_ptr
+BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info
 BUILTIN_TYPER[lltype.direct_fieldptr] = rtype_direct_fieldptr
 BUILTIN_TYPER[lltype.direct_arrayitems] = rtype_direct_arrayitems
 BUILTIN_TYPER[lltype.direct_ptradd] = rtype_direct_ptradd
@@ -491,9 +492,7 @@
 BUILTIN_TYPER[lltype.cast_int_to_ptr] = rtype_cast_int_to_ptr
 BUILTIN_TYPER[lltype.typeOf] = rtype_const_result
 BUILTIN_TYPER[lltype.nullptr] = rtype_const_result
-BUILTIN_TYPER[lltype.getRuntimeTypeInfo] = rtype_const_result
 BUILTIN_TYPER[lltype.Ptr] = rtype_const_result
-BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info
 BUILTIN_TYPER[rarithmetic.intmask] = rtype_intmask
 BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated
 

Modified: pypy/branch/unified-rtti/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/rtyper.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/rtyper.py	Mon Feb 18 20:34:37 2008
@@ -21,8 +21,8 @@
 from pypy.rpython.lltypesystem.lltype import \
      Signed, Unsigned, Float, Char, Bool, Void, \
      LowLevelType, Ptr, ContainerType, \
-     FuncType, functionptr, typeOf, RuntimeTypeInfo, \
-     attachRuntimeTypeInfo, Primitive, Number
+     FuncType, functionptr, typeOf, \
+     Primitive, Number
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.unsimplify import insert_empty_block
 from pypy.rpython.error import TyperError
@@ -648,21 +648,6 @@
         graph = self.annotate_helper(ll_function, argtypes)
         return self.getcallable(graph)
 
-    def attachRuntimeTypeInfoFunc(self, GCSTRUCT, func, ARG_GCSTRUCT=None,
-                                  destrptr=None):
-        self.call_all_setups()  # compute ForwardReferences now
-        if ARG_GCSTRUCT is None:
-            ARG_GCSTRUCT = GCSTRUCT
-        args_s = [annmodel.SomePtr(Ptr(ARG_GCSTRUCT))]
-        graph = self.annotate_helper(func, args_s)
-        s = self.annotator.binding(graph.getreturnvar())
-        if (not isinstance(s, annmodel.SomePtr) or
-            s.ll_ptrtype != Ptr(RuntimeTypeInfo)):
-            raise TyperError("runtime type info function %r returns %r, "
-                             "excepted Ptr(RuntimeTypeInfo)" % (func, s))
-        funcptr = self.getcallable(graph)
-        attachRuntimeTypeInfo(GCSTRUCT, funcptr, destrptr)
-
 # register operations from annotation model
 RPythonTyper._registeroperations(annmodel)
 

Modified: pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py	Mon Feb 18 20:34:37 2008
@@ -650,8 +650,7 @@
         graph = graphof(t, f)
         TYPE = graph.startblock.operations[0].args[0].value
         RTTI = getRuntimeTypeInfo(TYPE)
-        queryptr = RTTI._obj.query_funcptr # should not raise
-        destrptr = RTTI._obj.destructor_funcptr
+        destrptr = RTTI.destructor_funcptr
         assert destrptr is not None
     
     def test_del_inheritance(self):
@@ -681,19 +680,18 @@
         t = TranslationContext()
         t.buildannotator().build_types(f, [])
         t.buildrtyper().specialize()
-        graph = graphof(t, f)
-        TYPEA = graph.startblock.operations[0].args[0].value
+
+        from pypy.rpython.rclass import getinstancerepr
+        getcdef = t.annotator.bookkeeper.getuniqueclassdef
+        TYPEA = getinstancerepr(t.rtyper, getcdef(A)).lowleveltype.TO
         RTTIA = getRuntimeTypeInfo(TYPEA)
-        TYPEB = graph.startblock.operations[3].args[0].value
+        TYPEB = getinstancerepr(t.rtyper, getcdef(B)).lowleveltype.TO
         RTTIB = getRuntimeTypeInfo(TYPEB)
-        TYPEC = graph.startblock.operations[6].args[0].value
+        TYPEC = getinstancerepr(t.rtyper, getcdef(C)).lowleveltype.TO
         RTTIC = getRuntimeTypeInfo(TYPEC)
-        queryptra = RTTIA._obj.query_funcptr # should not raise
-        queryptrb = RTTIB._obj.query_funcptr # should not raise
-        queryptrc = RTTIC._obj.query_funcptr # should not raise
-        destrptra = RTTIA._obj.destructor_funcptr
-        destrptrb = RTTIB._obj.destructor_funcptr
-        destrptrc = RTTIC._obj.destructor_funcptr
+        destrptra = RTTIA.destructor_funcptr
+        destrptrb = RTTIB.destructor_funcptr
+        destrptrc = RTTIC.destructor_funcptr
         assert destrptra == destrptrc
         assert typeOf(destrptra).TO.ARGS[0] != typeOf(destrptrb).TO.ARGS[0]
         assert destrptra is not None



More information about the Pypy-commit mailing list