1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 21:47:43 +00:00

LibJS: Make GetIterator's hint parameter required

This is an editorial change in the ECMA-262 spec. See:
2562811
This commit is contained in:
Timothy Flynn 2023-07-18 14:52:21 -04:00 committed by Andreas Kling
parent 5703833116
commit 1760361304
7 changed files with 25 additions and 26 deletions

View file

@ -1295,7 +1295,7 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Vector
auto rhs_result = for_of_head_state.rhs_value; auto rhs_result = for_of_head_state.rhs_value;
// NOTE: Perform step 7 from ForIn/OfHeadEvaluation. And since this is always async we only have to do step 7.d. // NOTE: Perform step 7 from ForIn/OfHeadEvaluation. And since this is always async we only have to do step 7.d.
// d. Return ? GetIterator(exprValue, iteratorHint). // d. Return ? GetIterator(exprValue, iteratorKind).
auto iterator = TRY(get_iterator(vm, rhs_result, IteratorHint::Async)); auto iterator = TRY(get_iterator(vm, rhs_result, IteratorHint::Async));
// 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset

View file

@ -2669,12 +2669,12 @@ static Bytecode::CodeGenerationErrorOr<ForInOfHeadEvaluationResult> for_in_of_he
// 7. Else, // 7. Else,
else { else {
// a. Assert: iterationKind is iterate or async-iterate. // a. Assert: iterationKind is iterate or async-iterate.
// b. If iterationKind is async-iterate, let iteratorHint be async. // b. If iterationKind is async-iterate, let iteratorKind be async.
// c. Else, let iteratorHint be sync. // c. Else, let iteratorKind be sync.
auto iterator_hint = iteration_kind == IterationKind::AsyncIterate ? IteratorHint::Async : IteratorHint::Sync; auto iterator_kind = iteration_kind == IterationKind::AsyncIterate ? IteratorHint::Async : IteratorHint::Sync;
// d. Return ? GetIterator(exprValue, iteratorHint). // d. Return ? GetIterator(exprValue, iteratorKind).
generator.emit<Bytecode::Op::GetIterator>(iterator_hint); generator.emit<Bytecode::Op::GetIterator>(iterator_kind);
} }
return result; return result;

View file

