From a25b824509da0f698eea5c6b3c2038a3f308c3ab Mon Sep 17 00:00:00 2001 From: batizdaniel Date: Tue, 10 Aug 2021 17:19:25 +0200 Subject: [PATCH] Implement {Array, %TypedArray%, String}.prototype.at method (#4681) The following methods were implemented: - Array.prototype.at based on ECMA-262 Stage 3 Draft Relative Indexing Method proposal - String.prototype.at based on ECMA-262 Stage 3 Draft Relative Indexing Method proposal - TypedArray.prototype.at based on ECMA-262 Stage 3 Draft Relative Indexing Method proposal https://tc39.es/proposal-relative-indexing-method/ JerryScript-DCO-1.0-Signed-off-by: Daniel Batiz batizjob@gmail.com --- ...-builtin-array-prototype-unscopables.inc.h | 4 + .../ecma-builtin-array-prototype.c | 34 ++++++++ .../ecma-builtin-array-prototype.inc.h | 1 + .../builtin-objects/ecma-builtin-helpers.c | 54 ++++++++++++ .../builtin-objects/ecma-builtin-helpers.h | 3 + .../ecma-builtin-string-prototype.c | 34 ++++++++ .../ecma-builtin-string-prototype.inc.h | 1 + .../ecma-builtin-typedarray-prototype.c | 31 +++++++ .../ecma-builtin-typedarray-prototype.inc.h | 1 + jerry-core/lit/lit-magic-strings.inc.h | 16 ++++ jerry-core/lit/lit-magic-strings.ini | 1 + tests/jerry/es.next/array-prototype-at.js | 50 +++++++++++ .../es.next/regression-test-issue-3606.js | 2 +- tests/jerry/es.next/string-prototype-at.js | 50 +++++++++++ .../jerry/es.next/typedarray-prototype-at.js | 82 +++++++++++++++++++ 15 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 tests/jerry/es.next/array-prototype-at.js create mode 100644 tests/jerry/es.next/string-prototype-at.js create mode 100644 tests/jerry/es.next/typedarray-prototype-at.js diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.inc.h index 55594f784..932c3d4c2 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.inc.h @@ -21,6 +21,10 @@ #if JERRY_ESNEXT +SIMPLE_VALUE (LIT_MAGIC_STRING_AT, + ECMA_VALUE_TRUE, + ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) + SIMPLE_VALUE (LIT_MAGIC_STRING_COPY_WITHIN, ECMA_VALUE_TRUE, ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) 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 a42a40356..1cf5bea25 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -60,6 +60,7 @@ enum ECMA_ARRAY_PROTOTYPE_SLICE, ECMA_ARRAY_PROTOTYPE_SPLICE, ECMA_ARRAY_PROTOTYPE_UNSHIFT, + ECMA_ARRAY_PROTOTYPE_AT, ECMA_ARRAY_PROTOTYPE_INDEX_OF, ECMA_ARRAY_PROTOTYPE_LAST_INDEX_OF, /* Note these 3 routines must be in this order */ @@ -1609,6 +1610,32 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg return ecma_make_number_value (new_len); } /* ecma_builtin_array_prototype_object_unshift */ +/** + * The Array.prototype object's 'at' routine + * + * See also: + * ECMA-262 Stage 3 Draft Relative Indexing Method proposal + * from: https://tc39.es/proposal-relative-indexing-method + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_array_prototype_object_at (const ecma_value_t index, /**< index argument */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ +{ + ecma_length_t res_index; + ecma_value_t return_value = ecma_builtin_helper_calculate_index (index, len, &res_index); + + if (return_value != ECMA_VALUE_EMPTY) + { + return return_value; + } + + return ecma_op_object_get_by_index (obj_p, res_index); +} /* ecma_builtin_array_prototype_object_at */ + /** * The Array.prototype object's 'indexOf' routine * @@ -3012,6 +3039,13 @@ ecma_builtin_array_prototype_dispatch_routine (uint8_t builtin_routine_id, /**< length); break; } + case ECMA_ARRAY_PROTOTYPE_AT: + { + ret_value = ecma_builtin_array_prototype_object_at (routine_arg_1, + obj_p, + length); + break; + } case ECMA_ARRAY_PROTOTYPE_INDEX_OF: { ret_value = ecma_builtin_array_prototype_object_index_of (arguments_list_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 82b6a74b4..387c3a486 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 @@ -58,6 +58,7 @@ ROUTINE (LIT_MAGIC_STRING_REVERSE, ECMA_ARRAY_PROTOTYPE_REVERSE, 0, 0) ROUTINE (LIT_MAGIC_STRING_SHIFT, ECMA_ARRAY_PROTOTYPE_SHIFT, 0, 0) ROUTINE (LIT_MAGIC_STRING_SLICE, ECMA_ARRAY_PROTOTYPE_SLICE, 2, 2) ROUTINE (LIT_MAGIC_STRING_SORT, ECMA_ARRAY_PROTOTYPE_SORT, 1, 1) +ROUTINE (LIT_MAGIC_STRING_AT, ECMA_ARRAY_PROTOTYPE_AT, 1, 1) ROUTINE (LIT_MAGIC_STRING_SPLICE, ECMA_ARRAY_PROTOTYPE_SPLICE, NON_FIXED, 2) ROUTINE (LIT_MAGIC_STRING_UNSHIFT, ECMA_ARRAY_PROTOTYPE_UNSHIFT, NON_FIXED, 1) ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ECMA_ARRAY_PROTOTYPE_INDEX_OF, 2, 1) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index 375c94936..d00f202c6 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -817,6 +817,60 @@ ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, /**< object */ return ret_value; } /* ecma_builtin_helper_def_prop_by_index */ +/** + * Helper function for at() functions. + * + * See also: + * ECMA-262 Stage 3 Draft Relative Indexing Method proposal 3. 4. 5. 6. + * + * Used by: + * - The Array.prototype.at routine. + * - The String.prototype.at routine. + * - The TypedArray.prototype.at routine. + * + * @return ECMA_VALUE_ERROR - on conversion error + * ECMA_VALUE_UNDEFINED - if the requested index is not exist + * ECMA_VALUE_EMPTY - otherwise + */ +ecma_value_t +ecma_builtin_helper_calculate_index (ecma_value_t index, /**< relative index argument */ + ecma_length_t length, /**< object's length */ + ecma_length_t *out_index) /**< calculated index */ +{ + JERRY_ASSERT (out_index != NULL); + + ecma_number_t relative_index; + ecma_value_t conversion_result = ecma_op_to_integer (index, &relative_index); + + /* 4. */ + if (ECMA_IS_VALUE_ERROR (conversion_result)) + { + return ECMA_VALUE_ERROR; + } + + /* 5. 6. */ + ecma_number_t k; + + if (relative_index >= 0) + { + k = relative_index; + } + else + { + k = ((ecma_number_t) length + relative_index); + } + + /* 7. */ + if (k < 0 || k >= ((ecma_number_t) length)) + { + return ECMA_VALUE_UNDEFINED; + } + + *out_index = (ecma_length_t) k; + + return ECMA_VALUE_EMPTY; +} /* ecma_builtin_helper_calculate_index */ + /** * Helper function for using [[DefineOwnProperty]]. * diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 45dd5b845..90aae7d95 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -65,6 +65,9 @@ ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *name_p, ecma_ ecma_value_t ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, ecma_length_t index, ecma_value_t value, uint32_t opts); +ecma_value_t +ecma_builtin_helper_calculate_index (ecma_value_t index, ecma_length_t length, ecma_length_t *out_index); + /** * Context for replace substitutions */ 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 76792dad2..377bc0fe0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -61,6 +61,7 @@ enum ECMA_STRING_PROTOTYPE_CONCAT, ECMA_STRING_PROTOTYPE_SLICE, + ECMA_STRING_PROTOTYPE_AT, ECMA_STRING_PROTOTYPE_LOCALE_COMPARE, @@ -920,6 +921,34 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**< return ecma_make_string_value (new_str_p); } /* ecma_builtin_string_prototype_object_slice */ +/** + * The String.prototype object's 'at' routine + * + * See also: + * ECMA-262 Stage 3 Draft Relative Indexing Method proposal + * from: https://tc39.es/proposal-relative-indexing-method + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_string_prototype_object_at (ecma_string_t *string_val, /**< this argument */ + const ecma_value_t index) /**< index argument */ +{ + ecma_length_t len = (ecma_length_t) ecma_string_get_length (string_val); + ecma_length_t res_index; + ecma_value_t return_value = ecma_builtin_helper_calculate_index (index, len, &res_index); + + if (return_value != ECMA_VALUE_EMPTY) + { + return return_value; + } + + ecma_char_t character = ecma_string_get_char_at_pos (string_val, (lit_utf8_size_t) res_index); + + return ecma_make_string_value (ecma_new_ecma_string_from_code_unit (character)); +} /* ecma_builtin_string_prototype_object_at */ + /** * The String.prototype object's 'split' routine * @@ -1536,6 +1565,11 @@ ecma_builtin_string_prototype_dispatch_routine (uint8_t builtin_routine_id, /**< ret_value = ecma_builtin_string_prototype_object_slice (string_p, arg1, arg2); break; } + case ECMA_STRING_PROTOTYPE_AT: + { + ret_value = ecma_builtin_string_prototype_object_at (string_p, arg1); + break; + } case ECMA_STRING_PROTOTYPE_LAST_INDEX_OF: case ECMA_STRING_PROTOTYPE_INDEX_OF: #if JERRY_ESNEXT diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h index 10d28ddb9..5e78ffeda 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.inc.h @@ -43,6 +43,7 @@ ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ECMA_STRING_PROTOTYPE_TO_STRING, 0, 0) ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ECMA_STRING_PROTOTYPE_VALUE_OF, 0, 0) ROUTINE (LIT_MAGIC_STRING_CONCAT, ECMA_STRING_PROTOTYPE_CONCAT, NON_FIXED, 1) ROUTINE (LIT_MAGIC_STRING_SLICE, ECMA_STRING_PROTOTYPE_SLICE, 2, 2) +ROUTINE (LIT_MAGIC_STRING_AT, ECMA_STRING_PROTOTYPE_AT, 1, 1) ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ECMA_STRING_PROTOTYPE_INDEX_OF, 2, 1) ROUTINE (LIT_MAGIC_STRING_LAST_INDEX_OF_UL, ECMA_STRING_PROTOTYPE_LAST_INDEX_OF, 2, 1) ROUTINE (LIT_MAGIC_STRING_CHAR_AT_UL, ECMA_STRING_PROTOTYPE_CHAR_AT, 1, 1) diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c index bae1fb3cd..8b017ffc1 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c @@ -65,6 +65,7 @@ enum ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FIND_INDEX, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_INDEX_OF, + ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_AT, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_LAST_INDEX_OF, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_INCLUDES, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FILL, @@ -1297,6 +1298,32 @@ ecma_builtin_typedarray_prototype_find_helper (ecma_value_t this_arg, /**< this return is_find ? ECMA_VALUE_UNDEFINED : ecma_make_integer_value (-1); } /* ecma_builtin_typedarray_prototype_find_helper */ +/** + * The %TypedArray%.prototype object's 'at' routine + * + * See also: + * ECMA-262 Stage 3 Draft Relative Indexing Method proposal + * from: https://tc39.es/proposal-relative-indexing-method + * + * @return ecma value + * Returned value must be freed with ecma_free_value. + */ +static ecma_value_t +ecma_builtin_typedarray_prototype_at (ecma_typedarray_info_t *info_p, /**< object info */ + const ecma_value_t index) /**< index argument */ +{ + ecma_length_t len = (ecma_length_t) info_p->length; + ecma_length_t res_index; + ecma_value_t return_value = ecma_builtin_helper_calculate_index (index, len, &res_index); + + if (return_value != ECMA_VALUE_EMPTY) + { + return return_value; + } + + return ecma_get_typedarray_element (info_p, (ecma_number_t) res_index); +} /* ecma_builtin_typedarray_prototype_at */ + /** * The %TypedArray%.prototype object's 'indexOf' routine * @@ -1855,6 +1882,10 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id, arguments_list_p[1], is_find); } + case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_AT: + { + return ecma_builtin_typedarray_prototype_at (&info, arguments_list_p[0]); + } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_INDEX_OF: { return ecma_builtin_typedarray_prototype_index_of (&info, arguments_list_p, arguments_number); diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.inc.h b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.inc.h index 8bb73ac2c..a5bf4cfdf 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.inc.h +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.inc.h @@ -61,6 +61,7 @@ ROUTINE (LIT_MAGIC_STRING_FIND, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FIND, 2, 1) ROUTINE (LIT_MAGIC_STRING_FIND_INDEX, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FIND_INDEX, 2, 1) ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FOR_EACH, 2, 1) ROUTINE (LIT_MAGIC_STRING_INCLUDES, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_INCLUDES, NON_FIXED, 1) +ROUTINE (LIT_MAGIC_STRING_AT, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_AT, 1, 1) ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_INDEX_OF, NON_FIXED, 1) ROUTINE (LIT_MAGIC_STRING_JOIN, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_JOIN, 1, 1) ROUTINE (LIT_MAGIC_STRING_KEYS, ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_KEYS, 0, 0) diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index fe0a6b0f3..2f5590eb4 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -37,6 +37,12 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR, "]") #if JERRY_BUILTIN_MATH LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PI_U, "PI") #endif +#if JERRY_BUILTIN_ARRAY \ +|| JERRY_BUILTIN_STRING \ +|| JERRY_BUILTIN_TYPEDARRAY \ +|| JERRY_ESNEXT +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_AT, "at") +#endif #if JERRY_ESNEXT LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_IS, "is") #endif @@ -1014,6 +1020,11 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_E_U) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_LEFT_SQUARE_CHAR) #elif JERRY_BUILTIN_MATH LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_PI_U) +#elif JERRY_BUILTIN_ARRAY \ +|| JERRY_BUILTIN_STRING \ +|| JERRY_BUILTIN_TYPEDARRAY \ +|| JERRY_ESNEXT +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_AT) #elif JERRY_ESNEXT LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_IS) #elif JERRY_BUILTIN_ARRAY && JERRY_ESNEXT \ @@ -1029,6 +1040,11 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (1, LIT_MAGIC_STRING_NAN) #endif #if JERRY_BUILTIN_MATH LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_PI_U) +#elif JERRY_BUILTIN_ARRAY \ +|| JERRY_BUILTIN_STRING \ +|| JERRY_BUILTIN_TYPEDARRAY \ +|| JERRY_ESNEXT +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_AT) #elif JERRY_ESNEXT LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_IS) #elif JERRY_BUILTIN_ARRAY && JERRY_ESNEXT \ diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini index 83f1e54f3..a52e429ff 100644 --- a/jerry-core/lit/lit-magic-strings.ini +++ b/jerry-core/lit/lit-magic-strings.ini @@ -30,6 +30,7 @@ LIT_MAGIC_STRING_E_U = "E" LIT_MAGIC_STRING_LEFT_SQUARE_CHAR = "[" LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR = "]" LIT_MAGIC_STRING_PI_U = "PI" +LIT_MAGIC_STRING_AT = "at" LIT_MAGIC_STRING_IS = "is" LIT_MAGIC_STRING_OF = "of" LIT_MAGIC_STRING_LN2_U = "LN2" diff --git a/tests/jerry/es.next/array-prototype-at.js b/tests/jerry/es.next/array-prototype-at.js new file mode 100644 index 000000000..903e3e44a --- /dev/null +++ b/tests/jerry/es.next/array-prototype-at.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 obj = {}; +var array = ['Apple', 'Banana', "zero", 0, obj, 'Apple']; + +var index = array.at(0); +assert(index === 'Apple'); +assert(array[index] === undefined); + +assert(array.at(array.length) === undefined); +assert(array.at(array.length+1) === undefined); +assert(array.at(array.length-1) === 'Apple'); +assert(array.at("1") === 'Banana'); +assert(array.at(-1) === 'Apple'); +assert(array.at("-1") === 'Apple'); +assert(array.at("-20") === undefined); + +/* 7 */ +var obj = {} +obj.length = 1; +Object.defineProperty(obj, '0', { 'get' : function () {throw new ReferenceError ("foo"); } }); +obj.at = Array.prototype.at; + +try { + obj.at(0); + assert(false); +} catch(e) { + assert(e.message === "foo"); + assert(e instanceof ReferenceError); +} + +try { + Array.prototype.at.call(undefined) + assert (false); +} catch(e) { + assert(e instanceof TypeError); +} diff --git a/tests/jerry/es.next/regression-test-issue-3606.js b/tests/jerry/es.next/regression-test-issue-3606.js index 8c9e127ec..3554eef11 100644 --- a/tests/jerry/es.next/regression-test-issue-3606.js +++ b/tests/jerry/es.next/regression-test-issue-3606.js @@ -13,5 +13,5 @@ // limitations under the License. -var expected = '{"copyWithin":true,"entries":true,"fill":true,"find":true,"findIndex":true,"flat":true,"flatMap":true,"includes":true,"keys":true,"values":true}'; +var expected = '{"at":true,"copyWithin":true,"entries":true,"fill":true,"find":true,"findIndex":true,"flat":true,"flatMap":true,"includes":true,"keys":true,"values":true}'; assert(JSON.stringify(Array.prototype[Symbol.unscopables]) === expected); diff --git a/tests/jerry/es.next/string-prototype-at.js b/tests/jerry/es.next/string-prototype-at.js new file mode 100644 index 000000000..d620a2bde --- /dev/null +++ b/tests/jerry/es.next/string-prototype-at.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 str = 'This is an Apple'; + +/* Basic tests */ +var index = str.at(0); +assert(index === 'T'); +assert(str[index] === undefined); + +assert(str.at(str.length) === undefined); +assert(str.at(str.length+1) === undefined); +assert(str.at(str.length-1) === 'e'); +assert(str.at("1") === 'h'); +assert(str.at(-1) === 'e'); +assert(str.at("-1") === 'e'); +assert(str.at("-20") === undefined); + +try { + String.prototype.at.call(undefined) + assert (false); +} catch(e) { + assert(e instanceof TypeError); +} + +var obj = {toString: function() { return "Apple"; } }; +obj.at = String.prototype.at; +assert(obj.at(0) === 'A'); + +/* BigInteger as num and char */ +assert(str.at("1n") === 'T') + +try { + str.at (10n); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} diff --git a/tests/jerry/es.next/typedarray-prototype-at.js b/tests/jerry/es.next/typedarray-prototype-at.js new file mode 100644 index 000000000..a12c5f5f3 --- /dev/null +++ b/tests/jerry/es.next/typedarray-prototype-at.js @@ -0,0 +1,82 @@ +/* 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. + */ + +/* Integer */ +var normal_typedarrays = [ + new Int8Array([0, 1, 2, 3, 0, 5, 6]), + new Uint8Array([0, 1, 2, 3, 0, 5, 6]), + new Uint8ClampedArray([0, 1, 2, 3, 0, 5, 6]), + new Int16Array([0, 1, 2, 3, 0, 5, 6]), + new Uint16Array([0, 1, 2, 3, 0, 5, 6]), + new Int32Array([0, 1, 2, 3, 0, 5, 6]), + new Uint32Array([0, 1, 2, 3, 0, 5, 6]), +]; + +/* Float */ +var float_typedarrays = [ + new Float32Array([1.5, 1.5, 2.5, 3.5, 0.5, 5.5, 10.5]), + new Float64Array([1.5, 2.5, 3.5, 0.5, 5.5, 6.5, 10.5]), +]; + +/* BigInt */ +var bigint_typedarrays = [ + new BigInt64Array([3n, 10n, 2n, 3n, 4n, 5n, 6n]), + new BigUint64Array([3n, 1n, 2n, 3n, 33n, 5n, 6n]) +]; + +var index = normal_typedarrays[0].at(0); +assert(index === 0); +assert(normal_typedarrays[index].at(0) === 0); + +/* Integer input */ +normal_typedarrays.forEach(function(e){ + assert(e.at(normal_typedarrays[1].length) === undefined); + assert(e.at(normal_typedarrays[2].length+1) === undefined); + assert(e.at(normal_typedarrays[3].length-1) === 6); + assert(e.at(0) === 0); + assert(e.at("-1") === 6); + assert(e.at(-1) === 6); + assert(e.at("-20") === undefined); + assert(e.at(100) === undefined) +}); + +/* Float input */ +float_typedarrays.forEach(function(f){ + assert(f.at(float_typedarrays[1].length) === undefined); + assert(f.at(0) === 1.5); + assert(f.at("-1") === 10.5); + assert(f.at(-1) === 10.5); + assert(f.at("-20") === undefined); + assert(f.at(100) === undefined) +}); + +/* BigInt input */ +bigint_typedarrays.forEach(function(b){ + assert(b.at(bigint_typedarrays[1].length) === undefined); + assert(b.at(0) === 3n); + assert(b.at("-1") === 6n); + assert(b.at(-1) === 6n); + assert(b.at("-20") === undefined); + assert(b.at(100) === undefined) +}); + +normal_typedarrays.forEach(function(e){ + try { + e.prototype.at.call(undefined); + assert(false); + } catch(e) { + assert(e instanceof TypeError); + } +});