From 1eafaf67feb31cc4b41a0926158372596a654a0e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 5 Jun 2021 15:14:09 +0200 Subject: [PATCH] LibJS: Add a new EnterScope bytecode instruction This is intended to perform the same duties as enter_scope() does in the AST tree-walk interpreter: - Hoisted function declaration processing - Hoisted variable declaration processing - ... maybe more This first cut only implements the function declaration processing. --- .../Libraries/LibJS/Bytecode/ASTCodegen.cpp | 1 + Userland/Libraries/LibJS/Bytecode/Op.cpp | 24 +++++++++++++++++++ Userland/Libraries/LibJS/Bytecode/Op.h | 15 ++++++++++++ 3 files changed, 40 insertions(+) diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index ea13482b0cc..a0b34e50fa6 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -20,6 +20,7 @@ Optional ASTNode::generate_bytecode(Bytecode::Generator&) co Optional ScopeNode::generate_bytecode(Bytecode::Generator& generator) const { + generator.emit(*this); for (auto& child : children()) { [[maybe_unused]] auto reg = child.generate_bytecode(generator); } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index ab3e25bcfe4..225ee92b422 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -4,9 +4,11 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include +#include #include namespace JS::Bytecode::Op { @@ -89,6 +91,23 @@ void JumpIfTrue::execute(Bytecode::Interpreter& interpreter) const interpreter.jump(m_target.value()); } +void EnterScope::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. +} + String Load::to_string() const { return String::formatted("Load dst:{}, value:{}", m_dst, m_value.to_string_without_side_effects()); @@ -163,4 +182,9 @@ String JumpIfTrue::to_string() const return String::formatted("JumpIfTrue result:{}, target:", m_result); } +String EnterScope::to_string() const +{ + return "EnterScope"; +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index cce02b2ecc2..c80ca2ba6c5 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -265,4 +265,19 @@ private: Optional