LibJS/Rust: Create for-of loop blocks before evaluating iterable

Match the C++ pipeline's block creation order by creating end_block
and update_block before evaluating the for-of RHS expression. This
ensures loop structure blocks get lower block numbers than blocks
created during RHS evaluation (e.g. from conditional expressions),
producing the same block layout as C++.
This commit is contained in:
Andreas Kling 2026-03-01 17:44:55 +01:00 committed by Andreas Kling
parent d88374e119
commit fdcb2cdd94

View file

@ -6605,21 +6605,22 @@ fn generate_for_of_statement_inner(
preferred_dst: Option<&ScopedOperand>,
is_await: bool,
) -> Option<ScopedOperand> {
// Match C++ block creation order: create end_block and update_block before
// evaluating the RHS expression. This ensures loop blocks get lower block
// numbers than any blocks created during RHS evaluation (e.g. conditional
// expressions), matching the C++ pipeline's block layout.
let end_block = generator.make_block();
let update_block = generator.make_block();
// Create TDZ for lexical declarations before evaluating the RHS expression.
let entered_tdz = enter_for_in_of_head_tdz(generator, lhs);
let object = generate_expression_or_undefined(rhs, generator, None);
if entered_tdz {
leave_for_in_of_head_tdz(generator);
}
let end_block = generator.make_block();
let needs_lexical_env = for_in_of_needs_lexical_env(lhs);
let old_handler = generator.current_unwind_handler;
// NB: Create update_block before exception blocks to match C++ block ordering
// (C++ creates loop_end and loop_update in ForOfStatement, then exception blocks
// in for_in_of_body_evaluation).
let update_block = generator.make_block();
// Get iterator
let iterator_object = generator.allocate_register();
let iterator_next_method = generator.allocate_register();