[pypy-commit] pypy default: merge
justinpeel
noreply at buildbot.pypy.org
Tue Jul 12 00:47:16 CEST 2011
Author: Justin Peel <notmuchtotell at gmail.com>
Branch:
Changeset: r45488:daa5541d43ee
Date: 2011-07-11 16:46 -0600
http://bitbucket.org/pypy/pypy/changeset/daa5541d43ee/
Log: merge
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
@@ -16,27 +16,92 @@
loop, = log.loops_by_filename(self.filepath)
assert loop.match("""
i14 = int_lt(i6, i9)
- guard_true(i14, descr=<Guard42>)
+ guard_true(i14, descr=...)
+ guard_not_invalidated(descr=...)
i15 = int_mod(i6, i10)
i17 = int_rshift(i15, 63)
i18 = int_and(i10, i17)
i19 = int_add(i15, i18)
i21 = int_lt(i19, 0)
- guard_false(i21, descr=<Guard43>)
+ guard_false(i21, descr=...)
i22 = int_ge(i19, i10)
- guard_false(i22, descr=<Guard44>)
+ guard_false(i22, descr=...)
i23 = strgetitem(p11, i19)
i24 = int_ge(i19, i12)
- guard_false(i24, descr=<Guard45>)
+ guard_false(i24, descr=...)
i25 = unicodegetitem(p13, i19)
- guard_not_invalidated(descr=<Guard46>)
p27 = newstr(1)
strsetitem(p27, 0, i23)
p30 = call(ConstClass(ll_str2unicode__rpy_stringPtr), p27, descr=<GcPtrCallDescr>)
- guard_no_exception(descr=<Guard47>)
+ guard_no_exception(descr=...)
i32 = call(ConstClass(_ll_2_str_eq_checknull_char__rpy_unicodePtr_UniChar), p30, i25, descr=<SignedCallDescr>)
- guard_true(i32, descr=<Guard48>)
+ guard_true(i32, descr=...)
i34 = int_add(i6, 1)
--TICK--
jump(p0, p1, p2, p3, p4, p5, i34, p7, p8, i9, i10, p11, i12, p13, descr=<Loop4>)
+ """)
+
+ def test_long(self):
+ def main(n):
+ import string
+ i = 1
+ while i < n:
+ i += int(long(string.digits[i % len(string.digits)], 16))
+ return i
+
+ log = self.run(main, [1000])
+ assert log.result == main(1000)
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i11 = int_lt(i6, i7)
+ guard_true(i11, descr=...)
+ guard_not_invalidated(descr=...)
+ i13 = int_eq(i6, -9223372036854775808)
+ guard_false(i13, descr=...)
+ i15 = int_mod(i6, i8)
+ i17 = int_rshift(i15, 63)
+ i18 = int_and(i8, i17)
+ i19 = int_add(i15, i18)
+ i21 = int_lt(i19, 0)
+ guard_false(i21, descr=...)
+ i22 = int_ge(i19, i8)
+ guard_false(i22, descr=...)
+ i23 = strgetitem(p10, i19)
+ p25 = newstr(1)
+ strsetitem(p25, 0, i23)
+ p28 = call(ConstClass(strip_spaces), p25, descr=<GcPtrCallDescr>)
+ guard_no_exception(descr=...)
+ i29 = strlen(p28)
+ i30 = int_is_true(i29)
+ guard_true(i30, descr=...)
+ i32 = int_sub(i29, 1)
+ i33 = strgetitem(p28, i32)
+ i35 = int_eq(i33, 108)
+ guard_false(i35, descr=...)
+ i37 = int_eq(i33, 76)
+ guard_false(i37, descr=...)
+ i39 = strgetitem(p28, 0)
+ i41 = int_eq(i39, 45)
+ guard_false(i41, descr=...)
+ i43 = int_eq(i39, 43)
+ guard_false(i43, descr=...)
+ i43 = call(ConstClass(ll_startswith__rpy_stringPtr_rpy_stringPtr), p28, ConstPtr(ptr42), descr=<BoolCallDescr>)
+ guard_false(i43, descr=...)
+ i46 = call(ConstClass(ll_startswith__rpy_stringPtr_rpy_stringPtr), p28, ConstPtr(ptr45), descr=<BoolCallDescr>)
+ guard_false(i46, descr=...)
+ p51 = new_with_vtable(21136408)
+ setfield_gc(p51, p28, descr=<GcPtrFieldDescr .*NumberStringParser.inst_literal .*>)
+ setfield_gc(p51, ConstPtr(ptr51), descr=<GcPtrFieldDescr pypy.objspace.std.strutil.NumberStringParser.inst_fname .*>)
+ setfield_gc(p51, 1, descr=<SignedFieldDescr .*NumberStringParser.inst_sign .*>)
+ setfield_gc(p51, 16, descr=<SignedFieldDescr .*NumberStringParser.inst_base .*>)
+ setfield_gc(p51, p28, descr=<GcPtrFieldDescr .*NumberStringParser.inst_s .*>)
+ setfield_gc(p51, i29, descr=<SignedFieldDescr .*NumberStringParser.inst_n .*>)
+ p55 = call(ConstClass(parse_digit_string), p51, descr=<GcPtrCallDescr>)
+ guard_no_exception(descr=...)
+ i57 = call(ConstClass(rbigint.toint), p55, descr=<SignedCallDescr>)
+ guard_no_exception(descr=...)
+ i58 = int_add_ovf(i6, i57)
+ guard_no_overflow(descr=...)
+ --TICK--
+ jump(p0, p1, p2, p3, p4, p5, i58, i7, i8, p9, p10, descr=<Loop4>)
""")
\ No newline at end of file
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
@@ -486,6 +486,11 @@
return True
+ def ll_startswith_char(s, ch):
+ if not len(s.chars):
+ return False
+ return s.chars[0] == ch
+
@elidable
def ll_endswith(s1, s2):
len1 = len(s1.chars)
@@ -503,6 +508,11 @@
return True
+ def ll_endswith_char(s, ch):
+ if not len(s.chars):
+ return False
+ return s.chars[len(s.chars) - 1] == ch
+
@elidable
def ll_find_char(s, ch, start, end):
i = start
diff --git a/pypy/rpython/ootypesystem/ootype.py b/pypy/rpython/ootypesystem/ootype.py
--- a/pypy/rpython/ootypesystem/ootype.py
+++ b/pypy/rpython/ootypesystem/ootype.py
@@ -433,7 +433,9 @@
"ll_streq": Meth([self.SELFTYPE_T], Bool),
"ll_strcmp": Meth([self.SELFTYPE_T], Signed),
"ll_startswith": Meth([self.SELFTYPE_T], Bool),
+ "ll_startswith_char": Meth([self.CHAR], Bool),
"ll_endswith": Meth([self.SELFTYPE_T], Bool),
+ "ll_endswith_char": Meth([self.CHAR], Bool),
"ll_find": Meth([self.SELFTYPE_T, Signed, Signed], Signed),
"ll_rfind": Meth([self.SELFTYPE_T, Signed, Signed], Signed),
"ll_count": Meth([self.SELFTYPE_T, Signed, Signed], Signed),
@@ -1429,10 +1431,18 @@
# NOT_RPYTHON
return self._str.startswith(s._str)
+ def ll_startswith_char(self, s):
+ # NOT_RPYTHON
+ return self._str.startswith(s)
+
def ll_endswith(self, s):
# NOT_RPYTHON
return self._str.endswith(s._str)
+ def ll_endswith_char(self, s):
+ # NOT_RPYTHON
+ return self._str.endswith(s)
+
def ll_find(self, s, start, end):
# NOT_RPYTHON
if start > len(self._str): # workaround to cope with corner case
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -81,16 +81,30 @@
return super(AbstractStringRepr, self).rtype_is_true(hop)
def rtype_method_startswith(self, hop):
- str1_repr, str2_repr = self._str_reprs(hop)
- v_str, v_value = hop.inputargs(str1_repr, str2_repr)
+ str1_repr = hop.args_r[0].repr
+ str2_repr = hop.args_r[1]
+ v_str = hop.inputarg(str1_repr, arg=0)
+ if str2_repr == str2_repr.char_repr:
+ v_value = hop.inputarg(str2_repr.char_repr, arg=1)
+ fn = self.ll.ll_startswith_char
+ else:
+ v_value = hop.inputarg(str2_repr, arg=1)
+ fn = self.ll.ll_startswith
hop.exception_cannot_occur()
- return hop.gendirectcall(self.ll.ll_startswith, v_str, v_value)
+ return hop.gendirectcall(fn, v_str, v_value)
def rtype_method_endswith(self, hop):
- str1_repr, str2_repr = self._str_reprs(hop)
- v_str, v_value = hop.inputargs(str1_repr, str2_repr)
+ str1_repr = hop.args_r[0].repr
+ str2_repr = hop.args_r[1]
+ v_str = hop.inputarg(str1_repr, arg=0)
+ if str2_repr == str2_repr.char_repr:
+ v_value = hop.inputarg(str2_repr.char_repr, arg=1)
+ fn = self.ll.ll_endswith_char
+ else:
+ v_value = hop.inputarg(str2_repr, arg=1)
+ fn = self.ll.ll_endswith
hop.exception_cannot_occur()
- return hop.gendirectcall(self.ll.ll_endswith, v_str, v_value)
+ return hop.gendirectcall(fn, v_str, v_value)
def rtype_method_find(self, hop, reverse=False):
# XXX binaryop
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
@@ -227,6 +227,15 @@
res = self.interpret(fn, [i,j])
assert res is fn(i, j)
+ def test_startswith_char(self):
+ const = self.const
+ def fn(i):
+ s = [const(''), const('one'), const('two'), const('o'), const('on'), const('ne'), const('e'), const('twos'), const('foobar'), const('fortytwo')]
+ return s[i].startswith('o')
+ for i in range(10):
+ res = self.interpret(fn, [i])
+ assert res == fn(i)
+
def test_endswith(self):
const = self.const
def fn(i, j):
@@ -238,6 +247,15 @@
res = self.interpret(fn, [i,j])
assert res is fn(i, j)
+ def test_endswith_char(self):
+ const = self.const
+ def fn(i):
+ s = [const(''), const('one'), const('two'), const('o'), const('on'), const('ne'), const('e'), const('twos'), const('foobar'), const('fortytwo')]
+ return s[i].endswith('e')
+ for i in range(10):
+ res = self.interpret(fn, [i])
+ assert res == fn(i)
+
def test_find(self):
const = self.const
def fn(i, j):
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -688,28 +688,54 @@
def getothernodes(self):
return self.othernodes[:]
+ def getbasecfilefornode(self, node, basecname):
+ # For FuncNode instances, use the python source filename (relative to
+ # the top directory):
+ if hasattr(node.obj, 'graph'):
+ g = node.obj.graph
+ # Lookup the filename from the function.
+ # However, not all FunctionGraph objs actually have a "func":
+ if hasattr(g, 'func'):
+ if g.filename.endswith('.py'):
+ localpath = py.path.local(g.filename)
+ pypkgpath = localpath.pypkgpath()
+ if pypkgpath:
+ relpypath = localpath.relto(pypkgpath)
+ return relpypath.replace('.py', '.c')
+ return basecname
+
def splitnodesimpl(self, basecname, nodes, nextra, nbetween,
split_criteria=SPLIT_CRITERIA):
+ # Gather nodes by some criteria:
+ nodes_by_base_cfile = {}
+ for node in nodes:
+ c_filename = self.getbasecfilefornode(node, basecname)
+ if c_filename in nodes_by_base_cfile:
+ nodes_by_base_cfile[c_filename].append(node)
+ else:
+ nodes_by_base_cfile[c_filename] = [node]
+
# produce a sequence of nodes, grouped into files
# which have no more than SPLIT_CRITERIA lines
- iternodes = iter(nodes)
- done = [False]
- def subiter():
- used = nextra
- for node in iternodes:
- impl = '\n'.join(list(node.implementation())).split('\n')
- if not impl:
- continue
- cost = len(impl) + nbetween
- yield node, impl
- del impl
- if used + cost > split_criteria:
- # split if criteria met, unless we would produce nothing.
- raise StopIteration
- used += cost
- done[0] = True
- while not done[0]:
- yield self.uniquecname(basecname), subiter()
+ for basecname in nodes_by_base_cfile:
+ iternodes = iter(nodes_by_base_cfile[basecname])
+ done = [False]
+ def subiter():
+ used = nextra
+ for node in iternodes:
+ impl = '\n'.join(list(node.implementation())).split('\n')
+ if not impl:
+ continue
+ cost = len(impl) + nbetween
+ yield node, impl
+ del impl
+ if used + cost > split_criteria:
+ # split if criteria met, unless we would produce nothing.
+ raise StopIteration
+ used += cost
+ done[0] = True
+ while not done[0]:
+ yield self.uniquecname(basecname), subiter()
def gen_readable_parts_of_source(self, f):
split_criteria_big = SPLIT_CRITERIA
diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py
--- a/pypy/translator/c/test/test_standalone.py
+++ b/pypy/translator/c/test/test_standalone.py
@@ -55,6 +55,13 @@
data = cbuilder.cmdexec('hi there')
assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''')
+ # Verify that the generated C files have sane names:
+ gen_c_files = [str(f) for f in cbuilder.extrafiles]
+ for expfile in ('rlib_rposix.c',
+ 'rpython_lltypesystem_rstr.c',
+ 'translator_c_test_test_standalone.c'):
+ assert cbuilder.targetdir.join(expfile) in gen_c_files
+
def test_print(self):
def entry_point(argv):
print "hello simpler world"
More information about the pypy-commit
mailing list