mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-01 16:58:52 +00:00
LibJS/Bytecode: Split SetVariable into four separate instructions
Instead of SetVariable having 2x2 modes for variable/lexical and initialize/set, those 4 modes are now separate instructions, which makes each instruction much less branchy.
This commit is contained in:
parent
640f195a70
commit
b7c04f999a
Notes:
sideshowbarker
2024-07-17 03:51:15 +09:00
Author: https://github.com/awesomekling
Commit: b7c04f999a
Pull-request: https://github.com/SerenityOS/serenity/pull/24324
8 changed files with 203 additions and 96 deletions
|
@ -39,7 +39,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
auto id = intern_identifier(parameter_name.key);
|
||||
emit<Op::CreateVariable>(id, Op::EnvironmentMode::Lexical, false);
|
||||
if (function.m_has_duplicates) {
|
||||
emit<Op::SetVariable>(id, add_constant(js_undefined()), Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Lexical);
|
||||
emit<Op::InitializeLexicalBinding>(id, add_constant(js_undefined()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,17 +87,18 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
set_local_initialized((*identifier)->local_variable_index());
|
||||
} else {
|
||||
auto id = intern_identifier((*identifier)->string());
|
||||
auto init_mode = function.m_has_duplicates ? Op::SetVariable::InitializationMode::Set : Op::SetVariable::InitializationMode::Initialize;
|
||||
auto argument_reg = allocate_register();
|
||||
emit<Op::GetArgument>(argument_reg.operand(), param_index);
|
||||
emit<Op::SetVariable>(id, argument_reg.operand(),
|
||||
init_mode,
|
||||
Op::EnvironmentMode::Lexical);
|
||||
if (function.m_has_duplicates) {
|
||||
emit<Op::SetLexicalBinding>(id, argument_reg.operand());
|
||||
} else {
|
||||
emit<Op::InitializeLexicalBinding>(id, argument_reg.operand());
|
||||
}
|
||||
}
|
||||
} else if (auto const* binding_pattern = parameter.binding.get_pointer<NonnullRefPtr<BindingPattern const>>(); binding_pattern) {
|
||||
auto input_operand = allocate_register();
|
||||
emit<Op::GetArgument>(input_operand.operand(), param_index);
|
||||
auto init_mode = function.m_has_duplicates ? Op::SetVariable::InitializationMode::Set : Bytecode::Op::SetVariable::InitializationMode::Initialize;
|
||||
auto init_mode = function.m_has_duplicates ? Op::BindingInitializationMode::Set : Bytecode::Op::BindingInitializationMode::Initialize;
|
||||
TRY((*binding_pattern)->generate_bytecode(*this, init_mode, input_operand, false));
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
} else {
|
||||
auto intern_id = intern_identifier(id.string());
|
||||
emit<Op::CreateVariable>(intern_id, Op::EnvironmentMode::Var, false);
|
||||
emit<Op::SetVariable>(intern_id, add_constant(js_undefined()), Bytecode::Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var);
|
||||
emit<Op::InitializeVariableBinding>(intern_id, add_constant(js_undefined()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +142,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
} else {
|
||||
auto intern_id = intern_identifier(id.string());
|
||||
emit<Op::CreateVariable>(intern_id, Op::EnvironmentMode::Var, false);
|
||||
emit<Op::SetVariable>(intern_id, initial_value, Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var);
|
||||
emit<Op::InitializeVariableBinding>(intern_id, initial_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
for (auto const& function_name : function.m_function_names_to_initialize_binding) {
|
||||
auto intern_id = intern_identifier(function_name);
|
||||
emit<Op::CreateVariable>(intern_id, Op::EnvironmentMode::Var, false);
|
||||
emit<Op::SetVariable>(intern_id, add_constant(js_undefined()), Bytecode::Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var);
|
||||
emit<Op::InitializeVariableBinding>(intern_id, add_constant(js_undefined()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +185,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
if (declaration.name_identifier()->is_local()) {
|
||||
emit<Op::Mov>(local(declaration.name_identifier()->local_variable_index()), function);
|
||||
} else {
|
||||
emit<Op::SetVariable>(intern_identifier(declaration.name()), function, Op::SetVariable::InitializationMode::Set, Op::EnvironmentMode::Var);
|
||||
emit<Op::SetVariableBinding>(intern_identifier(declaration.name()), function);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,7 +809,7 @@ CodeGenerationErrorOr<Optional<ScopedOperand>> Generator::emit_delete_reference(
|
|||
return add_constant(Value(true));
|
||||
}
|
||||
|
||||
void Generator::emit_set_variable(JS::Identifier const& identifier, ScopedOperand value, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Op::EnvironmentMode mode)
|
||||
void Generator::emit_set_variable(JS::Identifier const& identifier, ScopedOperand value, Bytecode::Op::BindingInitializationMode initialization_mode, Bytecode::Op::EnvironmentMode environment_mode)
|
||||
{
|
||||
if (identifier.is_local()) {
|
||||
if (value.operand().is_local() && value.operand().index() == identifier.local_variable_index()) {
|
||||
|
@ -817,7 +818,22 @@ void Generator::emit_set_variable(JS::Identifier const& identifier, ScopedOperan
|
|||
}
|
||||
emit<Bytecode::Op::Mov>(local(identifier.local_variable_index()), value);
|
||||
} else {
|
||||
emit<Bytecode::Op::SetVariable>(intern_identifier(identifier.string()), value, initialization_mode, mode);
|
||||
auto identifier_index = intern_identifier(identifier.string());
|
||||
if (environment_mode == Bytecode::Op::EnvironmentMode::Lexical) {
|
||||
if (initialization_mode == Bytecode::Op::BindingInitializationMode::Initialize) {
|
||||
emit<Bytecode::Op::InitializeLexicalBinding>(identifier_index, value);
|
||||
} else if (initialization_mode == Bytecode::Op::BindingInitializationMode::Set) {
|
||||
emit<Bytecode::Op::SetLexicalBinding>(identifier_index, value);
|
||||
}
|
||||
} else if (environment_mode == Bytecode::Op::EnvironmentMode::Var) {
|
||||
if (initialization_mode == Bytecode::Op::BindingInitializationMode::Initialize) {
|
||||
emit<Bytecode::Op::InitializeVariableBinding>(identifier_index, value);
|
||||
} else if (initialization_mode == Bytecode::Op::BindingInitializationMode::Set) {
|
||||
emit<Bytecode::Op::SetVariableBinding>(identifier_index, value);
|
||||
}
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue