V4: Fix unwind handler reset after for-in loop
Consider this JavaScript snippet: function f() { for (var i in []) {} } This generates the following bytecode sequence: 2 0: 14 00 09 MoveConst r3, C0 3: ec 00 00 DefineArray (function), 0 6: da 00 GetIterator 0 8: 18 08 StoreReg r2 10: c0 0f SetUnwindHandler 27 12: 50 04 Jump 18 14: 16 0a LoadReg r4 16: 18 07 StoreReg r1 3 18: 16 08 LoadReg r2 20: dc 0a 09 IteratorNext r4, r3 23: 54 f5 JumpFalse 14 25: 50 03 Jump 30 27: c0 00 SetUnwindHandler <null> 29: c2 UnwindDispatch 4 30: 0e LoadUndefined 31: 02 Ret The problem is a normal loop exit: instruction 23 will not jump back, but fall through, and then instruction 25 will jump over the instructions resetting the unwind handler (27 + 29). Removing this jump fixes the issue. Change-Id: Ic9f03555ebebc27144490bce04e9a4166ed7c97c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
a8729cf143
commit
205f836e5d
|
@ -3339,7 +3339,6 @@ bool Codegen::visit(ForEachStatement *ast)
|
|||
|
||||
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
|
||||
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
|
||||
BytecodeGenerator::Label done = bytecodeGenerator->newLabel();
|
||||
|
||||
{
|
||||
auto cleanup = [ast, iterator, iteratorDone, this]() {
|
||||
|
@ -3397,13 +3396,11 @@ bool Codegen::visit(ForEachStatement *ast)
|
|||
next.done = iteratorDone.stackSlot();
|
||||
bytecodeGenerator->addInstruction(next);
|
||||
bytecodeGenerator->addJumpInstruction(Instruction::JumpFalse()).link(body);
|
||||
bytecodeGenerator->jump().link(done);
|
||||
|
||||
end.link();
|
||||
// all execution paths need to end up here (normal loop exit, break, and exceptions) in
|
||||
// order to reset the unwind handler, and to close the iterator in calse of an for-of loop.
|
||||
}
|
||||
|
||||
done.link();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue