Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r45479:ac574f367d2e Date: 2011-07-12 00:32 +0200 http://bitbucket.org/pypy/pypy/changeset/ac574f367d2e/
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" _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit