Author: Wim Lavrijsen <wlavrij...@lbl.gov>
Branch: cling-support
Changeset: r89032:026bbdbd61f5
Date: 2016-12-09 14:49 -0800
http://bitbucket.org/pypy/pypy/changeset/026bbdbd61f5/

Log:    support signed char and long double in as much that rffi supports
        them

diff --git a/pypy/module/cppyy/capi/builtin_capi.py 
b/pypy/module/cppyy/capi/builtin_capi.py
--- a/pypy/module/cppyy/capi/builtin_capi.py
+++ b/pypy/module/cppyy/capi/builtin_capi.py
@@ -146,6 +146,13 @@
     compilation_info=backend.eci)
 def c_call_d(space, cppmethod, cppobject, nargs, args):
     return _c_call_d(cppmethod, cppobject, nargs, args)
+_c_call_ld = rffi.llexternal(
+    "cppyy_call_ld",
+    [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGDOUBLE,
+    releasegil=ts_call,
+    compilation_info=backend.eci)
+def c_call_ld(space, cppmethod, cppobject, nargs, args):
+    return _c_call_ld(cppmethod, cppobject, nargs, args)
 
 _c_call_r = rffi.llexternal(
     "cppyy_call_r",
diff --git a/pypy/module/cppyy/capi/loadable_capi.py 
b/pypy/module/cppyy/capi/loadable_capi.py
--- a/pypy/module/cppyy/capi/loadable_capi.py
+++ b/pypy/module/cppyy/capi/loadable_capi.py
@@ -125,23 +125,24 @@
         # types (see capi/__init__.py), but by using strings here, that isn't 
guaranteed
         c_opaque_ptr = state.c_ulong
  
-        c_scope  = c_opaque_ptr
-        c_type   = c_scope
-        c_object = c_opaque_ptr
-        c_method = c_opaque_ptr
-        c_index  = state.c_long
+        c_scope       = c_opaque_ptr
+        c_type        = c_scope
+        c_object      = c_opaque_ptr
+        c_method      = c_opaque_ptr
+        c_index       = state.c_long
         c_index_array = state.c_voidp
 
-        c_void   = state.c_void
-        c_char   = state.c_char
-        c_uchar  = state.c_uchar
-        c_short  = state.c_short
-        c_int    = state.c_int
-        c_long   = state.c_long
-        c_llong  = state.c_llong
-        c_ullong = state.c_ullong
-        c_float  = state.c_float
-        c_double = state.c_double
+        c_void    = state.c_void
+        c_char    = state.c_char
+        c_uchar   = state.c_uchar
+        c_short   = state.c_short
+        c_int     = state.c_int
+        c_long    = state.c_long
+        c_llong   = state.c_llong
+        c_ullong  = state.c_ullong
+        c_float   = state.c_float
+        c_double  = state.c_double
+        c_ldouble = state.c_ldouble
 
         c_ccharp = state.c_ccharp
         c_voidp  = state.c_voidp
@@ -174,6 +175,7 @@
             'call_ll'      : ([c_method, c_object, c_int, c_voidp],   c_llong),
             'call_f'       : ([c_method, c_object, c_int, c_voidp],   c_float),
             'call_d'       : ([c_method, c_object, c_int, c_voidp],   
c_double),
+            'call_ld'      : ([c_method, c_object, c_int, c_voidp],   
c_ldouble),
 
             'call_r'       : ([c_method, c_object, c_int, c_voidp],   c_voidp),
             # call_s actually takes an size_t* as last parameter, but this 
will do
@@ -372,6 +374,9 @@
 def c_call_d(space, cppmethod, cppobject, nargs, cargs):
     args = [_ArgH(cppmethod), _ArgH(cppobject), _ArgL(nargs), _ArgP(cargs)]
     return rffi.cast(rffi.DOUBLE, space.float_w(call_capi(space, 'call_d', 
args)))
+def c_call_ld(space, cppmethod, cppobject, nargs, cargs):
+    args = [_ArgH(cppmethod), _ArgH(cppobject), _ArgL(nargs), _ArgP(cargs)]
+    return rffi.cast(rffi.LONGDOUBLE, space.float_w(call_capi(space, 
'call_ld', args)))
 
 def c_call_r(space, cppmethod, cppobject, nargs, cargs):
     args = [_ArgH(cppmethod), _ArgH(cppobject), _ArgL(nargs), _ArgP(cargs)]
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, oefmt
 
 from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.rlib.rarithmetic import r_singlefloat
+from rpython.rlib.rarithmetic import r_singlefloat, r_longfloat
 from rpython.rlib import rfloat
 
 from pypy.module._rawffi.interp_rawffi import letter2tp
@@ -351,7 +351,7 @@
     def from_memory(self, space, w_obj, w_pycppclass, offset):
         address = self._get_raw_address(space, w_obj, offset)
         rffiptr = rffi.cast(self.c_ptrtype, address)
-        return space.wrap(float(rffiptr[0]))
+        return self._wrap_object(space, rffiptr[0])
 
 class ConstFloatRefConverter(FloatConverter):
     _immutable_fields_ = ['typecode']
@@ -378,6 +378,25 @@
     _immutable_fields_ = ['typecode']
     typecode = 'd'
 
+class LongDoubleConverter(ffitypes.typeid(rffi.LONGDOUBLE), 
FloatTypeConverterMixin, TypeConverter):
+    _immutable_fields_ = ['default']
+
+    def __init__(self, space, default):
+        if default:
+            fval = float(rfloat.rstring_to_float(default))
+        else:
+            fval = float(0.)
+        self.default = r_longfloat(fval)
+
+    def from_memory(self, space, w_obj, w_pycppclass, offset):
+        address = self._get_raw_address(space, w_obj, offset)
+        rffiptr = rffi.cast(self.c_ptrtype, address)
+        return self._wrap_object(space, rffiptr[0])
+
+class ConstLongDoubleRefConverter(ConstRefNumericTypeConverterMixin, 
LongDoubleConverter):
+    _immutable_fields_ = ['typecode']
+    typecode = 'g'
+
 class CStringConverter(TypeConverter):
     def convert_argument(self, space, w_obj, address, call_local):
         x = rffi.cast(rffi.LONGP, address)
@@ -725,6 +744,8 @@
 _converters["const float&"]             = ConstFloatRefConverter
 _converters["double"]                   = DoubleConverter
 _converters["const double&"]            = ConstDoubleRefConverter
+_converters["long double"]              = LongDoubleConverter
+_converters["const long double&"]       = ConstLongDoubleRefConverter
 _converters["const char*"]              = CStringConverter
 _converters["void*"]                    = VoidPtrConverter
 _converters["void**"]                   = VoidPtrPtrConverter
@@ -837,7 +858,8 @@
 def _add_aliased_converters():
     "NOT_RPYTHON"
     aliases = (
-        ("char",                            "unsigned char"),
+        ("char",                            "unsigned char"), # TODO: check
+        ("char",                            "signed char"),   # TODO: check
         ("const char*",                     "char*"),
 
         ("std::basic_string<char>",         "string"),
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
@@ -318,7 +318,8 @@
     "NOT_RPYTHON"
     type_info = (
         (bool,            capi.c_call_b,   ("bool",)),
-        (rffi.CHAR,       capi.c_call_c,   ("char", "unsigned char")),
+        # TODO: either signed or unsigned is correct for a given platform ...
+        (rffi.CHAR,       capi.c_call_c,   ("char", "unsigned char", "signed 
char")),
         (rffi.SHORT,      capi.c_call_h,   ("short", "short int", "unsigned 
short", "unsigned short int")),
         (rffi.INT,        capi.c_call_i,   ("int", "internal_enum_type_t")),
         (rffi.UINT,       capi.c_call_l,   ("unsigned", "unsigned int")),
@@ -328,6 +329,7 @@
         (rffi.ULONGLONG,  capi.c_call_ll,  ("unsigned long long", "unsigned 
long long int", "ULong64_t")),
         (rffi.FLOAT,      capi.c_call_f,   ("float",)),
         (rffi.DOUBLE,     capi.c_call_d,   ("double",)),
+        (rffi.LONGDOUBLE, capi.c_call_ld,  ("long double",)),
     )
 
     for c_type, stub, names in type_info:
diff --git a/pypy/module/cppyy/ffitypes.py b/pypy/module/cppyy/ffitypes.py
--- a/pypy/module/cppyy/ffitypes.py
+++ b/pypy/module/cppyy/ffitypes.py
@@ -241,11 +241,16 @@
 
     c_type      = rffi.LONGDOUBLE
     c_ptrtype   = rffi.LONGDOUBLEP
-    typecode    = 'D'
+    typecode    = 'g'
 
     def _unwrap_object(self, space, w_obj):
         return space.float_w(w_obj)
 
+    def _wrap_object(self, space, obj):
+        # long double not really supported, so force a cast to double
+        dbl = rffi.cast(rffi.DOUBLE, obj)
+        return space.wrap(float(dbl))
+
     def cffi_type(self, space):
         state = space.fromcache(State)
         return state.c_ldouble
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -55,6 +55,8 @@
     float  cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
     RPY_EXTERN
     double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
+    RPY_EXTERN
+    long double cppyy_call_ld(cppyy_method_t method, cppyy_object_t self, int 
nargs, void* args);
 
     RPY_EXTERN
     void*  cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
diff --git a/pypy/module/cppyy/src/clingcwrapper.cxx 
b/pypy/module/cppyy/src/clingcwrapper.cxx
--- a/pypy/module/cppyy/src/clingcwrapper.cxx
+++ b/pypy/module/cppyy/src/clingcwrapper.cxx
@@ -1255,6 +1255,11 @@
     return (double)Cppyy::CallD(method, (void*)self, &parvec);
 }
 
+long double cppyy_call_ld(cppyy_method_t method, cppyy_object_t self, int 
nargs, void* args) {
+    std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
+    return (long double)Cppyy::CallLD(method, (void*)self, &parvec);
+}
+
 void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
     std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
     return (void*)Cppyy::CallR(method, (void*)self, &parvec);
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
@@ -15,20 +15,20 @@
     spaceconfig = dict(usemodules=['cppyy', '_rawffi', 'itertools'])
 
     def setup_class(cls):
-        cls.w_N = cls.space.wrap(5)  # should be imported from the dictionary
         cls.w_test_dct  = cls.space.wrap(test_dct)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
             return cppyy.load_reflection_info(%r)""" % (test_dct, ))
+        cls.w_N = cls.space.wrap(5)  # should be imported from the dictionary
 
     def test01_load_reflection_cache(self):
-        """Test whether loading a refl. info twice results in the same 
object."""
+        """Loading reflection info twice should result in the same object"""
         import cppyy
         lib2 = cppyy.load_reflection_info(self.test_dct)
         assert self.datatypes is lib2
 
     def test02_instance_data_read_access(self):
-        """Test read access to instance public data and verify values"""
+        """Read access to instance public data and verify values"""
 
         import cppyy
         CppyyTestData = cppyy.gbl.CppyyTestData
@@ -38,62 +38,63 @@
 
         # reading boolean type
         assert c.m_bool == False
+        assert not c.get_bool(); assert not c.get_bool_cr(); assert not 
c.get_bool_r()
 
         # reading char types
         assert c.m_char  == 'a'
+        assert c.m_schar == 'b'
         assert c.m_uchar == 'c'
 
         # reading integer types
-        assert c.m_short  == -11
-        assert c.m_ushort ==  11
-        assert c.m_int    == -22
-        assert c.m_uint   ==  22
-        assert c.m_long   == -33
-        assert c.m_ulong  ==  33
-        assert c.m_llong  == -44
-        assert c.m_ullong ==  44
+        assert c.m_short   == -11; assert c.get_short_cr()   == -11; assert 
c.get_short_r()   == -11
+        assert c.m_ushort  ==  11; assert c.get_ushort_cr()  ==  11; assert 
c.get_ushort_r()  ==  11
+        assert c.m_int     == -22; assert c.get_int_cr()     == -22; assert 
c.get_int_r()     == -22
+        assert c.m_uint    ==  22; assert c.get_uint_cr()    ==  22; assert 
c.get_uint_r()    ==  22
+        assert c.m_long    == -33; assert c.get_long_cr()    == -33; assert 
c.get_long_r()    == -33
+        assert c.m_ulong   ==  33; assert c.get_ulong_cr()   ==  33; assert 
c.get_ulong_r()   ==  33
+        assert c.m_llong   == -44; assert c.get_llong_cr()   == -44; assert 
c.get_llong_r()   == -44
+        assert c.m_ullong  ==  44; assert c.get_ullong_cr()  ==  44; assert 
c.get_ullong_r()  ==  44
+        assert c.m_long64  == -55; assert c.get_long64_cr()  == -55; assert 
c.get_long64_r()  == -55
+        assert c.m_ulong64 ==  55; assert c.get_ulong64_cr() ==  55; assert 
c.get_ulong64_r() ==  55
 
         # reading floating point types
-        assert round(c.m_float  + 66., 5) == 0
+        assert round(c.m_float          + 66.,  5) == 0
+        assert round(c.get_float_cr()   + 66.,  5) == 0
+        assert round(c.get_float_r()    + 66.,  5) == 0
+        assert round(c.m_double         + 77., 11) == 0
+        assert round(c.get_double_cr()  + 77., 11) == 0
+        assert round(c.get_double_r()   + 77., 11) == 0
+        assert round(c.m_ldouble        + 88., 24) == 0
+        assert round(c.get_ldouble_cr() + 88., 24) == 0
+        assert round(c.get_ldouble_r()  + 88., 24) == 0
         assert round(c.m_double + 77., 8) == 0
 
-        # reding of array types
+        # reading of enum types
+        assert c.m_enum == CppyyTestData.kNothing
+        assert c.m_enum == c.kNothing
+
+        # reading of boolean array
         for i in range(self.N):
-            # reading of integer array types
             assert c.m_bool_array[i]        ==   bool(i%2)
             assert c.get_bool_array()[i]    ==   bool(i%2)
             assert c.m_bool_array2[i]       ==   bool((i+1)%2)
             assert c.get_bool_array2()[i]   ==   bool((i+1)%2)
-            assert c.m_short_array[i]       ==  -1*i
-            assert c.get_short_array()[i]   ==  -1*i
-            assert c.m_short_array2[i]      ==  -2*i
-            assert c.get_short_array2()[i]  ==  -2*i
-            assert c.m_ushort_array[i]      ==   3*i
-            assert c.get_ushort_array()[i]  ==   3*i
-            assert c.m_ushort_array2[i]     ==   4*i
-            assert c.get_ushort_array2()[i] ==   4*i
-            assert c.m_int_array[i]         ==  -5*i
-            assert c.get_int_array()[i]     ==  -5*i
-            assert c.m_int_array2[i]        ==  -6*i
-            assert c.get_int_array2()[i]    ==  -6*i
-            assert c.m_uint_array[i]        ==   7*i
-            assert c.get_uint_array()[i]    ==   7*i
-            assert c.m_uint_array2[i]       ==   8*i
-            assert c.get_uint_array2()[i]   ==   8*i
 
-            assert c.m_long_array[i]        ==  -9*i
-            assert c.get_long_array()[i]    ==  -9*i
-            assert c.m_long_array2[i]       == -10*i
-            assert c.get_long_array2()[i]   == -10*i
-            assert c.m_ulong_array[i]       ==  11*i
-            assert c.get_ulong_array()[i]   ==  11*i
-            assert c.m_ulong_array2[i]      ==  12*i
-            assert c.get_ulong_array2()[i]  ==  12*i
+        # reading of integer array types
+        names = [ 'short', 'ushort',    'int', 'uint',    'long',  'ulong']
+        alpha = [(-1, -2),   (3, 4), (-5, -6), (7, 8), (-9, -10), (11, 12)]
+        for j in range(self.N):
+            assert getattr(c, 'm_%s_array'    % names[i])[i]   == alpha[i][0]*i
+            assert getattr(c, 'get_%s_array'  % names[i])()[i] == alpha[i][0]*i
+            assert getattr(c, 'm_%s_array2'   % names[i])[i]   == alpha[i][1]*i
+            assert getattr(c, 'get_%s_array2' % names[i])()[i] == alpha[i][1]*i
 
-            assert round(c.m_float_array[i]   + 13.*i, 5) == 0
-            assert round(c.m_float_array2[i]  + 14.*i, 5) == 0
-            assert round(c.m_double_array[i]  + 15.*i, 8) == 0
-            assert round(c.m_double_array2[i] + 16.*i, 8) == 0
+        # reading of floating point array types
+        for k in range(self.N):
+            assert round(c.m_float_array[k]   + 13.*k, 5) == 0
+            assert round(c.m_float_array2[k]  + 14.*k, 5) == 0
+            assert round(c.m_double_array[k]  + 15.*k, 8) == 0
+            assert round(c.m_double_array2[k] + 16.*k, 8) == 0
 
         # out-of-bounds checks
         raises(IndexError, c.m_short_array.__getitem__,  self.N)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to