Commit 7c71c9c9 authored by Armin Rigo's avatar Armin Rigo
Browse files

Finish the (non-partial) struct verification. For now uses

'typeof()', which is a gcc extension.

branch : linux-only
parent 369b47a0aaf7
......@@ -84,7 +84,7 @@ class FFI(object):
corresponding Python type: <class 'ffi.CData<...>'>.
It can also be used on 'cdata' instance to get its C type.
if isinstance(cdecl, (str, unicode)):
if isinstance(cdecl, basestring):
return self._parsed_types[cdecl]
except KeyError:
......@@ -99,7 +99,7 @@ class FFI(object):
"""Return the size in bytes of the argument. It can be a
string naming a C type, or a 'cdata' instance.
if isinstance(cdecl, (str, unicode)):
if isinstance(cdecl, basestring):
BType = self.typeof(cdecl)
return self._backend.sizeof(BType)
......@@ -109,15 +109,17 @@ class FFI(object):
"""Return the natural alignment size in bytes of the C type
given as a string.
BType = self.typeof(cdecl)
return self._backend.alignof(BType)
if isinstance(cdecl, basestring):
cdecl = self.typeof(cdecl)
return self._backend.alignof(cdecl)
def offsetof(self, cdecl, fieldname):
"""Return the offset of the named field inside the given
structure, which must be given as a C type name.
BType = self.typeof(cdecl)
return self._backend.offsetof(BType, fieldname)
if isinstance(cdecl, basestring):
cdecl = self.typeof(cdecl)
return self._backend.offsetof(cdecl, fieldname)
def new(self, cdecl, init=None):
"""Allocate an instance 'x' of the named C type, and return a
......@@ -27,7 +27,7 @@ class BaseType(object):
return self.new_backend_type(ffi, *args)
def verifier_declare_typedef(self, verifier, name):
verifier.write('{ %s = (%s**)0; }' % (
verifier.write('__sametype__(%s, %s)' % (
self.get_c_name('** result'), name))
......@@ -170,19 +170,37 @@ class StructType(StructOrUnion):
return ffi._backend.new_struct_type(
def verifier_declare_struct(self, verifier, name):
assert name ==
if self.partial:
self.verifier_decl_partial(verifier, name)
self.verifier_decl_notpartial(verifier, name)
def verifier_decl_notpartial(self, verifier, name):
def verifier_decl_notpartial(self, verifier):
if self.fldnames is None: # not partial, but fully opaque:
return # cannot really test even for existence
struct = verifier.ffi._get_cached_btype(self)
verifier.write('__sameconstant__(sizeof(struct %s), %d)' % (
name, verifier.ffi.sizeof(struct)))
verifier.write('struct __aligncheck__ { char x; struct %s y; };' %
'__sameconstant__(sizeof(struct %s), %d)' % (, verifier.ffi.sizeof(struct)))
'__sameconstant__(offsetof(struct __aligncheck__, y), %d)' % (
for fname, ftype, fbitsize in zip(self.fldnames, self.fldtypes,
if fbitsize >= 0:
assert 0, "XXX: bitfield"
verifier.write('__sameconstant__(offsetof(struct %s, %s), %d)' % (, fname, verifier.ffi.offsetof(struct, fname)))
# XXX gcc only!
verifier.write('__sametype__(%s, typeof(((struct %s *)0)->%s))' % (
ftype.get_c_name('** result'),, fname))
def verifier_decl_partial(self, verifier, name):
def verifier_decl_partial(self, verifier):
assert self.fldnames is not None
verifier.write('struct __aligncheck__ { char x; struct %s y; };' %
......@@ -21,15 +21,19 @@ class Verifier(object):
tst_file_base = ffiplatform._get_test_file_base()
self.has_printf = False
with open(tst_file_base + '.c', 'w') as f:
f.write('#include <stdio.h>\n'
'#include <stdint.h>\n'
'#include <stddef.h>\n'
'#include <unistd.h>\n'
'#define __sameconstant__(x, y) \\\n'
' { int result[1-2*((x)-(y))*((x)-(y))]; }\n'
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
#define __sameconstant__(x, y) \\
{ int result[1-2*((x)-(y))*((x)-(y))]; }
#define __sametype__(ppresult, typename) \\
{ ppresult = (typename**)0; }
f.write(preamble + "\n\n")
f.write('int main() {\n')
self.f = f
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment