Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r56242:d57f7dde9e95
Date: 2012-07-19 13:49 -0700
http://bitbucket.org/pypy/pypy/changeset/d57f7dde9e95/
Log: NULL and 0 passing through typed pointers
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -47,6 +47,24 @@
return rawobject
return capi.C_NULL_OBJECT
+def get_rawbuffer(space, w_obj):
+ try:
+ buf = space.buffer_w(w_obj)
+ return rffi.cast(rffi.VOIDP, buf.get_raw_address())
+ except Exception:
+ pass
+ # special case: allow integer 0 as NULL
+ try:
+ buf = space.int_w(w_obj)
+ if buf == 0:
+ return rffi.cast(rffi.VOIDP, 0)
+ except Exception:
+ pass
+ # special case: allow None as NULL
+ if space.is_true(space.is_(w_obj, space.w_None)):
+ return rffi.cast(rffi.VOIDP, 0)
+ raise TypeError("not an addressable buffer")
+
class TypeConverter(object):
_immutable_ = True
@@ -146,16 +164,13 @@
def convert_argument(self, space, w_obj, address, call_local):
w_tc = space.findattr(w_obj, space.wrap('typecode'))
- if w_tc is None:
- raise OperationError(space.w_TypeError, space.wrap("can not
determine buffer type"))
- if space.str_w(w_tc) != self.typecode:
+ if w_tc is not None and space.str_w(w_tc) != self.typecode:
msg = "expected %s pointer type, but received %s" %
(self.typecode, space.str_w(w_tc))
raise OperationError(space.w_TypeError, space.wrap(msg))
x = rffi.cast(rffi.LONGP, address)
- buf = space.buffer_w(w_obj)
try:
- x[0] = rffi.cast(rffi.LONG, buf.get_raw_address())
- except ValueError:
+ x[0] = rffi.cast(rffi.LONG, get_rawbuffer(space, w_obj))
+ except TypeError:
raise OperationError(space.w_TypeError,
space.wrap("raw buffer interface not
supported"))
ba = rffi.cast(rffi.CCHARP, address)
@@ -351,9 +366,8 @@
x = rffi.cast(rffi.VOIDPP, address)
ba = rffi.cast(rffi.CCHARP, address)
try:
- buf = space.buffer_w(w_obj)
- x[0] = rffi.cast(rffi.VOIDP, buf.get_raw_address())
- except (OperationError, ValueError), e:
+ x[0] = get_rawbuffer(space, w_obj)
+ except TypeError:
x[0] = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
ba[capi.c_function_arg_typeoffset()] = 'o'
@@ -369,9 +383,8 @@
ba = rffi.cast(rffi.CCHARP, address)
r = rffi.cast(rffi.VOIDPP, call_local)
try:
- buf = space.buffer_w(w_obj)
- r[0] = rffi.cast(rffi.VOIDP, buf.get_raw_address())
- except (OperationError, ValueError), e:
+ r[0] = get_rawbuffer(space, w_obj)
+ except TypeError:
r[0] = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
x[0] = rffi.cast(rffi.VOIDP, call_local)
ba[capi.c_function_arg_typeoffset()] = 'a'
@@ -381,7 +394,7 @@
try:
set_rawobject(space, w_obj, r[0])
except OperationError:
- pass # no set on buffer/array
+ pass # no set on buffer/array/None
class VoidPtrRefConverter(TypeConverter):
_immutable_ = True
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -6,7 +6,7 @@
from pypy.rlib import libffi, clibffi
from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
-from pypy.module._rawffi.array import W_Array
+from pypy.module._rawffi.array import W_Array, W_ArrayInstance
from pypy.module.cppyy import helper, capi, ffitypes
@@ -52,6 +52,14 @@
lresult = capi.c_call_l(cppmethod, cppthis, num_args, args)
address = rffi.cast(rffi.ULONG, lresult)
arr = space.interp_w(W_Array, unpack_simple_shape(space,
space.wrap(self.typecode)))
+ if address == 0:
+ # TODO: fix this hack; fromaddress() will allocate memory if
address
+ # is null and there seems to be no way around it (ll_buffer can not
+ # be touched directly)
+ nullarr = arr.fromaddress(space, address, 0)
+ assert isinstance(nullarr, W_ArrayInstance)
+ nullarr.free(space)
+ return nullarr
return arr.fromaddress(space, address, sys.maxint)
diff --git a/pypy/module/cppyy/test/test_advancedcpp.py
b/pypy/module/cppyy/test/test_advancedcpp.py
--- a/pypy/module/cppyy/test/test_advancedcpp.py
+++ b/pypy/module/cppyy/test/test_advancedcpp.py
@@ -387,6 +387,9 @@
addressofo = array.array('l', [cppyy.addressof(o)])
assert addressofo.buffer_info()[0] ==
pp.gime_address_ptr_ptr(addressofo)
+ assert 0 == pp.gime_address_ptr(0)
+ assert 0 == pp.gime_address_ptr(None)
+
def test09_opaque_pointer_assing(self):
"""Test passing around of opaque pointers"""
diff --git a/pypy/module/cppyy/test/test_datatypes.py
b/pypy/module/cppyy/test/test_datatypes.py
--- a/pypy/module/cppyy/test/test_datatypes.py
+++ b/pypy/module/cppyy/test/test_datatypes.py
@@ -5,7 +5,7 @@
currpath = py.path.local(__file__).dirpath()
test_dct = str(currpath.join("datatypesDict.so"))
-space = gettestobjspace(usemodules=['cppyy', 'array'])
+space = gettestobjspace(usemodules=['cppyy', 'array', '_rawffi'])
def setup_module(mod):
if sys.platform == 'win32':
@@ -226,6 +226,12 @@
for i in range(self.N):
assert ca[i] == b[i]
+ # NULL/None passing (will use short*)
+ assert not c.pass_array(0)
+ raises(Exception, c.pass_array(0).__getitem__, 0) # raises
SegfaultException
+ assert not c.pass_array(None)
+ raises(Exception, c.pass_array(None).__getitem__, 0) # id.
+
c.destruct()
def test05_class_read_access(self):
diff --git a/pypy/module/cppyy/test/test_zjit.py
b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -155,10 +155,16 @@
r_longlong_w = int_w
r_ulonglong_w = uint_w
+ def is_(self, w_obj1, w_obj2):
+ return w_obj1 is w_obj2
+
def isinstance_w(self, w_obj, w_type):
assert isinstance(w_obj, FakeBase)
return w_obj.typename == w_type.name
+ def is_true(self, w_obj):
+ return not not w_obj
+
def type(self, w_obj):
return FakeType("fake")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit