[pypy-svn] r47486 - pypy/dist/pypy/module/_ffi

fijal at codespeak.net fijal at codespeak.net
Tue Oct 16 11:20:23 CEST 2007


Author: fijal
Date: Tue Oct 16 11:20:22 2007
New Revision: 47486

Modified:
   pypy/dist/pypy/module/_ffi/interp_ffi.py
   pypy/dist/pypy/module/_ffi/structure.py
Log:
Make this thing RPython. Also fix setattr.


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 11:20:22 2007
@@ -112,44 +112,48 @@
 """
 )
 
-def pack_pointer(space, w_arg, ptr):
+def pack_pointer(space, argdesc, w_arg, push_func):
     arg = space.str_w(w_arg)
     ll_str = lltype.malloc(rffi.CCHARP.TO, len(arg), flavor='raw')
     for i in range(len(arg)):
         ll_str[i] = arg[i]
-    ptr.push_arg(ll_str)
+    push_func(argdesc, ll_str)
     return ll_str
 
-def push_arg(space, ptr, argnum, argtype, w_arg, to_free):
+def unwrap_arg(space, push_func, argdesc, argtype, w_arg, to_free):
     w = space.wrap
     # XXX how to handle LONGLONG here?
     # they're probably long, so we'll not get them through int_w
     if argtype == "d" or argtype == "f":
-        ptr.push_arg(space.float_w(w_arg))
+        push_func(argdesc, space.float_w(w_arg))
     elif argtype == "s":
         ll_str = rffi.str2charp(space.str_w(w_arg))
-        ptr.push_arg(ll_str)
-        to_free.append(ll_str)
+        if to_free is not None:
+            to_free.append(ll_str)
+        push_func(argdesc, ll_str)
     elif argtype == "P":
         # check for NULL ptr
         if space.is_w(w_arg, space.w_None):
-            ptr.push_arg(lltype.nullptr(rffi.VOIDP.TO))
+            push_func(argdesc, lltype.nullptr(rffi.VOIDP.TO))
         elif space.is_true(space.isinstance(w_arg, space.w_basestring)):
-            to_free.append(pack_pointer(space, w_arg, ptr))
+            if to_free is not None:
+                to_free.append(pack_pointer(space, argdesc, w_arg, push_func))
         else:
             mod = space.getbuiltinmodule('_ffi')
             w_StructureInstance = space.getattr(mod, w('StructureInstance'))
             if space.is_true(space.isinstance(w_arg, w_StructureInstance)):
                 #ptr.push_arg(lltype.cast_int_to_ptr(rffi.VOIDP, space.int_w(space.getattr(w_arg, w('buffer')))))
-                ptr.push_arg(w_arg.ll_buffer)
+                push_func(argdesc, w_arg.ll_buffer)
             else:
                 raise OperationError(space.w_TypeError, w(
                     "Expected structure, array or simple type"))
     elif argtype == "c" or argtype == "b" or argtype == "B":
-        ptr.push_arg(space.str_w(w_arg))
+        push_func(argdesc, space.str_w(w_arg))
     else:
-        assert argtype in ["iIhHlLqQ"]
-        ptr.push_arg(space.int_w(w_arg))
+        assert argtype in "iIhHlLqQ"
+        push_func(argdesc, space.int_w(w_arg))
+unwrap_arg._annspecialcase_ = 'specialize:arg(1)'
+# we should have also here specialize:argtype(5) :-/
 
 ll_typemap_iter = unrolling_iterable(LL_TYPEMAP.items())
 
@@ -174,6 +178,9 @@
         self.restype = restype
         self.argtypes = argtypes
 
+    def push(self, argdesc, value):
+        self.ptr.push_arg(value)
+
     def call(self, space, arguments):
         args_w, kwds_w = arguments.unpack()
         # C has no keyword arguments
@@ -183,7 +190,7 @@
         to_free = []
         i = 0
         for argtype, w_arg in zip(self.argtypes, args_w):
-            push_arg(space, self.ptr, i, argtype, w_arg, to_free)
+            unwrap_arg(space, self.push, i, argtype, w_arg, to_free)
             i += 1
         try:
             return wrap_result(space, self.restype, self.ptr.call)

Modified: pypy/dist/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/structure.py	(original)
+++ pypy/dist/pypy/module/_ffi/structure.py	Tue Oct 16 11:20:22 2007
@@ -12,8 +12,13 @@
 # XXX we've got the very same info in two places - one is native_fmttable
 # the other one is in rlib/libffi, we should refactor it to reuse the same
 # logic, I'll not touch it by now, and refactor it later
-from pypy.module.struct.nativefmttable import native_fmttable
-from pypy.module._ffi.interp_ffi import wrap_result
+from pypy.module.struct.nativefmttable import native_fmttable as struct_native_fmttable
+from pypy.module._ffi.interp_ffi import wrap_result, unwrap_arg
+
+native_fmttable = {}
+for key, value in struct_native_fmttable.items():
+    native_fmttable[key] = {'size': value['size'],
+                            'alignment': value.get('alignment', value['size'])}
 
 def unpack_fields(space, w_fields):
     fields_w = space.unpackiterable(w_fields)
@@ -77,16 +82,20 @@
             "C Structure has no attribute %s" % name))
     getattr.unwrap_spec = ['self', ObjSpace, str]
 
-    def setattr(self, space, attr, value):
-        # XXX value is now always int, needs fixing
+    def push_field(self, num, value):
+        ptr = rffi.ptradd(self.ll_buffer, self.ll_positions[num])
+        TP = lltype.typeOf(value)
+        T = rffi.CArrayPtr(TP)
+        rffi.cast(T, ptr)[0] = value
+    push_field._annspecialcase_ = 'specialize:argtype(2)'
+
+    def setattr(self, space, attr, w_value):
         for i in range(len(self.fields)):
             name, c = self.fields[i]
             if name == attr:
-                pos = rffi.ptradd(self.ll_buffer, self.ll_positions[i])
-                TP = rffi.CArrayPtr(rffi.INT)
-                rffi.cast(TP, pos)[0] = value
+                unwrap_arg(space, self.push_field, i, c, w_value, None)
                 return
-    setattr.unwrap_spec = ['self', ObjSpace, str, int]
+    setattr.unwrap_spec = ['self', ObjSpace, str, W_Root]
 
     def __del__(self):
         if self.free_afterwards:



More information about the Pypy-commit mailing list