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