From 3fdc562743cdaddf554785bd83b66b254f560090 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 6 Feb 2019 11:14:10 +0100 Subject: V4: Fix unwind handling when destructuring lists If there was a rest element in the list, the generated code would jump over the clean-up (closing of the iterator). However, this would also jump over any resetting of the unwind handler. (cherry-picked from commit 3310f173c1c6208cb0f6541578419196bc29831f) Task-number: QTBUG-73985 Change-Id: I9a1bcb9e69fd98975fe9c89e23a4568b0dafdf83 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4codegen.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src/qml/compiler/qv4codegen.cpp') diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 04da41430c..010848bdca 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -727,9 +727,6 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle bytecodeGenerator->addInstruction(iteratorObjInstr); iterator.storeConsumeAccumulator(); - bool hasRest = false; - - BytecodeGenerator::Label end = bytecodeGenerator->newLabel(); { auto cleanup = [this, iterator, iteratorDone]() { iterator.loadInAccumulator(); @@ -760,27 +757,17 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle Reference::fromConst(this, Encode(true)).storeOnStack(iteratorDone.stackSlot()); bytecodeGenerator->addInstruction(Instruction::DestructureRestElement()); initializeAndDestructureBindingElement(e, Reference::fromAccumulator(this), isDefinition); - hasRest = true; } else { Instruction::IteratorNext next; next.value = iteratorValue.stackSlot(); next.done = iteratorDone.stackSlot(); bytecodeGenerator->addInstruction(next); initializeAndDestructureBindingElement(e, iteratorValue, isDefinition); - if (hasError) { - end.link(); + if (hasError) return; - } } } - - if (hasRest) - // no need to close the iterator - bytecodeGenerator->jump().link(end); } - - - end.link(); } void Codegen::destructurePattern(Pattern *p, const Reference &rhs) -- cgit v1.2.3 From cdb8eb988e572411030486ad2834ae54e4567bf3 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 6 Feb 2019 10:32:31 +0100 Subject: V4: Rotate loop in ArrayPattern and eliminate "done" label This prevents jumping over the resetting of the unwind handler when an exception occurs. (cherry-picked from commit 0282b89ec672e25a465a8e51bc74c7fd58a624b1) Fixes: QTBUG-73985 Change-Id: I4a4da815f54c13980d239e0492f9b013991cfbd5 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4codegen.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'src/qml/compiler/qv4codegen.cpp') diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 010848bdca..256ab6e0be 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1207,7 +1207,6 @@ bool Codegen::visit(ArrayPattern *ast) BytecodeGenerator::Label in = bytecodeGenerator->newLabel(); BytecodeGenerator::Label end = bytecodeGenerator->newLabel(); - BytecodeGenerator::Label done = bytecodeGenerator->newLabel(); { auto cleanup = [this, iterator, iteratorDone]() { @@ -1217,12 +1216,6 @@ bool Codegen::visit(ArrayPattern *ast) bytecodeGenerator->addInstruction(close); }; ControlFlowLoop flow(this, &end, &in, cleanup); - bytecodeGenerator->jump().link(in); - - BytecodeGenerator::Label body = bytecodeGenerator->label(); - - lhsValue.loadInAccumulator(); - pushAccumulator(); in.link(); iterator.loadInAccumulator(); @@ -1230,13 +1223,14 @@ bool Codegen::visit(ArrayPattern *ast) next.value = lhsValue.stackSlot(); next.done = iteratorDone.stackSlot(); bytecodeGenerator->addInstruction(next); - bytecodeGenerator->addJumpInstruction(Instruction::JumpFalse()).link(body); - bytecodeGenerator->jump().link(done); + bytecodeGenerator->addJumpInstruction(Instruction::JumpTrue()).link(end); + lhsValue.loadInAccumulator(); + pushAccumulator(); + + bytecodeGenerator->jump().link(in); end.link(); } - - done.link(); } else { RegisterScope innerScope(this); Reference expr = expression(it->element->initializer); -- cgit v1.2.3