[pypy-commit] pypy arm-backend-2: merge default up to 9439564ba9b3
bivab
noreply at buildbot.pypy.org
Fri Jun 24 17:39:54 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r45106:4a9f1f42a77b
Date: 2011-06-24 16:54 +0200
http://bitbucket.org/pypy/pypy/changeset/4a9f1f42a77b/
Log: merge default up to 9439564ba9b3
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -43,8 +43,8 @@
class TestAnnotateTestCase:
- def setup_class(cls):
- cls.space = FlowObjSpace()
+ def setup_class(cls):
+ cls.space = FlowObjSpace()
def teardown_method(self, meth):
assert annmodel.s_Bool == annmodel.SomeBool()
@@ -263,7 +263,7 @@
getcdef = a.bookkeeper.getuniqueclassdef
assert getcdef(snippet.F).attrs.keys() == ['m']
assert getcdef(snippet.G).attrs.keys() == ['m2']
- assert getcdef(snippet.H).attrs.keys() == ['attr']
+ assert getcdef(snippet.H).attrs.keys() == ['attr']
assert getcdef(snippet.H).about_attribute('attr') == (
a.bookkeeper.immutablevalue(1))
@@ -390,34 +390,34 @@
def test_tuple_unpack_from_const_tuple_with_different_types(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.func_arg_unpack, [])
- assert isinstance(s, annmodel.SomeInteger)
- assert s.const == 3
+ assert isinstance(s, annmodel.SomeInteger)
+ assert s.const == 3
def test_pbc_attr_preserved_on_instance(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.preserve_pbc_attr_on_instance, [bool])
#a.simplify()
#a.translator.view()
- assert s == annmodel.SomeInteger(nonneg=True)
- #self.assertEquals(s.__class__, annmodel.SomeInteger)
+ assert s == annmodel.SomeInteger(nonneg=True)
+ #self.assertEquals(s.__class__, annmodel.SomeInteger)
def test_pbc_attr_preserved_on_instance_with_slots(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.preserve_pbc_attr_on_instance_with_slots,
[bool])
- assert s == annmodel.SomeInteger(nonneg=True)
-
- def test_is_and_knowntype_data(self):
+ assert s == annmodel.SomeInteger(nonneg=True)
+
+ def test_is_and_knowntype_data(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.is_and_knowntype, [str])
#a.simplify()
#a.translator.view()
assert s == a.bookkeeper.immutablevalue(None)
- def test_isinstance_and_knowntype_data(self):
+ def test_isinstance_and_knowntype_data(self):
a = self.RPythonAnnotator()
x = a.bookkeeper.immutablevalue(snippet.apbc)
- s = a.build_types(snippet.isinstance_and_knowntype, [x])
+ s = a.build_types(snippet.isinstance_and_knowntype, [x])
#a.simplify()
#a.translator.view()
assert s == x
@@ -434,8 +434,8 @@
# the annotator (it doesn't check that they operate property, though)
for example, methname, s_example in [
('', 'join', annmodel.SomeString()),
- ([], 'append', somelist()),
- ([], 'extend', somelist()),
+ ([], 'append', somelist()),
+ ([], 'extend', somelist()),
([], 'reverse', somelist()),
([], 'insert', somelist()),
([], 'pop', somelist()),
@@ -465,6 +465,13 @@
assert isinstance(s, annmodel.SomeList)
assert s.listdef.listitem.resized
+ def test_str_mul(self):
+ a = self.RPythonAnnotator()
+ def f(a_str):
+ return a_str * 3
+ s = a.build_types(f, [str])
+ assert isinstance(s, annmodel.SomeString)
+
def test_simple_slicing(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.simple_slice, [list])
@@ -474,7 +481,7 @@
a = self.RPythonAnnotator()
s = a.build_types(snippet.simple_iter, [list])
assert isinstance(s, annmodel.SomeIterator)
-
+
def test_simple_iter_next(self):
def f(x):
i = iter(range(x))
@@ -498,7 +505,7 @@
assert listitem(s).knowntype == tuple
assert listitem(s).items[0].knowntype == int
assert listitem(s).items[1].knowntype == str
-
+
def test_dict_copy(self):
a = self.RPythonAnnotator()
t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger())
@@ -544,7 +551,7 @@
a = self.RPythonAnnotator()
s = a.build_types(snippet.dict_values, [])
assert isinstance(listitem(s), annmodel.SomeString)
-
+
def test_dict_values2(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.dict_values2, [])
@@ -570,19 +577,19 @@
assert isinstance(dictkey(s), annmodel.SomeString)
assert isinstance(dictvalue(s), annmodel.SomeInteger)
assert not dictvalue(s).nonneg
-
+
def test_exception_deduction(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.exception_deduction, [])
assert isinstance(s, annmodel.SomeInstance)
assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
-
+
def test_exception_deduction_we_are_dumb(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.exception_deduction_we_are_dumb, [])
assert isinstance(s, annmodel.SomeInstance)
assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc)
-
+
def test_nested_exception_deduction(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.nested_exception_deduction, [])
@@ -645,8 +652,8 @@
assert Rdef.attrs['r'].s_value.classdef == Rdef
assert Rdef.attrs['n'].s_value.knowntype == int
assert Rdef.attrs['m'].s_value.knowntype == int
-
-
+
+
def test_propagation_of_fresh_instances_through_attrs_rec_eo(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.make_eo, [int])
@@ -958,7 +965,7 @@
f1(1,2)
g(f2)
g(f3)
-
+
a = self.RPythonAnnotator()
s = a.build_types(h, [])
@@ -1022,7 +1029,7 @@
famA_m = mdescA_m.getcallfamily()
famC_m = mdescC_m.getcallfamily()
famB_n = mdescB_n.getcallfamily()
-
+
assert famA_m is famC_m
assert famB_n is not famA_m
@@ -1038,7 +1045,7 @@
gfCinit = graphof(a, C.__init__.im_func)
assert famCinit.calltables == {(1, (), False, False): [{mdescCinit.funcdesc: gfCinit}] }
-
+
def test_isinstance_usigned(self):
def f(x):
return isinstance(x, r_uint)
@@ -1085,7 +1092,7 @@
s = a.build_types(f, [])
C1df = a.bookkeeper.getuniqueclassdef(C1)
C2df = a.bookkeeper.getuniqueclassdef(C2)
-
+
assert s.items[0].classdef == C1df
assert s.items[1].classdef == C2df
@@ -1098,29 +1105,29 @@
assert a.binding(graph2.getreturnvar()).classdef == C2df
assert graph1 in a.translator.graphs
assert graph2 in a.translator.graphs
-
+
def test_specialcase_args(self):
class C1(object):
pass
-
+
class C2(object):
pass
-
+
def alloc(cls, cls2):
i = cls()
assert isinstance(i, cls)
j = cls2()
assert isinstance(j, cls2)
return i
-
+
def f():
alloc(C1, C1)
alloc(C1, C2)
alloc(C2, C1)
alloc(C2, C2)
-
+
alloc._annspecialcase_ = "specialize:arg(0,1)"
-
+
a = self.RPythonAnnotator()
C1df = a.bookkeeper.getuniqueclassdef(C1)
C2df = a.bookkeeper.getuniqueclassdef(C2)
@@ -1180,9 +1187,9 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [int, int])
-
+
executedesc = a.bookkeeper.getdesc(I.execute.im_func)
- assert len(executedesc._cache) == 2
+ assert len(executedesc._cache) == 2
assert len(executedesc._cache[(0, 'star', 2)].startblock.inputargs) == 4
assert len(executedesc._cache[(1, 'star', 3)].startblock.inputargs) == 5
@@ -1201,7 +1208,7 @@
s_item = listitem(s)
assert isinstance(s_item, annmodel.SomeInstance)
assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T)
-
+
def test_assert_type_is_list_doesnt_lose_info(self):
class T(object):
pass
@@ -1254,7 +1261,7 @@
x = bool(l)
l.append(1)
return x, bool(l)
-
+
a = self.RPythonAnnotator()
s = a.build_types(f, [])
assert s.const == False
@@ -1264,7 +1271,7 @@
assert s.items[0].knowntype == bool and not s.items[0].is_constant()
assert s.items[1].knowntype == bool and not s.items[1].is_constant()
-
+
def test_empty_dict(self):
def f():
d = {}
@@ -1274,7 +1281,7 @@
x = bool(d)
d['a'] = 1
return x, bool(d)
-
+
a = self.RPythonAnnotator()
s = a.build_types(f, [])
assert s.const == False
@@ -1534,7 +1541,7 @@
def witness1(x):
pass
def witness2(x):
- pass
+ pass
def f(x):
if 0 < x:
witness1(x)
@@ -1543,15 +1550,15 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [annmodel.SomeInteger(unsigned=True)])
wg1 = graphof(a, witness1)
- wg2 = graphof(a, witness2)
+ wg2 = graphof(a, witness2)
assert a.binding(wg1.getargs()[0]).unsigned is True
- assert a.binding(wg2.getargs()[0]).unsigned is True
-
+ assert a.binding(wg2.getargs()[0]).unsigned is True
+
def test_general_nonneg_cleverness_is_gentle_with_unsigned(self):
def witness1(x):
pass
def witness2(x):
- pass
+ pass
def f(x):
if 0 < x:
witness1(x)
@@ -1560,7 +1567,7 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [annmodel.SomeInteger(knowntype=r_ulonglong)])
wg1 = graphof(a, witness1)
- wg2 = graphof(a, witness2)
+ wg2 = graphof(a, witness2)
assert a.binding(wg1.getargs()[0]).knowntype is r_ulonglong
assert a.binding(wg2.getargs()[0]).knowntype is r_ulonglong
@@ -1742,11 +1749,11 @@
assert s.const == "bool"
a = self.RPythonAnnotator()
s = a.build_types(f, [int])
- assert s.const == "int"
+ assert s.const == "int"
a = self.RPythonAnnotator()
s = a.build_types(f, [float])
- assert s.const == "dontknow"
-
+ assert s.const == "dontknow"
+
def test_hidden_method(self):
class Base:
def method(self):
@@ -1825,7 +1832,7 @@
s = a.build_types(f, [])
assert s.knowntype == bool
assert not s.is_constant()
-
+
def test_const_dict_and_none(self):
def g(d=None):
return d is None
@@ -1837,7 +1844,7 @@
s = a.build_types(f, [])
assert s.knowntype == bool
assert not s.is_constant()
-
+
def test_issubtype_and_const(self):
class A(object):
pass
@@ -1951,7 +1958,7 @@
a = annrpython.RPythonAnnotator()
from pypy.annotation import model as annmodel
- s_f = a.bookkeeper.immutablevalue(f)
+ s_f = a.bookkeeper.immutablevalue(f)
a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
a.complete()
@@ -1960,7 +1967,7 @@
someint = annmodel.SomeInteger()
- assert (fdesc.get_s_signatures((2,(),False,False))
+ assert (fdesc.get_s_signatures((2,(),False,False))
== [([someint,someint],someint)])
def test_emulated_pbc_call_callback(self):
@@ -1974,7 +1981,7 @@
def callb(ann, graph):
memo.append(annmodel.SomeInteger() == ann.binding(graph.getreturnvar()))
- s_f = a.bookkeeper.immutablevalue(f)
+ s_f = a.bookkeeper.immutablevalue(f)
s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()],
callback=callb)
assert s == annmodel.SomeImpossibleValue()
@@ -1996,7 +2003,7 @@
s = a.build_types(f, [])
assert isinstance(s, annmodel.SomeIterator)
assert s.variant == ('items',)
-
+
def test_non_none_and_none_with_isinstance(self):
class A(object):
pass
@@ -2230,7 +2237,7 @@
def f(i):
witness(None)
return witness(get(i))
-
+
a = self.RPythonAnnotator()
s = a.build_types(f, [int])
assert s.__class__ == annmodel.SomeObject
@@ -2284,8 +2291,8 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [])
assert isinstance(s.items[0], annmodel.SomeInteger)
- assert isinstance(s.items[1], annmodel.SomeChar)
- assert isinstance(s.items[2], annmodel.SomeChar)
+ assert isinstance(s.items[1], annmodel.SomeChar)
+ assert isinstance(s.items[2], annmodel.SomeChar)
def test___class___attribute(self):
class Base(object): pass
@@ -2344,7 +2351,7 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [bool])
assert s.knowntype == int
-
+
def f(x):
return -x
@@ -2394,7 +2401,7 @@
assert isinstance(s, annmodel.SomeInteger)
assert s.knowntype == inttype
assert s.unsigned == (inttype(-1) > 0)
-
+
for inttype in inttypes:
def f():
return inttype(0)
@@ -2493,11 +2500,11 @@
def test_helper_method_annotator(self):
def fun():
return 21
-
+
class A(object):
def helper(self):
return 42
-
+
a = self.RPythonAnnotator()
a.build_types(fun, [])
a.annotate_helper_method(A, "helper", [])
@@ -2794,7 +2801,7 @@
def c(x):
return int(x)
-
+
def g(a, x):
if x == -1:
a = None
@@ -2806,7 +2813,7 @@
x = x + .01
return a(x)
- #def fun(x):
+ #def fun(x):
a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
s = a.build_types(g, [annmodel.SomeGenericCallable(
@@ -2845,7 +2852,7 @@
class B(A):
def meth(self):
return self
- class C(A):
+ class C(A):
def meth(self):
return self
@@ -2893,7 +2900,7 @@
i.x = x
a = self.RPythonAnnotator()
- py.test.raises(Exception, a.build_types, f, [])
+ py.test.raises(Exception, a.build_types, f, [])
class M:
@@ -2910,30 +2917,30 @@
self.l2 = []
c = C()
-
+
def f():
x = A()
x = hint(x, access_directly=True)
c.m.l.append(x)
a = self.RPythonAnnotator()
- py.test.raises(AssertionError, a.build_types, f, [])
+ py.test.raises(AssertionError, a.build_types, f, [])
def f():
x = A()
x = hint(x, access_directly=True)
c.m.d[None] = x
-
+
a = self.RPythonAnnotator()
- py.test.raises(AssertionError, a.build_types, f, [])
+ py.test.raises(AssertionError, a.build_types, f, [])
def f():
x = A()
x = hint(x, access_directly=True)
c.m.d[x] = None
-
+
a = self.RPythonAnnotator()
- py.test.raises(AssertionError, a.build_types, f, [])
+ py.test.raises(AssertionError, a.build_types, f, [])
def test_ctr_location(self):
from pypy.rlib.jit import hint
@@ -3026,7 +3033,7 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [])
- assert isinstance(s, annmodel.SomeUnicodeString)
+ assert isinstance(s, annmodel.SomeUnicodeString)
def test_unicode(self):
def g(n):
@@ -3091,7 +3098,7 @@
a = self.RPythonAnnotator()
s = a.build_types(f, [str])
assert isinstance(s, annmodel.SomeString)
-
+
def f(x):
return u'a'.replace(x, u'b')
@@ -3105,7 +3112,7 @@
if c == i:
return c
return 'x'
-
+
a = self.RPythonAnnotator()
s = a.build_types(f, [unicode, str])
assert isinstance(s, annmodel.SomeUnicodeCodePoint)
@@ -3113,22 +3120,22 @@
def test_strformatting_unicode(self):
def f(x):
return '%s' % unichr(x)
-
+
a = self.RPythonAnnotator()
py.test.raises(NotImplementedError, a.build_types, f, [int])
def f(x):
return '%s' % (unichr(x) * 3)
-
+
a = self.RPythonAnnotator()
py.test.raises(NotImplementedError, a.build_types, f, [int])
def f(x):
return '%s%s' % (1, unichr(x))
-
+
a = self.RPythonAnnotator()
py.test.raises(NotImplementedError, a.build_types, f, [int])
def f(x):
return '%s%s' % (1, unichr(x) * 15)
-
+
a = self.RPythonAnnotator()
py.test.raises(NotImplementedError, a.build_types, f, [int])
@@ -3197,7 +3204,7 @@
called.append(True)
assert not ann.listdef.listitem.mutated
ann.listdef.never_resize()
-
+
def f():
l = [1,2,3]
check_annotation(l, checker)
@@ -3213,7 +3220,7 @@
def test_listitem_no_mutating2(self):
from pypy.rlib.debug import make_sure_not_resized
-
+
def f():
return make_sure_not_resized([1,2,3])
@@ -3293,11 +3300,11 @@
return d1[x].meth()
d1[i+1] = A()
return 0
-
+
a = self.RPythonAnnotator()
s = a.build_types(g, [int, int])
assert s.knowntype is int
-
+
def f(x):
d0 = {}
if x in d0:
@@ -3476,7 +3483,7 @@
return total
constant_unsigned_five = r_uint(5)
-
+
class Freezing:
def _freeze_(self):
return True
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -286,6 +286,7 @@
while True:
extended_arg_count = 0
offset = 0
+ force_redo = False
# Calculate the code offset of each block.
for block in blocks:
block.offset = offset
@@ -313,7 +314,7 @@
instr.has_jump = False
# The size of the code changed,
# we have to trigger another pass
- extended_arg_count += 1
+ force_redo = True
continue
if absolute:
jump_arg = target.offset
@@ -322,7 +323,7 @@
instr.arg = jump_arg
if jump_arg > 0xFFFF:
extended_arg_count += 1
- if extended_arg_count == last_extended_arg_count:
+ if extended_arg_count == last_extended_arg_count and not force_redo:
break
else:
last_extended_arg_count = extended_arg_count
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -73,6 +73,10 @@
def error_test(self, source, exc_type):
py.test.raises(exc_type, self.simple_test, source, None, None)
+ def test_issue_713(self):
+ func = "def f(_=2): return (_ if _ else _) if False else _"
+ yield self.st, func, "f()", 2
+
def test_long_jump(self):
func = """def f(x):
y = 0
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1417,13 +1417,16 @@
def print_item_to(x, stream):
if file_softspace(stream, False):
stream.write(" ")
- if isinstance(x, unicode) and getattr(stream, "encoding", None) is not None:
- x = x.encode(stream.encoding, getattr(stream, "errors", None) or "strict")
- stream.write(str(x))
+
+ # give to write() an argument which is either a string or a unicode
+ # (and let it deals itself with unicode handling)
+ if not isinstance(x, unicode):
+ x = str(x)
+ stream.write(x)
# add a softspace unless we just printed a string which ends in a '\t'
# or '\n' -- or more generally any whitespace character but ' '
- if isinstance(x, (str, unicode)) and x:
+ if x:
lastchar = x[-1]
if lastchar.isspace() and lastchar != ' ':
return
diff --git a/pypy/interpreter/test/test_interpreter.py b/pypy/interpreter/test/test_interpreter.py
--- a/pypy/interpreter/test/test_interpreter.py
+++ b/pypy/interpreter/test/test_interpreter.py
@@ -277,20 +277,25 @@
class Out(object):
def __init__(self):
self.data = []
-
def write(self, x):
- self.data.append(x)
+ self.data.append((type(x), x))
sys.stdout = out = Out()
try:
- raises(UnicodeError, "print unichr(0xa2)")
- assert out.data == []
- out.encoding = "cp424"
print unichr(0xa2)
- assert out.data == [unichr(0xa2).encode("cp424"), "\n"]
+ assert out.data == [(unicode, unichr(0xa2)), (str, "\n")]
+ out.data = []
+ out.encoding = "cp424" # ignored!
+ print unichr(0xa2)
+ assert out.data == [(unicode, unichr(0xa2)), (str, "\n")]
del out.data[:]
del out.encoding
print u"foo\t", u"bar\n", u"trick", u"baz\n" # softspace handling
- assert out.data == ["foo\t", "bar\n", "trick", " ", "baz\n", "\n"]
+ assert out.data == [(unicode, "foo\t"),
+ (unicode, "bar\n"),
+ (unicode, "trick"),
+ (str, " "),
+ (unicode, "baz\n"),
+ (str, "\n")]
finally:
sys.stdout = save
diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -261,6 +261,19 @@
self.arg_classes = arg_classes # string of "r" and "i" (ref/int)
self.extrainfo = extrainfo
+ def __repr__(self):
+ res = '%s(%s)' % (self.__class__.__name__, self.arg_classes)
+ oopspecindex = getattr(self.extrainfo, 'oopspecindex', 0)
+ if oopspecindex:
+ from pypy.jit.codewriter.effectinfo import EffectInfo
+ for key, value in EffectInfo.__dict__.items():
+ if key.startswith('OS_') and value == oopspecindex:
+ break
+ else:
+ key = 'oopspecindex=%r' % oopspecindex
+ res += ' ' + key
+ return '<%s>' % res
+
def get_extra_info(self):
return self.extrainfo
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -832,6 +832,11 @@
effectinfo = op.getdescr().get_extra_info()
oopspecindex = effectinfo.oopspecindex
genop_llong_list[oopspecindex](self, op, arglocs, resloc)
+
+ def regalloc_perform_math(self, op, arglocs, resloc):
+ effectinfo = op.getdescr().get_extra_info()
+ oopspecindex = effectinfo.oopspecindex
+ genop_math_list[oopspecindex](self, op, arglocs, resloc)
def regalloc_perform_with_guard(self, op, guard_op, faillocs,
arglocs, resloc, current_depths):
@@ -1119,6 +1124,9 @@
genop_guard_float_eq = _cmpop_guard_float("E", "E", "NE","NE")
genop_guard_float_gt = _cmpop_guard_float("A", "B", "BE","AE")
genop_guard_float_ge = _cmpop_guard_float("AE","BE", "B", "A")
+
+ def genop_math_sqrt(self, op, arglocs, resloc):
+ self.mc.SQRTSD(arglocs[0], resloc)
def genop_guard_float_ne(self, op, guard_op, guard_token, arglocs, result_loc):
guard_opnum = guard_op.getopnum()
@@ -2158,6 +2166,7 @@
genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
genop_list = [Assembler386.not_implemented_op] * rop._LAST
genop_llong_list = {}
+genop_math_list = {}
genop_guard_list = [Assembler386.not_implemented_op_guard] * rop._LAST
for name, value in Assembler386.__dict__.iteritems():
@@ -2173,6 +2182,10 @@
opname = name[len('genop_llong_'):]
num = getattr(EffectInfo, 'OS_LLONG_' + opname.upper())
genop_llong_list[num] = value
+ elif name.startswith('genop_math_'):
+ opname = name[len('genop_math_'):]
+ num = getattr(EffectInfo, 'OS_MATH_' + opname.upper())
+ genop_math_list[num] = value
elif name.startswith('genop_'):
opname = name[len('genop_'):]
num = getattr(rop, opname.upper())
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -324,6 +324,11 @@
if not we_are_translated():
self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs))
self.assembler.regalloc_perform_llong(op, arglocs, result_loc)
+
+ def PerformMath(self, op, arglocs, result_loc):
+ if not we_are_translated():
+ self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs))
+ self.assembler.regalloc_perform_math(op, arglocs, result_loc)
def locs_for_fail(self, guard_op):
return [self.loc(v) for v in guard_op.getfailargs()]
@@ -619,15 +624,13 @@
consider_float_gt = _consider_float_cmp
consider_float_ge = _consider_float_cmp
- def consider_float_neg(self, op):
+ def _consider_float_unary_op(self, op):
loc0 = self.xrm.force_result_in_reg(op.result, op.getarg(0))
self.Perform(op, [loc0], loc0)
self.xrm.possibly_free_var(op.getarg(0))
-
- def consider_float_abs(self, op):
- loc0 = self.xrm.force_result_in_reg(op.result, op.getarg(0))
- self.Perform(op, [loc0], loc0)
- self.xrm.possibly_free_var(op.getarg(0))
+
+ consider_float_neg = _consider_float_unary_op
+ consider_float_abs = _consider_float_unary_op
def consider_cast_float_to_int(self, op):
loc0 = self.xrm.make_sure_var_in_reg(op.getarg(0))
@@ -713,6 +716,11 @@
loc1 = self.rm.make_sure_var_in_reg(op.getarg(1))
self.PerformLLong(op, [loc1], loc0)
self.rm.possibly_free_vars_for_op(op)
+
+ def _consider_math_sqrt(self, op):
+ loc0 = self.xrm.force_result_in_reg(op.result, op.getarg(1))
+ self.PerformMath(op, [loc0], loc0)
+ self.xrm.possibly_free_var(op.getarg(1))
def _call(self, op, arglocs, force_store=[], guard_not_forced_op=None):
save_all_regs = guard_not_forced_op is not None
@@ -749,12 +757,12 @@
guard_not_forced_op=guard_not_forced_op)
def consider_call(self, op):
- if IS_X86_32:
- # support for some of the llong operations,
- # which only exist on x86-32
- effectinfo = op.getdescr().get_extra_info()
- if effectinfo is not None:
- oopspecindex = effectinfo.oopspecindex
+ effectinfo = op.getdescr().get_extra_info()
+ if effectinfo is not None:
+ oopspecindex = effectinfo.oopspecindex
+ if IS_X86_32:
+ # support for some of the llong operations,
+ # which only exist on x86-32
if oopspecindex in (EffectInfo.OS_LLONG_ADD,
EffectInfo.OS_LLONG_SUB,
EffectInfo.OS_LLONG_AND,
@@ -773,7 +781,8 @@
if oopspecindex == EffectInfo.OS_LLONG_LT:
if self._maybe_consider_llong_lt(op):
return
- #
+ if oopspecindex == EffectInfo.OS_MATH_SQRT:
+ return self._consider_math_sqrt(op)
self._consider_call(op)
def consider_call_may_force(self, op, guard_op):
diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -515,6 +515,8 @@
UCOMISD = _binaryop('UCOMISD')
CVTSI2SD = _binaryop('CVTSI2SD')
CVTTSD2SI = _binaryop('CVTTSD2SI')
+
+ SQRTSD = _binaryop('SQRTSD')
ANDPD = _binaryop('ANDPD')
XORPD = _binaryop('XORPD')
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -1,3 +1,4 @@
+import py
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.llinterp import LLInterpreter
@@ -10,6 +11,11 @@
from pypy.jit.backend.x86 import regloc
import sys
+from pypy.tool.ansi_print import ansi_log
+log = py.log.Producer('jitbackend')
+py.log.setconsumer('jitbackend', ansi_log)
+
+
class AbstractX86CPU(AbstractLLCPU):
debug = True
supports_floats = True
@@ -29,6 +35,8 @@
config = rtyper.annotator.translator.config
if config.translation.jit_profiler == "oprofile":
from pypy.jit.backend.x86 import oprofile
+ if not oprofile.OPROFILE_AVAILABLE:
+ log.WARNING('oprofile support was explicitly enabled, but oprofile headers seem not to be available')
profile_agent = oprofile.OProfileAgent()
self.profile_agent = profile_agent
diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py
--- a/pypy/jit/backend/x86/rx86.py
+++ b/pypy/jit/backend/x86/rx86.py
@@ -691,6 +691,8 @@
define_modrm_modes('MOVSD_x*', ['\xF2', rex_nw, '\x0F\x10', register(1,8)], regtype='XMM')
define_modrm_modes('MOVSD_*x', ['\xF2', rex_nw, '\x0F\x11', register(2,8)], regtype='XMM')
+define_modrm_modes('SQRTSD_x*', ['\xF2', rex_nw, '\x0F\x51', register(1,8)], regtype='XMM')
+
#define_modrm_modes('XCHG_r*', [rex_w, '\x87', register(1, 8)])
define_modrm_modes('ADDSD_x*', ['\xF2', rex_nw, '\x0F\x58', register(1, 8)], regtype='XMM')
diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -72,6 +72,8 @@
OS_LLONG_UGE = 91
OS_LLONG_URSHIFT = 92
OS_LLONG_FROM_UINT = 93
+ #
+ OS_MATH_SQRT = 100
def __new__(cls, readonly_descrs_fields,
write_descrs_fields, write_descrs_arrays,
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
@@ -351,6 +351,8 @@
prepare = self._handle_jit_call
elif oopspec_name.startswith('libffi_'):
prepare = self._handle_libffi_call
+ elif oopspec_name.startswith('math.sqrt'):
+ prepare = self._handle_math_sqrt_call
else:
prepare = self.prepare_builtin_call
try:
@@ -1360,6 +1362,13 @@
assert vinfo is not None
self.vable_flags[op.args[0]] = op.args[2].value
return []
+
+ # ---------
+ # ll_math.sqrt_nonneg()
+
+ def _handle_math_sqrt_call(self, op, oopspec_name, args):
+ return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT,
+ EffectInfo.EF_PURE)
# ____________________________________________________________
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -4,6 +4,7 @@
from pypy.rpython import rlist
from pypy.rpython.lltypesystem import rstr as ll_rstr, rdict as ll_rdict
from pypy.rpython.lltypesystem import rlist as lltypesystem_rlist
+from pypy.rpython.lltypesystem.module import ll_math
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.ootypesystem import rdict as oo_rdict
from pypy.rpython.llinterp import LLInterpreter
@@ -221,6 +222,11 @@
return -x
else:
return x
+
+# math support
+# ------------
+
+_ll_1_ll_math_ll_math_sqrt = ll_math.ll_math_sqrt
# long long support
@@ -388,6 +394,7 @@
('int_mod_zer', [lltype.Signed, lltype.Signed], lltype.Signed),
('int_lshift_ovf', [lltype.Signed, lltype.Signed], lltype.Signed),
('int_abs', [lltype.Signed], lltype.Signed),
+ ('ll_math.ll_math_sqrt', [lltype.Float], lltype.Float),
]
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
@@ -5,6 +5,7 @@
from pypy.jit.codewriter.jtransform import Transformer
from pypy.jit.metainterp.history import getkind
from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rlist
+from pypy.rpython.lltypesystem.module import ll_math
from pypy.translator.unsimplify import varoftype
from pypy.jit.codewriter import heaptracker, effectinfo
from pypy.jit.codewriter.flatten import ListOfKind
@@ -98,7 +99,9 @@
PUNICODE = lltype.Ptr(rstr.UNICODE)
INT = lltype.Signed
UNICHAR = lltype.UniChar
+ FLOAT = lltype.Float
argtypes = {
+ EI.OS_MATH_SQRT: ([FLOAT], FLOAT),
EI.OS_STR2UNICODE:([PSTR], PUNICODE),
EI.OS_STR_CONCAT: ([PSTR, PSTR], PSTR),
EI.OS_STR_SLICE: ([PSTR, INT, INT], PSTR),
@@ -947,3 +950,22 @@
assert op1.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_ARRAYCOPY
assert op1.args[2] == ListOfKind('int', [v3, v4, v5])
assert op1.args[3] == ListOfKind('ref', [v1, v2])
+
+def test_math_sqrt():
+ # test that the oopspec is present and correctly transformed
+ FLOAT = lltype.Float
+ FUNC = lltype.FuncType([FLOAT], FLOAT)
+ func = lltype.functionptr(FUNC, 'll_math',
+ _callable=ll_math.sqrt_nonneg)
+ v1 = varoftype(FLOAT)
+ v2 = varoftype(FLOAT)
+ op = SpaceOperation('direct_call', [const(func), v1], v2)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'residual_call_irf_f'
+ assert op1.args[0].value == func
+ assert op1.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_MATH_SQRT
+ assert op1.args[2] == ListOfKind("int", [])
+ assert op1.args[3] == ListOfKind("ref", [])
+ assert op1.args[4] == ListOfKind('float', [v1])
+ assert op1.result == v2
diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py
--- a/pypy/jit/metainterp/test/support.py
+++ b/pypy/jit/metainterp/test/support.py
@@ -9,6 +9,7 @@
from pypy.jit.metainterp.warmstate import set_future_value
from pypy.jit.codewriter.policy import JitPolicy
from pypy.jit.codewriter import longlong
+from pypy.rlib.rfloat import isinf, isnan
def _get_jitcodes(testself, CPUClass, func, values, type_system,
supports_longlong=False, **kwds):
@@ -51,6 +52,7 @@
cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
testself.cw = cw
policy = JitPolicy()
+ policy.set_supports_floats(True)
policy.set_supports_longlong(supports_longlong)
cw.find_all_graphs(policy)
#
@@ -180,10 +182,10 @@
result1 = _run_with_blackhole(self, args)
# try to run it with pyjitpl.py
result2 = _run_with_pyjitpl(self, args)
- assert result1 == result2
+ assert result1 == result2 or isnan(result1) and isnan(result2)
# try to run it by running the code compiled just before
result3 = _run_with_machine_code(self, args)
- assert result1 == result3 or result3 == NotImplemented
+ assert result1 == result3 or result3 == NotImplemented or isnan(result1) and isnan(result3)
#
if (longlong.supports_longlong and
isinstance(result1, longlong.r_float_storage)):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -1664,6 +1664,7 @@
assert loop.match_by_id('shift', "") # optimized away
def test_division_to_rshift(self):
+ py.test.skip('in-progress')
def main(b):
res = 0
a = 0
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -11,7 +11,7 @@
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.rlib.rstring import StringBuilder, string_repeat
+from pypy.rlib.rstring import StringBuilder
from pypy.interpreter.buffer import StringBuffer
from pypy.objspace.std.stringtype import sliced, wrapstr, wrapchar, \
@@ -856,7 +856,7 @@
if len(input) == 1:
s = input[0] * mul
else:
- s = string_repeat(input, mul)
+ s = input * mul
# xxx support again space.config.objspace.std.withstrjoin?
return W_StringObject(s)
@@ -963,19 +963,20 @@
space.wrap("translation table must be 256 characters long"))
string = w_string._value
- chars = []
deletechars = space.str_w(w_deletechars)
if len(deletechars) == 0:
+ buf = StringBuilder(len(string))
for char in string:
- chars.append(table[ord(char)])
+ buf.append(table[ord(char)])
else:
+ buf = StringBuilder()
deletion_table = [False] * 256
for c in deletechars:
deletion_table[ord(c)] = True
for char in string:
if not deletion_table[ord(char)]:
- chars.append(table[ord(char)])
- return W_StringObject(''.join(chars))
+ buf.append(table[ord(char)])
+ return W_StringObject(buf.build())
def str_decode__String_ANY_ANY(space, w_string, w_encoding=None, w_errors=None):
from pypy.objspace.std.unicodetype import _get_encoding_and_errors, \
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -11,7 +11,7 @@
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
from pypy.rlib.objectmodel import compute_hash
-from pypy.rlib.rstring import UnicodeBuilder, string_repeat
+from pypy.rlib.rstring import UnicodeBuilder
from pypy.rlib.runicode import unicode_encode_unicode_escape
from pypy.module.unicodedata import unicodedb
from pypy.tool.sourcetools import func_with_new_name
@@ -278,7 +278,7 @@
if len(input) == 1:
result = input[0] * times
else:
- result = string_repeat(input, times)
+ result = input * times
return W_UnicodeObject(result)
def mul__ANY_Unicode(space, w_times, w_uni):
diff --git a/pypy/rlib/rstring.py b/pypy/rlib/rstring.py
--- a/pypy/rlib/rstring.py
+++ b/pypy/rlib/rstring.py
@@ -3,7 +3,6 @@
from pypy.annotation.model import SomeObject, SomeString, s_None,\
SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString
-from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.extregistry import ExtRegistryEntry
@@ -79,32 +78,6 @@
tp = unicode
-# XXX: This does log(mul) mallocs, the GCs probably make that efficient, but
-# some measurement should be done at some point.
-def string_repeat(s, mul):
- """Repeat a string or unicode. Note that this assumes that 'mul' > 0."""
- result = None
- factor = 1
- assert mul > 0
- try:
- ovfcheck(len(s) * mul)
- except OverflowError:
- raise MemoryError
-
- limit = mul >> 1
- while True:
- if mul & factor:
- if result is None:
- result = s
- else:
- result = s + result
- if factor > limit:
- break
- s += s
- factor *= 2
- return result
-string_repeat._annspecialcase_ = 'specialize:argtype(0)'
-
# ------------------------------------------------------------
# ----------------- implementation details -------------------
# ------------------------------------------------------------
@@ -159,7 +132,7 @@
def method_build(self):
return SomeUnicodeString()
-
+
def rtyper_makerepr(self, rtyper):
return rtyper.type_system.rbuilder.unicodebuilder_repr
@@ -170,7 +143,7 @@
if self.use_unicode:
return SomeUnicodeBuilder()
return SomeStringBuilder()
-
+
def specialize_call(self, hop):
return hop.r_result.rtyper_new(hop)
diff --git a/pypy/rlib/test/test_rstring.py b/pypy/rlib/test/test_rstring.py
--- a/pypy/rlib/test/test_rstring.py
+++ b/pypy/rlib/test/test_rstring.py
@@ -1,7 +1,6 @@
import sys
-from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, split, rsplit, \
- string_repeat
+from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, split, rsplit
def test_split():
@@ -43,7 +42,4 @@
assert s.getlength() == len('aabcb')
s.append_multiple_char(u'd', 4)
assert s.build() == 'aabcbdddd'
- assert isinstance(s.build(), unicode)
-
-def test_string_repeat():
- raises(MemoryError, string_repeat, "abc", sys.maxint)
+ assert isinstance(s.build(), unicode)
\ No newline at end of file
diff --git a/pypy/rpython/extfuncregistry.py b/pypy/rpython/extfuncregistry.py
--- a/pypy/rpython/extfuncregistry.py
+++ b/pypy/rpython/extfuncregistry.py
@@ -45,6 +45,9 @@
register_external(math.floor, [float], float,
export_name="ll_math.ll_math_floor", sandboxsafe=True,
llimpl=ll_math.ll_math_floor)
+register_external(math.sqrt, [float], float,
+ export_name="ll_math.ll_math_sqrt", sandboxsafe=True,
+ llimpl=ll_math.ll_math_sqrt)
complex_math_functions = [
('frexp', [float], (float, int)),
diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py
--- a/pypy/rpython/lltypesystem/module/ll_math.py
+++ b/pypy/rpython/lltypesystem/module/ll_math.py
@@ -9,7 +9,7 @@
from pypy.rlib import jit, rposix
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator.platform import platform
-from pypy.rlib.rfloat import isinf, isnan, INFINITY, NAN
+from pypy.rlib.rfloat import isfinite, isinf, isnan, INFINITY, NAN
if sys.platform == "win32":
if platform.name == "msvc":
@@ -69,6 +69,13 @@
[rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE, pure_function=True)
+math_sqrt = llexternal('sqrt', [rffi.DOUBLE], rffi.DOUBLE)
+
+ at jit.purefunction
+def sqrt_nonneg(x):
+ return math_sqrt(x)
+sqrt_nonneg.oopspec = "math.sqrt_nonneg(x)"
+
# ____________________________________________________________
#
# Error handling functions
@@ -319,6 +326,15 @@
_likely_raise(errno, r)
return r
+def ll_math_sqrt(x):
+ if x < 0.0:
+ raise ValueError, "math domain error"
+
+ if isfinite(x):
+ return sqrt_nonneg(x)
+
+ return x # +inf or nan
+
# ____________________________________________________________
#
# Default implementations
@@ -357,7 +373,7 @@
unary_math_functions = [
'acos', 'asin', 'atan',
'ceil', 'cos', 'cosh', 'exp', 'fabs',
- 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'log', 'log10',
+ 'sin', 'sinh', 'tan', 'tanh', 'log', 'log10',
'acosh', 'asinh', 'atanh', 'log1p', 'expm1',
]
unary_math_functions_can_overflow = [
diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -5,6 +5,7 @@
from pypy.rlib.objectmodel import _hash_string, enforceargs
from pypy.rlib.debug import ll_assert
from pypy.rlib.jit import purefunction, we_are_jitted
+from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.robject import PyObjRepr, pyobj_repr
from pypy.rpython.rmodel import inputconst, IntegerRepr
from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\
@@ -255,6 +256,27 @@
class LLHelpers(AbstractLLHelpers):
+ @purefunction
+ def ll_str_mul(s, times):
+ if times < 0:
+ times = 0
+ try:
+ size = ovfcheck(len(s.chars) * times)
+ except OverflowError:
+ raise MemoryError
+ newstr = s.malloc(size)
+ i = 0
+ if i < size:
+ s.copy_contents(s, newstr, 0, 0, len(s.chars))
+ i += len(s.chars)
+ while i < size:
+ if i <= size - i:
+ j = i
+ else:
+ j = size - i
+ s.copy_contents(newstr, newstr, 0, i, j)
+ i += j
+ return newstr
@purefunction
def ll_char_mul(ch, times):
diff --git a/pypy/rpython/ootypesystem/rstr.py b/pypy/rpython/ootypesystem/rstr.py
--- a/pypy/rpython/ootypesystem/rstr.py
+++ b/pypy/rpython/ootypesystem/rstr.py
@@ -1,4 +1,5 @@
from pypy.tool.pairtype import pairtype
+from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.error import TyperError
from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\
AbstractUniCharRepr, AbstractStringIteratorRepr,\
@@ -134,6 +135,19 @@
i+= 1
return buf.ll_build()
+ def ll_str_mul(s, times):
+ if times < 0:
+ times = 0
+ try:
+ size = ovfcheck(s.ll_strlen() * times)
+ except OverflowError:
+ raise MemoryError
+ buf = ootype.new(typeOf(s).builder)
+ buf.ll_allocate(size)
+ for i in xrange(times):
+ buf.ll_append(s)
+ return buf.ll_build()
+
def ll_streq(s1, s2):
if s1 is None:
return s2 is None
@@ -203,7 +217,7 @@
return s.ll_substring(start, s.ll_strlen() - start)
def ll_stringslice_startstop(s, start, stop):
- length = s.ll_strlen()
+ length = s.ll_strlen()
if stop > length:
stop = length
return s.ll_substring(start, stop-start)
@@ -265,7 +279,7 @@
def ll_float(ll_str):
return ootype.ooparse_float(ll_str)
-
+
# interface to build strings:
# x = ll_build_start(n)
# ll_build_push(x, next_string, 0)
@@ -300,7 +314,7 @@
c8 = hop.inputconst(ootype.Signed, 8)
c10 = hop.inputconst(ootype.Signed, 10)
c16 = hop.inputconst(ootype.Signed, 16)
- c_StringBuilder = hop.inputconst(ootype.Void, ootype.StringBuilder)
+ c_StringBuilder = hop.inputconst(ootype.Void, ootype.StringBuilder)
v_buf = hop.genop("new", [c_StringBuilder], resulttype=ootype.StringBuilder)
things = cls.parse_fmt_string(s)
@@ -334,7 +348,7 @@
hop.genop('oosend', [c_append, v_buf, vchunk], resulttype=ootype.Void)
hop.exception_cannot_occur() # to ignore the ZeroDivisionError of '%'
- return hop.genop('oosend', [c_build, v_buf], resulttype=ootype.String)
+ return hop.genop('oosend', [c_build, v_buf], resulttype=ootype.String)
do_stringformat = classmethod(do_stringformat)
@@ -399,7 +413,7 @@
return iter
def ll_strnext(iter):
- string = iter.string
+ string = iter.string
index = iter.index
if index >= string.ll_strlen():
raise StopIteration
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -34,7 +34,7 @@
class __extend__(annmodel.SomeUnicodeString):
def rtyper_makerepr(self, rtyper):
return rtyper.type_system.rstr.unicode_repr
-
+
def rtyper_makekey(self):
return self.__class__,
@@ -164,7 +164,7 @@
v_str, = hop.inputargs(string_repr)
hop.exception_cannot_occur()
return hop.gendirectcall(self.ll.ll_upper, v_str)
-
+
def rtype_method_lower(self, hop):
string_repr = hop.args_r[0].repr
v_str, = hop.inputargs(string_repr)
@@ -361,6 +361,17 @@
rtype_getitem_idx_key = rtype_getitem_idx
+ def rtype_mul((r_str, r_int), hop):
+ str_repr = r_str.repr
+ v_str, v_int = hop.inputargs(str_repr, Signed)
+ return hop.gendirectcall(r_str.ll.ll_str_mul, v_str, v_int)
+ rtype_inplace_mul = rtype_mul
+
+class __extend__(pairtype(IntegerRepr, AbstractStringRepr)):
+ def rtype_mul((r_int, r_str), hop):
+ return pair(r_str, r_int).rtype_mul(hop)
+ rtype_inplace_mul = rtype_mul
+
class __extend__(AbstractStringRepr):
@@ -384,7 +395,7 @@
def rtype_eq((r_str1, r_str2), hop):
v_str1, v_str2 = hop.inputargs(r_str1.repr, r_str2.repr)
return hop.gendirectcall(r_str1.ll.ll_streq, v_str1, v_str2)
-
+
def rtype_ne((r_str1, r_str2), hop):
v_str1, v_str2 = hop.inputargs(r_str1.repr, r_str2.repr)
vres = hop.gendirectcall(r_str1.ll.ll_streq, v_str1, v_str2)
@@ -465,7 +476,7 @@
return value
def get_ll_eq_function(self):
- return None
+ return None
def get_ll_hash_function(self):
return self.ll.ll_char_hash
@@ -505,7 +516,7 @@
class __extend__(pairtype(AbstractCharRepr, IntegerRepr),
pairtype(AbstractUniCharRepr, IntegerRepr)):
-
+
def rtype_mul((r_chr, r_int), hop):
char_repr = r_chr.char_repr
v_char, v_int = hop.inputargs(char_repr, Signed)
@@ -545,7 +556,7 @@
return value
def get_ll_eq_function(self):
- return None
+ return None
def get_ll_hash_function(self):
return self.ll.ll_unichar_hash
diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py
--- a/pypy/rpython/test/test_rstr.py
+++ b/pypy/rpython/test/test_rstr.py
@@ -88,7 +88,7 @@
for i in range(3):
res = self.interpret(fn, [i])
assert res is True
-
+
def test_char_constant(self):
const = self.const
def fn(s):
@@ -141,6 +141,16 @@
res = self.interpret(fn, [const('5'), 3])
assert res == 5551
+ def test_str_mul(self):
+ const = self.const
+ def fn(i, mul):
+ s = ["", "a", "aba"][i]
+ return s * mul
+ for i in xrange(3):
+ for m in [0, 1, 4]:
+ res = self.interpret(fn, [i, m])
+ assert self.ll_to_string(res) == fn(i, m)
+
def test_is_none(self):
const = self.const
def fn(i):
@@ -295,7 +305,7 @@
for i, expected in enumerate([0, 1110, 2220, 3330, -1110, -1110]):
res = self.interpret(f, [i])
assert res == expected
-
+
def test_rfind(self):
const = self.const
def fn():
@@ -531,7 +541,7 @@
assert res.find('>, much nicer than <D object') != -1
res = self.ll_to_string(self.interpret(dummy, [0]))
- res = res.replace('pypy.rpython.test.test_rstr.', '')
+ res = res.replace('pypy.rpython.test.test_rstr.', '')
assert res.find('what a nice <D object') != -1
assert res.find('>, much nicer than <C object') != -1
@@ -786,7 +796,7 @@
return const('ababa').count(const('aba'))
res = self.interpret(fn, [])
assert res == 1
-
+
def test_count_TyperError(self):
const = self.const
def f():
@@ -797,7 +807,7 @@
s = const('abc')
s.count(s, -10)
raises(TyperError, self.interpret, f, ())
-
+
def test_getitem_exc(self):
const = self.const
def f(x):
@@ -812,7 +822,7 @@
pass
else:
assert False
-
+
def f(x):
s = const("z")
try:
@@ -825,7 +835,7 @@
res = self.interpret(f, [0])
assert res == 'z'
res = self.interpret(f, [1])
- assert res == 'X'
+ assert res == 'X'
def f(x):
s = const("z")
@@ -882,7 +892,7 @@
assert self.ll_to_string(self.interpret(f, [1,
self.string_to_ll('abc')])) == 'ababc'
-
+
def test_hlstr(self):
const = self.const
from pypy.rpython.annlowlevel import hlstr
@@ -965,7 +975,7 @@
def test_ll_find_rfind(self):
llstr = self.string_to_ll
-
+
for i in range(50):
n1 = random.randint(0, 10)
s1 = ''.join([random.choice("ab") for i in range(n1)])
diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py
--- a/pypy/rpython/tool/rffi_platform.py
+++ b/pypy/rpython/tool/rffi_platform.py
@@ -787,7 +787,7 @@
eci = ExternalCompilationInfo(
platform=platform,
includes=includes,
- libraries=['gc'],
+ libraries=['gc', 'dl'],
)
return configure_external_library(
'gc', eci,
diff --git a/pypy/tool/algo/test/test_unionref.py b/pypy/tool/algo/test/test_unionref.py
deleted file mode 100644
--- a/pypy/tool/algo/test/test_unionref.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from pypy.tool.algo.unionref import UnionRef, UnionDict
-
-def test_ref():
- x = object()
- ref = UnionRef(x)
- assert ref() is x
- assert ref == ref
- assert ref != UnionRef(x)
-
-def test_merge():
- d1 = {1: '1'}
- d2 = {2: '2'}
- d3 = {3: '3'}
- d4 = {4: '4'}
- r1 = UnionRef(d1)
- r2 = UnionRef(d2)
- r3 = UnionRef(d3)
- r4 = UnionRef(d4)
- r1.merge(r1)
- assert r1 != r2 != r3 != r4
- r1.merge(r2)
- assert r1() is r2() == {1: '1', 2: '2'}
- assert r1 == r2
- r3.merge(r4)
- assert r3() is r4() == {3: '3', 4: '4'}
- assert r1 != r3
- assert r2 != r3
- assert r1 != r4
- assert r2 != r4
- r1.merge(r4)
- assert r1() is r2() is r3() is r4() == {1: '1', 2: '2', 3: '3', 4: '4'}
- assert r1 == r2 == r3 == r4
-
-def test_uniondict():
- k1 = object()
- k2 = object()
- k3 = object()
- k4 = object()
- d = UnionDict()
- d[k1] = {1: '1'}
- d[k2] = {2: '2'}
- d[k3] = {3: '3'}
- d[k4] = {4: '4'}
- assert d[k1] == {1: '1'}
- assert d[k2] == {2: '2'}
- assert d[k3] == {3: '3'}
- assert d[k4] == {4: '4'}
- assert len(d) == 4
- d.merge(k1, k2)
- d.merge(k3, k4)
- assert d[k1] is d[k2] == {1: '1', 2: '2'}
- assert d[k3] is d[k4] == {3: '3', 4: '4'}
- d.merge(k1, k4)
- assert d[k1] is d[k2] is d[k3] is d[k4] == {1: '1', 2: '2', 3: '3', 4: '4'}
- assert len(d) == 4
diff --git a/pypy/tool/algo/unionref.py b/pypy/tool/algo/unionref.py
deleted file mode 100644
--- a/pypy/tool/algo/unionref.py
+++ /dev/null
@@ -1,151 +0,0 @@
-"""
-ref = UnionRef(x) -> creates a reference to x, such that ref() is x.
-
-Two references can be merged: ref.merge(ref2) make ref and ref2 interchangeable.
-After a merge, ref() is ref2(). This is done by asking the two older objects
-that ref and ref2 pointed to how they should be merged. The point is that
-large equivalence relations can be built this way:
-
- >>> ref1.merge(ref2)
- >>> ref3.merge(ref4)
- >>> ref1() is ref4()
- False
- >>> ref2.merge(ref3)
- >>> ref1() is ref4()
- True
-
-By default, two objects x and y are merged by calling x.update(y).
-"""
-
-import UserDict
-from pypy.tool.uid import uid
-
-
-class UnionRef(object):
- __slots__ = ('_obj', '_parent', '_weight')
-
- def __init__(self, obj):
- "Build a new reference to 'obj'."
- self._obj = obj
- self._parent = None
- self._weight = 1
-
- def __call__(self):
- "Return the 'obj' that self currently references."
- return self._findrep()._obj
-
- def _findrep(self):
- p = self._parent
- if p:
- if p._parent:
- # this linked list is unnecessarily long, shorten it
- path = [self]
- while p._parent:
- path.append(p)
- p = p._parent
- for q in path:
- q._parent = p
- return p
- return self
-
- def merge(self, other, union=None):
- "Merge two references. After a.merge(b), a() and b() are identical."
- self = self ._findrep()
- other = other._findrep()
- if self is not other:
- w1 = self ._weight
- w2 = other._weight
- if w1 < w2:
- self, other = other, self
- self._weight = w1 + w2
- other._parent = self
- o = other._obj
- del other._obj
- if union is not None:
- self._obj = union(self._obj, o)
- else:
- self.update(o)
- return self
-
- def update(self, obj):
- "Merge 'obj' in self. Default implementation, can be overridden."
- self._obj.update(obj)
-
- def __hash__(self):
- raise TypeError("UnionRef objects are unhashable")
-
- def __eq__(self, other):
- return (isinstance(other, UnionRef) and
- self._findrep() is other._findrep())
-
- def __ne__(self, other):
- return not (self == other)
-
-
-class UnionDict(object, UserDict.DictMixin):
- """Mapping class whose items can be unified. Conceptually, instead of
- a set of (key, value) pairs, this is a set of ({keys}, value) pairs.
- The method merge(key1, key2) merges the two pairs containing, respectively,
- key1 and key2.
- """
- _slots = ('_data',)
-
- def __init__(self, dict=None, **kwargs):
- self._data = {}
- if dict is not None:
- self.update(dict)
- if len(kwargs):
- self.update(kwargs)
-
- def merge(self, key1, key2, union=None):
- self._data[key1] = self._data[key1].merge(self._data[key2], union)
-
- def copy(self):
- result = UnionDict()
- newrefs = {}
- for key, valueref in self._data.iteritems():
- valueref = valueref._findrep()
- try:
- newref = newrefs[valueref]
- except KeyError:
- newref = newrefs[valueref] = UnionRef(valueref())
- result._data[key] = newref
- return result
-
- def __repr__(self):
- return "<UnionDict at 0x%x>" % uid(self)
-
- def __getitem__(self, key):
- return self._data[key]()
-
- def __setitem__(self, key, value):
- self._data[key] = UnionRef(value)
-
- def __delitem__(self, key):
- del self._data[key]
-
- def keys(self):
- return self._data.keys()
-
- def has_key(self, key):
- return key in self._data
-
- def __contains__(self, key):
- return key in self._data
-
- def __iter__(self):
- return iter(self._data)
-
- def iteritems(self):
- for key, valueref in self._data.iteritems():
- yield (key, valueref())
-
- def clear(self):
- self._data.clear()
-
- def popitem(self):
- key, valueref = self._data.popitem()
- return key, valueref()
-
- def __len__(self):
- return len(self._data)
More information about the pypy-commit
mailing list