diff options
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp | 30 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/IteratorOperations.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/VM.cpp | 16 |
4 files changed, 31 insertions, 30 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 58a0a96b03..5dc4201ee5 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -144,9 +144,10 @@ void IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const size_t index = 0; while (true) { - auto iterator_result = iterator_next(*iterator); - if (!iterator_result) + auto iterator_result_or_error = iterator_next(*iterator); + if (iterator_result_or_error.is_error()) return; + auto* iterator_result = iterator_result_or_error.release_value(); auto complete = iterator_complete(global_object, *iterator_result); if (vm.exception()) @@ -490,7 +491,13 @@ void IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const if (object_or_error.is_error()) return; auto* object = object_or_error.release_value(); - interpreter.accumulator() = iterator_next(*object); + + auto iterator_result_or_error = iterator_next(*object); + if (iterator_result_or_error.is_error()) + return; + auto* iterator_result = iterator_result_or_error.release_value(); + + interpreter.accumulator() = iterator_result; } void IteratorResultDone::execute_impl(Bytecode::Interpreter& interpreter) const diff --git a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp index c465b550ee..2dfdeac91e 100644 --- a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp @@ -34,29 +34,24 @@ ThrowCompletionOr<Object*> get_iterator(GlobalObject& global_object, Value value } // 7.4.2 IteratorNext ( iteratorRecord [ , value ] ), https://tc39.es/ecma262/#sec-iteratornext -Object* iterator_next(Object& iterator, Value value) +ThrowCompletionOr<Object*> iterator_next(Object& iterator, Value value) { // FIXME: Implement using iterator records, not ordinary objects auto& vm = iterator.vm(); auto& global_object = iterator.global_object(); - auto next_method = TRY_OR_DISCARD(iterator.get(vm.names.next)); - - if (!next_method.is_function()) { - vm.throw_exception<TypeError>(global_object, ErrorType::IterableNextNotAFunction); - return nullptr; - } + auto next_method = TRY(iterator.get(vm.names.next)); + if (!next_method.is_function()) + return vm.throw_completion<TypeError>(global_object, ErrorType::IterableNextNotAFunction); Value result; if (value.is_empty()) - result = TRY_OR_DISCARD(vm.call(next_method.as_function(), &iterator)); + result = TRY(vm.call(next_method.as_function(), &iterator)); else - result = TRY_OR_DISCARD(vm.call(next_method.as_function(), &iterator, value)); + result = TRY(vm.call(next_method.as_function(), &iterator, value)); - if (!result.is_object()) { - vm.throw_exception<TypeError>(global_object, ErrorType::IterableNextBadReturn); - return nullptr; - } + if (!result.is_object()) + return vm.throw_completion<TypeError>(global_object, ErrorType::IterableNextBadReturn); return &result.as_object(); } @@ -84,9 +79,7 @@ Object* iterator_step(GlobalObject& global_object, Object& iterator) { auto& vm = global_object.vm(); - auto result = iterator_next(iterator); - if (vm.exception()) - return {}; + auto result = TRY_OR_DISCARD(iterator_next(iterator)); auto done = iterator_complete(global_object, *result); if (vm.exception()) @@ -176,9 +169,10 @@ void get_iterator_values(GlobalObject& global_object, Value value, Function<Iter auto* iterator = iterator_or_error.release_value(); while (true) { - auto next_object = iterator_next(*iterator); - if (!next_object) + auto next_object_or_error = iterator_next(*iterator); + if (next_object_or_error.is_error()) return; + auto* next_object = next_object_or_error.release_value(); auto done_property_or_error = next_object->get(vm.names.done); if (done_property_or_error.is_error()) diff --git a/Userland/Libraries/LibJS/Runtime/IteratorOperations.h b/Userland/Libraries/LibJS/Runtime/IteratorOperations.h index b77d46909c..d53ef65339 100644 --- a/Userland/Libraries/LibJS/Runtime/IteratorOperations.h +++ b/Userland/Libraries/LibJS/Runtime/IteratorOperations.h @@ -20,7 +20,7 @@ enum class IteratorHint { }; ThrowCompletionOr<Object*> get_iterator(GlobalObject&, Value value, IteratorHint hint = IteratorHint::Sync, Value method = {}); -Object* iterator_next(Object& iterator, Value value = {}); +ThrowCompletionOr<Object*> iterator_next(Object& iterator, Value value = {}); Object* iterator_step(GlobalObject&, Object& iterator); bool iterator_complete(GlobalObject&, Object& iterator_result); Value iterator_value(GlobalObject&, Object& iterator_result); diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 22b9e5cef9..5e8dc951a8 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -359,12 +359,12 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const auto* array = Array::create(global_object, 0); while (!iterator_done) { - auto next_object = iterator_next(*iterator); - if (!next_object) { + auto next_object_or_error = iterator_next(*iterator); + if (next_object_or_error.is_throw_completion()) { iterator_done = true; - VERIFY(exception()); - return JS::throw_completion(exception()->value()); + return JS::throw_completion(next_object_or_error.release_error().value()); } + auto* next_object = next_object_or_error.release_value(); auto done_property = TRY(next_object->get(names.done)); if (done_property.to_boolean()) { @@ -378,12 +378,12 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const value = array; } else if (!iterator_done) { - auto next_object = iterator_next(*iterator); - if (!next_object) { + auto next_object_or_error = iterator_next(*iterator); + if (next_object_or_error.is_throw_completion()) { iterator_done = true; - VERIFY(exception()); - return JS::throw_completion(exception()->value()); + return JS::throw_completion(next_object_or_error.release_error().value()); } + auto* next_object = next_object_or_error.release_value(); auto done_property = TRY(next_object->get(names.done)); if (done_property.to_boolean()) { |