Author: Antonio Cuni <[email protected]>
Branch: ffistruct
Changeset: r55088:0d600e8db028
Date: 2012-05-14 20:42 +0200
http://bitbucket.org/pypy/pypy/changeset/0d600e8db028/

Log:    remove ffitype from the _immutable_fields_ and use an elidable
        method instead. This will make it possible to instantiate
        'incomplete types' whose ffitype is not known yet

diff --git a/pypy/module/_ffi/interp_ffitype.py 
b/pypy/module/_ffi/interp_ffitype.py
--- a/pypy/module/_ffi/interp_ffitype.py
+++ b/pypy/module/_ffi/interp_ffitype.py
@@ -1,22 +1,29 @@
 from pypy.rlib import libffi
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib import jit
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.interpreter.gateway import interp2app
 
 class W_FFIType(Wrappable):
 
-    _immutable_fields_ = ['name', 'ffitype', 'w_datashape', 'w_pointer_to']
+    _immutable_fields_ = ['name', 'w_datashape', 'w_pointer_to']
 
     def __init__(self, name, ffitype, w_datashape=None, w_pointer_to=None):
         self.name = name
-        self.ffitype = ffitype
+        self._ffitype = ffitype
         self.w_datashape = w_datashape
         self.w_pointer_to = w_pointer_to
         ## XXX: re-enable this check when the ffistruct branch is done
         ## if self.is_struct():
         ##     assert w_datashape is not None
 
+    @jit.elidable
+    def get_ffitype(self):
+        if not self._ffitype:
+            raise ValueError("Operation not permitted on an incomplete type")
+        return self._ffitype
+
     def descr_deref_pointer(self, space):
         if self.w_pointer_to is None:
             return space.w_None
@@ -26,16 +33,19 @@
         return space.wrap(self.sizeof())
 
     def sizeof(self):
-        return intmask(self.ffitype.c_size)
+        return intmask(self.get_ffitype().c_size)
 
     def get_alignment(self):
-        return intmask(self.ffitype.c_alignment)
+        return intmask(self.get_ffitype().c_alignment)
 
     def repr(self, space):
         return space.wrap(self.__repr__())
 
     def __repr__(self):
-        return "<ffi type %s>" % self.name
+        name = self.name
+        if not self._ffitype:
+            name += ' (incomplete)'
+        return "<ffi type %s>" % name
 
     def is_signed(self):
         return (self is app_types.slong or
@@ -52,7 +62,7 @@
                 self is app_types.ulonglong)
 
     def is_pointer(self):
-        return self.ffitype is libffi.types.pointer
+        return self.get_ffitype() is libffi.types.pointer
 
     def is_char(self):
         return self is app_types.char
@@ -74,7 +84,7 @@
         return self is app_types.void
 
     def is_struct(self):
-        return libffi.types.is_struct(self.ffitype)
+        return libffi.types.is_struct(self.get_ffitype())
 
     def is_char_p(self):
         return self is app_types.char_p
diff --git a/pypy/module/_ffi/interp_funcptr.py 
b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -16,7 +16,7 @@
 
 
 def unwrap_ffitype(space, w_argtype, allow_void=False):
-    res = w_argtype.ffitype
+    res = w_argtype.get_ffitype()
     if res is libffi.types.void and not allow_void:
         msg = 'void is not a valid argument type'
         raise OperationError(space.w_TypeError, space.wrap(msg))
@@ -154,7 +154,7 @@
         # that, we cast it back to LONG, because this is what we want to pass
         # to space.wrap in order to get a nice applevel <int>.
         #
-        restype = w_ffitype.ffitype
+        restype = w_ffitype.get_ffitype()
         call = self.func.call
         if restype is libffi.types.slong:
             return call(self.argchain, rffi.LONG)
@@ -172,7 +172,7 @@
 
     def get_unsigned_which_fits_into_a_signed(self, w_ffitype):
         # the same comment as get_signed apply
-        restype = w_ffitype.ffitype
+        restype = w_ffitype.get_ffitype()
         call = self.func.call
         if restype is libffi.types.uint:
             assert not libffi.IS_32_BIT
diff --git a/pypy/module/_ffi/interp_struct.py 
b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -76,7 +76,7 @@
     size, alignment, fields_w = compute_size_and_alignement(space, fields_w)
     field_types = [] # clibffi's types
     for w_field in fields_w:
