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

arigo at codespeak.net arigo at codespeak.net
Fri Sep 22 19:20:13 CEST 2006


Author: arigo
Date: Fri Sep 22 19:20:11 2006
New Revision: 32596

Modified:
   pypy/dist/pypy/rpython/rctypes/astruct.py
   pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
   pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py
   pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py
Log:
Two rctypes extensions: offsetof(Struct, fieldname), and ctypes_platform
support for guessing the length of a 'char[]' array field in a struct.



Modified: pypy/dist/pypy/rpython/rctypes/astruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/astruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/astruct.py	Fri Sep 22 19:20:11 2006
@@ -1,5 +1,6 @@
 from ctypes import Structure, Union
-from pypy.annotation.model import SomeCTypesObject
+from pypy.annotation.model import SomeCTypesObject, SomeInteger
+from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.rctypes.implementation import CTypesCallEntry, CTypesObjEntry
 from pypy.rpython.lltypesystem import lltype
 
@@ -10,6 +11,30 @@
 #     by the llinterpreter.  They work in the generated C code, though.
 
 
+def offsetof(Struct, fieldname):
+    "Utility function that returns the offset of a field in a structure."
+    return getattr(Struct, fieldname).offset
+
+
+class OffsetOfFnEntry(ExtRegistryEntry):
+    "Annotation and rtyping of calls to offsetof()"
+    _about_ = offsetof
+
+    def compute_result_annotation(self, s_Struct, s_fieldname):
+        assert s_Struct.is_constant()
+        assert s_fieldname.is_constant()
+        ofs = offsetof(s_Struct.const, s_fieldname.const)
+        assert ofs >= 0
+        s_result = SomeInteger(nonneg=True)
+        s_result.const = ofs
+        return s_result
+
+    def specialize_call(self, hop):
+        ofs = hop.s_result.const
+        return hop.inputconst(lltype.Signed, ofs)
+
+# ____________________________________________________________
+
 class CallEntry(CTypesCallEntry):
     "Annotation and rtyping of calls to structure types."
     _type_ = StructType, UnionType

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py	Fri Sep 22 19:20:11 2006
@@ -4,6 +4,7 @@
 
 import py.test
 import pypy.rpython.rctypes.implementation
+from pypy.rpython.rctypes.astruct import offsetof
 from pypy.rpython.error import TyperError
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.translator.translator import TranslationContext
@@ -235,6 +236,12 @@
             S(x, x=5)
         py.test.raises(TyperError, "interpret(f2, [4])")
 
+    def test_specialize_offsetof(self):
+        def f1():
+            return offsetof(tagpoint, 'y')
+        res = interpret(f1, [])
+        assert res == tagpoint.y.offset
+
 class Test_compilation:
     def test_compile_struct_access(self):
         def access_struct(n):

Modified: pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py	Fri Sep 22 19:20:11 2006
@@ -391,6 +391,12 @@
             for ctype in typeclass:
                 if size_and_sign(ctype) == expected_size_and_sign:
                     return ctype
+    if (hasattr(fieldtype, '_length_')
+        and getattr(fieldtype, '_type_', None) == ctypes.c_char):
+        # for now, assume it is an array of chars; otherwise we'd also
+        # have to check the exact integer type of the elements of the array
+        size, sign = expected_size_and_sign
+        return ctypes.c_char * size
     raise TypeError("conflicting field type %r for %r" % (fieldtype,
                                                           fieldname))
 

Modified: pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py	Fri Sep 22 19:20:11 2006
@@ -147,3 +147,17 @@
     assert issubclass(c_x , ctypes.Structure)
     assert issubclass(c_y, ctypes.Structure)
     assert c_y_fields["x"] is c_x
+
+def test_array():
+    dirent = ctypes_platform.getstruct("struct dirent",
+                                       """
+           struct dirent  /* for this example only, not the exact dirent */
+           {
+               long d_ino;
+               int d_off;
+               unsigned short d_reclen;
+               char d_name[32];
+           };
+                                       """,
+                                       [("d_name", ctypes.c_char * 0)])
+    assert dirent.d_name.size == 32



More information about the Pypy-commit mailing list