[pypy-commit] pypy reflex-support: global variables and pointers for CINT backend

wlav noreply at buildbot.pypy.org
Thu Mar 1 09:07:38 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r53039:33cb5ec4fc46
Date: 2012-02-29 23:08 -0800
http://bitbucket.org/pypy/pypy/changeset/33cb5ec4fc46/

Log:	global variables and pointers for CINT backend

diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -91,30 +91,25 @@
     return property(binder, setter)
 
 
-def update_cppnamespace(nsdct, metans):
-    cppns = nsdct["_cpp_proxy"]
-
-    # insert static methods into the "namespace" dictionary
-    for func_name in cppns.get_method_names():
-        cppol = cppns.get_overload(func_name)
-        nsdct[func_name] = make_static_function(cppns, func_name, cppol)
-
-    # add all data members to the dictionary of the class to be created, and
-    # static ones also to the meta class (needed for property setters)
-    for dm in cppns.get_data_member_names():
-        cppdm = cppns.get_data_member(dm)
-        pydm = make_data_member(cppdm)
-        nsdct[dm] = pydm
-        setattr(metans, dm, pydm)
-
-def make_cppnamespace(namespace_name, cppns, update=True):
+def make_cppnamespace(namespace_name, cppns, build_in_full=True):
     nsdct = {"_cpp_proxy" : cppns }
 
     # create a meta class to allow properties (for static data write access)
     metans = type(CppyyNamespaceMeta)(namespace_name+'_meta', (CppyyNamespaceMeta,), {})
 
-    if update:
-        update_cppnamespace(nsdct, metans)
+    if build_in_full:   # if False, rely on lazy build-up
+        # insert static methods into the "namespace" dictionary
+        for func_name in cppns.get_method_names():
+            cppol = cppns.get_overload(func_name)
+            nsdct[func_name] = make_static_function(cppns, func_name, cppol)
+
+        # add all data members to the dictionary of the class to be created, and
+        # static ones also to the meta class (needed for property setters)
+        for dm in cppns.get_data_member_names():
+            cppdm = cppns.get_data_member(dm)
+            pydm = make_data_member(cppdm)
+            nsdct[dm] = pydm
+            setattr(metans, dm, pydm)
 
     # create the python-side C++ namespace representation
     pycppns = metans(namespace_name, (object,), nsdct)
@@ -316,7 +311,6 @@
 # cause the creation of classes in the global namespace, so gbl must exist at
 # that point to cache them)
 gbl = make_cppnamespace("::", cppyy._type_byname(""), False)     # global C++ namespace
-update_cppnamespace(gbl.__dict__, type(gbl))
 
 # mostly for the benefit of CINT, which treats std as special
 gbl.std = make_cppnamespace("std", cppyy._type_byname("std"), False)
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -17,12 +17,13 @@
 #include "TClassEdit.h"
 #include "TClassRef.h"
 #include "TDataMember.h"
+#include "TFunction.h"
+#include "TGlobal.h"
 #include "TMethod.h"
 #include "TMethodArg.h"
 
 #include <assert.h>
 #include <string.h>
-#include <iostream>
 #include <map>
 #include <sstream>
 #include <string>
@@ -45,10 +46,14 @@
 
 class ClassRefsInit {
 public:
-    ClassRefsInit() {   // setup dummy holder for global namespace
+    ClassRefsInit() {   // setup dummy holders for global and std namespaces
         assert(g_classrefs.size() == (ClassRefs_t::size_type)GLOBAL_HANDLE);
         g_classref_indices[""] = (ClassRefs_t::size_type)GLOBAL_HANDLE;
         g_classrefs.push_back(TClassRef(""));
+        g_classref_indices["std"] = g_classrefs.size();
+        g_classrefs.push_back(TClassRef(""));    // CINT ignores std
+        g_classref_indices["::std"] = g_classrefs.size();
+        g_classrefs.push_back(TClassRef(""));    // id.
     }
 };
 static ClassRefsInit _classrefs_init;
@@ -56,6 +61,9 @@
 typedef std::vector<TFunction*> GlobalFuncs_t;
 static GlobalFuncs_t g_globalfuncs;
 
+typedef std::vector<TGlobal*> GlobalVars_t;
+static GlobalVars_t g_globalvars;
+
 
 /* initialization of th ROOT system (debatable ... ) ---------------------- */
 namespace {
@@ -230,7 +238,7 @@
 }
 
 void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
-   cppyy_call_T(method, self, nargs, args);
+    cppyy_call_T(method, self, nargs, args);
 }
 
 int cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
@@ -277,9 +285,9 @@
     G__value result = cppyy_call_T(method, self, nargs, args);
     G__pop_tempobject_nodel();
     if (result.ref && *(long*)result.ref) {
-       char* charp = cppstring_to_cstring(*(std::string*)result.ref);
-       delete (std::string*)result.ref;
-       return charp;
+        char* charp = cppstring_to_cstring(*(std::string*)result.ref);
+        delete (std::string*)result.ref;
+        return charp;
     }
     return cppstring_to_cstring("");
 }
@@ -404,7 +412,7 @@
 /* method/function reflection information --------------------------------- */
 int cppyy_num_methods(cppyy_scope_t handle) {
     TClassRef cr = type_from_handle(handle);
-     if (cr.GetClass() && cr->GetListOfMethods())
+    if (cr.GetClass() && cr->GetListOfMethods())
         return cr->GetListOfMethods()->GetSize();
     else if (strcmp(cr.GetClassName(), "") == 0) {
     // NOTE: the updated list of global funcs grows with 5 "G__ateval"'s just
@@ -452,8 +460,8 @@
 }
 
 char* cppyy_method_arg_default(cppyy_scope_t, int, int) {
-/* unused: libffi does not work with CINT back-end */
-   return cppstring_to_cstring("");
+    /* unused: libffi does not work with CINT back-end */
+    return cppstring_to_cstring("");
 }
 
 cppyy_method_t cppyy_get_method(cppyy_scope_t handle, int method_index) {
@@ -480,48 +488,80 @@
 int cppyy_num_data_members(cppyy_scope_t handle) {
     TClassRef cr = type_from_handle(handle);
     if (cr.GetClass() && cr->GetListOfDataMembers())
-       return cr->GetListOfDataMembers()->GetSize();
+        return cr->GetListOfDataMembers()->GetSize();
+    else if (strcmp(cr.GetClassName(), "") == 0) {
+        TCollection* vars = gROOT->GetListOfGlobals(kTRUE);
+       	if (g_globalvars.size() != (GlobalVars_t::size_type)vars->GetSize()) {
+            g_globalvars.clear();
+	    g_globalvars.reserve(vars->GetSize());
+
+            TIter ivar(vars);
+
+            TGlobal* var = 0;
+            while ((var = (TGlobal*)ivar.Next()))
+                g_globalvars.push_back(var);
+        }
+	return (int)g_globalvars.size();
+    }
     return 0;
 }
 
 char* cppyy_data_member_name(cppyy_scope_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());
+    if (cr.GetClass()) {
+        TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
+        return cppstring_to_cstring(m->GetName());
+    }
+    TGlobal* gbl = g_globalvars[data_member_index];
+    return cppstring_to_cstring(gbl->GetName());
 }
 
 char* cppyy_data_member_type(cppyy_scope_t handle, int data_member_index) {
     TClassRef cr = type_from_handle(handle);
-    TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
-    std::string fullType = m->GetFullTypeName();
-    if ((int)m->GetArrayDim() > 1 || (!m->IsBasic() && m->IsaPointer()))
-        fullType.append("*");
-    else if ((int)m->GetArrayDim() == 1) {
-        std::ostringstream s;
-        s << '[' << m->GetMaxIndex(0) << ']' << std::ends;
-        fullType.append(s.str());
+    if (cr.GetClass())  {
+        TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
+        std::string fullType = m->GetFullTypeName();
+        if ((int)m->GetArrayDim() > 1 || (!m->IsBasic() && m->IsaPointer()))
+            fullType.append("*");
+        else if ((int)m->GetArrayDim() == 1) {
+            std::ostringstream s;
+            s << '[' << m->GetMaxIndex(0) << ']' << std::ends;
+            fullType.append(s.str());
+        }
+        return cppstring_to_cstring(fullType);
     }
-    return cppstring_to_cstring(fullType);
+    TGlobal* gbl = g_globalvars[data_member_index];
+    return cppstring_to_cstring(gbl->GetFullTypeName());
 }
 
 size_t cppyy_data_member_offset(cppyy_scope_t handle, int data_member_index) {
     TClassRef cr = type_from_handle(handle);
-    TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
-    return m->GetOffsetCint();
+    if (cr.GetClass()) {
+        TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
+        return (size_t)m->GetOffsetCint();
+    }
+    TGlobal* gbl = g_globalvars[data_member_index];
+    return (size_t)gbl->GetAddress();
 }
 
 
 /* data member properties ------------------------------------------------  */
 int cppyy_is_publicdata(cppyy_scope_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_ISPUBLIC;
+    if (cr.GetClass()) {
+        TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
+        return m->Property() & G__BIT_ISPUBLIC;
+    }
+    return 1;  // global data is always public
 }
 
 int cppyy_is_staticdata(cppyy_scope_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;
+    if (cr.GetClass()) {
+        TDataMember* m = (TDataMember*)cr->GetListOfDataMembers()->At(data_member_index);
+        return m->Property() & G__BIT_ISSTATIC;
+    }
+    return 1;  // global data is always static
 }
 
 
@@ -539,11 +579,11 @@
 }
 
 cppyy_object_t cppyy_charp2stdstring(const char* str) {
-   return (cppyy_object_t)new std::string(str);
+    return (cppyy_object_t)new std::string(str);
 }
 
 cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr) {
-   return (cppyy_object_t)new std::string(*(std::string*)ptr);
+    return (cppyy_object_t)new std::string(*(std::string*)ptr);
 }
 
 void cppyy_free_stdstring(cppyy_object_t ptr) {
@@ -551,7 +591,7 @@
 }
 
 void* cppyy_load_dictionary(const char* lib_name) {
-   if (0 <= gSystem->Load(lib_name))
-      return (void*)1;
-   return (void*)0;
+    if (0 <= gSystem->Load(lib_name))
+        return (void*)1;
+    return (void*)0;
 }
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
@@ -121,7 +121,7 @@
 }   
 
 void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
