LibJS: Remove VM::binding_initialization()

This function was used for function params initialization but no longer
used after it got replaced by emitting bytecode.
This commit is contained in:
Aliaksandr Kalenik 2024-05-09 16:35:11 +02:00 committed by Andreas Kling
parent 3d4b13a01c
commit 1e361db3f3
2 changed files with 0 additions and 247 deletions

View file

@ -238,55 +238,6 @@ ThrowCompletionOr<Value> VM::named_evaluation_if_anonymous_function(ASTNode cons
return execute_ast_node(expression);
}
// 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
ThrowCompletionOr<void> VM::binding_initialization(DeprecatedFlyString const& target, Value value, Environment* environment)
{
// 1. Let name be StringValue of Identifier.
// 2. Return ? InitializeBoundName(name, value, environment).
return initialize_bound_name(*this, target, value, environment);
}
// 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern const> const& target, Value value, Environment* environment)
{
auto& vm = *this;
// BindingPattern : ObjectBindingPattern
if (target->kind == BindingPattern::Kind::Object) {
// 1. Perform ? RequireObjectCoercible(value).
TRY(require_object_coercible(vm, value));
// 2. Return ? BindingInitialization of ObjectBindingPattern with arguments value and environment.
// BindingInitialization of ObjectBindingPattern
// 1. Perform ? PropertyBindingInitialization of BindingPropertyList with arguments value and environment.
TRY(property_binding_initialization(*target, value, environment));
// 2. Return unused.
return {};
}
// BindingPattern : ArrayBindingPattern
else {
// 1. Let iteratorRecord be ? GetIterator(value, sync).
auto iterator_record = TRY(get_iterator(vm, value, IteratorHint::Sync));
// 2. Let result be Completion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment).
auto result = iterator_binding_initialization(*target, iterator_record, environment);
// 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
if (!iterator_record->done) {
// iterator_close() always returns a Completion, which ThrowCompletionOr will interpret as a throw
// completion. So only return the result of iterator_close() if it is indeed a throw completion.
auto completion = result.is_throw_completion() ? result.release_error() : normal_completion({});
if (completion = iterator_close(vm, iterator_record, move(completion)); completion.is_error())
return completion.release_error();
}
// 4. Return ? result.
return result;
}
}
ThrowCompletionOr<Value> VM::execute_ast_node(ASTNode const& node)
{
// FIXME: This function should be gone once we will emit bytecode for everything before executing instructions.
@ -309,198 +260,6 @@ ThrowCompletionOr<Value> VM::execute_ast_node(ASTNode const& node)
return result_or_error.return_register_value;
}
// 13.15.5.3 Runtime Semantics: PropertyDestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation
// 14.3.3.1 Runtime Semantics: PropertyBindingInitialization, https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment)
{
auto& vm = *this;
auto& realm = *vm.current_realm();
auto object = TRY(value.to_object(vm));
HashTable<PropertyKey> seen_names;
for (auto& property : binding.entries) {
VERIFY(!property.is_elision());
if (property.is_rest) {
Reference assignment_target;
if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier const>>()) {
assignment_target = TRY(resolve_binding((*identifier_ptr)->string(), environment));
} else {
VERIFY_NOT_REACHED();
}
auto rest_object = Object::create(realm, realm.intrinsics().object_prototype());
VERIFY(rest_object);
TRY(rest_object->copy_data_properties(vm, object, seen_names));
if (!environment)
return assignment_target.put_value(vm, rest_object);
else
return assignment_target.initialize_referenced_binding(vm, rest_object);
}
auto name = TRY(property.name.visit(
[&](Empty) -> ThrowCompletionOr<PropertyKey> { VERIFY_NOT_REACHED(); },
[&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<PropertyKey> {
return identifier->string();
},
[&](NonnullRefPtr<Expression const> const& expression) -> ThrowCompletionOr<PropertyKey> {
auto result = TRY(execute_ast_node(*expression));
return result.to_property_key(vm);
}));
seen_names.set(name);
if (property.name.has<NonnullRefPtr<Identifier const>>() && property.alias.has<Empty>()) {
// FIXME: this branch and not taking this have a lot in common we might want to unify it more (like it was before).
auto& identifier = *property.name.get<NonnullRefPtr<Identifier const>>();
auto reference = TRY(resolve_binding(identifier.string(), environment));
auto value_to_assign = TRY(object->get(name));
if (property.initializer && value_to_assign.is_undefined()) {
value_to_assign = TRY(named_evaluation_if_anonymous_function(*property.initializer, identifier.string()));
}
if (!environment)
TRY(reference.put_value(vm, value_to_assign));
else
TRY(reference.initialize_referenced_binding(vm, value_to_assign));
continue;
}
auto reference_to_assign_to = TRY(property.alias.visit(
[&](Empty) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(resolve_binding(identifier->string(), environment));
},
[&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression const> const&) -> ThrowCompletionOr<Optional<Reference>> {
VERIFY_NOT_REACHED();
}));
auto value_to_assign = TRY(object->get(name));
if (property.initializer && value_to_assign.is_undefined()) {
if (auto* identifier_ptr = property.alias.get_pointer<NonnullRefPtr<Identifier const>>())
value_to_assign = TRY(named_evaluation_if_anonymous_function(*property.initializer, (*identifier_ptr)->string()));
else
value_to_assign = TRY(execute_ast_node(*property.initializer));
}
if (auto* binding_ptr = property.alias.get_pointer<NonnullRefPtr<BindingPattern const>>()) {
TRY(binding_initialization(*binding_ptr, value_to_assign, environment));
} else {
VERIFY(reference_to_assign_to.has_value());
if (!environment)
TRY(reference_to_assign_to->put_value(vm, value_to_assign));
else
TRY(reference_to_assign_to->initialize_referenced_binding(vm, value_to_assign));
}
}
return {};
}
// 13.15.5.5 Runtime Semantics: IteratorDestructuringAssignmentEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-iteratordestructuringassignmentevaluation
// 8.5.3 Runtime Semantics: IteratorBindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-iteratorbindinginitialization
ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const& binding, IteratorRecord& iterator_record, Environment* environment)
{
auto& vm = *this;
auto& realm = *vm.current_realm();
// FIXME: this method is nearly identical to destructuring assignment!
for (size_t i = 0; i < binding.entries.size(); i++) {
auto& entry = binding.entries[i];
Value value;
auto assignment_target = TRY(entry.alias.visit(
[&](Empty) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<Identifier const> const& identifier) -> ThrowCompletionOr<Optional<Reference>> {
return TRY(resolve_binding(identifier->string(), environment));
},
[&](NonnullRefPtr<BindingPattern const> const&) -> ThrowCompletionOr<Optional<Reference>> { return Optional<Reference> {}; },
[&](NonnullRefPtr<MemberExpression const> const&) -> ThrowCompletionOr<Optional<Reference>> {
VERIFY_NOT_REACHED();
}));
// BindingRestElement : ... BindingIdentifier
// BindingRestElement : ... BindingPattern
if (entry.is_rest) {
VERIFY(i == binding.entries.size() - 1);
// 2. Let A be ! ArrayCreate(0).
auto array = MUST(Array::create(realm, 0));
// 3. Let n be 0.
// 4. Repeat,
while (true) {
// a. Let next be DONE.
Optional<Value> next;
// b. If iteratorRecord.[[Done]] is false, then
if (!iterator_record.done) {
// i. Set next to ? IteratorStepValue(iteratorRecord).
next = TRY(iterator_step_value(vm, iterator_record));
}
// c. If next is DONE, then
if (!next.has_value()) {
// NOTE: Step i. and ii. are handled below.
break;
}
// d. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next).
array->indexed_properties().append(next.release_value());
// e. Set n to n + 1.
}
value = array;
}
// SingleNameBinding : BindingIdentifier Initializer[opt]
// BindingElement : BindingPattern Initializer[opt]
else {
// 1. Let v be undefined.
value = js_undefined();
// 2. If iteratorRecord.[[Done]] is false, then
if (!iterator_record.done) {
// a. Let next be ? IteratorStepValue(iteratorRecord).
auto next = TRY(iterator_step_value(vm, iterator_record));
// b. If next is not DONE, then
if (next.has_value()) {
// i. Set v to next.
value = next.release_value();
}
}
// NOTE: Step 3. and 4. are handled below.
}
if (value.is_undefined() && entry.initializer) {
VERIFY(!entry.is_rest);
if (auto* identifier_ptr = entry.alias.get_pointer<NonnullRefPtr<Identifier const>>())
value = TRY(named_evaluation_if_anonymous_function(*entry.initializer, (*identifier_ptr)->string()));
else
value = TRY(execute_ast_node(*entry.initializer));
}
if (auto* binding_ptr = entry.alias.get_pointer<NonnullRefPtr<BindingPattern const>>()) {
TRY(binding_initialization(*binding_ptr, value, environment));
} else if (!entry.alias.has<Empty>()) {
VERIFY(assignment_target.has_value());
if (!environment)
TRY(assignment_target->put_value(vm, value));
else
TRY(assignment_target->initialize_referenced_binding(vm, value));
}
}
return {};
}
// 9.1.2.1 GetIdentifierReference ( env, name, strict ), https://tc39.es/ecma262/#sec-getidentifierreference
ThrowCompletionOr<Reference> VM::get_identifier_reference(Environment* environment, DeprecatedFlyString name, bool strict, size_t hops)
{

View file

@ -226,9 +226,6 @@ public:
CustomData* custom_data() { return m_custom_data; }
ThrowCompletionOr<void> binding_initialization(DeprecatedFlyString const& target, Value value, Environment* environment);
ThrowCompletionOr<void> binding_initialization(NonnullRefPtr<BindingPattern const> const& target, Value value, Environment* environment);
ThrowCompletionOr<Value> named_evaluation_if_anonymous_function(ASTNode const& expression, DeprecatedFlyString const& name);
void save_execution_context_stack();
@ -281,9 +278,6 @@ private:
VM(OwnPtr<CustomData>, ErrorMessages);
ThrowCompletionOr<void> property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment);
ThrowCompletionOr<void> iterator_binding_initialization(BindingPattern const& binding, IteratorRecord& iterator_record, Environment* environment);
void load_imported_module(ImportedModuleReferrer, ModuleRequest const&, GCPtr<GraphLoadingState::HostDefined>, ImportedModulePayload);
ThrowCompletionOr<void> link_and_eval_module(CyclicModule&);