[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