[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