From 9d4c2315f3a59e83dff1c4f2c3c76423a12f5982 Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Mon, 24 Jun 2019 11:18:37 +0200 Subject: [PATCH] Implement the Map/Set iterator operations (#2882) JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- jerry-core/ecma/base/ecma-gc.c | 13 +- jerry-core/ecma/base/ecma-globals.h | 26 +- jerry-core/ecma/base/ecma-helpers-string.c | 8 +- jerry-core/ecma/base/ecma-helpers.h | 4 +- .../ecma-builtin-array-iterator-prototype.c | 6 +- .../ecma-builtin-array-prototype.c | 8 +- .../ecma-builtin-map-iterator-prototype.c | 67 ++++ .../ecma-builtin-map-iterator-prototype.inc.h | 34 ++ .../ecma-builtin-map-prototype.c | 72 ++++- .../ecma-builtin-map-prototype.inc.h | 6 + .../ecma/builtin-objects/ecma-builtin-map.c | 5 +- .../ecma-builtin-set-iterator-prototype.c | 67 ++++ .../ecma-builtin-set-iterator-prototype.inc.h | 34 ++ .../ecma-builtin-set-prototype.c | 78 ++++- .../ecma-builtin-set-prototype.inc.h | 8 +- .../ecma/builtin-objects/ecma-builtin-set.c | 5 +- .../ecma/builtin-objects/ecma-builtins.inc.h | 18 ++ .../ecma/operations/ecma-container-object.c | 293 +++++++++++++++--- .../ecma/operations/ecma-container-object.h | 23 +- .../ecma/operations/ecma-iterator-object.c | 2 +- jerry-core/ecma/operations/ecma-objects.c | 14 + jerry-core/lit/lit-magic-strings.inc.h | 37 ++- jerry-core/lit/lit-magic-strings.ini | 2 + tests/jerry/es2015/map-iterators.js | 124 ++++++++ tests/jerry/es2015/set-iterators.js | 108 +++++++ 25 files changed, 953 insertions(+), 109 deletions(-) create mode 100644 jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.c create mode 100644 jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.inc.h create mode 100644 jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.c create mode 100644 jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.inc.h create mode 100644 tests/jerry/es2015/map-iterators.js create mode 100644 tests/jerry/es2015/set-iterators.js diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 402b1ae02..969d2be35 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -18,6 +18,7 @@ */ #include "ecma-alloc.h" +#include "ecma-container-object.h" #include "ecma-globals.h" #include "ecma-gc.h" #include "ecma-helpers.h" @@ -36,9 +37,6 @@ #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) #include "ecma-promise-object.h" #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) -#include "ecma-container-object.h" -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ /* TODO: Extract GC to a separate component */ @@ -395,6 +393,8 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) case ECMA_PSEUDO_ARRAY_ITERATOR: + case ECMA_PSEUDO_SET_ITERATOR: + case ECMA_PSEUDO_MAP_ITERATOR: { ecma_value_t iterated_value = ext_object_p->u.pseudo_array.u2.iterated_value; if (!ecma_is_value_empty (iterated_value)) @@ -710,6 +710,11 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ #if ENABLED (JERRY_ES2015_BUILTIN_SET) case LIT_MAGIC_STRING_SET_UL: + { + ecma_op_container_clear_map ((ecma_map_object_t *) object_p); + ecma_dealloc_extended_object (object_p, sizeof (ecma_map_object_t)); + return; + } #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ #if ENABLED (JERRY_ES2015_BUILTIN_MAP) case LIT_MAGIC_STRING_MAP_UL: @@ -820,6 +825,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) case ECMA_PSEUDO_ARRAY_ITERATOR: + case ECMA_PSEUDO_SET_ITERATOR: + case ECMA_PSEUDO_MAP_ITERATOR: { ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t)); return; diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 53b9496ce..d42b143fe 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -628,8 +628,9 @@ typedef enum ECMA_PSEUDO_ARRAY_TYPEDARRAY = 1, /**< TypedArray which does NOT need extra space to store length and offset */ ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO = 2, /**< TypedArray which NEEDS extra space to store length and offset */ ECMA_PSEUDO_ARRAY_ITERATOR = 3, /**< Array iterator object (ECMAScript v6, 22.1.5.1) */ - ECMA_PSEUDO_STRING_ITERATOR = 4, /**< Array iterator object (ECMAScript v6, 22.1.5.1) */ - + ECMA_PSEUDO_SET_ITERATOR = 4, /**< Set iterator object (ECMAScript v6, 23.2.5.1) */ + ECMA_PSEUDO_MAP_ITERATOR = 5, /**< Map iterator object (ECMAScript v6, 23.1.5.1) */ + ECMA_PSEUDO_STRING_ITERATOR = 6, /**< String iterator object (ECMAScript v6, 22.1.5.1) */ ECMA_PSEUDO_ARRAY__MAX = ECMA_PSEUDO_STRING_ITERATOR /**< maximum value */ } ecma_pseudo_array_type_t; @@ -657,10 +658,10 @@ typedef enum */ typedef enum { - ECMA_ARRAY_ITERATOR_KEYS, /**< List only key indices */ - ECMA_ARRAY_ITERATOR_VALUES, /**< List only key values */ - ECMA_ARRAY_ITERATOR_KEYS_VALUES, /**< List key indices and values */ -} ecma_array_iterator_type_t; + 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; #endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ /** @@ -918,23 +919,16 @@ typedef struct #endif /* ENABLED (JERRY_ES2015_ARROW_FUNCTION) */ -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) - +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) /** - * Map item count of chunks - */ -#define ECMA_MAP_OBJECT_ITEM_COUNT 3 - -/** - * Description of Map objects. + * Description of Map/Set objects. */ typedef struct { ecma_extended_object_t header; /**< header part */ uint32_t size; /**< size of the map object */ } ecma_map_object_t; - -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ /** * Description of ECMA property descriptor diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 8d60cc3fb..f249eb901 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -237,7 +237,7 @@ ecma_prop_name_is_symbol (ecma_string_t *string_p) /**< ecma-string */ } /* ecma_prop_name_is_symbol */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) /** * Allocate new ecma-string and fill it with reference to the map key descriptor * @@ -270,7 +270,7 @@ ecma_prop_name_is_map_key (ecma_string_t *string_p) /**< ecma-string */ return (!ECMA_IS_DIRECT_STRING (string_p) && ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAP_KEY); } /* ecma_prop_name_is_map_key */ -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ /** * Allocate new ecma-string and fill it with characters from the utf8 string @@ -1038,13 +1038,13 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */ break; } #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) case ECMA_STRING_CONTAINER_MAP_KEY: { ecma_free_value_if_not_object (string_p->u.value); break; } -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ default: { JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 8bf30a33a..4a6655e96 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -222,10 +222,10 @@ lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value); ecma_string_t *ecma_new_symbol_from_descriptor_string (ecma_value_t string_desc); bool ecma_prop_name_is_symbol (ecma_string_t *string_p); #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) ecma_string_t *ecma_new_map_key_string (ecma_value_t value); bool ecma_prop_name_is_map_key (ecma_string_t *string_p); -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size); ecma_string_t *ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c index 7c7db5959..ab3c17464 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c @@ -155,7 +155,7 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t /* 7. */ uint8_t iterator_type = ext_obj_p->u.pseudo_array.extra_info; - if (iterator_type == ECMA_ARRAY_ITERATOR_KEYS) + if (iterator_type == ECMA_ITERATOR_KEYS) { /* 12. */ return ecma_create_iter_result_object (ecma_make_uint32_value (index), ECMA_VALUE_FALSE); @@ -177,14 +177,14 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t ecma_value_t result; /* 16. */ - if (iterator_type == ECMA_ARRAY_ITERATOR_VALUES) + if (iterator_type == ECMA_ITERATOR_VALUES) { result = ecma_create_iter_result_object (get_value, ECMA_VALUE_FALSE); } else { /* 17.a */ - JERRY_ASSERT (iterator_type == ECMA_ARRAY_ITERATOR_KEYS_VALUES); + JERRY_ASSERT (iterator_type == ECMA_ITERATOR_KEYS_VALUES); /* 17.b */ ecma_value_t entry_array_value; 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 7b3ff023f..17ec8c811 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -2088,7 +2088,7 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback static ecma_value_t ecma_builtin_array_iterators_helper (ecma_object_t *obj_p, /**< array object */ uint8_t type) /**< any combination of - * ecma_array_iterator_type_t bits */ + * ecma_iterator_type_t bits */ { ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_ITERATOR_PROTOTYPE); @@ -2150,18 +2150,18 @@ ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< if (builtin_routine_id == ECMA_ARRAY_PROTOTYPE_ENTRIES) { - ret_value = ecma_builtin_array_iterators_helper (obj_p, ECMA_ARRAY_ITERATOR_KEYS_VALUES); + 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_ARRAY_ITERATOR_KEYS); + ret_value = ecma_builtin_array_iterators_helper (obj_p, ECMA_ITERATOR_KEYS); } 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_ARRAY_ITERATOR_VALUES); + ret_value = ecma_builtin_array_iterators_helper (obj_p, ECMA_ITERATOR_VALUES); } ecma_deref_object (obj_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.c new file mode 100644 index 000000000..aea9071bb --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.c @@ -0,0 +1,67 @@ +/* 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-builtin-helpers.h" +#include "ecma-builtins.h" +#include "ecma-container-object.h" + +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) + +#if !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +#error "Map iterator builtin requires ES2015 iterator builtin" +#endif /* !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-map-iterator-prototype.inc.h" +#define BUILTIN_UNDERSCORED_ID map_iterator_prototype +#include "ecma-builtin-internal-routines-template.inc.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup %mapiteratorprototype% ECMA %MapIteratorPrototype% object built-in + * @{ + */ + +/** + * The %MapIteratorPrototype% object's 'next' routine + * + * See also: + * ECMA-262 v6, 23.1.5.2.1 + * + * Note: + * Returned value must be freed with ecma_free_value. + * + * @return iterator result object, if success + * error - otherwise + */ +static ecma_value_t +ecma_builtin_map_iterator_prototype_object_next (ecma_value_t this_val) /**< this argument */ +{ + return ecma_op_container_iterator_next (this_val, ECMA_PSEUDO_MAP_ITERATOR); +} /* ecma_builtin_map_iterator_prototype_object_next */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.inc.h new file mode 100644 index 000000000..8f3b326e8 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.inc.h @@ -0,0 +1,34 @@ +/* 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. + */ + +/* + * %MapIteratorPrototype% built-in description + */ + +#include "ecma-builtin-helpers-macro-defines.inc.h" + +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) + +STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG, + LIT_MAGIC_STRING_MAP_ITERATOR_UL, + ECMA_PROPERTY_FLAG_CONFIGURABLE) + +/* Routine properties: + * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ +ROUTINE (LIT_MAGIC_STRING_NEXT, ecma_builtin_map_iterator_prototype_object_next, 0, 0) + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ + +#include "ecma-builtin-helpers-macro-undefs.inc.h" diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c index de6d8b1af..31266bd7a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c @@ -46,7 +46,7 @@ static ecma_value_t ecma_builtin_map_prototype_object_clear (ecma_value_t this_arg) /**< this argument */ { - return ecma_op_container_clear (this_arg, false); + return ecma_op_container_clear (this_arg, LIT_MAGIC_STRING_MAP_UL); } /* ecma_builtin_map_prototype_object_clear */ /** @@ -62,7 +62,7 @@ static ecma_value_t ecma_builtin_map_prototype_object_delete (ecma_value_t this_arg, /**< this argument */ ecma_value_t key_arg) /**< key argument */ { - return ecma_op_container_delete (this_arg, key_arg, false); + return ecma_op_container_delete (this_arg, key_arg, LIT_MAGIC_STRING_MAP_UL); } /* ecma_builtin_map_prototype_object_delete */ /** @@ -80,7 +80,7 @@ ecma_builtin_map_prototype_object_foreach (ecma_value_t this_arg, /**< this argu ecma_value_t predicate_this_arg) /**< this argument for * invoke predicate */ { - return ecma_op_container_foreach (this_arg, predicate, predicate_this_arg, false); + return ecma_op_container_foreach (this_arg, predicate, predicate_this_arg, LIT_MAGIC_STRING_MAP_UL); } /* ecma_builtin_map_prototype_object_foreach */ /** @@ -112,7 +112,7 @@ static ecma_value_t ecma_builtin_map_prototype_object_has (ecma_value_t this_arg, /**< this argument */ ecma_value_t key_arg) /**< key argument */ { - return ecma_op_container_has (this_arg, key_arg, false); + return ecma_op_container_has (this_arg, key_arg, LIT_MAGIC_STRING_MAP_UL); } /* ecma_builtin_map_prototype_object_has */ /** @@ -129,7 +129,7 @@ ecma_builtin_map_prototype_object_set (ecma_value_t this_arg, /**< this argument ecma_value_t key_arg, /**< key argument */ ecma_value_t value_arg) /**< value argument */ { - return ecma_op_container_set (this_arg, key_arg, value_arg, false); + return ecma_op_container_set (this_arg, key_arg, value_arg, LIT_MAGIC_STRING_MAP_UL); } /* ecma_builtin_map_prototype_object_set */ /** @@ -144,9 +144,69 @@ ecma_builtin_map_prototype_object_set (ecma_value_t this_arg, /**< this argument static ecma_value_t ecma_builtin_map_prototype_object_size_getter (ecma_value_t this_arg) /**< this argument */ { - return ecma_op_container_size (this_arg, false); + return ecma_op_container_size (this_arg, LIT_MAGIC_STRING_MAP_UL); } /* ecma_builtin_map_prototype_object_size_getter */ +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +/** + * The Map.prototype object's 'entries' routine + * + * See also: + * ECMA-262 v6, 23.1.3.4 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_map_prototype_object_entries (ecma_value_t this_arg) /**< this argument */ +{ + return ecma_op_container_create_iterator (this_arg, + ECMA_ITERATOR_KEYS_VALUES, + LIT_MAGIC_STRING_MAP_UL, + ECMA_BUILTIN_ID_MAP_ITERATOR_PROTOTYPE, + ECMA_PSEUDO_MAP_ITERATOR); +} /* ecma_builtin_map_prototype_object_entries */ + +/** + * The Map.prototype object's 'keys' routine + * + * See also: + * ECMA-262 v6, 23.1.3.8 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_map_prototype_object_keys (ecma_value_t this_arg) /**< this argument */ +{ + return ecma_op_container_create_iterator (this_arg, + ECMA_ITERATOR_KEYS, + LIT_MAGIC_STRING_MAP_UL, + ECMA_BUILTIN_ID_MAP_ITERATOR_PROTOTYPE, + ECMA_PSEUDO_MAP_ITERATOR); +} /* ecma_builtin_map_prototype_object_keys */ + +/** + * The Map.prototype object's 'values' routine + * + * See also: + * ECMA-262 v6, 23.1.3.11 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_map_prototype_object_values (ecma_value_t this_arg) /**< this argument */ +{ + return ecma_op_container_create_iterator (this_arg, + ECMA_ITERATOR_VALUES, + LIT_MAGIC_STRING_MAP_UL, + ECMA_BUILTIN_ID_MAP_ITERATOR_PROTOTYPE, + ECMA_PSEUDO_MAP_ITERATOR); +} /* ecma_builtin_map_prototype_object_values */ + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ + /** * @} * @} diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h index 628647e68..c7d7bc7cb 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h @@ -44,6 +44,12 @@ ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_map_prototype_object_foreach ROUTINE (LIT_MAGIC_STRING_GET, ecma_builtin_map_prototype_object_get, 1, 1) ROUTINE (LIT_MAGIC_STRING_HAS, ecma_builtin_map_prototype_object_has, 1, 1) ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_map_prototype_object_set, 2, 2) +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +ROUTINE (LIT_MAGIC_STRING_ENTRIES, ecma_builtin_map_prototype_object_entries, 0, 0) +ROUTINE (LIT_MAGIC_STRING_VALUES, ecma_builtin_map_prototype_object_values, 0, 0) +ROUTINE (LIT_MAGIC_STRING_KEYS, ecma_builtin_map_prototype_object_keys, 0, 0) +ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ecma_builtin_map_prototype_object_values, 0, 0) +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ /* ECMA-262 v6, 23.1.3.10 */ ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_SIZE, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-map.c b/jerry-core/ecma/builtin-objects/ecma-builtin-map.c index fe8886f99..644753c85 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-map.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-map.c @@ -59,7 +59,10 @@ ecma_value_t ecma_builtin_map_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< number of arguments */ { - return ecma_op_container_create (arguments_list_p, arguments_list_len, false); + return ecma_op_container_create (arguments_list_p, + arguments_list_len, + LIT_MAGIC_STRING_MAP_UL, + ECMA_BUILTIN_ID_MAP_PROTOTYPE); } /* ecma_builtin_map_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.c new file mode 100644 index 000000000..6a0f5d141 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.c @@ -0,0 +1,67 @@ +/* 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-builtin-helpers.h" +#include "ecma-builtins.h" +#include "ecma-container-object.h" + +#if ENABLED (JERRY_ES2015_BUILTIN_SET) + +#if !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +#error "Set iterator builtin requires ES2015 iterator builtin" +#endif /* !ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-set-iterator-prototype.inc.h" +#define BUILTIN_UNDERSCORED_ID set_iterator_prototype +#include "ecma-builtin-internal-routines-template.inc.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup %setiteratorprototype% ECMA %SetIteratorPrototype% object built-in + * @{ + */ + +/** + * The %SetIteratorPrototype% object's 'next' routine + * + * See also: + * ECMA-262 v6, 23.2.5.2.1 + * + * Note: + * Returned value must be freed with ecma_free_value. + * + * @return iterator result object, if success + * error - otherwise + */ +static ecma_value_t +ecma_builtin_set_iterator_prototype_object_next (ecma_value_t this_val) /**< this argument */ +{ + return ecma_op_container_iterator_next (this_val, ECMA_PSEUDO_SET_ITERATOR); +} /* ecma_builtin_set_iterator_prototype_object_next */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.inc.h new file mode 100644 index 000000000..a19399163 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.inc.h @@ -0,0 +1,34 @@ +/* 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. + */ + +/* + * %SetIteratorPrototype% built-in description + */ + +#include "ecma-builtin-helpers-macro-defines.inc.h" + +#if ENABLED (JERRY_ES2015_BUILTIN_SET) + +STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG, + LIT_MAGIC_STRING_SET_ITERATOR_UL, + ECMA_PROPERTY_FLAG_CONFIGURABLE) + +/* Routine properties: + * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ +ROUTINE (LIT_MAGIC_STRING_NEXT, ecma_builtin_set_iterator_prototype_object_next, 0, 0) + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ + +#include "ecma-builtin-helpers-macro-undefs.inc.h" diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.c index c052721b2..af5d1ffa8 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.c @@ -17,10 +17,6 @@ #if ENABLED (JERRY_ES2015_BUILTIN_SET) -#if !ENABLED (JERRY_ES2015_BUILTIN_MAP) -#error "Set builtin requires ES2015 map builtin" -#endif /* !ENABLED (JERRY_ES2015_BUILTIN_MAP) */ - #define ECMA_BUILTINS_INTERNAL #include "ecma-builtins-internal.h" @@ -51,7 +47,7 @@ static ecma_value_t ecma_builtin_set_prototype_object_add (ecma_value_t this_arg, /**< this argument */ ecma_value_t value_arg) /**< value argument */ { - return ecma_op_container_set (this_arg, value_arg, value_arg, true); + return ecma_op_container_set (this_arg, value_arg, value_arg, LIT_MAGIC_STRING_SET_UL); } /* ecma_builtin_set_prototype_object_add */ /** @@ -66,7 +62,7 @@ ecma_builtin_set_prototype_object_add (ecma_value_t this_arg, /**< this argument static ecma_value_t ecma_builtin_set_prototype_object_clear (ecma_value_t this_arg) /**< this argument */ { - return ecma_op_container_clear (this_arg, true); + return ecma_op_container_clear (this_arg, LIT_MAGIC_STRING_SET_UL); } /* ecma_builtin_set_prototype_object_clear */ /** @@ -82,7 +78,7 @@ static ecma_value_t ecma_builtin_set_prototype_object_delete (ecma_value_t this_arg, /**< this argument */ ecma_value_t value_arg) /**< value argument */ { - return ecma_op_container_delete (this_arg, value_arg, true); + return ecma_op_container_delete (this_arg, value_arg, LIT_MAGIC_STRING_SET_UL); } /* ecma_builtin_set_prototype_object_delete */ /** @@ -100,7 +96,7 @@ ecma_builtin_set_prototype_object_foreach (ecma_value_t this_arg, /**< this argu ecma_value_t predicate_this_arg) /**< this argument for * invoke predicate */ { - return ecma_op_container_foreach (this_arg, predicate, predicate_this_arg, true); + return ecma_op_container_foreach (this_arg, predicate, predicate_this_arg, LIT_MAGIC_STRING_SET_UL); } /* ecma_builtin_set_prototype_object_foreach */ /** @@ -116,7 +112,7 @@ static ecma_value_t ecma_builtin_set_prototype_object_has (ecma_value_t this_arg, /**< this argument */ ecma_value_t value_arg) /**< value argument */ { - return ecma_op_container_has (this_arg, value_arg, true); + return ecma_op_container_has (this_arg, value_arg, LIT_MAGIC_STRING_SET_UL); } /* ecma_builtin_set_prototype_object_has */ /** @@ -131,13 +127,73 @@ ecma_builtin_set_prototype_object_has (ecma_value_t this_arg, /**< this argument static ecma_value_t ecma_builtin_set_prototype_object_size_getter (ecma_value_t this_arg) /**< this argument */ { - return ecma_op_container_size (this_arg, true); + return ecma_op_container_size (this_arg, LIT_MAGIC_STRING_SET_UL); } /* ecma_builtin_set_prototype_object_size_getter */ +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +/** + * The Set.prototype object's 'entries' routine + * + * See also: + * ECMA-262 v6, 23.2.3.5 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_set_prototype_object_entries (ecma_value_t this_arg) /**< this argument */ +{ + return ecma_op_container_create_iterator (this_arg, + ECMA_ITERATOR_KEYS_VALUES, + LIT_MAGIC_STRING_SET_UL, + ECMA_BUILTIN_ID_SET_ITERATOR_PROTOTYPE, + ECMA_PSEUDO_SET_ITERATOR); +} /* ecma_builtin_set_prototype_object_entries */ + +/** + * The Set.prototype object's 'keys' routine + * + * See also: + * ECMA-262 v6, 23.2.3.8 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_set_prototype_object_keys (ecma_value_t this_arg) /**< this argument */ +{ + return ecma_op_container_create_iterator (this_arg, + ECMA_ITERATOR_KEYS, + LIT_MAGIC_STRING_SET_UL, + ECMA_BUILTIN_ID_SET_ITERATOR_PROTOTYPE, + ECMA_PSEUDO_SET_ITERATOR); +} /* ecma_builtin_set_prototype_object_keys */ + +/** + * The Set.prototype object's 'values' routine + * + * See also: + * ECMA-262 v6, 23.2.3.10 + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_set_prototype_object_values (ecma_value_t this_arg) /**< this argument */ +{ + return ecma_op_container_create_iterator (this_arg, + ECMA_ITERATOR_VALUES, + LIT_MAGIC_STRING_SET_UL, + ECMA_BUILTIN_ID_SET_ITERATOR_PROTOTYPE, + ECMA_PSEUDO_SET_ITERATOR); +} /* ecma_builtin_set_prototype_object_values */ + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ + /** * @} * @} * @} */ -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.inc.h index d6bf0d5df..a0356127a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-set-prototype.inc.h @@ -26,7 +26,7 @@ /* ECMA-262 v6, 23.2.3.2 */ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR, - ECMA_BUILTIN_ID_MAP, + ECMA_BUILTIN_ID_SET, ECMA_PROPERTY_CONFIGURABLE_WRITABLE) #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) @@ -43,6 +43,12 @@ ROUTINE (LIT_MAGIC_STRING_CLEAR, ecma_builtin_set_prototype_object_clear, 0, 0) ROUTINE (LIT_MAGIC_STRING_DELETE, ecma_builtin_set_prototype_object_delete, 1, 1) ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_set_prototype_object_foreach, 2, 1) ROUTINE (LIT_MAGIC_STRING_HAS, ecma_builtin_set_prototype_object_has, 1, 1) +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +ROUTINE (LIT_MAGIC_STRING_ENTRIES, ecma_builtin_set_prototype_object_entries, 0, 0) +ROUTINE (LIT_MAGIC_STRING_VALUES, ecma_builtin_set_prototype_object_values, 0, 0) +ROUTINE (LIT_MAGIC_STRING_KEYS, ecma_builtin_set_prototype_object_keys, 0, 0) +ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ecma_builtin_set_prototype_object_values, 0, 0) +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_SIZE, ecma_builtin_set_prototype_object_size_getter, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-set.c b/jerry-core/ecma/builtin-objects/ecma-builtin-set.c index 297b5c489..e6f6187a9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-set.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-set.c @@ -59,7 +59,10 @@ ecma_value_t ecma_builtin_set_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< number of arguments */ { - return ecma_op_container_create (arguments_list_p, arguments_list_len, true); + return ecma_op_container_create (arguments_list_p, + arguments_list_len, + LIT_MAGIC_STRING_SET_UL, + ECMA_BUILTIN_ID_SET_PROTOTYPE); } /* ecma_builtin_set_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index 4ce9b56eb..dd490990e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -497,6 +497,24 @@ BUILTIN (ECMA_BUILTIN_ID_STRING_ITERATOR_PROTOTYPE, ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE, true, string_iterator_prototype) + +#if ENABLED (JERRY_ES2015_BUILTIN_SET) +/* The %SetIteratorPrototype% object (ECMA-262 v6, 23.2.5.2) */ +BUILTIN (ECMA_BUILTIN_ID_SET_ITERATOR_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE, + true, + set_iterator_prototype) +#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ + +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +/* The %MapIteratorPrototype% object (ECMA-262 v6, 23.1.5.2) */ +BUILTIN (ECMA_BUILTIN_ID_MAP_ITERATOR_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE, + true, + map_iterator_prototype) +#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) diff --git a/jerry-core/ecma/operations/ecma-container-object.c b/jerry-core/ecma/operations/ecma-container-object.c index b22bc6729..498de7503 100644 --- a/jerry-core/ecma/operations/ecma-container-object.c +++ b/jerry-core/ecma/operations/ecma-container-object.c @@ -24,7 +24,7 @@ #include "ecma-property-hashmap.h" #include "ecma-objects.h" -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) /** \addtogroup ecma ECMA * @{ @@ -59,19 +59,17 @@ ecma_op_container_create_internal_object (void) ecma_value_t ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len, /**< number of arguments */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id, /**< internal class id */ + ecma_builtin_id_t proto_id) /**< prototype builtin id */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); - ecma_object_t *proto_p = ecma_builtin_get (is_set ? ECMA_BUILTIN_ID_SET_PROTOTYPE : ECMA_BUILTIN_ID_MAP_PROTOTYPE); - - ecma_object_t *object_p = ecma_create_object (proto_p, + ecma_object_t *object_p = ecma_create_object (ecma_builtin_get (proto_id), sizeof (ecma_map_object_t), ECMA_OBJECT_TYPE_CLASS); ecma_map_object_t *map_obj_p = (ecma_map_object_t *) object_p; - map_obj_p->header.u.class_prop.class_id = is_set ? LIT_MAGIC_STRING_SET_UL : LIT_MAGIC_STRING_MAP_UL; + map_obj_p->header.u.class_prop.class_id = lit_id; map_obj_p->header.u.class_prop.u.value = ecma_op_container_create_internal_object (); map_obj_p->size = 0; @@ -125,9 +123,9 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l } ecma_value_t result; - if (is_set) + if (lit_id == LIT_MAGIC_STRING_SET_UL) { - result = ecma_op_container_set (set_value, next_value, next_value, is_set); + result = ecma_op_container_set (set_value, next_value, next_value, lit_id); } else { @@ -168,7 +166,7 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l return value; } - result = ecma_op_container_set (set_value, key, value, is_set); + result = ecma_op_container_set (set_value, key, value, lit_id); ecma_free_value (key); ecma_free_value (value); @@ -207,21 +205,34 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l */ static ecma_map_object_t * ecma_op_container_get_object (ecma_value_t this_arg, /**< this argument */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { if (ecma_is_value_object (this_arg)) { ecma_map_object_t *map_object_p = (ecma_map_object_t *) ecma_get_object_from_value (this_arg); if (ecma_get_object_type (&map_object_p->header.object) == ECMA_OBJECT_TYPE_CLASS - && map_object_p->header.u.class_prop.class_id == (is_set ? LIT_MAGIC_STRING_SET_UL : LIT_MAGIC_STRING_MAP_UL)) + && map_object_p->header.u.class_prop.class_id == lit_id) { return map_object_p; } } - ecma_raise_type_error (ECMA_ERR_MSG (is_set ? "Expected a Set object." : "Expected a Map object.")); +#ifdef JERRY_ENABLE_ERROR_MESSAGES + char *msg_p = "Expected a Map object."; + +#if ENABLED (JERRY_ES2015_BUILTIN_SET) + if (lit_id == LIT_MAGIC_STRING_SET_UL) + { + msg_p = "Expected a Set object."; + } +#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ + + ecma_raise_type_error (ECMA_ERR_MSG (msg_p)); +#else /* !JERRY_ENABLE_ERROR_MESSAGES */ + ecma_raise_type_error (NULL); +#endif /* JERRY_ENABLE_ERROR_MESSAGES */ + return NULL; } /* ecma_op_container_get_object */ @@ -289,10 +300,9 @@ ecma_op_container_to_key (ecma_value_t key_arg) /**< key argument */ */ ecma_value_t ecma_op_container_size (ecma_value_t this_arg, /**< this argument */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, is_set); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); if (map_object_p == NULL) { @@ -312,7 +322,7 @@ ecma_value_t ecma_op_container_get (ecma_value_t this_arg, /**< this argument */ ecma_value_t key_arg) /**< key argument */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, false); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, LIT_MAGIC_STRING_MAP_UL); if (map_object_p == NULL) { @@ -332,7 +342,7 @@ ecma_op_container_get (ecma_value_t this_arg, /**< this argument */ ecma_deref_ecma_string (prop_name_p); - if (property_p == NULL) + if (property_p == NULL || ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)) { return ECMA_VALUE_UNDEFINED; } @@ -349,10 +359,9 @@ ecma_op_container_get (ecma_value_t this_arg, /**< this argument */ ecma_value_t ecma_op_container_has (ecma_value_t this_arg, /**< this argument */ ecma_value_t key_arg, /**< key argument */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, is_set); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); if (map_object_p == NULL) { @@ -372,7 +381,8 @@ ecma_op_container_has (ecma_value_t this_arg, /**< this argument */ ecma_deref_ecma_string (prop_name_p); - return ecma_make_boolean_value (property_p != NULL); + return ecma_make_boolean_value (property_p != NULL + && !ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)); } /* ecma_op_container_has */ /** @@ -385,10 +395,9 @@ ecma_value_t ecma_op_container_set (ecma_value_t this_arg, /**< this argument */ ecma_value_t key_arg, /**< key argument */ ecma_value_t value_arg, /**< value argument */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, is_set); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); if (map_object_p == NULL) { @@ -412,6 +421,10 @@ ecma_op_container_set (ecma_value_t this_arg, /**< this argument */ } else { + if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)) + { + map_object_p->size++; + } ecma_named_data_property_assign_value (internal_obj_p, ECMA_PROPERTY_VALUE_PTR (property_p), value_arg); } @@ -479,10 +492,9 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ ecma_value_t predicate, /**< callback function */ ecma_value_t predicate_this_arg, /**< this argument for * invoke predicate */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, is_set); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); if (map_object_p == NULL) { @@ -509,8 +521,9 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ { ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p); ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p); + JERRY_ASSERT (property_p != NULL); - if (property_p == NULL) + if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)) { ecma_value_p = ecma_collection_iterator_next (ecma_value_p); continue; @@ -519,7 +532,11 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ ecma_value_t value = ecma_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); ecma_value_t key_arg; - if (ecma_prop_name_is_map_key (prop_name_p)) + if (lit_id == LIT_MAGIC_STRING_SET_UL) + { + key_arg = value; + } + else if (ecma_prop_name_is_map_key (prop_name_p)) { key_arg = prop_name_p->u.value; } @@ -536,7 +553,7 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ } } - ecma_value_t call_args[] = { value, is_set ? value : key_arg }; + ecma_value_t call_args[] = { value, key_arg }; ecma_value_t call_value = ecma_op_function_call (func_object_p, predicate_this_arg, call_args, 2); @@ -566,10 +583,9 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ */ ecma_value_t ecma_op_container_clear (ecma_value_t this_arg, /**< this argument */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, is_set); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); if (map_object_p == NULL) { @@ -593,10 +609,9 @@ ecma_op_container_clear (ecma_value_t this_arg, /**< this argument */ ecma_value_t ecma_op_container_delete (ecma_value_t this_arg, /**< this argument */ ecma_value_t key_arg, /**< key argument */ - bool is_set) /**< true - to perform Set operations - * false - to perform Map operations */ + lit_magic_string_id_t lit_id) /**< internal class id */ { - ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, is_set); + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); if (map_object_p == NULL) { @@ -616,15 +631,213 @@ ecma_op_container_delete (ecma_value_t this_arg, /**< this argument */ return ECMA_VALUE_FALSE; } - ecma_delete_property (internal_obj_p, ECMA_PROPERTY_VALUE_PTR (property_p)); + ecma_named_data_property_assign_value (internal_obj_p, ECMA_PROPERTY_VALUE_PTR (property_p), ECMA_VALUE_EMPTY); map_object_p->size--; return ECMA_VALUE_TRUE; } /* ecma_op_container_delete */ +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) + +/** + * The Create{Set, Map}Iterator Abstract operation + * + * See also: + * ECMA-262 v6, 23.1.5.1 + * ECMA-262 v6, 23.2.5.1 + * + * Note: + * Returned value must be freed with ecma_free_value. + * + * @return set/map iterator object, if success + * error - otherwise + */ +ecma_value_t +ecma_op_container_create_iterator (ecma_value_t this_arg, /**< this argument */ + uint8_t type, /**< any combination of + * ecma_iterator_type_t bits */ + lit_magic_string_id_t lit_id, /**< internal class id */ + ecma_builtin_id_t proto_id, /**< prototype builtin id */ + ecma_pseudo_array_type_t iterator_type) /**< type of the iterator */ +{ + ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id); + + if (map_object_p == NULL) + { + return ECMA_VALUE_ERROR; + } + + return ecma_op_create_iterator_object (this_arg, + ecma_builtin_get (proto_id), + iterator_type, + type); +} /* ecma_op_container_create_iterator */ + +/** + * The %{Set, Map}IteratorPrototype% object's 'next' routine + * + * See also: + * ECMA-262 v6, 23.1.5.2.1 + * ECMA-262 v6, 23.2.5.2.1 + * + * Note: + * Returned value must be freed with ecma_free_value. + * + * @return iterator result object, if success + * error - otherwise + */ +ecma_value_t +ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */ + ecma_pseudo_array_type_t iterator_type) /**< type of the iterator */ +{ + if (!ecma_is_value_object (this_val)) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object.")); + } + + ecma_object_t *obj_p = ecma_get_object_from_value (this_val); + ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; + + if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY + && ext_obj_p->u.pseudo_array.type != iterator_type) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an iterator.")); + } + + ecma_value_t iterated_value = ext_obj_p->u.pseudo_array.u2.iterated_value; + + if (ecma_is_value_empty (iterated_value)) + { + return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE); + } + + ecma_map_object_t *map_object_p = (ecma_map_object_t *) (ecma_get_object_from_value (iterated_value)); + + ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value); + ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS); + + uint32_t length = props_p->item_count; + uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index; + + if (JERRY_UNLIKELY (index == ECMA_ITERATOR_INDEX_LIMIT)) + { + /* After the ECMA_ITERATOR_INDEX_LIMIT limit is reached the [[%Iterator%NextIndex]] + property is stored as an internal property */ + ecma_string_t *prop_name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ITERATOR_NEXT_INDEX); + + ecma_property_t *property_p = ecma_find_named_property (obj_p, prop_name_p); + ecma_property_value_t *value_p; + + if (property_p == NULL) + { + value_p = ecma_create_named_data_property (obj_p, prop_name_p, ECMA_PROPERTY_FLAG_WRITABLE, &property_p); + value_p->value = ecma_make_uint32_value (index); + } + else + { + value_p = ECMA_PROPERTY_VALUE_PTR (property_p); + index = (uint32_t) (ecma_get_number_from_value (value_p->value) + 1); + value_p->value = ecma_make_uint32_value (index); + } + } + else + { + ext_obj_p->u.pseudo_array.u1.iterator_index++; + } + + if (index >= length) + { + ext_obj_p->u.pseudo_array.u2.iterated_value = ECMA_VALUE_EMPTY; + ecma_free_values_collection (props_p, 0); + return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE); + } + + uint8_t iterator_kind = ext_obj_p->u.pseudo_array.extra_info; + + ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + + ecma_value_t ret_value = ECMA_VALUE_UNDEFINED; + + while (ecma_value_p != NULL) + { + if (index > 0) + { + index--; + ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + continue; + } + + ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p); + ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p); + JERRY_ASSERT (property_p != NULL); + + if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)) + { + ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + + if (ecma_value_p == NULL) + { + ret_value = ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE); + } + continue; + } + + ecma_value_t value = ecma_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); + ecma_value_t key_arg; + + if (iterator_type == ECMA_PSEUDO_SET_ITERATOR) + { + key_arg = value; + } + else if (ecma_prop_name_is_map_key (prop_name_p)) + { + key_arg = prop_name_p->u.value; + } + else + { + if (ECMA_IS_DIRECT_STRING (prop_name_p) + && ECMA_GET_DIRECT_STRING_TYPE (prop_name_p) == ECMA_DIRECT_STRING_ECMA_INTEGER) + { + key_arg = ecma_make_uint32_value ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (prop_name_p)); + } + else + { + key_arg = *ecma_value_p; + } + } + + if (iterator_kind == ECMA_ITERATOR_KEYS) + { + ret_value = ecma_create_iter_result_object (key_arg, ECMA_VALUE_FALSE); + } + else if (iterator_kind == ECMA_ITERATOR_VALUES) + { + ret_value = ecma_create_iter_result_object (value, ECMA_VALUE_FALSE); + } + else + { + JERRY_ASSERT (iterator_kind == ECMA_ITERATOR_KEYS_VALUES); + + ecma_value_t entry_array_value; + entry_array_value = ecma_create_array_from_iter_element (value, key_arg); + + ret_value = ecma_create_iter_result_object (entry_array_value, ECMA_VALUE_FALSE); + ecma_free_value (entry_array_value); + } + + ecma_free_value (value); + break; + } + + ecma_free_values_collection (props_p, 0); + + return ret_value; +} /* ecma_op_container_iterator_next */ + +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ /** * @} * @} */ -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ diff --git a/jerry-core/ecma/operations/ecma-container-object.h b/jerry-core/ecma/operations/ecma-container-object.h index 38e3a8130..ed8519f2a 100644 --- a/jerry-core/ecma/operations/ecma-container-object.h +++ b/jerry-core/ecma/operations/ecma-container-object.h @@ -17,8 +17,9 @@ #define ECMA_CONTAINER_OBJECT_H #include "ecma-globals.h" +#include "ecma-builtins.h" -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) /** \addtogroup ecma ECMA * @{ @@ -28,22 +29,26 @@ */ ecma_value_t ecma_op_container_create (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len, - bool is_set); -ecma_value_t ecma_op_container_size (ecma_value_t this_arg, bool is_set); + lit_magic_string_id_t lit_id, ecma_builtin_id_t proto_id); +ecma_value_t ecma_op_container_size (ecma_value_t this_arg, lit_magic_string_id_t lit_id); ecma_value_t ecma_op_container_get (ecma_value_t this_arg, ecma_value_t key_arg); ecma_value_t ecma_op_container_foreach (ecma_value_t this_arg, ecma_value_t predicate, ecma_value_t predicate_this_arg, - bool is_set); -ecma_value_t ecma_op_container_has (ecma_value_t this_arg, ecma_value_t key_arg, bool is_set); -ecma_value_t ecma_op_container_set (ecma_value_t this_arg, ecma_value_t key_arg, ecma_value_t value_arg, bool is_set); + lit_magic_string_id_t lit_id); +ecma_value_t ecma_op_container_has (ecma_value_t this_arg, ecma_value_t key_arg, lit_magic_string_id_t lit_id); +ecma_value_t ecma_op_container_set (ecma_value_t this_arg, ecma_value_t key_arg, ecma_value_t value_arg, + lit_magic_string_id_t lit_id); void ecma_op_container_clear_map (ecma_map_object_t *map_object_p); -ecma_value_t ecma_op_container_clear (ecma_value_t this_arg, bool is_set); -ecma_value_t ecma_op_container_delete (ecma_value_t this_arg, ecma_value_t key_arg, bool is_set); +ecma_value_t ecma_op_container_clear (ecma_value_t this_arg, lit_magic_string_id_t lit_id); +ecma_value_t ecma_op_container_delete (ecma_value_t this_arg, ecma_value_t key_arg, lit_magic_string_id_t lit_id); +ecma_value_t ecma_op_container_create_iterator (ecma_value_t this_arg, uint8_t type, lit_magic_string_id_t lit_id, + ecma_builtin_id_t proto_id, ecma_pseudo_array_type_t iterator_type); +ecma_value_t ecma_op_container_iterator_next (ecma_value_t this_val, ecma_pseudo_array_type_t iterator_type); /** * @} * @} */ -#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ +#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ #endif /* !ECMA_CONTAINER_OBJECT_H */ diff --git a/jerry-core/ecma/operations/ecma-iterator-object.c b/jerry-core/ecma/operations/ecma-iterator-object.c index 61d60624f..f6319d6eb 100644 --- a/jerry-core/ecma/operations/ecma-iterator-object.c +++ b/jerry-core/ecma/operations/ecma-iterator-object.c @@ -134,7 +134,7 @@ ecma_create_iter_result_object (ecma_value_t value, /**< value */ ecma_value_t ecma_op_create_iterator_object (ecma_value_t iterated_value, /**< value from create iterator */ ecma_object_t *prototype_obj_p, /**< prototype object */ - uint8_t iterator_type, /**< itertator type, see ecma_pseudo_array_type_t */ + uint8_t iterator_type, /**< iterator type, see ecma_pseudo_array_type_t */ uint8_t extra_info) /**< extra information */ { /* 1. */ diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index cb3e32475..953053127 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -1887,9 +1887,15 @@ ecma_object_check_class_name_is_object (ecma_object_t *obj_p) /**< object */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ #if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_MAP_PROTOTYPE) +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) + || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_MAP_ITERATOR_PROTOTYPE) +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ #if ENABLED (JERRY_ES2015_BUILTIN_SET) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SET_PROTOTYPE) +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) + || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SET_ITERATOR_PROTOTYPE) +#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SYMBOL_PROTOTYPE) @@ -1943,6 +1949,14 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ { return LIT_MAGIC_STRING_ARRAY_ITERATOR_UL; } + case ECMA_PSEUDO_SET_ITERATOR: + { + return LIT_MAGIC_STRING_SET_ITERATOR_UL; + } + case ECMA_PSEUDO_MAP_ITERATOR: + { + return LIT_MAGIC_STRING_MAP_ITERATOR_UL; + } #endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */ #if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) case ECMA_PSEUDO_STRING_ITERATOR: diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index 6df47ff69..199fb07fa 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -44,11 +44,12 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_OF, "of") #if ENABLED (JERRY_BUILTIN_MATH) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LN2_U, "LN2") #endif -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MAP_UL, "Map") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NAN, "NaN") -#if ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) \ || ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UL, "Set") #endif @@ -146,7 +147,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_JOIN, "join") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_KEYS, "keys") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NAME, "name") -#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NEXT, "next") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NULL, "null") @@ -324,7 +327,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SYMBOL, "symbol") || ENABLED (JERRY_BUILTIN_JSON) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_JSON_UL, "toJSON") #endif -#if ENABLED (JERRY_BUILTIN_ARRAY) && ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +#if ENABLED (JERRY_BUILTIN_ARRAY) && ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) && ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) && ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_VALUES, "values") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_BOOLEAN_UL, "Boolean") @@ -345,7 +350,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COMPILE, "compile") #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DEFAULT, "default") #endif -#if ENABLED (JERRY_BUILTIN_ARRAY) && ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) +#if ENABLED (JERRY_BUILTIN_ARRAY) && ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) && ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) && ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ENTRIES, "entries") #endif #if ENABLED (JERRY_BUILTIN_ARRAY) \ @@ -617,6 +624,14 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, "Float64Array") #if ENABLED (JERRY_BUILTIN_DATE) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_INVALID_DATE_UL, "Invalid Date") #endif +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_MAP) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MAP_ITERATOR_UL, "Map Iterator") +#endif +#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_SET) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_ITERATOR_UL, "Set Iterator") +#endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CONFIGURABLE, "configurable") #if ENABLED (JERRY_BUILTIN_STRING) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FROM_CHAR_CODE_UL, "fromCharCode") @@ -713,14 +728,16 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_PI_U) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_OF) #elif ENABLED (JERRY_BUILTIN_MATH) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_LN2_U) -#elif ENABLED (JERRY_ES2015_BUILTIN_MAP) +#elif ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_MAP_UL) #else LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_NAN) #endif #if ENABLED (JERRY_BUILTIN_MATH) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (3, LIT_MAGIC_STRING_LN2_U) -#elif ENABLED (JERRY_ES2015_BUILTIN_MAP) +#elif ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (3, LIT_MAGIC_STRING_MAP_UL) #else LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (3, LIT_MAGIC_STRING_NAN) @@ -773,6 +790,12 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_FLOAT32_ARRAY_UL) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_FLOAT64_ARRAY_UL) #elif ENABLED (JERRY_BUILTIN_DATE) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_INVALID_DATE_UL) +#elif ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_MAP) +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_MAP_ITERATOR_UL) +#elif ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) \ +|| ENABLED (JERRY_ES2015_BUILTIN_SET) +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_SET_ITERATOR_UL) #else LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_CONFIGURABLE) #endif diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini index 92e6d1719..58afef467 100644 --- a/jerry-core/lit/lit-magic-strings.ini +++ b/jerry-core/lit/lit-magic-strings.ini @@ -270,6 +270,8 @@ LIT_MAGIC_STRING_UNSCOPABLES = "unscopables" LIT_MAGIC_STRING_FLOAT32_ARRAY_UL = "Float32Array" LIT_MAGIC_STRING_FLOAT64_ARRAY_UL = "Float64Array" LIT_MAGIC_STRING_INVALID_DATE_UL = "Invalid Date" +LIT_MAGIC_STRING_SET_ITERATOR_UL = "Set Iterator" +LIT_MAGIC_STRING_MAP_ITERATOR_UL = "Map Iterator" LIT_MAGIC_STRING_CONFIGURABLE = "configurable" LIT_MAGIC_STRING_FROM_CHAR_CODE_UL = "fromCharCode" LIT_MAGIC_STRING_IS_EXTENSIBLE = "isExtensible" diff --git a/tests/jerry/es2015/map-iterators.js b/tests/jerry/es2015/map-iterators.js new file mode 100644 index 000000000..64122e3b6 --- /dev/null +++ b/tests/jerry/es2015/map-iterators.js @@ -0,0 +1,124 @@ +// 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 methods = ['entries', 'keys', 'values', Symbol.iterator]; + +methods.forEach(function (method) { + try { + Map.prototype[method].call(5); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +methods.forEach(function (method) { + try { + Map.prototype[method].call({}); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +var m = new Map([{0: '0', 1: 0}, + {0: '1', 1: 1}, + {0: '2', 1: 2}, + {0: '3', 1: 3}, + {0: '4', 1: 4}, + {0: '5', 1: 5}, + {0: '6', 1: 6}]); + +methods.forEach(function(method) { + assert(m[method]().toString() === '[object Map Iterator]'); +}); + +methods.forEach(function (method) { + try { + m[method].next.call(5); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +methods.forEach(function (method) { + try { + m[method].next.call({}); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +var valueIterators = [m.values(), m[Symbol.iterator]()]; +var keyIterator = m.keys(); +var entryIterator = m.entries(); +var elementCount = m.size; + +for (var i = 0; i < elementCount; i++) { + valueIterators.forEach(function(element) { + var next = element.next(); + assert(next.done === false); + assert(next.value === i); + }); + + var next = keyIterator.next(); + assert(next.done === false); + assert(next.value === '' + i); + + var next = entryIterator.next(); + assert(next.done === false); + assert(next.value[0] === '' + i); + assert(next.value[1] === i); +} + +valueIterators.forEach(function(element) { + var next = element.next(); + assert(next.done === true); + assert(next.value === undefined); + }); + +var next = keyIterator.next(); +assert(next.done === true); +assert(next.value === undefined); + +next = entryIterator.next(); +assert(next.done === true); +assert(next.value === undefined); + +var valueIterators = [m.values(), m[Symbol.iterator]()]; +var keyIterator = m.keys(); +var entryIterator = m.entries(); +var elementCount = m.size; + +for (var i = 0; i < elementCount; i++) { + valueIterators.forEach(function(element) { + var next = element.next(); + assert(next.done === false); + assert(next.value === i); + }); + + var next = keyIterator.next(); + assert(next.done === false); + assert(next.value === '' + i); + + var next = entryIterator.next(); + assert(next.done === false); + assert(next.value[0] === '' + i); + assert(next.value[1] === i); + m.delete('' + i); +} + +assert(m.size === 0); diff --git a/tests/jerry/es2015/set-iterators.js b/tests/jerry/es2015/set-iterators.js new file mode 100644 index 000000000..136688173 --- /dev/null +++ b/tests/jerry/es2015/set-iterators.js @@ -0,0 +1,108 @@ +// 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 methods = ['entries', 'keys', 'values', Symbol.iterator]; + +methods.forEach(function (method) { + try { + Set.prototype[method].call(5); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +methods.forEach(function (method) { + try { + Set.prototype[method].call({}); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +var s = new Set([0, 1, 2, 3, 4, 5, 6]); + +methods.forEach(function(method) { + assert(s[method]().toString() === '[object Set Iterator]'); +}); + +methods.forEach(function (method) { + try { + s[method].next.call(5); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +methods.forEach(function (method) { + try { + s[method].next.call({}); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +}); + +var setFromSet = new Set(s); +assert(setFromSet.size === 7); + +var iterators = [s.keys(), s.values(), s[Symbol.iterator]()]; +var entryIterator = s.entries(); +var elementCount = s.size; + +for (var i = 0; i < elementCount; i++) { + iterators.forEach(function(element) { + var next = element.next(); + assert(next.done === false); + assert(next.value === i); + }); + + var next = entryIterator.next(); + assert(next.done === false); + assert(next.value[0] === i); + assert(next.value[1] === i); +} + +iterators.forEach(function(element) { + var next = element.next(); + assert(next.done === true); + assert(next.value === undefined); + }); + +var next = entryIterator.next(); +assert(next.done === true); +assert(next.value === undefined); + + +iterators = [s.keys(), s.values(), s[Symbol.iterator]()]; +entryIterator = s.entries(); +var elementCount = s.size; + +for (var i = 0; i < elementCount; i++) { + iterators.forEach(function(element) { + var next = element.next(); + assert(next.done === false); + assert(next.value === i); + }); + + var next = entryIterator.next(); + assert(next.done === false); + assert(next.value[0] === i); + assert(next.value[1] === i); + s.delete(i); +} + +assert(s.size === 0);