[pypy-svn] r72828 - in pypy/branch/fix-64/pypy/rpython/tool: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Mar 25 17:36:27 CET 2010
Author: arigo
Date: Thu Mar 25 17:36:26 2010
New Revision: 72828
Modified:
pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py
pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py
Log:
Whack whack whack until the test passes.
Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py (original)
+++ pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py Thu Mar 25 17:36:26 2010
@@ -299,11 +299,16 @@
fieldoffsets.append(offset)
seen[cell] = True
+ allfields = tuple(['c_' + name for name, _ in fields])
+ padfields = tuple(padfields)
name = self.name
+ padding_drop = PaddingDrop(name, allfields, padfields,
+ config_result.CConfig._compilation_info_)
hints = {'align': info['align'],
'size': info['size'],
'fieldoffsets': tuple(fieldoffsets),
- 'padding': tuple(padfields)}
+ 'padding': padfields,
+ 'get_padding_drop': padding_drop}
if name.startswith('struct '):
name = name[7:]
else:
@@ -477,6 +482,85 @@
return info['size']
# ____________________________________________________________
+
+class PaddingDrop(object):
+ # Compute (lazily) the padding_drop for a structure.
+ # See test_generate_padding for more information.
+ cache = None
+
+ def __init__(self, name, allfields, padfields, eci):
+ self.name = name
+ self.allfields = allfields
+ self.padfields = padfields
+ self.eci = eci
+
+ def __call__(self, types):
+ if self.cache is None:
+ self.compute_now(types)
+ return self.cache
+
+ def compute_now(self, types):
+ # Some simplifying assumptions there. We assume that all fields
+ # are either integers or pointers, so can be written in C as '0'.
+ # We also assume that the C backend gives us in 'types' a dictionary
+ # mapping non-padding field names to their C type (without '@').
+ drops = []
+ staticfields = []
+ consecutive_pads = []
+ for fieldname in self.allfields:
+ if fieldname in self.padfields:
+ consecutive_pads.append(fieldname)
+ continue
+ staticfields.append(types[fieldname])
+ if consecutive_pads:
+ # In that case we have to ask: how many of these pads are
+ # really needed? The correct answer might be between none
+ # and all of the pads listed in 'consecutive_pads'.
+ for i in range(len(consecutive_pads)+1):
+ class CConfig:
+ _compilation_info_ = self.eci
+ FIELDLOOKUP = _PaddingDropFieldLookup(self.name,
+ staticfields,
+ fieldname)
+ got = configure(CConfig)['FIELDLOOKUP']
+ if got == 1:
+ break # found
+ staticfields.insert(-1, None)
+ else:
+ raise Exception("could not determine the detailed field"
+ " layout of %r" % (self.name,))
+ # succeeded with 'i' pads. Drop all pads beyond that.
+ drops += consecutive_pads[i:]
+ consecutive_pads = []
+ self.cache = drops
+
+class _PaddingDropFieldLookup(CConfigEntry):
+ def __init__(self, name, staticfields, fieldname):
+ self.name = name
+ self.staticfields = staticfields
+ self.fieldname = fieldname
+
+ def prepare_code(self):
+ yield 'typedef %s platcheck_t;' % (self.name,)
+ yield 'static platcheck_t s = {'
+ for i, type in enumerate(self.staticfields):
+ if i == len(self.staticfields)-1:
+ value = -1
+ else:
+ value = 0
+ if type:
+ yield '\t(%s)%s,' % (type, value)
+ else:
+ yield '\t%s,' % (value,)
+ yield '};'
+ fieldname = self.fieldname
+ assert fieldname.startswith('c_')
+ yield 'dump("fieldlookup", s.%s != 0);' % (fieldname[2:],)
+
+ def build_result(self, info, config_result):
+ return info['fieldlookup']
+
+# ____________________________________________________________
#
# internal helpers
Modified: pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py
==============================================================================
--- pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py (original)
+++ pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Thu Mar 25 17:36:26 2010
@@ -275,7 +275,8 @@
""", [("c1", lltype.Signed),
("s1", lltype.Signed)])
assert S._hints['padding'] == ('c__pad0',)
- assert S._hints['padding_drop'] == ('c__pad0',)
+ d = {'c_c1': 'char', 'c_s1': 'short'}
+ assert S._hints['get_padding_drop'](d) == ['c__pad0']
#
S = rffi_platform.getstruct("foobar_t", """
typedef struct {
@@ -286,7 +287,8 @@
""", [("c1", lltype.Signed),
("s1", lltype.Signed)])
assert S._hints['padding'] == ('c__pad0',)
- assert S._hints['padding_drop'] == ()
+ d = {'c_c1': 'char', 'c_s1': 'short'}
+ assert S._hints['get_padding_drop'](d) == []
#
S = rffi_platform.getstruct("foobar_t", """
typedef struct {
@@ -298,7 +300,8 @@
""", [("c1", lltype.Signed),
("i1", lltype.Signed)])
assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2')
- assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2')
+ d = {'c_c1': 'char', 'c_i1': 'int'}
+ assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2']
#
S = rffi_platform.getstruct("foobar_t", """
typedef struct {
@@ -311,7 +314,8 @@
""", [("c1", lltype.Signed),
("i1", lltype.Signed)])
assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2')
- assert S._hints['padding_drop'] == ('c__pad2',)
+ d = {'c_c1': 'char', 'c_i1': 'int'}
+ assert S._hints['get_padding_drop'](d) == ['c__pad2']
#
S = rffi_platform.getstruct("foobar_t", """
typedef struct {
@@ -323,7 +327,8 @@
""", [("c1", lltype.Signed),
("i1", lltype.Signed)])
assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2')
- assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2')
+ d = {'c_c1': 'char', 'c_i1': 'int'}
+ assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2']
#
S = rffi_platform.getstruct("foobar_t", """
typedef struct {
@@ -340,4 +345,5 @@
("s1", lltype.Signed)])
assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2',
'c__pad3', 'c__pad4')
- assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2', 'c__pad4')
+ d = {'c_c1': 'char', 'c_i1': 'int', 'c_s1': 'short'}
+ assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2', 'c__pad4']
More information about the Pypy-commit
mailing list