[pypy-svn] r30856 - in pypy/dist/pypy/rpython/rctypes: . test

arigo at codespeak.net arigo at codespeak.net
Tue Aug 1 18:03:04 CEST 2006


Author: arigo
Date: Tue Aug  1 18:03:02 2006
New Revision: 30856

Modified:
   pypy/dist/pypy/rpython/rctypes/apointer.py
   pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
   pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
Log:
Support for 'POINTER(ctype * length)'.  In rctypes it actually returns
the same as 'POINTER(ctype * 0)', because rctypes performs no index
checking so it should be equivalent.  But both have to be supported,
otherwise we can't run the code on top of the normal ctypes without
getting IndexErrors.


Modified: pypy/dist/pypy/rpython/rctypes/apointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/apointer.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/apointer.py	Tue Aug  1 18:03:02 2006
@@ -63,9 +63,18 @@
 
     def compute_result_annotation(self, s_arg):
         from pypy.annotation.bookkeeper import getbookkeeper
-        assert s_arg.is_constant(), (
-            "POINTER(%r): argument must be constant" % (s_arg,))
-        RESTYPE = POINTER(s_arg.const)
+        from atype import SomeVarSizedCTypesType
+        if isinstance(s_arg, SomeVarSizedCTypesType):
+            # POINTER(varsized_array_type): given that rctypes performs
+            # no index checking, this pointer-to-array type is equivalent
+            # to a pointer to an array of whatever size.
+            RESTYPE = POINTER(s_arg.ctype_array._type_ * 0)
+        else:
+            # POINTER(constant_ctype) returns the constant annotation
+            # corresponding to the POINTER(ctype).
+            assert s_arg.is_constant(), (
+                "POINTER(%r): argument must be constant" % (s_arg,))
+            RESTYPE = POINTER(s_arg.const)
         return getbookkeeper().immutablevalue(RESTYPE)
 
     def specialize_call(self, hop):

Modified: pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	Tue Aug  1 18:03:02 2006
@@ -218,3 +218,12 @@
     assert PyString_FromString((c_char * 6)(*"hello")) == "hello"
     assert PyString_FromString((c_byte * 6)(104,101,108,108,111)) =="hello"
     assert PyString_FromString(create_string_buffer("hello")) == "hello"
+
+def test_varsize_cast():
+    import struct
+    N = struct.calcsize("l")
+    x = c_long()
+    p = cast(pointer(x), POINTER(c_ubyte*N))
+    for i, c in enumerate(struct.pack("l", 12345678)):
+        p.contents[i] = ord(c)
+    assert x.value == 12345678

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	Tue Aug  1 18:03:02 2006
@@ -11,7 +11,7 @@
 import sys
 from pypy.rpython.test.test_llinterp import interpret
 
-from ctypes import c_int, c_short, c_char_p, c_char, pointer
+from ctypes import c_int, c_short, c_char_p, c_char, c_ubyte, pointer, cast
 from ctypes import ARRAY, POINTER, Structure
 
 c_int_10 = ARRAY(c_int,10)
@@ -364,6 +364,22 @@
         fn = self.compile(func, [])
         assert fn() == "xy"
 
+    def test_compile_varsize_cast(self):
+        # this cannot work on top of lltype, but only in unsafe C
+        import struct
+        N = struct.calcsize("i")
+        BYTES = list(enumerate(struct.pack("i", 12345678)))
+        def func(n):
+            x = c_int()
+            arraytype = c_ubyte * n     # runtime length
+            p = cast(pointer(x), POINTER(arraytype))
+            for i, c in BYTES:
+                p.contents[i] = ord(c)
+            return x.value
+        fn = self.compile(func, [int])
+        res = fn(N)
+        assert res == 12345678
+
 class Test_compilation_llvm(Test_compilation):
     def setup_class(self):
         if not test_llvm_compile:



More information about the Pypy-commit mailing list