Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit