Author: Armin Rigo <[email protected]>
Branch: portable-threadlocal
Changeset: r74721:ac12cf96b219
Date: 2014-11-26 00:01 +0100
http://bitbucket.org/pypy/pypy/changeset/ac12cf96b219/
Log: hg merge default
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -131,7 +131,6 @@
# class bodies only have CO_NEWLOCALS.
# CO_NEWLOCALS: make a locals dict unless optimized is also set
# CO_OPTIMIZED: no locals dict needed at all
- # NB: this method is overridden in nestedscope.py
flags = code.co_flags
if not (flags & pycode.CO_OPTIMIZED):
if flags & pycode.CO_NEWLOCALS:
diff --git a/pypy/module/pypyjit/test_pypy_c/model.py
b/pypy/module/pypyjit/test_pypy_c/model.py
--- a/pypy/module/pypyjit/test_pypy_c/model.py
+++ b/pypy/module/pypyjit/test_pypy_c/model.py
@@ -275,9 +275,19 @@
@classmethod
def parse_op(cls, line):
- # strip comment
+ # strip comment after '#', but not if it appears inside parentheses
if '#' in line:
- line = line[:line.index('#')]
+ nested = 0
+ for i, c in enumerate(line):
+ if c == '(':
+ nested += 1
+ elif c == ')':
+ assert nested > 0, "more ')' than '(' in %r" % (line,)
+ nested -= 1
+ elif c == '#' and nested == 0:
+ line = line[:i]
+ break
+ #
if line.strip() == 'guard_not_invalidated?':
return 'guard_not_invalidated', None, [], '...', False
# find the resvar, if any
@@ -314,7 +324,7 @@
# to repeat it every time
ticker_check = """
guard_not_invalidated?
- ticker0 = getfield_raw(ticker_address, descr=<FieldS
pypysig_long_struct.c_value .*>)
+ ticker0 = getfield_raw(#, descr=<FieldS
pypysig_long_struct.c_value .*>)
ticker_cond0 = int_lt(ticker0, 0)
guard_false(ticker_cond0, descr=...)
"""
@@ -323,9 +333,9 @@
# this is the ticker check generated if we have threads
thread_ticker_check = """
guard_not_invalidated?
- ticker0 = getfield_raw(ticker_address, descr=<FieldS
pypysig_long_struct.c_value .*>)
- ticker1 = int_sub(ticker0, _)
- setfield_raw(ticker_address, ticker1, descr=<FieldS
pypysig_long_struct.c_value .*>)
+ ticker0 = getfield_raw(#, descr=<FieldS
pypysig_long_struct.c_value .*>)
+ ticker1 = int_sub(ticker0, #)
+ setfield_raw(#, ticker1, descr=<FieldS pypysig_long_struct.c_value
.*>)
ticker_cond0 = int_lt(ticker1, 0)
guard_false(ticker_cond0, descr=...)
"""
@@ -333,7 +343,7 @@
#
# this is the ticker check generated in PyFrame.handle_operation_error
exc_ticker_check = """
- ticker2 = getfield_raw(ticker_address, descr=<FieldS
pypysig_long_struct.c_value .*>)
+ ticker2 = getfield_raw(#, descr=<FieldS
pypysig_long_struct.c_value .*>)
ticker_cond1 = int_lt(ticker2, 0)
guard_false(ticker_cond1, descr=...)
"""
@@ -351,18 +361,31 @@
@staticmethod
def as_numeric_const(v1):
+ # returns one of: ('int', value) ('float', value) None
try:
- return int(v1)
- except (ValueError, TypeError):
- return None
+ return ('int', int(v1))
+ except ValueError:
+ pass
+ if '.' in v1:
+ try:
+ return ('float', float(v1))
+ except ValueError:
+ pass
+ return None
def match_var(self, v1, exp_v2):
assert v1 != '_'
- if exp_v2 == '_':
+ if exp_v2 == '_': # accept anything
return True
+ if exp_v2 is None:
+ return v1 is None
+ assert exp_v2 != '...' # bogus use of '...' in the expected code
n1 = self.as_numeric_const(v1)
+ if exp_v2 == '#': # accept any (integer or float) number
+ return n1 is not None
n2 = self.as_numeric_const(exp_v2)
- if n1 is not None and n2 is not None:
+ if n1 is not None or n2 is not None:
+ # at least one is a number; check that both are, and are equal
return n1 == n2
if self.is_const(v1) or self.is_const(exp_v2):
return v1[:-1].startswith(exp_v2[:-1])
@@ -382,10 +405,13 @@
def match_op(self, op, (exp_opname, exp_res, exp_args, exp_descr, _)):
self._assert(op.name == exp_opname, "operation mismatch")
self.match_var(op.res, exp_res)
- if exp_args != ['...']:
+ if exp_args[-1:] == ['...']: # exp_args ends with '...'
+ exp_args = exp_args[:-1]
+ self._assert(len(op.args) >= len(exp_args), "not enough arguments")
+ else:
self._assert(len(op.args) == len(exp_args), "wrong number of
arguments")
- for arg, exp_arg in zip(op.args, exp_args):
- self._assert(self.match_var(arg, exp_arg), "variable mismatch:
%r instead of %r" % (arg, exp_arg))
+ for arg, exp_arg in zip(op.args, exp_args):
+ self._assert(self.match_var(arg, exp_arg), "variable mismatch: %r
instead of %r" % (arg, exp_arg))
self.match_descr(op.descr, exp_descr)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -158,6 +158,24 @@
assert match_var('v0', 'V0')
assert match_var('ConstPtr(ptr0)', '_')
py.test.raises(AssertionError, "match_var('_', 'v0')")
+ #
+ # numerics
+ assert match_var('1234', '1234')
+ assert not match_var('1234', '1235')
+ assert not match_var('v0', '1234')
+ assert not match_var('1234', 'v0')
+ assert match_var('1234', '#') # the '#' char matches any number
+ assert not match_var('v0', '#')
+ assert match_var('1234', '_') # the '_' char matches anything
+ #
+ # float numerics
+ assert match_var('0.000000', '0.0')
+ assert not match_var('0.000000', '0')
+ assert not match_var('0', '0.0')
+ assert not match_var('v0', '0.0')
+ assert not match_var('0.0', 'v0')
+ assert match_var('0.0', '#')
+ assert match_var('0.0', '_')
def test_parse_op(self):
res = OpMatcher.parse_op(" a = int_add( b, 3 ) # foo")
@@ -210,6 +228,19 @@
"""
assert not self.match(loop, expected)
+ def test_dotdotdot_in_operation(self):
+ loop = """
+ [i0, i1]
+ jit_debug(i0, 1, ConstClass(myclass), i1)
+ """
+ assert self.match(loop, "jit_debug(...)")
+ assert self.match(loop, "jit_debug(i0, ...)")
+ assert self.match(loop, "jit_debug(i0, 1, ...)")
+ assert self.match(loop, "jit_debug(i0, 1, _, ...)")
+ assert self.match(loop, "jit_debug(i0, 1, _, i1, ...)")
+ py.test.raises(AssertionError, self.match,
+ loop, "jit_debug(i0, 1, ..., i1)")
+
def test_match_descr(self):
loop = """
[p0]
@@ -232,7 +263,7 @@
jump(i4)
"""
expected = """
- i1 = int_add(0, 1)
+ i1 = int_add(i0, 1)
...
i4 = int_mul(i1, 1000)
jump(i4, descr=...)
@@ -249,7 +280,7 @@
jump(i4, descr=...)
"""
expected = """
- i1 = int_add(0, 1)
+ i1 = int_add(i0, 1)
...
_ = int_mul(_, 1000)
jump(i4, descr=...)
@@ -268,7 +299,7 @@
jump(i4)
"""
expected = """
- i1 = int_add(0, 1)
+ i1 = int_add(i0, 1)
...
"""
assert self.match(loop, expected)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_buffers.py
b/pypy/module/pypyjit/test_pypy_c/test_buffers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_buffers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_buffers.py
@@ -21,7 +21,7 @@
i65 = getfield_gc(p18, descr=...)
i67 = int_gt(0, i65)
guard_false(i67, descr=...)
- i69 = int_gt(., i65)
+ i69 = int_gt(#, i65)
guard_true(i69, descr=...)
--TICK--
""")
@@ -56,7 +56,7 @@
guard_false(i99, descr=...)
i100 = int_lshift(i98, 24)
i101 = int_or(i97, i100)
- i102 = getfield_raw(\d+, descr=<FieldS pypysig_long_struct.c_value
0>)
+ i102 = getfield_raw(#, descr=<FieldS pypysig_long_struct.c_value
0>)
i103 = int_lt(i102, 0)
guard_false(i103, descr=...)
""")
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py
b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -395,7 +395,7 @@
setarrayitem_gc(p24, 0, p26, descr=<ArrayP .>)
setfield_gc(p22, p24, descr=<FieldP .*Arguments.inst_arguments_w
.*>)
}}}
- p32 = call_may_force(..., p18, p22, descr=<Callr . rr EF=6>)
+ p32 = call_may_force(_, p18, p22, descr=<Callr . rr EF=6>)
...
""")
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py
b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -82,7 +82,7 @@
guard_no_exception(descr=...)
i23 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12,
descr=<Calli . rri EF=4 OS=4>)
guard_no_exception(descr=...)
- i26 = int_and(i23, .*)
+ i26 = int_and(i23, #)
i27 = int_is_true(i26)
guard_false(i27, descr=...)
p28 = getfield_gc(p13, descr=<FieldP dicttable.entries .*>)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py
b/pypy/module/pypyjit/test_pypy_c/test_math.py
--- a/pypy/module/pypyjit/test_pypy_c/test_math.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_math.py
@@ -21,7 +21,7 @@
guard_true(i2, descr=...)
guard_not_invalidated(descr=...)
f1 = cast_int_to_float(i0)
- i3 = float_le(f1, 0)
+ i3 = float_le(f1, 0.0)
guard_false(i3, descr=...)
f2 = call(ConstClass(log), f1, descr=<Callf . f EF=2>)
f3 = call(ConstClass(log10), f1, descr=<Callf . f EF=2>)
@@ -56,7 +56,7 @@
f3 = call(ConstClass(cos), f1, descr=<Callf . f EF=0>)
f4 = float_sub(f2, f3)
f5 = float_add(f0, f4)
- i7 = int_add(i0, f1)
+ i7 = int_add(i0, 1)
--TICK--
jump(..., descr=)
""")
diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
--- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
@@ -104,7 +104,7 @@
setarrayitem_gc(p150, 1, 0, descr=<ArrayS .+>)
setarrayitem_gc(p150, 0, 0, descr=<ArrayS .+>)
guard_not_invalidated(descr=...)
- i154 = getfield_raw(ticker_address, descr=<FieldS
pypysig_long_struct.c_value 0>)
+ i154 = getfield_raw(#, descr=<FieldS pypysig_long_struct.c_value
0>)
i155 = int_lt(i154, 0)
guard_false(i155, descr=...)
p156 = new_with_vtable(...)
@@ -142,7 +142,7 @@
raw_store(i103, i132, 42.000000, descr=<ArrayF 8>)
p152 = getfield_gc_pure(p126, descr=<FieldP
pypy.module.micronumpy.iterators.IterState.inst_indices .+>)
i153 = int_add(i120, 1)
- i154 = getfield_raw(ticker_address, descr=<FieldS
pypysig_long_struct.c_value 0>)
+ i154 = getfield_raw(#, descr=<FieldS pypysig_long_struct.c_value
0>)
setarrayitem_gc(p152, 1, 0, descr=<ArrayS .+>)
setarrayitem_gc(p152, 0, 0, descr=<ArrayS .+>)
i157 = int_lt(i154, 0)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py
b/pypy/module/pypyjit/test_pypy_c/test_string.py
--- a/pypy/module/pypyjit/test_pypy_c/test_string.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_string.py
@@ -67,15 +67,15 @@
i11 = int_lt(i6, i7)
guard_true(i11, descr=...)
guard_not_invalidated(descr=...)
- i13 = int_eq(i6, %d)
+ i13 = int_eq(i6, %d) # value provided below
guard_false(i13, descr=...)
- i15 = int_mod(i6, i8)
- i17 = int_rshift(i15, %d)
- i18 = int_and(i8, i17)
+ i15 = int_mod(i6, 10)
+ i17 = int_rshift(i15, %d) # value provided below
+ i18 = int_and(10, i17)
i19 = int_add(i15, i18)
i21 = int_lt(i19, 0)
guard_false(i21, descr=...)
- i22 = int_ge(i19, i8)
+ i22 = int_ge(i19, 10)
guard_false(i22, descr=...)
i23 = strgetitem(p10, i19)
p25 = newstr(1)
@@ -83,7 +83,7 @@
p93 = call(ConstClass(fromstr), p25, 16, descr=<Callr . ri EF=3>)
guard_no_exception(descr=...)
i95 = getfield_gc_pure(p93, descr=<FieldS
rpython.rlib.rbigint.rbigint.inst_size .*>)
- i96 = int_gt(i95, .*)
+ i96 = int_gt(i95, #)
guard_false(i96, descr=...)
i94 = call(ConstClass(rbigint._toint_helper), p93, descr=<Calli .
r EF=3>)
guard_no_exception(descr=...)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py
b/pypy/module/pypyjit/test_pypy_c/test_thread.py
--- a/pypy/module/pypyjit/test_pypy_c/test_thread.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py
@@ -64,7 +64,7 @@
guard_true(i56, descr=...)
p57 = force_token()
setfield_gc(p0, p57, descr=<FieldP
pypy.interpreter.pyframe.PyFrame.vable_token 8>)
- i58 = call_release_gil(..., i37, 1, descr=<Calli 4 ii EF=6>)
+ i58 = call_release_gil(_, i37, 1, descr=<Calli 4 ii EF=6>)
guard_not_forced(descr=...)
guard_no_exception(descr=...)
i59 = int_is_true(i58)
@@ -72,14 +72,14 @@
i60 = int_sub(i44, 1)
p62 = force_token()
setfield_gc(p0, p62, descr=<FieldP
pypy.interpreter.pyframe.PyFrame.vable_token 8>)
- i63 = call_release_gil(..., i37, 0, descr=<Calli 4 ii EF=6>)
+ i63 = call_release_gil(_, i37, 0, descr=<Calli 4 ii EF=6>)
guard_not_forced(descr=...)
guard_no_exception(descr=...)
i64 = int_is_true(i63)
guard_false(i64, descr=...)
p65 = force_token()
setfield_gc(p0, p65, descr=<FieldP
pypy.interpreter.pyframe.PyFrame.vable_token 8>)
- call_release_gil(..., i37, descr=<Callv 0 i EF=6>)
+ call_release_gil(_, i37, descr=<Callv 0 i EF=6>)
guard_not_forced(descr=...)
guard_no_exception(descr=...)
guard_not_invalidated(descr=...)
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1833,15 +1833,17 @@
offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
mc.MOV_br(offset, ebx.value)
- # now we return from the complete frame, which starts from
- # _call_header_with_stack_check(). The LEA in _call_footer below
- # throws away most of the frame, including all the PUSHes that we
- # did just above.
+ # fill in the jf_descr and jf_gcmap fields of the frame according
+ # to which failure we are resuming from. These are constants
+ # pushed on the stack just before we jump to the current helper,
+ # in generate_quick_failure().
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap')
mc.POP_b(ofs2)
mc.POP_b(ofs)
+ # now we return from the complete frame, which starts from
+ # _call_header_with_stack_check(). The _call_footer below does it.
self._call_footer()
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.failure_recovery_code[exc + 2 * withfloats] = rawstart
diff --git a/rpython/rtyper/normalizecalls.py b/rpython/rtyper/normalizecalls.py
--- a/rpython/rtyper/normalizecalls.py
+++ b/rpython/rtyper/normalizecalls.py
@@ -298,12 +298,16 @@
# ____________________________________________________________
+class TooLateForNewSubclass(Exception):
+ pass
+
class TotalOrderSymbolic(ComputedIntSymbolic):
def __init__(self, orderwitness, peers):
self.orderwitness = orderwitness
self.peers = peers
self.value = None
+ self._with_subclasses = None # unknown
peers.append(self)
def __cmp__(self, other):
@@ -320,12 +324,34 @@
def __rsub__(self, other):
return other - self.compute_fn()
+ def check_any_subclass_in_peer_list(self, i):
+ # check if the next peer, in order, is or not the end
+ # marker for this start marker
+ assert self.peers[i] is self
+ return self.peers[i + 1].orderwitness != self.orderwitness + [MAX]
+
+ def number_with_subclasses(self):
+ # Return True or False depending on whether this is the
+ # subclassrange_min corresponding to a class which has subclasses
+ # or not. If this is called and returns False, then adding later
+ # new subclasses will crash in compute_fn().
+ if self._with_subclasses is None: # unknown so far
+ self.peers.sort()
+ i = self.peers.index(self)
+ self._with_subclasses = self.check_any_subclass_in_peer_list(i)
+ return self._with_subclasses
+
def compute_fn(self):
if self.value is None:
self.peers.sort()
for i, peer in enumerate(self.peers):
assert peer.value is None or peer.value == i
peer.value = i
+ #
+ if peer._with_subclasses is False:
+ if peer.check_any_subclass_in_peer_list(i):
+ raise TooLateForNewSubclass
+ #
assert self.value is not None
return self.value
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -1007,14 +1007,11 @@
v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
if isinstance(v_cls, Constant):
cls = v_cls.value
- # XXX re-implement the following optimization
- #if cls.subclassrange_max == cls.subclassrange_min:
- # # a class with no subclass
- # return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj,
v_cls)
- #else:
- minid = hop.inputconst(Signed, cls.subclassrange_min)
- maxid = hop.inputconst(Signed, cls.subclassrange_max)
- return hop.gendirectcall(ll_isinstance_const, v_obj, minid, maxid)
+ llf, llf_nonnull = make_ll_isinstance(self.rtyper, cls)
+ if hop.args_s[0].can_be_None:
+ return hop.gendirectcall(llf, v_obj)
+ else:
+ return hop.gendirectcall(llf_nonnull, v_obj)
else:
return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
@@ -1128,16 +1125,26 @@
obj_cls = obj.typeptr
return ll_issubclass(obj_cls, cls)
-def ll_isinstance_const(obj, minid, maxid):
- if not obj:
- return False
- return ll_issubclass_const(obj.typeptr, minid, maxid)
-
-def ll_isinstance_exact(obj, cls):
- if not obj:
- return False
- obj_cls = obj.typeptr
- return obj_cls == cls
+def make_ll_isinstance(rtyper, cls):
+ try:
+ return rtyper.isinstance_helpers[cls._obj]
+ except KeyError:
+ minid = cls.subclassrange_min
+ maxid = cls.subclassrange_max
+ if minid.number_with_subclasses():
+ def ll_isinstance_const_nonnull(obj):
+ objid = obj.typeptr.subclassrange_min
+ return llop.int_between(Bool, minid, objid, maxid)
+ else:
+ def ll_isinstance_const_nonnull(obj):
+ return obj.typeptr == cls
+ def ll_isinstance_const(obj):
+ if not obj:
+ return False
+ return ll_isinstance_const_nonnull(obj)
+ result = (ll_isinstance_const, ll_isinstance_const_nonnull)
+ rtyper.isinstance_helpers[cls._obj] = result
+ return result
def ll_runtime_type_info(obj):
return obj.typeptr.rtti
diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py
--- a/rpython/rtyper/rtyper.py
+++ b/rpython/rtyper/rtyper.py
@@ -59,6 +59,7 @@
self.typererror_count = 0
# make the primitive_to_repr constant mapping
self.primitive_to_repr = {}
+ self.isinstance_helpers = {}
self.exceptiondata = ExceptionData(self)
self.custom_trace_funcs = []
diff --git a/rpython/rtyper/test/test_normalizecalls.py
b/rpython/rtyper/test/test_normalizecalls.py
--- a/rpython/rtyper/test/test_normalizecalls.py
+++ b/rpython/rtyper/test/test_normalizecalls.py
@@ -6,6 +6,7 @@
from rpython.rtyper.test.test_llinterp import interpret
from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.normalizecalls import TotalOrderSymbolic, MAX
+from rpython.rtyper.normalizecalls import TooLateForNewSubclass
def test_TotalOrderSymbolic():
@@ -21,6 +22,49 @@
assert t1 <= 5
assert t1.value == 0
+def test_TotalOrderSymbolic_with_subclasses():
+ lst = []
+ t3 = TotalOrderSymbolic([3, 4, 2, MAX], lst)
+ t1 = TotalOrderSymbolic([3, 4], lst)
+ t2 = TotalOrderSymbolic([3, 4, 2], lst)
+ t4 = TotalOrderSymbolic([3, 4, MAX], lst)
+ assert t1.number_with_subclasses()
+ assert not t2.number_with_subclasses()
+ assert [t.compute_fn() for t in [t1, t2, t3, t4]] == range(4)
+ #
+ lst = []
+ t1 = TotalOrderSymbolic([3, 4], lst)
+ t3 = TotalOrderSymbolic([3, 4, 2, MAX], lst)
+ t4 = TotalOrderSymbolic([3, 4, MAX], lst)
+ t2 = TotalOrderSymbolic([3, 4, 2], lst)
+ assert not t2.number_with_subclasses()
+ assert t1.number_with_subclasses()
+ assert [t.compute_fn() for t in [t1, t2, t3, t4]] == range(4)
+ #
+ lst = []
+ t1 = TotalOrderSymbolic([3, 4], lst)
+ t4 = TotalOrderSymbolic([3, 4, MAX], lst)
+ assert not t1.number_with_subclasses()
+ t2 = TotalOrderSymbolic([3, 4, 2], lst)
+ t3 = TotalOrderSymbolic([3, 4, 2, MAX], lst)
+ py.test.raises(TooLateForNewSubclass, t2.compute_fn)
+ #
+ lst = []
+ t1 = TotalOrderSymbolic([3, 4], lst)
+ t4 = TotalOrderSymbolic([3, 4, MAX], lst)
+ assert not t1.number_with_subclasses()
+ t2 = TotalOrderSymbolic([1], lst)
+ t3 = TotalOrderSymbolic([1, MAX], lst)
+ assert [t.compute_fn() for t in [t2, t3, t1, t4]] == range(4)
+ #
+ lst = []
+ t1 = TotalOrderSymbolic([3, 4], lst)
+ t4 = TotalOrderSymbolic([3, 4, MAX], lst)
+ assert not t1.number_with_subclasses()
+ t2 = TotalOrderSymbolic([6], lst)
+ t3 = TotalOrderSymbolic([6, MAX], lst)
+ assert [t.compute_fn() for t in [t1, t4, t2, t3]] == range(4)
+
# ____________________________________________________________
class TestNormalize(object):
diff --git a/rpython/tool/jitlogparser/parser.py
b/rpython/tool/jitlogparser/parser.py
--- a/rpython/tool/jitlogparser/parser.py
+++ b/rpython/tool/jitlogparser/parser.py
@@ -216,7 +216,7 @@
line_starts_here = property(getline_starts_here)
def __repr__(self):
- return "[%s]" % ", ".join([repr(op) for op in self.operations])
+ return "[%s\n]" % "\n ".join([repr(op) for op in self.operations])
def pretty_print(self, out):
pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit