[pypy-svn] r25850 - in pypy/dist/pypy/rpython: lltypesystem rctypes rctypes/test

arigo at codespeak.net arigo at codespeak.net
Sat Apr 15 12:42:16 CEST 2006


Author: arigo
Date: Sat Apr 15 12:42:14 2006
New Revision: 25850

Modified:
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/rctypes/rvoid_p.py
   pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
Log:
Specialize and compile cast() between pointers.


Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Sat Apr 15 12:42:14 2006
@@ -232,7 +232,6 @@
                                                    ref.fieldname)
         else:
             # regular case
-            assert isinstance(ref.type(), lltype.ContainerType)
             return lltype.cast_pointer(EXPECTED_TYPE, ref.get())
 
     def _cast_to_int(self):

Modified: pypy/dist/pypy/rpython/rctypes/rvoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rvoid_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rvoid_p.py	Sat Apr 15 12:42:14 2006
@@ -1,12 +1,18 @@
 from pypy.rpython import extregistry
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.annotation import model as annmodel
+from pypy.rpython.rctypes.rmodel import CTypesValueRepr, C_ZERO
+from pypy.rpython.rctypes.rpointer import PointerRepr
 
 from ctypes import c_void_p, c_int, POINTER, cast
 
 PointerType = type(POINTER(c_int))
 
 
+class CVoidPRepr(CTypesValueRepr):
+    pass  # No operations supported on c_void_p instances so far
+
+
 # c_void_p() as a function
 def c_void_p_compute_result_annotation(s_arg=None):
     raise NotImplementedError("XXX calling c_void_p()")
@@ -33,11 +39,34 @@
     assert s_type.is_constant(), "cast(p, %r): argument 2 must be constant" % (
         s_type,)
     type = s_type.const
-    assert isinstance(type, PointerType) or type == c_void_p, (
-       "cast(p, %r): XXX can only cast between pointer types so far" % (type,))
+
+    def checkptr(ctype):
+        assert isinstance(ctype, PointerType) or ctype == c_void_p, (
+            "cast(): can only cast between pointers so far, not %r" % (ctype,))
+    checkptr(s_arg.knowntype)
+    checkptr(type)
     return annmodel.SomeCTypesObject(type,
                                      annmodel.SomeCTypesObject.OWNSMEMORY)
 
+def cast_specialize_call(hop):
+    assert isinstance(hop.args_r[0], (PointerRepr, CVoidPRepr))
+    targetctype = hop.args_s[1].const
+    v_box, c_targetctype = hop.inputargs(hop.args_r[0], lltype.Void)
+    v_adr = hop.args_r[0].getvalue(hop.llops, v_box)
+    if v_adr.concretetype != llmemory.Address:
+        v_adr = hop.genop('cast_ptr_to_adr', [v_adr],
+                          resulttype = llmemory.Address)
+
+    if targetctype == c_void_p:
+        # cast to void
+        v_result = v_adr
+    else:
+        # cast to pointer
+        v_result = hop.genop('cast_adr_to_ptr', [v_adr],
+                             resulttype = hop.r_result.ll_type)
+    return hop.r_result.return_value(hop.llops, v_result)
+
 extregistry.register_value(cast,
     compute_result_annotation=cast_compute_result_annotation,
+    specialize_call=cast_specialize_call,
     )

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py	Sat Apr 15 12:42:14 2006
@@ -8,7 +8,7 @@
 from pypy.translator.translator import TranslationContext
 from pypy.translator.c.test.test_genc import compile
 from pypy import conftest
-import sys
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.test.test_llinterp import interpret
 
 try:
@@ -19,7 +19,7 @@
 from ctypes import c_void_p, c_int, cast, pointer, POINTER
 
 class Test_annotation:
-    def test_annotate_c_char_p(self):
+    def test_annotate_c_void_p(self):
         def fn():
             x = c_int(12)
             p1 = cast(pointer(x), c_void_p)
@@ -35,3 +35,26 @@
 
         if conftest.option.view:
             t.view()
+
+class Test_specialization:
+    def test_specialize_c_void_p(self):
+        def func():
+            x = c_int(12)
+            p1 = cast(pointer(x), c_void_p)
+            p2 = cast(p1, POINTER(c_int))
+            return p1, p2.contents.value
+
+        res = interpret(func, [])
+        assert lltype.typeOf(res.item0.c_data[0]) == llmemory.Address
+        assert res.item1 == 12
+
+class Test_compilation:
+    def test_compile_c_char_p(self):
+        def func():
+            x = c_int(12)
+            p1 = cast(pointer(x), c_void_p)
+            p2 = cast(p1, POINTER(c_int))
+            return p2.contents.value
+
+        fn = compile(func, [])
+        assert fn() == 12



More information about the Pypy-commit mailing list