From b3e6a6c1cdfb7aec7a1ac96b1a6200e5bb106253 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 10 Jun 2021 00:49:23 +0200 Subject: [PATCH] LibJS: Perform function instantiation in bytecode This replaces Bytecode::Op::EnterScope with a new NewFunction op that instantiates a ScriptFunction from a given FunctionNode (AST). This is then used to instantiate the local functions directly from bytecode when entering a ScopeNode. :^) --- .../Libraries/LibJS/Bytecode/ASTCodegen.cpp | 6 +++++- .../Libraries/LibJS/Bytecode/Instruction.h | 2 +- Userland/Libraries/LibJS/Bytecode/Op.cpp | 18 ++++-------------- Userland/Libraries/LibJS/Bytecode/Op.h | 10 +++++----- Userland/Libraries/LibJS/Forward.h | 1 + 5 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 4c16903670..2fdfb567f0 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -22,7 +22,11 @@ void ASTNode::generate_bytecode(Bytecode::Generator&) const void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const { - generator.emit(*this); + for (auto& function : functions()) { + generator.emit(function); + generator.emit(generator.intern_string(function.name())); + } + for (auto& child : children()) { child.generate_bytecode(generator); if (generator.is_current_block_terminated()) diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index 61aa3aac3b..19a80e5aa9 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -39,7 +39,7 @@ O(JumpConditional) \ O(JumpNullish) \ O(Call) \ - O(EnterScope) \ + O(NewFunction) \ O(Return) \ O(BitwiseAnd) \ O(BitwiseOr) \ diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 260f104a05..c8991de6e2 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -210,21 +210,11 @@ void Call::execute(Bytecode::Interpreter& interpreter) const interpreter.accumulator() = return_value; } -void EnterScope::execute(Bytecode::Interpreter& interpreter) const +void NewFunction::execute(Bytecode::Interpreter& interpreter) const { auto& vm = interpreter.vm(); auto& global_object = interpreter.global_object(); - - for (auto& declaration : m_scope_node.functions()) - vm.current_scope()->put_to_scope(declaration.name(), { js_undefined(), DeclarationKind::Var }); - - for (auto& declaration : m_scope_node.functions()) { - auto* function = ScriptFunction::create(global_object, declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), vm.current_scope(), declaration.is_strict_mode()); - vm.set_variable(declaration.name(), function, global_object); - } - - // FIXME: Process variable declarations. - // FIXME: Whatever else JS::Interpreter::enter_scope() does. + interpreter.accumulator() = ScriptFunction::create(global_object, m_function_node.name(), m_function_node.body(), m_function_node.parameters(), m_function_node.function_length(), vm.current_scope(), m_function_node.is_strict_mode()); } void Return::execute(Bytecode::Interpreter& interpreter) const @@ -384,9 +374,9 @@ String Call::to_string(Bytecode::Executable const&) const return builder.to_string(); } -String EnterScope::to_string(Bytecode::Executable const&) const +String NewFunction::to_string(Bytecode::Executable const&) const { - return "EnterScope"; + return "NewFunction"; } String Return::to_string(Bytecode::Executable const&) const diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 1b7f62dbb1..73e792c1df 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -346,11 +346,11 @@ private: Register m_arguments[]; }; -class EnterScope final : public Instruction { +class NewFunction final : public Instruction { public: - explicit EnterScope(ScopeNode const& scope_node) - : Instruction(Type::EnterScope) - , m_scope_node(scope_node) + explicit NewFunction(FunctionNode const& function_node) + : Instruction(Type::NewFunction) + , m_function_node(function_node) { } @@ -358,7 +358,7 @@ public: String to_string(Bytecode::Executable const&) const; private: - ScopeNode const& m_scope_node; + FunctionNode const& m_function_node; }; class Return final : public Instruction { diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 81404dfa30..da0eb5fe27 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -114,6 +114,7 @@ class Error; class ErrorType; class Exception; class Expression; +class FunctionNode; class Accessor; class GlobalObject; class HandleImpl;