Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: reflex-support Changeset: r45427:b191cd469f0b Date: 2011-07-08 15:13 -0700 http://bitbucket.org/pypy/pypy/changeset/b191cd469f0b/
Log: first attempt at CINT back-end diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py new file mode 100644 --- /dev/null +++ b/pypy/module/cppyy/capi/__init__.py @@ -0,0 +1,2 @@ +from reflex_capi import * +#from cint_capi import * diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py new file mode 100644 --- /dev/null +++ b/pypy/module/cppyy/capi/cint_capi.py @@ -0,0 +1,194 @@ +import py, os + +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.rpython.lltypesystem import rffi, lltype + +pkgpath = py.path.local(__file__).dirpath().join(os.pardir) +srcpath = pkgpath.join("src") +incpath = pkgpath.join("include") + +if os.environ.get("ROOTSYS"): + rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] + rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib")] +else: + rootincpath = [] + rootlibpath = [] + +eci = ExternalCompilationInfo( + separate_module_files=[srcpath.join("cintcwrapper.cxx")], + include_dirs=[incpath] + rootincpath, + includes=["cintcwrapper.h"], + library_dirs=rootlibpath, +# libraries=["Core", "Cint"], + link_extra=["-lCore", "-lCint"], + use_cpp_linker=True, +) + +C_TYPEHANDLE = rffi.VOIDP +C_OBJECT = rffi.VOIDP + +C_METHPTRGETTER = lltype.FuncType([C_OBJECT], rffi.VOIDP) +C_METHPTRGETTER_PTR = lltype.Ptr(C_METHPTRGETTER) + +c_get_typehandle = rffi.llexternal( + "cppyy_get_typehandle", + [rffi.CCHARP], C_TYPEHANDLE, + compilation_info=eci) + +c_get_templatehandle = rffi.llexternal( + "cppyy_get_templatehandle", + [rffi.CCHARP], C_TYPEHANDLE, + compilation_info=eci) + +c_allocate = rffi.llexternal( + "cppyy_allocate", + [C_TYPEHANDLE], rffi.VOIDP, + compilation_info=eci) +c_deallocate = rffi.llexternal( + "cppyy_deallocate", + [C_TYPEHANDLE, C_OBJECT], lltype.Void, + compilation_info=eci) + +c_destruct = rffi.llexternal( + "cppyy_destruct", + [C_TYPEHANDLE, C_OBJECT], lltype.Void, + compilation_info=eci) + + +c_is_namespace = rffi.llexternal( + "cppyy_is_namespace", + [C_TYPEHANDLE], rffi.INT, + compilation_info=eci) + + +c_final_name = rffi.llexternal( + "cppyy_final_name", + [C_TYPEHANDLE], rffi.CCHARP, + compilation_info=eci) + +c_num_bases = rffi.llexternal( + "cppyy_num_bases", + [C_TYPEHANDLE], rffi.INT, + compilation_info=eci) + +c_base_name = rffi.llexternal( + "cppyy_base_name", + [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + compilation_info=eci) + +c_is_subtype = rffi.llexternal( + "cppyy_is_subtype", + [C_TYPEHANDLE, C_TYPEHANDLE], rffi.INT, + compilation_info=eci) +c_base_offset = rffi.llexternal( + "cppyy_base_offset", + [C_TYPEHANDLE, C_TYPEHANDLE], rffi.SIZE_T, + compilation_info=eci) + + +c_call_v = rffi.llexternal( + "cppyy_call_v", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], lltype.Void, + compilation_info=eci) +c_call_o = rffi.llexternal( + "cppyy_call_o", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP, C_TYPEHANDLE], rffi.LONG, + compilation_info=eci) +c_call_b = rffi.llexternal( + "cppyy_call_b", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], rffi.INT, + compilation_info=eci) +c_call_c = rffi.llexternal( + "cppyy_call_c", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], rffi.CHAR, + compilation_info=eci) +c_call_h = rffi.llexternal( + "cppyy_call_h", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], rffi.SHORT, + compilation_info=eci) +c_call_l = rffi.llexternal( + "cppyy_call_l", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], rffi.LONG, + compilation_info=eci) +c_call_f = rffi.llexternal( + "cppyy_call_f", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], rffi.DOUBLE, + compilation_info=eci) +c_call_d = rffi.llexternal( + "cppyy_call_d", + [C_TYPEHANDLE, rffi.INT, C_OBJECT, rffi.INT, rffi.VOIDPP], rffi.DOUBLE, + compilation_info=eci) + + +c_get_methptr_getter = rffi.llexternal( + "cppyy_get_methptr_getter", + [C_TYPEHANDLE, rffi.INT], C_METHPTRGETTER_PTR, + compilation_info=eci) + + +c_num_methods = rffi.llexternal( + "cppyy_num_methods", + [C_TYPEHANDLE], rffi.INT, + compilation_info=eci) +c_method_name = rffi.llexternal( + "cppyy_method_name", + [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + compilation_info=eci) +c_method_result_type = rffi.llexternal( + "cppyy_method_result_type", + [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + compilation_info=eci) +c_method_num_args = rffi.llexternal( + "cppyy_method_num_args", + [C_TYPEHANDLE, rffi.INT], rffi.INT, + compilation_info=eci) +c_method_req_args = rffi.llexternal( + "cppyy_method_req_args", + [C_TYPEHANDLE, rffi.INT], rffi.INT, + compilation_info=eci) +c_method_arg_type = rffi.llexternal( + "cppyy_method_arg_type", + [C_TYPEHANDLE, rffi.INT, rffi.INT], rffi.CCHARP, + compilation_info=eci) + +c_is_constructor = rffi.llexternal( + "cppyy_is_constructor", + [C_TYPEHANDLE, rffi.INT], rffi.INT, + compilation_info=eci) +c_is_staticmethod = rffi.llexternal( + "cppyy_is_staticmethod", + [C_TYPEHANDLE, rffi.INT], rffi.INT, + compilation_info=eci) + +c_num_data_members = rffi.llexternal( + "cppyy_num_data_members", + [C_TYPEHANDLE], rffi.INT, + compilation_info=eci) +c_data_member_name = rffi.llexternal( + "cppyy_data_member_name", + [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + compilation_info=eci) +c_data_member_type = rffi.llexternal( + "cppyy_data_member_type", + [C_TYPEHANDLE, rffi.INT], rffi.CCHARP, + compilation_info=eci) +c_data_member_offset = rffi.llexternal( + "cppyy_data_member_offset", + [C_TYPEHANDLE, rffi.INT], rffi.SIZE_T, + compilation_info=eci) + +c_is_staticdata = rffi.llexternal( + "cppyy_is_staticdata", + [C_TYPEHANDLE, rffi.INT], rffi.INT, + compilation_info=eci) + +c_free = rffi.llexternal( + "cppyy_free", + [rffi.VOIDP], lltype.Void, + compilation_info=eci) + +def charp2str_free(charp): + string = rffi.charp2str(charp) + voidp = rffi.cast(rffi.VOIDP, charp) + c_free(voidp) + return string diff --git a/pypy/module/cppyy/capi.py b/pypy/module/cppyy/capi/reflex_capi.py rename from pypy/module/cppyy/capi.py rename to pypy/module/cppyy/capi/reflex_capi.py --- a/pypy/module/cppyy/capi.py +++ b/pypy/module/cppyy/capi/reflex_capi.py @@ -3,8 +3,9 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.rpython.lltypesystem import rffi, lltype -srcpath = py.path.local(__file__).dirpath().join("src") -incpath = py.path.local(__file__).dirpath().join("include") +pkgpath = py.path.local(__file__).dirpath().join(os.pardir) +srcpath = pkgpath.join("src") +incpath = pkgpath.join("include") if os.environ.get("ROOTSYS"): rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")] diff --git a/pypy/module/cppyy/include/reflexcwrapper.h b/pypy/module/cppyy/include/capi.h copy from pypy/module/cppyy/include/reflexcwrapper.h copy to pypy/module/cppyy/include/capi.h --- a/pypy/module/cppyy/include/reflexcwrapper.h +++ b/pypy/module/cppyy/include/capi.h @@ -1,5 +1,7 @@ -#ifndef CPPYY_REFLEXCWRAPPER -#define CPPYY_REFLEXCWRAPPER +#ifndef CPPYY_CAPI +#define CPPYY_CAPI + +#include <stddef.h> #ifdef __cplusplus extern "C" { @@ -67,4 +69,4 @@ } #endif // ifdef __cplusplus -#endif // ifndef CPPYY_REFLEXCWRAPPER +#endif // ifndef CPPYY_CAPI diff --git a/pypy/module/cppyy/include/cintcwrapper.h b/pypy/module/cppyy/include/cintcwrapper.h new file mode 100644 --- /dev/null +++ b/pypy/module/cppyy/include/cintcwrapper.h @@ -0,0 +1,6 @@ +#ifndef CPPYY_CINTCWRAPPER +#define CPPYY_CINTCWRAPPER + +#include "capi.h" + +#endif // ifndef CPPYY_CINTCWRAPPER diff --git a/pypy/module/cppyy/include/cppyy.h b/pypy/module/cppyy/include/cppyy.h --- a/pypy/module/cppyy/include/cppyy.h +++ b/pypy/module/cppyy/include/cppyy.h @@ -1,12 +1,6 @@ #ifndef CPPYY_CPPYY #define CPPYY_CPPYY -#include "Reflex/Type.h" -#include "Reflex/Base.h" -#include "Reflex/Member.h" -#include "Reflex/Object.h" -#include "Reflex/Builder/TypeBuilder.h" -#include "Reflex/PropertyList.h" -#include "Reflex/TypeTemplate.h" +// for now, just a conventional placeholder #endif // CPPYY_CPPYY diff --git a/pypy/module/cppyy/include/reflexcwrapper.h b/pypy/module/cppyy/include/reflexcwrapper.h --- a/pypy/module/cppyy/include/reflexcwrapper.h +++ b/pypy/module/cppyy/include/reflexcwrapper.h @@ -1,70 +1,6 @@ #ifndef CPPYY_REFLEXCWRAPPER #define CPPYY_REFLEXCWRAPPER -#ifdef __cplusplus -extern "C" { -#endif // ifdef __cplusplus - typedef void* cppyy_typehandle_t; - typedef void* cppyy_object_t; - typedef void* (*cppyy_methptrgetter_t)(cppyy_object_t); - - /* name to handle */ - cppyy_typehandle_t cppyy_get_typehandle(const char* class_name); - cppyy_typehandle_t cppyy_get_templatehandle(const char* template_name); - - /* memory management */ - void* cppyy_allocate(cppyy_typehandle_t handle); - void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance); - void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self); - - /* method/function dispatching */ - void cppyy_call_v(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - long cppyy_call_o(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[], cppyy_typehandle_t rettype); - int cppyy_call_b(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - char cppyy_call_c(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - short cppyy_call_h(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - long cppyy_call_l(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - double cppyy_call_f(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - double cppyy_call_d(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]); - - cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int method_index); - - /* scope reflection information ------------------------------------------- */ - int cppyy_is_namespace(cppyy_typehandle_t handle); - - /* type/class reflection information -------------------------------------- */ - char* cppyy_final_name(cppyy_typehandle_t handle); - int cppyy_num_bases(cppyy_typehandle_t handle); - char* cppyy_base_name(cppyy_typehandle_t handle, int base_index); - int cppyy_is_subtype(cppyy_typehandle_t dh, cppyy_typehandle_t bh); - size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh); - - /* method/function reflection information */ - int cppyy_num_methods(cppyy_typehandle_t handle); - char* cppyy_method_name(cppyy_typehandle_t handle, int method_index); - char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index); - int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index); - int cppyy_method_req_args(cppyy_typehandle_t handle, int method_index); - char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int index); - - /* method properties */ - int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index); - int cppyy_is_staticmethod(cppyy_typehandle_t handle, int method_index); - - /* data member reflection information */ - int cppyy_num_data_members(cppyy_typehandle_t handle); - char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index); - char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index); - size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index); - - /* data member properties */ - int cppyy_is_staticdata(cppyy_typehandle_t handle, int data_member_index); - - /* misc helper */ - void cppyy_free(void* ptr); - -#ifdef __cplusplus -} -#endif // ifdef __cplusplus +#include "capi.h" #endif // ifndef CPPYY_REFLEXCWRAPPER 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 @@ -18,7 +18,8 @@ NULL_VOIDP = lltype.nullptr(rffi.VOIDP.TO) def load_lib(space, name): - cdll = libffi.CDLL(name) + # TODO: allow open in RTLD_GLOBAL mode + cdll = libffi.CDLL(name) #, 0x100 | 0x02) return W_CPPLibrary(space, cdll) load_lib.unwrap_spec = [ObjSpace, str] diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx new file mode 100644 --- /dev/null +++ b/pypy/module/cppyy/src/cintcwrapper.cxx @@ -0,0 +1,295 @@ +#include "cppyy.h" +#include "cintcwrapper.h" + +#include "Api.h" + +#include "TList.h" + +#include "TBaseClass.h" +#include "TClass.h" +#include "TClassEdit.h" +#include "TClassRef.h" +#include "TDataMember.h" +#include "TMethod.h" +#include "TMethodArg.h" + +#include <string.h> +#include <iostream> +#include <map> +#include <string> +#include <utility> + + +/* data for life time management ------------------------------------------ */ +typedef std::vector<TClassRef> ClassRefs_t; +static ClassRefs_t g_classrefs(1); + +typedef std::map<std::string, ClassRefs_t::size_type> ClassRefIndices_t; +static ClassRefIndices_t g_classref_indices; + + +/* local helpers ---------------------------------------------------------- */ +static inline char* cppstring_to_cstring(const std::string& name) { + char* name_char = (char*)malloc(name.size() + 1); + strcpy(name_char, name.c_str()); + return name_char; +} + +static inline char* type_cppstring_to_cstring(const std::string& tname) { + G__TypeInfo ti(tname.c_str()); + std::string name = ti.IsValid() ? ti.TrueName() : tname; + return cppstring_to_cstring(name); +} + +static inline TClassRef type_from_handle(cppyy_typehandle_t handle) { + return g_classrefs[(ClassRefs_t::size_type)handle]; +} + + +/* name to handle --------------------------------------------------------- */ +cppyy_typehandle_t cppyy_get_typehandle(const char* class_name) { + ClassRefIndices_t::iterator icr = g_classref_indices.find(class_name); + if (icr != g_classref_indices.end()) + return (cppyy_typehandle_t)icr->second; + + ClassRefs_t::size_type sz = g_classrefs.size(); + g_classref_indices[class_name] = sz; + g_classrefs.push_back(TClassRef(class_name)); + return (cppyy_typehandle_t)sz; +} + +cppyy_typehandle_t cppyy_get_templatehandle(const char* template_name) { + return cppyy_get_typehandle(template_name); +} + + +/* memory management ------------------------------------------------------ */ +void* cppyy_allocate(cppyy_typehandle_t handle) { + TClassRef cr = type_from_handle(handle); + return malloc(cr->Size()); +} + +void cppyy_deallocate(cppyy_typehandle_t /*handle*/, cppyy_object_t instance) { + free((void*)instance); +} + +void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self) { + TClassRef cr = type_from_handle(handle); + cr->Destructor((void*)self, true); +} + + +/* method/function dispatching -------------------------------------------- */ +long cppyy_call_o(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[], + cppyy_typehandle_t rettype) { + void* result = cppyy_allocate(rettype); + /* TODO: perform call ... */ + return (long)result; +} + +static inline G__value cppyy_call_T(cppyy_typehandle_t handle, + int method_index, cppyy_object_t self, int numargs, void* args[]) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + + G__InterfaceMethod meth = (G__InterfaceMethod)m->InterfaceMethod(); + G__param libp; + for (int i = 0; i < numargs; ++i ) { + G__letint(&libp.para[i], 'u', *(long*)args[i]); // TODO: use actual type code + } + + G__value result; + meth(&result, 0, &libp, 0); + + return result; +} + +void cppyy_call_v(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + cppyy_call_T(handle, method_index, self, numargs, args); +} + +int cppyy_call_b(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + G__value result = cppyy_call_T(handle, method_index, self, numargs, args); + return (bool)G__int(result); +} + +char cppyy_call_c(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + G__value result = cppyy_call_T(handle, method_index, self, numargs, args); + return (char)G__int(result); +} + +short cppyy_call_h(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + G__value result = cppyy_call_T(handle, method_index, self, numargs, args); + return (short)G__int(result); +} + +long cppyy_call_l(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + G__value result = cppyy_call_T(handle, method_index, self, numargs, args); + return G__int(result); +} + +double cppyy_call_f(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + G__value result = cppyy_call_T(handle, method_index, self, numargs, args); + return G__double(result); +} + +double cppyy_call_d(cppyy_typehandle_t handle, int method_index, + cppyy_object_t self, int numargs, void* args[]) { + G__value result = cppyy_call_T(handle, method_index, self, numargs, args); + return G__double(result); +} + + +cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t /*handle*/, int /*method_index*/) { + return (cppyy_methptrgetter_t)NULL; +} + + +/* scope reflection information ------------------------------------------- */ +int cppyy_is_namespace(cppyy_typehandle_t handle) { + TClassRef cr = type_from_handle(handle); + if (cr.GetClass() && cr->Property()) + return cr->Property() & G__BIT_ISNAMESPACE; + if (strcmp(cr.GetClassName(), "") == 0) + return true; + return false; +} + + +/* type/class reflection information -------------------------------------- */ +char* cppyy_final_name(cppyy_typehandle_t handle) { + TClassRef cr = type_from_handle(handle); + if (cr.GetClass() && cr->Property()) + return type_cppstring_to_cstring(cr->GetName()); + return cppstring_to_cstring(cr.GetClassName()); +} + +int cppyy_num_bases(cppyy_typehandle_t handle) { + TClassRef cr = type_from_handle(handle); + if (cr.GetClass() && cr->GetListOfBases() != 0) + return cr->GetListOfBases()->GetSize(); + return 0; +} + +char* cppyy_base_name(cppyy_typehandle_t handle, int base_index) { + TClassRef cr = type_from_handle(handle); + TBaseClass* b = (TBaseClass*)cr->GetListOfBases()->At(base_index); + return type_cppstring_to_cstring(b->GetName()); +} + +int cppyy_is_subtype(cppyy_typehandle_t dh, cppyy_typehandle_t bh) { + if (dh == bh) + return 1; + TClassRef crd = type_from_handle(dh); + TClassRef crb = type_from_handle(bh); + return (int)crd->GetBaseClass(crb); +} + +size_t cppyy_base_offset(cppyy_typehandle_t dh, cppyy_typehandle_t bh) { + if (dh == bh) + return 0; + TClassRef crd = type_from_handle(dh); + TClassRef crb = type_from_handle(bh); + return (size_t)crd->GetBaseClassOffset(crb); +} + + +/* method/function reflection information --------------------------------- */ +int cppyy_num_methods(cppyy_typehandle_t handle) { + TClassRef cr = type_from_handle(handle); + if (cr.GetClass() && cr->GetListOfMethods()) + return cr->GetListOfMethods()->GetSize(); + return 0; +} + +char* cppyy_method_name(cppyy_typehandle_t handle, int method_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + return cppstring_to_cstring(m->GetName()); +} + +char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + std::string name = TClassEdit::CleanType(m->GetReturnTypeName(), 1); + return type_cppstring_to_cstring(name); +} + +int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + return m->GetNargs(); +} + +int cppyy_method_req_args(cppyy_typehandle_t handle, int method_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + return m->GetNargs() - m->GetNargsOpt(); +} + +char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int arg_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + TMethodArg* arg = (TMethodArg*)m->GetListOfMethodArgs()->At(arg_index); + return type_cppstring_to_cstring(arg->GetFullTypeName()); +} + + +int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + return strcmp(m->GetName(), cr->GetName()) == 0; +} + +int cppyy_is_staticmethod(cppyy_typehandle_t handle, int method_index) { + TClassRef cr = type_from_handle(handle); + TMethod* m = (TMethod*)cr->GetListOfMethods()->At(method_index); + return m->Property() & G__BIT_ISSTATIC; +} + + +/* data member reflection information ------------------------------------- */ +int cppyy_num_data_members(cppyy_typehandle_t handle) { + TClassRef cr = type_from_handle(handle); + if (cr.GetClass() && cr->GetListOfDataMembers()) + return cr->GetListOfDataMembers()->GetSize(); + return 0; +} + +char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index) { + TClassRef cr = type_from_handle(handle); + TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index); + return cppstring_to_cstring(m->GetName()); +} + +char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index) { + TClassRef cr = type_from_handle(handle); + TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index); + return cppstring_to_cstring(m->GetFullTypeName()); +} + +size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index) { + TClassRef cr = type_from_handle(handle); + TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index); + return m->GetOffset(); +} + + +int cppyy_is_staticdata(cppyy_typehandle_t handle, int data_member_index) { + TClassRef cr = type_from_handle(handle); + TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index); + return m->Property() & G__BIT_ISSTATIC; +} + + +/* misc helper ------------------------------------------------------------ */ +void cppyy_free(void* ptr) { + free(ptr); +} 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 @@ -1,5 +1,14 @@ #include "cppyy.h" #include "reflexcwrapper.h" + +#include "Reflex/Type.h" +#include "Reflex/Base.h" +#include "Reflex/Member.h" +#include "Reflex/Object.h" +#include "Reflex/Builder/TypeBuilder.h" +#include "Reflex/PropertyList.h" +#include "Reflex/TypeTemplate.h" + #include <iostream> #include <string> #include <utility> @@ -77,7 +86,7 @@ void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self) { Reflex::Type t = type_from_handle(handle); - t.Destruct(self, true); + t.Destruct((void*)self, true); } @@ -98,8 +107,7 @@ long cppyy_call_o(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[], cppyy_typehandle_t rettype) { - Reflex::Type rt = type_from_handle(rettype); - void* result = rt.Allocate(); + void* result = cppyy_allocate(rettype); std::vector<void*> arguments(args, args+numargs); Reflex::Scope s = scope_from_handle(handle); Reflex::Member m = s.FunctionMemberAt(method_index); @@ -214,7 +222,7 @@ return 0; Reflex::Type td = type_from_handle(dh); Reflex::Type tb = type_from_handle(bh); - return base_offset(td, tb); + return (size_t)base_offset(td, tb); } diff --git a/pypy/module/cppyy/test/Makefile b/pypy/module/cppyy/test/Makefile --- a/pypy/module/cppyy/test/Makefile +++ b/pypy/module/cppyy/test/Makefile @@ -22,6 +22,9 @@ $(genreflex) example01.h $(genreflexflags) --selection=example01.xml g++ -o $@ example01_rflx.cpp example01.cxx -shared -lReflex $(cppflags) $(cppflags2) +# rootcint -f example01_cint.cxx -c example01.h +# g++ -I$ROOTSYS/include example01_cint.cxx example01.cxx -shared -o example01Dict.so -L$ROOTSYS/lib -lCore -lCint + datatypesDict.so: datatypes.cxx datatypes.h $(genreflex) datatypes.h $(genreflexflags) g++ -o $@ datatypes_rflx.cpp datatypes.cxx -shared -lReflex $(cppflags) $(cppflags2) diff --git a/pypy/module/cppyy/test/bench1.py b/pypy/module/cppyy/test/bench1.py --- a/pypy/module/cppyy/test/bench1.py +++ b/pypy/module/cppyy/test/bench1.py @@ -30,9 +30,10 @@ self.cls = PyCintex.gbl.example01 self.inst = self.cls(0) - self.scale = 10 def __call__(self): + # note that PyCintex calls don't actually scale linearly, but worse + # than linear (leak or wrong filling of a cache??) instance = self.inst niter = NNN/self.scale for i in range(niter): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit