[pypy-svn] r46744 - in pypy/dist/pypy/rpython: lltypesystem lltypesystem/test tool

arigo at codespeak.net arigo at codespeak.net
Wed Sep 19 19:18:11 CEST 2007


Author: arigo
Date: Wed Sep 19 19:18:11 2007
New Revision: 46744

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rffi.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
   pypy/dist/pypy/rpython/tool/rffi_platform.py
Log:
Implement rffi.offsetof(), which tries to return a real number
for structures built by rffi_platform.


Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py	Wed Sep 19 19:18:11 2007
@@ -311,12 +311,16 @@
     return size, unsigned
 
 def sizeof(tp):
+    """Similar to llmemory.sizeof() but tries hard to return a integer
+    instead of a symbolic value.
+    """
     if isinstance(tp, lltype.FixedSizeArray):
         return sizeof(tp.OF) * tp.length
     if isinstance(tp, lltype.Struct):
         # the hint is present in structures probed by rffi_platform.
         size = tp._hints.get('size')
         if size is None:
+            from pypy.rpython.lltypesystem import llmemory
             size = llmemory.sizeof(tp)    # a symbolic result in this case
         return size
     if isinstance(tp, lltype.Ptr):
@@ -329,6 +333,23 @@
     if tp is lltype.Signed:
         return ULONG._type.BITS/8
     return tp._type.BITS/8
+_annspecialcase_ = 'specialize:memo'
+
+def offsetof(STRUCT, fieldname):
+    """Similar to llmemory.offsetof() but tries hard to return a integer
+    instead of a symbolic value.
+    """
+    # the hint is present in structures probed by rffi_platform.
+    fieldoffsets = STRUCT._hints.get('fieldoffsets')
+    if fieldoffsets is not None:
+        # a numeric result when known
+        for index, name in enumerate(STRUCT._names):
+            if name == fieldname:
+                return fieldoffsets[index]
+    # a symbolic result as a fallback
+    from pypy.rpython.lltypesystem import llmemory
+    return llmemory.offsetof(STRUCT, fieldname)
+_annspecialcase_ = 'specialize:memo'
 
 # ********************** some helpers *******************
 

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py	Wed Sep 19 19:18:11 2007
@@ -269,6 +269,23 @@
     assert not size_and_sign(lltype.Char)[1]
     assert size_and_sign(UINT)[1]
 
+def test_rffi_offsetof():
+    import struct
+    from pypy.rpython.tool import rffi_platform
+    S = rffi_platform.getstruct("struct S",
+                                  """
+           struct S {
+               short a;
+               int b, c;
+           };                     """,
+                                  [("a", INT),
+                                   ("b", INT),
+                                   ("c", INT)])
+    assert sizeof(S) == struct.calcsize("hii")
+    assert offsetof(S, "c_a") == 0
+    assert offsetof(S, "c_b") == struct.calcsize("hi") - struct.calcsize("i")
+    assert offsetof(S, "c_c") == struct.calcsize("hii") - struct.calcsize("i")
+
 def test_prebuild_constant():
     py.test.skip("WIP")
     h_source = py.code.Source("""

Modified: pypy/dist/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/rffi_platform.py	(original)
+++ pypy/dist/pypy/rpython/tool/rffi_platform.py	Wed Sep 19 19:18:11 2007
@@ -240,17 +240,20 @@
         # build the lltype Structure
         seen = {}
         fields = []
-        for cell in layout:
+        fieldoffsets = []
+        for offset, cell in enumerate(layout):
             if cell in seen:
                 continue
             fields.append((cell.name, cell.ctype))
+            fieldoffsets.append(offset)
             seen[cell] = True
 
         name = self.name
         if name.startswith('struct '):
             name = name[7:]
         kwds = {'hints':{'align':info['align'],
-                         'size':info['size']}}
+                         'size':info['size'],
+                         'fieldoffsets':tuple(fieldoffsets)}}
         return rffi.CStruct(name, *fields, **kwds)
 
 class SimpleType(CConfigEntry):



More information about the Pypy-commit mailing list