diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 454fd3c44..ed5df15bd 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -666,7 +666,7 @@ typedef enum ECMA_ITERATOR_KEYS, /**< List only key indices */ ECMA_ITERATOR_VALUES, /**< List only key values */ ECMA_ITERATOR_KEYS_VALUES, /**< List key indices and values */ -} ecma_iterator_type_t; +} ecma_array_iterator_type_t; #endif /* ENABLED (JERRY_ES2015) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 8b96bf217..4a9197f52 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -24,7 +24,6 @@ #include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" -#include "ecma-iterator-object.h" #include "ecma-objects.h" #include "ecma-string-object.h" #include "lit-char-helpers.h" @@ -73,7 +72,6 @@ enum ECMA_ARRAY_PROTOTYPE_FIND, ECMA_ARRAY_PROTOTYPE_FIND_INDEX, ECMA_ARRAY_PROTOTYPE_ENTRIES, - ECMA_ARRAY_PROTOTYPE_VALUES, ECMA_ARRAY_PROTOTYPE_KEYS, ECMA_ARRAY_PROTOTYPE_SYMBOL_ITERATOR, ECMA_ARRAY_PROTOTYPE_FILL, @@ -2493,36 +2491,6 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< return ecma_copy_value (ecma_make_object_value (obj_p)); } /* ecma_builtin_array_prototype_object_copy_within */ - -/** - * Helper function for Array.prototype object's {'keys', 'values', 'entries', '@@iterator'} - * routines common parts. - * - * See also: - * ECMA-262 v6, 22.1.3.4 - * ECMA-262 v6, 22.1.3.13 - * ECMA-262 v6, 22.1.3.29 - * ECMA-262 v6, 22.1.3.30 - * - * Note: - * Returned value must be freed with ecma_free_value. - * - * @return iterator result object, if success - * error - otherwise - */ -static ecma_value_t -ecma_builtin_array_iterators_helper (ecma_object_t *obj_p, /**< array object */ - uint8_t type) /**< any combination of - * ecma_iterator_type_t bits */ -{ - ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_ITERATOR_PROTOTYPE); - - return ecma_op_create_iterator_object (ecma_make_object_value (obj_p), - prototype_obj_p, - ECMA_PSEUDO_ARRAY_ITERATOR, - type); -} /* ecma_builtin_array_iterators_helper */ - #endif /* ENABLED (JERRY_ES2015) */ /** @@ -2570,24 +2538,18 @@ ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< #if ENABLED (JERRY_ES2015) if (JERRY_UNLIKELY (builtin_routine_id >= ECMA_ARRAY_PROTOTYPE_ENTRIES - && builtin_routine_id <= ECMA_ARRAY_PROTOTYPE_SYMBOL_ITERATOR)) + && builtin_routine_id <= ECMA_ARRAY_PROTOTYPE_KEYS)) { ecma_value_t ret_value; if (builtin_routine_id == ECMA_ARRAY_PROTOTYPE_ENTRIES) { - ret_value = ecma_builtin_array_iterators_helper (obj_p, ECMA_ITERATOR_KEYS_VALUES); - } - else if (builtin_routine_id == ECMA_ARRAY_PROTOTYPE_KEYS) - { - ret_value = ecma_builtin_array_iterators_helper (obj_p, ECMA_ITERATOR_KEYS); + ret_value = ecma_op_create_array_iterator (obj_p, ECMA_ITERATOR_KEYS_VALUES); } else { - JERRY_ASSERT (builtin_routine_id == ECMA_ARRAY_PROTOTYPE_VALUES - || builtin_routine_id == ECMA_ARRAY_PROTOTYPE_SYMBOL_ITERATOR); - - ret_value = ecma_builtin_array_iterators_helper (obj_p, ECMA_ITERATOR_VALUES); + JERRY_ASSERT (builtin_routine_id == ECMA_ARRAY_PROTOTYPE_KEYS); + ret_value = ecma_op_create_array_iterator (obj_p, ECMA_ITERATOR_KEYS); } ecma_deref_object (obj_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h index 5f12393d8..a1f17add5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h @@ -75,9 +75,9 @@ ROUTINE (LIT_MAGIC_STRING_FIND_INDEX, ECMA_ARRAY_PROTOTYPE_FIND_INDEX, 2, 1) ROUTINE (LIT_MAGIC_STRING_FILL, ECMA_ARRAY_PROTOTYPE_FILL, 3, 1) ROUTINE (LIT_MAGIC_STRING_COPY_WITHIN, ECMA_ARRAY_PROTOTYPE_COPY_WITHIN, NON_FIXED, 2) ROUTINE (LIT_MAGIC_STRING_ENTRIES, ECMA_ARRAY_PROTOTYPE_ENTRIES, 0, 0) -ROUTINE (LIT_MAGIC_STRING_VALUES, ECMA_ARRAY_PROTOTYPE_VALUES, 0, 0) ROUTINE (LIT_MAGIC_STRING_KEYS, ECMA_ARRAY_PROTOTYPE_KEYS, 0, 0) -ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ECMA_ARRAY_PROTOTYPE_SYMBOL_ITERATOR, 0, 0) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_VALUES, LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES) +INTRINSIC_PROPERTY (LIT_GLOBAL_SYMBOL_ITERATOR, LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES) #endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_BUILTIN_ARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c index ee2d95c44..b37457bfc 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c @@ -108,7 +108,7 @@ ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */ } /* 4. */ - ecma_value_t using_iterator = ecma_op_get_method_by_symbol_id (items, LIT_MAGIC_STRING_ITERATOR); + ecma_value_t using_iterator = ecma_op_get_method_by_symbol_id (items, LIT_GLOBAL_SYMBOL_ITERATOR); /* 5. */ if (ECMA_IS_VALUE_ERROR (using_iterator)) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-defines.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-defines.inc.h index 88f0d582f..41227d5ac 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-defines.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-defines.inc.h @@ -27,8 +27,12 @@ #if ENABLED (JERRY_ES2015) #ifndef SYMBOL_VALUE -#define SYMBOL_VALUE(name, desc_string_id) +#define SYMBOL_VALUE(symbol, desc_magic_string_id) #endif /* !SYMBOL_VALUE */ + +#ifndef INTRINSIC_PROPERTY +#define INTRINSIC_PROPERTY(name, magic_string_id) +#endif /* !INTRINSIC_PROPERTY */ #endif /* ENABLED (JERRY_ES2015) */ #ifndef OBJECT_VALUE diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-undefs.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-undefs.inc.h index 1810c6743..0089fdaa1 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-undefs.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-macro-undefs.inc.h @@ -18,6 +18,7 @@ #undef STRING_VALUE #if ENABLED (JERRY_ES2015) #undef SYMBOL_VALUE +#undef INTRINSIC_PROPERTY #endif /* ENABLED (JERRY_ES2015) */ #undef OBJECT_VALUE #undef ROUTINE diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index cb184d923..540d8f5cb 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -142,7 +142,7 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg type_string = ecma_object_get_class_name (obj_p); #if ENABLED (JERRY_ES2015) - ecma_value_t tag_value = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_TO_STRING_TAG); + ecma_value_t tag_value = ecma_op_object_get_by_symbol_id (obj_p, LIT_GLOBAL_SYMBOL_TO_STRING_TAG); if (ECMA_IS_VALUE_ERROR (tag_value)) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h index 1efe72fef..5ca45b828 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h @@ -175,12 +175,19 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] = magic_string_id \ }, #if ENABLED (JERRY_ES2015) -#define SYMBOL_VALUE(name, desc_string_id) \ +#define SYMBOL_VALUE(symbol, desc_magic_string_id) \ { \ - name, \ + symbol, \ ECMA_BUILTIN_PROPERTY_SYMBOL, \ ECMA_PROPERTY_FIXED, \ - desc_string_id \ + desc_magic_string_id \ + }, +#define INTRINSIC_PROPERTY(name, magic_string_id) \ + { \ + name, \ + ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY, \ + ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \ + magic_string_id \ }, #endif /* ENABLED (JERRY_ES2015) */ #define ACCESSOR_READ_WRITE(name, c_getter_name, c_setter_name, prop_attributes) \ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c new file mode 100644 index 000000000..07ea2ac96 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c @@ -0,0 +1,73 @@ +/* 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-builtins.h" +#include "ecma-array-object.h" +#include "ecma-gc.h" + +#if ENABLED (JERRY_ES2015) + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-intrinsic.inc.h" +#define BUILTIN_UNDERSCORED_ID intrinsic +#include "ecma-builtin-internal-routines-template.inc.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup intrinsic ECMA Intrinsic object built-in + * @{ + */ + +/** + * The %ArrayProto_values% intrinsic routine + * + * See also: + * ECMA-262 v5, 15.4.4.4 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_intrinsic_array_prototype_values (ecma_value_t this_value) /**< this argument */ +{ + ecma_value_t this_obj = ecma_op_to_object (this_value); + + if (ECMA_IS_VALUE_ERROR (this_obj)) + { + return this_obj; + } + + ecma_object_t *this_obj_p = ecma_get_object_from_value (this_obj); + + ecma_value_t ret_value = ecma_op_create_array_iterator (this_obj_p, ECMA_ITERATOR_VALUES); + + ecma_deref_object (this_obj_p); + + return ret_value; +} /* ecma_builtin_intrinsic_array_prototype_values */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_ES2015) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h new file mode 100644 index 000000000..4f7378f33 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h @@ -0,0 +1,71 @@ +/* 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. + */ + +/* + * Intrinsic built-in description + */ + +#include "ecma-builtin-helpers-macro-defines.inc.h" + +#if ENABLED (JERRY_ES2015) + +/* ECMA-262 v6, 19.4.2.2 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_HAS_INSTANCE, + LIT_MAGIC_STRING_HAS_INSTANCE) + +/* ECMA-262 v6, 19.4.2.3 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE, + LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE) + +/* ECMA-262 v6, 19.4.2.4 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_ITERATOR, + LIT_MAGIC_STRING_ITERATOR) + +/* ECMA-262 v6, 19.4.2.6 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_MATCH, + LIT_MAGIC_STRING_MATCH) + +/* ECMA-262 v6, 19.4.2.8 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_REPLACE, + LIT_MAGIC_STRING_REPLACE) + +/* ECMA-262 v6, 19.4.2.9 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SEARCH, + LIT_MAGIC_STRING_SEARCH) + +/* ECMA-262 v6, 19.4.2.10 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SPECIES, + LIT_MAGIC_STRING_SPECIES) + +/* ECMA-262 v6, 19.4.2.11 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SPLIT, + LIT_MAGIC_STRING_SPLIT) + +/* ECMA-262 v6, 19.4.2.12 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_TO_PRIMITIVE, + LIT_MAGIC_STRING_TO_PRIMITIVE) + +/* ECMA-262 v6, 19.4.2.13 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG, + LIT_MAGIC_STRING_TO_STRING_TAG) + +/* ECMA-262 v6, 19.4.2.14 */ +SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_UNSCOPABLES, + LIT_MAGIC_STRING_UNSCOPABLES) + +ROUTINE (LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, ecma_builtin_intrinsic_array_prototype_values, 0, 0) + +#endif /* ENABLED (JERRY_ES2015) */ +#include "ecma-builtin-helpers-macro-undefs.inc.h" diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index 47867ac36..35a62871a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -290,7 +290,7 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, / #if ENABLED (JERRY_ES2015) if (!(ecma_is_value_undefined (regexp_arg) || ecma_is_value_null (regexp_arg))) { - ecma_value_t matcher = ecma_op_get_method_by_symbol_id (regexp_arg, LIT_MAGIC_STRING_MATCH); + ecma_value_t matcher = ecma_op_get_method_by_symbol_id (regexp_arg, LIT_GLOBAL_SYMBOL_MATCH); if (ECMA_IS_VALUE_ERROR (matcher)) { @@ -331,7 +331,7 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, / #if ENABLED (JERRY_ES2015) ecma_object_t *new_regexp_obj = ecma_get_object_from_value (new_regexp); - ecma_value_t func_value = ecma_op_object_get_by_symbol_id (new_regexp_obj, LIT_MAGIC_STRING_MATCH); + ecma_value_t func_value = ecma_op_object_get_by_symbol_id (new_regexp_obj, LIT_GLOBAL_SYMBOL_MATCH); if (ECMA_IS_VALUE_ERROR (func_value) || !ecma_op_is_callable (func_value)) { @@ -392,7 +392,7 @@ ecma_builtin_string_prototype_object_replace (ecma_value_t this_value, /**< this if (!(ecma_is_value_undefined (search_value) || ecma_is_value_null (search_value))) { ecma_object_t *obj_p = ecma_get_object_from_value (ecma_op_to_object (search_value)); - ecma_value_t replace_symbol = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_REPLACE); + ecma_value_t replace_symbol = ecma_op_object_get_by_symbol_id (obj_p, LIT_GLOBAL_SYMBOL_REPLACE); ecma_deref_object (obj_p); if (ECMA_IS_VALUE_ERROR (replace_symbol)) @@ -582,7 +582,7 @@ ecma_builtin_string_prototype_object_search (ecma_value_t this_value, /**< this if (!(ecma_is_value_undefined (regexp_value) || ecma_is_value_null (regexp_value))) { ecma_object_t *obj_p = ecma_get_object_from_value (ecma_op_to_object (regexp_value)); - ecma_value_t search_symbol = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_SEARCH); + ecma_value_t search_symbol = ecma_op_object_get_by_symbol_id (obj_p, LIT_GLOBAL_SYMBOL_SEARCH); ecma_deref_object (obj_p); if (ECMA_IS_VALUE_ERROR (search_symbol)) @@ -638,7 +638,7 @@ ecma_builtin_string_prototype_object_search (ecma_value_t this_value, /**< this ecma_deref_object (ecma_get_object_from_value (new_regexp)); #else /* ENABLED (JERRY_ES2015) */ ecma_object_t *regexp_obj_p = ecma_get_object_from_value (new_regexp); - ecma_value_t search_symbol = ecma_op_object_get_by_symbol_id (regexp_obj_p, LIT_MAGIC_STRING_SEARCH); + ecma_value_t search_symbol = ecma_op_object_get_by_symbol_id (regexp_obj_p, LIT_GLOBAL_SYMBOL_SEARCH); if (ECMA_IS_VALUE_ERROR (search_symbol)) { goto cleanup_regexp; @@ -734,7 +734,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_value, /**< this a if (!(ecma_is_value_undefined (separator_value) || ecma_is_value_null (separator_value))) { ecma_object_t *obj_p = ecma_get_object_from_value (ecma_op_to_object (separator_value)); - ecma_value_t split_symbol = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_SPLIT); + ecma_value_t split_symbol = ecma_op_object_get_by_symbol_id (obj_p, LIT_GLOBAL_SYMBOL_SPLIT); ecma_deref_object (obj_p); if (ECMA_IS_VALUE_ERROR (split_symbol)) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h index 2628ec058..24736b530 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h @@ -38,48 +38,48 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE, ECMA_PROPERTY_FIXED) /* ECMA-262 v6, 19.4.2.2 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_HAS_INSTANCE, - LIT_GLOBAL_SYMBOL_HAS_INSTANCE) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_HAS_INSTANCE, + LIT_GLOBAL_SYMBOL_HAS_INSTANCE) /* ECMA-262 v6, 19.4.2.3 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE, - LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE, + LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE) /* ECMA-262 v6, 19.4.2.4 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_ITERATOR, - LIT_GLOBAL_SYMBOL_ITERATOR) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_ITERATOR, + LIT_GLOBAL_SYMBOL_ITERATOR) /* ECMA-262 v6, 19.4.2.6 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_MATCH, - LIT_GLOBAL_SYMBOL_MATCH) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_MATCH, + LIT_GLOBAL_SYMBOL_MATCH) /* ECMA-262 v6, 19.4.2.8 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_REPLACE, - LIT_GLOBAL_SYMBOL_REPLACE) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_REPLACE, + LIT_GLOBAL_SYMBOL_REPLACE) /* ECMA-262 v6, 19.4.2.9 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_SEARCH, - LIT_GLOBAL_SYMBOL_SEARCH) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_SEARCH, + LIT_GLOBAL_SYMBOL_SEARCH) /* ECMA-262 v6, 19.4.2.10 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_SPECIES, - LIT_GLOBAL_SYMBOL_SPECIES) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_SPECIES, + LIT_GLOBAL_SYMBOL_SPECIES) /* ECMA-262 v6, 19.4.2.11 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_SPLIT, - LIT_GLOBAL_SYMBOL_SPLIT) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_SPLIT, + LIT_GLOBAL_SYMBOL_SPLIT) /* ECMA-262 v6, 19.4.2.12 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_TO_PRIMITIVE, - LIT_GLOBAL_SYMBOL_TO_PRIMITIVE) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TO_PRIMITIVE, + LIT_GLOBAL_SYMBOL_TO_PRIMITIVE) /* ECMA-262 v6, 19.4.2.13 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_TO_STRING_TAG, - LIT_GLOBAL_SYMBOL_TO_STRING_TAG) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TO_STRING_TAG, + LIT_GLOBAL_SYMBOL_TO_STRING_TAG) /* ECMA-262 v6, 19.4.2.14 */ -SYMBOL_VALUE (LIT_MAGIC_STRING_UNSCOPABLES, - LIT_GLOBAL_SYMBOL_UNSCOPABLES) +INTRINSIC_PROPERTY (LIT_MAGIC_STRING_UNSCOPABLES, + LIT_GLOBAL_SYMBOL_UNSCOPABLES) /* Routine properties: * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h b/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h index ca17ae117..0efa46ce5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h @@ -33,6 +33,7 @@ typedef enum ECMA_BUILTIN_PROPERTY_STRING, /**< string value property */ #if ENABLED (JERRY_ES2015) ECMA_BUILTIN_PROPERTY_SYMBOL, /**< symbol value property */ + ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY, /**< intrinsic routine property */ #endif /* ENABLED (JERRY_ES2015) */ ECMA_BUILTIN_PROPERTY_OBJECT, /**< builtin object property */ ECMA_BUILTIN_PROPERTY_ROUTINE, /**< routine property */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index a087ebeb4..ff450b5a0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -793,7 +793,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * #if ENABLED (JERRY_ES2015) case ECMA_BUILTIN_PROPERTY_SYMBOL: { - lit_magic_string_id_t symbol_desc_id = (lit_magic_string_id_t) curr_property_p->magic_string_id; + lit_magic_string_id_t symbol_desc_id = (lit_magic_string_id_t) curr_property_p->value; ecma_string_t *symbol_desc_p; symbol_desc_p = ecma_append_magic_string_to_string (ecma_get_magic_string (LIT_MAGIC_STRING_SYMBOL_DOT_UL), @@ -802,12 +802,18 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * ecma_value_t symbol_desc_value = ecma_make_string_value (symbol_desc_p); ecma_string_t *symbol_p = ecma_new_symbol_from_descriptor_string (symbol_desc_value); - lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->value; + lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->magic_string_id; symbol_p->u.hash = (uint16_t) ((symbol_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG); value = ecma_make_symbol_value (symbol_p); break; } + case ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY: + { + value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_INTRINSIC_OBJECT), + (lit_magic_string_id_t) curr_property_p->value); + break; + } #endif /* ENABLED (JERRY_ES2015) */ case ECMA_BUILTIN_PROPERTY_OBJECT: { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index b2b4c6be9..67494b84e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -510,6 +510,13 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_WEAKSET, #if ENABLED (JERRY_ES2015) +/* Intrinsic hidden builtin object */ +BUILTIN (ECMA_BUILTIN_ID_INTRINSIC_OBJECT, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID__COUNT, + true, + intrinsic) + /* The Array.prototype[@@unscopables] object */ BUILTIN (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE_UNSCOPABLES, ECMA_OBJECT_TYPE_GENERAL, diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 3763b75a3..04eb9d2f3 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -15,6 +15,7 @@ #include "ecma-alloc.h" #include "ecma-array-object.h" +#include "ecma-iterator-object.h" #include "ecma-builtin-helpers.h" #include "ecma-builtins.h" #include "ecma-exceptions.h" @@ -687,7 +688,7 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f else if (ecma_is_value_object (constructor)) { ecma_object_t *ctor_object_p = ecma_get_object_from_value (constructor); - constructor = ecma_op_object_get_by_symbol_id (ctor_object_p, LIT_MAGIC_STRING_SPECIES); + constructor = ecma_op_object_get_by_symbol_id (ctor_object_p, LIT_GLOBAL_SYMBOL_SPECIES); ecma_deref_object (ctor_object_p); if (ECMA_IS_VALUE_ERROR (constructor)) @@ -729,6 +730,35 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f ecma_free_value (len_val); return ret_val; } /* ecma_op_array_species_create */ + +/** + * CreateArrayIterator Abstract Operation + * + * See also: + * ECMA-262 v6, 22.1.5.1 + * + * Referenced by: + * ECMA-262 v6, 22.1.3.4 + * ECMA-262 v6, 22.1.3.13 + * ECMA-262 v6, 22.1.3.29 + * ECMA-262 v6, 22.1.3.30 + * + * Note: + * Returned value must be freed with ecma_free_value. + * + * @return array iterator object + */ +ecma_value_t +ecma_op_create_array_iterator (ecma_object_t *obj_p, /**< array object */ + ecma_array_iterator_type_t type) /**< array iterator type */ +{ + ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_ITERATOR_PROTOTYPE); + + return ecma_op_create_iterator_object (ecma_make_object_value (obj_p), + prototype_obj_p, + ECMA_PSEUDO_ARRAY_ITERATOR, + (uint8_t) type); +} /* ecma_op_create_array_iterator */ #endif /* ENABLED (JERRY_ES2015) */ /** diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index 3e1e35a5b..7a6fde10c 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -101,6 +101,10 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, ecma_length_t ecma_value_t ecma_op_array_species_create (ecma_object_t *original_array_p, ecma_length_t length); + +ecma_value_t +ecma_op_create_array_iterator (ecma_object_t *obj_p, + ecma_array_iterator_type_t type); #endif /* ENABLED (JERRY_ES2015) */ ecma_value_t diff --git a/jerry-core/ecma/operations/ecma-iterator-object.c b/jerry-core/ecma/operations/ecma-iterator-object.c index ceffa652e..86fdb72c1 100644 --- a/jerry-core/ecma/operations/ecma-iterator-object.c +++ b/jerry-core/ecma/operations/ecma-iterator-object.c @@ -187,7 +187,7 @@ ecma_op_get_iterator (ecma_value_t value, /**< value to get iterator from */ if (!has_method) { /* 2.a */ - method = ecma_op_get_method_by_symbol_id (value, LIT_MAGIC_STRING_ITERATOR); + method = ecma_op_get_method_by_symbol_id (value, LIT_GLOBAL_SYMBOL_ITERATOR); /* 2.b */ if (ECMA_IS_VALUE_ERROR (method)) diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.c b/jerry-core/ecma/operations/ecma-objects-arguments.c index 313db79d5..2c3023a51 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.c +++ b/jerry-core/ecma/operations/ecma-objects-arguments.c @@ -140,6 +140,22 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); +#if ENABLED (JERRY_ES2015) + /* ECMAScript v6, 9.4.4.6.7, 9.4.4.7.22 */ + ecma_string_t *symbol_p = ecma_op_get_global_symbol (LIT_GLOBAL_SYMBOL_ITERATOR); + + prop_value_p = ecma_create_named_data_property (obj_p, + symbol_p, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE, + NULL); + ecma_deref_ecma_string (symbol_p); + prop_value_p->value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_INTRINSIC_OBJECT), + LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES); + + JERRY_ASSERT (ecma_is_value_object (prop_value_p->value)); + ecma_deref_object (ecma_get_object_from_value (prop_value_p->value)); +#endif /* ENABLED (JERRY_ES2015) */ + /* 13. */ if (!is_strict) { diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index cd442c450..c7ed458b0 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -235,7 +235,7 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */ ecma_value_t obj_value = ecma_make_object_value (obj_p); ecma_value_t exotic_to_prim = ecma_op_get_method_by_symbol_id (obj_value, - LIT_MAGIC_STRING_TO_PRIMITIVE); + LIT_GLOBAL_SYMBOL_TO_PRIMITIVE); if (ECMA_IS_VALUE_ERROR (exotic_to_prim)) { diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 613d62d9a..ab12b51aa 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -945,6 +945,21 @@ ecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */ } /* ecma_op_object_get_by_magic_id */ #if ENABLED (JERRY_ES2015) +/** + * [[Get]] a well-known symbol by the given property id + * + * @return pointer to the requested well-known symbol + */ +ecma_string_t * +ecma_op_get_global_symbol (lit_magic_string_id_t property_id) /**< property symbol id */ +{ + ecma_value_t symbol_value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_INTRINSIC_OBJECT), + property_id); + JERRY_ASSERT (ecma_is_value_symbol (symbol_value)); + + return ecma_get_symbol_from_value (symbol_value); +} /* ecma_op_get_global_symbol */ + /** * [[Get]] operation of ecma object where the property is a well-known symbol * @@ -955,13 +970,8 @@ ecma_value_t ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, /**< the object */ lit_magic_string_id_t property_id) /**< property symbol id */ { - ecma_value_t symbol_value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_SYMBOL), - property_id); - JERRY_ASSERT (ecma_is_value_symbol (symbol_value)); - - ecma_string_t *symbol_p = ecma_get_symbol_from_value (symbol_value); + ecma_string_t *symbol_p = ecma_op_get_global_symbol (property_id); ecma_value_t ret_value = ecma_op_object_get (object_p, symbol_p); - ecma_deref_ecma_string (symbol_p); return ret_value; @@ -979,10 +989,8 @@ ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, /**< the object */ * raised error - otherwise */ static ecma_value_t -ecma_op_get_method_by_id (ecma_value_t value, /**< ecma value */ - lit_magic_string_id_t id, /**< property magic id */ - bool is_symbol_id) /**< true - if id represents a symbol id - * false - otherwise */ +ecma_op_get_method (ecma_value_t value, /**< ecma value */ + ecma_string_t *prop_name_p) /** property name */ { /* 2. */ ecma_value_t obj_value = ecma_op_to_object (value); @@ -995,14 +1003,7 @@ ecma_op_get_method_by_id (ecma_value_t value, /**< ecma value */ ecma_object_t *obj_p = ecma_get_object_from_value (obj_value); ecma_value_t func; - if (is_symbol_id) - { - func = ecma_op_object_get_by_symbol_id (obj_p, id); - } - else - { - func = ecma_op_object_get_by_magic_id (obj_p, id); - } + func = ecma_op_object_get (obj_p, prop_name_p); ecma_deref_object (obj_p); /* 3. */ @@ -1026,7 +1027,7 @@ ecma_op_get_method_by_id (ecma_value_t value, /**< ecma value */ /* 6. */ return func; -} /* ecma_op_get_method_by_id */ +} /* ecma_op_get_method */ /** * GetMethod operation when the property is a well-known symbol @@ -1043,7 +1044,11 @@ ecma_value_t ecma_op_get_method_by_symbol_id (ecma_value_t value, /**< ecma value */ lit_magic_string_id_t symbol_id) /**< property symbol id */ { - return ecma_op_get_method_by_id (value, symbol_id, true); + ecma_string_t *prop_name_p = ecma_op_get_global_symbol (symbol_id); + ecma_value_t ret_value = ecma_op_get_method (value, prop_name_p); + ecma_deref_ecma_string (prop_name_p); + + return ret_value; } /* ecma_op_get_method_by_symbol_id */ /** @@ -1061,7 +1066,7 @@ ecma_value_t ecma_op_get_method_by_magic_id (ecma_value_t value, /**< ecma value */ lit_magic_string_id_t magic_id) /**< property magic id */ { - return ecma_op_get_method_by_id (value, magic_id, false); + return ecma_op_get_method (value, ecma_get_magic_string (magic_id)); } /* ecma_op_get_method_by_magic_id */ #endif /* ENABLED (JERRY_ES2015) */ @@ -2568,7 +2573,7 @@ ecma_op_is_concat_spreadable (ecma_value_t arg) /**< argument */ } ecma_value_t spreadable = ecma_op_object_get_by_symbol_id (ecma_get_object_from_value (arg), - LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE); + LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE); if (ECMA_IS_VALUE_ERROR (spreadable)) { @@ -2604,7 +2609,7 @@ ecma_op_is_regexp (ecma_value_t arg) /**< argument */ } ecma_value_t is_regexp = ecma_op_object_get_by_symbol_id (ecma_get_object_from_value (arg), - LIT_MAGIC_STRING_MATCH); + LIT_GLOBAL_SYMBOL_MATCH); if (ECMA_IS_VALUE_ERROR (is_regexp)) { @@ -2653,7 +2658,7 @@ ecma_op_species_constructor (ecma_object_t *this_value, /**< This Value */ } ecma_object_t *ctor_object_p = ecma_get_object_from_value (constructor); - ecma_value_t species = ecma_op_object_get_by_symbol_id (ctor_object_p, LIT_MAGIC_STRING_SPECIES); + ecma_value_t species = ecma_op_object_get_by_symbol_id (ctor_object_p, LIT_GLOBAL_SYMBOL_SPECIES); ecma_deref_object (ctor_object_p); if (ECMA_IS_VALUE_ERROR (species)) diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index b68e32628..e666a9f36 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -43,6 +43,7 @@ ecma_value_t ecma_op_object_get_length (ecma_object_t *object_p, uint32_t *lengt ecma_value_t ecma_op_object_get_by_uint32_index (ecma_object_t *object_p, uint32_t index); ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id); #if ENABLED (JERRY_ES2015) +ecma_string_t *ecma_op_get_global_symbol (lit_magic_string_id_t property_id); ecma_value_t ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, lit_magic_string_id_t property_id); ecma_value_t ecma_op_get_method_by_symbol_id (ecma_value_t value, lit_magic_string_id_t symbol_id); ecma_value_t ecma_op_get_method_by_magic_id (ecma_value_t value, lit_magic_string_id_t magic_id); diff --git a/jerry-core/ecma/operations/ecma-reference.c b/jerry-core/ecma/operations/ecma-reference.c index 5be8fac51..40a5c99bf 100644 --- a/jerry-core/ecma/operations/ecma-reference.c +++ b/jerry-core/ecma/operations/ecma-reference.c @@ -113,7 +113,7 @@ ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, /**< lexical environment * ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); - ecma_value_t unscopables = ecma_op_object_get_by_symbol_id (binding_obj_p, LIT_MAGIC_STRING_UNSCOPABLES); + ecma_value_t unscopables = ecma_op_object_get_by_symbol_id (binding_obj_p, LIT_GLOBAL_SYMBOL_UNSCOPABLES); if (ECMA_IS_VALUE_ERROR (unscopables)) { diff --git a/jerry-core/lit/lit-magic-strings.h b/jerry-core/lit/lit-magic-strings.h index 92e378937..304b3cdeb 100644 --- a/jerry-core/lit/lit-magic-strings.h +++ b/jerry-core/lit/lit-magic-strings.h @@ -49,6 +49,7 @@ typedef enum LIT_INTERNAL_MAGIC_STRING_ITERATOR_NEXT_INDEX, /**< [[%Iterator%NextIndex]] property */ LIT_INTERNAL_MAGIC_STRING_MAP_KEY, /**< Property key used when an object is a key in a map object */ LIT_INTERNAL_MAGIC_API_INTERNAL, /**< Property key used to add non-visible JS properties from the public API */ + LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, /**< %ArrayProto_values% intrinsic routine */ /* List of well known symbols */ LIT_GLOBAL_SYMBOL_HAS_INSTANCE, /**< @@hasInstance well known symbol */ LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE, /**< @@isConcatSpreadable well known symbol */ diff --git a/jerry-core/vm/opcodes-ecma-relational-equality.c b/jerry-core/vm/opcodes-ecma-relational-equality.c index 0a45ae098..a811e90f7 100644 --- a/jerry-core/vm/opcodes-ecma-relational-equality.c +++ b/jerry-core/vm/opcodes-ecma-relational-equality.c @@ -111,7 +111,7 @@ opfunc_instanceof (ecma_value_t left_value, /**< left value */ } #if ENABLED (JERRY_ES2015) - ecma_value_t has_instance_method = ecma_op_get_method_by_symbol_id (right_value, LIT_MAGIC_STRING_HAS_INSTANCE); + ecma_value_t has_instance_method = ecma_op_get_method_by_symbol_id (right_value, LIT_GLOBAL_SYMBOL_HAS_INSTANCE); if (ECMA_IS_VALUE_ERROR (has_instance_method)) { return has_instance_method; diff --git a/tests/jerry/es2015/arguments-iterator.js b/tests/jerry/es2015/arguments-iterator.js new file mode 100644 index 000000000..d98499aba --- /dev/null +++ b/tests/jerry/es2015/arguments-iterator.js @@ -0,0 +1,50 @@ +// 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. + +var arrayPrototypeValues = Array.prototype.values; + +function f_mapped() { + assert(typeof arguments[Symbol.iterator] === 'function'); + assert(arguments[Symbol.iterator] === arrayPrototypeValues); + assert(Object.hasOwnProperty.call(arguments, Symbol.iterator)); + + let sum = 0; + for (a of arguments) { + sum += a; + } + return sum; +}; + +function f_unmapped(b = 2) { + assert(typeof arguments[Symbol.iterator] === 'function'); + assert(arguments[Symbol.iterator] === arrayPrototypeValues); + assert(Object.hasOwnProperty.call(arguments, Symbol.iterator)); + + let sum = 0; + for (a of arguments) { + sum += a; + } + return sum; +}; + +assert(f_mapped(1, 2, 3, 4, 5) === 15); +assert(f_unmapped(1, 2, 3, 4, 5) === 15); + +Object.defineProperty(Array.prototype, "values", { get : function () { + /* should not be executed */ + assert(false); +}}); + +assert(f_mapped(1, 2, 3, 4, 5) === 15); +assert(f_unmapped(1, 2, 3, 4, 5) === 15);