Author: Maciej Fijalkowski <fij...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit