Author: Armin Rigo <[email protected]>
Branch:
Changeset: r46682:e5fb197506d6
Date: 2011-08-21 11:31 +0200
http://bitbucket.org/pypy/pypy/changeset/e5fb197506d6/
Log: Fix the test by properly detecting the case during codewriting, and
raising NotImplementedError.
diff --git a/pypy/jit/codewriter/jtransform.py
b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -571,6 +571,7 @@
pure = '_pure'
else:
pure = ''
+ self.check_field_access(v_inst.concretetype.TO)
argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc')
descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
c_fieldname.value)
@@ -604,6 +605,7 @@
return [SpaceOperation('-live-', [], None),
SpaceOperation('setfield_vable_%s' % kind,
[v_inst, descr, v_value], None)]
+ self.check_field_access(v_inst.concretetype.TO)
argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc')
descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
c_fieldname.value)
@@ -616,6 +618,22 @@
return (op.args[1].value == 'typeptr' and
op.args[0].concretetype.TO._hints.get('typeptr'))
+ def check_field_access(self, STRUCT):
+ # check against a GcStruct with a nested GcStruct as a first argument
+ # but which is not an object at all; see metainterp/test/test_loop,
+ # test_regular_pointers_in_short_preamble.
+ if not isinstance(STRUCT, lltype.GcStruct):
+ return
+ if STRUCT._first_struct() == (None, None):
+ return
+ PARENT = STRUCT
+ while not PARENT._hints.get('typeptr'):
+ _, PARENT = PARENT._first_struct()
+ if PARENT is None:
+ raise NotImplementedError("%r is a GcStruct using nesting but "
+ "not inheriting from object" %
+ (STRUCT,))
+
def get_vinfo(self, v_virtualizable):
if self.callcontrol is None: # for tests
return None
diff --git a/pypy/jit/codewriter/test/test_jtransform.py
b/pypy/jit/codewriter/test/test_jtransform.py
--- a/pypy/jit/codewriter/test/test_jtransform.py
+++ b/pypy/jit/codewriter/test/test_jtransform.py
@@ -1014,3 +1014,13 @@
assert op1.opname == 'jit_force_quasi_immutable'
assert op1.args[0] == v_x
assert op1.args[1] == ('fielddescr', STRUCT, 'mutate_x')
+
+def test_no_gcstruct_nesting_outside_of_OBJECT():
+ PARENT = lltype.GcStruct('parent')
+ STRUCT = lltype.GcStruct('struct', ('parent', PARENT),
+ ('x', lltype.Signed))
+ v_x = varoftype(lltype.Ptr(STRUCT))
+ op = SpaceOperation('getfield', [v_x, Constant('x', lltype.Void)],
+ varoftype(lltype.Signed))
+ tr = Transformer(None, None)
+ raises(NotImplementedError, tr.rewrite_operation, op)
diff --git a/pypy/jit/metainterp/test/test_loop.py
b/pypy/jit/metainterp/test/test_loop.py
--- a/pypy/jit/metainterp/test/test_loop.py
+++ b/pypy/jit/metainterp/test/test_loop.py
@@ -801,8 +801,6 @@
res = self.meta_interp(f, [200])
def test_regular_pointers_in_short_preamble(self):
- # XXX do we really care about this case? If not, we should
- # at least detect it and complain during codewriter/jtransform
from pypy.rpython.lltypesystem import lltype
BASE = lltype.GcStruct('BASE')
A = lltype.GcStruct('A', ('parent', BASE), ('val', lltype.Signed))
@@ -829,9 +827,8 @@
assert n>0 and m>0
i += j
return sa
- expected = f(20, 10, 1)
- res = self.meta_interp(f, [20, 10, 1])
- assert res == expected
+ # This is detected as invalid by the codewriter, for now
+ py.test.raises(NotImplementedError, self.meta_interp, f, [20, 10, 1])
def test_unerased_pointers_in_short_preamble(self):
from pypy.rlib.rerased import new_erasing_pair
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit