Commit 50fe6169 authored by Stefan Behnel's avatar Stefan Behnel

reuse normal iterable unpacking code for extended iterable unpacking

parent 0c1c628e
...@@ -4915,7 +4915,7 @@ class SequenceNode(ExprNode): ...@@ -4915,7 +4915,7 @@ class SequenceNode(ExprNode):
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
else: else:
self.generate_generic_parallel_unpacking_code( self.generate_generic_parallel_unpacking_code(
code, rhs, use_loop=long_enough_for_a_loop) code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
code.putln("}") code.putln("}")
for value_node in self.coerced_unpacked_items: for value_node in self.coerced_unpacked_items:
...@@ -4959,8 +4959,7 @@ class SequenceNode(ExprNode): ...@@ -4959,8 +4959,7 @@ class SequenceNode(ExprNode):
code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (item.result(), sequence_type, i)) code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (item.result(), sequence_type, i))
code.put_incref(item.result(), item.ctype()) code.put_incref(item.result(), item.ctype())
def generate_generic_parallel_unpacking_code(self, code, rhs, use_loop): def generate_generic_parallel_unpacking_code(self, code, rhs, unpacked_items, use_loop, terminate=True):
code.globalstate.use_utility_code(iternext_unpacking_end_utility_code)
code.globalstate.use_utility_code(raise_need_more_values_to_unpack) code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c")) code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c"))
code.putln("Py_ssize_t index = -1;") # must be at the start of a C block! code.putln("Py_ssize_t index = -1;") # must be at the start of a C block!
...@@ -4968,7 +4967,7 @@ class SequenceNode(ExprNode): ...@@ -4968,7 +4967,7 @@ class SequenceNode(ExprNode):
if use_loop: if use_loop:
code.putln("PyObject** temps[%s] = {%s};" % ( code.putln("PyObject** temps[%s] = {%s};" % (
len(self.unpacked_items), len(self.unpacked_items),
','.join(['&%s' % item.result() for item in self.unpacked_items]))) ','.join(['&%s' % item.result() for item in unpacked_items])))
iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
code.putln( code.putln(
...@@ -4986,14 +4985,14 @@ class SequenceNode(ExprNode): ...@@ -4986,14 +4985,14 @@ class SequenceNode(ExprNode):
unpacking_error_label = code.new_label('unpacking_failed') unpacking_error_label = code.new_label('unpacking_failed')
unpack_code = "%s(%s)" % (iternext_func, iterator_temp) unpack_code = "%s(%s)" % (iternext_func, iterator_temp)
if use_loop: if use_loop:
code.putln("for (index=0; index < %s; index++) {" % len(self.unpacked_items)) code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code) code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
code.put_goto(unpacking_error_label) code.put_goto(unpacking_error_label)
code.put_gotref("item") code.put_gotref("item")
code.putln("*(temps[index]) = item;") code.putln("*(temps[index]) = item;")
code.putln("}") code.putln("}")
else: else:
for i, item in enumerate(self.unpacked_items): for i, item in enumerate(unpacked_items):
code.put( code.put(
"index = %d; %s = %s; if (unlikely(!%s)) " % ( "index = %d; %s = %s; if (unlikely(!%s)) " % (
i, i,
...@@ -5002,22 +5001,32 @@ class SequenceNode(ExprNode): ...@@ -5002,22 +5001,32 @@ class SequenceNode(ExprNode):
item.result())) item.result()))
code.put_goto(unpacking_error_label) code.put_goto(unpacking_error_label)
code.put_gotref(item.py_result()) code.put_gotref(item.py_result())
code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
unpack_code, if terminate:
len(self.unpacked_items))) code.globalstate.use_utility_code(iternext_unpacking_end_utility_code)
code.put_decref_clear(iterator_temp, py_object_type) code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
code.funcstate.release_temp(iterator_temp) unpack_code,
code.putln("%s = NULL;" % iternext_func) len(unpacked_items)))
code.funcstate.release_temp(iternext_func) code.putln("%s = NULL;" % iternext_func)
code.put_decref_clear(iterator_temp, py_object_type)
unpacking_done_label = code.new_label('unpacking_done') unpacking_done_label = code.new_label('unpacking_done')
code.put_goto(unpacking_done_label) code.put_goto(unpacking_done_label)
code.put_label(unpacking_error_label) code.put_label(unpacking_error_label)
code.put_decref_clear(iterator_temp, py_object_type) code.put_decref_clear(iterator_temp, py_object_type)
code.putln("%s = NULL;" % iternext_func)
code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);") code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);")
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
code.put_label(unpacking_done_label) code.put_label(unpacking_done_label)
code.funcstate.release_temp(iternext_func)
if terminate:
code.funcstate.release_temp(iterator_temp)
iterator_temp = None
return iterator_temp
def generate_starred_assignment_code(self, rhs, code): def generate_starred_assignment_code(self, rhs, code):
for i, arg in enumerate(self.args): for i, arg in enumerate(self.args):
if arg.is_starred: if arg.is_starred:
...@@ -5030,24 +5039,16 @@ class SequenceNode(ExprNode): ...@@ -5030,24 +5039,16 @@ class SequenceNode(ExprNode):
iterator_temp = None iterator_temp = None
if unpacked_fixed_items_left: if unpacked_fixed_items_left:
iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) for item in unpacked_fixed_items_left:
code.putln("%s = PyObject_GetIter(%s); %s" % (
iterator_temp,
rhs.py_result(),
code.error_goto_if_null(iterator_temp, self.pos)))
code.put_gotref(iterator_temp)
rhs.generate_disposal_code(code)
code.globalstate.use_utility_code(
UtilityCode.load_cached("UnpackItem", "ObjectHandling.c"))
for i, item in enumerate(unpacked_fixed_items_left):
item.allocate(code) item.allocate(code)
code.putln("%s = __Pyx_UnpackItem(%s, %d); %s" % ( code.putln('{')
item.result(), iterator_temp, i, iterator_temp = self.generate_generic_parallel_unpacking_code(
code.error_goto_if_null(item.result(), self.pos))) code, rhs, unpacked_fixed_items_left,
code.put_gotref(item.py_result()) use_loop=True, terminate=False)
for i, item in enumerate(unpacked_fixed_items_left):
value_node = self.coerced_unpacked_items[i] value_node = self.coerced_unpacked_items[i]
value_node.generate_evaluation_code(code) value_node.generate_evaluation_code(code)
code.putln('}')
starred_target.allocate(code) starred_target.allocate(code)
target_list = starred_target.result() target_list = starred_target.result()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment