[pypy-svn] r75960 - in pypy/branch/reflex-support/pypy/module/cppyy: . test

wlav at codespeak.net wlav at codespeak.net
Wed Jul 7 11:44:58 CEST 2010


Author: wlav
Date: Wed Jul  7 11:44:56 2010
New Revision: 75960

Added:
   pypy/branch/reflex-support/pypy/module/cppyy/capi.py   (contents, props changed)
   pypy/branch/reflex-support/pypy/module/cppyy/executor.py   (contents, props changed)
Modified:
   pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py
   pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py
Log:
(cfbolz, wlav) Make use of the new executor module and moved all Reflex-C interface code to capi.py.


Added: pypy/branch/reflex-support/pypy/module/cppyy/capi.py
==============================================================================
--- (empty file)
+++ pypy/branch/reflex-support/pypy/module/cppyy/capi.py	Wed Jul  7 11:44:56 2010
@@ -0,0 +1,82 @@
+import py, os
+
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rpython.lltypesystem import rffi, lltype
+
+srcpath = py.path.local(__file__).dirpath().join("src")
+incpath = py.path.local(__file__).dirpath().join("include")
+
+try:
+   rootincpath = os.path.join(os.environ["ROOTSYS"], "include")
+   rootlibpath = os.path.join(os.environ["ROOTSYS"], "lib")
+except KeyError:
+   print 'please set ROOTSYS envar to the location of the ROOT installation'
+   raise
+
+eci = ExternalCompilationInfo(
+    separate_module_files=[srcpath.join("reflexcwrapper.cxx")],
+    include_dirs=[incpath, rootincpath],
+    library_dirs=[rootlibpath],
+    libraries=["Reflex"],
+    use_cpp_linker=True,
+)
+
+c_callstatic_l = rffi.llexternal(
+    "callstatic_l",
+    [rffi.CCHARP, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.LONG,
+    compilation_info=eci)
+c_callstatic_d = rffi.llexternal(
+    "callstatic_d",
+    [rffi.CCHARP, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.DOUBLE,
+    compilation_info=eci)
+c_construct = rffi.llexternal(
+    "construct",
+    [rffi.CCHARP, rffi.INT, rffi.VOIDPP], rffi.VOIDP,
+    compilation_info=eci)
+c_callmethod_l = rffi.llexternal(
+    "callmethod_l",
+    [rffi.CCHARP, rffi.INT, rffi.VOIDP, rffi.INT, rffi.VOIDPP], rffi.LONG,
+    compilation_info=eci)
+c_destruct = rffi.llexternal(
+    "destruct",
+    [rffi.CCHARP, rffi.VOIDP], lltype.Void,
+    compilation_info=eci)
+
+
+c_num_methods = rffi.llexternal(
+    "num_methods",
+    [rffi.CCHARP], rffi.INT,
+    compilation_info=eci)
+c_method_name = rffi.llexternal(
+    "method_name",
+    [rffi.CCHARP, rffi.INT], rffi.CCHARP,
+    compilation_info=eci)
+c_result_type_method = rffi.llexternal(
+    "result_type_method",
+    [rffi.CCHARP, rffi.INT], rffi.CCHARP,
+    compilation_info=eci)
+c_num_args_method = rffi.llexternal(
+    "num_args_method",
+    [rffi.CCHARP, rffi.INT], rffi.INT,
+    compilation_info=eci)
+c_arg_type_method = rffi.llexternal(
+    "arg_type_method",
+    [rffi.CCHARP, rffi.INT, rffi.INT], rffi.CCHARP,
+    compilation_info=eci)
+c_is_constructor = rffi.llexternal(
+    "is_constructor",
+    [rffi.CCHARP, rffi.INT], rffi.INT,
+    compilation_info=eci)
+c_is_static = rffi.llexternal(
+    "is_static",
+    [rffi.CCHARP, rffi.INT], rffi.INT,
+    compilation_info=eci)
+c_myfree = rffi.llexternal(
+    "myfree",
+    [rffi.VOIDP], lltype.Void,
+    compilation_info=eci)
+
+def charp2str_free(charp):
+    string = rffi.charp2str(charp)
+    c_myfree(charp)
+    return string

Added: pypy/branch/reflex-support/pypy/module/cppyy/executor.py
==============================================================================
--- (empty file)
+++ pypy/branch/reflex-support/pypy/module/cppyy/executor.py	Wed Jul  7 11:44:56 2010
@@ -0,0 +1,43 @@
+import pypy.module.cppyy.capi as capi
+
+from pypy.rpython.lltypesystem import rffi, lltype
+
+_executors = {}
+
+
+class FunctionExecutor(object):
+    def execute(self, space, func, num_args, args):
+        raise NotImplementedError("abstract base class")
+
+
+class LongExecutor(FunctionExecutor):
+    def execute(self, space, func, num_args, args):
+        result = capi.c_callstatic_l(func.cpptype.name, func.method_index, num_args, args)
+        return space.wrap(result)
+
+class DoubleExecutor(FunctionExecutor):
+    def execute(self, space, func, num_args, args):
+        result = capi.c_callstatic_d(func.cpptype.name, func.method_index, num_args, args)
+        return space.wrap(result)
+
+class CStringExecutor(FunctionExecutor):
+    def execute(self, space, func, num_args, args):
+        lresult = capi.c_callstatic_l(func.cpptype.name, func.method_index, num_args, args)
+        ccpresult = rffi.cast(rffi.CCHARP, lresult)
+        result = capi.charp2str_free(ccpresult)
+        return space.wrap(result)
+
+def get_executor(name):
+    try:
+        return _executors[name]
+    except KeyError:
+        pass
+
+    return None # currently used until proper lazy instantiation available in interp_cppyy
+ 
+ #  raise TypeError("no clue what %s is" % name)
+
+_executors["int"]                 = LongExecutor()
+_executors["long"]                = LongExecutor()
+_executors["double"]              = DoubleExecutor()
+_executors["char*"]               = CStringExecutor()

Modified: pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py	Wed Jul  7 11:44:56 2010
@@ -1,86 +1,16 @@
-import py, os
+import pypy.module.cppyy.capi as capi
 
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import ObjSpace, interp2app
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.baseobjspace import Wrappable
 
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rpython.lltypesystem import rffi, lltype
 
 from pypy.rlib.libffi import CDLL
 from pypy.rlib import jit, debug
 
-from pypy.module.cppyy import converter
-
-
-srcpath = py.path.local(__file__).dirpath().join("src")
-incpath = py.path.local(__file__).dirpath().join("include")
-rootincpath = os.path.join(os.environ["ROOTSYS"], "include")
-rootlibpath = os.path.join(os.environ["ROOTSYS"], "lib")
-
-eci = ExternalCompilationInfo(
-    separate_module_files=[srcpath.join("reflexcwrapper.cxx")],
-    include_dirs=[incpath, rootincpath],
-    library_dirs=[rootlibpath],
-    libraries=["Reflex"],
-    use_cpp_linker=True,
-)
-
-c_callstatic_l = rffi.llexternal(
-    "callstatic_l",
-    [rffi.CCHARP, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.LONG,
-    compilation_info=eci)
-c_callstatic_d = rffi.llexternal(
-    "callstatic_d",
-    [rffi.CCHARP, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.DOUBLE,
-    compilation_info=eci)
-c_construct = rffi.llexternal(
-    "construct",
-    [rffi.CCHARP, rffi.INT, rffi.VOIDPP], rffi.VOIDP,
-    compilation_info=eci)
-c_callmethod_l = rffi.llexternal(
-    "callmethod_l",
-    [rffi.CCHARP, rffi.INT, rffi.VOIDP, rffi.INT, rffi.VOIDPP], rffi.LONG,
-    compilation_info=eci)
-c_destruct = rffi.llexternal(
-    "destruct",
-    [rffi.CCHARP, rffi.VOIDP], lltype.Void,
-    compilation_info=eci)
-
-
-c_num_methods = rffi.llexternal(
-    "num_methods",
-    [rffi.CCHARP], rffi.INT,
-    compilation_info=eci)
-c_method_name = rffi.llexternal(
-    "method_name",
-    [rffi.CCHARP, rffi.INT], rffi.CCHARP,
-    compilation_info=eci)
-c_result_type_method = rffi.llexternal(
-    "result_type_method",
-    [rffi.CCHARP, rffi.INT], rffi.CCHARP,
-    compilation_info=eci)
-c_num_args_method = rffi.llexternal(
-    "num_args_method",
-    [rffi.CCHARP, rffi.INT], rffi.INT,
-    compilation_info=eci)
-c_arg_type_method = rffi.llexternal(
-    "arg_type_method",
-    [rffi.CCHARP, rffi.INT, rffi.INT], rffi.CCHARP,
-    compilation_info=eci)
-c_is_constructor = rffi.llexternal(
-    "is_constructor",
-    [rffi.CCHARP, rffi.INT], rffi.INT,
-    compilation_info=eci)
-c_is_static = rffi.llexternal(
-    "is_static",
-    [rffi.CCHARP, rffi.INT], rffi.INT,
-    compilation_info=eci)
-c_myfree = rffi.llexternal(
-    "myfree",
-    [rffi.VOIDP], lltype.Void,
-    compilation_info=eci)
+from pypy.module.cppyy import converter, executor
 
 
 NULL_VOIDP = lltype.nullptr(rffi.VOIDP.TO)
@@ -113,13 +43,13 @@
         self.cpptype = cpptype
         self.space = cpptype.space
         self.method_index = method_index
-        self.result_type = result_type
         self.arg_types = arg_types
+        self.executor = executor.get_executor( result_type )
         self.arg_converters = None
 
     def call(self, cppthis, args_w):
         args = self.prepare_arguments(args_w)
-        result = c_callmethod_l(self.cpptype.name, self.method_index,
+        result = capi.c_callmethod_l(self.cpptype.name, self.method_index,
                               cppthis, len(args_w), args)
         self.free_arguments(args)
         return self.space.wrap(result)
@@ -159,27 +89,18 @@
         lltype.free(args, flavor='raw')
 
     def __repr__(self):
-        return "CPPFunction(%s, %s, %s, %s)" % (
-            self.cpptype, self.method_index, self.result_type, self.arg_types)
+        return "CPPFunction(%s, %s, %r, %s)" % (
+            self.cpptype, self.method_index, self.executor, self.arg_types)
 
 class CPPFunction(CPPMethod):
     def call(self, cppthis, args_w):
+        if self.executor is None:
+            raise OperationError(self.space.w_TypeError, self.space.wrap("return type not handled"))
+
         assert not cppthis
         args = self.prepare_arguments(args_w)
         try:
-            if self.result_type == "int":
-                result = c_callstatic_l(self.cpptype.name, self.method_index, len(args_w), args)
-                return self.space.wrap(result)
-            if self.result_type == "double":
-                result = c_callstatic_d(self.cpptype.name, self.method_index, len(args_w), args)
-                return self.space.wrap(result)
-            if self.result_type == "char*":
-                lresult = c_callstatic_l(self.cpptype.name, self.method_index, len(args_w), args)
-                ccpresult = rffi.cast(rffi.CCHARP, lresult)
-                result = charp2str_free(ccpresult)
-                return self.space.wrap(result)
-            else:
-                raise NotImplementedError
+            return self.executor.execute(self.space, self, len(args_w), args)
         finally:
             self.free_arguments(args)
  
@@ -188,7 +109,7 @@
     def call(self, cppthis, args_w):
         assert not cppthis
         args = self.prepare_arguments(args_w)
-        result = c_construct(self.cpptype.name, len(args_w), args)
+        result = capi.c_construct(self.cpptype.name, len(args_w), args)
         self.free_arguments(args)
         return W_CPPObject(self.cpptype, result)
 
@@ -219,10 +140,6 @@
     def __repr__(self):
         return "CPPOverload(%s, %s)" % (self.func_name, self.functions)
 
-def charp2str_free(charp):
-    string = rffi.charp2str(charp)
-    c_myfree(charp)
-    return string
 
 class W_CPPType(Wrappable):
     _immutable_fields_ = ["cpplib", "name"]
@@ -235,10 +152,10 @@
         self._find_func_members()
     
     def _find_func_members(self):
-        num_func_members = c_num_methods(self.name)
+        num_func_members = capi.c_num_methods(self.name)
         args_temp = {}
         for i in range(num_func_members):
-            func_member_name = charp2str_free(c_method_name(self.name, i))
+            func_member_name = capi.charp2str_free(capi.c_method_name(self.name, i))
             cppfunction = self._make_cppfunction(i)
             overload = args_temp.setdefault(func_member_name, [])
             overload.append(cppfunction)
@@ -247,15 +164,15 @@
             self.function_members[name] = overload
 
     def _make_cppfunction(self, method_index):
-        result_type = charp2str_free(c_result_type_method(self.name, method_index))
-        num_args = c_num_args_method(self.name, method_index)
+        result_type = capi.charp2str_free(capi.c_result_type_method(self.name, method_index))
+        num_args = capi.c_num_args_method(self.name, method_index)
         argtypes = []
         for i in range(num_args):
-            argtype = charp2str_free(c_arg_type_method(self.name, method_index, i))
+            argtype = capi.charp2str_free(capi.c_arg_type_method(self.name, method_index, i))
             argtypes.append(argtype)
-        if c_is_constructor(self.name, method_index):
+        if capi.c_is_constructor(self.name, method_index):
             cls = CPPConstructor
-        elif c_is_static(self.name, method_index):
+        elif capi.c_is_static(self.name, method_index):
             cls = CPPFunction
         else:
             cls = CPPMethod
@@ -292,7 +209,7 @@
         return overload.call(self.rawobject, args_w)
 
     def destruct(self):
-        c_destruct(self.cppclass.name, self.rawobject)
+        capi.c_destruct(self.cppclass.name, self.rawobject)
 
 W_CPPObject.typedef = TypeDef(
     'CPPObject',

Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py	(original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py	Wed Jul  7 11:44:56 2010
@@ -1,7 +1,8 @@
 import py
 import os
 from pypy.conftest import gettestobjspace
-from pypy.module.cppyy import interp_cppyy
+from pypy.module.cppyy import interp_cppyy, executor
+
 
 currpath = py.path.local(__file__).dirpath()
 shared_lib = str(currpath.join("example01Dict.so"))
@@ -17,7 +18,7 @@
         w_cppyyclass = lib.type_byname("example01")
         adddouble = w_cppyyclass.function_members["adddouble"]
         func, = adddouble.functions
-        assert func.result_type == "double"
+        assert isinstance(func.executor, executor.DoubleExecutor)
         assert func.arg_types == ["double"]
 
 



More information about the Pypy-commit mailing list