Author: Armin Rigo <[email protected]>
Branch:
Changeset: r86041:5df38f3fbcc0
Date: 2016-08-05 20:27 +0200
http://bitbucket.org/pypy/pypy/changeset/5df38f3fbcc0/
Log: Another hack to avoid constant-folding "2 ** 12345678912"
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
@@ -108,8 +108,15 @@
return getattr(space, name)(operand)
return do_fold
-def _fold_pow(space, left, right):
- return space.pow(left, right, space.w_None)
+def _fold_pow(space, w_left, w_right):
+ # don't constant-fold if "w_left" and "w_right" are integers and
+ # the estimated bit length of the power is unreasonably large
+ space.appexec([w_left, w_right], """(left, right):
+ if isinstance(left, (int, long)) and isinstance(right, (int, long)):
+ if left.bit_length() * right > 5000:
+ raise OverflowError
+ """)
+ return space.pow(w_left, w_right, space.w_None)
def _fold_not(space, operand):
return space.wrap(not space.is_true(operand))
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
@@ -1156,3 +1156,22 @@
counts = self.count_instructions(source)
assert ops.BUILD_SET not in counts
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",
+ ):
+ source = 'def f(): %s' % source
+ counts = self.count_instructions(source)
+ assert ops.BINARY_POWER in counts
+
+ for source in (
+ "2 ** 2000", # constant-folded
+ "2 ** -3000",
+ "1.001 ** 3000",
+ "1 ** 3000.0",
+ ):
+ source = 'def f(): %s' % source
+ counts = self.count_instructions(source)
+ assert ops.BINARY_POWER not in counts
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit