[pypy-commit] pypy reflex-support: public function renaming and a better way of loading dictionaries globally

wlav noreply at buildbot.pypy.org
Thu Aug 11 02:31:51 CEST 2011


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r46432:8e5ab51e060f
Date: 2011-08-08 18:49 -0700
http://bitbucket.org/pypy/pypy/changeset/8e5ab51e060f/

Log:	public function renaming and a better way of loading dictionaries
	globally

diff --git a/pypy/jit/tl/pypyjit_demo.py b/pypy/jit/tl/pypyjit_demo.py
--- a/pypy/jit/tl/pypyjit_demo.py
+++ b/pypy/jit/tl/pypyjit_demo.py
@@ -1,15 +1,11 @@
-import cppyy
 
-import time
-import cppyy
-lib = cppyy.load_lib("../../module/cppyy/test/example01Dict.so")
-cls = cppyy._type_byname('example01')
-inst = cls.construct(-17)
-cppol = cls.get_overload("addDataToInt")
+try:
+    import numpy
+    a = numpy.array(range(10))
+    b = a + a + a
+    print b[3]
 
-t1 = time.time()
-res = 0
-for i in range(1000000):
-    res += inst.invoke(cppol, i)
-t2 = time.time()
-print t2 - t1
+except Exception, e:
+    print "Exception: ", type(e)
+    print e
+
diff --git a/pypy/module/cppyy/__init__.py b/pypy/module/cppyy/__init__.py
--- a/pypy/module/cppyy/__init__.py
+++ b/pypy/module/cppyy/__init__.py
@@ -4,7 +4,7 @@
     """    """
 
     interpleveldefs = {
-        '_load_lib'              : 'interp_cppyy.load_lib',
+        '_load_dictionary'       : 'interp_cppyy.load_dictionary',
         '_type_byname'           : 'interp_cppyy.type_byname',
         '_template_byname'       : 'interp_cppyy.template_byname',
         'CPPInstance'            : 'interp_cppyy.W_CPPInstance',
@@ -12,5 +12,5 @@
 
     appleveldefs = {
         'gbl'                    : 'pythonify.gbl',
-        'load_lib'               : 'pythonify.load_lib',
+        'load_reflection_info'   : 'pythonify.load_reflection_info',
     }
diff --git a/pypy/module/cppyy/capi/cint_capi.py b/pypy/module/cppyy/capi/cint_capi.py
--- a/pypy/module/cppyy/capi/cint_capi.py
+++ b/pypy/module/cppyy/capi/cint_capi.py
@@ -15,14 +15,20 @@
     rootincpath = []
     rootlibpath = []
 
-ll2ctypes.load_library_kwargs['mode'] = rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW
+# force loading in global mode of core libraries, rather than linking with
+# them as PyPy uses various version of dlopen in various places; note that
+# this isn't going to fly on Windows (note that locking them in objects and
+# calling dlclose in __del__ seems to come too late, so this'll do for now)
+with rffi.scoped_str2charp('libCint.so') as ll_libname:
+    _cintdll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
+with rffi.scoped_str2charp('libCore.so') as ll_libname:
+    _coredll = rdynload.dlopen(ll_libname, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
 
 eci = ExternalCompilationInfo(
     separate_module_files=[srcpath.join("cintcwrapper.cxx")],
     include_dirs=[incpath] + rootincpath,
     includes=["cintcwrapper.h"],
     library_dirs=rootlibpath,
-    libraries=["Cint", "Core"],
     use_cpp_linker=True,
 )
 
@@ -32,6 +38,11 @@
 C_METHPTRGETTER = lltype.FuncType([C_OBJECT], rffi.VOIDP)
 C_METHPTRGETTER_PTR = lltype.Ptr(C_METHPTRGETTER)
 
+c_load_dictionary = rffi.llexternal(
+    "cppyy_load_dictionary",
+    [rffi.CCHARP], rdynload.DLLHANDLE,
+    compilation_info=eci)
+
 c_get_typehandle = rffi.llexternal(
     "cppyy_get_typehandle",
     [rffi.CCHARP], C_TYPEHANDLE,
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
@@ -2,6 +2,7 @@
 
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rlib import libffi
 
 pkgpath = py.path.local(__file__).dirpath().join(os.pardir)
 srcpath = pkgpath.join("src")
@@ -220,3 +221,6 @@
     voidp = rffi.cast(rffi.VOIDP, charp)
     c_free(voidp)
     return string
+
+def c_load_dictionary(name):
+    return libffi.CDLL(name)
diff --git a/pypy/module/cppyy/include/cintcwrapper.h b/pypy/module/cppyy/include/cintcwrapper.h
--- a/pypy/module/cppyy/include/cintcwrapper.h
+++ b/pypy/module/cppyy/include/cintcwrapper.h
@@ -3,4 +3,14 @@
 
 #include "capi.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif // ifdef __cplusplus
+
+    void* cppyy_load_dictionary(const char* lib_name);
+
+#ifdef __cplusplus
+}
+#endif // ifdef __cplusplus
+
 #endif // ifndef CPPYY_CINTCWRAPPER
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
@@ -17,14 +17,13 @@
 
 NULL_VOIDP  = lltype.nullptr(rffi.VOIDP.TO)
 
-def load_lib(space, name):
-    # TODO: the following uses a hacked CDLL that won't work on Windows
+def load_dictionary(space, name):
     try:
-        cdll = libffi.CDLL(name, rdynload.RTLD_GLOBAL | rdynload.RTLD_NOW)
+        cdll = capi.c_load_dictionary(name)
     except rdynload.DLOpenError, e:
         raise OperationError(space.w_RuntimeError, space.wrap(str(e)))
     return W_CPPLibrary(space, cdll)
-load_lib.unwrap_spec = [ObjSpace, str]
+load_dictionary.unwrap_spec = [ObjSpace, str]
 
 class State(object):
     def __init__(self, space):
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
@@ -251,14 +251,14 @@
         pyclass.__iter__ = __iter__
 
 
-_loaded_shared_libs = {}
-def load_lib(name):
+_loaded_dictionaries = {}
+def load_reflection_info(name):
     try:
-        return _loaded_shared_libs[name]
+        return _loaded_dictionaries[name]
     except KeyError:
-        lib = cppyy._load_lib(name)
-        _loaded_shared_libs[name] = lib
-        return lib
+        dct = cppyy._load_dictionary(name)
+        _loaded_dictionaries[name] = dct
+        return dct
     
 
 # user interface objects
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
@@ -6,6 +6,7 @@
 #include "TROOT.h"
 #include "TError.h"
 #include "TList.h"
+#include "TSystem.h"
 
 #include "TBaseClass.h"
 #include "TClass.h"
@@ -387,7 +388,11 @@
 }
 
 
-/* misc helper ------------------------------------------------------------ */
+/* misc helpers ----------------------------------------------------------- */
 void cppyy_free(void* ptr) {
     free(ptr);
 }
+
+void* cppyy_load_dictionary(const char* lib_name) {
+   gSystem->Load(lib_name);
+}
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
@@ -31,10 +31,10 @@
 	$(genreflex) $< $(genreflexflags) --selection=$*.xml
 
 # rootcint -f example01_cint.cxx -c example01.h example01_LinkDef.h
-# g++ -I$ROOTSYS/include example01_cint.cxx example01.cxx -shared -o example01Dict.so -L$ROOTSYS/lib -lCore -lCint
+# g++ -I$ROOTSYS/include example01_cint.cxx example01.cxx -shared -o example01Dict.so -rdynamic
 #
 # rootcint -f operators_cint.cxx -c operators.h operators_LinkDef.h
-# g++ -I$ROOTSYS/include operators_cint.cxx operators.cxx -shared -o operatorsDict.so -L$ROOTSYS/lib -lCore -lCint
+# g++ -I$ROOTSYS/include operators_cint.cxx operators.cxx -shared -o operatorsDict.os -rdynamic
 
 
 # TODO: methptrgetter causes these tests to crash, so don't use it for now
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
@@ -52,7 +52,7 @@
     scale = 1
     def __init__(self):
         import cppyy
-        self.lib = cppyy.load_lib("./example01Dict.so")
+        self.lib = cppyy.load_reflection_info("./example01Dict.so")
 
         self.cls  = cppyy._type_byname("example01")
         self.inst = self.cls.get_overload(self.cls.type_name).call(None, cppyy.CPPInstance, 0)
@@ -68,7 +68,7 @@
     scale = 1
     def __init__(self):
         import cppyy
-        self.lib = cppyy.load_lib("./example01Dict.so")
+        self.lib = cppyy.load_reflection_info("./example01Dict.so")
 
         self.cls = cppyy.gbl.example01
         self.inst = self.cls(0)
diff --git a/pypy/module/cppyy/test/test_advancedcpp.py b/pypy/module/cppyy/test/test_advancedcpp.py
--- a/pypy/module/cppyy/test/test_advancedcpp.py
+++ b/pypy/module/cppyy/test/test_advancedcpp.py
@@ -3,7 +3,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("advancedcppDict.so"))
+test_dct = str(currpath.join("advancedcppDict.so"))
 
 space = gettestobjspace(usemodules=['cppyy'])
 
@@ -18,10 +18,10 @@
     def setup_class(cls):
         cls.space = space
         env = os.environ
-        cls.w_shared_lib = space.wrap(shared_lib)
+        cls.w_test_dct  = space.wrap(test_dct)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
-            return cppyy.load_lib(%r)""" % (shared_lib, ))
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
     def test01_default_arguments(self):
         """Test usage of default arguments"""
diff --git a/pypy/module/cppyy/test/test_cppyy.py b/pypy/module/cppyy/test/test_cppyy.py
--- a/pypy/module/cppyy/test/test_cppyy.py
+++ b/pypy/module/cppyy/test/test_cppyy.py
@@ -4,7 +4,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("example01Dict.so"))
+test_dct = str(currpath.join("example01Dict.so"))
 
 space = gettestobjspace(usemodules=['cppyy'])
 
@@ -17,7 +17,7 @@
 
 class TestCPPYYImplementation:
     def test_class_query(self):
-        lib = interp_cppyy.load_lib(space, shared_lib)
+        dct = interp_cppyy.load_dictionary(space, test_dct)
         w_cppyyclass = interp_cppyy.type_byname(space, "example01")
         w_cppyyclass2 = interp_cppyy.type_byname(space, "example01")
         assert space.is_w(w_cppyyclass, w_cppyyclass2)
@@ -33,8 +33,8 @@
         env = os.environ
         cls.w_example01, cls.w_payload = cls.space.unpackiterable(cls.space.appexec([], """():
             import cppyy
-            cppyy.load_lib(%r)
-            return cppyy._type_byname('example01'), cppyy._type_byname('payload')""" % (shared_lib, )))
+            cppyy.load_reflection_info(%r)
+            return cppyy._type_byname('example01'), cppyy._type_byname('payload')""" % (test_dct, )))
 
     def test01_static_int(self):
         """Test passing of an int, returning of an int, and overloading on a
diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py
--- a/pypy/module/cppyy/test/test_datatypes.py
+++ b/pypy/module/cppyy/test/test_datatypes.py
@@ -3,7 +3,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("datatypesDict.so"))
+test_dct = str(currpath.join("datatypesDict.so"))
 
 space = gettestobjspace(usemodules=['cppyy', 'array'])
 
@@ -19,15 +19,15 @@
         cls.space = space
         env = os.environ
         cls.w_N = space.wrap(5)    # should be imported from the dictionary
-        cls.w_shared_lib = space.wrap(shared_lib)
+        cls.w_test_dct  = space.wrap(test_dct)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
-            return cppyy.load_lib(%r)""" % (shared_lib, ))
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
-    def test0_load_lib_cache(self):
-        """Test whether loading a library twice results in the same object."""
+    def test0_load_reflection_cache(self):
+        """Test whether loading a refl. info twice results in the same object."""
         import cppyy
-        lib2 = cppyy.load_lib(self.shared_lib)
+        lib2 = cppyy.load_reflection_info(self.test_dct)
         assert self.datatypes is lib2
 
     def test1_instance_data_read_access(self):
diff --git a/pypy/module/cppyy/test/test_fragile.py b/pypy/module/cppyy/test/test_fragile.py
--- a/pypy/module/cppyy/test/test_fragile.py
+++ b/pypy/module/cppyy/test/test_fragile.py
@@ -3,7 +3,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("fragileDict.so"))
+test_dct = str(currpath.join("fragileDict.so"))
 
 space = gettestobjspace(usemodules=['cppyy'])
 
@@ -18,16 +18,16 @@
     def setup_class(cls):
         cls.space = space
         env = os.environ
