[pypy-commit] pypy default: Fix for b43a6e2c0ea1: can't very reasonably use appexec() here,
arigo
pypy.commits at gmail.com
Mon Jul 31 05:41:11 EDT 2017
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r91996:abb9f6f4b003
Date: 2017-07-31 09:40 +0200
http://bitbucket.org/pypy/pypy/changeset/abb9f6f4b003/
Log: Fix for b43a6e2c0ea1: can't very reasonably use appexec() here,
because it would create a single jit loop. If the logic is called
with various types in the same program, we get a longer and longer
jit loop keeping previous results alive.
Fixed the same way than listobject.py's _do_extend_from_iterable.
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -569,14 +569,43 @@
return list(buf.as_str())
return _from_byte_sequence(space, w_source)
+def _get_printable_location(w_type):
+ return ('bytearray_from_byte_sequence [w_type=%s]' %
+ w_type.getname(w_type.space))
+
+_byteseq_jitdriver = jit.JitDriver(
+ name='bytearray_from_byte_sequence',
+ greens=['w_type'],
+ reds=['w_iter', 'data'],
+ get_printable_location=_get_printable_location)
+
def _from_byte_sequence(space, w_source):
# Split off in a separate function for the JIT's benefit
- w_result = space.appexec([w_source], """(seq):
- result = bytearray()
- for i in seq:
- result.append(i)
- return result""")
- return w_result.getdata()
+ # and add a jitdriver with the type of w_iter as the green key
+ w_iter = space.iter(w_source)
+ length_hint = space.length_hint(w_source, 0)
+ data = newlist_hint(length_hint)
+ #
+ _from_byte_sequence_loop(space, w_iter, data)
+ #
+ extended = len(data)
+ if extended < length_hint:
+ resizelist_hint(data, extended)
+ return data
+
+def _from_byte_sequence_loop(space, w_iter, data):
+ w_type = space.type(w_iter)
+ while True:
+ _byteseq_jitdriver.jit_merge_point(w_type=w_type,
+ w_iter=w_iter,
+ data=data)
+ try:
+ w_item = space.next(w_iter)
+ except OperationError as e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ break
+ data.append(space.byte_w(w_item))
def _hex_digit_to_int(d):
diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py
--- a/pypy/objspace/std/test/test_bytearrayobject.py
+++ b/pypy/objspace/std/test/test_bytearrayobject.py
@@ -448,6 +448,13 @@
raises(TypeError, b.extend, [object()])
raises(TypeError, b.extend, u"unicode")
+ def test_extend_calls_len_or_lengthhint(self):
+ class BadLen(object):
+ def __iter__(self): return iter(range(10))
+ def __len__(self): raise RuntimeError('hello')
+ b = bytearray()
+ raises(RuntimeError, b.extend, BadLen())
+
def test_setitem_from_front(self):
b = bytearray(b'abcdefghij')
b[:2] = b''
More information about the pypy-commit
mailing list