diff options
author | kisbg <kisbg@inf.u-szeged.hu> | 2021-03-22 12:42:20 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-22 12:42:20 +0100 |
commit | 22ebb00a4c7b1e5920facb0c49c01d96e7622ac5 (patch) | |
tree | 2d35565dea21f66e298074fc6cd04815a0f7c4e9 | |
parent | edd2f203974acc9ddfbad9998c29bdc40ccc0719 (diff) |
Implement Promise.any and AggregateError Object (#4623)
JerryScript-DCO-1.0-Signed-off-by: Bence Gabor Kis kisbg@inf.u-szeged.hu
25 files changed, 737 insertions, 167 deletions
diff --git a/jerry-core/CMakeLists.txt b/jerry-core/CMakeLists.txt index 5d9d00cd..d5091ae0 100644 --- a/jerry-core/CMakeLists.txt +++ b/jerry-core/CMakeLists.txt @@ -145,6 +145,8 @@ set(SOURCE_CORE_FILES ecma/base/ecma-literal-storage.c ecma/base/ecma-module.c ecma/base/ecma-property-hashmap.c + ecma/builtin-objects/ecma-builtin-aggregateerror.c + ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.c ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.c ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -333,6 +335,8 @@ if(ENABLE_AMALGAM) ecma/base/ecma-literal-storage.h ecma/base/ecma-module.h ecma/base/ecma-property-hashmap.h + ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.inc.h + ecma/builtin-objects/ecma-builtin-aggregateerror.inc.h ecma/builtin-objects/ecma-builtin-array-iterator-prototype.inc.h ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.inc.h ecma/builtin-objects/ecma-builtin-array-prototype.inc.h diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 0f398ff0..ea67ce6a 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -62,6 +62,10 @@ JERRY_STATIC_ASSERT ((int) ECMA_ERROR_NONE == (int) JERRY_ERROR_NONE && (int) ECMA_ERROR_TYPE == (int) JERRY_ERROR_TYPE && (int) ECMA_ERROR_URI == (int) JERRY_ERROR_URI, ecma_standard_error_t_must_be_equal_to_jerry_error_t); +#if JERRY_BUILTIN_PROMISE +JERRY_STATIC_ASSERT ((int) ECMA_ERROR_AGGREGATE == (int) JERRY_ERROR_AGGREGATE, + ecma_standard_error_t_must_be_equal_to_jerry_error_t); +#endif /* JERRY_BUILTIN_PROMISE */ JERRY_STATIC_ASSERT ((int) ECMA_INIT_EMPTY == (int) JERRY_INIT_EMPTY && (int) ECMA_INIT_SHOW_OPCODES == (int) JERRY_INIT_SHOW_OPCODES diff --git a/jerry-core/config.h b/jerry-core/config.h index 10d191b8..ce536a18 100644 --- a/jerry-core/config.h +++ b/jerry-core/config.h @@ -610,6 +610,7 @@ || (JERRY_BUILTIN_PROMISE == 1) \ || (JERRY_BUILTIN_PROXY == 1) \ || (JERRY_BUILTIN_REFLECT == 1) \ +|| (JERRY_BUILTIN_PROMISE == 1) \ || (JERRY_BUILTIN_TYPEDARRAY == 1)) # error "JERRY_ESNEXT should be enabled too to enable JERRY_BUILTIN_xxxxx macro." #endif diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index c22ffb4a..019ef291 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -1457,6 +1457,13 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /** string_id = LIT_MAGIC_STRING_TYPE_ERROR_UL; break; } + #if JERRY_BUILTIN_PROMISE + case ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE: + { + string_id = LIT_MAGIC_STRING_AGGREGATE_ERROR_UL; + break; + } + #endif /* JERRY_BUILTIN_PROMISE */ case ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE: { string_id = LIT_MAGIC_STRING_URI_ERROR_UL; diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 6d846a12..267a6e58 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -2136,7 +2136,7 @@ typedef struct ecma_extended_object_t header; /**< object header */ ecma_value_t remaining_elements; /**< [[Remaining elements]] internal slot */ ecma_value_t capability; /**< [[Capabilities]] internal slot */ - ecma_value_t values; /**< [[Values]] internal slot */ + ecma_value_t values; /**< [[Values]] or [[Errors]] internal slot */ uint32_t index; /**< [[Index]] and [[AlreadyCalled]] internal slot * 0 - if the element has been resolved * real index + 1 in the [[Values]] list - otherwise */ @@ -2150,7 +2150,8 @@ typedef enum ECMA_PROMISE_ALL_RESOLVE, /**< promise.all resolve */ ECMA_PROMISE_ALLSETTLED_RESOLVE, /**< promise.allSettled resolve */ ECMA_PROMISE_ALLSETTLED_REJECT, /**< promise.allSettled reject */ -} ecma_promise_helper; + ECMA_PROMISE_ANY_REJECT, /**< promise.any reject */ +} ecma_promise_all_exector_type_t; #endif /* JERRY_ESNEXT */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.c new file mode 100644 index 00000000..e749fc6c --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.c @@ -0,0 +1,36 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-alloc.h" +#include "ecma-builtins.h" +#include "ecma-conversion.h" +#include "ecma-exceptions.h" +#include "ecma-gc.h" +#include "ecma-globals.h" +#include "ecma-helpers.h" +#include "ecma-objects.h" +#include "ecma-string-object.h" +#include "jrt.h" + +#if JERRY_BUILTIN_PROMISE + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-aggregateerror-prototype.inc.h" +#define BUILTIN_UNDERSCORED_ID aggregate_error_prototype +#include "ecma-builtin-internal-routines-template.inc.h" + +#endif /* JERRY_BUILTIN_PROMISE */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.inc.h new file mode 100644 index 00000000..7365960f --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror-prototype.inc.h @@ -0,0 +1,44 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * AggregateError.prototype built-in description + */ + +#include "ecma-builtin-helpers-macro-defines.inc.h" + +#if JERRY_BUILTIN_PROMISE + +/* Object properties: + * (property name, object pointer getter) */ + +/* ECMA-262 v5, 15.11.7.8 */ +OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR, + ECMA_BUILTIN_ID_AGGREGATE_ERROR, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE) + +/* ECMA-262 v5, 15.11.7.9 */ +STRING_VALUE (LIT_MAGIC_STRING_NAME, + LIT_MAGIC_STRING_AGGREGATE_ERROR_UL, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE) + +/* ECMA-262 v5, 15.11.7.10 */ +STRING_VALUE (LIT_MAGIC_STRING_MESSAGE, + LIT_MAGIC_STRING__EMPTY, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE) + +#endif /* JERRY_BUILTIN_PROMISE */ + +#include "ecma-builtin-helpers-macro-undefs.inc.h" diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror.c b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror.c new file mode 100644 index 00000000..0b31d359 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror.c @@ -0,0 +1,112 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-alloc.h" +#include "ecma-builtins.h" +#include "ecma-conversion.h" +#include "ecma-exceptions.h" +#include "ecma-gc.h" +#include "ecma-globals.h" +#include "ecma-helpers.h" +#include "ecma-builtin-helpers.h" +#include "ecma-objects.h" +#include "ecma-function-object.h" +#include "ecma-iterator-object.h" +#include "ecma-array-object.h" +#include "jrt.h" +#include "jcontext.h" + +#if JERRY_BUILTIN_PROMISE + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-aggregateerror.inc.h" +#define BUILTIN_UNDERSCORED_ID aggregate_error +#include "ecma-builtin-internal-routines-template.inc.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup aggregateerror ECMA AggregateError object built-in + * @{ + */ + +/** + * Handle calling [[Call]] of built-in AggregateError object + * + * @return ecma value + */ +ecma_value_t +ecma_builtin_aggregate_error_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ + uint32_t arguments_list_len) /**< number of arguments */ +{ + JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + ecma_value_t message_val = ECMA_VALUE_UNDEFINED; + ecma_value_t error_val = ECMA_VALUE_UNDEFINED; + + if (arguments_list_len > 0) + { + error_val = arguments_list_p[0]; + + if (arguments_list_len > 1) + { + message_val = arguments_list_p[1]; + } + } + + return ecma_new_aggregate_error (error_val, message_val); +} /* ecma_builtin_aggregate_error_dispatch_call */ + +/** + * Handle calling [[Construct]] of built-in AggregateError object + * + * @return ecma value + */ +ecma_value_t +ecma_builtin_aggregate_error_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ + uint32_t arguments_list_len) /**< number of arguments */ +{ + ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target_p), + ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE); + + if (proto_p == NULL) + { + return ECMA_VALUE_ERROR; + } + + ecma_value_t result = ecma_builtin_aggregate_error_dispatch_call (arguments_list_p, arguments_list_len); + + if (!ECMA_IS_VALUE_ERROR (result)) + { + ecma_object_t *object_p = ecma_get_object_from_value (result); + ECMA_SET_NON_NULL_POINTER (object_p->u2.prototype_cp, proto_p); + } + + ecma_deref_object (proto_p); + + return result; +} /* ecma_builtin_aggregate_error_dispatch_construct */ + +/** + * @} + * @} + * @} + */ + +#endif /* JERRY_BUILTIN_PROMISE */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror.inc.h new file mode 100644 index 00000000..c9c3a0dc --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-aggregateerror.inc.h @@ -0,0 +1,45 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * AggregateError built-in description + */ + +#include "ecma-builtin-helpers-macro-defines.inc.h" + +#if JERRY_BUILTIN_PROMISE + +/* Number properties: + * (property name, number value, writable, enumerable, configurable) */ + +NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH, + 2, + ECMA_PROPERTY_FLAG_DEFAULT_LENGTH) + +/* Object properties: + * (property name, object pointer getter) */ + +/* ECMA-262 v5, 15.11.3.1 */ +OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE, + ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE, + ECMA_PROPERTY_FIXED) + +STRING_VALUE (LIT_MAGIC_STRING_NAME, + LIT_MAGIC_STRING_AGGREGATE_ERROR_UL, + ECMA_PROPERTY_FLAG_CONFIGURABLE) + +#endif /* JERRY_BUILTIN_PROMISE */ + +#include "ecma-builtin-helpers-macro-undefs.inc.h" diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h index 918c7615..b4c93832 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h @@ -127,6 +127,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_TYPE_ERROR_UL, ECMA_BUILTIN_ID_TYPE_ERROR, ECMA_PROPERTY_CONFIGURABLE_WRITABLE) +#if JERRY_BUILTIN_PROMISE +OBJECT_VALUE (LIT_MAGIC_STRING_AGGREGATE_ERROR_UL, + ECMA_BUILTIN_ID_AGGREGATE_ERROR, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE) +#endif /* JERRY_BUILTIN_PROMISE */ + /* ECMA-262 v5, 15.1.4.15 */ OBJECT_VALUE (LIT_MAGIC_STRING_URI_ERROR_UL, ECMA_BUILTIN_ID_URI_ERROR, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c index a55e61e9..387d974d 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c @@ -47,6 +47,7 @@ enum ECMA_PROMISE_ROUTINE_RACE, ECMA_PROMISE_ROUTINE_ALL, ECMA_PROMISE_ROUTINE_ALLSETTLED, + ECMA_PROMISE_ROUTINE_ANY, ECMA_PROMISE_ROUTINE_SPECIES_GET }; @@ -187,7 +188,7 @@ exit: } /* ecma_builtin_promise_perform_race */ /** - * Runtime Semantics: PerformPromise all or allSettled. + * Runtime Semantics: Perform Promise all, allSettled or any. * * See also: * ES2020 25.6.4.1.1 @@ -196,14 +197,13 @@ exit: * Returned value must be freed with ecma_free_value. */ static inline ecma_value_t -ecma_builtin_promise_perform_all_or_all_settled (ecma_value_t iterator, /**< iteratorRecord */ - ecma_value_t next_method, /**< next method */ - ecma_object_t *capability_obj_p, /**< PromiseCapability record */ - ecma_value_t ctor, /**< the caller of Promise.all */ - ecma_value_t resolve, /** the resolve of Promise.all */ - uint8_t builtin_routine_id, /**< built-in wide routine - * identifier */ - bool *done_p) /**< [out] iteratorRecord[[done]] */ +ecma_builtin_promise_perform (ecma_value_t iterator, /**< iteratorRecord */ + ecma_value_t next_method, /**< next method */ + ecma_object_t *capability_obj_p, /**< PromiseCapability record */ + ecma_value_t ctor, /**< the caller of Promise.all */ + ecma_value_t resolve, /** the resolve of Promise.all */ + uint8_t builtin_routine_id, /**< built-in wide routine identifier */ + bool *done_p) /**< [out] iteratorRecord[[done]] */ { /* 1. - 2. */ JERRY_ASSERT (ecma_object_class_is (capability_obj_p, LIT_INTERNAL_MAGIC_PROMISE_CAPABILITY)); @@ -240,6 +240,12 @@ ecma_builtin_promise_perform_all_or_all_settled (ecma_value_t iterator, /**< ite /* ii. - iii. */ if (ecma_promise_remaining_inc_or_dec (remaining, false) == 0) { + if (builtin_routine_id == ECMA_PROMISE_ROUTINE_ANY) + { + ret_value = ecma_raise_aggregate_error (values_array, ECMA_VALUE_UNDEFINED); + goto done; + } + /* 2. */ ecma_value_t resolve_result = ecma_op_function_call (ecma_get_object_from_value (capability_p->resolve), ECMA_VALUE_UNDEFINED, @@ -291,38 +297,56 @@ ecma_builtin_promise_perform_all_or_all_settled (ecma_value_t iterator, /**< ite goto exit; } - /* k. */ - ecma_object_t *executor_func_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER, - sizeof (ecma_promise_all_executor_t)); + idx++; + ecma_value_t args[2]; + ecma_object_t *executor_func_p = NULL; + + if (builtin_routine_id != ECMA_PROMISE_ROUTINE_ANY) + { + /* k. */ + executor_func_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER, + sizeof (ecma_promise_all_executor_t)); - ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) executor_func_p; + ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) executor_func_p; - /* m. + t. */ - executor_p->index = ++idx; + /* m. + t. */ + executor_p->index = idx; - /* n. */ - executor_p->values = values_array; + /* n. */ + executor_p->values = values_array; - /* o. */ - executor_p->capability = ecma_make_object_value (capability_obj_p); + /* o. */ + executor_p->capability = ecma_make_object_value (capability_obj_p); - /* p. */ - executor_p->remaining_elements = remaining; - executor_p->header.u.class_prop.extra_info = ECMA_PROMISE_ALL_RESOLVE; + /* p. */ + executor_p->remaining_elements = remaining; + executor_p->header.u.class_prop.extra_info = ECMA_PROMISE_ALL_RESOLVE; - if (builtin_routine_id == ECMA_PROMISE_ROUTINE_ALLSETTLED) + if (builtin_routine_id == ECMA_PROMISE_ROUTINE_ALLSETTLED) + { + executor_p->header.u.class_prop.extra_info = ECMA_PROMISE_ALLSETTLED_RESOLVE; + } + + args[0] = ecma_make_object_value (executor_func_p); + } + else { - executor_p->header.u.class_prop.extra_info = ECMA_PROMISE_ALLSETTLED_RESOLVE; + args[0] = capability_p->resolve; } - ecma_value_t args[2]; - args[0] = ecma_make_object_value (executor_func_p); - /* q. */ ecma_promise_remaining_inc_or_dec (remaining, true); ecma_value_t result; - if (builtin_routine_id == ECMA_PROMISE_ROUTINE_ALLSETTLED) + + if (builtin_routine_id != ECMA_PROMISE_ROUTINE_ALL) { + ecma_promise_all_exector_type_t type = ECMA_PROMISE_ALLSETTLED_REJECT; + + if (builtin_routine_id == ECMA_PROMISE_ROUTINE_ANY) + { + type = ECMA_PROMISE_ANY_REJECT; + } + ecma_object_t *reject_func_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER, sizeof (ecma_promise_all_executor_t)); @@ -331,18 +355,21 @@ ecma_builtin_promise_perform_all_or_all_settled (ecma_value_t iterator, /**< ite reject_p->values = values_array; reject_p->capability = ecma_make_object_value (capability_obj_p); reject_p->remaining_elements = remaining; - reject_p->header.u.class_prop.extra_info = ECMA_PROMISE_ALLSETTLED_REJECT; + reject_p->header.u.class_prop.extra_info = (uint16_t) type; args[1] = ecma_make_object_value (reject_func_p); result = ecma_op_invoke_by_magic_id (next_promise, LIT_MAGIC_STRING_THEN, args, 2); - ecma_free_value (next_promise); - ecma_deref_object (executor_func_p); ecma_deref_object (reject_func_p); } else { args[1] = capability_p->reject; result = ecma_op_invoke_by_magic_id (next_promise, LIT_MAGIC_STRING_THEN, args, 2); - ecma_free_value (next_promise); + } + + ecma_free_value (next_promise); + + if (builtin_routine_id != ECMA_PROMISE_ROUTINE_ANY) + { ecma_deref_object (executor_func_p); } @@ -361,10 +388,10 @@ exit: ecma_free_value (remaining); ecma_deref_object (values_array_obj_p); return ret_value; -} /* ecma_builtin_promise_perform_all_or_all_settled */ +} /* ecma_builtin_promise_perform */ /** - * The common function for Promise.race, Promise.all and Promise.allSettled. + * The common function for Promise.race, Promise.all, Promise.any and Promise.allSettled. * * @return ecma value of the new promise. * Returned value must be freed with ecma_free_value. @@ -372,8 +399,7 @@ exit: static ecma_value_t ecma_builtin_promise_helper (ecma_value_t this_arg, /**< 'this' argument */ ecma_value_t iterable, /**< the items to be resolved */ - uint8_t builtin_routine_id) /**< built-in wide routine - * identifier */ + uint8_t builtin_routine_id) /**< built-in wide routine identifier */ { ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg, ECMA_VALUE_UNDEFINED); @@ -420,8 +446,13 @@ ecma_builtin_promise_helper (ecma_value_t this_arg, /**< 'this' argument */ } else { - ret = ecma_builtin_promise_perform_all_or_all_settled (iterator, next_method, capability_obj_p, this_arg, resolve, - builtin_routine_id, &is_done); + ret = ecma_builtin_promise_perform (iterator, + next_method, + capability_obj_p, + this_arg, + resolve, + builtin_routine_id, + &is_done); } if (ECMA_IS_VALUE_ERROR (ret)) @@ -508,6 +539,7 @@ ecma_builtin_promise_dispatch_routine (uint8_t builtin_routine_id, /**< built-in case ECMA_PROMISE_ROUTINE_RACE: case ECMA_PROMISE_ROUTINE_ALL: case ECMA_PROMISE_ROUTINE_ALLSETTLED: + case ECMA_PROMISE_ROUTINE_ANY: { return ecma_builtin_promise_helper (this_arg, argument, builtin_routine_id); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.inc.h index 1355e3f6..5bc63f7e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.inc.h @@ -46,6 +46,7 @@ ROUTINE (LIT_MAGIC_STRING_RESOLVE, ECMA_PROMISE_ROUTINE_RESOLVE, 1, 1) ROUTINE (LIT_MAGIC_STRING_RACE, ECMA_PROMISE_ROUTINE_RACE, 1, 1) ROUTINE (LIT_MAGIC_STRING_ALL, ECMA_PROMISE_ROUTINE_ALL, 1, 1) ROUTINE (LIT_MAGIC_STRING_ALLSETTLED, ECMA_PROMISE_ROUTINE_ALLSETTLED, 1, 1) +ROUTINE (LIT_MAGIC_STRING_ANY, ECMA_PROMISE_ROUTINE_ANY, 1, 1) /* ES2015 25.4.4.6 */ ACCESSOR_READ_ONLY (LIT_GLOBAL_SYMBOL_SPECIES, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index cc73d1db..c94cbbc5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -283,6 +283,22 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_TYPE_ERROR, true, type_error) +#if JERRY_BUILTIN_PROMISE +/* The AggregateError.prototype object (15.11.6.5) */ +BUILTIN (ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_ERROR_PROTOTYPE, + true, + aggregate_error_prototype) + +/* The AggregateError object (15.11.6.5) */ +BUILTIN_ROUTINE (ECMA_BUILTIN_ID_AGGREGATE_ERROR, + ECMA_OBJECT_TYPE_NATIVE_FUNCTION, + ECMA_BUILTIN_NATIVE_ERROR_PROTOTYPE_ID, + true, + aggregate_error) +#endif /* JERRY_BUILTIN_PROMISE */ + /* The URIError.prototype object (15.11.6.6) */ BUILTIN (ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE, ECMA_OBJECT_TYPE_GENERAL, diff --git a/jerry-core/ecma/operations/ecma-exceptions.c b/jerry-core/ecma/operations/ecma-exceptions.c index 42472454..085dcf8e 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.c +++ b/jerry-core/ecma/operations/ecma-exceptions.c @@ -22,6 +22,8 @@ #include "ecma-helpers.h" #include "ecma-objects.h" #include "ecma-symbol-object.h" +#include "ecma-iterator-object.h" +#include "ecma-array-object.h" #include "jcontext.h" #include "jrt.h" @@ -60,6 +62,9 @@ const ecma_error_mapping_t ecma_error_mappings[] = ERROR_ELEMENT (ECMA_ERROR_TYPE, ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE), ERROR_ELEMENT (ECMA_ERROR_URI, ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE), ERROR_ELEMENT (ECMA_ERROR_SYNTAX, ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE), +#if JERRY_BUILTIN_PROMISE + ERROR_ELEMENT (ECMA_ERROR_AGGREGATE, ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE), +#endif /* JERRY_BUILTIN_PROMISE */ #endif /* JERRY_BUILTIN_ERRORS */ #undef ERROR_ELEMENT @@ -111,6 +116,13 @@ ecma_new_standard_error (ecma_standard_error_t error_type, /**< native error typ break; } +#if JERRY_BUILTIN_PROMISE + case ECMA_ERROR_AGGREGATE: + { + prototype_id = ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE; + break; + } +#endif /* JERRY_BUILTIN_PROMISE */ case ECMA_ERROR_URI: { prototype_id = ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE; @@ -187,6 +199,112 @@ ecma_new_standard_error (ecma_standard_error_t error_type, /**< native error typ return new_error_obj_p; } /* ecma_new_standard_error */ +#if JERRY_BUILTIN_PROMISE +/** + * aggregate-error object constructor. + * + * @return newly constructed aggregate errors + */ +ecma_value_t +ecma_new_aggregate_error (ecma_value_t error_list_val, /**< errors list */ + ecma_value_t message_val) /**< message string */ +{ + ecma_object_t *new_error_object_p; + + if (!ecma_is_value_undefined (message_val)) + { + ecma_string_t *message_string_p = ecma_op_to_string (message_val); + + if (JERRY_UNLIKELY (message_string_p == NULL)) + { + return ECMA_VALUE_ERROR; + } + + new_error_object_p = ecma_new_standard_error (ECMA_ERROR_AGGREGATE, message_string_p); + ecma_deref_ecma_string (message_string_p); + } + else + { + new_error_object_p = ecma_new_standard_error (ECMA_ERROR_AGGREGATE, NULL); + } + + ecma_value_t using_iterator = ecma_op_get_method_by_symbol_id (error_list_val, LIT_GLOBAL_SYMBOL_ITERATOR); + + if (ECMA_IS_VALUE_ERROR (using_iterator)) + { + ecma_deref_object (new_error_object_p); + return using_iterator; + } + + if (!ecma_is_value_undefined (using_iterator)) + { + ecma_value_t next_method; + ecma_value_t iterator = ecma_op_get_iterator (error_list_val, using_iterator, &next_method); + ecma_free_value (using_iterator); + + if (ECMA_IS_VALUE_ERROR (iterator)) + { + ecma_deref_object (new_error_object_p); + return iterator; + } + + ecma_collection_t *error_list_p = ecma_new_collection (); + ecma_value_t result = ECMA_VALUE_ERROR; + + while (true) + { + ecma_value_t next = ecma_op_iterator_step (iterator, next_method); + + if (ECMA_IS_VALUE_ERROR (next)) + { + break; + } + + if (next == ECMA_VALUE_FALSE) + { + result = ECMA_VALUE_UNDEFINED; + break; + } + + /* 8.e.iii */ + ecma_value_t next_error = ecma_op_iterator_value (next); + ecma_free_value (next); + + if (ECMA_IS_VALUE_ERROR (next_error)) + { + break; + } + + ecma_collection_push_back (error_list_p, next_error); + } + + ecma_free_value (iterator); + ecma_free_value (next_method); + + if (ECMA_IS_VALUE_ERROR (result)) + { + ecma_collection_free (error_list_p); + ecma_deref_object (new_error_object_p); + return result; + } + + JERRY_ASSERT (ecma_is_value_undefined (result)); + + ecma_value_t error_list_arr = ecma_op_new_array_object_from_collection (error_list_p, true); + ecma_property_value_t *prop_value_p; + prop_value_p = ecma_create_named_data_property (new_error_object_p, + ecma_get_magic_string (LIT_MAGIC_STRING_ERRORS_UL), + ECMA_PROPERTY_CONFIGURABLE_WRITABLE, + NULL); + prop_value_p->value = error_list_arr; + ecma_free_value (error_list_arr); + } + + return ecma_make_object_value (new_error_object_p); +} /* ecma_new_aggregate_error */ + +#endif /* JERRY_BUILTIN_PROMISE */ + /** * Return the error type for an Error object. * @@ -414,6 +532,26 @@ ecma_raise_uri_error (const char *msg_p) /**< error message */ return ecma_raise_standard_error (ECMA_ERROR_URI, (const lit_utf8_byte_t *) msg_p); } /* ecma_raise_uri_error */ +#if JERRY_BUILTIN_PROMISE + +/** + * Raise a AggregateError with the given errors and message. + * + * @return ecma value + * Returned value must be freed with ecma_free_value + */ +ecma_value_t +ecma_raise_aggregate_error (ecma_value_t error_list_val, /**< errors list */ + ecma_value_t message_val) /**< error message */ +{ + ecma_value_t aggre_val = ecma_new_aggregate_error (error_list_val, message_val); + jcontext_raise_exception (aggre_val); + + return ECMA_VALUE_ERROR; +} /* ecma_raise_aggregate_error */ + +#endif /* JERRY_BUILTIN_PROMISE */ + /** * @} * @} diff --git a/jerry-core/ecma/operations/ecma-exceptions.h b/jerry-core/ecma/operations/ecma-exceptions.h index 653d8046..cedcc410 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.h +++ b/jerry-core/ecma/operations/ecma-exceptions.h @@ -47,7 +47,10 @@ typedef enum ECMA_ERROR_REFERENCE, /**< ReferenceError */ ECMA_ERROR_SYNTAX, /**< SyntaxError */ ECMA_ERROR_TYPE, /**< TypeError */ - ECMA_ERROR_URI /**< URIError */ + ECMA_ERROR_URI, /**< URIError */ +#if JERRY_BUILTIN_PROMISE + ECMA_ERROR_AGGREGATE, /**< AggregateError */ +#endif /* JERRY_BUILTIN_PROMISE */ } ecma_standard_error_t; ecma_standard_error_t ecma_get_error_type (ecma_object_t *error_object); @@ -61,6 +64,10 @@ ecma_value_t ecma_raise_reference_error (const char *msg_p); ecma_value_t ecma_raise_syntax_error (const char *msg_p); ecma_value_t ecma_raise_type_error (const char *msg_p); ecma_value_t ecma_raise_uri_error (const char *msg_p); +#if JERRY_BUILTIN_PROMISE +ecma_value_t ecma_new_aggregate_error (ecma_value_t error_list_val, ecma_value_t message_val); +ecma_value_t ecma_raise_aggregate_error (ecma_value_t error_list_val, ecma_value_t message_val); +#endif /* JERRY_BUILTIN_PROMISE */ /** * @} diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index fff988b6..4c5a6ced 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -2626,6 +2626,7 @@ ecma_object_check_class_name_is_object (ecma_object_t *obj_p) /**< object */ || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE) + || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_AGGREGATE_ERROR_PROTOTYPE) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ERROR_PROTOTYPE) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_DATE_PROTOTYPE) diff --git a/jerry-core/ecma/operations/ecma-promise-object.c b/jerry-core/ecma/operations/ecma-promise-object.c index defa6ea7..3cdf01eb 100644 --- a/jerry-core/ecma/operations/ecma-promise-object.c +++ b/jerry-core/ecma/operations/ecma-promise-object.c @@ -600,8 +600,8 @@ ecma_promise_remaining_inc_or_dec (ecma_value_t remaining, /**< the remaining co */ ecma_value_t ecma_promise_all_or_all_settled_handler_cb (ecma_object_t *function_obj_p, /**< function object */ - const ecma_value_t args_p[], /**< argument list */ - const uint32_t args_count) /**< argument number */ + const ecma_value_t args_p[], /**< argument list */ + const uint32_t args_count) /**< argument number */ { JERRY_UNUSED (args_count); ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) function_obj_p; @@ -613,7 +613,7 @@ ecma_promise_all_or_all_settled_handler_cb (ecma_object_t *function_obj_p, /**< return ECMA_VALUE_UNDEFINED; } - if (promise_type == ECMA_PROMISE_ALL_RESOLVE) + if (promise_type == ECMA_PROMISE_ALL_RESOLVE || promise_type == ECMA_PROMISE_ANY_REJECT) { /* 8. */ ecma_op_object_put_by_index (ecma_get_object_from_value (executor_p->values), @@ -669,10 +669,22 @@ ecma_promise_all_or_all_settled_handler_cb (ecma_object_t *function_obj_p, /**< { ecma_value_t capability = executor_p->capability; ecma_promise_capabality_t *capability_p = (ecma_promise_capabality_t *) ecma_get_object_from_value (capability); - ret = ecma_op_function_call (ecma_get_object_from_value (capability_p->resolve), - ECMA_VALUE_UNDEFINED, - &executor_p->values, - 1); + if (promise_type == ECMA_PROMISE_ANY_REJECT) + { + ecma_value_t error_val = ecma_new_aggregate_error (executor_p->values, ECMA_VALUE_UNDEFINED); + ret = ecma_op_function_call (ecma_get_object_from_value (capability_p->reject), + ECMA_VALUE_UNDEFINED, + &error_val, + 1); + ecma_free_value (error_val); + } + else + { + ret = ecma_op_function_call (ecma_get_object_from_value (capability_p->resolve), + ECMA_VALUE_UNDEFINED, + &executor_p->values, + 1); + } } return ret; diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 5ef080bc..f193582d 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -72,7 +72,8 @@ typedef enum JERRY_ERROR_REFERENCE, /**< ReferenceError */ JERRY_ERROR_SYNTAX, /**< SyntaxError */ JERRY_ERROR_TYPE, /**< TypeError */ - JERRY_ERROR_URI /**< URIError */ + JERRY_ERROR_URI, /**< URIError */ + JERRY_ERROR_AGGREGATE /**< AggregateError */ } jerry_error_t; /** diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index a40a229c..509c2b80 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -71,6 +71,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ADD, "add") #endif #if JERRY_BUILTIN_PROMISE LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ALL, "all") +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ANY, "any") #endif #if JERRY_BUILTIN_MATH LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COS, "cos") @@ -360,6 +361,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DELETE, "delete") #if JERRY_BUILTIN_REGEXP && JERRY_ESNEXT LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DOTALL, "dotAll") #endif +#if JERRY_BUILTIN_PROMISE +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ERRORS_UL, "errors") +#endif #if JERRY_BUILTIN_ANNEXB LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ESCAPE, "escape") #endif @@ -917,6 +921,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UTC_SECONDS_UL, "setUTCSeconds") #if JERRY_BUILTIN_NUMBER LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_EXPONENTIAL_UL, "toExponential") #endif +#if JERRY_BUILTIN_PROMISE +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_AGGREGATE_ERROR_UL, "AggregateError") +#endif #if JERRY_ESNEXT LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARRAY_ITERATOR_UL, "Array Iterator") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ASYNC_GENERATOR_UL, "AsyncGenerator") @@ -1137,7 +1144,9 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_GET_UTC_MINUTES_UL #else LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_IS_PROTOTYPE_OF_UL) #endif -#if JERRY_ESNEXT +#if JERRY_BUILTIN_PROMISE +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (14, LIT_MAGIC_STRING_AGGREGATE_ERROR_UL) +#elif JERRY_ESNEXT LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (14, LIT_MAGIC_STRING_ARRAY_ITERATOR_UL) #elif JERRY_BUILTIN_BIGINT && JERRY_BUILTIN_TYPEDARRAY LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (14, LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL) diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini index 2b05f8bd..afd9f3a5 100644 --- a/jerry-core/lit/lit-magic-strings.ini +++ b/jerry-core/lit/lit-magic-strings.ini @@ -40,6 +40,7 @@ LIT_MAGIC_STRING_UTC_U = "UTC" LIT_MAGIC_STRING_ABS = "abs" LIT_MAGIC_STRING_ADD = "add" LIT_MAGIC_STRING_ALL = "all" +LIT_MAGIC_STRING_ANY = "any" LIT_MAGIC_STRING_COS = "cos" LIT_MAGIC_STRING_EXP = "exp" LIT_MAGIC_STRING_FOR = "for" @@ -136,6 +137,7 @@ LIT_MAGIC_STRING_TRUNC = "trunc" LIT_MAGIC_STRING_VALUE = "value" LIT_MAGIC_STRING_RESOURCE_EVAL = "<eval>" LIT_MAGIC_STRING_BIGINT_UL = "BigInt" +LIT_MAGIC_STRING_ERRORS_UL = "errors" LIT_MAGIC_STRING_LOG10E_U = "LOG10E" LIT_MAGIC_STRING_MODULE_UL = "Module" LIT_MAGIC_STRING_NUMBER_UL = "Number" @@ -362,6 +364,7 @@ LIT_MAGIC_STRING_LOCALE_COMPARE_UL = "localeCompare" LIT_MAGIC_STRING_SET_UTC_MINUTES_UL = "setUTCMinutes" LIT_MAGIC_STRING_SET_UTC_SECONDS_UL = "setUTCSeconds" LIT_MAGIC_STRING_TO_EXPONENTIAL_UL = "toExponential" +LIT_MAGIC_STRING_AGGREGATE_ERROR_UL = "AggregateError" LIT_MAGIC_STRING_ARRAY_ITERATOR_UL = "Array Iterator" LIT_MAGIC_STRING_ASYNC_GENERATOR_UL = "AsyncGenerator" LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL = "BigUint64Array" diff --git a/tests/jerry/es.next/error-names.js b/tests/jerry/es.next/error-names.js index 05232dd9..da78afb5 100644 --- a/tests/jerry/es.next/error-names.js +++ b/tests/jerry/es.next/error-names.js @@ -29,3 +29,15 @@ for (var idx = 0; idx < items.length; idx++) { assert ((new type).name === expected_name); } + +assert (AggregateError.name === "AggregateError"); +assert (new AggregateError([]).name === "AggregateError") + +try +{ + new AggregateError.name === "TypeError"; +} +catch(e) +{ + assert (e instanceof TypeError) +} diff --git a/tests/jerry/es.next/error.js b/tests/jerry/es.next/error.js index 4f1daa53..9e44abff 100644 --- a/tests/jerry/es.next/error.js +++ b/tests/jerry/es.next/error.js @@ -19,3 +19,4 @@ assert(Object.getPrototypeOf(ReferenceError) === Error); assert(Object.getPrototypeOf(SyntaxError) === Error); assert(Object.getPrototypeOf(TypeError) === Error); assert(Object.getPrototypeOf(URIError) === Error); +assert(Object.getPrototypeOf(AggregateError) === Error); diff --git a/tests/jerry/es.next/promise-all-settled.js b/tests/jerry/es.next/promise-all-settled.js new file mode 100644 index 00000000..05133baa --- /dev/null +++ b/tests/jerry/es.next/promise-all-settled.js @@ -0,0 +1,97 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function createIterable(arr, methods = {}) { + let iterable = function *() { + let idx = 0; + while (idx < arr.length) { + yield arr[idx]; + idx++; + } + }(); + iterable['return'] = methods['return']; + iterable['throw'] = methods['throw']; + + return iterable; +}; + +// iterator next +Promise.allSettled({ + [Symbol.iterator]() { return {get next() { throw 5; }}} +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +// iterator value +Promise.allSettled({ + [Symbol.iterator] () { return { next () { return { get value () { throw 5 }}}}} +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +// iterator done +Promise.allSettled({ + [Symbol.iterator] () { return { next () { return { get done () { throw 5 }}}}} +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +// iterator get +Promise.allSettled({ + get [Symbol.iterator] () { throw 5 } +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +var fulfills = Promise.allSettled(createIterable([ + new Promise(resolve => { resolve("foo"); }), + new Promise(resolve => { resolve("bar"); }), +])); +var rejects = Promise.allSettled(createIterable([ + new Promise((_, reject) => { reject("baz"); }), + new Promise((_, reject) => { reject("qux"); }), +])); + +fulfills.then(result => { assert (result + "" === "foo,bar"); }); +rejects.catch(result => { assert (result === "baz"); }); + +var closed = true; +delete Promise.resolve; +Promise.allSettled(createIterable([1,2,3], {'return': function () { closed = false; }})); +assert (closed); + +var arr = []; +Object.defineProperty(arr, Symbol.species, { get: function () { assert(false) }}); +Promise.allSettled(arr); + +Promise.resolve = function () { + return { then(resolve,reject) { + assert(resolve !== reject) + }}; +} + +Promise.allSettled([1,2]) diff --git a/tests/jerry/es.next/promise-any.js b/tests/jerry/es.next/promise-any.js new file mode 100644 index 00000000..238ac152 --- /dev/null +++ b/tests/jerry/es.next/promise-any.js @@ -0,0 +1,97 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function createIterable(arr, methods = {}) { + let iterable = function *() { + let idx = 0; + while (idx < arr.length) { + yield arr[idx]; + idx++; + } + }(); + + iterable['return'] = methods['return']; + iterable['throw'] = methods['throw']; + return iterable; +}; + +// iterator next +Promise.any({ + [Symbol.iterator]() { return {get next() { throw 5; }}} +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +// iterator value +Promise.any({ + [Symbol.iterator] () { return { next () { return { get value () { throw 5 }}}}} +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +// iterator done +Promise.any({ + [Symbol.iterator] () { return { next () { return { get done () { throw 5 }}}}} +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +// iterator get +Promise.any({ + get [Symbol.iterator] () { throw 5 } +}).then(onfullfilled => { + // If this is not called, the promise has failed, and catch must be called. + assert(false); +}).catch(err => { + assert(err === 5); +}); + +var fulfills = Promise.any(createIterable([ + new Promise(resolve => { resolve("foo"); }), + new Promise(resolve => { resolve("bar"); }), +])); +var rejects = Promise.any(createIterable([ + new Promise((_, reject) => { reject("baz"); }), + new Promise((_, reject) => { reject("qux"); }), +])); + +fulfills.then(result => { assert (result + "" === "foo"); }); +rejects.catch(result => { assert (result == "AggregateError"); }); + +var closed = true; +delete Promise.resolve; +Promise.any(createIterable([1,2,3], {'return': function () { closed = false; }})); +assert (closed); + +var arr = []; +Object.defineProperty(arr, Symbol.species, { get: function () { assert(false) }}); +Promise.any(arr); + +Promise.resolve = function () { + return { then(resolve,reject) { + assert(resolve !== reject) + }}; +} + +Promise.any([1,2]) diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index cfb64908..458d9241 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -5112,122 +5112,6 @@ <test id="built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call.js"><reason></reason></test> <!-- END - ESNext stage 4 proposal: String.prototype.replaceAll --> - <!-- ESNext stage 4 proposal: Promise.any - features: [Promise.any, AggregateError] - https://github.com/tc39/proposal-promise-any - --> - <test id="built-ins/NativeErrors/AggregateError/errors-iterabletolist-failures.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/errors-iterabletolist.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/length.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/message-method-prop-cast.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/message-method-prop.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/message-tostring-abrupt-symbol.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/message-tostring-abrupt.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/message-undefined-no-prop.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/name.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/newtarget-is-undefined.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/newtarget-proto-custom.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/newtarget-proto-fallback.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/newtarget-proto.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prop-desc.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/proto-from-ctor-realm.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/proto.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prototype/constructor.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prototype/errors-absent-on-prototype.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prototype/message.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prototype/name.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prototype/prop-desc.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/prototype/proto.js"><reason></reason></test> - <test id="built-ins/Promise/any/call-reject-element-after-return.js"><reason></reason></test> - <test id="built-ins/Promise/any/call-reject-element-items.js"><reason></reason></test> - <test id="built-ins/Promise/any/capability-executor-called-twice.js"><reason></reason></test> - <test id="built-ins/Promise/any/capability-executor-not-callable.js"><reason></reason></test> - <test id="built-ins/Promise/any/capability-reject-throws-no-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/capability-resolve-throws-no-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/capability-resolve-throws-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/ctx-ctor-throws.js"><reason></reason></test> - <test id="built-ins/Promise/any/ctx-ctor.js"><reason></reason></test> - <test id="built-ins/Promise/any/ctx-non-ctor.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-error-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-error-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-get-error-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-get-error.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-get-once-no-calls.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve-return.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-resolve.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-then-error-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-then-error-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-then-get-error-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-then-get-error-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-then-on-promises-every-iteration.js"><reason></reason></test> - <test id="built-ins/Promise/any/invoke-then.js"><reason></reason></test> - <test id="built-ins/Promise/any/is-function.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-empty-string-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-error-object-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-false-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-null-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-number-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-poisoned.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-string-resolve.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-symbol-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-true-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-arg-is-undefined-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-false-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-null-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-number-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-string-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-symbol-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-true-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-assigned-undefined-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-next-val-err-no-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-next-val-err-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-false-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-null-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-number-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-string-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-symbol-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-true-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-returns-undefined-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-step-err-no-close.js"><reason></reason></test> - <test id="built-ins/Promise/any/iter-step-err-reject.js"><reason></reason></test> - <test id="built-ins/Promise/any/length.js"><reason></reason></test> - <test id="built-ins/Promise/any/name.js"><reason></reason></test> - <test id="built-ins/Promise/any/new-reject-function.js"><reason></reason></test> - <test id="built-ins/Promise/any/prop-desc.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-all-mixed.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-deferred.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-element-function-extensible.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-element-function-length.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-element-function-name.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-element-function-nonconstructor.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-element-function-prototype.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-from-same-thenable.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-ignored-immed.js"><reason></reason></test> - <test id="built-ins/Promise/any/reject-immed.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-before-loop-exit-from-same.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-before-loop-exit.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-from-reject-catch.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-from-resolve-reject-catch.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-from-same-thenable.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-ignores-late-rejection.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-non-callable.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-non-thenable.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolve-not-callable-reject-with-typeerror.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolved-sequence-extra-ticks.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolved-sequence-mixed.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolved-sequence-with-rejections.js"><reason></reason></test> - <test id="built-ins/Promise/any/resolved-sequence.js"><reason></reason></test> - <test id="built-ins/Promise/any/returns-promise.js"><reason></reason></test> - <test id="built-ins/Promise/any/species-get-error.js"><reason></reason></test> - <!-- END - ESNext stage 4 proposal: Promise.any --> - <!-- ESNext stage 4 proposal: WeakRefs features: [WeakRef, FinalizationRegistry] https://github.com/tc39/proposal-weakrefs @@ -8458,7 +8342,6 @@ <test id="built-ins/FinalizationRegistry/gc-has-one-chance-to-call-cleanupCallback.js"><reason></reason></test> <test id="built-ins/FinalizationRegistry/proto-from-ctor-realm.js"><reason></reason></test> <test id="built-ins/Function/internals/Call/class-ctor-realm.js"><reason></reason></test> - <test id="built-ins/NativeErrors/AggregateError/proto-from-ctor-realm.js"><reason></reason></test> <test id="built-ins/SharedArrayBuffer/proto-from-ctor-realm.js"><reason></reason></test> <test id="built-ins/TypedArrayConstructors/ctors-bigint/buffer-arg/proto-from-ctor-realm-sab.js"><reason></reason></test> <test id="built-ins/TypedArrayConstructors/ctors/buffer-arg/proto-from-ctor-realm-sab.js"><reason></reason></test> |