[pypy-commit] cffi default: Accessing global array variables. C is fun :-/
arigo
noreply at buildbot.pypy.org
Fri Jun 15 20:39:45 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r373:96f9a1b9fe69
Date: 2012-06-15 20:39 +0200
http://bitbucket.org/cffi/cffi/changeset/96f9a1b9fe69/
Log: Accessing global array variables. C is fun :-/
diff --git a/c/_ffi_backend.c b/c/_ffi_backend.c
--- a/c/_ffi_backend.c
+++ b/c/_ffi_backend.c
@@ -3411,6 +3411,7 @@
_cffi_restore_errno,
_cffi_save_errno,
_cffi_from_c_char,
+ convert_to_object,
};
/************************************************************/
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -165,6 +165,9 @@
elif isinstance(tp, model.PointerType):
return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
var, self.gettypenum(tp))
+ elif isinstance(tp, model.ArrayType):
+ return '_cffi_from_c_deref((char *)%s, _cffi_type(%d))' % (
+ var, self.gettypenum(tp))
else:
raise NotImplementedError(tp)
@@ -351,7 +354,8 @@
# ----------
# constants, likely declared with '#define'
- def _generate_cpy_const(self, is_int, name, tp=None, category='const'):
+ def _generate_cpy_const(self, is_int, name, tp=None, category='const',
+ vartp=None):
prnt = self.prnt
funcname = '_cffi_%s_%s' % (category, name)
prnt('static int %s(PyObject *lib)' % funcname)
@@ -359,7 +363,7 @@
prnt(' PyObject *o;')
prnt(' int res;')
if not is_int:
- prnt(' %s;' % tp.get_c_name(' i'))
+ prnt(' %s;' % (vartp or tp).get_c_name(' i'))
else:
assert category == 'const'
#
@@ -452,13 +456,19 @@
# global variables
def generate_cpy_variable_decl(self, tp, name):
- tp_ptr = model.PointerType(tp)
- self._generate_cpy_const(False, name, tp_ptr, category='var')
+ if isinstance(tp, model.ArrayType):
+ tp_ptr = model.PointerType(tp.item)
+ self._generate_cpy_const(False, name, tp, vartp=tp_ptr)
+ else:
+ tp_ptr = model.PointerType(tp)
+ self._generate_cpy_const(False, name, tp_ptr, category='var')
generate_cpy_variable_method = generate_nothing
loading_cpy_variable = loaded_noop
def loaded_cpy_variable(self, tp, name, module, library):
+ if isinstance(tp, model.ArrayType): # a[5] is "constant" in the
+ return # sense that "a=..." is forbidden
# remove ptr=<cdata 'int *'> from the library instance, and replace
# it by a property on the class, which reads/writes into ptr[0].
ptr = getattr(library, name)
@@ -541,7 +551,9 @@
((void(*)(void))_cffi_exports[14])
#define _cffi_from_c_char \
((PyObject *(*)(char))_cffi_exports[15])
-#define _CFFI_NUM_EXPORTS 16
+#define _cffi_from_c_deref \
+ ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16])
+#define _CFFI_NUM_EXPORTS 17
#if SIZEOF_LONG < SIZEOF_LONG_LONG
# define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -373,3 +373,20 @@
lib.somenumber = -6
assert lib.foo() == -42
assert lib.somenumber == -6
+
+def test_access_array_variable():
+ ffi = FFI()
+ ffi.cdef("int foo(int);\n"
+ "int somenumber[5];")
+ lib = ffi.verify("""
+ static int somenumber[] = {2, 2, 3, 4, 5};
+ static int foo(int i) {
+ return somenumber[i] * 7;
+ }
+ """)
+ assert lib.somenumber[3] == 4
+ assert lib.foo(3) == 28
+ lib.somenumber[3] = -6
+ assert lib.foo(3) == -42
+ assert lib.somenumber[3] == -6
+ assert lib.somenumber[4] == 5
More information about the pypy-commit
mailing list