[pypy-commit] pypy reflex-support: allow int(0) and None to be passed as NULL through instance*
wlav
noreply at buildbot.pypy.org
Wed Sep 11 01:31:14 CEST 2013
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r66897:51089b1669b5
Date: 2013-09-10 15:55 -0700
http://bitbucket.org/pypy/pypy/changeset/51089b1669b5/
Log: allow int(0) and None to be passed as NULL through instance*
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,21 +47,22 @@
return rawobject
return capi.C_NULL_OBJECT
+def is_nullpointer_specialcase(space, w_obj):
+ # special case: allow integer 0 as (void*)0
+ try:
+ return space.int_w(w_obj) == 0
+ except Exception:
+ pass
+ # special case: allow None as (void*)0
+ return space.is_true(space.is_(w_obj, space.w_None))
+
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)):
+ if is_nullpointer_specialcase(space, w_obj):
return rffi.cast(rffi.VOIDP, 0)
raise TypeError("not an addressable buffer")
@@ -412,7 +413,7 @@
_immutable_fields_ = ['uses_local']
uses_local = True
-class InstancePtrConverter(TypeConverter):
+class InstanceRefConverter(TypeConverter):
_immutable_fields_ = ['libffitype', 'cppclass']
libffitype = jit_libffi.types.pointer
@@ -444,17 +445,7 @@
x = rffi.cast(rffi.VOIDPP, address)
x[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_obj))
- def from_memory(self, space, w_obj, w_pycppclass, offset):
- address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
- from pypy.module.cppyy import interp_cppyy
- return interp_cppyy.wrap_cppobject(space, address, self.cppclass,
- do_cast=False, is_ref=True)
-
- def to_memory(self, space, w_obj, w_value, offset):
- address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
- address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value))
-
-class InstanceConverter(InstancePtrConverter):
+class InstanceConverter(InstanceRefConverter):
def convert_argument_libffi(self, space, w_obj, address, call_local):
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
@@ -468,6 +459,28 @@
def to_memory(self, space, w_obj, w_value, offset):
self._is_abstract(space)
+
+class InstancePtrConverter(InstanceRefConverter):
+
+ def _unwrap_object(self, space, w_obj):
+ try:
+ return InstanceRefConverter._unwrap_object(self, space, w_obj)
+ except OperationError, e:
+ # if not instance, allow certain special cases
+ if is_nullpointer_specialcase(space, w_obj):
+ return capi.C_NULL_OBJECT
+ raise e
+
+ def from_memory(self, space, w_obj, w_pycppclass, offset):
+ address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
+ from pypy.module.cppyy import interp_cppyy
+ return interp_cppyy.wrap_cppobject(space, address, self.cppclass,
+ do_cast=False, is_ref=True)
+
+ def to_memory(self, space, w_obj, w_value, offset):
+ address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
+ address[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_value))
+
class InstancePtrPtrConverter(InstancePtrConverter):
_immutable_fields_ = ['uses_local']
@@ -487,12 +500,6 @@
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
raise FastCallNotPossible
- def from_memory(self, space, w_obj, w_pycppclass, offset):
- self._is_abstract(space)
-
- def to_memory(self, space, w_obj, w_value, offset):
- self._is_abstract(space)
-
def finalize_call(self, space, w_obj, call_local):
from pypy.module.cppyy.interp_cppyy import W_CPPInstance
assert isinstance(w_obj, W_CPPInstance)
@@ -628,8 +635,10 @@
# type check for the benefit of the annotator
from pypy.module.cppyy.interp_cppyy import W_CPPClass
cppclass = space.interp_w(W_CPPClass, cppclass, can_be_None=False)
- if compound == "*" or compound == "&":
+ if compound == "*":
return InstancePtrConverter(space, cppclass)
+ elif compound == "&":
+ return InstanceRefConverter(space, cppclass)
elif compound == "**":
return InstancePtrPtrConverter(space, cppclass)
elif compound == "":
diff --git a/pypy/module/cppyy/test/datatypes.cxx b/pypy/module/cppyy/test/datatypes.cxx
--- a/pypy/module/cppyy/test/datatypes.cxx
+++ b/pypy/module/cppyy/test/datatypes.cxx
@@ -119,10 +119,12 @@
double* cppyy_test_data::get_double_array2() { return m_double_array2; }
cppyy_test_pod cppyy_test_data::get_pod_val() { return m_pod; }
-cppyy_test_pod* cppyy_test_data::get_pod_ptr() { return &m_pod; }
-cppyy_test_pod& cppyy_test_data::get_pod_ref() { return m_pod; }
+cppyy_test_pod* cppyy_test_data::get_pod_val_ptr() { return &m_pod; }
+cppyy_test_pod& cppyy_test_data::get_pod_val_ref() { return m_pod; }
cppyy_test_pod*& cppyy_test_data::get_pod_ptrref() { return m_ppod; }
+cppyy_test_pod* cppyy_test_data::get_pod_ptr() { return m_ppod; }
+
//- setters -----------------------------------------------------------------
void cppyy_test_data::set_bool(bool b) { m_bool = b; }
void cppyy_test_data::set_char(char c) { m_char = c; }
@@ -159,6 +161,8 @@
void cppyy_test_data::set_pod_void_ptrptr_out(void** pp) { delete *((cppyy_test_pod**)pp);
*((cppyy_test_pod**)pp) = new cppyy_test_pod(m_pod); }
+void cppyy_test_data::set_pod_ptr(cppyy_test_pod* pp) { m_ppod = pp; }
+
//- passers -----------------------------------------------------------------
short* cppyy_test_data::pass_array(short* a) { return a; }
unsigned short* cppyy_test_data::pass_array(unsigned short* a) { return a; }
diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h
--- a/pypy/module/cppyy/test/datatypes.h
+++ b/pypy/module/cppyy/test/datatypes.h
@@ -89,11 +89,13 @@
double* get_double_array();
double* get_double_array2();
- cppyy_test_pod get_pod_val();
- cppyy_test_pod* get_pod_ptr();
- cppyy_test_pod& get_pod_ref();
+ cppyy_test_pod get_pod_val(); // for m_pod
+ cppyy_test_pod* get_pod_val_ptr();
+ cppyy_test_pod& get_pod_val_ref();
cppyy_test_pod*& get_pod_ptrref();
+ cppyy_test_pod* get_pod_ptr(); // for m_ppod
+
// setters
void set_bool(bool b);
void set_char(char c);
@@ -120,7 +122,7 @@
void set_double_c(const double& d);
void set_enum(what w);
- void set_pod_val(cppyy_test_pod);
+ void set_pod_val(cppyy_test_pod); // for m_pod
void set_pod_ptr_in(cppyy_test_pod*);
void set_pod_ptr_out(cppyy_test_pod*);
void set_pod_ref(const cppyy_test_pod&);
@@ -129,6 +131,8 @@
void set_pod_ptrptr_out(cppyy_test_pod**);
void set_pod_void_ptrptr_out(void**);
+ void set_pod_ptr(cppyy_test_pod*); // for m_ppod
+
// passers
short* pass_array(short*);
unsigned short* pass_array(unsigned short*);
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
@@ -514,15 +514,15 @@
assert pod.m_int == 888
assert pod.m_double == 3.14
- assert c.get_pod_ptr().m_int == 888
- assert c.get_pod_ptr().m_double == 3.14
- c.get_pod_ptr().m_int = 777
- assert c.get_pod_ptr().m_int == 777
+ assert c.get_pod_val_ptr().m_int == 888
+ assert c.get_pod_val_ptr().m_double == 3.14
+ c.get_pod_val_ptr().m_int = 777
+ assert c.get_pod_val_ptr().m_int == 777
- assert c.get_pod_ref().m_int == 777
- assert c.get_pod_ref().m_double == 3.14
- c.get_pod_ref().m_int = 666
- assert c.get_pod_ref().m_int == 666
+ assert c.get_pod_val_ref().m_int == 777
+ assert c.get_pod_val_ref().m_double == 3.14
+ c.get_pod_val_ref().m_int = 666
+ assert c.get_pod_val_ref().m_int == 666
assert c.get_pod_ptrref().m_int == 666
assert c.get_pod_ptrref().m_double == 3.14
@@ -595,7 +595,22 @@
assert p.m_int == 888
assert p.m_double == 3.14
- def test16_respect_privacy(self):
+ def test16_nullptr_passing(self):
+ """Integer 0 ('NULL') and None allowed to pass through instance*"""
+
+ import cppyy
+
+ for o in (0, None):
+ c = cppyy.gbl.cppyy_test_data()
+ assert c.m_pod.m_int == 888
+ assert c.m_pod.m_double == 3.14
+ assert not not c.m_ppod
+
+ c.set_pod_ptr(o)
+ assert not c.m_ppod
+ assert not c.get_pod_ptr()
+
+ def test17_respect_privacy(self):
"""Test that privacy settings are respected"""
import cppyy
@@ -608,7 +623,7 @@
c.destruct()
- def test17_object_and_pointer_comparisons(self):
+ def test18_object_and_pointer_comparisons(self):
"""Verify object and pointer comparisons"""
import cppyy
@@ -645,7 +660,7 @@
assert l3 != l5
assert l5 != l3
- def test18_object_validity(self):
+ def test19_object_validity(self):
"""Test object validity checking"""
from cppyy import gbl
@@ -659,7 +674,7 @@
assert not d2
- def test19_buffer_reshaping(self):
+ def test20_buffer_reshaping(self):
"""Test usage of buffer sizing"""
import cppyy
More information about the pypy-commit
mailing list