mirror of
https://github.com/RGBCube/serenity
synced 2025-05-19 23:25:08 +00:00
LibJS: Add BytecodeGenerator helpers for reference get/put
This allows code sharing between all AST nodes that want to get and/or put through a reference.
This commit is contained in:
parent
b63d17e2f8
commit
1dc60b028f
2 changed files with 64 additions and 0 deletions
|
@ -93,4 +93,65 @@ void Generator::end_breakable_scope()
|
|||
{
|
||||
m_breakable_scopes.take_last();
|
||||
}
|
||||
|
||||
void Generator::emit_load_from_reference(JS::ASTNode const& node)
|
||||
{
|
||||
if (is<Identifier>(node)) {
|
||||
auto& identifier = static_cast<Identifier const&>(node);
|
||||
emit<Bytecode::Op::GetVariable>(intern_identifier(identifier.string()));
|
||||
return;
|
||||
}
|
||||
if (is<MemberExpression>(node)) {
|
||||
auto& expression = static_cast<MemberExpression const&>(node);
|
||||
expression.object().generate_bytecode(*this);
|
||||
|
||||
auto object_reg = allocate_register();
|
||||
emit<Bytecode::Op::Store>(object_reg);
|
||||
|
||||
if (expression.is_computed()) {
|
||||
expression.property().generate_bytecode(*this);
|
||||
emit<Bytecode::Op::GetByValue>(object_reg);
|
||||
} else {
|
||||
auto identifier_table_ref = intern_identifier(verify_cast<Identifier>(expression.property()).string());
|
||||
emit<Bytecode::Op::GetById>(identifier_table_ref);
|
||||
}
|
||||
return;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void Generator::emit_store_to_reference(JS::ASTNode const& node)
|
||||
{
|
||||
if (is<Identifier>(node)) {
|
||||
auto& identifier = static_cast<Identifier const&>(node);
|
||||
emit<Bytecode::Op::SetVariable>(intern_identifier(identifier.string()));
|
||||
return;
|
||||
}
|
||||
if (is<MemberExpression>(node)) {
|
||||
// NOTE: The value is in the accumulator, so we have to store that away first.
|
||||
auto value_reg = allocate_register();
|
||||
emit<Bytecode::Op::Store>(value_reg);
|
||||
|
||||
auto& expression = static_cast<MemberExpression const&>(node);
|
||||
expression.object().generate_bytecode(*this);
|
||||
|
||||
auto object_reg = allocate_register();
|
||||
emit<Bytecode::Op::Store>(object_reg);
|
||||
|
||||
if (expression.is_computed()) {
|
||||
expression.property().generate_bytecode(*this);
|
||||
auto property_reg = allocate_register();
|
||||
emit<Bytecode::Op::Store>(property_reg);
|
||||
emit<Bytecode::Op::Load>(value_reg);
|
||||
emit<Bytecode::Op::PutByValue>(object_reg, property_reg);
|
||||
} else {
|
||||
emit<Bytecode::Op::Load>(value_reg);
|
||||
auto identifier_table_ref = intern_identifier(verify_cast<Identifier>(expression.property()).string());
|
||||
emit<Bytecode::Op::PutById>(object_reg, identifier_table_ref);
|
||||
}
|
||||
return;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue