1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 14:38:11 +00:00

LibJS: Convert get_iterator_values helper to ThrowCompletionOr

This one is a bit unusual, so to clarify:

Previously, callers of get_iterator_values() would supply a callback
that would return an IterationDecision, and an enum to indicate whether
iterator_close() should be invoked upon IterationDecision::Break.

Now, use of both those enums is removed, and callers must return an
Optional<Completion>. If a Completion is provided, the iterator will be
closed, and that completion will be returned from get_iterator_values.
Otherwise, once the iterator is exhausted, a default-initialized
Completion will be returned.
This commit is contained in:
Timothy Flynn 2021-10-20 12:10:23 -04:00 committed by Linus Groh
parent 7b4814f74c
commit 04b4307b3d
8 changed files with 74 additions and 135 deletions

View file

@ -251,13 +251,11 @@ static void argument_list_evaluation(Interpreter& interpreter, GlobalObject& glo
if (vm.exception())
return;
if (argument.is_spread) {
get_iterator_values(global_object, value, [&](Value iterator_value) {
if (vm.exception())
return IterationDecision::Break;
auto result = get_iterator_values(global_object, value, [&](Value iterator_value) -> Optional<Completion> {
list.append(iterator_value);
return IterationDecision::Continue;
return {};
});
if (vm.exception())
if (result.is_error())
return;
} else {
list.append(value);
@ -871,29 +869,24 @@ Value ForOfStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
interpreter.vm().running_execution_context().lexical_environment = old_environment;
});
get_iterator_values(global_object, rhs_result, [&](Value value) {
auto result = for_of_head_state.execute_head(interpreter, global_object, value);
if (result.is_error())
return IterationDecision::Break;
TRY_OR_DISCARD(get_iterator_values(global_object, rhs_result, [&](Value value) -> Optional<Completion> {
TRY(for_of_head_state.execute_head(interpreter, global_object, value));
last_value = m_body->execute(interpreter, global_object).value_or(last_value);
interpreter.vm().running_execution_context().lexical_environment = old_environment;
if (interpreter.exception())
return IterationDecision::Break;
if (auto* exception = interpreter.exception())
return throw_completion(exception->value());
if (interpreter.vm().should_unwind()) {
if (interpreter.vm().should_unwind_until(ScopeType::Continuable, m_labels)) {
interpreter.vm().stop_unwind();
} else if (interpreter.vm().should_unwind_until(ScopeType::Breakable, m_labels)) {
interpreter.vm().stop_unwind();
return IterationDecision::Break;
return normal_completion(last_value);
} else {
return IterationDecision::Break;
return normal_completion(last_value);
}
}
return IterationDecision::Continue;
});
if (interpreter.exception())
return {};
}));
return last_value;
}
@ -2885,12 +2878,10 @@ Value ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
return {};
if (is<SpreadExpression>(*element)) {
get_iterator_values(global_object, value, [&](Value iterator_value) {
TRY_OR_DISCARD(get_iterator_values(global_object, value, [&](Value iterator_value) -> Optional<Completion> {
array->indexed_properties().put(index++, iterator_value, default_attributes);
return IterationDecision::Continue;
});
if (interpreter.exception())
return {};
}));
continue;
}
}