Author: Maciej Fijalkowski <[email protected]>
Branch: resume-refactor
Changeset: r66401:ea101e9bbee4
Date: 2013-08-28 15:04 +0100
http://bitbucket.org/pypy/pypy/changeset/ea101e9bbee4/
Log: merge jitframe-offset
diff --git a/pypy/module/micronumpy/interp_numarray.py
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -88,13 +88,27 @@
w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(),
w_instance=self)
return loop.getitem_filter(w_res, self, arr)
- def setitem_filter(self, space, idx, val):
+ def setitem_filter(self, space, idx, value):
+ from pypy.module.micronumpy.interp_boxes import Box
+ val = value
if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape():
raise OperationError(space.w_ValueError,
space.wrap("boolean index array should have 1
dimension"))
if idx.get_size() > self.get_size():
raise OperationError(space.w_ValueError,
space.wrap("index out of range for array"))
+ idx_iter = idx.create_iter(self.get_shape())
+ size = loop.count_all_true_iter(idx_iter, self.get_shape(),
idx.get_dtype())
+ if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size >
val.get_shape()[0]:
+ raise OperationError(space.w_ValueError, space.wrap("NumPy boolean
array indexing assignment "
+ "cannot assign
%d input values to "
+ "the %d output
values where the mask is true" % (val.get_shape()[0],size)))
+ if val.get_shape() == [1]:
+ box = val.descr_getitem(space, space.wrap(0))
+ assert isinstance(box, Box)
+ val = W_NDimArray(scalar.Scalar(val.get_dtype(), box))
+ elif val.get_shape() == [0]:
+ val.implementation.dtype = self.implementation.dtype
loop.setitem_filter(self, idx, val)
def _prepare_array_index(self, space, w_index):
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -318,23 +318,27 @@
lefti.next()
return result
-count_all_true_driver = jit.JitDriver(name = 'numpy_count',
- greens = ['shapelen', 'dtype'],
- reds = 'auto')
def count_all_true(arr):
- s = 0
if arr.is_scalar():
return arr.get_dtype().itemtype.bool(arr.get_scalar_value())
iter = arr.create_iter()
- shapelen = len(arr.get_shape())
- dtype = arr.get_dtype()
+ return count_all_true_iter(iter, arr.get_shape(), arr.get_dtype())
+
+count_all_true_iter_driver = jit.JitDriver(name = 'numpy_count',
+ greens = ['shapelen', 'dtype'],
+ reds = 'auto')
+def count_all_true_iter(iter, shape, dtype):
+ s = 0
+ shapelen = len(shape)
+ dtype = dtype
while not iter.done():
- count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype)
+ count_all_true_iter_driver.jit_merge_point(shapelen=shapelen,
dtype=dtype)
s += iter.getitem_bool()
iter.next()
return s
+
getitem_filter_driver = jit.JitDriver(name = 'numpy_getitem_bool',
greens = ['shapelen', 'arr_dtype',
'index_dtype'],
diff --git a/pypy/module/micronumpy/test/test_numarray.py
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -2354,6 +2354,12 @@
def test_array_indexing_bool_specialcases(self):
from numpypy import arange, array
a = arange(6)
+ try:
+ a[a < 3] = [1, 2]
+ assert False, "Should not work"
+ except ValueError:
+ pass
+ a = arange(6)
a[a > 3] = array([15])
assert (a == [0, 1, 2, 3, 15, 15]).all()
a = arange(6).reshape(3, 2)
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -5,7 +5,7 @@
from rpython.tool.ansi_print import ansi_log
from rpython.tool.pairtype import pair
from rpython.tool.error import (format_blocked_annotation_error,
- AnnotatorError, gather_error, ErrorWrapper)
+ AnnotatorError, gather_error, ErrorWrapper,
source_lines)
from rpython.flowspace.model import (Variable, Constant, FunctionGraph,
c_last_exception, checkgraph)
from rpython.translator import simplify, transform
@@ -383,8 +383,8 @@
try:
unions = [annmodel.unionof(c1,c2) for c1, c2 in
zip(oldcells,inputcells)]
except annmodel.UnionError, e:
- e.args = e.args + (
- ErrorWrapper(gather_error(self, graph, block, None)),)
+ # Add source code to the UnionError
+ e.source = '\n'.join(source_lines(graph, block, None, long=True))
raise
# if the merged cells changed, we must redo the analysis
if unions != oldcells:
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -243,14 +243,16 @@
if t2 is int:
if int2.nonneg == False:
- raise UnionError, "Merging %s and a possibly negative int
is not allowed" % t1
+ raise UnionError(int1, int2, "RPython cannot prove that
these " + \
+ "integers are of the same signedness")
knowntype = t1
elif t1 is int:
if int1.nonneg == False:
- raise UnionError, "Merging %s and a possibly negative int
is not allowed" % t2
+ raise UnionError(int1, int2, "RPython cannot prove that
these " + \
+ "integers are of the same signedness")
knowntype = t2
else:
- raise UnionError, "Merging these types (%s, %s) is not
supported" % (t1, t2)
+ raise UnionError(int1, int2)
return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
knowntype=knowntype)
@@ -551,9 +553,9 @@
def union((tup1, tup2)):
if len(tup1.items) != len(tup2.items):
- raise UnionError("cannot take the union of a tuple of length %d "
- "and a tuple of length %d" % (len(tup1.items),
- len(tup2.items)))
+ raise UnionError(tup1, tup2, "RPython cannot unify tuples of "
+ "different length: %d versus %d" % \
+ (len(tup1.items), len(tup2.items)))
else:
unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)]
return SomeTuple(items = unions)
@@ -726,7 +728,8 @@
else:
basedef = ins1.classdef.commonbase(ins2.classdef)
if basedef is None:
- raise UnionError(ins1, ins2)
+ raise UnionError(ins1, ins2, "RPython cannot unify instances "
+ "with no common base class")
flags = ins1.flags
if flags:
flags = flags.copy()
@@ -768,7 +771,8 @@
def union((iter1, iter2)):
s_cont = unionof(iter1.s_container, iter2.s_container)
if iter1.variant != iter2.variant:
- raise UnionError("merging incompatible iterators variants")
+ raise UnionError(iter1, iter2,
+ "RPython cannot unify incompatible iterator variants")
return SomeIterator(s_cont, *iter1.variant)
@@ -778,8 +782,7 @@
if (bltn1.analyser != bltn2.analyser or
bltn1.methodname != bltn2.methodname or
bltn1.s_self is None or bltn2.s_self is None):
- raise UnionError("cannot merge two different builtin functions "
- "or methods:\n %r\n %r" % (bltn1, bltn2))
+ raise UnionError(bltn1, bltn2)
s_self = unionof(bltn1.s_self, bltn2.s_self)
return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname)
@@ -976,8 +979,8 @@
class __extend__(pairtype(SomeAddress, SomeObject)):
def union((s_addr, s_obj)):
- raise UnionError, "union of address and anything else makes no sense"
+ raise UnionError(s_addr, s_obj)
class __extend__(pairtype(SomeObject, SomeAddress)):
def union((s_obj, s_addr)):
- raise UnionError, "union of address and anything else makes no sense"
+ raise UnionError(s_obj, s_addr)
diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py
--- a/rpython/annotator/listdef.py
+++ b/rpython/annotator/listdef.py
@@ -58,7 +58,7 @@
def merge(self, other):
if self is not other:
if getattr(TLS, 'no_side_effects_in_union', 0):
- raise UnionError("merging list/dict items")
+ raise UnionError(self, other)
if other.dont_change_any_more:
if self.dont_change_any_more:
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -680,6 +680,33 @@
"""Signals an suspicious attempt at taking the union of
deeply incompatible SomeXxx instances."""
+ def __init__(self, s_obj1, s_obj2, msg=None):
+ """
+ This exception expresses the fact that s_obj1 and s_obj2 cannot be
unified.
+ The msg paramter is appended to a generic message. This can be used to
+ give the user a little more information.
+ """
+ self.s_obj1 = s_obj1
+ self.s_obj2 = s_obj2
+ self.msg = msg
+ self.source = None
+
+ def __str__(self):
+ s = "\n\n"
+
+ if self.msg is not None:
+ s += "%s\n\n" % self.msg
+
+ s += "Offending annotations:\n"
+ s += "%s\n%s\n\n" % (self.s_obj1, self.s_obj2)
+
+ if self.source is not None:
+ s += self.source
+
+ return s
+
+ def __repr__(self):
+ return str(self)
def unionof(*somevalues):
"The most precise SomeValue instance that contains all the values."
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -4023,6 +4023,81 @@
a = self.RPythonAnnotator()
assert not a.build_types(fn, [int]).nonneg
+ def test_unionerror_attrs(self):
+ def f(x):
+ if x < 10:
+ return 1
+ else:
+ return "bbb"
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ the_exc = exc.value
+ s_objs = set([type(the_exc.s_obj1), type(the_exc.s_obj2)])
+
+ assert s_objs == set([annmodel.SomeInteger, annmodel.SomeString])
+ assert the_exc.msg == None # Check that this is a generic UnionError
+
+ def test_unionerror_tuple_size(self):
+ def f(x):
+ if x < 10:
+ return (1, )
+ else:
+ return (1, 2)
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == "RPython cannot unify tuples of different
length: 2 versus 1"
+
+ def test_unionerror_signedness(self):
+ def f(x):
+ if x < 10:
+ return r_uint(99)
+ else:
+ return -1
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == ("RPython cannot prove that these integers are
of "
+ "the same signedness")
+
+ def test_unionerror_instance(self):
+ class A(object): pass
+ class B(object): pass
+
+ def f(x):
+ if x < 10:
+ return A()
+ else:
+ return B()
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == ("RPython cannot unify instances with no
common base class")
+
+ def test_unionerror_iters(self):
+
+ def f(x):
+ d = { 1 : "a", 2 : "b" }
+ if x < 10:
+ return d.iterkeys()
+ else:
+ return d.itervalues()
+ a = self.RPythonAnnotator()
+
+ with py.test.raises(annmodel.UnionError) as exc:
+ a.build_types(f, [int])
+
+ assert exc.value.msg == ("RPython cannot unify incompatible iterator
variants")
+
def g(n):
return [0, 1, 2, n]
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -24,8 +24,9 @@
self.frame = frame
def __str__(self):
- msg = ['-+' * 30]
+ msg = ["\n"]
msg += map(str, self.args)
+ msg += [""]
msg += source_lines(self.frame.graph, None,
offset=self.frame.last_instr)
return "\n".join(msg)
@@ -293,7 +294,7 @@
_unsupported_ops = [
('BINARY_POWER', "a ** b"),
- ('BUILD_CLASS', 'creating new classes'),
+ ('BUILD_CLASS', 'defining classes inside functions'),
('EXEC_STMT', 'exec statement'),
('STOP_CODE', '???'),
('STORE_NAME', 'modifying globals'),
diff --git a/rpython/jit/backend/arm/locations.py
b/rpython/jit/backend/arm/locations.py
--- a/rpython/jit/backend/arm/locations.py
+++ b/rpython/jit/backend/arm/locations.py
@@ -33,6 +33,9 @@
def get_position(self):
raise NotImplementedError # only for stack
+ def get_jitframe_position(self):
+ raise NotImplementedError
+
class RegisterLocation(AssemblerLocation):
_immutable_ = True
width = WORD
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -46,6 +46,26 @@
self.fcond = fcond
self.offset = offset
+ def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth):
+ # note that this is an old version that should not be here in
+ # the first place. Implement get_jitframe_position on ARM locations
+ # in order to make it work, then kill this function
+ input_i = 0
+ for i in range(len(failargs)):
+ arg = failargs[i]
+ if arg is None:
+ continue
+ loc = fail_locs[input_i]
+ input_i += 1
+ if arg.type == REF:
+ loc = fail_locs[i]
+ if loc.is_core_reg():
+ val = self.cpu.all_reg_indexes[loc.value]
+ else:
+ val = loc.get_position() + self.cpu.JITFRAME_FIXED_SIZE
+ gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
+ return gcmap
+
class ResOpAssembler(BaseAssembler):
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -36,22 +36,12 @@
self.is_guard_not_forced = is_guard_not_forced
def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth):
- # note that regalloc has a very similar compute, but
- # one that does iteration over all bindings, so slightly different,
- # eh
- input_i = 0
for i in range(len(failargs)):
arg = failargs[i]
if arg is None:
continue
- loc = fail_locs[input_i]
- input_i += 1
if arg.type == REF:
- loc = fail_locs[i]
- if loc.is_core_reg():
- val = self.cpu.all_reg_indexes[loc.value]
- else:
- val = loc.get_position() + self.cpu.JITFRAME_FIXED_SIZE
+ val = fail_locs[i].get_jitframe_position()
gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
return gcmap
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
@@ -1772,17 +1772,13 @@
regs = gpr_reg_mgr_cls.all_regs
for gpr in regs:
if gpr not in ignored_regs:
- v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
+ v = gpr.get_jitframe_position()
mc.MOV_br(v * WORD + base_ofs, gpr.value)
if withfloats:
- if IS_X86_64:
- coeff = 1
- else:
- coeff = 2
# Push all XMM regs
- ofs = len(gpr_reg_mgr_cls.all_regs)
- for i in range(len(xmm_reg_mgr_cls.all_regs)):
- mc.MOVSD_bx((ofs + i * coeff) * WORD + base_ofs, i)
+ for reg in xmm_reg_mgr_cls.all_regs:
+ v = reg.get_jitframe_position()
+ mc.MOVSD_bx(v * WORD + base_ofs, reg.value)
def _pop_all_regs_from_frame(self, mc, ignored_regs, withfloats,
callee_only=False):
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -898,12 +898,12 @@
if box.type == REF and self.rm.is_still_alive(box):
assert not noregs
assert isinstance(loc, RegLoc)
- val = gpr_reg_mgr_cls.all_reg_indexes[loc.value]
+ val = loc.get_jitframe_position()
gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
for box, loc in self.fm.bindings.iteritems():
if box.type == REF and self.rm.is_still_alive(box):
assert isinstance(loc, FrameLoc)
- val = loc.position + JITFRAME_FIXED_SIZE
+ val = loc.get_jitframe_position()
gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
return gcmap
diff --git a/rpython/jit/backend/x86/regloc.py
b/rpython/jit/backend/x86/regloc.py
--- a/rpython/jit/backend/x86/regloc.py
+++ b/rpython/jit/backend/x86/regloc.py
@@ -1,5 +1,6 @@
from rpython.jit.metainterp.history import ConstInt
from rpython.jit.backend.x86 import rx86
+from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE
from rpython.rlib.unroll import unrolling_iterable
from rpython.jit.backend.x86.arch import WORD, IS_X86_32, IS_X86_64
from rpython.tool.sourcetools import func_with_new_name
@@ -51,6 +52,8 @@
def get_position(self):
raise NotImplementedError # only for stack
+ def get_jitframe_position(self):
+ raise NotImplementedError
class RawEbpLoc(AssemblerLocation):
""" The same as stack location, but does not know it's position.
@@ -129,6 +132,9 @@
def get_position(self):
return self.position
+ def get_jitframe_position(self):
+ return self.position + JITFRAME_FIXED_SIZE
+
class RegLoc(AssemblerLocation):
_immutable_ = True
def __init__(self, regnum, is_xmm):
@@ -173,6 +179,18 @@
def is_core_reg(self):
return True
+ def get_jitframe_position(self):
+ from rpython.jit.backend.x86 import regalloc
+
+ if self.is_xmm:
+ ofs = len(regalloc.gpr_reg_mgr_cls.all_regs)
+ if IS_X86_64:
+ return ofs + self.value
+ else:
+ return ofs + 2 * self.value
+ else:
+ return regalloc.gpr_reg_mgr_cls.all_reg_indexes[self.value]
+
class ImmediateAssemblerLocation(AssemblerLocation):
_immutable_ = True
diff --git a/rpython/tool/error.py b/rpython/tool/error.py
--- a/rpython/tool/error.py
+++ b/rpython/tool/error.py
@@ -90,7 +90,7 @@
format_simple_call(annotator, oper, msg)
else:
oper = None
- msg.append(" " + str(oper))
+ msg.append(" %s\n" % str(oper))
msg += source_lines(graph, block, operindex, long=True)
if oper is not None:
if SHOW_ANNOTATIONS:
@@ -106,7 +106,7 @@
def format_blocked_annotation_error(annotator, blocked_blocks):
text = []
for block, (graph, index) in blocked_blocks.items():
- text.append('-+' * 30)
+ text.append('\n')
text.append("Blocked block -- operation cannot succeed")
text.append(gather_error(annotator, graph, block, index))
return '\n'.join(text)
diff --git a/rpython/translator/goal/translate.py
b/rpython/translator/goal/translate.py
--- a/rpython/translator/goal/translate.py
+++ b/rpython/translator/goal/translate.py
@@ -246,17 +246,19 @@
tb = None
if got_error:
import traceback
- errmsg = ["Error:\n"]
+ stacktrace_errmsg = ["Error:\n"]
exc, val, tb = sys.exc_info()
- errmsg.extend([" %s" % line for line in
traceback.format_exception(exc, val, tb)])
+ stacktrace_errmsg.extend([" %s" % line for line in
traceback.format_tb(tb)])
+ summary_errmsg = traceback.format_exception_only(exc, val)
block = getattr(val, '__annotator_block', None)
if block:
class FileLike:
def write(self, s):
- errmsg.append(" %s" % s)
- errmsg.append("Processing block:\n")
+ summary_errmsg.append(" %s" % s)
+ summary_errmsg.append("Processing block:\n")
t.about(block, FileLike())
- log.ERROR(''.join(errmsg))
+ log.info(''.join(stacktrace_errmsg))
+ log.ERROR(''.join(summary_errmsg))
else:
log.event('Done.')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit