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.
This commit is contained in:
Andreas Kling 2021-06-05 15:14:09 +02:00
parent 2316a084bf
commit 1eafaf67fe
Notes: sideshowbarker 2024-07-18 12:42:10 +09:00
3 changed files with 40 additions and 0 deletions

View File

@ -20,6 +20,7 @@ Optional<Bytecode::Register> ASTNode::generate_bytecode(Bytecode::Generator&) co
Optional<Bytecode::Register> ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
{
generator.emit<Bytecode::Op::EnterScope>(*this);
for (auto& child : children()) {
[[maybe_unused]] auto reg = child.generate_bytecode(generator);
}

View File

@ -4,9 +4,11 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/AST.h>
#include <LibJS/Bytecode/Interpreter.h>
#include <LibJS/Bytecode/Op.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/ScriptFunction.h>
#include <LibJS/Runtime/Value.h>
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:<empty>", m_result);
}
String EnterScope::to_string() const
{
return "EnterScope";
}
}

View File

@ -265,4 +265,19 @@ private:
Optional<Label> m_target;
};
class EnterScope final : public Instruction {
public:
explicit EnterScope(ScopeNode const& scope_node)
: m_scope_node(scope_node)
{
}
virtual ~EnterScope() override { }
virtual void execute(Bytecode::Interpreter&) const override;
virtual String to_string() const override;
private:
ScopeNode const& m_scope_node;
};
}