[pypy-commit] pypy reflex-support: o) mixin for floats
wlav
noreply at buildbot.pypy.org
Wed Feb 8 00:59:29 CET 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52212:c1bf38d38a14
Date: 2012-02-07 14:35 -0800
http://bitbucket.org/pypy/pypy/changeset/c1bf38d38a14/
Log: o) mixin for floats o) combine common mixing parts for floats and
integers o) support for float default arguments on ffi path
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
@@ -3,7 +3,7 @@
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rlib.rarithmetic import r_singlefloat
-from pypy.rlib import jit, libffi, clibffi
+from pypy.rlib import jit, libffi, clibffi, rfloat
from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
from pypy.module._rawffi.array import W_Array
@@ -140,14 +140,10 @@
space.wrap("raw buffer interface not supported"))
-class IntTypeConverterMixin(object):
+class NumericTypeConverterMixin(object):
_mixin_ = True
_immutable_ = True
- def convert_argument(self, space, w_obj, address):
- x = rffi.cast(self.rffiptype, address)
- x[0] = self._unwrap_object(space, w_obj)
-
def convert_argument_libffi(self, space, w_obj, argchain):
argchain.arg(self._unwrap_object(space, w_obj))
@@ -164,6 +160,25 @@
rffiptr = rffi.cast(self.rffiptype, address)
rffiptr[0] = self._unwrap_object(space, w_value)
+class IntTypeConverterMixin(NumericTypeConverterMixin):
+ _mixin_ = True
+ _immutable_ = True
+
+ def convert_argument(self, space, w_obj, address):
+ x = rffi.cast(self.rffiptype, address)
+ x[0] = self._unwrap_object(space, w_obj)
+
+class FloatTypeConverterMixin(NumericTypeConverterMixin):
+ _mixin_ = True
+ _immutable_ = True
+
+ def convert_argument(self, space, w_obj, address):
+ x = rffi.cast(self.rffiptype, address)
+ x[0] = self._unwrap_object(space, w_obj)
+ typecode = rffi.cast(rffi.CCHARP,
+ _direct_ptradd(address, capi.c_function_arg_typeoffset()))
+ typecode[0] = self.typecode
+
class VoidConverter(TypeConverter):
_immutable_ = True
@@ -312,63 +327,43 @@
def _unwrap_object(self, space, w_obj):
return space.uint_w(w_obj)
-class FloatConverter(TypeConverter):
+
+class FloatConverter(FloatTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.float
+ rffiptype = rffi.FLOATP
+ typecode = 'f'
+
+ def __init__(self, space, default):
+ if default:
+ fval = float(rfloat.rstring_to_float(default))
+ else:
+ fval = float(0.)
+ self.default = r_singlefloat(fval)
def _unwrap_object(self, space, w_obj):
return r_singlefloat(space.float_w(w_obj))
- def convert_argument(self, space, w_obj, address):
- x = rffi.cast(rffi.FLOATP, address)
- x[0] = self._unwrap_object(space, w_obj)
- typecode = rffi.cast(rffi.CCHARP,
- _direct_ptradd(address, capi.c_function_arg_typeoffset()))
- typecode[0] = 'f'
-
- def convert_argument_libffi(self, space, w_obj, argchain):
- from pypy.rlib.rarithmetic import r_singlefloat
- fval = space.float_w(w_obj)
- sfval = r_singlefloat(fval)
- argchain.arg(sfval)
-
def from_memory(self, space, w_obj, w_type, offset):
address = self._get_raw_address(space, w_obj, offset)
- floatptr = rffi.cast(rffi.FLOATP, address)
- return space.wrap(float(floatptr[0]))
+ rffiptr = rffi.cast(self.rffiptype, address)
+ return space.wrap(float(rffiptr[0]))
- def to_memory(self, space, w_obj, w_value, offset):
- address = self._get_raw_address(space, w_obj, offset)
- floatptr = rffi.cast(rffi.FLOATP, address)
- floatptr[0] = self._unwrap_object(space, w_value)
-
-class DoubleConverter(TypeConverter):
+class DoubleConverter(FloatTypeConverterMixin, TypeConverter):
_immutable_ = True
libffitype = libffi.types.double
+ rffiptype = rffi.DOUBLEP
+ typecode = 'd'
+
+ def __init__(self, space, default):
+ if default:
+ self.default = rffi.cast(rffi.DOUBLE, rfloat.rstring_to_float(default))
+ else:
+ self.default = rffi.cast(rffi.DOUBLE, 0.)
def _unwrap_object(self, space, w_obj):
return space.float_w(w_obj)
- def convert_argument(self, space, w_obj, address):
- x = rffi.cast(rffi.DOUBLEP, address)
- x[0] = self._unwrap_object(space, w_obj)
- typecode = rffi.cast(rffi.CCHARP,
- _direct_ptradd(address, capi.c_function_arg_typeoffset()))
- typecode[0] = 'd'
-
- def convert_argument_libffi(self, space, w_obj, argchain):
- argchain.arg(self._unwrap_object(space, w_obj))
-
- def from_memory(self, space, w_obj, w_type, offset):
- address = self._get_raw_address(space, w_obj, offset)
- doubleptr = rffi.cast(rffi.DOUBLEP, address)
- return space.wrap(doubleptr[0])
-
- def to_memory(self, space, w_obj, w_value, offset):
- address = self._get_raw_address(space, w_obj, offset)
- doubleptr = rffi.cast(rffi.DOUBLEP, address)
- doubleptr[0] = self._unwrap_object(space, w_value)
-
class CStringConverter(TypeConverter):
_immutable_ = True
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
@@ -1,3 +1,5 @@
+import pypy.module.cppyy.capi as capi
+
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef, interp_attrproperty
@@ -8,13 +10,14 @@
from pypy.rlib import libffi, rdynload, rweakref
from pypy.rlib import jit, debug
-from pypy.module.cppyy import converter, executor, helper, capi
+from pypy.module.cppyy import converter, executor, helper
class FastCallNotPossible(Exception):
pass
def _direct_ptradd(ptr, offset): # TODO: factor out with convert.py
+ assert lltype.typeOf(ptr) == capi.C_OBJECT
address = rffi.cast(rffi.CCHARP, ptr)
return rffi.cast(capi.C_OBJECT, lltype.direct_ptradd(address, offset))
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
@@ -162,6 +162,9 @@
typeValueImp(long, long)
typeValueImp(unsigned long, ulong)
+typeValueImp(float, float)
+typeValueImp(double, double)
+
std::string ArgPasser::stringValue(std::string arg0, int argn, std::string arg1)
{
switch (argn) {
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
@@ -61,18 +61,24 @@
int globalAddOneToInt(int a);
}
-#define typeValue(itype, tname) \
+#define itypeValue(itype, tname) \
itype tname##Value(itype arg0, int argn=0, itype arg1=1, itype arg2=2)
+#define ftypeValue(ftype) \
+ ftype ftype##Value(ftype arg0, int argn=0, ftype arg1=1., ftype arg2=2.)
+
// argument passing
class ArgPasser { // use a class for now as methptrgetter not
public: // implemented for global functions
- typeValue(short, short);
- typeValue(unsigned short, ushort);
- typeValue(int, int);
- typeValue(unsigned int, uint);
- typeValue(long, long);
- typeValue(unsigned long, ulong);
+ itypeValue(short, short);
+ itypeValue(unsigned short, ushort);
+ itypeValue(int, int);
+ itypeValue(unsigned int, uint);
+ itypeValue(long, long);
+ itypeValue(unsigned long, ulong);
+
+ ftypeValue(float);
+ ftypeValue(double);
std::string stringValue(
std::string arg0, int argn=0, std::string arg1 = "default");
diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py
--- a/pypy/module/cppyy/test/test_pythonify.py
+++ b/pypy/module/cppyy/test/test_pythonify.py
@@ -268,7 +268,18 @@
assert g(11, 2) == 2
assert g(11) == 11
- def test12_underscore_in_class_name(self):
+ for ftype in ['float', 'double']:
+ g = getattr(a, '%sValue' % ftype)
+ raises(TypeError, 'g(1., 2, 3., 4., 6.)')
+ assert g(11., 0, 12., 13.) == 11.
+ assert g(11., 1, 12., 13.) == 12.
+ assert g(11., 1, 12.) == 12.
+ assert g(11., 2, 12.) == 2.
+ assert g(11., 1) == 1.
+ assert g(11., 2) == 2.
+ assert g(11.) == 11.
+
+ def test11_underscore_in_class_name(self):
"""Test recognition of '_' as part of a valid class name"""
import cppyy
More information about the pypy-commit
mailing list