From 125a71d36dcaf2c5e5263cc8b3368609ccbe17e3 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Sat, 11 Jun 2022 23:24:55 +0100 Subject: [PATCH] LibJS/Bytecode: Define named functions as a variable inside their scope This allows you to recurse into a named function that is stored in a variable. For example, this would previously print "wrong" instead of "right": ```js function g() { console.log("wrong") } f = function g(i) { if (i !== 1) g(1); else console.log("right"); } f() ``` --- Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index d0f9ce0329..27184a4106 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -1010,7 +1010,23 @@ Bytecode::CodeGenerationErrorOr FunctionDeclaration::generate_bytecode(Byt Bytecode::CodeGenerationErrorOr FunctionExpression::generate_bytecode(Bytecode::Generator& generator) const { + bool has_name = !name().is_empty(); + Optional name_identifier; + + if (has_name) { + generator.begin_variable_scope(Bytecode::Generator::BindingMode::Lexical); + + name_identifier = generator.intern_identifier(name()); + generator.emit(*name_identifier, Bytecode::Op::EnvironmentMode::Lexical, true); + } + generator.emit(*this); + + if (has_name) { + generator.emit(*name_identifier, Bytecode::Op::SetVariable::InitializationMode::Initialize, Bytecode::Op::EnvironmentMode::Lexical); + generator.end_variable_scope(); + } + return {}; }