Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: py3.6
Changeset: r97491:cedd17bf511f
Date: 2019-09-16 13:50 +0200
http://bitbucket.org/pypy/pypy/changeset/cedd17bf511f/

Log:    don't fold too huge left shift either

diff --git a/pypy/interpreter/astcompiler/optimize.py 
b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -142,6 +142,16 @@
     """)
     return space.pow(w_left, w_right, space.w_None)
 
+def _fold_lshift(space, w_left, w_right):
+    # don't constant-fold if "w_left" and "w_right" are integers and
+    # the estimated bit length of the result is unreasonably large
+    space.appexec([w_left, w_right], """(left, right):
+        if isinstance(left, int) and isinstance(right, int):
+            if left.bit_length() + right > 1000:
+                raise OverflowError
+    """)
+    return space.lshift(w_left, w_right)
+
 def _fold_not(space, operand):
     return space.newbool(not space.is_true(operand))
 
@@ -154,7 +164,7 @@
     ast.FloorDiv : _binary_fold("floordiv"),
     ast.Mod : _binary_fold("mod"),
     ast.Pow : _fold_pow,
-    ast.LShift : _binary_fold("lshift"),
+    ast.LShift : _fold_lshift,
     ast.RShift : _binary_fold("rshift"),
     ast.BitOr : _binary_fold("or_"),
     ast.BitXor : _binary_fold("xor"),
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
@@ -1474,13 +1474,14 @@
             assert ops.LOAD_CONST in counts
 
     def test_dont_fold_huge_powers(self):
-        for source in (
-            "2 ** 3000",         # not constant-folded: too big
-            "(-2) ** 3000",
+        for source, op in (
+                ("2 ** 3000", ops.BINARY_POWER),  # not constant-folded: too 
big
+                ("(-2) ** 3000", ops.BINARY_POWER),
+                ("5 << 1000", ops.BINARY_LSHIFT),
             ):
             source = 'def f(): %s' % source
             counts = self.count_instructions(source)
-            assert ops.BINARY_POWER in counts
+            assert op in counts
 
         for source in (
             "2 ** 2000",         # constant-folded
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to