-        cls.w_shared_lib = space.wrap(shared_lib)
+        cls.w_test_dct  = space.wrap(test_dct)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
-            return cppyy.load_lib(%r)""" % (shared_lib, ))
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
     def test01_load_failure(self):
         """Test failure to load dictionary"""
 
         import cppyy
-        raises(RuntimeError, cppyy.load_lib, "does_not_exist.so")
+        raises(RuntimeError, cppyy.load_reflection_info, "does_not_exist.so")
 
     def test02_missing_classes(self):
         """Test (non-)access to missing classes"""
diff --git a/pypy/module/cppyy/test/test_operators.py b/pypy/module/cppyy/test/test_operators.py
--- a/pypy/module/cppyy/test/test_operators.py
+++ b/pypy/module/cppyy/test/test_operators.py
@@ -3,7 +3,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("operatorsDict.so"))
+test_dct = str(currpath.join("operatorsDict.so"))
 
 space = gettestobjspace(usemodules=['cppyy'])
 
@@ -19,10 +19,10 @@
         cls.space = space
         env = os.environ
         cls.w_N = space.wrap(5)    # should be imported from the dictionary
-        cls.w_shared_lib = space.wrap(shared_lib)
+        cls.w_test_dct  = space.wrap(test_dct)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
-            return cppyy.load_lib(%r)""" % (shared_lib, ))
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
     def teardown_method(self, meth):
         import gc
diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py
--- a/pypy/module/cppyy/test/test_pythonify.py
+++ b/pypy/module/cppyy/test/test_pythonify.py
@@ -4,7 +4,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("example01Dict.so"))
+test_dct = str(currpath.join("example01Dict.so"))
 
 space = gettestobjspace(usemodules=['cppyy'])
 
@@ -19,15 +19,15 @@
     def setup_class(cls):
         cls.space = space
         env = os.environ
-        cls.w_shared_lib = space.wrap(shared_lib)
+        cls.w_test_dct  = space.wrap(test_dct)
         cls.w_example01 = cls.space.appexec([], """():
             import cppyy
-            return cppyy.load_lib(%r)""" % (shared_lib, ))
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
-    def test01_load_lib_cache(self):
-        """Test whether loading a library twice results in the same object."""
+    def test01_load_dicionary_cache(self):
+        """Test whether loading a dictionary twice results in the same object."""
         import cppyy
-        lib2 = cppyy.load_lib(self.shared_lib)
+        lib2 = cppyy.load_reflection_info(self.test_dct)
         assert self.example01 is lib2
 
     def test02_finding_classes(self):
diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -3,7 +3,7 @@
 
 
 currpath = py.path.local(__file__).dirpath()
-shared_lib = str(currpath.join("stltypesDict.so"))
+test_dct = str(currpath.join("stltypesDict.so"))
 
 space = gettestobjspace(usemodules=['cppyy'])
 
@@ -19,10 +19,10 @@
         cls.space = space
         env = os.environ
         cls.w_N = space.wrap(13)
-        cls.w_shared_lib = space.wrap(shared_lib)
+        cls.w_test_dct  = space.wrap(test_dct)
         cls.w_datatypes = cls.space.appexec([], """():
             import cppyy
-            return cppyy.load_lib(%r)""" % (shared_lib, ))
+            return cppyy.load_reflection_info(%r)""" % (test_dct, ))
 
     def test01_builtin_type_vector_type(self):
         """Test access to an std::vector<int>"""
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -119,7 +119,7 @@
         space = FakeSpace()
         drv = jit.JitDriver(greens=[], reds=["i", "inst", "addDataToInt"])
         def f():
-            lib = interp_cppyy.load_lib(space, "./example01Dict.so")
+            lib = interp_cppyy.load_dictionary(space, "./example01Dict.so")
             cls  = interp_cppyy.type_byname(space, "example01")
             inst = cls.get_overload("example01").call(None, "stuff", [FakeInt(0)])
             addDataToInt = cls.get_overload("addDataToInt")
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -392,11 +392,11 @@
 
 # XXX: it partially duplicate the code in clibffi.py
 class CDLL(object):
-    def __init__(self, libname, mode=-1):
+    def __init__(self, libname):
         """Load the library, or raises DLOpenError."""
         self.lib = rffi.cast(DLLHANDLE, 0)
         with rffi.scoped_str2charp(libname) as ll_libname:
-            self.lib = dlopen(ll_libname, mode)
+            self.lib = dlopen(ll_libname)
 
     def __del__(self):
         if self.lib:


More information about the pypy-commit mailing list