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

antocuni at codespeak.net antocuni at codespeak.net
Thu Jul 8 18:04:44 CEST 2010


Author: antocuni
Date: Thu Jul  8 18:04:42 2010
New Revision: 76042

Modified:
   pypy/branch/reflex-support/pypy/module/cppyy/capi.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
Log:
(antocuni, arigo around) huge pile of custom hacks to convince the jit that
the function pointer to the method that we get is constant, given the dynamic
class of the cpp object



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 18:04:42 2010
@@ -91,6 +91,11 @@
     "is_static",
     [C_TYPEHANDLE, rffi.INT], rffi.INT,
     compilation_info=eci)
+c_dynamic_type = rffi.llexternal(
+    "dynamic_type",
+    [C_TYPEHANDLE, C_OBJECT], C_TYPEHANDLE,
+    compilation_info=eci)
+
 c_myfree = rffi.llexternal(
     "myfree",
     [rffi.VOIDP], lltype.Void,

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 18:04:42 2010
@@ -27,6 +27,7 @@
     char* arg_type_method(cppyy_typehandle_t handle, int method_index, int index);
     int is_constructor(cppyy_typehandle_t handle, int method_index);
     int is_static(cppyy_typehandle_t handle, int method_index);
+    cppyy_typehandle_t dynamic_type(cppyy_typehandle_t handle, cppyy_object_t self);
 
     void myfree(void* ptr);
 

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 18:04:42 2010
@@ -78,11 +78,11 @@
         if len(args_w) != 1:
             raise OperationError(space.w_TypeError, space.wrap("wrong number of args"))
         arg = space.c_int_w(args_w[0])
-        methgetter = capi.c_cppyy_get_methptr_getter(self.cpptype.handle,
-                                                     self.method_index)
-        if not methgetter:
-            raise NotImplementedError
-        funcptr = methgetter(cppthis)
+
+        cpptype = jit.hint(self.cpptype, promote=True)
+        cpp_dynamic_type = capi.c_dynamic_type(cpptype.handle, cppthis)
+        cppthis_holder.cppthis = cppthis
+        funcptr = cpptype.get_methptr(cpp_dynamic_type, self.method_index)
         funcptr = rffi.cast(self.INT_2_INT_FNPTR, funcptr)
         result = funcptr(cppthis, arg)
         return space.wrap(rffi.cast(lltype.Signed, result))
@@ -184,6 +184,10 @@
     is_static = interp2app(W_CPPOverload.is_static, unwrap_spec=['self']),
 )
 
+# hack hack hack (see get_methptr)
+class _CppthisHolder(object):
+    pass
+cppthis_holder = _CppthisHolder()
 
 class W_CPPType(Wrappable):
     _immutable_fields_ = ["name","handle"]
@@ -229,6 +233,18 @@
     def get_overload(self, name):
         return self.function_members[name]
 
+    @jit.purefunction
+    def get_methptr(self, cpp_dynamic_type, method_index):
+        # hack hack hack: we can't really pass cppthis as an argument as it's
+        # not constant, but as long as it corresponds to cpp_dynamic_type, the
+        # function is still pure
+        cppthis = cppthis_holder.cppthis
+        methgetter = capi.c_cppyy_get_methptr_getter(self.handle, method_index)
+        if not methgetter:
+            raise NotImplementedError
+        return methgetter(cppthis)
+
+
     def invoke(self, name, args_w):
         overload = self.get_overload(name)
         return overload.call(NULL_VOIDP, args_w)

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 18:04:42 2010
@@ -147,6 +147,12 @@
     return m.IsStatic();
 }
 
+cppyy_typehandle_t dynamic_type(cppyy_typehandle_t handle, cppyy_object_t self) {
+    Reflex::Type t((Reflex::TypeName*)handle);
+    const Reflex::Object* obj = (const Reflex::Object*)self;
+    return t.DynamicType((*obj)).Id();
+}
+
 void myfree(void* ptr) {
     free(ptr);
 }



More information about the Pypy-commit mailing list