Author: Alex Gaynor <alex.gay...@gmail.com> Branch: kill-faking Changeset: r59229:395e7928acb6 Date: 2012-12-02 12:18 -0800 http://bitbucket.org/pypy/pypy/changeset/395e7928acb6/
Log: Resolved merge conflicts diff --git a/lib-python/2.7/json/decoder.py b/lib-python/2.7/json/decoder.py --- a/lib-python/2.7/json/decoder.py +++ b/lib-python/2.7/json/decoder.py @@ -62,8 +62,7 @@ DEFAULT_ENCODING = "utf-8" -def py_scanstring(s, end, encoding=None, strict=True, - _b=BACKSLASH, _m=STRINGCHUNK.match): +def py_scanstring(s, end, encoding=None, strict=True): """Scan the string s for a JSON string. End is the index of the character in s after the quote that started the JSON string. Unescapes all valid JSON string escape sequences and raises ValueError @@ -78,7 +77,7 @@ _append = chunks.append begin = end - 1 while 1: - chunk = _m(s, end) + chunk = STRINGCHUNK.match(s, end) if chunk is None: raise ValueError( errmsg("Unterminated string starting at", s, begin)) @@ -109,7 +108,7 @@ # If not a unicode escape sequence, must be in the lookup table if esc != 'u': try: - char = _b[esc] + char = BACKSLASH[esc] except KeyError: msg = "Invalid \\escape: " + repr(esc) raise ValueError(errmsg(msg, s, end)) @@ -147,7 +146,7 @@ WHITESPACE_STR = ' \t\n\r' def JSONObject(s_and_end, encoding, strict, scan_once, object_hook, - object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + object_pairs_hook): s, end = s_and_end pairs = [] pairs_append = pairs.append @@ -156,8 +155,8 @@ nextchar = s[end:end + 1] # Normally we expect nextchar == '"' if nextchar != '"': - if nextchar in _ws: - end = _w(s, end).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end).end() nextchar = s[end:end + 1] # Trivial empty object if nextchar == '}': @@ -177,17 +176,17 @@ # To skip some function call overhead we optimize the fast paths where # the JSON key separator is ": " or just ":". if s[end:end + 1] != ':': - end = _w(s, end).end() + end = WHITESPACE.match(s, end).end() if s[end:end + 1] != ':': raise ValueError(errmsg("Expecting : delimiter", s, end)) end += 1 try: - if s[end] in _ws: + if s[end] in WHITESPACE_STR: end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() + if s[end] in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() except IndexError: pass @@ -199,8 +198,8 @@ try: nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' @@ -213,11 +212,11 @@ try: nextchar = s[end] - if nextchar in _ws: + if nextchar in WHITESPACE_STR: end += 1 nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' @@ -234,12 +233,12 @@ pairs = object_hook(pairs) return pairs, end -def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): +def JSONArray(s_and_end, scan_once): s, end = s_and_end values = [] nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end:end + 1] # Look-ahead for trivial empty array if nextchar == ']': @@ -252,8 +251,8 @@ raise ValueError(errmsg("Expecting object", s, end)) _append(value) nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end:end + 1] end += 1 if nextchar == ']': @@ -262,10 +261,10 @@ raise ValueError(errmsg("Expecting , delimiter", s, end)) try: - if s[end] in _ws: + if s[end] in WHITESPACE_STR: end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() + if s[end] in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() except IndexError: pass @@ -358,13 +357,13 @@ self.parse_string = scanstring self.scan_once = scanner.make_scanner(self) - def decode(self, s, _w=WHITESPACE.match): + def decode(self, s): """Return the Python representation of ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() + obj, end = self.raw_decode(s, idx=WHITESPACE.match(s, 0).end()) + end = WHITESPACE.match(s, end).end() if end != len(s): raise ValueError(errmsg("Extra data", s, end, len(s))) return obj diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -64,7 +64,6 @@ assert '_cfgimpl_values' in attrs # from self if sys.version_info >= (2, 6): assert 'gc' in attrs # custom attribute - assert 'objspace' in attrs # custom attribute # attrs = dir(config.gc) if sys.version_info >= (2, 6): @@ -262,14 +261,14 @@ config = Config(descr) assert config.getpaths() == ['gc.name', 'gc.dummy', 'gc.float', 'bool', - 'objspace', 'wantref', 'str', 'wantframework', + 'wantref', 'str', 'wantframework', 'int'] assert config.getpaths() == descr.getpaths() assert config.gc.getpaths() == ['name', 'dummy', 'float'] assert config.gc.getpaths() == descr.gc.getpaths() assert config.getpaths(include_groups=True) == [ 'gc', 'gc.name', 'gc.dummy', 'gc.float', - 'bool', 'objspace', 'wantref', 'str', 'wantframework', 'int'] + 'bool', 'wantref', 'str', 'wantframework', 'int'] assert config.getpaths(True) == descr.getpaths(True) def test_underscore_in_option_name(): diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -1,12 +1,16 @@ ====================== -What's new in PyPy xxx +What's new in PyPy 2.0 ====================== .. this is a revision shortly after release-2.0-beta1 .. startrev: 0e6161a009c6 +.. branch: length-hint +Implement __lenght_hint__ according to PEP 424 + +.. branches we don't care about .. branch: autoreds -XXX -.. branch: length-hint -XXX +.. branch: release-2.0-beta1 + +.. branch: remove-PYPY_NOT_MAIN_FILE diff --git a/pypy/jit/metainterp/heapcache.py b/pypy/jit/metainterp/heapcache.py --- a/pypy/jit/metainterp/heapcache.py +++ b/pypy/jit/metainterp/heapcache.py @@ -128,6 +128,18 @@ if frombox not in self.new_boxes: del cache[frombox] return + else: + # Only invalidate things that are either escaped or arguments + for descr, boxes in self.heap_cache.iteritems(): + for box in boxes.keys(): + if not self.is_unescaped(box) or box in argboxes: + del boxes[box] + for descr, indices in self.heap_array_cache.iteritems(): + for boxes in indices.itervalues(): + for box in boxes.keys(): + if not self.is_unescaped(box) or box in argboxes: + del boxes[box] + return self.heap_cache.clear() self.heap_array_cache.clear() diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py --- a/pypy/jit/metainterp/test/support.py +++ b/pypy/jit/metainterp/test/support.py @@ -10,6 +10,8 @@ from pypy.jit.codewriter.policy import JitPolicy from pypy.jit.codewriter import codewriter, longlong from pypy.rlib.rfloat import isnan +from pypy.translator.backendopt.all import backend_optimizations + def _get_jitcodes(testself, CPUClass, func, values, type_system, supports_longlong=False, translationoptions={}, **kwds): @@ -68,7 +70,9 @@ policy = JitPolicy() policy.set_supports_floats(True) policy.set_supports_longlong(supports_longlong) - cw.find_all_graphs(policy) + graphs = cw.find_all_graphs(policy) + if kwds.get("backendopt"): + backend_optimizations(rtyper.annotator.translator, graphs=graphs) # testself.warmrunnerstate = FakeWarmRunnerState() testself.warmrunnerstate.cpu = cpu diff --git a/pypy/jit/metainterp/test/test_heapcache.py b/pypy/jit/metainterp/test/test_heapcache.py --- a/pypy/jit/metainterp/test/test_heapcache.py +++ b/pypy/jit/metainterp/test/test_heapcache.py @@ -18,7 +18,7 @@ index2 = ConstInt(1) -class FakeEffektinfo(object): +class FakeEffectinfo(object): EF_ELIDABLE_CANNOT_RAISE = 0 #elidable function (and cannot raise) EF_LOOPINVARIANT = 1 #special: call it only once per loop EF_CANNOT_RAISE = 2 #a function which cannot raise @@ -39,7 +39,7 @@ self.oopspecindex = oopspecindex def get_extra_info(self): - return FakeEffektinfo(self.extraeffect, self.oopspecindex) + return FakeEffectinfo(self.extraeffect, self.oopspecindex) class TestHeapCache(object): def test_known_class_box(self): @@ -252,7 +252,7 @@ assert h.getarrayitem(box1, index2, descr1) is box4 h.invalidate_caches( - rop.CALL, FakeCallDescr(FakeEffektinfo.EF_ELIDABLE_CANNOT_RAISE), []) + rop.CALL, FakeCallDescr(FakeEffectinfo.EF_ELIDABLE_CANNOT_RAISE), []) assert h.getfield(box1, descr1) is box2 assert h.getarrayitem(box1, index1, descr1) is box2 assert h.getarrayitem(box1, index2, descr1) is box4 @@ -263,10 +263,10 @@ assert h.getarrayitem(box1, index2, descr1) is box4 h.invalidate_caches( - rop.CALL_LOOPINVARIANT, FakeCallDescr(FakeEffektinfo.EF_LOOPINVARIANT), []) + rop.CALL_LOOPINVARIANT, FakeCallDescr(FakeEffectinfo.EF_LOOPINVARIANT), []) h.invalidate_caches( - rop.CALL, FakeCallDescr(FakeEffektinfo.EF_RANDOM_EFFECTS), []) + rop.CALL, FakeCallDescr(FakeEffectinfo.EF_RANDOM_EFFECTS), []) assert h.getfield(box1, descr1) is None assert h.getarrayitem(box1, index1, descr1) is None assert h.getarrayitem(box1, index2, descr1) is None @@ -364,13 +364,13 @@ # Just need the destination box for this call h.invalidate_caches( rop.CALL, - FakeCallDescr(FakeEffektinfo.EF_CANNOT_RAISE, FakeEffektinfo.OS_ARRAYCOPY), + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY), [None, None, box2, None, None] ) assert h.getarrayitem(box1, index1, descr1) is box2 h.invalidate_caches( rop.CALL, - FakeCallDescr(FakeEffektinfo.EF_CANNOT_RAISE, FakeEffektinfo.OS_ARRAYCOPY), + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY), [None, None, box3, None, None] ) assert h.getarrayitem(box1, index1, descr1) is None @@ -379,7 +379,7 @@ assert h.getarrayitem(box4, index1, descr1) is box2 h.invalidate_caches( rop.CALL, - FakeCallDescr(FakeEffektinfo.EF_CANNOT_RAISE, FakeEffektinfo.OS_ARRAYCOPY), + FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, FakeEffectinfo.OS_ARRAYCOPY), [None, None, box2, None, None] ) assert h.getarrayitem(box4, index1, descr1) is None @@ -451,7 +451,29 @@ assert h.is_unescaped(box1) assert h.is_unescaped(box2) h.invalidate_caches( - rop.CALL, FakeCallDescr(FakeEffektinfo.EF_RANDOM_EFFECTS), [box1] + rop.CALL, FakeCallDescr(FakeEffectinfo.EF_RANDOM_EFFECTS), [box1] ) assert not h.is_unescaped(box1) assert not h.is_unescaped(box2) + + def test_call_doesnt_invalidate_unescaped_boxes(self): + h = HeapCache() + h.new(box1) + assert h.is_unescaped(box1) + h.setfield(box1, box2, descr1) + h.invalidate_caches(rop.CALL, + FakeCallDescr(FakeEffectinfo.EF_CAN_RAISE), + [] + ) + assert h.getfield(box1, descr1) is box2 + + def test_call_doesnt_invalidate_unescaped_array_boxes(self): + h = HeapCache() + h.new_array(box1, lengthbox1) + assert h.is_unescaped(box1) + h.setarrayitem(box1, index1, box3, descr1) + h.invalidate_caches(rop.CALL, + FakeCallDescr(FakeEffectinfo.EF_CAN_RAISE), + [] + ) + assert h.getarrayitem(box1, index1, descr1) is box3 diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py --- a/pypy/jit/metainterp/test/test_list.py +++ b/pypy/jit/metainterp/test/test_list.py @@ -1,6 +1,6 @@ import py from pypy.rlib.objectmodel import newlist_hint -from pypy.rlib.jit import JitDriver +from pypy.rlib.jit import JitDriver, promote from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin @@ -79,7 +79,7 @@ self.check_loops(setarrayitem_gc=0, call=0) def test_vlist_with_default_read(self): - jitdriver = JitDriver(greens = [], reds = ['n']) + jitdriver = JitDriver(greens=[], reds=['n']) def f(n): l = [1] * 20 while n > 0: @@ -93,7 +93,7 @@ n -= 1 return l[0] - res = self.meta_interp(f, [10], listops=True) + res = self.meta_interp(f, [10], listops=True, backendopt=True) assert res == f(10) self.check_resops(setarrayitem_gc=0, call=0, getarrayitem_gc=0) @@ -272,6 +272,22 @@ r = self.interp_operations(f, [-1]) assert r == 0 + def test_list_mul_nonzero(self): + driver = JitDriver(greens=[], reds=['i', 'n']) + + def f(n): + i = 0 + while i < n: + driver.jit_merge_point(i=i, n=n) + x = promote(n) + l = [-1] * x + i -= l[2] + return i + res = self.meta_interp(f, [5]) + assert res == 5 + self.check_resops(call=0) + + class TestOOtype(ListTests, OOJitMixin): pass diff --git a/pypy/jit/metainterp/test/test_tracingopts.py b/pypy/jit/metainterp/test/test_tracingopts.py --- a/pypy/jit/metainterp/test/test_tracingopts.py +++ b/pypy/jit/metainterp/test/test_tracingopts.py @@ -339,7 +339,7 @@ res = self.interp_operations(fn, [7]) assert res == 7 + 7 + 1 self.check_operations_history(setarrayitem_gc=2, - setfield_gc=2) + setfield_gc=0) def test_virtualizable_with_array_heap_cache(self): myjitdriver = jit.JitDriver(greens = [], reds = ['n', 'x', 'i', 'frame'], @@ -559,7 +559,7 @@ a1 = [0] * n g.a = a1 return len(a1) + res - res = self.interp_operations(fn, [7]) + res = self.interp_operations(fn, [7], backendopt=True) assert res == 7 * 3 self.check_operations_history(arraylen_gc=1) @@ -574,7 +574,7 @@ x = [0] * n x[2] = 21 return len(a[:n]) + x[2] - res = self.interp_operations(fn, [3]) + res = self.interp_operations(fn, [3], backendopt=True) assert res == 24 self.check_operations_history(getarrayitem_gc=0) diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py --- a/pypy/module/_random/interp_random.py +++ b/pypy/module/_random/interp_random.py @@ -3,7 +3,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable from pypy.rlib.rarithmetic import r_uint, intmask -from pypy.rlib import rrandom +from pypy.rlib import rbigint, rrandom, rstring import time @@ -89,25 +89,21 @@ strerror = space.wrap("number of bits must be greater than zero") raise OperationError(space.w_ValueError, strerror) bytes = ((k - 1) // 32 + 1) * 4 - bytesarray = [0] * bytes + bytesarray = rstring.StringBuilder(bytes) for i in range(0, bytes, 4): r = self._rnd.genrand32() if k < 32: r >>= (32 - k) - bytesarray[i + 0] = r & r_uint(0xff) - bytesarray[i + 1] = (r >> 8) & r_uint(0xff) - bytesarray[i + 2] = (r >> 16) & r_uint(0xff) - bytesarray[i + 3] = (r >> 24) & r_uint(0xff) + bytesarray.append(chr(r & r_uint(0xff))) + bytesarray.append(chr((r >> 8) & r_uint(0xff))) + bytesarray.append(chr((r >> 16) & r_uint(0xff))) + bytesarray.append(chr((r >> 24) & r_uint(0xff))) k -= 32 - # XXX so far this is quadratic - w_result = space.newint(0) - w_eight = space.newint(8) - for i in range(len(bytesarray) - 1, -1, -1): - byte = bytesarray[i] - w_result = space.or_(space.lshift(w_result, w_eight), - space.newint(intmask(byte))) - return w_result + # little endian order to match bytearray assignment order + result = rbigint.rbigint.frombytes( + bytesarray.build(), 'little', signed=False) + return space.newlong_from_rbigint(result) W_Random.typedef = TypeDef("Random", diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -120,7 +120,6 @@ assert info.loop_no == 0 assert info.type == 'loop' raises(TypeError, 'info.bridge_no') - assert info.key == ('loop', 0) assert len(info.operations) == 4 int_add = info.operations[0] dmp = info.operations[1] diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -143,6 +143,9 @@ def newcomplex(self, x, y): return w_some_obj() + def newlong_from_rbigint(self, x): + return w_some_obj() + def marshal_w(self, w_obj): "NOT_RPYTHON" raise NotImplementedError diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py --- a/pypy/objspace/std/test/test_complexobject.py +++ b/pypy/objspace/std/test/test_complexobject.py @@ -9,7 +9,6 @@ EPS = 1e-9 class TestW_ComplexObject: - def test_instantiation(self): def _t_complex(r=0.0,i=0.0): c = W_ComplexObject(r, i) diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -60,6 +60,8 @@ class AppTestAppFloatTest: + spaceconfig = dict(usemodules=['binascii', 'rctime']) + def setup_class(cls): cls.w_py26 = cls.space.wrap(sys.version_info >= (2, 6)) diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -161,8 +161,7 @@ def trampoline(%(arguments)s): return func(%(arguments)s) if hasattr(func, "oopspec"): - # XXX: This seems like it should be here, but it causes errors. - # trampoline.oopspec = func.oopspec + trampoline.oopspec = func.oopspec del func.oopspec trampoline.__name__ = func.__name__ + "_trampoline" trampoline._annspecialcase_ = "specialize:call_location" @@ -173,6 +172,7 @@ else: return trampoline(%(arguments)s) f.__name__ = func.__name__ + "_look_inside_iff" + f._always_inline = True """ % {"arguments": ", ".join(args)}).compile() in d return d["f"] return inner diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -2,6 +2,7 @@ from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int from pypy.rlib.rarithmetic import most_neg_value_of_same_type from pypy.rlib.rfloat import isinf, isnan +from pypy.rlib.rstring import StringBuilder from pypy.rlib.debug import make_sure_not_resized, check_regular_int from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.rlib import jit @@ -11,6 +12,7 @@ import math, sys SUPPORT_INT128 = hasattr(rffi, '__INT128_T') +BYTEORDER = sys.byteorder # note about digit sizes: # In division, the native integer type must be able to hold @@ -94,6 +96,12 @@ assert type(x) is type(NULLDIGIT) assert UDIGIT_MASK(x) & MASK == UDIGIT_MASK(x) +class InvalidEndiannessError(Exception): + pass + +class InvalidSignednessError(Exception): + pass + class Entry(extregistry.ExtRegistryEntry): _about_ = _check_digits def compute_result_annotation(self, s_list): @@ -261,6 +269,117 @@ # then modify the result. return _decimalstr_to_bigint(s) + @staticmethod + def frombytes(s, byteorder, signed): + if byteorder not in ('big', 'little'): + raise InvalidEndiannessError() + + if byteorder != BYTEORDER: + msb = ord(s[0]) + itr = range(len(s)-1, -1, -1) + else: + msb = ord(s[-1]) + itr = range(0, len(s)) + + sign = -1 if msb >= 0x80 and signed else 1 + accum = _widen_digit(0) + accumbits = 0 + digits = [] + carry = 1 + + for i in itr: + c = _widen_digit(ord(s[i])) + if sign == -1: + c = (0xFF ^ c) + carry + carry = c >> 8 + c &= 0xFF + + accum |= c << accumbits + accumbits += 8 + if accumbits >= SHIFT: + digits.append(_store_digit(intmask(accum & MASK))) + accum >>= SHIFT + accumbits -= SHIFT + + if accumbits: + digits.append(_store_digit(intmask(accum))) + result = rbigint(digits[:], sign) + result._normalize() + return result + + @jit.elidable + def tobytes(self, nbytes, byteorder, signed): + if byteorder not in ('big', 'little'): + raise InvalidEndiannessError() + if not signed and self.sign == -1: + raise InvalidSignednessError() + + bswap = byteorder != BYTEORDER + d = _widen_digit(0) + j = 0 + imax = self.numdigits() + accum = _widen_digit(0) + accumbits = 0 + result = StringBuilder(nbytes) + carry = 1 + + for i in range(0, imax): + d = self.widedigit(i) + if self.sign == -1: + d = (d ^ MASK) + carry + carry = d >> SHIFT + d &= MASK + + accum |= d << accumbits + if i == imax - 1: + # Avoid bogus 0's + s = d ^ MASK if self.sign == -1 else d + while s: + s >>=1 + accumbits += 1 + else: + accumbits += SHIFT + + while accumbits >= 8: + if j >= nbytes: + raise OverflowError() + j += 1 + + result.append(chr(accum & 0xFF)) + accum >>= 8 + accumbits -= 8 + + if accumbits: + if j >= nbytes: + raise OverflowError() + j += 1 + + if self.sign == -1: + # Add a sign bit + accum |= (~_widen_digit(0)) << accumbits; + + result.append(chr(accum & 0xFF)) + + if j < nbytes: + signbyte = 0xFF if self.sign == -1 else 0 + result.append_multiple_char(chr(signbyte), nbytes - j) + + digits = result.build() + + if j == nbytes and nbytes > 0 and signed: + # If not already set, we cannot contain the sign bit + msb = digits[-1] + if (self.sign == -1) != (ord(msb) >= 0x80): + raise OverflowError() + + if bswap: + # Bah, this is very inefficient. At least it's not + # quadratic. + length = len(digits) + if length >= 0: + digits = ''.join([digits[i] for i in range(length-1, -1, -1)]) + return digits + @jit.elidable def toint(self): """ @@ -1122,85 +1241,6 @@ z._normalize() return z -def _x_mul(a, b, digit=0): - """ - Grade school multiplication, ignoring the signs. - Returns the absolute value of the product, or None if error. - """ - - size_a = a.numdigits() - size_b = b.numdigits() - - if a is b: - # Efficient squaring per HAC, Algorithm 14.16: - # http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf - # Gives slightly less than a 2x speedup when a == b, - # via exploiting that each entry in the multiplication - # pyramid appears twice (except for the size_a squares). - z = rbigint([NULLDIGIT] * (size_a + size_b), 1) - i = UDIGIT_TYPE(0) - while i < size_a: - f = a.widedigit(i) - pz = i << 1 - pa = i + 1 - - carry = z.widedigit(pz) + f * f - z.setdigit(pz, carry) - pz += 1 - carry >>= SHIFT - assert carry <= MASK - - # Now f is added in twice in each column of the - # pyramid it appears. Same as adding f<<1 once. - f <<= 1 - while pa < size_a: - carry += z.widedigit(pz) + a.widedigit(pa) * f - pa += 1 - z.setdigit(pz, carry) - pz += 1 - carry >>= SHIFT - if carry: - carry += z.widedigit(pz) - z.setdigit(pz, carry) - pz += 1 - carry >>= SHIFT - if carry: - z.setdigit(pz, z.widedigit(pz) + carry) - assert (carry >> SHIFT) == 0 - i += 1 - z._normalize() - return z - - elif digit: - if digit & (digit - 1) == 0: - return b.lqshift(ptwotable[digit]) - - # Even if it's not power of two it can still be useful. - return _muladd1(b, digit) - - z = rbigint([NULLDIGIT] * (size_a + size_b), 1) - # gradeschool long mult - i = UDIGIT_TYPE(0) - while i < size_a: - carry = 0 - f = a.widedigit(i) - pz = i - pb = 0 - while pb < size_b: - carry += z.widedigit(pz) + b.widedigit(pb) * f - pb += 1 - z.setdigit(pz, carry) - pz += 1 - carry >>= SHIFT - assert carry <= MASK - if carry: - assert pz >= 0 - z.setdigit(pz, z.widedigit(pz) + carry) - assert (carry >> SHIFT) == 0 - i += 1 - z._normalize() - return z - def _kmul_split(n, size): """ A helper for Karatsuba multiplication (k_mul). diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py --- a/pypy/rlib/test/test_rbigint.py +++ b/pypy/rlib/test/test_rbigint.py @@ -9,7 +9,7 @@ from pypy.rlib import rbigint as lobj from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from pypy.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, - _store_digit, _mask_digit) + _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError) from pypy.rlib.rfloat import NAN from pypy.rpython.test.test_llinterp import interpret @@ -769,3 +769,31 @@ res = interpret(fn, []) assert res == -42.0 + + def test_frombytes(self): + s = "\xFF\x12\x34\x56" + bigint = rbigint.frombytes(s, byteorder="big", signed=False) + assert bigint.tolong() == 0xFF123456 + bigint = rbigint.frombytes(s, byteorder="little", signed=False) + assert bigint.tolong() == 0x563412FF + s = "\xFF\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\xFF" + bigint = rbigint.frombytes(s, byteorder="big", signed=False) + assert s == bigint.tobytes(16, byteorder="big", signed=False) + raises(InvalidEndiannessError, bigint.frombytes, '\xFF', 'foo', + signed=True) + + def test_tobytes(self): + assert rbigint.fromint(0).tobytes(1, 'big', signed=True) == '\x00' + assert rbigint.fromint(1).tobytes(2, 'big', signed=True) == '\x00\x01' + raises(OverflowError, rbigint.fromint(255).tobytes, 1, 'big', signed=True) + assert rbigint.fromint(-129).tobytes(2, 'big', signed=True) == '\xff\x7f' + assert rbigint.fromint(-129).tobytes(2, 'little', signed=True) == '\x7f\xff' + assert rbigint.fromint(65535).tobytes(3, 'big', signed=True) == '\x00\xff\xff' + assert rbigint.fromint(-65536).tobytes(3, 'little', signed=True) == '\x00\x00\xff' + assert rbigint.fromint(65535).tobytes(2, 'big', signed=False) == '\xff\xff' + assert rbigint.fromint(-8388608).tobytes(3, 'little', signed=True) == '\x00\x00\x80' + i = rbigint.fromint(-8388608) + raises(InvalidEndiannessError, i.tobytes, 3, 'foo', signed=True) + raises(InvalidSignednessError, i.tobytes, 3, 'little', signed=False) + raises(OverflowError, i.tobytes, 2, 'little', signed=True) + diff --git a/pypy/rpython/memory/gctransform/test/test_framework.py b/pypy/rpython/memory/gctransform/test/test_framework.py --- a/pypy/rpython/memory/gctransform/test/test_framework.py +++ b/pypy/rpython/memory/gctransform/test/test_framework.py @@ -36,6 +36,7 @@ from pypy.translator.c.genc import CStandaloneBuilder t = rtype(entrypoint, [s_list_of_strings]) + t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) db = cbuild.generate_graphs_for_llinterp() @@ -110,6 +111,7 @@ return g() + 2 t = rtype(entrypoint, [s_list_of_strings]) + t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) db = cbuild.generate_graphs_for_llinterp() @@ -133,6 +135,7 @@ return g() + 2 t = rtype(entrypoint, [s_list_of_strings]) + t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) f = py.test.raises(Exception, cbuild.generate_graphs_for_llinterp) diff --git a/pypy/rpython/rlist.py b/pypy/rpython/rlist.py --- a/pypy/rpython/rlist.py +++ b/pypy/rpython/rlist.py @@ -461,7 +461,6 @@ return self.r_list.recast(hop.llops, v_res) - # ____________________________________________________________ # # Low-level methods. These can be run for testing, but are meant to @@ -481,6 +480,8 @@ # done with it. So in the sequel we don't bother checking for overflow # when we compute "ll_length() + 1". +@jit.look_inside_iff(lambda LIST, count, item: jit.isconstant(count) and count < 15) +@jit.oopspec("newlist(count, item)") def ll_alloc_and_set(LIST, count, item): if count < 0: count = 0 @@ -492,14 +493,14 @@ check = widen(item) else: check = item - if (not malloc_zero_filled) or check: # as long as malloc it is known to zero the allocated memory avoid zeroing twice - + # as long as malloc is known to zero the allocated memory avoid zeroing + # twice + if (not malloc_zero_filled) or check: i = 0 while i < count: l.ll_setitem_fast(i, item) i += 1 return l -ll_alloc_and_set.oopspec = 'newlist(count, item)' # return a nullptr() if lst is a list of pointers it, else None. Note diff --git a/pypy/tool/option.py b/pypy/tool/option.py --- a/pypy/tool/option.py +++ b/pypy/tool/option.py @@ -10,7 +10,8 @@ def get_standard_options(): config = get_pypy_config() - parser = to_optparse(config, extra_useage=extra_useage) + parser = to_optparse(config, useoptions=["objspace.*"], + extra_useage=extra_useage) return config, parser def process_options(parser, argv=None): diff --git a/pypy/translator/platform/darwin.py b/pypy/translator/platform/darwin.py --- a/pypy/translator/platform/darwin.py +++ b/pypy/translator/platform/darwin.py @@ -61,8 +61,9 @@ class Darwin_i386(Darwin): name = "darwin_i386" - link_flags = ('-arch', 'i386') - cflags = ('-arch', 'i386', '-O3', '-fomit-frame-pointer') + link_flags = ('-arch', 'i386', '-mmacosx-version-min=10.4') + cflags = ('-arch', 'i386', '-O3', '-fomit-frame-pointer', + '-mmacosx-version-min=10.4') class Darwin_PowerPC(Darwin):#xxx fixme, mwp name = "darwin_powerpc" @@ -71,5 +72,6 @@ class Darwin_x86_64(Darwin): name = "darwin_x86_64" - link_flags = ('-arch', 'x86_64') - cflags = ('-arch', 'x86_64', '-O3', '-fomit-frame-pointer') + link_flags = ('-arch', 'x86_64', '-mmacosx-version-min=10.5') + cflags = ('-arch', 'x86_64', '-O3', '-fomit-frame-pointer', + '-mmacosx-version-min=10.5') _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit