[pypy-svn] r51723 - in pypy/branch/unified-rtti/pypy: rpython/lltypesystem rpython/memory rpython/memory/gctransform translator/c translator/c/src

arigo at codespeak.net arigo at codespeak.net
Thu Feb 21 15:26:33 CET 2008


Author: arigo
Date: Thu Feb 21 15:26:33 2008
New Revision: 51723

Modified:
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py
   pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
   pypy/branch/unified-rtti/pypy/translator/c/database.py
   pypy/branch/unified-rtti/pypy/translator/c/gc.py
   pypy/branch/unified-rtti/pypy/translator/c/node.py
   pypy/branch/unified-rtti/pypy/translator/c/primitive.py
   pypy/branch/unified-rtti/pypy/translator/c/src/exception.h
Log:
First test translating to C passes!


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	Thu Feb 21 15:26:33 2008
@@ -1824,6 +1824,13 @@
         return rttiptr
 getRuntimeTypeInfo._annspecialcase_ = 'specialize:memo'
 
+def getGcTypeForRtti(rttiptr):
+    assert typeOf(rttiptr) == Ptr(RuntimeTypeInfo)
+    if not hasattr(rttiptr._obj, '_GCTYPE'):
+        raise TypeError("rtti object %r is not attached to any type" % (
+            rttiptr,))
+    return rttiptr._obj._GCTYPE
+
 def _install_rtti(STRUCT, runtime_type_info):
     if not isinstance(STRUCT, GcStruct):
         raise TypeError("can only attach a runtime_type_info to a GcStruct")

Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py	Thu Feb 21 15:26:33 2008
@@ -51,6 +51,15 @@
                                       rttiptr)
         return self.rtti2typeinfo[rttiptr._obj]
 
+    def new_typeinfo(self, rttiptr):
+        rttiptr = lltype.cast_pointer(lltype.Ptr(lltype.RuntimeTypeInfo),
+                                      rttiptr)
+        rtti = rttiptr._obj
+        assert rtti not in self.rtti2typeinfo
+        typeinfo = lltype.malloc(self.TYPEINFO, immortal=True)
+        self.rtti2typeinfo[rtti] = typeinfo
+        return typeinfo
+
     def cast_rtti_to_typeinfo(self, rttiptr):
         # this is RPython
         addr = llmemory.cast_ptr_to_adr(rttiptr)

Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py	Thu Feb 21 15:26:33 2008
@@ -175,6 +175,23 @@
                                resulttype=llmemory.Address)
         return v_raw
 
+    def gct_gc_runtime_type_info(self, hop):
+        # generate inline code equivalent to:
+        #   gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR)
+        #   return gcheader.typeptr
+        [v_ptr] = hop.spaceop.args
+        v_adr = hop.genop("cast_ptr_to_adr", [v_ptr],
+                          resulttype=llmemory.Address)
+        c_gc_header_offset = rmodel.inputconst(lltype.Signed,
+                                         self.gcheaderbuilder.size_gc_header)
+        v_adr = hop.genop("adr_sub", [v_adr, c_gc_header_offset],
+                          resulttype=llmemory.Address)
+        v_hdr = hop.genop("cast_adr_to_ptr", [v_adr],
+                          resulttype=lltype.Ptr(self.HDR))
+        c_typeptr = rmodel.inputconst(lltype.Void, "typeptr")
+        hop.genop("getfield", [v_hdr, c_typeptr],
+                  resultvar=hop.spaceop.result)
+
     def consider_constant(self, TYPE, value):
         if value is not lltype.top_container(value):
                 return
@@ -260,3 +277,13 @@
         for p in find_gc_ptrs_in_type(TYPE):
             self.static_deallocation_funcptr_for_type(p.TO)
         return fptr
+
+    def convert_rtti(self, rtti):
+        rtti = rtti._as_ptr()
+        try:
+            return self.gcheaderbuilder.typeinfo_from_rtti(rtti)
+        except KeyError:
+            TYPE = lltype.getGcTypeForRtti(rtti)
+            typeinfo = self.gcheaderbuilder.new_typeinfo(rtti)
+            typeinfo.dealloc = self.static_deallocation_funcptr_for_type(TYPE)
+            return typeinfo

Modified: pypy/branch/unified-rtti/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/database.py	(original)
+++ pypy/branch/unified-rtti/pypy/translator/c/database.py	Thu Feb 21 15:26:33 2008
@@ -1,5 +1,5 @@
 from pypy.rpython.lltypesystem.lltype import \
-     Primitive, Ptr, typeOf, RuntimeTypeInfo, \
+     Primitive, Ptr, typeOf, RuntimeTypeInfo, RuntimeTypeInfoType, \
      Struct, Array, FuncType, PyObject, Void, \
      ContainerType, OpaqueType, FixedSizeArray, _uninitialized
 from pypy.rpython.lltypesystem import lltype
@@ -88,6 +88,9 @@
             elif T == WeakRef:
                 REALT = self.gcpolicy.get_real_weakref_type()
                 node = self.gettypedefnode(REALT)
+            elif T == RuntimeTypeInfo:
+                REALT = self.gcpolicy.get_real_rtti_type()
+                node = self.gettypedefnode(REALT)
             else:
                 raise NoCorrespondingNode("don't know about %r" % (T,))
             self.structdefnodes[key] = node
@@ -107,7 +110,7 @@
                     return node.getptrtype()   # special-casing because of C
             typename = self.gettype(T.TO)   # who_asks not propagated
             return typename.replace('@', '*@')
-        elif isinstance(T, (Struct, Array, _WeakRefType)):
+        elif isinstance(T, (Struct, Array, _WeakRefType, RuntimeTypeInfoType)):
             node = self.gettypedefnode(T, varlength=varlength)
             if who_asks is not None:
                 who_asks.dependencies[node] = True

Modified: pypy/branch/unified-rtti/pypy/translator/c/gc.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/gc.py	(original)
+++ pypy/branch/unified-rtti/pypy/translator/c/gc.py	Thu Feb 21 15:26:33 2008
@@ -2,8 +2,7 @@
 from pypy.translator.c.support import cdecl
 from pypy.translator.c.node import ContainerNode
 from pypy.rpython.lltypesystem.lltype import \
-     typeOf, Ptr, ContainerType, \
-     RuntimeTypeInfo, getRuntimeTypeInfo, top_container
+     typeOf, Ptr, ContainerType, top_container
 from pypy.rpython.memory.gctransform import \
      refcounting, boehm, framework, stacklessframework, llvmgcroot, asmgcroot
 from pypy.rpython.lltypesystem import lltype, llmemory
@@ -48,14 +47,12 @@
     def gc_startup_code(self):
         return []
 
-    def struct_setup(self, structdefnode, rtti):
-        return None
-
-    def array_setup(self, arraydefnode):
-        return None
+    # for rtti node
+    def get_real_rtti_type(self):
+        return self.transformerclass.TYPEINFO
 
-    def rtti_type(self):
-        return ''
+    def convert_rtti(self, obj):
+        return self.db.gctransformer.convert_rtti(obj)
 
     def OP_GC_PUSH_ALIVE_PYOBJ(self, funcgen, op):
         expr = funcgen.expr(op.args[0])
@@ -71,11 +68,6 @@
         return ''
 
 
-class RefcountingInfo:
-    static_deallocator = None
-
-from pypy.rlib.objectmodel import CDefinedIntSymbolic
-
 class RefcountingGcPolicy(BasicGcPolicy):
     transformerclass = refcounting.RefcountingGCTransformer
 
@@ -95,29 +87,6 @@
         else:
             return []
 
-    # for structs
-
-    def struct_setup(self, structdefnode, rtti):
-        if rtti is not None:
-            transformer = structdefnode.db.gctransformer
-            fptr = transformer.static_deallocation_funcptr_for_type(
-                structdefnode.STRUCT)
-            structdefnode.gcinfo = RefcountingInfo()
-            structdefnode.gcinfo.static_deallocator = structdefnode.db.get(fptr)
-
-    # for arrays
-
-    def array_setup(self, arraydefnode):
-        pass
-
-    # for rtti node
-
-    def rtti_type(self):
-        return 'void (@)(void *)'   # void dealloc_xx(struct xx *)
-
-    def rtti_node_factory(self):
-        return RefcountingRuntimeTypeInfo_OpaqueNode
-
     # zero malloc impl
 
     def OP_GC_CALL_RTTI_DESTRUCTOR(self, funcgen, op):
@@ -129,49 +98,9 @@
         return ''
 
 
-class RefcountingRuntimeTypeInfo_OpaqueNode(ContainerNode):
-    nodekind = 'refcnt rtti'
-    globalcontainer = True
-    typename = 'void (@)(void *)'
-
-    def __init__(self, db, T, obj):
-        assert T == RuntimeTypeInfo
-        assert isinstance(obj.about, GcStruct)
-        self.db = db
-        self.T = T
-        self.obj = obj
-        defnode = db.gettypedefnode(obj.about)
-        self.implementationtypename = 'void (@)(void *)'
-        self.name = defnode.gcinfo.static_deallocator
-        self.ptrname = '((void (*)(void *)) %s)' % (self.name,)
-
-    def enum_dependencies(self):
-        return []
-
-    def implementation(self):
-        return []
-
-
-
-class BoehmInfo:
-    finalizer = None
-
-
 class BoehmGcPolicy(BasicGcPolicy):
     transformerclass = boehm.BoehmGCTransformer
 
-    def array_setup(self, arraydefnode):
-        pass
-
-    def struct_setup(self, structdefnode, rtti):
-        pass
-
-    def rtti_type(self):
-        return BoehmGcRuntimeTypeInfo_OpaqueNode.typename
-
-    def rtti_node_factory(self):
-        return BoehmGcRuntimeTypeInfo_OpaqueNode
-
     def gc_libraries(self):
         if sys.platform == 'win32':
             return ['gc_pypy']
@@ -210,31 +139,6 @@
         nbytes = funcgen.expr(op.args[0])
         return 'GC_set_max_heap_size(%s);' % (nbytes,)
 
-class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode):
-    nodekind = 'boehm rtti'
-    globalcontainer = True
-    typename = 'char @'
-
-    def __init__(self, db, T, obj):
-        assert T == RuntimeTypeInfo
-        assert isinstance(obj.about, GcStruct)
-        self.db = db
-        self.T = T
-        self.obj = obj
-        defnode = db.gettypedefnode(obj.about)
-        self.implementationtypename = self.typename
-        self.name = self.db.namespace.uniquename('g_rtti_v_'+ defnode.barename)
-        self.ptrname = '(&%s)' % (self.name,)
-
-    def enum_dependencies(self):
-        return []
-
-    def implementation(self):
-        yield 'char %s  /* uninitialized */;' % self.name
-
-class FrameworkGcRuntimeTypeInfo_OpaqueNode(BoehmGcRuntimeTypeInfo_OpaqueNode):
-    nodekind = 'framework rtti'
-
 
 # to get an idea how it looks like with no refcount/gc at all
 
@@ -250,29 +154,6 @@
 class FrameworkGcPolicy(BasicGcPolicy):
     transformerclass = framework.FrameworkGCTransformer
 
-    def struct_setup(self, structdefnode, rtti):
-        if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
-            destrptr = rtti._obj.destructor_funcptr
-            # make sure this is seen by the database early, i.e. before
-            # finish_helpers() on the gctransformer
-            self.db.get(destrptr)
-            # the following, on the other hand, will only discover ll_finalizer
-            # helpers.  The get() sees and records a delayed pointer.  It is
-            # still important to see it so that it can be followed as soon as
-            # the mixlevelannotator resolves it.
-            gctransf = self.db.gctransformer
-            fptr = gctransf.finalizer_funcptr_for_type(structdefnode.STRUCT)
-            self.db.get(fptr)
-
-    def array_setup(self, arraydefnode):
-        pass
-
-    def rtti_type(self):
-        return FrameworkGcRuntimeTypeInfo_OpaqueNode.typename
-
-    def rtti_node_factory(self):
-        return FrameworkGcRuntimeTypeInfo_OpaqueNode
-
     def pre_pre_gc_code(self):
         yield '#define USING_FRAMEWORK_GC'
 

Modified: pypy/branch/unified-rtti/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/node.py	(original)
+++ pypy/branch/unified-rtti/pypy/translator/c/node.py	Thu Feb 21 15:26:33 2008
@@ -4,7 +4,7 @@
      GcStruct, GcArray, ContainerType, \
      parentlink, Ptr, PyObject, Void, OpaqueType, Float, \
      RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.c.funcgen import FunctionCodeGenerator
 from pypy.translator.c.external import CExternalFunctionCodeGenerator
 from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
@@ -25,15 +25,6 @@
             return False   # gcheader already in the first field
     return True
 
-class defaultproperty(object):
-    def __init__(self, fget):
-        self.fget = fget
-    def __get__(self, obj, cls=None):
-        if obj is None:
-            return self
-        else:
-            return self.fget(obj)
-
 
 class StructDefNode:
     typetag = 'struct'
@@ -88,23 +79,6 @@
             else:
                 typename = db.gettype(T, who_asks=self)
             self.fields.append((self.c_struct_field_name(name), typename))
