Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: record-known-result
Changeset: r97697:0085d3e74e02
Date: 2019-10-01 15:51 +0200
http://bitbucket.org/pypy/pypy/changeset/0085d3e74e02/

Log:    tell the jit that the result of str.find is always smaller than the
        length of the string

diff --git a/rpython/jit/metainterp/test/test_string.py 
b/rpython/jit/metainterp/test/test_string.py
--- a/rpython/jit/metainterp/test/test_string.py
+++ b/rpython/jit/metainterp/test/test_string.py
@@ -990,7 +990,48 @@
             return len(d[s])
         assert self.interp_operations(f, [222]) == 6
 
-    def test_codepoint_index_at_byte_position_record_known_result(self):
+    def test_str_find(self):
+        jitdriver = JitDriver(greens=['x'], reds=['z', 'res'])
+        s1 = "aaaaaaef"
+        s2 = "aaaaaaaaaaaaaaaaaaaaeebbbbbbbbbbbbbbbbbbef"
+
+        @dont_look_inside
+        def pick(x):
+            if x > 0:
+                return s1
+            else:
+                return s2
+
+        @dont_look_inside
+        def pick_s(z):
+            if z < 5:
+                return "e"
+            return "ef"
+
+        def f(x):
+            z = 0
+            res = 0
+            while z < 10:
+                jitdriver.jit_merge_point(x=x, res=res, z=z)
+                s = pick(x)
+                # the following lines emulate unicode.find
+                byteindex = s.find(pick_s(x))
+                if byteindex < 0:
+                    return -1001
+                if byteindex >= len(s):  # no guard
+                    return -106
+                res += ord(s[byteindex])
+                z += 1
+            return res
+        res = self.meta_interp(f, [1], backendopt=True)
+        assert res == f(1)
+        self.check_simple_loop(guard_false=1)  # only one guard, to check for 
-1
+        res = self.meta_interp(f, [10], backendopt=True)
+        assert res == f(10)
+        # one guard to check whether the search string is len == 1, one to 
check for result -1
+        self.check_simple_loop(guard_false=2)
+
+    def 
test_codepoint_index_at_byte_position_record_known_result_and_invariants(self):
         from rpython.rlib import rutf8
         jitdriver = JitDriver(greens=['x'], reds=['z', 'res'])
         s1 = u"abce&#252;f".encode("utf-8")
diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -721,16 +721,22 @@
     def ll_find(s1, s2, start, end):
         if start < 0:
             start = 0
-        if end > len(s1.chars):
-            end = len(s1.chars)
+        n = len(s1.chars)
+        if end > n:
+            end = n
         if end - start < 0:
             return -1
 
         m = len(s2.chars)
         if m == 1:
-            return LLHelpers.ll_find_char(s1, s2.chars[0], start, end)
+            res = LLHelpers.ll_find_char(s1, s2.chars[0], start, end)
+            jit.record_exact_value(res < end, True)
+            return res
 
-        return LLHelpers.ll_search(s1, s2, start, end, FAST_FIND)
+        res = LLHelpers.ll_search(s1, s2, start, end, FAST_FIND)
+        jit.record_exact_value(res < end, True)
+        jit.record_exact_value(res + m <= n, True)
+        return res
 
     @staticmethod
     @signature(types.any(), types.any(), types.int(), types.int(), 
returns=types.int())
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to