@ -226,7 +226,8 @@ ThrowCompletionOr<GroupsType> group_by(VM& vm, Value items, Value callback_funct
GroupsType groups; GroupsType groups;
// 4. Let iteratorRecord be ? GetIterator(items). // 4. Let iteratorRecord be ? GetIterator(items).
auto iterator_record = TRY(get_iterator(vm, items)); // FIXME: The Array Grouping proposal is out of date - the `kind` parameter is now required.
auto iterator_record = TRY(get_iterator(vm, items, IteratorHint::Sync));
// 5. Let k be 0. // 5. Let k be 0.
u64 k = 0; u64 k = 0;

View file

@ -34,15 +34,13 @@ ThrowCompletionOr<IteratorRecord> get_iterator_from_method(VM& vm, Value object,
return iterator_record; return iterator_record;
} }
// 7.4.3 GetIterator ( obj [ , hint ] ), https://tc39.es/ecma262/#sec-getiterator // 7.4.3 GetIterator ( obj, kind ), https://tc39.es/ecma262/#sec-getiterator
ThrowCompletionOr<IteratorRecord> get_iterator(VM& vm, Value object, IteratorHint hint) ThrowCompletionOr<IteratorRecord> get_iterator(VM& vm, Value object, IteratorHint kind)
{ {
JS::GCPtr<FunctionObject> method; JS::GCPtr<FunctionObject> method;
// 1. If hint is not present, set hint to sync. // 1. If kind is async, then
if (kind == IteratorHint::Async) {
// 2. If hint is async, then
if (hint == IteratorHint::Async) {
// a. Let method be ? GetMethod(obj, @@asyncIterator). // a. Let method be ? GetMethod(obj, @@asyncIterator).
method = TRY(object.get_method(vm, vm.well_known_symbol_async_iterator())); method = TRY(object.get_method(vm, vm.well_known_symbol_async_iterator()));
@ -62,7 +60,7 @@ ThrowCompletionOr<IteratorRecord> get_iterator(VM& vm, Value object, IteratorHin
return create_async_from_sync_iterator(vm, sync_iterator_record); return create_async_from_sync_iterator(vm, sync_iterator_record);
} }
} }
// 3. Else, // 2. Else,
else { else {
// a. Let method be ? GetMethod(obj, @@iterator). // a. Let method be ? GetMethod(obj, @@iterator).
method = TRY(object.get_method(vm, vm.well_known_symbol_iterator())); method = TRY(object.get_method(vm, vm.well_known_symbol_iterator()));
@ -72,7 +70,7 @@ ThrowCompletionOr<IteratorRecord> get_iterator(VM& vm, Value object, IteratorHin
if (!method) if (!method)
return vm.throw_completion<TypeError>(ErrorType::NotIterable, TRY_OR_THROW_OOM(vm, object.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotIterable, TRY_OR_THROW_OOM(vm, object.to_string_without_side_effects()));
// 4. Return ? GetIteratorFromMethod(obj, method). // 3. Return ? GetIteratorFromMethod(obj, method).
return TRY(get_iterator_from_method(vm, object, *method)); return TRY(get_iterator_from_method(vm, object, *method));
} }

View file

@ -23,7 +23,7 @@ enum class IteratorHint {
}; };
ThrowCompletionOr<IteratorRecord> get_iterator_from_method(VM&, Value, NonnullGCPtr<FunctionObject>); ThrowCompletionOr<IteratorRecord> get_iterator_from_method(VM&, Value, NonnullGCPtr<FunctionObject>);
ThrowCompletionOr<IteratorRecord> get_iterator(VM&, Value, IteratorHint = IteratorHint::Sync); ThrowCompletionOr<IteratorRecord> get_iterator(VM&, Value, IteratorHint);
ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord const&, Optional<Value> = {}); ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord const&, Optional<Value> = {});
ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord const&); ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord const&);
ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result); ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result);

View file

@ -324,9 +324,9 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
// 4. IfAbruptRejectPromise(promiseResolve, promiseCapability). // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor)); auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0), IteratorHint::Sync));
// 7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_all(vm, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_all(vm, iterator_record, constructor, promise_capability, promise_resolve);
@ -358,9 +358,9 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
// 4. IfAbruptRejectPromise(promiseResolve, promiseCapability). // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor)); auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0), IteratorHint::Sync));
// 7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_all_settled(vm, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_all_settled(vm, iterator_record, constructor, promise_capability, promise_resolve);
@ -392,9 +392,9 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
// 4. IfAbruptRejectPromise(promiseResolve, promiseCapability). // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor)); auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0), IteratorHint::Sync));
// 7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_any(vm, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_any(vm, iterator_record, constructor, promise_capability, promise_resolve);
@ -426,9 +426,9 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
// 4. IfAbruptRejectPromise(promiseResolve, promiseCapability). // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor)); auto promise_resolve = TRY_OR_REJECT(vm, promise_capability, get_promise_resolve(vm, constructor));
// 5. Let iteratorRecord be Completion(GetIterator(iterable)). // 5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
// 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability). // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0))); auto iterator_record = TRY_OR_REJECT(vm, promise_capability, get_iterator(vm, vm.argument(0), IteratorHint::Sync));
// 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)). // 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
auto result = perform_promise_race(vm, iterator_record, constructor, promise_capability, promise_resolve); auto result = perform_promise_race(vm, iterator_record, constructor, promise_capability, promise_resolve);

View file

@ -337,8 +337,8 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern
} }
// BindingPattern : ArrayBindingPattern // BindingPattern : ArrayBindingPattern
else { else {
// 1. Let iteratorRecord be ? GetIterator(value). // 1. Let iteratorRecord be ? GetIterator(value, sync).
auto iterator_record = TRY(get_iterator(vm, value)); auto iterator_record = TRY(get_iterator(vm, value, IteratorHint::Sync));
// 2. Let result be Completion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment). // 2. Let result be Completion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment).
auto result = iterator_binding_initialization(*target, iterator_record, environment); auto result = iterator_binding_initialization(*target, iterator_record, environment);