[pypy-commit] pypy reflex-support: o) initialize the ROOT system when using the CINT backend (only use case, really)

wlav noreply at buildbot.pypy.org
Sat Feb 25 00:29:55 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52891:be35f099e272
Date: 2012-02-24 14:43 -0800
http://bitbucket.org/pypy/pypy/changeset/be35f099e272/

Log:	o) initialize the ROOT system when using the CINT backend (only use
	case, really) o) make operator name mapping behave better o) minor
	refactoring

diff --git a/pypy/module/cppyy/capi/reflex_capi.py b/pypy/module/cppyy/capi/reflex_capi.py
--- a/pypy/module/cppyy/capi/reflex_capi.py
+++ b/pypy/module/cppyy/capi/reflex_capi.py
@@ -9,9 +9,6 @@
 srcpath = pkgpath.join("src")
 incpath = pkgpath.join("include")
 
-def identify():
-    return 'Reflex'
-
 if os.environ.get("ROOTSYS"):
     rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")]
     rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib")]
@@ -19,6 +16,9 @@
     rootincpath = []
     rootlibpath = []
 
+def identify():
+    return 'Reflex'
+
 eci = ExternalCompilationInfo(
     separate_module_files=[srcpath.join("reflexcwrapper.cxx")],
     include_dirs=[incpath] + rootincpath,
diff --git a/pypy/module/cppyy/helper.py b/pypy/module/cppyy/helper.py
--- a/pypy/module/cppyy/helper.py
+++ b/pypy/module/cppyy/helper.py
@@ -64,11 +64,6 @@
     if cppname[0:8] == "operator":
         op = cppname[8:].strip(' ')
 
-        # operator could be a conversion using a typedef
-        handle = capi.c_get_typehandle(op)
-        if handle:
-            op = capi.charp2str_free(capi.c_final_name(handle))
-
         # look for known mapping
         try:
             return _operator_mappings[op]
@@ -100,7 +95,21 @@
         if op == "--":  # prefix v.s. postfix decrement (not python)
             return nargs and "__postdec__" or "__predec__";
 
-    # might get here, as not all operator methods handled (new, delete,etc.)
+        # operator could have been a conversion using a typedef (this lookup
+        # is put at the end only as it is unlikely and may trigger unwanted
+        # errors in class loaders in the backend, because a typical operator
+        # name is illegal as a class name)
+        handle = capi.c_get_typehandle(op)
+        if handle:
+            op = capi.charp2str_free(capi.c_final_name(handle))
+
+            try:
+                return _operator_mappings[op]
+            except KeyError:
+                pass
+
+    # might get here, as not all operator methods handled (although some with
+    # no python equivalent, such as new, delete, etc., are simply retained)
     # TODO: perhaps absorb or "pythonify" these operators?
     return cppname
 
@@ -120,6 +129,7 @@
 _operator_mappings["|"]   = "__or__"
 _operator_mappings["^"]   = "__xor__"
 _operator_mappings["~"]   = "__inv__"
+_operator_mappings["!"]   = "__nonzero__"
 _operator_mappings["+="]  = "__iadd__"
 _operator_mappings["-="]  = "__isub__"
 _operator_mappings["*="]  = "__imul__"
@@ -161,3 +171,11 @@
 # the following are not python, but useful to expose
 _operator_mappings["->"]  = "__follow__"
 _operator_mappings["="]   = "__assign__"
+
+# a bundle of operators that have no equivalent and are left "as-is" for now:
+_operator_mappings["&&"]       = "&&"
+_operator_mappings["||"]       = "||"
+_operator_mappings["new"]      = "new"
+_operator_mappings["delete"]   = "delete"
+_operator_mappings["new[]"]    = "new[]"
+_operator_mappings["delete[]"] = "delete[]"
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
@@ -157,7 +157,6 @@
     metabases = [type(base) for base in bases]
     metacpp = type(CppyyClass)(class_name+'_meta', _drop_cycles(metabases), {})
 
-
     # create the python-side C++ class representation
     d = {"_cpp_proxy" : cpptype,
          "__new__"    : make_new(class_name, cpptype),
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
@@ -8,6 +8,10 @@
 #include "TList.h"
 #include "TSystem.h"
 
+#include "TApplication.h"
+#include "TInterpreter.h"
+#include "Getline.h"
+
 #include "TBaseClass.h"
 #include "TClass.h"
 #include "TClassEdit.h"
@@ -53,6 +57,54 @@
 static GlobalFuncs_t g_globalfuncs;
 
 
+/* initialization of th ROOT system (debatable ... ) ---------------------- */
+namespace {
+
+class TCppyyApplication : public TApplication {
+public:
+    TCppyyApplication(const char* acn, Int_t* argc, char** argv, Bool_t do_load = kTRUE)
+           : TApplication(acn, argc, argv) {
+
+       if (do_load) {
+            // follow TRint to minimize differences with CINT
+            ProcessLine("#include <iostream>", kTRUE);
+            ProcessLine("#include <_string>",  kTRUE); // for std::string iostream.
+            ProcessLine("#include <vector>",   kTRUE); // needed because they're used within the
+            ProcessLine("#include <pair>",     kTRUE); //  core ROOT dicts and CINT won't be able
+                                                       //  to properly unload these files
+        }
+
+        // save current interpreter context
+        gInterpreter->SaveContext();
+        gInterpreter->SaveGlobalsContext();
+
+        // prevent crashes on accessing history
+        Gl_histinit((char*)"-");
+
+        // prevent ROOT from exiting python
+        SetReturnFromRun(kTRUE);
+
+        // enable auto-loader
+        gInterpreter->EnableAutoLoading();
+    }
+};
+
+static const char* appname = "pypy-cppyy";
+
+class ApplicationStarter {
+public:
+    ApplicationStarter() {
+        if (!gApplication) {
+            int argc = 1;
+            char* argv[1]; argv[0] = (char*)appname;
+            gApplication = new TCppyyApplication(appname, &argc, argv, kTRUE);
+        }
+    }
+} _applicationStarter;
+
+} // unnamed namespace
+
+
 /* local helpers ---------------------------------------------------------- */
 static inline char* cppstring_to_cstring(const std::string& name) {
     char* name_char = (char*)malloc(name.size() + 1);
@@ -102,7 +154,8 @@
     if (icr != g_classref_indices.end())
         return (cppyy_typehandle_t)icr->second;
 
-    TClassRef cr(class_name);
+    // use TClass directly, to enable auto-loading
+    TClassRef cr(TClass::GetClass(class_name, kTRUE, kTRUE));
     if (!cr.GetClass())
         return (cppyy_typehandle_t)NULL;
 


More information about the pypy-commit mailing list