Author: Wim Lavrijsen <wlavrij...@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; _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit