mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 19:35:09 +00:00
LibJS/Bytecode: Support destructuring in try..catch
112 new passes in test262.
This commit is contained in:
parent
3d755a57b6
commit
4fd71e3c3a
1 changed files with 29 additions and 20 deletions
|
@ -353,7 +353,7 @@ Bytecode::CodeGenerationErrorOr<void> SuperCall::generate_bytecode(Bytecode::Gen
|
|||
return {};
|
||||
}
|
||||
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode, Bytecode::Register const& value_reg);
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode, Bytecode::Register const& value_reg, bool create_variables);
|
||||
|
||||
Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(Bytecode::Generator& generator) const
|
||||
{
|
||||
|
@ -450,7 +450,7 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
|
|||
generator.emit<Bytecode::Op::Store>(value_register);
|
||||
|
||||
// 5. Perform ? DestructuringAssignmentEvaluation of assignmentPattern with argument rval.
|
||||
TRY(generate_binding_pattern_bytecode(generator, pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register));
|
||||
TRY(generate_binding_pattern_bytecode(generator, pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register, false));
|
||||
|
||||
// 6. Return rval.
|
||||
generator.emit<Bytecode::Op::Load>(value_register);
|
||||
|
@ -991,7 +991,7 @@ Bytecode::CodeGenerationErrorOr<void> FunctionExpression::generate_bytecode(Byte
|
|||
return generate_bytecode_with_lhs_name(generator, {});
|
||||
}
|
||||
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg)
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables)
|
||||
{
|
||||
Vector<Bytecode::Register> excluded_property_names;
|
||||
auto has_rest = false;
|
||||
|
@ -1008,6 +1008,8 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
|
|||
auto interned_identifier = generator.intern_identifier(identifier);
|
||||
|
||||
generator.emit_with_extra_register_slots<Bytecode::Op::CopyObjectExcludingProperties>(excluded_property_names.size(), value_reg, excluded_property_names);
|
||||
if (create_variables)
|
||||
generator.emit<Bytecode::Op::CreateVariable>(interned_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
|
||||
generator.emit<Bytecode::Op::SetVariable>(interned_identifier, initialization_mode);
|
||||
|
||||
return {};
|
||||
|
@ -1066,7 +1068,7 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
|
|||
auto& binding_pattern = *alias.get<NonnullRefPtr<BindingPattern const>>();
|
||||
auto nested_value_reg = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Store>(nested_value_reg);
|
||||
TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg));
|
||||
TRY(generate_binding_pattern_bytecode(generator, binding_pattern, initialization_mode, nested_value_reg, create_variables));
|
||||
} else if (alias.has<Empty>()) {
|
||||
if (name.has<NonnullRefPtr<Expression const>>()) {
|
||||
// This needs some sort of SetVariableByValue opcode, as it's a runtime binding
|
||||
|
@ -1077,16 +1079,22 @@ static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_byt
|
|||
}
|
||||
|
||||
auto& identifier = name.get<NonnullRefPtr<Identifier const>>()->string();
|
||||
generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier), initialization_mode);
|
||||
auto identifier_ref = generator.intern_identifier(identifier);
|
||||
if (create_variables)
|
||||
generator.emit<Bytecode::Op::CreateVariable>(identifier_ref, Bytecode::Op::EnvironmentMode::Lexical, false);
|
||||
generator.emit<Bytecode::Op::SetVariable>(identifier_ref, initialization_mode);
|
||||
} else {
|
||||
auto& identifier = alias.get<NonnullRefPtr<Identifier const>>()->string();
|
||||
generator.emit<Bytecode::Op::SetVariable>(generator.intern_identifier(identifier), initialization_mode);
|
||||
auto identifier_ref = generator.intern_identifier(identifier);
|
||||
if (create_variables)
|
||||
generator.emit<Bytecode::Op::CreateVariable>(identifier_ref, Bytecode::Op::EnvironmentMode::Lexical, false);
|
||||
generator.emit<Bytecode::Op::SetVariable>(identifier_ref, initialization_mode);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg)
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables)
|
||||
{
|
||||
/*
|
||||
* Consider the following destructuring assignment:
|
||||
|
@ -1127,6 +1135,8 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
|
|||
},
|
||||
[&](NonnullRefPtr<Identifier const> const& identifier) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||
auto interned_index = generator.intern_identifier(identifier->string());
|
||||
if (create_variables)
|
||||
generator.emit<Bytecode::Op::CreateVariable>(interned_index, Bytecode::Op::EnvironmentMode::Lexical, false);
|
||||
generator.emit<Bytecode::Op::SetVariable>(interned_index, initialization_mode);
|
||||
return {};
|
||||
},
|
||||
|
@ -1134,7 +1144,7 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
|
|||
// Store the accumulator value in a permanent register
|
||||
auto target_reg = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Store>(target_reg);
|
||||
return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, target_reg);
|
||||
return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, target_reg, create_variables);
|
||||
},
|
||||
[&](NonnullRefPtr<MemberExpression const> const& expr) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||
return generator.emit_store_to_reference(*expr);
|
||||
|
@ -1263,12 +1273,12 @@ static Bytecode::CodeGenerationErrorOr<void> generate_array_binding_pattern_byte
|
|||
return {};
|
||||
}
|
||||
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg)
|
||||
static Bytecode::CodeGenerationErrorOr<void> generate_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables)
|
||||
{
|
||||
if (pattern.kind == BindingPattern::Kind::Object)
|
||||
return generate_object_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg);
|
||||
return generate_object_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg, create_variables);
|
||||
|
||||
return generate_array_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg);
|
||||
return generate_array_binding_pattern_bytecode(generator, pattern, initialization_mode, value_reg, create_variables);
|
||||
}
|
||||
|
||||
static Bytecode::CodeGenerationErrorOr<void> assign_accumulator_to_variable_declarator(Bytecode::Generator& generator, VariableDeclarator const& declarator, VariableDeclaration const& declaration)
|
||||
|
@ -1283,7 +1293,7 @@ static Bytecode::CodeGenerationErrorOr<void> assign_accumulator_to_variable_decl
|
|||
[&](NonnullRefPtr<BindingPattern const> const& pattern) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||
auto value_register = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Store>(value_register);
|
||||
return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value_register);
|
||||
return generate_binding_pattern_bytecode(generator, pattern, initialization_mode, value_register, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2051,12 +2061,11 @@ Bytecode::CodeGenerationErrorOr<void> TryStatement::generate_bytecode(Bytecode::
|
|||
}
|
||||
return {};
|
||||
},
|
||||
[&](NonnullRefPtr<BindingPattern const> const&) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||
// FIXME: Implement this path when the above DeclarativeEnvironment issue is dealt with.
|
||||
return Bytecode::CodeGenerationError {
|
||||
this,
|
||||
"Unimplemented catch argument: BindingPattern"sv,
|
||||
};
|
||||
[&](NonnullRefPtr<BindingPattern const> const& binding_pattern) -> Bytecode::CodeGenerationErrorOr<void> {
|
||||
auto value_register = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Store>(value_register);
|
||||
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Initialize, value_register, true));
|
||||
return {};
|
||||
}));
|
||||
|
||||
TRY(m_handler->body().generate_bytecode(generator));
|
||||
|
@ -2457,7 +2466,7 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
|
|||
auto& binding_pattern = lhs.get<NonnullRefPtr<BindingPattern const>>();
|
||||
auto value_register = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Store>(value_register);
|
||||
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register));
|
||||
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Set, value_register, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2534,7 +2543,7 @@ static Bytecode::CodeGenerationErrorOr<void> for_in_of_body_evaluation(Bytecode:
|
|||
|
||||
auto value_register = generator.allocate_register();
|
||||
generator.emit<Bytecode::Op::Store>(value_register);
|
||||
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, head_result.lhs_kind == LHSKind::VarBinding ? Bytecode::Op::SetVariable::InitializationMode::Set : Bytecode::Op::SetVariable::InitializationMode::Initialize, value_register));
|
||||
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, head_result.lhs_kind == LHSKind::VarBinding ? Bytecode::Op::SetVariable::InitializationMode::Set : Bytecode::Op::SetVariable::InitializationMode::Initialize, value_register, false));
|
||||
} else {
|
||||
return Bytecode::CodeGenerationError {
|
||||
&node,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue