[pypy-svn] r47505 - in pypy/dist/pypy: module/_ffi rlib rlib/test

fijal at codespeak.net fijal at codespeak.net
Tue Oct 16 22:56:51 CEST 2007


Author: fijal
Date: Tue Oct 16 22:56:50 2007
New Revision: 47505

Modified:
   pypy/dist/pypy/module/_ffi/interp_ffi.py
   pypy/dist/pypy/rlib/libffi.py
   pypy/dist/pypy/rlib/test/test_libffi.py
Log:
* Some more rpythonism.
* Disable things that are known to be broken (uchar, ushort and friends)


Modified: pypy/dist/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/interp_ffi.py	(original)
+++ pypy/dist/pypy/module/_ffi/interp_ffi.py	Tue Oct 16 22:56:50 2007
@@ -11,11 +11,11 @@
 
 TYPEMAP = {
     # XXX A mess with unsigned/signed/normal chars :-/
-    'c' : ffi_type_uchar,
-    'b' : ffi_type_schar,
-    'B' : ffi_type_uchar,
-    'h' : ffi_type_sshort,
-    'H' : ffi_type_ushort,
+    #'c' : ffi_type_uchar,
+    #'b' : ffi_type_schar,
+    #'B' : ffi_type_uchar,
+    #'h' : ffi_type_sshort,
+    #'H' : ffi_type_ushort,
     'i' : ffi_type_sint,
     'I' : ffi_type_uint,
     'l' : ffi_type_slong,
@@ -30,11 +30,11 @@
 }
 
 LL_TYPEMAP = {
-    'c' : rffi.CHAR,
-    'b' : rffi.UCHAR,
-    'B' : rffi.CHAR,
-    'h' : rffi.SHORT,
-    'H' : rffi.USHORT,
+    #'c' : rffi.CHAR,
+    #'b' : rffi.UCHAR,
+    #'B' : rffi.CHAR,
+    #'h' : rffi.SHORT,
+    #'H' : rffi.USHORT,
     'i' : rffi.INT,
     'I' : rffi.UINT,
     'l' : rffi.LONG,
@@ -155,7 +155,7 @@
         s = s[0]
         push_func(add_arg, argdesc, s)
     else:
-        assert argtype in "iIhHlLqQ"
+        #assert argtype  "iIhHlLqQ"
         push_func(add_arg, argdesc, space.int_w(w_arg))
 unwrap_arg._annspecialcase_ = 'specialize:arg(1)'
 # we should have also here specialize:argtype(5) :-/
@@ -170,10 +170,14 @@
             elif c == 'P':
                 res = func(arg, rffi.VOIDP)
                 return space.wrap(rffi.cast(rffi.INT, res))
-            elif c == 'q' or c == 'Q' or c == 'L':
-                return space.newlong(func(arg, ll_type))
-            else:
+            #elif c == 'q' or c == 'Q' or c == 'L':
+            #    return space.newlong(func(arg, ll_type))
+            elif c == 'f' or c == 'd':
+                return space.wrap(float(func(arg, ll_type)))
+            elif c == 'c' or c == 'b' or c == 'B':
                 return space.wrap(func(arg, ll_type))
+            else:
+                return space.wrap(intmask(func(arg, ll_type)))
     return space.w_None
 wrap_result._annspecialcase_ = 'specialize:arg(3)'
 
@@ -181,16 +185,16 @@
     return ptr.call(ll_type)
 ptr_call._annspecialcase_ = 'specialize:arg(1)'
 
+def push(ptr, argdesc, value):
+    ptr.push_arg(value)
+push._annspecialcase_ = 'specialize:argtype(2)'
+
 class W_FuncPtr(Wrappable):
     def __init__(self, ptr, argtypes, restype):
         self.ptr = ptr
         self.restype = restype
         self.argtypes = argtypes
 
-    def push(ptr, argdesc, value):
-        ptr.push_arg(value)
-    push = staticmethod(push)
-
     def call(self, space, arguments):
         args_w, kwds_w = arguments.unpack()
         # C has no keyword arguments
@@ -199,8 +203,10 @@
                 "Provided keyword arguments for C function call"))
         to_free = []
         i = 0
-        for argtype, w_arg in zip(self.argtypes, args_w):
-            unwrap_arg(space, self.push, self.ptr, i, argtype, w_arg, to_free)
+        for i in range(len(self.argtypes)):
+            argtype = self.argtypes[i]
+            w_arg = args_w[i]
+            unwrap_arg(space, push, self.ptr, i, argtype, w_arg, to_free)
             i += 1
         try:
             return wrap_result(space, self.restype, self.ptr, ptr_call)

Modified: pypy/dist/pypy/rlib/libffi.py
==============================================================================
--- pypy/dist/pypy/rlib/libffi.py	(original)
+++ pypy/dist/pypy/rlib/libffi.py	Tue Oct 16 22:56:50 2007
@@ -6,6 +6,7 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import we_are_translated
 
 includes = ['dlfcn.h', 'ffi.h']
 include_dirs = ['/usr/include/libffi']
@@ -144,10 +145,11 @@
     return TYPE_MAP[tp]
 cast_type_to_ffitype._annspecialcase_ = 'specialize:memo'
 
-def push_arg_as_ffiptr(ffitp, TP, arg, ll_buf):
+def push_arg_as_ffiptr(ffitp, arg, ll_buf):
     # this is for primitive types. For structures and arrays
     # would be something different (more dynamic)
-    TP_P = rffi.CArrayPtr(TP)
+    TP = lltype.typeOf(arg)
+    TP_P = lltype.Ptr(rffi.CArray(TP))
     buf = rffi.cast(TP_P, ll_buf)
     buf[0] = arg
 push_arg_as_ffiptr._annspecialcase_ = 'specialize:argtype(1)'
@@ -190,18 +192,22 @@
         if self.pushed_args == self.argnum:
             raise TypeError("Too much arguments, eats %d, pushed %d" %
                             (self.argnum, self.argnum + 1))
-        TP = lltype.typeOf(value)
-        if isinstance(TP, lltype.Ptr):
-            if TP.TO._gckind != 'raw':
-                raise ValueError("Can only push raw values to C, not 'gc'")
-            # XXX probably we should recursively check for struct fields
-            # here, lets just ignore that for now
-            if isinstance(TP.TO, lltype.Array) and not \
-                   TP.TO._hints.get('nolength', None):
-                raise ValueError("Can only push to C arrays without length info")
-        push_arg_as_ffiptr(self.argtypes[self.pushed_args], TP, value,
+        if not we_are_translated():
+            TP = lltype.typeOf(value)
+            if isinstance(TP, lltype.Ptr):
+                if TP.TO._gckind != 'raw':
+                    raise ValueError("Can only push raw values to C, not 'gc'")
+                # XXX probably we should recursively check for struct fields
+                # here, lets just ignore that for now
+                if isinstance(TP.TO, lltype.Array):
+                    try:
+                        TP.TO._hints['nolength']
+                    except KeyError:
+                        raise ValueError("Can only push to C arrays without length info")
+        push_arg_as_ffiptr(self.argtypes[self.pushed_args], value,
                            self.ll_args[self.pushed_args])
         self.pushed_args += 1
+    push_arg._annspecialcase_ = 'specialize:argtype(1)'
 
     def _check_args(self):
         if self.pushed_args < self.argnum:
@@ -215,14 +221,14 @@
         c_ffi_call(self.ll_cif, self.funcsym,
                    rffi.cast(rffi.VOIDP, self.ll_result),
                    rffi.cast(VOIDPP, self.ll_args))
-        if self.restype != ffi_type_void:
-            TP = rffi.CArrayPtr(RES_TP)
+        if RES_TP is not lltype.Void:
+            TP = lltype.Ptr(rffi.CArray(RES_TP))
             res = rffi.cast(TP, self.ll_result)[0]
         else:
             res = None
         self._clean_args()
         return res
-    call._annspecialcase_ = 'specialize:argtype(1)'
+    call._annspecialcase_ = 'specialize:arg(1)'
 
     def __del__(self):
         argnum = len(self.argtypes)

Modified: pypy/dist/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/dist/pypy/rlib/test/test_libffi.py	Tue Oct 16 22:56:50 2007
@@ -112,7 +112,8 @@
             c_pow = libm.getpointer('pow', [ffi_type_double, ffi_type_double], ffi_type_double)
             c_pow.push_arg(x)
             c_pow.push_arg(y)
-            return c_pow.call(rffi.DOUBLE)
+            res = c_pow.call(rffi.DOUBLE)
+            return res
 
         fn = compile(f, [float, float])
         res = fn(2.0, 4.0)



More information about the Pypy-commit mailing list