[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