LibJS/Bytecode: Ensure iterator is closed after array destructuring

If destructuring didn't exhaust the iterator, we have to manually close
the iterator.

49 new passes on test262. :^)
This commit is contained in:
Andreas Kling 2023-06-26 17:21:12 +02:00
parent 55531e5cda
commit 56fb5a3f5d
Notes: sideshowbarker 2024-07-16 23:13:25 +09:00

View file

@ -1152,6 +1152,8 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
*/
auto is_iterator_exhausted_register = generator.allocate_register();
generator.emit<Bytecode::Op::LoadImmediate>(Value(false));
generator.emit<Bytecode::Op::Store>(is_iterator_exhausted_register);
auto iterator_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Load>(value_reg);
@ -1306,6 +1308,20 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
first = false;
}
auto& done_block = generator.make_block();
auto& not_done_block = generator.make_block();
generator.emit<Bytecode::Op::Load>(is_iterator_exhausted_register);
generator.emit<Bytecode::Op::JumpConditional>().set_targets(
Bytecode::Label { done_block },
Bytecode::Label { not_done_block });
generator.switch_to_basic_block(not_done_block);
generator.emit<Bytecode::Op::Load>(iterator_reg);
generator.emit<Bytecode::Op::IteratorClose>(Completion::Type::Normal, Optional<Value> {});
generator.emit<Bytecode::Op::Jump>(Bytecode::Label { done_block });
generator.switch_to_basic_block(done_block);
return {};
}