[pypy-svn] pypy out-of-line-guards-2: Implement these two cast functions to "work" when run

arigo commits-noreply at bitbucket.org
Sat Apr 2 20:17:21 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: out-of-line-guards-2
Changeset: r43110:5848fef711b0
Date: 2011-04-02 17:08 +0200
http://bitbucket.org/pypy/pypy/changeset/5848fef711b0/

Log:	Implement these two cast functions to "work" when run untranslated
	too. This is equivalent to the ropaque module in the previous out-
	of-line-guards branch, and serves the same purpose: for tests,
	temporarily hiding an RPython instance into a field of a low-level
	Struct.

diff --git a/pypy/rpython/annlowlevel.py b/pypy/rpython/annlowlevel.py
--- a/pypy/rpython/annlowlevel.py
+++ b/pypy/rpython/annlowlevel.py
@@ -480,7 +480,23 @@
 # ____________________________________________________________
 
 def cast_object_to_ptr(PTR, object):
-    raise NotImplementedError("cast_object_to_ptr")
+    """NOT_RPYTHON: hack. The object may be disguised as a PTR now.
+    Limited to casting a given object to a single type.
+    """
+    if isinstance(PTR, lltype.Ptr):
+        if not hasattr(object, '_TYPE'):
+            object._TYPE = PTR.TO
+        else:
+            assert object._TYPE == PTR.TO
+        return lltype._ptr(PTR, object, True)
+    elif isinstance(PTR, ootype.Instance):
+        if not hasattr(object, '_TYPE'):
+            object._TYPE = PTR
+        else:
+            assert object._TYPE == PTR
+        return object
+    else:
+        raise NotImplementedError("cast_object_to_ptr(%r, ...)" % PTR)
 
 def cast_instance_to_base_ptr(instance):
     return cast_object_to_ptr(base_ptr_lltype(), instance)
@@ -535,7 +551,13 @@
 # ____________________________________________________________
 
 def cast_base_ptr_to_instance(Class, ptr):
-    raise NotImplementedError("cast_base_ptr_to_instance")
+    """NOT_RPYTHON: hack. Reverse the hacking done in cast_object_to_ptr()."""
+    if isinstance(lltype.typeOf(ptr), lltype.Ptr):
+        ptr = ptr._as_obj()
+    if not isinstance(ptr, Class):
+        raise NotImplementedError("cast_base_ptr_to_instance: casting %r to %r"
+                                  % (ptr, Class))
+    return ptr
 
 class CastBasePtrToInstanceEntry(extregistry.ExtRegistryEntry):
     _about_ = cast_base_ptr_to_instance

diff --git a/pypy/rpython/test/test_annlowlevel.py b/pypy/rpython/test/test_annlowlevel.py
--- a/pypy/rpython/test/test_annlowlevel.py
+++ b/pypy/rpython/test/test_annlowlevel.py
@@ -4,9 +4,12 @@
 
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.rpython.lltypesystem.rstr import mallocstr, mallocunicode
+from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.annlowlevel import hlstr, llstr, oostr
 from pypy.rpython.annlowlevel import hlunicode, llunicode
+from pypy.rpython import annlowlevel
+
 
 class TestLLType(BaseRtypingTest, LLRtypeMixin):
     def test_hlstr(self):
@@ -53,6 +56,15 @@
         res = self.interpret(f, [self.unicode_to_ll(u"abc")])
         assert res == 3
 
+    def test_cast_instance_to_base_ptr(self):
+        class X(object):
+            pass
+        x = X()
+        ptr = annlowlevel.cast_instance_to_base_ptr(x)
+        assert lltype.typeOf(ptr) == annlowlevel.base_ptr_lltype()
+        y = annlowlevel.cast_base_ptr_to_instance(X, ptr)
+        assert y is x
+
 
 class TestOOType(BaseRtypingTest, OORtypeMixin):
     def test_hlstr(self):
@@ -71,3 +83,12 @@
 
         res = self.interpret(f, [self.string_to_ll("abc")])
         assert res == 3
+
+    def test_cast_instance_to_base_obj(self):
+        class X(object):
+            pass
+        x = X()
+        obj = annlowlevel.cast_instance_to_base_obj(x)
+        assert lltype.typeOf(obj) == annlowlevel.base_obj_ootype()
+        y = annlowlevel.cast_base_ptr_to_instance(X, obj)
+        assert y is x


More information about the Pypy-commit mailing list