[pypy-commit] pypy cffi-1.0: ffi.offsetof(), and improve JITting of ffi.addressof()
arigo
noreply at buildbot.pypy.org
Fri May 8 15:23:05 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r77209:8319d5c0a983
Date: 2015-05-08 15:23 +0200
http://bitbucket.org/pypy/pypy/changeset/8319d5c0a983/
Log: ffi.offsetof(), and improve JITting of ffi.addressof()
diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -88,6 +88,14 @@
cerrno.set_errno(space, space.c_int_w(errno))
+ def _more_addressof(self, args_w, w_ctype):
+ # contains a loop, the JIT doesn't look inside this helper
+ offset = 0
+ for i in range(len(args_w)):
+ w_ctype, ofs1 = w_ctype.direct_typeoffsetof(args_w[i], i > 0)
+ offset += ofs1
+ return w_ctype, offset
+
def descr_addressof(self, w_arg, args_w):
"""\
With a single arg, return the address of a <cdata 'struct-or-union'>.
@@ -97,21 +105,22 @@
#
w_ctype = self.ffi_type(w_arg, ACCEPT_CDATA)
space = self.space
- offset = 0
if len(args_w) == 0:
if (not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion) and
not isinstance(w_ctype, ctypearray.W_CTypeArray)):
raise oefmt(space.w_TypeError,
"expected a cdata struct/union/array object")
+ offset = 0
else:
if (not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion) and
not isinstance(w_ctype, ctypearray.W_CTypeArray) and
not isinstance(w_ctype, ctypeptr.W_CTypePointer)):
raise oefmt(space.w_TypeError,
"expected a cdata struct/union/array/pointer object")
- for i in range(len(args_w)):
- w_ctype, ofs1 = w_ctype.direct_typeoffsetof(args_w[i], i > 0)
- offset += ofs1
+ if len(args_w) == 1:
+ w_ctype, offset = w_ctype.direct_typeoffsetof(args_w[0], False)
+ else:
+ w_ctype, offset = self._more_addressof(args_w, w_ctype)
#
assert isinstance(w_arg, W_CData)
cdata = w_arg.unsafe_escaping_ptr()
@@ -244,6 +253,29 @@
return handle._newp_handle(space, newtype.new_voidp_type(space), w_arg)
+ def _more_offsetof(self, w_ctype, w_arg0, args_w):
+ # contains a loop, the JIT doesn't look inside this helper
+ w_ctype, offset = w_ctype.direct_typeoffsetof(w_arg0, False)
+ for i in range(len(args_w)):
+ w_ctype, ofs1 = w_ctype.direct_typeoffsetof(args_w[i], True)
+ offset += ofs1
+ return offset
+
+ def descr_offsetof(self, w_arg, w_field_or_array, args_w):
+ """\
+Return the offset of the named field inside the given structure or
+array, which must be given as a C type name. You can give several
+field names in case of nested structures. You can also give numeric
+values which correspond to array items, in case of an array type."""
+ #
+ w_ctype = self.ffi_type(w_arg, ACCEPT_STRING | ACCEPT_CTYPE)
+ if len(args_w) == 0:
+ _, offset = w_ctype.direct_typeoffsetof(w_field_or_array, False)
+ else:
+ offset = self._more_offsetof(w_ctype, w_field_or_array, args_w)
+ return self.space.wrap(offset)
+
+
@unwrap_spec(w_cdata=W_CData, maxlen=int)
def descr_string(self, w_cdata, maxlen=-1):
"""\
@@ -322,6 +354,7 @@
getctype = interp2app(W_FFIObject.descr_getctype),
new = interp2app(W_FFIObject.descr_new),
new_handle = interp2app(W_FFIObject.descr_new_handle),
+ offsetof = interp2app(W_FFIObject.descr_offsetof),
sizeof = interp2app(W_FFIObject.descr_sizeof),
string = interp2app(W_FFIObject.descr_string),
typeof = interp2app(W_FFIObject.descr_typeof),
More information about the pypy-commit
mailing list