From 9a7e6158afedee8f169f10040a79db95a4e9aebc Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 24 Jul 2024 10:35:39 +0200 Subject: [PATCH] LibJS: Fix crash in bytecode generator on https://twinings.co.uk/ If the current block has already been terminated, we should just skip creating a per-iteration environment. --- Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 16 ++++++++++------ .../Tests/for-loop-per-iteration-env-bug.js | 12 ++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 Userland/Libraries/LibJS/Tests/for-loop-per-iteration-env-bug.js diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 887b24d33dd..010ff28c4c4 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -1042,9 +1042,12 @@ Bytecode::CodeGenerationErrorOr> ForStatement::generate_ } }; - // CreatePerIterationEnvironment where lastIterationEnv is the variable - // scope created above for bound identifiers - generate_per_iteration_bindings(); + if (m_init) { + // CreatePerIterationEnvironment where lastIterationEnv is the variable + // scope created above for bound identifiers + generate_per_iteration_bindings(); + } + body_block_ptr = &generator.make_block(); if (m_update) @@ -1082,10 +1085,11 @@ Bytecode::CodeGenerationErrorOr> ForStatement::generate_ generator.end_breakable_scope(); generator.end_continuable_scope(); - // CreatePerIterationEnvironment where lastIterationEnv is the environment - // created by the previous CreatePerIterationEnvironment setup - generate_per_iteration_bindings(); if (!generator.is_current_block_terminated()) { + // CreatePerIterationEnvironment where lastIterationEnv is the environment + // created by the previous CreatePerIterationEnvironment setup + generate_per_iteration_bindings(); + if (m_update) { generator.emit(Bytecode::Label { *update_block_ptr }); } else { diff --git a/Userland/Libraries/LibJS/Tests/for-loop-per-iteration-env-bug.js b/Userland/Libraries/LibJS/Tests/for-loop-per-iteration-env-bug.js new file mode 100644 index 00000000000..af703d1d8ff --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/for-loop-per-iteration-env-bug.js @@ -0,0 +1,12 @@ +test("check that codegen doesn't crash", () => { + function func(x) { + expect(x()).toBe(0); + } + + function go() { + for (let i = 0; ; ) { + func(() => i); + break; + } + } +});