mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
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:
parent
3d4b13a01c
commit
1e361db3f3
2 changed files with 0 additions and 247 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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&);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue