Skip to content

Commit

Permalink
Fix the test by properly detecting the case during codewriting,
Browse files Browse the repository at this point in the history
and raising NotImplementedError.
  • Loading branch information
arigo committed Aug 21, 2011
1 parent a0d6023 commit 5d4dd7d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
18 changes: 18 additions & 0 deletions pypy/jit/codewriter/jtransform.py
Expand Up @@ -571,6 +571,7 @@ def rewrite_op_getfield(self, op):
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)
Expand Down Expand Up @@ -604,6 +605,7 @@ def rewrite_op_setfield(self, op):
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)
Expand All @@ -616,6 +618,22 @@ def is_typeptr_getset(self, op):
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
Expand Down
10 changes: 10 additions & 0 deletions pypy/jit/codewriter/test/test_jtransform.py
Expand Up @@ -1014,3 +1014,13 @@ def test_quasi_immutable_setfield():
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)
7 changes: 2 additions & 5 deletions pypy/jit/metainterp/test/test_loop.py
Expand Up @@ -801,8 +801,6 @@ def f(n):
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))
Expand All @@ -829,9 +827,8 @@ def f(n, m, j):
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
Expand Down

0 comments on commit 5d4dd7d

Please sign in to comment.