[pypy-svn] r76040 - in pypy/branch/reflex-support/pypy/module/cppyy: . include src test

wlav at codespeak.net wlav at codespeak.net
Thu Jul 8 17:43:22 CEST 2010


Author: wlav
Date: Thu Jul  8 17:43:20 2010
New Revision: 76040

Modified:
   pypy/branch/reflex-support/pypy/module/cppyy/capi.py
   pypy/branch/reflex-support/pypy/module/cppyy/executor.py
   pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h
   pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py
   pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx
   pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx
   pypy/branch/reflex-support/pypy/module/cppyy/test/test_pythonify.py
Log:
(cfbolz, wlav) Implementation of overloads for constructors from the python side.


Modified: pypy/branch/reflex-support/pypy/module/cppyy/capi.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/capi.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/capi.py	Thu Jul  8 17:43:20 2010
@@ -33,13 +33,17 @@
     [rffi.CCHARP], C_TYPEHANDLE,
     compilation_info=eci)
 
-c_callstatic_l = rffi.llexternal(
-    "callstatic_l",
-    [C_TYPEHANDLE, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.LONG,
-    compilation_info=eci)
-c_cppyy_construct = rffi.llexternal(
-    "cppyy_construct",
-    [C_TYPEHANDLE, rffi.INT, rffi.VOIDPP], C_OBJECT,
+c_cppyy_allocate = rffi.llexternal(
+    "cppyy_allocate",
+    [C_TYPEHANDLE], rffi.VOIDP,
+    compilation_info=eci)
+c_cppyy_deallocate = rffi.llexternal(
+    "cppyy_deallocate",
+    [C_TYPEHANDLE, C_OBJECT], rffi.VOIDP,
+    compilation_info=eci)
+c_cppyy_call_v = rffi.llexternal(
+    "cppyy_call_v",
+    [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], lltype.Void,
     compilation_info=eci)
 c_cppyy_call_l = rffi.llexternal(
     "cppyy_call_l",

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 Jul  8 17:43:20 2010
@@ -10,6 +10,11 @@
         raise NotImplementedError("abstract base class")
 
 
+class VoidExecutor(object):
+    def execute(self, space, func, cppthis, num_args, args):
+        capi.c_cppyy_call_v(func.cpptype.handle, func.method_index, cppthis, num_args, args)
+        return space.w_None
+
 class LongExecutor(FunctionExecutor):
     def execute(self, space, func, cppthis, num_args, args):
         result = capi.c_cppyy_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
@@ -37,6 +42,7 @@
  
  #  raise TypeError("no clue what %s is" % name)
 
+_executors["void"]                = VoidExecutor()
 _executors["int"]                 = LongExecutor()
 _executors["long"]                = LongExecutor()
 _executors["double"]              = DoubleExecutor()

Modified: pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h	Thu Jul  8 17:43:20 2010
@@ -11,7 +11,10 @@
 
     cppyy_typehandle_t cppyy_get_typehandle(const char* class_name);
 
-    cppyy_object_t cppyy_construct(cppyy_typehandle_t handle, int numargs, void* args[]);
+    void* cppyy_allocate(cppyy_typehandle_t handle);
+    void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance);
+
+    void cppyy_call_v(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]);
     long cppyy_call_l(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_destruct(cppyy_typehandle_t handle, cppyy_object_t self);

Modified: pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py	Thu Jul  8 17:43:20 2010
@@ -138,13 +138,16 @@
             self.free_arguments(args)
  
 
-class CPPConstructor(CPPFunction):
+class CPPConstructor(CPPMethod):
     def call(self, cppthis, args_w):
         assert not cppthis
-        args = self.prepare_arguments(args_w)
-        result = capi.c_cppyy_construct(self.cpptype.handle, len(args_w), args)
-        self.free_arguments(args)
-        return W_CCPInstance(self.cpptype, result)
+        newthis = capi.c_cppyy_allocate(self.cpptype.handle)
+        try:
+            CPPMethod.call(self, newthis, args_w)
+        except Exception, e:
+            capi.c_cppyy_deallocate(self.cpptype.handle, newthis)
+            raise
+        return W_CCPInstance(self.cpptype, newthis)
 
 
 class W_CPPOverload(Wrappable):

Modified: pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx	Thu Jul  8 17:43:20 2010
@@ -9,17 +9,25 @@
 }
 
 
-cppyy_object_t cppyy_construct(cppyy_typehandle_t handle, int numargs, void* args[]) {
+void* cppyy_allocate(cppyy_typehandle_t handle) {
+    return Reflex::Type((Reflex::TypeName*)handle).Allocate();
+}
+
+void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance) {
+    Reflex::Type((Reflex::TypeName*)handle).Deallocate(instance);
+}
+
+void cppyy_call_v(cppyy_typehandle_t handle, int method_index,
+                  cppyy_object_t self, int numargs, void* args[]) {
     std::vector<void*> arguments(args, args+numargs);
     Reflex::Type t((Reflex::TypeName*)handle);
-    std::vector<Reflex::Type> argtypes;
-    argtypes.reserve(numargs);
-    for (int i = 0; i < numargs; i++) {
-        argtypes.push_back(Reflex::Type::ByName("int"));
+    Reflex::Member m = t.FunctionMemberAt(method_index);
+    if (self) {
+        Reflex::Object o(t, self);
+        m.Invoke(o, 0, arguments);
+    } else {
+        m.Invoke(0, arguments);
     }
-    Reflex::Type constructor_type = Reflex::FunctionTypeBuilder(
-            Reflex::Type::ByName("void"), argtypes);
-    return t.Construct(constructor_type, arguments).Address();
 }
 
 long cppyy_call_l(cppyy_typehandle_t handle, int method_index,

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx	Thu Jul  8 17:43:20 2010
@@ -4,6 +4,22 @@
 #include <stdlib.h>
 #include <string.h>
 
+
+class payload {
+public:
+    payload(double d) : m_data(d) {}
+
+// cctor needed as long as we have no converter for const& objects
+    payload( const payload& p ) : m_data(p.m_data) {}
+
+    double getData() { return m_data; }
+    void setData(double d) { m_data = d; }
+
+private:
+    double m_data;
+};
+
+
 class example01 {
 public:
     static int count;
@@ -48,6 +64,9 @@
         ::strcpy(strout, strin);
         return strout;
     }
+    static void setPayload( payload* p, double d ) {
+        p->setData(d);
+    }
 
     static int getCount() {
         std::cout << "getcount called" << std::endl;

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_pythonify.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_pythonify.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_pythonify.py	Thu Jul  8 17:43:20 2010
@@ -70,9 +70,9 @@
 
         raises(TypeError, 'example01_class.staticStrcpy(1.)')
 
-    def test_ConstrucingAndCalling(self):
+    def test_ConstructingAndCalling(self):
         """Test object and method calls."""
-        import cppyy, sys
+        import cppyy
         example01_class = cppyy.gbl.example01
         assert example01_class.getCount() == 0
         instance = example01_class(7)
@@ -114,6 +114,22 @@
         assert res == "54"
         res = instance.addToStringValue("-12")
         assert res == "30"
+
+        res = instance.staticAddOneToInt(1L)
+        assert res == 2
+
         instance.destruct()
         assert example01_class.getCount() == 0
 
+    def testPassingOfAnObjectByPointer(self):
+        import cppyy
+        example01_class = cppyy.gbl.example01
+        payload_class = cppyy.gbl.payload
+
+        e = example01_class(14)
+        pl = payload_class(3.14)
+
+
+        pl.destruct()
+        e.destruct()
+        assert example01_class.getCount() == 0



More information about the Pypy-commit mailing list