[pypy-commit] cffi c99-array: Fix vengine_gen for global arrays with [...].

arigo noreply at buildbot.pypy.org
Fri Nov 8 20:47:23 CET 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: c99-array
Changeset: r1389:2a2ec0277dbf
Date: 2013-11-08 20:29 +0100
http://bitbucket.org/cffi/cffi/changeset/2a2ec0277dbf/

Log:	Fix vengine_gen for global arrays with [...].

diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py
--- a/cffi/vengine_gen.py
+++ b/cffi/vengine_gen.py
@@ -472,6 +472,14 @@
 
     def _generate_gen_variable_decl(self, tp, name):
         if isinstance(tp, model.ArrayType):
+            if tp.length == '...':
+                prnt = self._prnt
+                funcname = '_cffi_sizeof_%s' % (name,)
+                self.export_symbols.append(funcname)
+                prnt("size_t %s(void)" % funcname)
+                prnt("{")
+                prnt("  return sizeof(%s);" % (name,))
+                prnt("}")
             tp_ptr = model.PointerType(tp.item)
             self._generate_gen_const(False, name, tp_ptr)
         else:
@@ -483,11 +491,23 @@
     def _loaded_gen_variable(self, tp, name, module, library):
         if isinstance(tp, model.ArrayType):   # int a[5] is "constant" in the
                                               # sense that "a=..." is forbidden
+            if tp.length == '...':
+                funcname = '_cffi_sizeof_%s' % (name,)
+                BFunc = self.ffi.typeof('size_t(*)(void)')
+                function = module.load_function(BFunc, funcname)
+                size = function()
+                BItemType = self.ffi._get_cached_btype(tp.item)
+                length, rest = divmod(size, self.ffi.sizeof(BItemType))
+                if rest != 0:
+                    raise ffiplatform.VerificationError(
+                        "bad size: %r does not seem to be an array of %s" %
+                        (name, tp.item))
+                tp = tp.resolve_length(length)
             tp_ptr = model.PointerType(tp.item)
             value = self._load_constant(False, tp_ptr, name, module)
             # 'value' is a <cdata 'type *'> which we have to replace with
             # a <cdata 'type[N]'> if the N is actually known
-            if tp.length is not None and tp.length != '...':
+            if tp.length is not None:
                 BArray = self.ffi._get_cached_btype(tp)
                 value = self.ffi.cast(BArray, value)
             setattr(library, name, value)
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1509,7 +1509,12 @@
     ffi = FFI()
     ffi.cdef("int fooarray[...];")
     lib = ffi.verify("int fooarray[50];")
-    assert repr(lib.fooarray).startswith("<cdata 'int *'")
+    assert repr(lib.fooarray).startswith("<cdata 'int[50]'")
+
+def test_bad_global_array_with_dotdotdot_length():
+    ffi = FFI()
+    ffi.cdef("int fooarray[...];")
+    py.test.raises(VerificationError, ffi.verify, "char fooarray[23];")
 
 def test_struct_containing_struct():
     ffi = FFI()


More information about the pypy-commit mailing list