-        field_types.append(w_field.w_ffitype.ffitype)
+        field_types.append(w_field.w_ffitype.get_ffitype())
     ffistruct = clibffi.make_struct_ffitype_e(size, alignment, field_types)
     return W__StructDescr(space, name, fields_w, ffistruct)
 
@@ -167,27 +167,32 @@
 
 
     def get_signed(self, w_ffitype):
-        return libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, 
self.offset)
+        return libffi.struct_getfield_int(w_ffitype.get_ffitype(),
+                                          self.rawmem, self.offset)
 
     def get_unsigned(self, w_ffitype):
-        value = libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, 
self.offset)
+        value = libffi.struct_getfield_int(w_ffitype.get_ffitype(),
+                                           self.rawmem, self.offset)
         return r_uint(value)
 
     get_unsigned_which_fits_into_a_signed = get_signed
     get_pointer = get_unsigned
 
     def get_char(self, w_ffitype):
-        return libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, 
self.offset)
+        return libffi.struct_getfield_int(w_ffitype.get_ffitype(),
+                                          self.rawmem, self.offset)
 
     def get_unichar(self, w_ffitype):
-        return libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, 
self.offset)
+        return libffi.struct_getfield_int(w_ffitype.get_ffitype(),
+                                          self.rawmem, self.offset)
 
     def get_float(self, w_ffitype):
-        return libffi.struct_getfield_float(w_ffitype.ffitype, self.rawmem, 
self.offset)
+        return libffi.struct_getfield_float(w_ffitype.get_ffitype(),
+                                            self.rawmem, self.offset)
 
     def get_singlefloat(self, w_ffitype):
-        return libffi.struct_getfield_singlefloat(w_ffitype.ffitype, 
self.rawmem,
-                                                  self.offset)
+        return libffi.struct_getfield_singlefloat(w_ffitype.get_ffitype(),
+                                                  self.rawmem, self.offset)
 
     ## def get_struct(self, w_datashape):
     ##     ...
@@ -208,11 +213,11 @@
         self.offset = offset
 
     def handle_signed(self, w_ffitype, w_obj, intval):
-        libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, self.offset,
+        libffi.struct_setfield_int(w_ffitype.get_ffitype(), self.rawmem, 
self.offset,
                                    intval)
 
     def handle_unsigned(self, w_ffitype, w_obj, uintval):
-        libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, self.offset,
+        libffi.struct_setfield_int(w_ffitype.get_ffitype(), self.rawmem, 
self.offset,
                                    intmask(uintval))
 
     handle_pointer = handle_signed
@@ -220,16 +225,16 @@
     handle_unichar = handle_signed
 
     def handle_longlong(self, w_ffitype, w_obj, longlongval):
-        libffi.struct_setfield_longlong(w_ffitype.ffitype, self.rawmem, 
self.offset,
-                                        longlongval)
+        libffi.struct_setfield_longlong(w_ffitype.get_ffitype(),
+                                        self.rawmem, self.offset, longlongval)
 
     def handle_float(self, w_ffitype, w_obj, floatval):
-        libffi.struct_setfield_float(w_ffitype.ffitype, self.rawmem, 
self.offset,
-                                     floatval)
+        libffi.struct_setfield_float(w_ffitype.get_ffitype(),
+                                     self.rawmem, self.offset, floatval)
 
     def handle_singlefloat(self, w_ffitype, w_obj, singlefloatval):
-        libffi.struct_setfield_singlefloat(w_ffitype.ffitype, self.rawmem, 
self.offset,
-                                           singlefloatval)
+        libffi.struct_setfield_singlefloat(w_ffitype.get_ffitype(),
+                                           self.rawmem, self.offset, 
singlefloatval)
 
     ## def handle_struct(self, w_ffitype, w_structinstance):
     ##     ...
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -141,6 +141,7 @@
 
 FFI_TYPE_P = lltype.Ptr(lltype.ForwardReference())
 FFI_TYPE_PP = rffi.CArrayPtr(FFI_TYPE_P)
+FFI_TYPE_NULL = lltype.nullptr(FFI_TYPE_P.TO)
 
 class CConfig:
     _compilation_info_ = eci
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -210,7 +210,7 @@
 
     _immutable_fields_ = ['funcsym']
     argtypes = []
-    restype = lltype.nullptr(clibffi.FFI_TYPE_P.TO)
+    restype = clibffi.FFI_TYPE_NULL
     flags = 0
     funcsym = lltype.nullptr(rffi.VOIDP.TO)
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to