mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 09:34:57 +09:00
LibJS: Add a TRY_OR_CLOSE_ITERATOR macro for IfAbruptCloseIterator
Behaves just like TRY_OR_REJECT for promises.
This commit is contained in:
parent
568524f8ba
commit
908349f8fe
Notes:
github-actions[bot]
2025-04-29 11:34:16 +00:00
Author: https://github.com/trflynn89
Commit: 908349f8fe
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4514
3 changed files with 25 additions and 20 deletions
|
@ -237,22 +237,16 @@ ThrowCompletionOr<GroupsType> group_by(VM& vm, Value items, Value callback_funct
|
|||
auto value = next.release_value();
|
||||
|
||||
// e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)).
|
||||
auto key = call(vm, callback_function, js_undefined(), value, Value(k));
|
||||
|
||||
// f. IfAbruptCloseIterator(key, iteratorRecord).
|
||||
if (key.is_error())
|
||||
return Completion { TRY(iterator_close(vm, iterator_record, key.release_error())) };
|
||||
auto key = TRY_OR_CLOSE_ITERATOR(vm, iterator_record, call(vm, callback_function, js_undefined(), value, Value(k)));
|
||||
|
||||
// g. If keyCoercion is property, then
|
||||
if constexpr (IsSame<KeyType, PropertyKey>) {
|
||||
// i. Set key to Completion(ToPropertyKey(key)).
|
||||
auto property_key = key.value().to_property_key(vm);
|
||||
|
||||
// ii. IfAbruptCloseIterator(key, iteratorRecord).
|
||||
if (property_key.is_error())
|
||||
return Completion { TRY(iterator_close(vm, iterator_record, property_key.release_error())) };
|
||||
auto property_key = TRY_OR_CLOSE_ITERATOR(vm, iterator_record, key.to_property_key(vm));
|
||||
|
||||
add_value_to_keyed_group(vm, groups, property_key.release_value(), value);
|
||||
add_value_to_keyed_group(vm, groups, move(property_key), value);
|
||||
}
|
||||
// h. Else,
|
||||
else {
|
||||
|
@ -260,9 +254,9 @@ ThrowCompletionOr<GroupsType> group_by(VM& vm, Value items, Value callback_funct
|
|||
static_assert(IsSame<KeyType, void>);
|
||||
|
||||
// ii. Set key to CanonicalizeKeyedCollectionKey(key).
|
||||
key = canonicalize_keyed_collection_key(key.value());
|
||||
key = canonicalize_keyed_collection_key(key);
|
||||
|
||||
add_value_to_keyed_group(vm, groups, make_root(key.release_value()), value);
|
||||
add_value_to_keyed_group(vm, groups, make_root(key), value);
|
||||
}
|
||||
|
||||
// i. Perform AddValueToKeyedGroup(groups, key, value).
|
||||
|
|
|
@ -214,12 +214,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
|||
// v. If mapping is true, then
|
||||
if (mapfn) {
|
||||
// 1. Let mappedValue be Completion(Call(mapfn, thisArg, « nextValue, 𝔽(k) »)).
|
||||
auto mapped_value_or_error = JS::call(vm, *mapfn, this_arg, next.release_value(), Value(k));
|
||||
|
||||
// 2. IfAbruptCloseIterator(mappedValue, iteratorRecord).
|
||||
if (mapped_value_or_error.is_error())
|
||||
return TRY(iterator_close(vm, iterator, mapped_value_or_error.release_error()));
|
||||
mapped_value = mapped_value_or_error.release_value();
|
||||
mapped_value = TRY_OR_CLOSE_ITERATOR(vm, iterator, JS::call(vm, *mapfn, this_arg, next.release_value(), Value(k)));
|
||||
}
|
||||
// vi. Else, let mappedValue be nextValue.
|
||||
else {
|
||||
|
@ -227,11 +223,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
|||
}
|
||||
|
||||
// vii. Let defineStatus be Completion(CreateDataPropertyOrThrow(A, Pk, mappedValue)).
|
||||
auto result_or_error = array->create_data_property_or_throw(property_key, mapped_value);
|
||||
|
||||
// viii. IfAbruptCloseIterator(defineStatus, iteratorRecord).
|
||||
if (result_or_error.is_error())
|
||||
return TRY(iterator_close(vm, iterator, result_or_error.release_error()));
|
||||
TRY_OR_CLOSE_ITERATOR(vm, iterator, array->create_data_property_or_throw(property_key, mapped_value));
|
||||
|
||||
// ix. Set k to k + 1.
|
||||
}
|
||||
|
|
|
@ -67,6 +67,24 @@ enum class PrimitiveHandling {
|
|||
RejectPrimitives,
|
||||
};
|
||||
|
||||
// 7.4.12 IfAbruptCloseIterator ( value, iteratorRecord ), https://tc39.es/ecma262/#sec-ifabruptcloseiterator
|
||||
#define TRY_OR_CLOSE_ITERATOR(vm, iterator_record, expression) \
|
||||
({ \
|
||||
auto&& _temporary_try_or_close_result = (expression); \
|
||||
\
|
||||
/* 1. Assert: value is a Completion Record. */ \
|
||||
/* 2. If value is an abrupt completion, return ? IteratorClose(iteratorRecord, value). */ \
|
||||
if (_temporary_try_or_close_result.is_error()) { \
|
||||
return iterator_close(vm, iterator_record, _temporary_try_or_close_result.release_error()); \
|
||||
} \
|
||||
\
|
||||
static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_try_or_close_result.release_value())>, \
|
||||
"Do not return a reference from a fallible expression"); \
|
||||
\
|
||||
/* 3. Else, set value to ! value. */ \
|
||||
_temporary_try_or_close_result.release_value(); \
|
||||
})
|
||||
|
||||
ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_direct(VM&, Object&);
|
||||
ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_from_method(VM&, Value, GC::Ref<FunctionObject>);
|
||||
ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator(VM&, Value, IteratorHint);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue