[pypy-svn] r69934 - in pypy/branch/virtual-forcing/pypy/rpython: . lltypesystem lltypesystem/test

arigo at codespeak.net arigo at codespeak.net
Sun Dec 6 20:34:27 CET 2009


Author: arigo
Date: Sun Dec  6 20:34:26 2009
New Revision: 69934

Modified:
   pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/rclass.py
   pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
   pypy/branch/virtual-forcing/pypy/rpython/rtyper.py
Log:
Found a bug.  Writing a test.


Modified: pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/ll2ctypes.py	Sun Dec  6 20:34:26 2009
@@ -677,7 +677,10 @@
                 if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0:
                     # figure out the real type of the object
                     containerheader = lltype._struct(OBJECT)
-                    struct_use_ctypes_storage(containerheader, cobj.contents)
+                    cobjheader = ctypes.cast(cobj,
+                                       get_ctypes_type(lltype.Ptr(OBJECT)))
+                    struct_use_ctypes_storage(containerheader,
+                                              cobjheader.contents)
                     REAL_TYPE = get_rtyper().get_type_for_typeptr(
                         containerheader.typeptr)
                     REAL_T = lltype.Ptr(REAL_TYPE)

Modified: pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/rclass.py	Sun Dec  6 20:34:26 2009
@@ -383,7 +383,7 @@
                                                   ll_runtime_type_info,
                                                   OBJECT, destrptr)
             vtable = self.rclass.getvtable()
-            self.rtyper.type_for_typeptr[vtable._obj] = self.lowleveltype.TO
+            self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO)
             self.rtyper.lltype2vtable[self.lowleveltype.TO] = vtable
 
     def common_repr(self): # -> object or nongcobject reprs
@@ -693,3 +693,23 @@
             break
     raise AttributeError("%s has no field %s" % (lltype.typeOf(widest),
                                                  name))
+
+def declare_type_for_typeptr(vtable, TYPE):
+    """Hack for custom low-level-only 'subclasses' of OBJECT:
+    call this somewhere annotated, in order to declare that it is
+    of the given TYPE and has got the corresponding vtable."""
+
+class Entry(ExtRegistryEntry):
+    _about_ = declare_type_for_typeptr
+    def compute_result_annotation(self, s_vtable, s_TYPE):
+        assert s_vtable.is_constant()
+        assert s_TYPE.is_constant()
+        return annmodel.s_None
+    def specialize_call(self, hop):
+        vtable = hop.args_v[0].value
+        TYPE   = hop.args_v[1].value
+        assert lltype.typeOf(vtable) == CLASSTYPE
+        assert isinstance(TYPE, GcStruct)
+        assert lltype._castdepth(TYPE, OBJECT) > 0
+        hop.rtyper.set_type_for_typeptr(vtable, TYPE)
+        return hop.inputconst(lltype.Void, None)

Modified: pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Sun Dec  6 20:34:26 2009
@@ -1125,6 +1125,26 @@
         res = interpret(f, [123])
         assert res == 123
 
+    def test_object_subclass_2(self):
+        from pypy.rpython.lltypesystem import rclass
+        SCLASS = lltype.GcStruct('SCLASS',
+                                 ('parent', rclass.OBJECT),
+                                 ('n', lltype.Signed))
+        sclass_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True,
+                                      immortal=True)
+        sclass_vtable.name = rclass.alloc_array_name('SClass')
+        def f(n):
+            rclass.declare_type_for_typeptr(sclass_vtable, SCLASS)
+            s = lltype.malloc(SCLASS)
+            s.parent.typeptr = sclass_vtable
+            s.n = n
+            as_num = rffi.cast(lltype.Signed, s)
+            # --- around this point, only 'as_num' is passed
+            t = rffi.cast(lltype.Ptr(SCLASS), as_num)
+            return t.n
+        res = interpret(f, [123])
+        assert res == 123
+
 class TestPlatform(object):
     def test_lib_on_libpaths(self):
         from pypy.translator.platform import platform

Modified: pypy/branch/virtual-forcing/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/rpython/rtyper.py	(original)
+++ pypy/branch/virtual-forcing/pypy/rpython/rtyper.py	Sun Dec  6 20:34:26 2009
@@ -137,7 +137,7 @@
         try:
             return self.type_for_typeptr[search]
         except KeyError:
-            # rehash the dictionary, and perform a non-dictionary scan
+            # rehash the dictionary, and perform a linear scan
             # for the case of ll2ctypes typeptr
             found = None
             type_for_typeptr = {}
@@ -150,6 +150,9 @@
                 raise KeyError(search)
             return found
 
+    def set_type_for_typeptr(self, typeptr, TYPE):
+        self.type_for_typeptr[typeptr._obj] = TYPE
+
     def makekey(self, s_obj):
         return pair(self.type_system, s_obj).rtyper_makekey(self)
 



More information about the Pypy-commit mailing list