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

arigo at codespeak.net arigo at codespeak.net
Thu Jul 8 13:25:01 CEST 2010


Author: arigo
Date: Thu Jul  8 13:25:00 2010
New Revision: 76020

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
   pypy/branch/reflex-support/pypy/module/cppyy/test/Makefile
Log:
(antocuni, arigo)

Hack: manually do the fast-path construction enabled by
--with-methptrgetter for methods of signature 'int m(int)' only.
The JIT should speed that case up.



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 13:25:00 2010
@@ -22,6 +22,9 @@
     use_cpp_linker=True,
 )
 
+C_METHPTRGETTER = lltype.FuncType([rffi.VOIDP], rffi.VOIDP)
+C_METHPTRGETTER_PTR = lltype.Ptr(C_METHPTRGETTER)
+
 c_cppyy_get_typehandle = rffi.llexternal(
     "cppyy_get_typehandle",
     [rffi.CCHARP], rffi.VOIDP,
@@ -47,6 +50,10 @@
     "cppyy_destruct",
     [rffi.VOIDP, rffi.VOIDP], lltype.Void,
     compilation_info=eci)
+c_cppyy_get_methptr_getter = rffi.llexternal(
+    "cppyy_get_methptr_getter",
+    [rffi.VOIDP, rffi.INT], C_METHPTRGETTER_PTR,
+    compilation_info=eci)
 
 
 c_num_methods = rffi.llexternal(

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 13:25:00 2010
@@ -5,12 +5,15 @@
 #ifdef __cplusplus
 extern "C" {
 #endif // ifdef __cplusplus
+    typedef void* (*cppyy_methptrgetter_t)(void*);
+
     void* cppyy_get_typehandle(const char* class_name);
 
     void* cppyy_construct(void* handle, int numargs, void* args[]);
     long cppyy_call_l(void* handle, int method_index, void* self, int numargs, void* args[]);
     double cppyy_call_d(void* handle, int method_index, void* self, int numargs, void* args[]);
     void cppyy_destruct(void* handle, void* self);
+    cppyy_methptrgetter_t cppyy_get_methptr_getter(void* handle, int method_index);
 
     int num_methods(void* handle);
     char* method_name(void* handle, int method_index);

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 13:25:00 2010
@@ -50,17 +50,42 @@
         self.arg_types = arg_types
         self.executor = executor.get_executor( result_type )
         self.arg_converters = None
+        # <hack>
+        self.hack_call = arg_types == ['int'] and result_type == 'int'
+        # </hack>
 
     def call(self, cppthis, args_w):
         if self.executor is None:
             raise OperationError(self.space.w_TypeError, self.space.wrap("return type not handled"))
 
+        if self.hack_call:
+            try:
+                return self.do_hack_call(cppthis, args_w)
+            except NotImplementedError:
+                pass
+
         args = self.prepare_arguments(args_w)
         try:
             return self.executor.execute(self.space, self, cppthis, len(args_w), args)
         finally:
             self.free_arguments(args)
 
+    INT_2_INT_FNPTR = lltype.Ptr(lltype.FuncType([rffi.VOIDP, rffi.INT],
+                                                 rffi.INT))
+    def do_hack_call(self, cppthis, args_w):
+        # hack: only for methods 'int m(int)'
+        if len(args_w) != 1:
+            raise OperationError(space.w_TypeError, space.wrap("wrong number of args"))
+        arg = self.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)
+        funcptr = rffi.cast(self.INT_2_INT_FNPTR, funcptr)
+        result = funcptr(cppthis, arg)
+        return self.space.wrap(rffi.cast(lltype.Signed, result))
+
     def _build_converters(self):
         self.arg_converters = [converter.get_converter(arg_type)
                                    for arg_type in self.arg_types]
@@ -74,7 +99,6 @@
             self._build_converters()
         args = lltype.malloc(rffi.CArray(rffi.VOIDP), len(args_w), flavor='raw')
         for i in range(len(args_w)):
-            argtype = self.arg_types[i]
             conv = self.arg_converters[i]
             w_arg = args_w[i]
             try:

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 13:25:00 2010
@@ -57,18 +57,24 @@
     t.Destruct(self, true);
 }
 
-typedef void* (*MethPtrGetter)(void*);
-static MethPtrGetter get_methptr_getter(Reflex::Member m)
+static cppyy_methptrgetter_t get_methptr_getter(Reflex::Member m)
 {
   Reflex::PropertyList plist = m.Properties();
   if (plist.HasProperty("MethPtrGetter")) {
     Reflex::Any& value = plist.PropertyValue("MethPtrGetter");
-    return (MethPtrGetter)Reflex::any_cast<void*>(value);
+    return (cppyy_methptrgetter_t)Reflex::any_cast<void*>(value);
   }
   else
     return 0;
 }
 
+cppyy_methptrgetter_t cppyy_get_methptr_getter(void* handle, int method_index)
+{
+    Reflex::Type t((Reflex::TypeName*)handle);
+    Reflex::Member m = t.FunctionMemberAt(method_index);
+    return get_methptr_getter(m);
+}
+
 
 int num_methods(void* handle) {
     Reflex::Type t((Reflex::TypeName*)handle);

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/Makefile
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/Makefile	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/Makefile	Thu Jul  8 13:25:00 2010
@@ -8,6 +8,14 @@
   cppflags=-I$(ROOTSYS)/include -L$(ROOTSYS)/lib
 endif
 
+ifeq ($(shell $(genreflex) --help | grep -- --with-methptrgetter),)
+  genreflexflags=
+  cppflags2=
+else
+  genreflexflags=--with-methptrgetter
+  cppflags2=-Wno-pmf-conversions
+endif
+
 example01Dict.so: example01.cxx
-	$(genreflex) example01.cxx
-	g++ -o $@ example01_rflx.cpp -shared -lReflex $(cppflags)
+	$(genreflex) example01.cxx $(genreflexflags)
+	g++ -o $@ example01_rflx.cpp -shared -lReflex $(cppflags) $(cppflags2)



More information about the Pypy-commit mailing list