Author: Armin Rigo <ar...@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 # ____________________________________________________________ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit