[pypy-commit] pypy cffi-1.0: Globals

arigo noreply at buildbot.pypy.org
Fri May 8 10:25:00 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r77191:fe991631ae9c
Date: 2015-05-08 09:29 +0200
http://bitbucket.org/pypy/pypy/changeset/fe991631ae9c/

Log:	Globals

diff --git a/pypy/module/_cffi_backend/cglob.py b/pypy/module/_cffi_backend/cglob.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_cffi_backend/cglob.py
@@ -0,0 +1,16 @@
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.typedef import TypeDef
+from pypy.module._cffi_backend.cdataobj import W_CData
+
+
+class W_GlobSupport(W_Root):
+    def __init__(self, space, w_ctype, ptr):
+        self.space = space
+        self.w_ctype = w_ctype
+        self.ptr = ptr
+
+    def read_global_var(self):
+        return self.w_ctype.convert_to_object(self.ptr)
+
+W_GlobSupport.typedef = TypeDef("FFIGlobSupport")
+W_GlobSupport.typedef.acceptable_as_base_class = False
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
@@ -6,7 +6,8 @@
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app
 
-from pypy.module._cffi_backend import parse_c_type, realize_c_type, cffi_opcode
+from pypy.module._cffi_backend import parse_c_type, realize_c_type
+from pypy.module._cffi_backend import cffi_opcode, cglob
 from pypy.module._cffi_backend.realize_c_type import getop, getarg
 from pypy.module._cffi_backend.cdataobj import W_CData
 
@@ -33,22 +34,40 @@
             if index < 0:
                 return None     # no active caching, but still @elidable
 
+            space = self.space
             g = self.ctx.c_globals[index]
             op = getop(g.c_type_op)
             if (op == cffi_opcode.OP_CPYTHON_BLTN_V or
                 op == cffi_opcode.OP_CPYTHON_BLTN_N or
                 op == cffi_opcode.OP_CPYTHON_BLTN_O):
-                #
+                # A function: in the PyPy version, these are all equivalent
+                # and 'g->address' is a pointer to a function of exactly the
+                # C type specified
                 type_index = getarg(g.c_type_op)
                 opcodes = self.ctx.c_types
                 w_ct = realize_c_type.realize_c_type_or_func(self.ffi, opcodes,
                                                              type_index)
                 w_ct = realize_c_type.unwrap_fn_as_fnptr(w_ct)
                 ptr = rffi.cast(rffi.CCHARP, g.c_address)
-                w_result = W_CData(self.space, ptr, w_ct)
+                w_result = W_CData(space, ptr, w_ct)
+                #
+            elif op == cffi_opcode.OP_GLOBAL_VAR:
+                # A global variable of the exact type specified here
+                type_index = getarg(g.c_type_op)
+                opcodes = self.ctx.c_types
+                w_ct = realize_c_type.realize_c_type(self.ffi, opcodes,
+                                                     type_index)
+                g_size = rffi.getintfield(g, 'c_size')
+                if g_size != w_ct.size and g_size != 0 and w_ct.size > 0:
+                    raise oefmt(self.ffi.w_FFIError,
+                            "global variable '%s' should be %d bytes "
+                            "according to the cdef, but is actually %d",
+                            attr, w_ct.size, g_size)
+                ptr = rffi.cast(rffi.CCHARP, g.c_address)
+                w_result = cglob.W_GlobSupport(space, w_ct, ptr)
                 #
             else:
-                raise oefmt(ffi.space.w_NotImplementedError,
+                raise oefmt(space.w_NotImplementedError,
                             "in lib_build_attr: op=%d", op)
 
             self.dict_w[attr] = w_result
@@ -66,8 +85,8 @@
         w_value = self._get_attr(attr)
         if w_value is None:
             raise self._no_such_attr(attr)
-        #elif isinstance(w_value, Globxxx):
-        #    ...
+        elif isinstance(w_value, cglob.W_GlobSupport):
+            w_value = w_value.read_global_var()
         return w_value
 
 
@@ -76,4 +95,4 @@
         __repr__ = interp2app(W_LibObject.descr_repr),
         __getattribute__ = interp2app(W_LibObject.descr_getattribute),
         )
-W_LibObject.acceptable_as_base_class = False
+W_LibObject.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py
--- a/pypy/module/_cffi_backend/libraryobj.py
+++ b/pypy/module/_cffi_backend/libraryobj.py
@@ -91,7 +91,7 @@
     read_variable = interp2app(W_Library.read_variable),
     write_variable = interp2app(W_Library.write_variable),
     )
-W_Library.acceptable_as_base_class = False
+W_Library.typedef.acceptable_as_base_class = False
 
 
 @unwrap_spec(filename="str_or_None", flags=int)


More information about the pypy-commit mailing list