[pypy-commit] pypy ffi-backend: offsetof()

arigo noreply at buildbot.pypy.org
Sat Jun 23 17:22:45 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r55786:d6bdf5bed625
Date: 2012-06-23 17:22 +0200
http://bitbucket.org/pypy/pypy/changeset/d6bdf5bed625/

Log:	offsetof()

diff --git a/pypy/module/_ffi_backend/__init__.py b/pypy/module/_ffi_backend/__init__.py
--- a/pypy/module/_ffi_backend/__init__.py
+++ b/pypy/module/_ffi_backend/__init__.py
@@ -20,5 +20,6 @@
         'cast': 'func.cast',
         'sizeof': 'func.sizeof',
         'alignof': 'func.alignof',
+        'offsetof': 'func.offsetof',
         '_getfields': 'func._getfields',
         }
diff --git a/pypy/module/_ffi_backend/ctypeobj.py b/pypy/module/_ffi_backend/ctypeobj.py
--- a/pypy/module/_ffi_backend/ctypeobj.py
+++ b/pypy/module/_ffi_backend/ctypeobj.py
@@ -83,6 +83,11 @@
     def _alignof(self):
         xxx
 
+    def offsetof(self, fieldname):
+        space = self.space
+        raise OperationError(space.w_TypeError,
+                             space.wrap("not a struct or union ctype"))
+
     def _getfields(self):
         return None
 
@@ -402,11 +407,14 @@
         name = '%s %s' % (self.kind, name)
         W_CType.__init__(self, space, -1, name, len(name))
 
-    def _alignof(self):
-        space = self.space
-        if self.size < 0:
+    def check_complete(self):
+        if self.fields_dict is None:
+            space = self.space
             raise operationerrfmt(space.w_TypeError,
                                   "'%s' is not completed yet", self.name)
+
+    def _alignof(self):
+        self.check_complete()
         return self.alignment
 
     def _getfields(self):
@@ -422,12 +430,18 @@
 
     def convert_to_object(self, cdata):
         space = self.space
-        if self.size < 0:
-            raise operationerrfmt(space.w_TypeError,
-                                  "cannot return an incomplete cdata '%s'",
-                                  self.name)
+        self.check_complete()
         return cdataobj.W_CData(space, cdata, self)
 
+    def offsetof(self, fieldname):
+        self.check_complete()
+        try:
+            cfield = self.fields_dict[fieldname]
+        except KeyError:
+            space = self.space
+            raise OperationError(space.w_KeyError, space.wrap(fieldname))
+        return cfield.offset
+
 
 class W_CTypeStruct(W_CTypeStructOrUnion):
     kind = "struct"
diff --git a/pypy/module/_ffi_backend/func.py b/pypy/module/_ffi_backend/func.py
--- a/pypy/module/_ffi_backend/func.py
+++ b/pypy/module/_ffi_backend/func.py
@@ -41,6 +41,11 @@
     align = ctype.alignof()
     return space.wrap(align)
 
+ at unwrap_spec(ctype=ctypeobj.W_CType, fieldname=str)
+def offsetof(space, ctype, fieldname):
+    ofs = ctype.offsetof(fieldname)
+    return space.wrap(ofs)
+
 @unwrap_spec(ctype=ctypeobj.W_CType)
 def _getfields(space, ctype):
     return ctype._getfields()


More information about the pypy-commit mailing list