-   return (void*)cppyy_call_T<long>(method, self, nargs, args);
+    return (void*)cppyy_call_T<long>(method, self, nargs, args);
 }
 
 char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
@@ -134,7 +134,7 @@
 
 cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void* args,
                   cppyy_type_t result_type) {
-   void* result = (void*)cppyy_allocate(result_type);
+    void* result = (void*)cppyy_allocate(result_type);
     std::vector<void*> arguments = build_args(nargs, args);
     Reflex::StubFunction stub = (Reflex::StubFunction)method;
     stub(result, (void*)self, arguments, NULL /* stub context */);
@@ -390,11 +390,11 @@
 }
 
 cppyy_object_t cppyy_charp2stdstring(const char* str) {
-   return (cppyy_object_t)new std::string(str);
+    return (cppyy_object_t)new std::string(str);
 }
 
 cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr) {
-   return (cppyy_object_t)new std::string(*(std::string*)ptr);
+    return (cppyy_object_t)new std::string(*(std::string*)ptr);
 }
 
 void cppyy_free_stdstring(cppyy_object_t ptr) {
diff --git a/pypy/module/cppyy/test/datatypes_LinkDef.h b/pypy/module/cppyy/test/datatypes_LinkDef.h
--- a/pypy/module/cppyy/test/datatypes_LinkDef.h
+++ b/pypy/module/cppyy/test/datatypes_LinkDef.h
@@ -6,9 +6,19 @@
 
 #pragma link C++ struct cppyy_test_pod;
 #pragma link C++ class cppyy_test_data;
+
 #pragma link C++ function get_pod_address(cppyy_test_data&);
 #pragma link C++ function get_int_address(cppyy_test_data&);
 #pragma link C++ function get_double_address(cppyy_test_data&);
-#pragma link C++ variable N;
+#pragma link C++ function set_global_int(int);
+#pragma link C++ function get_global_int();
+
+#pragma link C++ function is_global_pod(cppyy_test_pod*);
+#pragma link C++ function set_global_pod(cppyy_test_pod*);
+#pragma link C++ function get_global_pod();
+
+#pragma link C++ global N;
+#pragma link C++ global g_int;
+#pragma link C++ global g_pod;
 
 #endif
diff --git a/pypy/module/cppyy/test/stltypes_LinkDef.h b/pypy/module/cppyy/test/stltypes_LinkDef.h
--- a/pypy/module/cppyy/test/stltypes_LinkDef.h
+++ b/pypy/module/cppyy/test/stltypes_LinkDef.h
@@ -4,9 +4,6 @@
 #pragma link off all classes;
 #pragma link off all functions;
 
-//#pragma link C++ class std::vector<int>;
-//#pragma link C++ class std::vector<int>::iterator;
-//#pragma link C++ class std::vector<int>::const_iterator;
 #pragma link C++ class std::vector<just_a_class>;
 #pragma link C++ class std::vector<just_a_class>::iterator;
 #pragma link C++ class std::vector<just_a_class>::const_iterator;


More information about the pypy-commit mailing list