[pypy-svn] r75034 - in pypy/branch/fast-ctypes/pypy/rlib: . test

getxsick at codespeak.net getxsick at codespeak.net
Thu Jun 3 00:32:39 CEST 2010


Author: getxsick
Date: Thu Jun  3 00:32:33 2010
New Revision: 75034

Modified:
   pypy/branch/fast-ctypes/pypy/rlib/jitffi.py
   pypy/branch/fast-ctypes/pypy/rlib/test/test_jitffi.py
Log:
add the Get class.
it's used for declaration of function.
also it can call the function. still very limited


Modified: pypy/branch/fast-ctypes/pypy/rlib/jitffi.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/rlib/jitffi.py	(original)
+++ pypy/branch/fast-ctypes/pypy/rlib/jitffi.py	Thu Jun  3 00:32:33 2010
@@ -77,3 +77,100 @@
         else:
             raise ValueError(res_type)
         return r
+
+    def get(self, func, args_type, res_type='void'):
+        return _Get(self.cpu, self.lib, func, args_type, res_type)
+
+class _Get(object):
+    def __init__(self, cpu, lib, func, args_type, res_type='void'):
+        assert isinstance(args_type, list)
+        if 'void' in args_type and len(args_type) > 1:
+            raise ValueError("'void' must be the only parameter")
+        self.args_type = args_type
+        self.res_type = res_type
+        self.cpu = cpu
+        self.lib = lib
+        # XXX add 'void' handling
+        if self.res_type == 'int':
+            self.bres = BoxInt()
+            res = lltype.Signed
+        elif self.res_type == 'float':
+            self.bres = BoxFloat()
+            res = lltype.Float
+        elif self.res_type == 'ref':
+            self.bres = BoxPtr()
+            res = lltype.Signed
+        elif self.res_type == 'void':
+            self.bres = None
+            res = None
+        else:
+            raise ValueError(self.res_type)
+
+        try:
+            addr = rffi.cast(lltype.Signed, rdynload.dlsym(self.lib, func))
+        except KeyError:
+            raise operationerrfmt(space.w_ValueError,
+                                  "Cannot find symbol %s", func)
+        self.bfuncaddr = BoxInt(addr)
+
+        args = []
+        for arg in self.args_type:
+            if arg == 'int':
+                args.append(lltype.Signed)
+            elif arg == 'float':
+                args.append(lltype.Float)
+            elif arg == 'ref':
+                args.append(lltype.Signed)
+            elif arg == 'void':
+                args.append(None)
+            else:
+                raise ValueError(arg)
+
+        FPTR = lltype.Ptr(lltype.FuncType(args, res))
+        FUNC = deref(FPTR)
+        self.calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+
+    def __call__(self, *func_args):
+        bargs = []
+        for tp, value in zip(self.args_type, func_args):
+            if tp == 'int':
+                bargs.append(BoxInt(value))
+            elif tp == 'float':
+                bargs.append(BoxFloat(value))
+            elif tp == 'ref':
+                bargs.append(BoxPtr(value))
+            elif tp == 'void':
+                bargs
+            
+        bargs = [ BoxInt(x) for x in func_args ]
+        inputargs = [self.bfuncaddr] + bargs
+
+        oplist = [ResOperation(rop.CALL, inputargs, self.bres,
+                               descr=self.calldescr),
+                  ResOperation(rop.FINISH, [self.bres], None,
+                               descr=BasicFailDescr(0))]
+        looptoken = LoopToken()
+        self.cpu.compile_loop(inputargs, oplist, looptoken)
+
+        i = 0
+        for box in inputargs:
+            self.cpu.set_future_value_int(i, box.getint())
+            i += 1
+
+        res = self.cpu.execute_token(looptoken)
+        if res is oplist[-1].descr:
+            self.guard_failed = False
+        else:
+            self.guard_failed = True
+
+        if self.res_type == 'int':
+            r = BoxInt(self.cpu.get_latest_value_int(0)).getint()
+        elif self.res_type == 'float':
+            r = BoxFloat(self.cpu.get_latest_value_float(0)).getfloat()
+        elif self.res_type == 'ref':
+            r = BoxPtr(self.cpu.get_latest_value_ref(0)).getref()
+        elif self.res_type == 'void':
+            r = None
+        else:
+            raise ValueError(self.res_type)
+        return r

Modified: pypy/branch/fast-ctypes/pypy/rlib/test/test_jitffi.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/rlib/test/test_jitffi.py	(original)
+++ pypy/branch/fast-ctypes/pypy/rlib/test/test_jitffi.py	Thu Jun  3 00:32:33 2010
@@ -58,3 +58,23 @@
         #res = lib.call('return_float', [1.5, 1.2], 'float')
         #assert 2.7 == res
 
+    def test_get_with_same_type(self):
+        lib = jitffi.CDLL(self.lib_name)
+
+        func = lib.get('add_integers', ['int', 'int'], 'int')
+        assert 3 == func(1,2)
+        func = lib.get('add_integers', ['int', 'int'], 'int')
+        assert 1 == func(-1,2)
+        func = lib.get('add_integers', ['int', 'int'], 'int')
+        assert 0 == func(0,0)
+
+        func = lib.get('max3', ['int', 'int', 'int'], 'int')
+        assert 8 == func(2, 8, 3)
+
+        #res = lib.get('return_float', ['float', 'float'], 'float')
+        #assert 2.7 == func(1.5, 1.2)
+
+    def test_get_void(self):
+        lib = jitffi.CDLL(self.lib_name)
+        py.test.raises(ValueError, lib.get,
+                       'add_integers', ['void', 'int'], 'int')



More information about the Pypy-commit mailing list