[pypy-commit] pypy default: PyPy support for CFFI up to 9dd27fd230ca.
arigo
noreply at buildbot.pypy.org
Wed Sep 19 01:03:04 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r57378:2de6f6527347
Date: 2012-09-19 01:02 +0200
http://bitbucket.org/pypy/pypy/changeset/2de6f6527347/
Log: PyPy support for CFFI up to 9dd27fd230ca.
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -27,7 +27,8 @@
'alignof': 'func.alignof',
'sizeof': 'func.sizeof',
'typeof': 'func.typeof',
- 'offsetof': 'func.offsetof',
+ 'typeoffsetof': 'func.typeoffsetof',
+ 'rawaddressof': 'func.rawaddressof',
'_getfields': 'func._getfields',
'getcname': 'func.getcname',
'_get_types': 'func._get_types',
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -134,7 +134,7 @@
"ctype '%s' is of unknown alignment",
self.name)
- def offsetof(self, fieldname):
+ def typeoffsetof(self, fieldname):
space = self.space
raise OperationError(space.w_TypeError,
space.wrap("not a struct or union ctype"))
@@ -142,6 +142,11 @@
def _getfields(self):
return None
+ def rawaddressof(self, cdata, offset):
+ space = self.space
+ raise OperationError(space.w_TypeError,
+ space.wrap("expected a pointer ctype"))
+
def call(self, funcaddr, args_w):
space = self.space
raise operationerrfmt(space.w_TypeError,
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -274,18 +274,26 @@
return True
else:
set_mustfree_flag(cdata, False)
- try:
- self.convert_from_object(cdata, w_ob)
- except OperationError:
- if (self.is_struct_ptr and isinstance(ob, cdataobj.W_CData)
- and ob.ctype is self.ctitem):
- # special case to make the life of verifier.py easier:
- # if the formal argument type is 'struct foo *' but
- # we pass a 'struct foo', then get a pointer to it
- rffi.cast(rffi.CCHARPP, cdata)[0] = ob._cdata
- else:
- raise
+ self.convert_from_object(cdata, w_ob)
return False
def getcfield(self, attr):
return self.ctitem.getcfield(attr)
+
+ def typeoffsetof(self, fieldname):
+ if fieldname is None:
+ return W_CTypePtrBase.typeoffsetof(self, fieldname)
+ else:
+ return self.ctitem.typeoffsetof(fieldname)
+
+ def rawaddressof(self, cdata, offset):
+ from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion
+ space = self.space
+ ctype2 = cdata.ctype
+ if (isinstance(ctype2, W_CTypeStructOrUnion) or
+ (isinstance(ctype2, W_CTypePtrOrArray) and ctype2.is_struct_ptr)):
+ ptrdata = rffi.ptradd(cdata._cdata, offset)
+ return cdataobj.W_CData(space, ptrdata, self)
+ else:
+ raise OperationError(space.w_TypeError,
+ space.wrap("expected a 'cdata struct-or-union' object"))
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -61,14 +61,19 @@
keepalive_until_here(ob)
return ob
- def offsetof(self, fieldname):
+ def typeoffsetof(self, fieldname):
+ if fieldname is None:
+ return (self, 0)
self.check_complete()
+ space = self.space
try:
cfield = self.fields_dict[fieldname]
except KeyError:
- space = self.space
raise OperationError(space.w_KeyError, space.wrap(fieldname))
- return cfield.offset
+ if cfield.bitshift >= 0:
+ raise OperationError(space.w_TypeError,
+ space.wrap("not supported for bitfields"))
+ return (cfield.ctype, cfield.offset)
def _copy_from_same(self, cdata, w_ob):
space = self.space
diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py
--- a/pypy/module/_cffi_backend/func.py
+++ b/pypy/module/_cffi_backend/func.py
@@ -53,15 +53,19 @@
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)
+ at unwrap_spec(ctype=ctypeobj.W_CType, fieldname="str_or_None")
+def typeoffsetof(space, ctype, fieldname):
+ ctype, offset = ctype.typeoffsetof(fieldname)
+ return space.newtuple([space.wrap(ctype), space.wrap(offset)])
@unwrap_spec(ctype=ctypeobj.W_CType)
def _getfields(space, ctype):
return ctype._getfields()
+ at unwrap_spec(ctype=ctypeobj.W_CType, cdata=cdataobj.W_CData, offset=int)
+def rawaddressof(space, ctype, cdata, offset=0):
+ return ctype.rawaddressof(cdata, offset)
+
# ____________________________________________________________
@unwrap_spec(ctype=ctypeobj.W_CType, replace_with=str)
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -741,6 +741,8 @@
assert repr(s.a1).startswith("<cdata 'int[5]' 0x")
def test_offsetof():
+ def offsetof(BType, fieldname):
+ return typeoffsetof(BType, fieldname)[1]
BInt = new_primitive_type("int")
BStruct = new_struct_type("foo")
py.test.raises(TypeError, offsetof, BInt, "abc")
@@ -749,6 +751,7 @@
assert offsetof(BStruct, 'abc') == 0
assert offsetof(BStruct, 'def') == size_of_int()
py.test.raises(KeyError, offsetof, BStruct, "ghi")
+ assert offsetof(new_pointer_type(BStruct), "def") == size_of_int()
def test_function_type():
BInt = new_primitive_type("int")
@@ -888,11 +891,8 @@
BFunc20 = new_function_type((BStructPtr,), BShort, False)
f = cast(BFunc20, _testfunc(20))
x = newp(BStructPtr, {'a1': b'A', 'a2': -4042})
- # test the exception that allows us to pass a 'struct foo' where the
- # function really expects a 'struct foo *'.
- res = f(x[0])
- assert res == -4042 + ord(b'A')
- assert res == f(x)
+ # can't pass a 'struct foo'
+ py.test.raises(TypeError, f, x[0])
def test_call_function_21():
BInt = new_primitive_type("int")
@@ -2115,3 +2115,49 @@
BDouble = new_primitive_type("double")
assert int(cast(BBool, cast(BDouble, 0.1))) == 1
assert int(cast(BBool, cast(BDouble, 0.0))) == 0
+
+def test_typeoffsetof():
+ BChar = new_primitive_type("char")
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BChar, -1),
+ ('a2', BChar, -1),
+ ('a3', BChar, -1)])
+ py.test.raises(TypeError, typeoffsetof, BStructPtr, None)
+ assert typeoffsetof(BStruct, None) == (BStruct, 0)
+ assert typeoffsetof(BStructPtr, 'a1') == (BChar, 0)
+ assert typeoffsetof(BStruct, 'a1') == (BChar, 0)
+ assert typeoffsetof(BStructPtr, 'a2') == (BChar, 1)
+ assert typeoffsetof(BStruct, 'a3') == (BChar, 2)
+ py.test.raises(KeyError, typeoffsetof, BStructPtr, 'a4')
+ py.test.raises(KeyError, typeoffsetof, BStruct, 'a5')
+
+def test_typeoffsetof_no_bitfield():
+ BInt = new_primitive_type("int")
+ BStruct = new_struct_type("foo")
+ complete_struct_or_union(BStruct, [('a1', BInt, 4)])
+ py.test.raises(TypeError, typeoffsetof, BStruct, 'a1')
+
+def test_rawaddressof():
+ BChar = new_primitive_type("char")
+ BCharP = new_pointer_type(BChar)
+ BStruct = new_struct_type("foo")
+ BStructPtr = new_pointer_type(BStruct)
+ complete_struct_or_union(BStruct, [('a1', BChar, -1),
+ ('a2', BChar, -1),
+ ('a3', BChar, -1)])
+ p = newp(BStructPtr)
+ assert repr(p) == "<cdata 'struct foo *' owning 3 bytes>"
+ s = p[0]
+ assert repr(s) == "<cdata 'struct foo' owning 3 bytes>"
+ a = rawaddressof(BStructPtr, s)
+ assert repr(a).startswith("<cdata 'struct foo *' 0x")
+ py.test.raises(TypeError, rawaddressof, BStruct, s)
+ b = rawaddressof(BCharP, s)
+ assert b == cast(BCharP, p)
+ c = rawaddressof(BStructPtr, a)
+ assert c == a
+ py.test.raises(TypeError, rawaddressof, BStructPtr, cast(BChar, '?'))
+ #
+ d = rawaddressof(BCharP, s, 1)
+ assert d == cast(BCharP, p) + 1
More information about the pypy-commit
mailing list