mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:17:42 +00:00
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. :^)
This commit is contained in:
parent
941be2dcc2
commit
b3e6a6c1cd
5 changed files with 16 additions and 21 deletions
|
@ -22,7 +22,11 @@ void ASTNode::generate_bytecode(Bytecode::Generator&) const
|
||||||
|
|
||||||
void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
|
void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const
|
||||||
{
|
{
|
||||||
generator.emit<Bytecode::Op::EnterScope>(*this);
|
for (auto& function : functions()) {
|
||||||
|
generator.emit<Bytecode::Op::NewFunction>(function);
|
||||||
|
generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(function.name()));
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& child : children()) {
|
for (auto& child : children()) {
|
||||||
child.generate_bytecode(generator);
|
child.generate_bytecode(generator);
|
||||||
if (generator.is_current_block_terminated())
|
if (generator.is_current_block_terminated())
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
O(JumpConditional) \
|
O(JumpConditional) \
|
||||||
O(JumpNullish) \
|
O(JumpNullish) \
|
||||||
O(Call) \
|
O(Call) \
|
||||||
O(EnterScope) \
|
O(NewFunction) \
|
||||||
O(Return) \
|
O(Return) \
|
||||||
O(BitwiseAnd) \
|
O(BitwiseAnd) \
|
||||||
O(BitwiseOr) \
|
O(BitwiseOr) \
|
||||||
|
|
|
@ -210,21 +210,11 @@ void Call::execute(Bytecode::Interpreter& interpreter) const
|
||||||
interpreter.accumulator() = return_value;
|
interpreter.accumulator() = return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterScope::execute(Bytecode::Interpreter& interpreter) const
|
void NewFunction::execute(Bytecode::Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
auto& vm = interpreter.vm();
|
auto& vm = interpreter.vm();
|
||||||
auto& global_object = interpreter.global_object();
|
auto& global_object = interpreter.global_object();
|
||||||
|
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());
|
||||||
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.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Return::execute(Bytecode::Interpreter& interpreter) const
|
void Return::execute(Bytecode::Interpreter& interpreter) const
|
||||||
|
@ -384,9 +374,9 @@ String Call::to_string(Bytecode::Executable const&) const
|
||||||
return builder.to_string();
|
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
|
String Return::to_string(Bytecode::Executable const&) const
|
||||||
|
|
|
@ -346,11 +346,11 @@ private:
|
||||||
Register m_arguments[];
|
Register m_arguments[];
|
||||||
};
|
};
|
||||||
|
|
||||||
class EnterScope final : public Instruction {
|
class NewFunction final : public Instruction {
|
||||||
public:
|
public:
|
||||||
explicit EnterScope(ScopeNode const& scope_node)
|
explicit NewFunction(FunctionNode const& function_node)
|
||||||
: Instruction(Type::EnterScope)
|
: Instruction(Type::NewFunction)
|
||||||
, m_scope_node(scope_node)
|
, m_function_node(function_node)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ public:
|
||||||
String to_string(Bytecode::Executable const&) const;
|
String to_string(Bytecode::Executable const&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScopeNode const& m_scope_node;
|
FunctionNode const& m_function_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Return final : public Instruction {
|
class Return final : public Instruction {
|
||||||
|
|
|
@ -114,6 +114,7 @@ class Error;
|
||||||
class ErrorType;
|
class ErrorType;
|
||||||
class Exception;
|
class Exception;
|
||||||
class Expression;
|
class Expression;
|
||||||
|
class FunctionNode;
|
||||||
class Accessor;
|
class Accessor;
|
||||||
class GlobalObject;
|
class GlobalObject;
|
||||||
class HandleImpl;
|
class HandleImpl;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue