Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r54323:1ea1ba708588
Date: 2012-04-12 20:43 -0700
http://bitbucket.org/pypy/pypy/changeset/1ea1ba708588/
Log: const ref only worked b/c it didn't; 2nd attempt with explicit tests
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
@@ -150,26 +150,39 @@
def convert_argument_libffi(self, space, w_obj, argchain):
argchain.arg(self._unwrap_object(space, w_obj))
+ return lltype.nullptr(rffi.VOIDP.TO)
def default_argument_libffi(self, space, argchain):
argchain.arg(self.default)
def from_memory(self, space, w_obj, w_pycppclass, offset):
address = self._get_raw_address(space, w_obj, offset)
- rffiptr = rffi.cast(self.rffiptype, address)
+ rffiptr = rffi.cast(self.c_ptrtype, address)
return space.wrap(rffiptr[0])
def to_memory(self, space, w_obj, w_value, offset):
address = self._get_raw_address(space, w_obj, offset)
- rffiptr = rffi.cast(self.rffiptype, address)
+ rffiptr = rffi.cast(self.c_ptrtype, address)
rffiptr[0] = self._unwrap_object(space, w_value)
+class ConstRefNumericTypeConverterMixin(NumericTypeConverterMixin):
+ _mixin_ = True
+ _immutable_ = True
+
+ def convert_argument_libffi(self, space, w_obj, argchain):
+ obj = self._unwrap_object(space, w_obj)
+ tbuf = lltype.malloc(self.c_ptrtype.TO, rffi.sizeof(self.c_type),
flavor='raw')
+ tbuf[0] = obj
+ vbuf = rffi.cast(rffi.VOIDP, tbuf)
+ argchain.arg(vbuf)
+ return vbuf
+
class IntTypeConverterMixin(NumericTypeConverterMixin):
_mixin_ = True
_immutable_ = True
def convert_argument(self, space, w_obj, address):
- x = rffi.cast(self.rffiptype, address)
+ x = rffi.cast(self.c_ptrtype, address)
x[0] = self._unwrap_object(space, w_obj)
class FloatTypeConverterMixin(NumericTypeConverterMixin):
@@ -177,7 +190,7 @@
_immutable_ = True
def convert_argument(self, space, w_obj, address):
- x = rffi.cast(self.rffiptype, address)
+ x = rffi.cast(self.c_ptrtype, address)
x[0] = self._unwrap_object(space, w_obj)
ba = rffi.cast(rffi.CCHARP, address)
ba[capi.c_function_arg_typeoffset()] = self.typecode
@@ -212,6 +225,7 @@
def convert_argument_libffi(self, space, w_obj, argchain):
argchain.arg(self._unwrap_object(space, w_obj))
+ return lltype.nullptr(rffi.VOIDP.TO)
def from_memory(self, space, w_obj, w_pycppclass, offset):
address = rffi.cast(rffi.CCHARP, self._get_raw_address(space, w_obj,
offset))
@@ -254,6 +268,7 @@
def convert_argument_libffi(self, space, w_obj, argchain):
argchain.arg(self._unwrap_object(space, w_obj))
+ return lltype.nullptr(rffi.VOIDP.TO)
def from_memory(self, space, w_obj, w_pycppclass, offset):
address = rffi.cast(rffi.CCHARP, self._get_raw_address(space, w_obj,
offset))
@@ -267,7 +282,8 @@
class ShortConverter(IntTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.sshort
- rffiptype = rffi.SHORTP
+ c_type = rffi.SHORT
+ c_ptrtype = rffi.SHORTP
def __init__(self, space, default):
self.default = rffi.cast(rffi.SHORT, capi.c_strtoll(default))
@@ -275,73 +291,77 @@
def _unwrap_object(self, space, w_obj):
return rffi.cast(rffi.SHORT, space.int_w(w_obj))
-class ConstShortRefConverter(ShortConverter):
+class ConstShortRefConverter(ConstRefNumericTypeConverterMixin,
ShortConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
class UnsignedShortConverter(IntTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.sshort
- rffiptype = rffi.USHORTP
+ c_type = rffi.USHORT
+ c_ptrtype = rffi.USHORTP
def __init__(self, space, default):
- self.default = rffi.cast(rffi.USHORT, capi.c_strtoull(default))
+ self.default = rffi.cast(self.c_type, capi.c_strtoull(default))
def _unwrap_object(self, space, w_obj):
- return rffi.cast(rffi.USHORT, space.int_w(w_obj))
+ return rffi.cast(self.c_type, space.int_w(w_obj))
-class ConstUnsignedShortRefConverter(UnsignedShortConverter):
+class ConstUnsignedShortRefConverter(ConstRefNumericTypeConverterMixin,
UnsignedShortConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
class IntConverter(IntTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.sint
- rffiptype = rffi.INTP
+ c_type = rffi.INT
+ c_ptrtype = rffi.INTP
def __init__(self, space, default):
- self.default = rffi.cast(rffi.INT, capi.c_strtoll(default))
+ self.default = rffi.cast(self.c_type, capi.c_strtoll(default))
def _unwrap_object(self, space, w_obj):
- return rffi.cast(rffi.INT, space.c_int_w(w_obj))
+ return rffi.cast(self.c_type, space.c_int_w(w_obj))
-class ConstIntRefConverter(IntConverter):
+class ConstIntRefConverter(ConstRefNumericTypeConverterMixin, IntConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
class UnsignedIntConverter(IntTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.uint
- rffiptype = rffi.UINTP
+ c_type = rffi.UINT
+ c_ptrtype = rffi.UINTP
def __init__(self, space, default):
- self.default = rffi.cast(rffi.UINT, capi.c_strtoull(default))
+ self.default = rffi.cast(self.c_type, capi.c_strtoull(default))
def _unwrap_object(self, space, w_obj):
- return rffi.cast(rffi.UINT, space.uint_w(w_obj))
+ return rffi.cast(self.c_type, space.uint_w(w_obj))
-class ConstUnsignedIntRefConverter(UnsignedIntConverter):
+class ConstUnsignedIntRefConverter(ConstRefNumericTypeConverterMixin,
UnsignedIntConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
class LongConverter(IntTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.slong
- rffiptype = rffi.LONGP
+ c_type = rffi.LONG
+ c_ptrtype = rffi.LONGP
def __init__(self, space, default):
- self.default = rffi.cast(rffi.LONG, capi.c_strtoll(default))
+ self.default = rffi.cast(self.c_type, capi.c_strtoll(default))
def _unwrap_object(self, space, w_obj):
return space.int_w(w_obj)
-class ConstLongRefConverter(LongConverter):
+class ConstLongRefConverter(ConstRefNumericTypeConverterMixin, LongConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
typecode = 'r'
def convert_argument(self, space, w_obj, address):
- x = rffi.cast(self.rffiptype, address)
+ x = rffi.cast(self.c_ptrtype, address)
x[0] = self._unwrap_object(space, w_obj)
ba = rffi.cast(rffi.CCHARP, address)
ba[capi.c_function_arg_typeoffset()] = self.typecode
@@ -349,23 +369,25 @@
class UnsignedLongConverter(IntTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.ulong
- rffiptype = rffi.ULONGP
+ c_type = rffi.ULONG
+ c_ptrtype = rffi.ULONGP
def __init__(self, space, default):
- self.default = rffi.cast(rffi.ULONG, capi.c_strtoull(default))
+ self.default = rffi.cast(self.c_type, capi.c_strtoull(default))
def _unwrap_object(self, space, w_obj):
return space.uint_w(w_obj)
-class ConstUnsignedLongRefConverter(UnsignedLongConverter):
+class ConstUnsignedLongRefConverter(ConstRefNumericTypeConverterMixin,
UnsignedLongConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
class FloatConverter(FloatTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.float
- rffiptype = rffi.FLOATP
- typecode = 'f'
+ c_type = rffi.FLOAT
+ c_ptrtype = rffi.FLOATP
+ typecode = 'f'
def __init__(self, space, default):
if default:
@@ -379,32 +401,37 @@
def from_memory(self, space, w_obj, w_pycppclass, offset):
address = self._get_raw_address(space, w_obj, offset)
- rffiptr = rffi.cast(self.rffiptype, address)
+ rffiptr = rffi.cast(self.c_ptrtype, address)
return space.wrap(float(rffiptr[0]))
class ConstFloatRefConverter(FloatConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
typecode = 'F'
+ def convert_argument_libffi(self, space, w_obj, argchain):
+ from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
+ raise FastCallNotPossible
+
class DoubleConverter(FloatTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.double
- rffiptype = rffi.DOUBLEP
- typecode = 'd'
+ c_type = rffi.DOUBLE
+ c_ptrtype = rffi.DOUBLEP
+ typecode = 'd'
def __init__(self, space, default):
if default:
- self.default = rffi.cast(rffi.DOUBLE,
rfloat.rstring_to_float(default))
+ self.default = rffi.cast(self.c_type,
rfloat.rstring_to_float(default))
else:
- self.default = rffi.cast(rffi.DOUBLE, 0.)
+ self.default = rffi.cast(self.c_type, 0.)
def _unwrap_object(self, space, w_obj):
return space.float_w(w_obj)
-class ConstDoubleRefConverter(DoubleConverter):
+class ConstDoubleRefConverter(ConstRefNumericTypeConverterMixin,
DoubleConverter):
_immutable_ = True
- libffitype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+ libffitype = libffi.types.pointer
typecode = 'D'
@@ -438,6 +465,7 @@
def convert_argument_libffi(self, space, w_obj, argchain):
argchain.arg(get_rawobject(space, w_obj))
+ return lltype.nullptr(rffi.VOIDP.TO)
class VoidPtrPtrConverter(TypeConverter):
@@ -572,6 +600,7 @@
def convert_argument_libffi(self, space, w_obj, argchain):
argchain.arg(self._unwrap_object(space, w_obj))
+ return lltype.nullptr(rffi.VOIDP.TO)
def from_memory(self, space, w_obj, w_pycppclass, offset):
address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj,
offset))
@@ -689,7 +718,7 @@
_converters["char"] = CharConverter
_converters["unsigned char"] = CharConverter
_converters["short int"] = ShortConverter
-_converters["const short int&"] = ConstIntRefConverter
+_converters["const short int&"] = ConstShortRefConverter
_converters["short"] = _converters["short int"]
_converters["const short&"] = _converters["const short int&"]
_converters["unsigned short int"] = UnsignedShortConverter
diff --git a/pypy/module/cppyy/interp_cppyy.py
b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -158,14 +158,21 @@
argchain = libffi.ArgChain()
argchain.arg(cppthis)
i = len(self.arg_defs)
- for i in range(len(args_w)):
- conv = self.arg_converters[i]
- w_arg = args_w[i]
- conv.convert_argument_libffi(self.space, w_arg, argchain)
- for j in range(i+1, len(self.arg_defs)):
- conv = self.arg_converters[j]
- conv.default_argument_libffi(self.space, argchain)
- return self.executor.execute_libffi(self.space, self._libffifunc,
argchain)
+ refbuffers = []
+ try:
+ for i in range(len(args_w)):
+ conv = self.arg_converters[i]
+ w_arg = args_w[i]
+ refbuf = conv.convert_argument_libffi(self.space, w_arg,
argchain)
+ if refbuf:
+ refbuffers.append(refbuf)
+ for j in range(i+1, len(self.arg_defs)):
+ conv = self.arg_converters[j]
+ conv.default_argument_libffi(self.space, argchain)
+ return self.executor.execute_libffi(self.space, self._libffifunc,
argchain)
+ finally:
+ for refbuf in refbuffers:
+ lltype.free(refbuf, flavor='raw')
def _setup(self, cppthis):
self.arg_converters = [converter.get_converter(self.space, arg_type,
arg_dflt)
diff --git a/pypy/module/cppyy/test/bench1.py b/pypy/module/cppyy/test/bench1.py
--- a/pypy/module/cppyy/test/bench1.py
+++ b/pypy/module/cppyy/test/bench1.py
@@ -72,6 +72,14 @@
addDataToInt.call(instance, i)
return i
+class CppyyInterpBench3(CppyyInterpBench1):
+ def __call__(self):
+ addDataToInt = self.cls.get_overload("addDataToIntConstRef")
+ instance = self.inst
+ for i in range(NNN):
+ addDataToInt.call(instance, i)
+ return i
+
class CppyyPythonBench1(object):
scale = 1
def __init__(self):
@@ -121,6 +129,7 @@
print "warming up ... "
interp_bench1 = CppyyInterpBench1()
interp_bench2 = CppyyInterpBench2()
+ interp_bench3 = CppyyInterpBench3()
python_bench1 = CppyyPythonBench1()
interp_bench1(); interp_bench2(); python_bench1()
@@ -130,6 +139,7 @@
# test runs ...
print_bench("cppyy interp", run_bench(interp_bench1))
print_bench("... overload", run_bench(interp_bench2))
+ print_bench("... constref", run_bench(interp_bench3))
print_bench("cppyy python", run_bench(python_bench1))
stat, t_cintex = commands.getstatusoutput("python bench1.py --pycintex")
print_bench("pycintex ", float(t_cintex))
diff --git a/pypy/module/cppyy/test/example01.cxx
b/pypy/module/cppyy/test/example01.cxx
--- a/pypy/module/cppyy/test/example01.cxx
+++ b/pypy/module/cppyy/test/example01.cxx
@@ -91,6 +91,10 @@
return m_somedata + a;
}
+int example01::addDataToIntConstRef(const int& a) {
+ return m_somedata + a;
+}
+
int example01::overloadedAddDataToInt(int a, int b) {
return m_somedata + a + b;
}
diff --git a/pypy/module/cppyy/test/example01.h
b/pypy/module/cppyy/test/example01.h
--- a/pypy/module/cppyy/test/example01.h
+++ b/pypy/module/cppyy/test/example01.h
@@ -39,6 +39,7 @@
public: // instance methods
int addDataToInt(int a);
+ int addDataToIntConstRef(const int& a);
int overloadedAddDataToInt(int a, int b);
int overloadedAddDataToInt(int a);
int overloadedAddDataToInt(int a, int b, int c);
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
@@ -1,3 +1,4 @@
+import py, os, sys
from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.rlib.objectmodel import specialize, instantiate
from pypy.rlib import rarithmetic, jit
@@ -6,6 +7,18 @@
from pypy.module.cppyy import interp_cppyy, capi
+
+currpath = py.path.local(__file__).dirpath()
+test_dct = str(currpath.join("example01Dict.so"))
+
+def setup_module(mod):
+ if sys.platform == 'win32':
+ py.test.skip("win32 not supported so far")
+ err = os.system("cd '%s' && make example01Dict.so" % currpath)
+ if err:
+ raise OSError("'make' failed (see stderr)")
+
+
class FakeBase(W_Root):
typename = None
@@ -150,24 +163,22 @@
return True
class TestFastPathJIT(LLJitMixin):
- def test_simple(self):
- """Test fast path being taken for methods"""
-
+ def _run_zjit(self, method_name):
if capi.identify() == 'CINT': # CINT does not support fast path
return
space = FakeSpace()
- drv = jit.JitDriver(greens=[], reds=["i", "inst", "addDataToInt"])
+ drv = jit.JitDriver(greens=[], reds=["i", "inst", "cppmethod"])
def f():
lib = interp_cppyy.load_dictionary(space, "./example01Dict.so")
cls = interp_cppyy.scope_byname(space, "example01")
inst = cls.get_overload("example01").call(None, [FakeInt(0)])
- addDataToInt = cls.get_overload("addDataToInt")
+ cppmethod = cls.get_overload(method_name)
assert isinstance(inst, interp_cppyy.W_CPPInstance)
i = 10
while i > 0:
- drv.jit_merge_point(inst=inst, addDataToInt=addDataToInt, i=i)
- addDataToInt.call(inst, [FakeInt(i)])
+ drv.jit_merge_point(inst=inst, cppmethod=cppmethod, i=i)
+ cppmethod.call(inst, [FakeInt(i)])
i -= 1
return 7
f()
@@ -175,27 +186,17 @@
result = self.meta_interp(f, [], listops=True, backendopt=True,
listcomp=True)
self.check_jitcell_token_count(1)
- def test_overload(self):
+ def test01_simple(self):
+ """Test fast path being taken for methods"""
+
+ self._run_zjit("addDataToInt")
+
+ def test02_overload(self):
"""Test fast path being taken for overloaded methods"""
- if capi.identify() == 'CINT': # CINT does not support fast path
- return
+ self._run_zjit("overloadedAddDataToInt")
- space = FakeSpace()
- drv = jit.JitDriver(greens=[], reds=["i", "inst", "addDataToInt"])
- def f():
- lib = interp_cppyy.load_dictionary(space, "./example01Dict.so")
- cls = interp_cppyy.scope_byname(space, "example01")
- inst = cls.get_overload("example01").call(None, [FakeInt(0)])
- addDataToInt = cls.get_overload("overloadedAddDataToInt")
- assert isinstance(inst, interp_cppyy.W_CPPInstance)
- i = 10
- while i > 0:
- drv.jit_merge_point(inst=inst, addDataToInt=addDataToInt, i=i)
- addDataToInt.call(inst, [FakeInt(i)])
- i -= 1
- return 7
- f()
- space = FakeSpace()
- result = self.meta_interp(f, [], listops=True, backendopt=True,
listcomp=True)
- self.check_jitcell_token_count(1)
+ def test03_const_ref(self):
+ """Test fast path being taken for methods with const ref arguments"""
+
+ self._run_zjit("addDataToIntConstRef")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit