[pypy-svn] r76827 - in pypy/branch/reflex-support/pypy/module/cppyy: . test
wlav at codespeak.net
wlav at codespeak.net
Thu Sep 2 02:20:21 CEST 2010
Author: wlav
Date: Thu Sep 2 02:20:18 2010
New Revision: 76827
Modified:
pypy/branch/reflex-support/pypy/module/cppyy/converter.py
pypy/branch/reflex-support/pypy/module/cppyy/executor.py
pypy/branch/reflex-support/pypy/module/cppyy/helper.py
pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h
pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py
pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py
Log:
Initial implementation for passing short int arrays.
Modified: pypy/branch/reflex-support/pypy/module/cppyy/converter.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/converter.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/converter.py Thu Sep 2 02:20:18 2010
@@ -3,6 +3,8 @@
from pypy.rlib.rarithmetic import r_singlefloat
from pypy.objspace.std.intobject import W_IntObject
+from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
+
from pypy.module.cppyy import helper, capi
_converters = {}
@@ -166,6 +168,41 @@
return rffi.cast(rffi.VOIDP, x)
+class ShortPtrConverter(TypeConverter):
+ _immutable_ = True
+ def __init__(self, detail=None):
+ if detail is None:
+ import sys
+ detail = sys.maxint
+ self.size = detail
+
+ def convert_argument(self, space, w_obj):
+ assert "not yet implemented"
+
+ def from_memory(self, space, w_obj, offset):
+ # read access, so no copy needed
+ fieldptr = self._get_fieldptr(space, w_obj, offset)
+ shortptr = rffi.cast(rffi.SHORTP, fieldptr)
+ w_array = unpack_simple_shape(space, space.wrap('h'))
+ return w_array.fromaddress(space, shortptr, self.size)
+
+ def to_memory(self, space, w_obj, w_value, offset):
+ # copy only the pointer value
+ obj = space.interpclass_w(space.findattr(w_obj, space.wrap("_cppinstance")))
+ byteptr = rffi.cast(rffi.LONGP, obj.rawobject[offset])
+ # TODO: now what ... ?? AFAICS, w_value is a pure python list, not an array?
+# byteptr[0] = space.unwrap(space.id(w_value.getslotvalue(2)))
+
+
+class ShortArrayConverter(ShortPtrConverter):
+ def to_memory(self, space, w_obj, w_value, offset):
+ # copy the full array (uses byte copy for now)
+ fieldptr = self._get_fieldptr(space, w_obj, offset)
+ value = w_value.getslotvalue(2)
+ for i in range(min(self.size*2, value.getlength())):
+ fieldptr[i] = value.getitem(i)
+
+
class InstancePtrConverter(TypeConverter):
_immutable_ = True
def __init__(self, space, cpptype):
@@ -199,13 +236,23 @@
# 5) generalized cases (covers basically all user classes)
# 6) void converter, which fails on use
+ # 1) full, exact match
try:
- return _converters[name]
+ return _converters[name]()
except KeyError:
pass
- compound = helper.compound(name)
- cpptype = interp_cppyy.type_byname(space, helper.clean_type(name))
+ # 2) match of decorated, unqualified type
+ compound, detail = helper.compound(name)
+ clean_name = helper.clean_type(name)
+ try:
+ if detail:
+ return _converters[clean_name+compound](detail)
+ return _converters[clean_name+compound]()
+ except KeyError:
+ pass
+
+ cpptype = interp_cppyy.type_byname(space, clean_name)
if compound == "*":
return InstancePtrConverter(space, cpptype)
@@ -214,15 +261,17 @@
return VoidConverter(space, name)
-_converters["bool"] = BoolConverter()
-_converters["char"] = CharConverter()
-_converters["unsigned char"] = CharConverter()
-_converters["short int"] = ShortConverter()
-_converters["unsigned short int"] = ShortConverter()
-_converters["int"] = LongConverter()
-_converters["unsigned int"] = LongConverter()
-_converters["long int"] = LongConverter()
-_converters["unsigned long int"] = LongConverter()
-_converters["float"] = FloatConverter()
-_converters["double"] = DoubleConverter()
-_converters["const char*"] = CStringConverter()
+_converters["bool"] = BoolConverter
+_converters["char"] = CharConverter
+_converters["unsigned char"] = CharConverter
+_converters["short int"] = ShortConverter
+_converters["short int*"] = ShortPtrConverter
+_converters["short int[]"] = ShortArrayConverter
+_converters["unsigned short int"] = ShortConverter
+_converters["int"] = LongConverter
+_converters["unsigned int"] = LongConverter
+_converters["long int"] = LongConverter
+_converters["unsigned long int"] = LongConverter
+_converters["float"] = FloatConverter
+_converters["double"] = DoubleConverter
+_converters["const char*"] = CStringConverter
Modified: pypy/branch/reflex-support/pypy/module/cppyy/executor.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/executor.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/executor.py Thu Sep 2 02:20:18 2010
@@ -75,7 +75,7 @@
except KeyError:
pass
- compound = helper.compound(name)
+ compound, detail = helper.compound(name)
cpptype = interp_cppyy.type_byname(space, helper.clean_type(name))
if compound == "*":
return InstancePtrExecutor(space, cpptype)
Modified: pypy/branch/reflex-support/pypy/module/cppyy/helper.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/helper.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/helper.py Thu Sep 2 02:20:18 2010
@@ -4,8 +4,11 @@
name = "".join(rstring.split(name, "const")) # poor man's replace
i = _find_qualifier_index(name)
if name[-1] == "]": # array type
- return "*"
- return "".join(name[i:].split(" "))
+ for i in range(len(name) - 1, -1, -1):
+ c = name[i]
+ if c == "[":
+ return "[]", int(name[i+1:-1])
+ return "".join(name[i:].split(" ")), None
def _find_qualifier_index(name):
i = len(name)
Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/datatypes.h Thu Sep 2 02:20:18 2010
@@ -14,6 +14,9 @@
cppyy_test_data();
~cppyy_test_data();
+// helper
+ void destroy_arrays();
+
// getters
bool get_bool();
char get_char();
@@ -107,9 +110,6 @@
static double s_double;
private:
- void destroy_arrays();
-
-private:
bool m_owns_arrays;
};
Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py Thu Sep 2 02:20:18 2010
@@ -16,11 +16,10 @@
raise OSError("'make' failed (see stderr)")
class AppTestDATATYPES:
- N = 5 # should be imported from the dictionary
-
def setup_class(cls):
cls.space = space
env = os.environ
+ cls.w_N = space.wrap(5) # should be imported from the dictionary
cls.w_shared_lib = space.wrap(shared_lib)
cls.w_datatypes = cls.space.appexec([], """():
import cppyy
@@ -93,23 +92,22 @@
c.m_double = 0.456; assert round(c.get_double() - 0.456, 8) == 0
c.set_double( 0.567 ); assert round(c.m_double - 0.567, 8) == 0
- """
# arrays; there will be pointer copies, so destroy the current ones
c.destroy_arrays()
# integer arrays
- a = range(N)
- atypes = [ 'h', 'H', 'i', 'I', 'l', 'L' ]
- for j in range(len(names)):
- b = array(atypes[j], a)
+ import array
+ a = range(self.N)
+ atypes = [ 'h' ] #, 'H', 'i', 'I', 'l', 'L' ]
+ for j in range(len(atypes)):#names)):
+ b = array.array(atypes[j], a)
exec 'c.m_%s_array = b' % names[j] # buffer copies
- for i in range(N):
+ for i in range(self.N):
assert eval('c.m_%s_array[i]' % names[j]) == b[i]
- exec 'c.m_%s_array2 = b' % names[j] # pointer copies
- b[i] = 28
- for i in range(N):
- assert eval('c.m_%s_array2[i]' % names[j]) == b[i]
- """
+# exec 'c.m_%s_array2 = b' % names[j] # pointer copies
+# b[i] = 28
+# for i in range(self.N):
+# assert eval('c.m_%s_array2[i]' % names[j]) == b[i]
c.destruct()
Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_helper.py Thu Sep 2 02:20:18 2010
@@ -1,11 +1,13 @@
from pypy.module.cppyy import helper
def test_compound():
- assert helper.compound("int*") == "*"
- assert helper.compound("int* const *&") == "**&"
- assert helper.compound("std::vector<int>*") == "*"
+ assert helper.compound("int*") == ("*", None)
+ assert helper.compound("int* const *&") == ("**&", None)
+ assert helper.compound("std::vector<int>*") == ("*", None)
+ assert helper.compound("unsigned long int[5]") == ("[]", 5)
def test_clean_type():
assert helper.clean_type(" int***") == "int"
assert helper.clean_type("std::vector<int>&") == "std::vector<int>"
+ assert helper.clean_type("unsigned short int[3]") == "unsigned short int"
More information about the Pypy-commit
mailing list