Commits

wlav committed 1ce8a35

simplification of interface for bringing cpp objects from interpreter to app

  • Participants
  • Parent commits 3129f9b
  • Branches reflex-support

Comments (0)

Files changed (3)

File pypy/module/cppyy/converter.py

     def from_memory(self, space, w_obj, w_pycppclass, offset):
         address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
         from pypy.module.cppyy import interp_cppyy
-        return interp_cppyy.wrap_cppobject_nocast(
-            space, space.w_None, self.cppclass, address, isref=True, python_owns=False)
+        return interp_cppyy.wrap_cppobject(space, address, self.cppclass,
+                                           do_cast=False, is_ref=True)
 
     def to_memory(self, space, w_obj, w_value, offset):
         address = rffi.cast(rffi.VOIDPP, self._get_raw_address(space, w_obj, offset))
     def from_memory(self, space, w_obj, w_pycppclass, offset):
         address = rffi.cast(capi.C_OBJECT, self._get_raw_address(space, w_obj, offset))
         from pypy.module.cppyy import interp_cppyy
-        return interp_cppyy.wrap_cppobject_nocast(
-            space, space.w_None, self.cppclass, address, isref=False, python_owns=False)
+        return interp_cppyy.wrap_cppobject(space, address, self.cppclass, do_cast=False)
 
     def to_memory(self, space, w_obj, w_value, offset):
         self._is_abstract(space)

File pypy/module/cppyy/executor.py

         from pypy.module.cppyy import interp_cppyy
         long_result = capi.c_call_l(cppmethod, cppthis, num_args, args)
         ptr_result = rffi.cast(capi.C_OBJECT, long_result)
-        return interp_cppyy.wrap_cppobject(
-            space, space.w_None, self.cppclass, ptr_result, isref=False, python_owns=False)
+        return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass)
 
     def execute_libffi(self, space, cif_descr, funcaddr, buffer):
         jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
         result = rffi.ptradd(buffer, cif_descr.exchange_result)
         from pypy.module.cppyy import interp_cppyy
         ptr_result = rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, result)[0])
-        return interp_cppyy.wrap_cppobject(
-            space, space.w_None, self.cppclass, ptr_result, isref=False, python_owns=False)
+        return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass)
 
 class InstancePtrPtrExecutor(InstancePtrExecutor):
 
         voidp_result = capi.c_call_r(cppmethod, cppthis, num_args, args)
         ref_address = rffi.cast(rffi.VOIDPP, voidp_result)
         ptr_result = rffi.cast(capi.C_OBJECT, ref_address[0])
-        return interp_cppyy.wrap_cppobject(
-            space, space.w_None, self.cppclass, ptr_result, isref=False, python_owns=False)
+        return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass)
 
     def execute_libffi(self, space, cif_descr, funcaddr, buffer):
         from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
         from pypy.module.cppyy import interp_cppyy
         long_result = capi.c_call_o(cppmethod, cppthis, num_args, args, self.cppclass)
         ptr_result = rffi.cast(capi.C_OBJECT, long_result)
-        return interp_cppyy.wrap_cppobject_nocast(
-            space, space.w_None, self.cppclass, ptr_result, isref=False, python_owns=True)
+        return interp_cppyy.wrap_cppobject(space, ptr_result, self.cppclass,
+                                           do_cast=False, python_owns=True)
 
     def execute_libffi(self, space, cif_descr, funcaddr, buffer):
         from pypy.module.cppyy.interp_cppyy import FastCallNotPossible

File pypy/module/cppyy/interp_cppyy.py

         vscope = rffi.cast(capi.C_OBJECT, self.scope.handle)
         w_result = CPPMethod.call(self, vscope, args_w)
         newthis = rffi.cast(capi.C_OBJECT, self.space.int_w(w_result))
-        return wrap_new_cppobject_nocast(
-            self.space, self.space.w_None, self.scope, newthis, isref=False, python_owns=True)
+        return wrap_cppobject(self.space, newthis, self.scope,
+                              do_cast=False, python_owns=True, fresh=True)
 
     def __repr__(self):
         return "CPPConstructor: %s" % self.signature()
         w_pycppclass = space.call_function(state.w_clgen_callback, space.wrap(final_name))
     return w_pycppclass
 
-def wrap_new_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, isref, python_owns):
+def wrap_cppobject(space, rawobject, cppclass,
+                   do_cast=True, python_owns=False, is_ref=False, fresh=False):
     rawobject = rffi.cast(capi.C_OBJECT, rawobject)
-    if space.is_w(w_pycppclass, space.w_None):
-        w_pycppclass = get_pythonized_cppclass(space, cppclass.handle)
-    w_cppinstance = space.allocate_instance(W_CPPInstance, w_pycppclass)
-    cppinstance = space.interp_w(W_CPPInstance, w_cppinstance)
-    cppinstance.__init__(space, cppclass, rawobject, isref, python_owns)
-    memory_regulator.register(cppinstance)
-    return w_cppinstance
 
-def wrap_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, isref, python_owns):
-    rawobject = rffi.cast(capi.C_OBJECT, rawobject)
-    obj = memory_regulator.retrieve(rawobject)
-    if obj is not None and obj.cppclass is cppclass:
-        return obj
-    return wrap_new_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, isref, python_owns)
-
-def wrap_cppobject(space, w_pycppclass, cppclass, rawobject, isref, python_owns):
-    rawobject = rffi.cast(capi.C_OBJECT, rawobject)
-    if rawobject:
+    # cast to actual cast if requested and possible
+    w_pycppclass = space.w_None
+    if do_cast and rawobject:
         actual = capi.c_actual_class(cppclass, rawobject)
         if actual != cppclass.handle:
             try:
                 # that only get_pythonized_cppclass is expected to raise, so none of
                 # the variables are re-assigned yet)
                 pass
-    return wrap_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, isref, python_owns)
+
+    if space.is_w(w_pycppclass, space.w_None):
+        w_pycppclass = get_pythonized_cppclass(space, cppclass.handle)
+
+    # try to recycle existing object if this one is not newly created
+    if not fresh:
+        obj = memory_regulator.retrieve(rawobject)
+        if obj is not None and obj.cppclass is cppclass:
+            return obj
+
+    # fresh creation
+    w_cppinstance = space.allocate_instance(W_CPPInstance, w_pycppclass)
+    cppinstance = space.interp_w(W_CPPInstance, w_cppinstance)
+    cppinstance.__init__(space, cppclass, rawobject, is_ref, python_owns)
+    memory_regulator.register(cppinstance)
+    return w_cppinstance
 
 @unwrap_spec(cppinstance=W_CPPInstance)
 def addressof(space, cppinstance):
     rawobject = rffi.cast(capi.C_OBJECT, address)
     w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy"))
     cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False)
-    return wrap_cppobject_nocast(space, w_pycppclass, cppclass, rawobject, False, owns)
+    return wrap_cppobject(space, rawobject, cppclass, do_cast=False, python_owns=owns)