[pypy-commit] pypy cffi-1.0: Finish to port the changes to c/_cffi_backend
arigo
noreply at buildbot.pypy.org
Thu May 7 16:02:25 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r77178:3fe66e2f8736
Date: 2015-05-07 16:02 +0200
http://bitbucket.org/pypy/pypy/changeset/3fe66e2f8736/
Log: Finish to port the changes to c/_cffi_backend
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -292,7 +292,8 @@
# here, so better safe (and forbid it) than sorry (and maybe
# crash).
space = self.space
- if ctype.custom_field_pos:
+ ctype.force_lazy_struct()
+ if ctype._custom_field_pos:
raise OperationError(space.w_TypeError,
space.wrap(
"cannot pass as an argument a struct that was completed "
@@ -302,7 +303,7 @@
# walk the fields, expanding arrays into repetitions; first,
# only count how many flattened fields there are
nflat = 0
- for i, cf in enumerate(ctype.fields_list):
+ for i, cf in enumerate(ctype._fields_list):
if cf.is_bitfield():
raise oefmt(space.w_NotImplementedError,
"ctype '%s' not supported as argument or return value"
@@ -334,7 +335,7 @@
# fill it with the ffi types of the fields
nflat = 0
- for i, cf in enumerate(ctype.fields_list):
+ for i, cf in enumerate(ctype._fields_list):
flat = 1
ct = cf.ctype
while isinstance(ct, ctypearray.W_CTypeArray):
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -199,9 +199,11 @@
# a W_CDataPtrToStruct object which has a strong reference
# to a W_CDataNewOwning that really contains the structure.
#
- if ctitem.with_var_array and not space.is_w(w_init, space.w_None):
- datasize = ctitem.convert_struct_from_object(
- lltype.nullptr(rffi.CCHARP.TO), w_init, datasize)
+ if not space.is_w(w_init, space.w_None):
+ ctitem.force_lazy_struct()
+ if ctitem._with_var_array:
+ datasize = ctitem.convert_struct_from_object(
+ lltype.nullptr(rffi.CCHARP.TO), w_init, datasize)
#
cdatastruct = cdataobj.W_CDataNewOwning(space, datasize, ctitem)
ptr = cdatastruct.unsafe_escaping_ptr()
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -16,24 +16,40 @@
class W_CTypeStructOrUnion(W_CType):
- _immutable_fields_ = ['alignment?', 'fields_list?[*]', 'fields_dict?',
- 'custom_field_pos?', 'with_var_array?']
+ _immutable_fields_ = ['alignment?', '_fields_list?[*]', '_fields_dict?',
+ '_custom_field_pos?', '_with_var_array?']
+
+ # three possible states:
+ # - "opaque": for opaque C structs; self.size < 0.
+ # - "lazy": for non-opaque C structs whose _fields_list, _fields_dict,
+ # _custom_field_pos and _with_var_array are not filled yet; can be
+ # filled by calling force_lazy_struct().
+ # (But self.size and .alignment are already set and won't change.)
+ # - "forced": for non-opaque C structs which are fully ready.
+
# fields added by complete_struct_or_union():
alignment = -1
- fields_list = None
- fields_dict = None
- custom_field_pos = False
- with_var_array = False
+ _fields_list = None
+ _fields_dict = None
+ _custom_field_pos = False
+ _with_var_array = False
def __init__(self, space, name):
W_CType.__init__(self, space, -1, name, len(name))
def check_complete(self, w_errorcls=None):
- if self.fields_dict is None:
+ # Check ONLY that are are not opaque. Complain if we are.
+ if self.size < 0:
space = self.space
raise oefmt(w_errorcls or space.w_TypeError,
"'%s' is opaque or not completed yet", self.name)
+ def force_lazy_struct(self, w_errorcls=None):
+ # Force a "lazy" struct to become "forced"; complain if we are "opaque".
+ if self._fields_list is None:
+ self.check_complete()
+ XXXXX
+
def _alignof(self):
self.check_complete(w_errorcls=self.space.w_ValueError)
return self.alignment
@@ -43,9 +59,10 @@
space = self.space
if self.size < 0:
return space.w_None
- result = [None] * len(self.fields_list)
- for fname, field in self.fields_dict.iteritems():
- i = self.fields_list.index(field)
+ self.force_lazy_struct()
+ result = [None] * len(self._fields_list)
+ for fname, field in self._fields_dict.iteritems():
+ i = self._fields_list.index(field)
result[i] = space.newtuple([space.wrap(fname),
space.wrap(field)])
return space.newlist(result)
@@ -65,10 +82,10 @@
return ob
def typeoffsetof_field(self, fieldname, following):
- self.check_complete()
+ self.force_lazy_struct()
space = self.space
try:
- cfield = self.fields_dict[fieldname]
+ cfield = self._fields_dict[fieldname]
except KeyError:
raise OperationError(space.w_KeyError, space.wrap(fieldname))
if cfield.bitshift >= 0:
@@ -95,19 +112,20 @@
lambda self, cdata, w_ob, optvarsize: jit.isvirtual(w_ob)
)
def convert_struct_from_object(self, cdata, w_ob, optvarsize):
+ self.force_lazy_struct()
self._check_only_one_argument_for_union(w_ob)
space = self.space
if (space.isinstance_w(w_ob, space.w_list) or
space.isinstance_w(w_ob, space.w_tuple)):
lst_w = space.listview(w_ob)
- if len(lst_w) > len(self.fields_list):
+ if len(lst_w) > len(self._fields_list):
raise oefmt(space.w_ValueError,
"too many initializers for '%s' (got %d)",
self.name, len(lst_w))
for i in range(len(lst_w)):
- optvarsize = self.fields_list[i].write_v(cdata, lst_w[i],
- optvarsize)
+ optvarsize = self._fields_list[i].write_v(cdata, lst_w[i],
+ optvarsize)
return optvarsize
elif space.isinstance_w(w_ob, space.w_dict):
@@ -116,7 +134,7 @@
w_key = lst_w[i]
key = space.str_w(w_key)
try:
- cf = self.fields_dict[key]
+ cf = self._fields_dict[key]
except KeyError:
space.raise_key_error(w_key)
assert 0
@@ -133,10 +151,14 @@
@jit.elidable
def _getcfield_const(self, attr):
- return self.fields_dict[attr]
+ return self._fields_dict[attr]
def getcfield(self, attr):
- if self.fields_dict is not None:
+ ready = self._fields_dict is not None
+ if not ready and self.size >= 0:
+ self.force_lazy_struct()
+ ready = True
+ if ready:
self = jit.promote(self)
attr = jit.promote_string(attr)
try:
diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -349,9 +349,10 @@
isinstance(ftype, ctypestruct.W_CTypeStructOrUnion)):
# a nested anonymous struct or union
srcfield2names = {}
- for name, srcfld in ftype.fields_dict.items():
+ ftype.force_lazy_struct()
+ for name, srcfld in ftype._fields_dict.items():
srcfield2names[srcfld] = name
- for srcfld in ftype.fields_list:
+ for srcfld in ftype._fields_list:
fld = srcfld.make_shifted(boffset // 8)
fields_list.append(fld)
try:
@@ -492,10 +493,10 @@
w_ctype.size = totalsize
w_ctype.alignment = totalalignment
- w_ctype.fields_list = fields_list[:]
- w_ctype.fields_dict = fields_dict
- w_ctype.custom_field_pos = custom_field_pos
- w_ctype.with_var_array = with_var_array
+ w_ctype._fields_list = fields_list[:]
+ w_ctype._fields_dict = fields_dict
+ w_ctype._custom_field_pos = custom_field_pos
+ w_ctype._with_var_array = with_var_array
# ____________________________________________________________
More information about the pypy-commit
mailing list