[pypy-commit] pypy kill-faking: Resolved merge conflicts

alex_gaynor noreply at buildbot.pypy.org
Sun Dec 2 22:35:07 CET 2012


Author: Alex Gaynor <alex.gaynor at 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".
 
+ at jit.look_inside_iff(lambda LIST, count, item: jit.isconstant(count) and count < 15)
+ at 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')


More information about the pypy-commit mailing list