Author: Maciej Fijalkowski <[email protected]>
Branch:
Changeset: r73987:d1bd6dc1f32f
Date: 2014-10-17 09:13 +0200
http://bitbucket.org/pypy/pypy/changeset/d1bd6dc1f32f/
Log: merge
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -249,10 +249,6 @@
assert s_value.contains(s_old)
arg.annotation = s_value
- def transfer_binding(self, v_target, v_source):
- assert v_source.annotation is not None
- v_target.annotation = v_source.annotation
-
def warning(self, msg, pos=None):
if pos is None:
try:
@@ -579,7 +575,7 @@
for arg in op.args:
if isinstance(self.annotation(arg), annmodel.SomeImpossibleValue):
raise BlockedInference(self, op, -1)
- resultcell = op.consider(self, *op.args)
+ resultcell = op.consider(self)
if resultcell is None:
resultcell = annmodel.s_ImpossibleValue
elif resultcell == annmodel.s_ImpossibleValue:
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -559,10 +559,6 @@
assert self.annotator.binding(op.args[pos]) == s_type
return op
- def ondegenerated(self, what, s_value, where=None, called_from_graph=None):
- self.annotator.ondegenerated(what, s_value, where=where,
- called_from_graph=called_from_graph)
-
def whereami(self):
return self.annotator.whereami(self.position_key)
diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py
--- a/rpython/annotator/description.py
+++ b/rpython/annotator/description.py
@@ -14,7 +14,6 @@
objects, where the equivalence relation is the transitive closure of
'd1~d2 if d1 and d2 might be called at the same call site'.
"""
- overridden = False
normalized = False
modified = True
@@ -175,7 +174,6 @@
class FunctionDesc(Desc):
knowntype = types.FunctionType
- overridden = False
def __init__(self, bookkeeper, pyobj=None,
name=None, signature=None, defaults=None,
diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py
--- a/rpython/flowspace/operation.py
+++ b/rpython/flowspace/operation.py
@@ -96,10 +96,10 @@
def constfold(self):
return None
- def consider(self, annotator, *args):
- args_s = [annotator.annotation(arg) for arg in args]
+ def consider(self, annotator):
+ args_s = [annotator.annotation(arg) for arg in self.args]
spec = type(self).get_specialization(*args_s)
- return spec(annotator, *args)
+ return spec(annotator, *self.args)
def get_can_only_throw(self, annotator):
return None
@@ -447,7 +447,7 @@
opname = 'newdict'
canraise = []
- def consider(self, annotator, *args):
+ def consider(self, annotator):
return annotator.bookkeeper.newdict()
@@ -456,16 +456,17 @@
pyfunc = staticmethod(lambda *args: args)
canraise = []
- def consider(self, annotator, *args):
- return SomeTuple(items=[annotator.annotation(arg) for arg in args])
+ def consider(self, annotator):
+ return SomeTuple(items=[annotator.annotation(arg) for arg in
self.args])
class NewList(HLOperation):
opname = 'newlist'
canraise = []
- def consider(self, annotator, *args):
- return annotator.bookkeeper.newlist(*[annotator.annotation(arg) for
arg in args])
+ def consider(self, annotator):
+ return annotator.bookkeeper.newlist(
+ *[annotator.annotation(arg) for arg in self.args])
class Pow(PureOperation):
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -44,6 +44,25 @@
MASK = int((1 << SHIFT) - 1)
FLOAT_MULTIPLIER = float(1 << SHIFT)
+# For BIGINT and INT mix.
+#
+# The VALID range of an int is different than a valid range of a bigint of
length one.
+# -1 << LONG_BIT is actually TWO digits, because they are stored without the
sign.
+if SHIFT == LONG_BIT - 1:
+ MIN_INT_VALUE = -1 << SHIFT
+ def int_in_valid_range(x):
+ if x == MIN_INT_VALUE:
+ return False
+ return True
+else:
+ # Means we don't have INT128 on 64bit.
+ def int_in_valid_range(x):
+ if x > MASK or x < -MASK:
+ return False
+ return True
+
+int_in_valid_range._always_inline_ = True
+
# Debugging digit array access.
#
# False == no checking at all
@@ -71,7 +90,6 @@
FIVEARY_CUTOFF = 8
-
def _mask_digit(x):
return UDIGIT_MASK(x & MASK)
_mask_digit._annspecialcase_ = 'specialize:argtype(0)'
@@ -384,12 +402,17 @@
digits = ''.join([digits[i] for i in range(length-1, -1, -1)])
return digits
- @jit.elidable
def toint(self):
"""
Get an integer from a bigint object.
Raises OverflowError if overflow occurs.
"""
+ if self.numdigits() > MAX_DIGITS_THAT_CAN_FIT_IN_INT:
+ raise OverflowError
+ return self._toint_helper()
+
+ @jit.elidable
+ def _toint_helper(self):
x = self._touint_helper()
# Haven't lost any bits, but if the sign bit is set we're in
# trouble *unless* this is the min negative number. So,
@@ -422,8 +445,7 @@
prev = x
x = (x << SHIFT) + self.udigit(i)
if (x >> SHIFT) != prev:
- raise OverflowError(
- "long int too large to convert to unsigned int (%d,
%d)" % (x >> SHIFT, prev))
+ raise OverflowError("long int too large to convert to unsigned
int")
i -= 1
return x
@@ -482,10 +504,27 @@
i += 1
return True
+ @jit.elidable
+ def int_eq(self, other):
+ """ eq with int """
+
+ if not int_in_valid_range(other):
+ # Fallback to Long.
+ return self.eq(rbigint.fromint(other))
+
+ if self.numdigits() > 1:
+ return False
+
+ return (self.sign * self.digit(0)) == other
+
@jit.look_inside
def ne(self, other):
return not self.eq(other)
+ @jit.look_inside
+ def int_ne(self, other):
+ return not self.int_eq(other)
+
@jit.elidable
def lt(self, other):
if self.sign > other.sign:
@@ -521,18 +560,67 @@
i -= 1
return False
+ @jit.elidable
+ def int_lt(self, other):
+ """ lt where other is an int """
+
+ if not int_in_valid_range(other):
+ # Fallback to Long.
+ return self.lt(rbigint.fromint(other))
+
+ osign = 1
+ if other == 0:
+ osign = 0
+ elif other < 0:
+ osign = -1
+
+ if self.sign > osign:
+ return False
+ elif self.sign < osign:
+ return True
+
+ digits = self.numdigits()
+
+ if digits > 1:
+ if osign == 1:
+ return False
+ else:
+ return True
+
+ d1 = self.sign * self.digit(0)
+ if d1 < other:
+ return True
+ return False
+
@jit.look_inside
def le(self, other):
return not other.lt(self)
@jit.look_inside
+ def int_le(self, other):
+ # Alternative that might be faster, reimplant this. as a check with
other + 1. But we got to check for overflow
+ # or reduce valid range.
+
+ if self.int_eq(other):
+ return True
+ return self.int_lt(other)
+
+ @jit.look_inside
def gt(self, other):
return other.lt(self)
@jit.look_inside
+ def int_gt(self, other):
+ return not self.int_le(other)
+
+ @jit.look_inside
def ge(self, other):
return not self.lt(other)
+ @jit.look_inside
+ def int_ge(self, other):
+ return not self.int_lt(other)
+
@jit.elidable
def hash(self):
return _hash(self)
@@ -551,12 +639,31 @@
return result
@jit.elidable
+ def int_add(self, other):
+ if not int_in_valid_range(other):
+ # Fallback to long.
+ return self.add(rbigint.fromint(other))
+ elif self.sign == 0:
+ return rbigint.fromint(other)
+ elif other == 0:
+ return self
+
+ sign = -1 if other < 0 else 1
+ if self.sign == sign:
+ result = _x_int_add(self, other)
+ else:
+ result = _x_int_sub(self, other)
+ result.sign *= -1
+ result.sign *= sign
+ return result
+
+ @jit.elidable
def sub(self, other):
if other.sign == 0:
return self
- if self.sign == 0:
+ elif self.sign == 0:
return rbigint(other._digits[:other.size], -other.sign, other.size)
- if self.sign == other.sign:
+ elif self.sign == other.sign:
result = _x_sub(self, other)
else:
result = _x_add(self, other)
@@ -564,6 +671,22 @@
return result
@jit.elidable
+ def int_sub(self, other):
+ if not int_in_valid_range(other):
+ # Fallback to long.
+ return self.sub(rbigint.fromint(other))
+ elif other == 0:
+ return self
+ elif self.sign == 0:
+ return rbigint.fromint(-other)
+ elif self.sign == (-1 if other < 0 else 1):
+ result = _x_int_sub(self, other)
+ else:
+ result = _x_int_add(self, other)
+ result.sign *= self.sign
+ return result
+
+ @jit.elidable
def mul(self, b):
asize = self.numdigits()
bsize = b.numdigits()
@@ -609,6 +732,37 @@
return result
@jit.elidable
+ def int_mul(self, b):
+ if not int_in_valid_range(b):
+ # Fallback to long.
+ return self.mul(rbigint.fromint(b))
+
+ if self.sign == 0 or b == 0:
+ return NULLRBIGINT
+
+ asize = self.numdigits()
+ digit = abs(b)
+ bsign = -1 if b < 0 else 1
+
+ if digit == 1:
+ return rbigint(self._digits[:self.size], self.sign * bsign, asize)
+ elif asize == 1:
+ res = self.widedigit(0) * digit
+ carry = res >> SHIFT
+ if carry:
+ return rbigint([_store_digit(res & MASK),
_store_digit(carry)], self.sign * bsign, 2)
+ else:
+ return rbigint([_store_digit(res & MASK)], self.sign * bsign,
1)
+
+ elif digit & (digit - 1) == 0:
+ result = self.lqshift(ptwotable[digit])
+ else:
+ result = _muladd1(self, digit)
+
+ result.sign = self.sign * bsign
+ return result
+
+ @jit.elidable
def truediv(self, other):
div = _bigint_true_divide(self, other)
return div
@@ -626,7 +780,7 @@
if mod.sign * other.sign == -1:
if div.sign == 0:
return ONENEGATIVERBIGINT
- div = div.sub(ONERBIGINT)
+ div = div.int_sub(1)
return div
@@ -649,7 +803,7 @@
return ONENEGATIVERBIGINT if other.sign == -1 else
ONERBIGINT
return NULLRBIGINT
elif digit & (digit - 1) == 0:
- mod = self.and_(rbigint([_store_digit(digit - 1)], 1, 1))
+ mod = self.int_and_(digit - 1)
else:
# Perform
size = self.numdigits() - 1
@@ -672,6 +826,48 @@
return mod
@jit.elidable
+ def int_mod(self, other):
+ if self.sign == 0:
+ return NULLRBIGINT
+
+ elif not int_in_valid_range(other):
+ # Fallback to long.
+ return self.mod(rbigint.fromint(other))
+
+ elif other != 0:
+ digit = abs(other)
+ if digit == 1:
+ return NULLRBIGINT
+ elif digit == 2:
+ modm = self.digit(0) & 1
+ if modm:
+ return ONENEGATIVERBIGINT if other < 0 else ONERBIGINT
+ return NULLRBIGINT
+ elif digit & (digit - 1) == 0:
+ mod = self.int_and_(digit - 1)
+ else:
+ # Perform
+ size = self.numdigits() - 1
+ if size > 0:
+ rem = self.widedigit(size)
+ size -= 1
+ while size >= 0:
+ rem = ((rem << SHIFT) + self.widedigit(size)) % digit
+ size -= 1
+ else:
+ rem = self.digit(0) % digit
+
+ if rem == 0:
+ return NULLRBIGINT
+ mod = rbigint([_store_digit(rem)], -1 if self.sign < 0 else 1,
1)
+ else:
+ raise ZeroDivisionError("long division or modulo by zero")
+
+ if mod.sign * (-1 if other < 0 else 1) == -1:
+ mod = mod.int_add(other)
+ return mod
+
+ @jit.elidable
def divmod(v, w):
"""
The / and % operators are now defined in terms of divmod().
@@ -694,7 +890,7 @@
mod = mod.add(w)
if div.sign == 0:
return ONENEGATIVERBIGINT, mod
- div = div.sub(ONERBIGINT)
+ div = div.int_sub(1)
return div, mod
@jit.elidable
@@ -852,7 +1048,7 @@
if self.sign == 0:
return ONENEGATIVERBIGINT
- ret = self.add(ONERBIGINT)
+ ret = self.int_add(1)
ret.sign = -ret.sign
return ret
@@ -997,14 +1193,26 @@
return _bitwise(self, '&', other)
@jit.elidable
+ def int_and_(self, other):
+ return _int_bitwise(self, '&', other)
+
+ @jit.elidable
def xor(self, other):
return _bitwise(self, '^', other)
@jit.elidable
+ def int_xor(self, other):
+ return _int_bitwise(self, '^', other)
+
+ @jit.elidable
def or_(self, other):
return _bitwise(self, '|', other)
@jit.elidable
+ def int_or_(self, other):
+ return _int_bitwise(self, '|', other)
+
+ @jit.elidable
def oct(self):
if self.sign == 0:
return '0L'
@@ -1084,6 +1292,11 @@
(2 * SHIFT) % 5,
(1 * SHIFT) % 5]
+
+# if the bigint has more digits than this, it cannot fit into an int
+MAX_DIGITS_THAT_CAN_FIT_IN_INT = rbigint.fromint(-sys.maxint - 1).numdigits()
+
+
#_________________________________________________________________
# Helper Functions
@@ -1182,6 +1395,25 @@
z._normalize()
return z
+def _x_int_add(a, b):
+ """ Add the absolute values of one bigint and one integer. """
+ size_a = a.numdigits()
+
+ z = rbigint([NULLDIGIT] * (size_a + 1), 1)
+ i = UDIGIT_TYPE(1)
+ carry = a.udigit(0) + abs(b)
+ z.setdigit(0, carry)
+ carry >>= SHIFT
+
+ while i < size_a:
+ carry += a.udigit(i)
+ z.setdigit(i, carry)
+ carry >>= SHIFT
+ i += 1
+ z.setdigit(i, carry)
+ z._normalize()
+ return z
+
def _x_sub(a, b):
""" Subtract the absolute values of two integers. """
@@ -1228,6 +1460,42 @@
z._normalize()
return z
+def _x_int_sub(a, b):
+ """ Subtract the absolute values of two integers. """
+
+ size_a = a.numdigits()
+
+ bdigit = abs(b)
+
+ if size_a == 1:
+ # Find highest digit where a and b differ:
+ adigit = a.digit(0)
+
+ if adigit == bdigit:
+ return NULLRBIGINT
+
+ return rbigint.fromint(adigit - bdigit)
+
+ z = rbigint([NULLDIGIT] * size_a, 1, size_a)
+ i = _load_unsigned_digit(1)
+ # The following assumes unsigned arithmetic
+ # works modulo 2**N for some N>SHIFT.
+ borrow = a.udigit(0) - bdigit
+ z.setdigit(0, borrow)
+ borrow >>= SHIFT
+ #borrow &= 1 # Keep only one sign bit
+
+ while i < size_a:
+ borrow = a.udigit(i) - borrow
+ z.setdigit(i, borrow)
+ borrow >>= SHIFT
+ #borrow &= 1
+ i += 1
+
+ assert borrow == 0
+ z._normalize()
+ return z
+
# A neat little table of power of twos.
ptwotable = {}
for x in range(SHIFT-1):
@@ -2335,6 +2603,89 @@
return z.invert()
_bitwise._annspecialcase_ = "specialize:arg(1)"
+def _int_bitwise(a, op, b): # '&', '|', '^'
+ """ Bitwise and/or/xor operations """
+
+ if not int_in_valid_range(b):
+ # Fallback to long.
+ return _bitwise(a, op, rbigint.fromint(b))
+
+ if a.sign < 0:
+ a = a.invert()
+ maska = MASK
+ else:
+ maska = 0
+ if b < 0:
+ b = ~b
+ maskb = MASK
+ else:
+ maskb = 0
+
+ negz = 0
+ if op == '^':
+ if maska != maskb:
+ maska ^= MASK
+ negz = -1
+ elif op == '&':
+ if maska and maskb:
+ op = '|'
+ maska ^= MASK
+ maskb ^= MASK
+ negz = -1
+ elif op == '|':
+ if maska or maskb:
+ op = '&'
+ maska ^= MASK
+ maskb ^= MASK
+ negz = -1
+
+ # JRH: The original logic here was to allocate the result value (z)
+ # as the longer of the two operands. However, there are some cases
+ # where the result is guaranteed to be shorter than that: AND of two
+ # positives, OR of two negatives: use the shorter number. AND with
+ # mixed signs: use the positive number. OR with mixed signs: use the
+ # negative number. After the transformations above, op will be '&'
+ # iff one of these cases applies, and mask will be non-0 for operands
+ # whose length should be ignored.
+
+ size_a = a.numdigits()
+ if op == '&':
+ if maska:
+ size_z = 1
+ else:
+ if maskb:
+ size_z = size_a
+ else:
+ size_z = 1
+ else:
+ size_z = size_a
+
+ z = rbigint([NULLDIGIT] * size_z, 1, size_z)
+ i = 0
+ while i < size_z:
+ if i < size_a:
+ diga = a.digit(i) ^ maska
+ else:
+ diga = maska
+ if i == 0:
+ digb = b ^ maskb
+ else:
+ digb = maskb
+
+ if op == '&':
+ z.setdigit(i, diga & digb)
+ elif op == '|':
+ z.setdigit(i, diga | digb)
+ elif op == '^':
+ z.setdigit(i, diga ^ digb)
+ i += 1
+
+ z._normalize()
+ if negz == 0:
+ return z
+
+ return z.invert()
+_int_bitwise._annspecialcase_ = "specialize:arg(1)"
ULONGLONG_BOUND = r_ulonglong(1L << (r_longlong.BITS-1))
LONGLONG_MIN = r_longlong(-(1L << (r_longlong.BITS-1)))
diff --git a/rpython/rlib/test/test_rbigint.py
b/rpython/rlib/test/test_rbigint.py
--- a/rpython/rlib/test/test_rbigint.py
+++ b/rpython/rlib/test/test_rbigint.py
@@ -2,7 +2,8 @@
import operator
import sys
-from random import random, randint, sample
+import math
+from random import random, randint, sample, seed
import py
@@ -14,6 +15,14 @@
from rpython.rtyper.test.test_llinterp import interpret
from rpython.translator.c.test.test_standalone import StandaloneTests
+long_vals_not_too_big = range(17) + [
+ 37, 50,
+ 127, 128, 129, 511, 512, 513, sys.maxint, sys.maxint + 1,
+ 123456789123456789000000L,
+ ]
+
+long_vals = long_vals_not_too_big + [
+ 1 << 100, 3 ** 10000]
class TestRLong(object):
def test_simple(self):
@@ -43,19 +52,23 @@
assert r2.str() == str(-n)
def test_floordiv(self):
- for op1 in [-12, -2, -1, 1, 2, 50]:
- for op2 in [-4, -2, -1, 1, 2, 8]:
- rl_op1 = rbigint.fromint(op1)
- rl_op2 = rbigint.fromint(op2)
+ for op1 in gen_signs(long_vals):
+ for op2 in gen_signs(long_vals):
+ if not op2:
+ continue
+ rl_op1 = rbigint.fromlong(op1)
+ rl_op2 = rbigint.fromlong(op2)
r1 = rl_op1.floordiv(rl_op2)
r2 = op1 // op2
assert r1.tolong() == r2
def test_truediv(self):
- for op1 in [-12, -2, -1, 1, 2, 50]:
- for op2 in [-4, -2, -1, 1, 2, 8]:
- rl_op1 = rbigint.fromint(op1)
- rl_op2 = rbigint.fromint(op2)
+ for op1 in gen_signs(long_vals_not_too_big):
+ for op2 in gen_signs(long_vals):
+ if not op2:
+ continue
+ rl_op1 = rbigint.fromlong(op1)
+ rl_op2 = rbigint.fromlong(op2)
r1 = rl_op1.truediv(rl_op2)
r2 = op1 / op2
assert r1 == r2
@@ -98,19 +111,29 @@
assert f == -1.7976931348623157e+308 # exactly
def test_mod(self):
- for op1 in [-50, -12, -2, -1, 1, 2, 50, 52]:
- for op2 in [-4, -2, -1, 1, 2, 8]:
- rl_op1 = rbigint.fromint(op1)
- rl_op2 = rbigint.fromint(op2)
+ for op1 in gen_signs(long_vals):
+ for op2 in gen_signs(long_vals):
+ if not op2:
+ continue
+ rl_op1 = rbigint.fromlong(op1)
+ rl_op2 = rbigint.fromlong(op2)
r1 = rl_op1.mod(rl_op2)
r2 = op1 % op2
print op1, op2
assert r1.tolong() == r2
+ def test_int_mod(self):
+ for x in gen_signs(long_vals):
+ for y in gen_signs([1, 2, 4, 8, 8888, sys.maxint, 2 ** 19, 2 ** 18
- 1]):
+ op1 = rbigint.fromlong(x)
+ r1 = op1.int_mod(y)
+ r2 = x % y
+ assert r1.tolong() == r2
+
def test_pow(self):
- for op1 in [-50, -12, -2, -1, 1, 2, 50, 52]:
+ for op1 in gen_signs(long_vals_not_too_big):
for op2 in [0, 1, 2, 8, 9, 10, 11]:
- rl_op1 = rbigint.fromint(op1)
+ rl_op1 = rbigint.fromlong(op1)
rl_op2 = rbigint.fromint(op2)
r1 = rl_op1.pow(rl_op2)
r2 = op1 ** op2
@@ -238,6 +261,13 @@
result = f1.add(f2)
assert result.tolong() == x * i + y * j
+ def test_int_add(self):
+ for x in gen_signs(long_vals):
+ for y in gen_signs([0, 1, 9999, sys.maxint, 2 ** 19, 2 ** 18 - 1]):
+ f1 = rbigint.fromlong(x)
+ result = f1.int_add(y)
+ assert result.tolong() == x + y
+
def test_sub(self):
x = 12378959520302182384345L
y = 88961284756491823819191823L
@@ -248,20 +278,34 @@
result = f1.sub(f2)
assert result.tolong() == x * i - y * j
+ def test_int_sub(self):
+ for x in gen_signs([0, 123456789123456789000000L, 1 << 100, 3 **
10000]):
+ for y in gen_signs([0, 1, 8888, sys.maxint, 2 ** 19, 2 ** 18 - 1]):
+ f1 = rbigint.fromlong(x)
+ result = f1.int_sub(y)
+ assert result.tolong() == x - y
+
def test_subzz(self):
w_l0 = rbigint.fromint(0)
assert w_l0.sub(w_l0).tolong() == 0
def test_mul(self):
- x = -1238585838347L
- y = 585839391919233L
- f1 = rbigint.fromlong(x)
- f2 = rbigint.fromlong(y)
- result = f1.mul(f2)
- assert result.tolong() == x * y
- # also test a * a, it has special code
- result = f1.mul(f1)
- assert result.tolong() == x * x
+ for x in gen_signs(long_vals):
+ f1 = rbigint.fromlong(x)
+ for y in gen_signs(long_vals_not_too_big):
+ f2 = rbigint.fromlong(y)
+ result = f1.mul(f2)
+ assert result.tolong() == x * y
+ # there's a special case for a is b
+ result = f1.mul(f1)
+ assert result.tolong() == x * x
+
+ def test_int_mul(self):
+ for x in gen_signs([39, 128, 111111111, 123456789123456789000000L, 1
<< 100, 3 ** 10000]):
+ for y in gen_signs([0, 1, 8888, sys.maxint, 2 ** 19, 2 ** 18 - 1]):
+ f1 = rbigint.fromlong(x)
+ result = f1.int_mul(y)
+ assert result.tolong() == x * y
def test_tofloat(self):
x = 12345678901234567890L ** 10
@@ -309,6 +353,9 @@
f1 = rbigint.fromfloat(9007199254740991.0)
assert f1.tolong() == 9007199254740991
+ null = rbigint.fromfloat(-0.0)
+ assert null.int_eq(0)
+
def test_eq(self):
x = 5858393919192332223L
y = 585839391919233111223311112332L
@@ -336,6 +383,17 @@
f2 = rbigint.fromlong(y)
assert (x < y) == f1.lt(f2)
+ def test_int_comparison(self):
+ for x in gen_signs(long_vals):
+ for y in gen_signs([0, 1, 0x11111111, 0x11111112, 8888,
sys.maxint, 2 ** 19, 2 ** 18 - 1]):
+ f1 = rbigint.fromlong(x)
+ assert (x < y) == f1.int_lt(y)
+ assert (x <= y) == f1.int_le(y)
+ assert (x > y) == f1.int_gt(y)
+ assert (x >= y) == f1.int_ge(y)
+ assert (x == y) == f1.int_eq(y)
+ assert (x != y) == f1.int_ne(y)
+
def test_order(self):
f6 = rbigint.fromint(6)
f7 = rbigint.fromint(7)
@@ -344,6 +402,14 @@
assert (f6.gt(f6), f6.gt(f7), f7.gt(f6)) == (0,0,1)
assert (f6.ge(f6), f6.ge(f7), f7.ge(f6)) == (1,0,1)
+ def test_int_order(self):
+ f6 = rbigint.fromint(6)
+ f7 = rbigint.fromint(7)
+ assert (f6.int_lt(6), f6.int_lt(7), f7.int_lt(6)) == (0,1,0)
+ assert (f6.int_le(6), f6.int_le(7), f7.int_le(6)) == (1,1,0)
+ assert (f6.int_gt(6), f6.int_gt(7), f7.int_gt(6)) == (0,0,1)
+ assert (f6.int_ge(6), f6.int_ge(7), f7.int_ge(6)) == (1,0,1)
+
def test_int_conversion(self):
f1 = rbigint.fromlong(12332)
f2 = rbigint.fromint(12332)
@@ -389,7 +455,6 @@
def test_pow_lll(self):
- return
x = 10L
y = 2L
z = 13L
@@ -514,12 +579,21 @@
res2 = getattr(operator, mod)(x, y)
assert res1 == res2
+ def test_int_bitwise(self):
+ for x in gen_signs([0, 1, 5, 11, 42, 43, 2 ** 30]):
+ for y in gen_signs([0, 1, 5, 11, 42, 43, 3 ** 30, 2 ** 31]):
+ lx = rbigint.fromlong(x)
+ for mod in "xor and_ or_".split():
+ res1 = getattr(lx, 'int_' + mod)(y).tolong()
+ res2 = getattr(operator, mod)(x, y)
+ assert res1 == res2
+
def test_mul_eq_shift(self):
p2 = rbigint.fromlong(1).lshift(63)
f1 = rbigint.fromlong(0).lshift(63)
f2 = rbigint.fromlong(0).mul(p2)
assert f1.eq(f2)
-
+
def test_tostring(self):
z = rbigint.fromlong(0)
assert z.str() == '0'
@@ -534,6 +608,11 @@
assert x.format('.!') == (
'-!....!!..!!..!.!!.!......!...!...!!!........!')
assert x.format('abcdefghijkl', '<<', '>>') == '-<<cakdkgdijffjf>>'
+ x =
rbigint.fromlong(-18471379832321000000000000000000000000000000000000000000)
+ assert x.str() ==
'-18471379832321000000000000000000000000000000000000000000'
+ assert x.repr() ==
'-18471379832321000000000000000000000000000000000000000000L'
+ assert x.hex() == '-0xc0d9a6f41fbcf1718b618443d45516a051e40000000000L'
+ assert x.oct() ==
'-014033151572037571705614266060420752125055201217100000000000000L'
def test_format_caching(self):
big = rbigint.fromlong(2 ** 1000)
@@ -579,6 +658,18 @@
assert rbigint.fromlong(x).hash() == rbigint.fromlong(y).hash()
assert rbigint.fromlong(-x).hash() == rbigint.fromlong(-y).hash()
+ def test_log(self):
+ from rpython.rlib.rfloat import ulps_check
+ for op in long_vals:
+ if not op:
+ continue
+ for base in [0, 2, 4, 8, 16, 10, math.e]:
+ l = rbigint.fromlong(op).log(base)
+ if base:
+ assert ulps_check(l, math.log(op, base), 1) is None
+ else:
+ assert ulps_check(l, math.log(op), 1) is None
+
class TestInternalFunctions(object):
def test__inplace_divrem1(self):
# signs are not handled in the helpers!
@@ -834,6 +925,8 @@
assert s == bigint.tobytes(16, byteorder="big", signed=False)
py.test.raises(InvalidEndiannessError, bigint.frombytes, '\xFF', 'foo',
signed=True)
+ bigint = rbigint.frombytes('\x82', byteorder='big', signed=True)
+ assert bigint.tolong() == -126
def test_tobytes(self):
assert rbigint.fromint(0).tobytes(1, 'big', signed=True) == '\x00'
diff --git a/rpython/rtyper/normalizecalls.py b/rpython/rtyper/normalizecalls.py
--- a/rpython/rtyper/normalizecalls.py
+++ b/rpython/rtyper/normalizecalls.py
@@ -19,15 +19,6 @@
def normalize_calltable(annotator, callfamily):
"""Try to normalize all rows of a table."""
- overridden = False
- for desc in callfamily.descs:
- if getattr(desc, 'overridden', False):
- overridden = True
- if overridden:
- if len(callfamily.descs) > 1:
- raise Exception("non-static call to overridden function")
- callfamily.overridden = True
- return
nshapes = len(callfamily.calltables)
for shape, table in callfamily.calltables.items():
for row in table:
diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py
--- a/rpython/rtyper/rpbc.py
+++ b/rpython/rtyper/rpbc.py
@@ -29,12 +29,9 @@
sample = self.any_description()
callfamily = sample.querycallfamily()
if callfamily and callfamily.total_calltable_size > 0:
- if sample.overridden:
- getRepr = OverriddenFunctionPBCRepr
- else:
- getRepr = FunctionsPBCRepr
- if small_cand(rtyper, self):
- getRepr = SmallFunctionSetPBCRepr
+ getRepr = FunctionsPBCRepr
+ if small_cand(rtyper, self):
+ getRepr = SmallFunctionSetPBCRepr
else:
getRepr = getFrozenPBCRepr
elif issubclass(kind, description.ClassDesc):
@@ -338,16 +335,6 @@
return inputconst(lltype.Void, None)
return NotImplemented
-class OverriddenFunctionPBCRepr(Repr):
- def __init__(self, rtyper, s_pbc):
- self.rtyper = rtyper
- self.s_pbc = s_pbc
- assert len(s_pbc.descriptions) == 1
- self.lowleveltype = lltype.Void
-
- def rtype_simple_call(self, hop):
- from rpython.rtyper.rspecialcase import rtype_call_specialcase
- return rtype_call_specialcase(hop)
def getFrozenPBCRepr(rtyper, s_pbc):
from rpython.rtyper.lltypesystem.rpbc import (
@@ -863,7 +850,6 @@
r_class = self.r_im_self.rclass
mangled_name, r_func = r_class.clsfields[self.methodname]
assert isinstance(r_func, (FunctionsPBCRepr,
- OverriddenFunctionPBCRepr,
SmallFunctionSetPBCRepr))
# s_func = r_func.s_pbc -- not precise enough, see
# test_precise_method_call_1. Build a more precise one...
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit