[pypy-commit] pypy default: Implement "x in (constant-tuple)" not by doing a dictionary lookup,
arigo
noreply at buildbot.pypy.org
Tue Mar 11 09:59:56 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r69851:c823adbf0d32
Date: 2014-03-11 09:59 +0100
http://bitbucket.org/pypy/pypy/changeset/c823adbf0d32/
Log: Implement "x in (constant-tuple)" not by doing a dictionary lookup,
but instead as a chain of equalities.
diff --git a/rpython/rtyper/rtuple.py b/rpython/rtyper/rtuple.py
--- a/rpython/rtyper/rtuple.py
+++ b/rpython/rtyper/rtuple.py
@@ -290,20 +290,23 @@
if not s_tup.is_constant():
raise TyperError("contains() on non-const tuple")
t = s_tup.const
- typ = type(t[0])
- for x in t[1:]:
- if type(x) is not typ:
- raise TyperError("contains() on mixed-type tuple "
- "constant %r" % (t,))
- d = {}
+ if len(t) == 0:
+ hop.exception_cannot_occur()
+ return hop.inputconst(Bool, False)
+ r_item = hop.args_r[1]
+ v_arg = hop.inputarg(r_item, arg=1)
+ ll_eq = r_item.get_ll_eq_function() or _ll_equal
+ v_result = None
for x in t:
- d[x] = None
- hop2 = hop.copy()
- _, _ = hop2.r_s_popfirstarg()
- v_dict = Constant(d)
- s_dict = hop.rtyper.annotator.bookkeeper.immutablevalue(d)
- hop2.v_s_insertfirstarg(v_dict, s_dict)
- return hop2.dispatch()
+ c_tuple_item = hop.inputconst(r_item, x)
+ v_equal = hop.gendirectcall(ll_eq, v_arg, c_tuple_item)
+ if v_result is None:
+ v_result = v_equal
+ else:
+ v_result = hop.genop("int_or", [v_result, v_equal],
+ resulttype = Bool)
+ hop.exception_cannot_occur()
+ return v_result or hop.inputconst(Bool, False)
class __extend__(pairtype(TupleRepr, TupleRepr)):
@@ -400,3 +403,6 @@
return t.item0
else:
raise StopIteration
+
+def _ll_equal(x, y):
+ return x == y
diff --git a/rpython/rtyper/test/test_rtuple.py b/rpython/rtyper/test/test_rtuple.py
--- a/rpython/rtyper/test/test_rtuple.py
+++ b/rpython/rtyper/test/test_rtuple.py
@@ -73,6 +73,20 @@
res = self.interpret(f, [0])
assert res is False
+ def test_constant_tuple_contains3(self):
+ def f(i):
+ return i in ()
+ res = self.interpret(f, [3])
+ assert res is False
+
+ def test_constant_tuple_contains4(self):
+ def f(i):
+ return i in (3,)
+ res = self.interpret(f, [3])
+ assert res is True
+ res = self.interpret(f, [4])
+ assert res is False
+
def test_constant_unichar_tuple_contains(self):
def f(i):
return unichr(i) in (u'1', u'9')
More information about the pypy-commit
mailing list