Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r54016:e21a5f2afe86
Date: 2012-03-26 16:51 -0700
http://bitbucket.org/pypy/pypy/changeset/e21a5f2afe86/

Log:    o) handle constructors separately, as needed for the CINT backend o)
        serialize calls through CINT (which uses global variables when
        calling stubs)

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
@@ -109,6 +109,11 @@
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP,
     compilation_info=backend.eci)
 
+c_constructor = rffi.llexternal(
+    "cppyy_constructor",
+    [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void,
+    compilation_info=backend.eci)
+
 c_call_o = rffi.llexternal(
     "cppyy_call_o",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG,
diff --git a/pypy/module/cppyy/capi/cint_capi.py 
b/pypy/module/cppyy/capi/cint_capi.py
--- a/pypy/module/cppyy/capi/cint_capi.py
+++ b/pypy/module/cppyy/capi/cint_capi.py
@@ -41,6 +41,7 @@
 _c_load_dictionary = rffi.llexternal(
     "cppyy_load_dictionary",
     [rffi.CCHARP], rdynload.DLLHANDLE,
+    threadsafe=False,
     compilation_info=eci)
 
 def c_load_dictionary(name):
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
@@ -236,6 +236,14 @@
     typecode = 'd'
 
 
+class ConstructorExecutor(VoidExecutor):
+    _immutable_ = True
+
+    def execute(self, space, cppmethod, cppthis, num_args, args):
+        capi.c_constructor(cppmethod, cppthis, num_args, args)
+        return space.w_None
+
+
 class InstancePtrExecutor(FunctionExecutor):
     _immutable_ = True
     libffitype = libffi.types.pointer
@@ -387,6 +395,8 @@
 _executors["double"]              = DoubleExecutor
 _executors["double*"]             = DoublePtrExecutor
 
+_executors["constructor"]         = ConstructorExecutor
+
 # special cases (note: CINT backend requires the simple name 'string')
 _executors["std::basic_string<char>"]        = StdStringExecutor
 _executors["string"]                         = 
_executors["std::basic_string<char>"]
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
@@ -37,6 +37,7 @@
     void*  cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
     char*  cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
 
+    void cppyy_constructor(cppyy_method_t method, cppyy_object_t self, int 
nargs, void* args);
     cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, 
int nargs, void* args, cppyy_type_t result_type);
 
     cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, int 
method_index);
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
@@ -490,7 +490,7 @@
             arg_dflt = capi.c_method_arg_default(self.handle, method_index, i)
             arg_defs.append((arg_type, arg_dflt))
         if capi.c_is_constructor(self.handle, method_index):
-            result_type = "void"       # b/c otherwise CINT v.s. Reflex 
difference
+            result_type = "constructor"
             cls = CPPConstructor
         elif capi.c_is_staticmethod(self.handle, method_index):
             cls = CPPFunction
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
@@ -30,9 +30,11 @@
 #include <utility>
 
 
-/*  CINT internals (won't work on Windwos) ------------------------------- */
+/*  CINT internals (some won't work on Windows) -------------------------- */
 extern long G__store_struct_offset;
 extern "C" void* G__SetShlHandle(char*);
+extern "C" void G__LockCriticalSection();
+extern "C" void G__UnlockCriticalSection();
 
 
 /* data for life time management ------------------------------------------ */
@@ -247,20 +249,26 @@
     assert(libp->paran == nargs);
     fixup_args(libp);
 
+    G__value result;
+    G__setnull(&result);
+
+    G__LockCriticalSection();      // is recursive lock
+
     // TODO: access to store_struct_offset won't work on Windows
     long store_struct_offset = G__store_struct_offset;
-    if (self) {
-        G__setgvp((long)self);
+    if (self)
         G__store_struct_offset = (long)self;
-    }
 
-    G__value result;
-    G__setnull(&result);
     meth(&result, 0, libp, 0);
 
     if (self)
         G__store_struct_offset = store_struct_offset;
 
+    if (G__get_return(0) > G__RETURN_NORMAL)
+        G__security_recover(0);    // 0 ensures silence
+
+    G__UnlockCriticalSection();
+
     return result;
 }
 
@@ -319,6 +327,12 @@
     return cppstring_to_cstring("");
 }
 
+void cppyy_constructor(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
+    G__setgvp((long)self);
+    cppyy_call_T(method, self, nargs, args);
+    G__setgvp((long)G__PVOID);
+}
+
 cppyy_object_t cppyy_call_o(cppyy_type_t method, cppyy_object_t self, int 
nargs, void* args,
                   cppyy_type_t /*result_type*/ ) {
     G__value result = cppyy_call_T(method, self, nargs, args);
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,10 @@
     return cppstring_to_cstring(result);
 }
 
+void cppyy_constructor(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
+    cppyy_call_v(method, self, nargs, args);
+}
+
 cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int 
nargs, void* args,
                   cppyy_type_t result_type) {
     void* result = (void*)cppyy_allocate(result_type);
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to