[pypy-commit] pypy reflex-support: first attempt at CINT back-end

wlav noreply at buildbot.pypy.org
Sat Jul 9 00:13:26 CEST 2011


Author: Wim Lavrijsen <WLavrijsen at 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):


More information about the pypy-commit mailing list