Author: Armin Rigo <ar...@tunes.org> Branch: cffi-1.0 Changeset: r77223:f259e960f2a7 Date: 2015-05-08 17:51 +0200 http://bitbucket.org/pypy/pypy/changeset/f259e960f2a7/
Log: Next test diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py --- a/pypy/module/_cffi_backend/ffi_obj.py +++ b/pypy/module/_cffi_backend/ffi_obj.py @@ -44,6 +44,7 @@ else: self.cached_types = None self.w_FFIError = get_ffi_error(space) + self.included_libs = [] # list of W_LibObject's included here @jit.elidable def parse_string_to_type(self, string, flags): diff --git a/pypy/module/_cffi_backend/lib_obj.py b/pypy/module/_cffi_backend/lib_obj.py --- a/pypy/module/_cffi_backend/lib_obj.py +++ b/pypy/module/_cffi_backend/lib_obj.py @@ -20,7 +20,6 @@ self.ffi = ffi self.dict_w = {} # content, built lazily self.libname = libname # some string that gives the name of the lib - self.includes = [] # list of W_LibObjects included here def descr_repr(self): return self.space.wrap("<Lib object for '%s'>" % self.libname) @@ -37,7 +36,7 @@ lib1 = space.interp_w(W_LibObject, w_lib1) includes.append(lib1) num += 1 - self.includes = includes[:] + self.ffi.included_libs = includes[:] @jit.elidable_promote() def _get_attr_elidable(self, attr): @@ -46,7 +45,7 @@ except KeyError: index = parse_c_type.search_in_globals(self.ctx, attr) if index < 0: - for lib1 in self.includes: + for lib1 in self.ffi.included_libs: w_result = lib1._get_attr_elidable(attr) if w_result is not None: return w_result diff --git a/pypy/module/_cffi_backend/parse_c_type.py b/pypy/module/_cffi_backend/parse_c_type.py --- a/pypy/module/_cffi_backend/parse_c_type.py +++ b/pypy/module/_cffi_backend/parse_c_type.py @@ -73,6 +73,9 @@ ll_search_in_globals = llexternal('pypy_search_in_globals', [PCTX, rffi.CCHARP, rffi.SIZE_T], rffi.INT) +ll_search_in_struct_unions = llexternal('pypy_search_in_struct_unions', + [PCTX, rffi.CCHARP, rffi.SIZE_T], + rffi.INT) def parse_c_type(info, input): p_input = rffi.str2charp(input) @@ -113,3 +116,10 @@ rffi.cast(rffi.SIZE_T, len(name))) rffi.free_charp(c_name) return rffi.cast(lltype.Signed, result) + +def search_in_struct_unions(ctx, name): + c_name = rffi.str2charp(name) + result = ll_search_in_struct_unions(ctx, c_name, + rffi.cast(rffi.SIZE_T, len(name))) + rffi.free_charp(c_name) + return rffi.cast(lltype.Signed, result) diff --git a/pypy/module/_cffi_backend/realize_c_type.py b/pypy/module/_cffi_backend/realize_c_type.py --- a/pypy/module/_cffi_backend/realize_c_type.py +++ b/pypy/module/_cffi_backend/realize_c_type.py @@ -183,7 +183,12 @@ w_ctype._lazy_ffi = ffi w_ctype._lazy_s = s else: - yyyy + x = _fetch_external_struct_or_union(s, ffi.included_libs) + if x is None: + raise oefmt(ffi.w_FFIError, + "'%s %s' should come from ffi.include() but was not found", + "union" if c_flags & cffi_opcode.F_UNION else "struct", + rffi.charp2str(s.c_name)) # Update the "primary" OP_STRUCT_UNION slot ffi.cached_types[type_index] = x @@ -385,3 +390,27 @@ w_ctype._lazy_ffi = None w_ctype._lazy_s = lltype.nullptr(parse_c_type.FIELD_S) + + +def _fetch_external_struct_or_union(s, included_libs): + name = rffi.charp2str(s.c_name) + # + for lib1 in included_libs: + sindex = parse_c_type.search_in_struct_unions(lib1.ctx, name) + if sindex < 0: # not found at all + continue + + s1 = lib1.ctx.c_struct_unions[sindex] + s1_flags = rffi.getintfield(s1, 'c_flags') + s_flags = rffi.getintfield(s, 'c_flags') + if ((s1_flags & (cffi_opcode.F_EXTERNAL | cffi_opcode.F_UNION)) + == (s_flags & cffi_opcode.F_UNION)): + # s1 is not external, and the same kind (struct or union) as s + return _realize_c_struct_or_union(lib1.ffi, sindex) + + # not found, look more recursively + if len(lib1.ffi.included_libs) > 0: + w_res = _fetch_external_struct_or_union(s, lib1.ffi.included_libs) + if w_res is not None: + return w_res + return None diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py --- a/pypy/module/_cffi_backend/test/test_recompiler.py +++ b/pypy/module/_cffi_backend/test/test_recompiler.py @@ -497,16 +497,17 @@ assert lib.foo2(42) == 37 assert lib.foo1(42) == 52 - def test_include_2(): - ffi1 = FFI() - ffi1.cdef("struct foo_s { int x, y; };") - verify(ffi1, "test_include_2_parent", "struct foo_s { int x, y; };") - ffi = FFI() - ffi.include(ffi1) - ffi.cdef("struct foo_s *ff2(struct foo_s *);") - lib = verify(ffi, "test_include_2", - "struct foo_s { int x, y; }; //usually from a #include\n" - "struct foo_s *ff2(struct foo_s *p) { p->y++; return p; }") + def test_include_2(self): + ffi1, lib1 = self.prepare( + "struct foo_s { int x, y; };", + "test_include_2_parent", + "struct foo_s { int x, y; };") + ffi, lib = self.prepare( + "struct foo_s *ff2(struct foo_s *);", + "test_include_2", + "struct foo_s { int x, y; }; //usually from a #include\n" + "struct foo_s *ff2(struct foo_s *p) { p->y++; return p; }", + includes=[ffi1]) p = ffi.new("struct foo_s *") p.y = 41 q = lib.ff2(p) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit