[pypy-commit] pypy reflex-support: bring CINT backend to the level of the Reflex backend

wlav noreply at buildbot.pypy.org
Thu Feb 23 01:41:51 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52788:2d378037bef0
Date: 2012-02-22 16:40 -0800
http://bitbucket.org/pypy/pypy/changeset/2d378037bef0/

Log:	bring CINT backend to the level of the Reflex backend

diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -132,6 +132,11 @@
     [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE,
     compilation_info=backend.eci)
 
+c_call_r = rffi.llexternal(
+    "cppyy_call_r",
+    [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP,
+    compilation_info=backend.eci)
+
 c_call_s = rffi.llexternal(
     "cppyy_call_s",
     [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP,
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
@@ -362,7 +362,7 @@
         x[0] = rffi.cast(rffi.LONG, rffi.str2charp(arg))
         typecode = rffi.cast(rffi.CCHARP,
             capi.direct_ptradd(address, capi.c_function_arg_typeoffset()))
-        typecode[0] = 'a'
+        typecode[0] = 'o'
 
     def from_memory(self, space, w_obj, w_type, offset):
         address = self._get_raw_address(space, w_obj, offset)
@@ -647,11 +647,17 @@
 
 # special cases
 _converters["std::string"]                       = StdStringConverter
+_converters["string"]                            = _converters["std::string"]
 _converters["std::basic_string<char>"]           = StdStringConverter
+_converters["basic_string<char>"]                = _converters["std::basic_string<char>"]
 _converters["const std::string&"]                = StdStringConverter     # TODO: shouldn't copy
+_converters["const string&"]                     = _converters["const std::string&"]
 _converters["const std::basic_string<char>&"]    = StdStringConverter
+_converters["const basic_string<char>&"]         = _converters["const std::basic_string<char>&"]
 _converters["std::string&"]                      = StdStringRefConverter
+_converters["string&"]                           = _converters["std::string&"]
 _converters["std::basic_string<char>&"]          = StdStringRefConverter
+_converters["basic_string<char>&"]               = _converters["std::basic_string<char>&"]
 
 # it should be possible to generate these:
 _a_converters["short int*"]               = ShortPtrConverter
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
@@ -145,7 +145,7 @@
         result = libffifunc.call(argchain, rffi.ULONG)
         return space.wrap(result)
 
-class ConstIntRefExecutor(LongExecutor):
+class ConstIntRefExecutor(FunctionExecutor):
     _immutable_ = True
     libffitype = libffi.types.pointer
 
@@ -153,11 +153,15 @@
         intptr = rffi.cast(rffi.INTP, result)
         return space.wrap(intptr[0])
 
+    def execute(self, space, w_returntype, func, cppthis, num_args, args):
+        result = capi.c_call_r(func.cpptype.handle, func.method_index, cppthis, num_args, args)
+        return self._wrap_result(space, result)
+
     def execute_libffi(self, space, w_returntype, libffifunc, argchain):
         result = libffifunc.call(argchain, rffi.INTP)
         return space.wrap(result[0])
 
-class ConstLongRefExecutor(LongExecutor):
+class ConstLongRefExecutor(ConstIntRefExecutor):
     _immutable_ = True
     libffitype = libffi.types.pointer
 
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
@@ -30,6 +30,7 @@
     double cppyy_call_f(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
     double cppyy_call_d(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
 
+    void*  cppyy_call_r(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
     char*  cppyy_call_s(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args);
 
     cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int method_index);
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -226,7 +226,7 @@
 
     if not cppitem and isinstance(scope, CppyyNamespaceMeta):
         global _loaded_dictionaries_isdirty
-        if _loaded_dictionaries_isdirty:
+        if _loaded_dictionaries_isdirty:  # TODO: this should've been per namespace
             scope._cpp_proxy.update()  # TODO: this is currently quadratic
         cppitem = scope._cpp_proxy.get_overload(name)
         pycppitem = make_static_function(scope._cpp_proxy, name, cppitem)
@@ -254,6 +254,7 @@
     if hasattr(pyclass, 'begin') and hasattr(pyclass, 'end'):
         def __iter__(self):
             iter = self.begin()
+            # TODO: make gnu-independent
             while gbl.__gnu_cxx.__ne__(iter, self.end()):
                 yield iter.__deref__()
                 iter.__preinc__()
@@ -268,11 +269,16 @@
                 return self.c_str() == other.c_str()
             else:
                 return self.c_str() == other
-        pyclass.__eq__ = eq 
+        pyclass.__eq__ = eq
+
+    # TODO: clean this up
+    # fixup lack of __getitem__ if no const return
+    if hasattr(pyclass, '__setitem__') and not hasattr(pyclass, '__getitem___'):
+        pyclass.__getitem__ = pyclass.__setitem__
 
 
 _loaded_dictionaries = {}
-_loaded_dictionaries_isdirty = False
+_loaded_dictionaries_isdirty = False    # should be per namespace
 def load_reflection_info(name):
     try:
         return _loaded_dictionaries[name]
@@ -289,3 +295,6 @@
 # that point to cache them)
 gbl = make_cppnamespace("::", cppyy._type_byname(""), False)     # global C++ namespace
 update_cppnamespace(gbl.__dict__, type(gbl))
+
+# mostly for the benefit of CINT, which treats std as special
+gbl.std = make_cppnamespace("std", cppyy._type_byname("std"), False)
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -151,32 +151,6 @@
 
 
 /* method/function dispatching -------------------------------------------- */
-long cppyy_call_o(cppyy_typehandle_t handle, int method_index,
-                  cppyy_object_t self, int numargs, void* args,
-                  cppyy_typehandle_t rettype) {
-    TClassRef cr = type_from_handle(handle);
-    TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index);
-
-    G__InterfaceMethod meth = (G__InterfaceMethod)m->InterfaceMethod();
-    G__param* libp = (G__param*)((char*)args - offsetof(G__param, para));
-    assert(libp->paran == numargs);
-    fixup_args(libp);
-
-    // TODO: access to store_struct_offset won't work on Windows
-    G__setgvp((long)self);
-    long store_struct_offset = G__store_struct_offset;
-    G__store_struct_offset = (long)self;
-
-    G__value result;
-    G__setnull(&result);
-    meth(&result, 0, libp, 0);
-
-    G__store_struct_offset = store_struct_offset;
-
-    G__pop_tempobject_nodel();
-    return G__int(result);
-}
-
 static inline G__value cppyy_call_T(cppyy_typehandle_t handle,
         int method_index, cppyy_object_t self, int numargs, void* args) {
     
@@ -219,6 +193,14 @@
     return result;
 }
 
+long cppyy_call_o(cppyy_typehandle_t handle, int method_index,
+                  cppyy_object_t self, int numargs, void* args,
+                  cppyy_typehandle_t) {
+    G__value result = cppyy_call_T(handle, method_index, self, numargs, args);
+    G__pop_tempobject_nodel();
+    return G__int(result);
+}
+
 void cppyy_call_v(cppyy_typehandle_t handle, int method_index,
                   cppyy_object_t self, int numargs, void* args) {
    cppyy_call_T(handle, method_index, self, numargs, args);
@@ -264,8 +246,25 @@
                     cppyy_object_t self, int numargs, void* args) {
     G__value result = cppyy_call_T(handle, method_index, self, numargs, args);
     return G__double(result);
-}   
+}
 
+void* cppyy_call_r(cppyy_typehandle_t handle, int method_index,
+                  cppyy_object_t self, int numargs, void* args) {
+    G__value result = cppyy_call_T(handle, method_index, self, numargs, args);
+    return (void*)result.ref;
+}
+
+char* cppyy_call_s(cppyy_typehandle_t handle, int method_index,
+                   cppyy_object_t self, int numargs, void* args) {
+    G__value result = cppyy_call_T(handle, method_index, self, numargs, args);
+    G__pop_tempobject_nodel();
+    if (result.ref && *(long*)result.ref) {
+       char* charp = cppstring_to_cstring(*(std::string*)result.ref);
+       delete (std::string*)result.ref;
+       return charp;
+    }
+    return cppstring_to_cstring("");
+}
 
 cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t /*handle*/, int /*method_index*/) {
     return (cppyy_methptrgetter_t)NULL;
@@ -507,6 +506,18 @@
     free(ptr);
 }
 
+void* cppyy_charp2stdstring(const char* str) {
+    return new std::string(str);
+}
+
+void* cppyy_stdstring2stdstring(void* ptr) {
+    return new std::string(*(std::string*)ptr);
+}
+
+void cppyy_free_stdstring(void* ptr) {
+    delete (std::string*)ptr;
+}
+
 void* cppyy_load_dictionary(const char* lib_name) {
    if (0 <= gSystem->Load(lib_name))
       return (void*)1;
diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx
--- a/pypy/module/cppyy/src/reflexcwrapper.cxx
+++ b/pypy/module/cppyy/src/reflexcwrapper.cxx
@@ -155,6 +155,11 @@
     return cppyy_call_T<double>(handle, method_index, self, numargs, args);
 }   
 
+void* cppyy_call_r(cppyy_typehandle_t handle, int method_index,
+                  cppyy_object_t self, int numargs, void* args) {
+   return (void*)cppyy_call_T<long>(handle, method_index, self, numargs, args);
+}
+
 char* cppyy_call_s(cppyy_typehandle_t handle, int method_index,
                    cppyy_object_t self, int numargs, void* args) {
     std::string result("");
@@ -420,4 +425,3 @@
 void cppyy_free_stdstring(void* ptr) {
     delete (std::string*)ptr;
 }
-
diff --git a/pypy/module/cppyy/test/example01_LinkDef.h b/pypy/module/cppyy/test/example01_LinkDef.h
--- a/pypy/module/cppyy/test/example01_LinkDef.h
+++ b/pypy/module/cppyy/test/example01_LinkDef.h
@@ -6,6 +6,12 @@
 
 #pragma link C++ class example01;
 #pragma link C++ class payload;
+#pragma link C++ class ArgPasser;
 #pragma link C++ class z_;
 
+#pragma link C++ function globalAddOneToInt(int);
+
+#pragma link C++ namespace ns_example01;
+#pragma link C++ function ns_example01::globalAddOneToInt(int);
+
 #endif
diff --git a/pypy/module/cppyy/test/std_streams.h b/pypy/module/cppyy/test/std_streams.h
--- a/pypy/module/cppyy/test/std_streams.h
+++ b/pypy/module/cppyy/test/std_streams.h
@@ -1,9 +1,13 @@
 #ifndef STD_STREAMS_H 
 #define STD_STREAMS_H 1
 
+#ifndef __CINT__
 #include <ios>
+#endif
 #include <iostream>
 
+#ifndef __CINT__
 extern template class std::basic_ios<char,std::char_traits<char> >;
+#endif
 
 #endif // STD_STREAMS_H
diff --git a/pypy/module/cppyy/test/stltypes.h b/pypy/module/cppyy/test/stltypes.h
--- a/pypy/module/cppyy/test/stltypes.h
+++ b/pypy/module/cppyy/test/stltypes.h
@@ -22,9 +22,11 @@
 };
 
 
+#ifndef __CINT__
 //- explicit instantiations of used types
 STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, int)
 STLTYPES_EXPLICIT_INSTANTIATION_DECL(vector, just_a_class)
+#endif
 
 
 //- class with lots of std::string handling
diff --git a/pypy/module/cppyy/test/stltypes_LinkDef.h b/pypy/module/cppyy/test/stltypes_LinkDef.h
--- a/pypy/module/cppyy/test/stltypes_LinkDef.h
+++ b/pypy/module/cppyy/test/stltypes_LinkDef.h
@@ -5,7 +5,11 @@
 #pragma link off all functions;
 
 #pragma link C++ class std::vector<int>;
+#pragma link C++ class std::vector<int>::iterator;
+#pragma link C++ class std::vector<int>::const_iterator;
 #pragma link C++ class std::vector<just_a_class>;
+#pragma link C++ class std::vector<just_a_class>::iterator;
+#pragma link C++ class std::vector<just_a_class>::const_iterator;
 
 #pragma link C++ class just_a_class;
 #pragma link C++ class stringy_class;
diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -42,6 +42,7 @@
         #-----
         v = tv1(self.N)
         for i in range(self.N):
+          # TODO:
           #  v[i] = i
           #  assert v[i] == i
           #  assert v.at(i) == i


More information about the pypy-commit mailing list