-        self.gcinfo  # force it to be computed
-
-    def computegcinfo(self):
-        # let the gcpolicy do its own setup
-        self.gcinfo = None   # unless overwritten below
-        rtti = None
-        STRUCT = self.STRUCT
-        if isinstance(STRUCT, GcStruct):
-            XXX
-            try:
-                rtti = getRuntimeTypeInfo(STRUCT)
-            except ValueError:
-                pass
-        if self.varlength == 1:
-            self.db.gcpolicy.struct_setup(self, rtti)
-        return self.gcinfo
-    gcinfo = defaultproperty(computegcinfo)
 
     def gettype(self):
         return '%s %s @' % (self.typetag, self.name)
@@ -222,20 +196,11 @@
             return      # setup() was already called, likely by __init__
         db = self.db
         ARRAY = self.ARRAY
-        self.gcinfo    # force it to be computed
         if needs_gcheader(ARRAY):
             for fname, T in db.gcpolicy.array_gcheader_definition(self):
                 self.gcfields.append((fname, db.gettype(T, who_asks=self)))
         self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
 
-    def computegcinfo(self):
-        # let the gcpolicy do its own setup
-        self.gcinfo = None   # unless overwritten below
-        if self.varlength == 1:
-            self.db.gcpolicy.array_setup(self)
-        return self.gcinfo
-    gcinfo = defaultproperty(computegcinfo)
-
     def gettype(self):
         return '%s %s @' % (self.typetag, self.name)
 
@@ -313,7 +278,6 @@
     Implemented directly as a C array instead of a struct with an items field.
     rffi kind of expects such arrays to be 'bare' C arrays.
     """
-    gcinfo = None
     name = None
     forward_decl = None
 
@@ -360,7 +324,6 @@
 
 
 class FixedSizeArrayDefNode:
-    gcinfo = None
     name = None
     typetag = 'struct'
 
@@ -912,6 +875,13 @@
     obj._converted_weakref = container     # hack for genllvm :-/
     return db.getcontainernode(container, _dont_write_c_code=False)
 
+def rttinode_factory(db, T, obj):
+    assert isinstance(obj, lltype._rtti)
+    wrapper = db.gcpolicy.convert_rtti(obj)
+    container = wrapper._obj
+    #obj._converted_rtti = container     # hack for genllvm :-/
+    return db.getcontainernode(container, _dont_write_c_code=False)
+
 
 ContainerNodeFactory = {
     Struct:       StructNode,
@@ -923,4 +893,5 @@
     OpaqueType:   opaquenode_factory,
     PyObjectType: PyObjectNode,
     llmemory._WeakRefType: weakrefnode_factory,
+    lltype.RuntimeTypeInfoType: rttinode_factory,
     }

Modified: pypy/branch/unified-rtti/pypy/translator/c/primitive.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/primitive.py	(original)
+++ pypy/branch/unified-rtti/pypy/translator/c/primitive.py	Thu Feb 21 15:26:33 2008
@@ -7,7 +7,7 @@
 from pypy.rpython.lltypesystem.llmemory import Address, \
      AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
      CompositeOffset, ArrayLengthOffset, \
-     GCHeaderOffset
+     GCHeaderOffset, GCTypeInfoOffset
 from pypy.rpython.lltypesystem.llarena import RoundedUpForAllocation
 from pypy.translator.c.support import cdecl, barebonearray
 
@@ -49,6 +49,8 @@
             return '0'
         elif type(value) == GCHeaderOffset:
             return '0'
+        elif type(value) == GCTypeInfoOffset:
+            return '0'
         elif type(value) == RoundedUpForAllocation:
             return 'ROUND_UP_FOR_ALLOCATION(%s)' % (
                 name_signed(value.basesize, db))

Modified: pypy/branch/unified-rtti/pypy/translator/c/src/exception.h
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/src/exception.h	(original)
+++ pypy/branch/unified-rtti/pypy/translator/c/src/exception.h	Thu Feb 21 15:26:33 2008
@@ -39,7 +39,7 @@
                                  long lineno, const char *functionname)
 {
   fprintf(stderr, "%s %s: %s:%ld %s\n", msg,
-          RPyFetchExceptionType()->ov_name->items,
+          RPyFetchExceptionType()->ov_name,
           filename, lineno, functionname);
 }
 #endif
@@ -98,7 +98,7 @@
 	PyObject *pycls, *v, *tb;
 	assert(RPyExceptionOccurred());
 	assert(!PyErr_Occurred());
-	clsname = RPyFetchExceptionType()->ov_name->items;
+	clsname = RPyFetchExceptionType()->ov_name;
 	pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname);
 	if (pycls != NULL && PyExceptionClass_Check(pycls) &&
 	    PyObject_IsSubclass(pycls, PyExc_Exception)) {



More information about the Pypy-commit mailing list