diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 64b38da59..92ad89d44 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -1825,12 +1825,12 @@ typedef struct /** * Function callback descriptor of a %TypedArray% object getter */ -typedef ecma_number_t (*ecma_typedarray_getter_fn_t) (lit_utf8_byte_t *src); +typedef ecma_value_t (*ecma_typedarray_getter_fn_t) (lit_utf8_byte_t *src); /** * Function callback descriptor of a %TypedArray% object setter */ -typedef void (*ecma_typedarray_setter_fn_t) (lit_utf8_byte_t *src, ecma_number_t value); +typedef ecma_value_t (*ecma_typedarray_setter_fn_t) (lit_utf8_byte_t *src, ecma_value_t value); /** * Builtin id for the different types of TypedArray's @@ -1846,6 +1846,9 @@ typedef enum ECMA_UINT32_ARRAY, /**< Uint32Array */ ECMA_FLOAT32_ARRAY, /**< Float32Array */ ECMA_FLOAT64_ARRAY, /**< Float64Array */ + /* ECMA_TYPEDARRAY_IS_BIGINT_TYPE macro should be updated when new types are added */ + ECMA_BIGINT64_ARRAY, /**< BigInt64Array */ + ECMA_BIGUINT64_ARRAY, /**< BigUInt64Array */ } ecma_typedarray_type_t; /** @@ -1904,6 +1907,14 @@ typedef struct uint8_t element_size; /**< element size based on [[TypedArrayName]] in Table 49 */ } ecma_typedarray_info_t; +#if ENABLED (JERRY_BUILTIN_BIGINT) +/** + * Checks whether a given typedarray is BigInt type or not. + **/ +#define ECMA_TYPEDARRAY_IS_BIGINT_TYPE(id) \ + ((id) >= ECMA_BIGINT64_ARRAY) + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ #endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ESNEXT) 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 1af3cb64d..939ad84c1 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -2664,7 +2664,7 @@ ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments while (from_index < len) { - if (ecma_op_same_value_zero (buffer_p[from_index], args[0])) + if (ecma_op_same_value_zero (buffer_p[from_index], args[0], false)) { return ECMA_VALUE_TRUE; } @@ -2687,7 +2687,7 @@ ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments return element; } - if (ecma_op_same_value_zero (element, args[0])) + if (ecma_op_same_value_zero (element, args[0], false)) { ecma_free_value (element); return ECMA_VALUE_TRUE; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h index 99c085bfb..2a3f2783b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h @@ -192,6 +192,16 @@ OBJECT_VALUE (LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, ECMA_PROPERTY_CONFIGURABLE_WRITABLE) #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) +OBJECT_VALUE (LIT_MAGIC_STRING_BIGINT64_ARRAY_UL, + ECMA_BUILTIN_ID_BIGINT64ARRAY, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE) + +OBJECT_VALUE (LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL, + ECMA_BUILTIN_ID_BIGUINT64ARRAY, + ECMA_PROPERTY_CONFIGURABLE_WRITABLE) +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + OBJECT_VALUE (LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL, ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY, ECMA_PROPERTY_CONFIGURABLE_WRITABLE) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index 7fdcd070a..4d0579622 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -392,6 +392,20 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT64ARRAY, float64array) #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) +BUILTIN_ROUTINE (ECMA_BUILTIN_ID_BIGINT64ARRAY, + ECMA_OBJECT_TYPE_FUNCTION, + ECMA_BUILTIN_ID_TYPEDARRAY, + true, + bigint64array) + +BUILTIN_ROUTINE (ECMA_BUILTIN_ID_BIGUINT64ARRAY, + ECMA_OBJECT_TYPE_FUNCTION, + ECMA_BUILTIN_ID_TYPEDARRAY, + true, + biguint64array) +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + BUILTIN (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE, ECMA_OBJECT_TYPE_GENERAL, ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, @@ -447,6 +461,20 @@ BUILTIN (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE, true, float64array_prototype) #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + +#if ENABLED (JERRY_BUILTIN_BIGINT) +BUILTIN (ECMA_BUILTIN_ID_BIGINT64ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + bigint64array_prototype) + +BUILTIN (ECMA_BUILTIN_ID_BIGUINT64ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + biguint64array_prototype) +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ #endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_BUILTIN_PROMISE) diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array-prototype.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array-prototype.c new file mode 100644 index 000000000..0e8514bc9 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array-prototype.c @@ -0,0 +1,45 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-builtins.h" + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-bigint64array-prototype.inc.h" +#define BUILTIN_UNDERSCORED_ID bigint64array_prototype +#include "ecma-builtin-internal-routines-template.inc.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup bigint64arrayprototype ECMA BigInt64Array.prototype object built-in + * @{ + */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array-prototype.inc.h b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array-prototype.inc.h new file mode 100644 index 000000000..b5cd21aa1 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array-prototype.inc.h @@ -0,0 +1,28 @@ +/* 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. + */ + +/* + * BigInt64Array prototype description + */ + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define TYPEDARRAY_BYTES_PER_ELEMENT 8 +#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_BIGINT64ARRAY +#include "ecma-builtin-typedarray-prototype-template.inc.h" + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array.c new file mode 100644 index 000000000..231815851 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array.c @@ -0,0 +1,80 @@ +/* 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-exceptions.h" +#include "ecma-gc.h" +#include "ecma-globals.h" +#include "ecma-helpers.h" +#include "ecma-typedarray-object.h" +#include "jrt.h" + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-bigint64array.inc.h" +#define BUILTIN_UNDERSCORED_ID bigint64array +#include "ecma-builtin-internal-routines-template.inc.h" + +#include "ecma-builtin-typedarray-helpers.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup bigint64array ECMA BigInt64Array object built-in + * @{ + */ + +/** + * Handle calling [[Call]] of BigInt64Array + * + * @return ecma value + */ +ecma_value_t +ecma_builtin_bigint64array_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ + uint32_t arguments_list_len) /**< number of arguments */ +{ + JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + + return ecma_raise_type_error (ECMA_ERR_MSG ("BigInt64Array cannot be directly called")); +} /* ecma_builtin_bigint64array_dispatch_call */ + +/** + * Handle calling [[Construct]] of BigInt64Array + * + * @return ecma value + */ +ecma_value_t +ecma_builtin_bigint64array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ + uint32_t arguments_list_len) /**< number of arguments */ +{ + return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, + ECMA_BIGINT64_ARRAY); +} /* ecma_builtin_bigint64array_dispatch_construct */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array.inc.h b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array.inc.h new file mode 100644 index 000000000..9e7854f4e --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-bigint64array.inc.h @@ -0,0 +1,27 @@ +/* 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. + */ + +/* + * BigInt64Array description + */ + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) + +#define TYPEDARRAY_BYTES_PER_ELEMENT 8 +#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_BIGINT64_ARRAY_UL +#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_BIGINT64ARRAY_PROTOTYPE +#include "ecma-builtin-typedarray-template.inc.h" + +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array-prototype.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array-prototype.c new file mode 100644 index 000000000..ef1539773 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array-prototype.c @@ -0,0 +1,45 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-builtins.h" + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-biguint64array-prototype.inc.h" +#define BUILTIN_UNDERSCORED_ID biguint64array_prototype +#include "ecma-builtin-internal-routines-template.inc.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup biguint64arrayprototype ECMA BigUInt64Array.prototype object built-in + * @{ + */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array-prototype.inc.h b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array-prototype.inc.h new file mode 100644 index 000000000..2be38f862 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array-prototype.inc.h @@ -0,0 +1,28 @@ +/* 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. + */ + +/* + * BigUInt64Array prototype description + */ + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define TYPEDARRAY_BYTES_PER_ELEMENT 8 +#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_BIGUINT64ARRAY +#include "ecma-builtin-typedarray-prototype-template.inc.h" + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array.c new file mode 100644 index 000000000..e3740c43e --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array.c @@ -0,0 +1,80 @@ +/* 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-exceptions.h" +#include "ecma-gc.h" +#include "ecma-globals.h" +#include "ecma-helpers.h" +#include "ecma-typedarray-object.h" +#include "jrt.h" + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define ECMA_BUILTINS_INTERNAL +#include "ecma-builtins-internal.h" + +#define BUILTIN_INC_HEADER_NAME "ecma-builtin-biguint64array.inc.h" +#define BUILTIN_UNDERSCORED_ID biguint64array +#include "ecma-builtin-internal-routines-template.inc.h" + +#include "ecma-builtin-typedarray-helpers.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmabuiltins + * @{ + * + * \addtogroup biguint64array ECMA BigUInt64Array object built-in + * @{ + */ + +/** + * Handle calling [[Call]] of BigUInt64Array + * + * @return ecma value + */ +ecma_value_t +ecma_builtin_biguint64array_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ + uint32_t arguments_list_len) /**< number of arguments */ +{ + JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + + return ecma_raise_type_error (ECMA_ERR_MSG ("BigUInt64Array cannot be directly called")); +} /* ecma_builtin_biguint64array_dispatch_call */ + +/** + * Handle calling [[Construct]] of BigUInt64Array + * + * @return ecma value + */ +ecma_value_t +ecma_builtin_biguint64array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ + uint32_t arguments_list_len) /**< number of arguments */ +{ + return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, + ECMA_BIGUINT64_ARRAY); +} /* ecma_builtin_biguint64array_dispatch_construct */ + +/** + * @} + * @} + * @} + */ + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array.inc.h b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array.inc.h new file mode 100644 index 000000000..441411bc8 --- /dev/null +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-biguint64array.inc.h @@ -0,0 +1,29 @@ +/* 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. + */ + +/* + * BigUInt64Array description + */ + +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +#if ENABLED (JERRY_BUILTIN_BIGINT) + +#define TYPEDARRAY_BYTES_PER_ELEMENT 8 +#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL +#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_BIGUINT64ARRAY_PROTOTYPE +#include "ecma-builtin-typedarray-template.inc.h" + +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ +#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) && ENABLED (JERRY_BUILTIN_BIGINT) */ 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 9733fdcf9..042ae8d5b 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 @@ -16,6 +16,7 @@ #include #include "ecma-arraybuffer-object.h" +#include "ecma-bigint.h" #include "ecma-builtin-helpers.h" #include "ecma-builtin-typedarray-helpers.h" #include "ecma-builtins.h" @@ -219,15 +220,14 @@ ecma_builtin_typedarray_prototype_exec_routine (ecma_value_t this_arg, /**< this for (uint32_t index = 0; index < info.length && ecma_is_value_empty (ret_value); index++) { ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_number_t element_num = typedarray_getter_cb (info.buffer_p + byte_pos); - ecma_value_t get_value = ecma_make_number_value (element_num); + ecma_value_t element = typedarray_getter_cb (info.buffer_p + byte_pos); - ecma_value_t call_args[] = { get_value, current_index, this_arg }; + ecma_value_t call_args[] = { element, current_index, this_arg }; ecma_value_t call_value = ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3); ecma_fast_free_value (current_index); - ecma_fast_free_value (get_value); + ecma_fast_free_value (element); if (ECMA_IS_VALUE_ERROR (call_value)) { @@ -415,39 +415,32 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this argument for (uint32_t index = 0; index < src_info.length; index++) { ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_number_t element_num = src_typedarray_getter_cb (src_info.buffer_p + src_byte_pos); - ecma_value_t get_value = ecma_make_number_value (element_num); - ecma_value_t call_args[] = { get_value, current_index, this_arg }; + ecma_value_t element = src_typedarray_getter_cb (src_info.buffer_p + src_byte_pos); + + ecma_value_t call_args[] = { element, current_index, this_arg }; ecma_value_t mapped_value = ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3); + + ecma_free_value (current_index); + ecma_free_value (element); + if (ECMA_IS_VALUE_ERROR (mapped_value)) { - ecma_free_value (current_index); - ecma_free_value (get_value); ecma_free_value (new_typedarray); return mapped_value; } - ecma_number_t mapped_num; - if (ECMA_IS_VALUE_ERROR (ecma_op_to_numeric (mapped_value, &mapped_num, ECMA_TO_NUMERIC_NO_OPTS))) + uint32_t target_byte_pos = index << target_info.shift; + ecma_value_t set_element = target_typedarray_setter_cb (target_info.buffer_p + target_byte_pos, mapped_value); + ecma_free_value (mapped_value); + + if (ECMA_IS_VALUE_ERROR (set_element)) { - ecma_free_value (mapped_value); - ecma_free_value (current_index); - ecma_free_value (get_value); ecma_free_value (new_typedarray); - return ECMA_VALUE_ERROR; - } - else - { - uint32_t target_byte_pos = index << target_info.shift; - target_typedarray_setter_cb (target_info.buffer_p + target_byte_pos, mapped_num); + return set_element; } src_byte_pos += src_info.element_size; - - ecma_fast_free_value (mapped_value); - ecma_fast_free_value (current_index); - ecma_fast_free_value (get_value); } return new_typedarray; @@ -506,8 +499,10 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, if (ecma_is_value_undefined (initial_val)) { byte_pos = index << info.shift; - ecma_number_t acc_num = getter_cb (info.buffer_p + byte_pos); - accumulator = ecma_make_number_value (acc_num); + ecma_value_t acc_value = getter_cb (info.buffer_p + byte_pos); + accumulator = ecma_copy_value (acc_value); + + ecma_free_value (acc_value); JERRY_ASSERT (ecma_is_value_number (accumulator)); @@ -541,8 +536,7 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, { ecma_value_t current_index = ecma_make_uint32_value (index); byte_pos = index << info.shift; - ecma_number_t get_num = getter_cb (info.buffer_p + byte_pos); - ecma_value_t get_value = ecma_make_number_value (get_num); + ecma_value_t get_value = getter_cb (info.buffer_p + byte_pos); ecma_value_t call_args[] = { accumulator, get_value, current_index, this_arg }; @@ -673,8 +667,7 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum for (uint32_t index = 0; index < info.length; index++) { ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_number_t get_num = getter_cb (info.buffer_p + byte_pos); - ecma_value_t get_value = ecma_make_number_value (get_num); + ecma_value_t get_value = getter_cb (info.buffer_p + byte_pos); JERRY_ASSERT (ecma_is_value_number (get_value)); @@ -842,8 +835,15 @@ ecma_op_typedarray_set_with_typedarray (ecma_value_t this_arg, /**< this argumen uint32_t src_byte_index = 0; while (target_byte_index < limit) { - ecma_number_t elem_num = src_typedarray_getter_cb (src_info.buffer_p + src_byte_index); - target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, elem_num); + ecma_value_t element = src_typedarray_getter_cb (src_info.buffer_p + src_byte_index); + ecma_value_t set_element = target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, element); + ecma_free_value (element); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + return set_element; + } + src_byte_index += src_info.element_size; target_byte_index += target_info.element_size; } @@ -947,19 +947,46 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument return elem; } - ecma_number_t elem_num; + ecma_value_t value_to_set; - if (ECMA_IS_VALUE_ERROR (ecma_op_to_numeric (elem, &elem_num, ECMA_TO_NUMERIC_NO_OPTS))) +#if ENABLED (JERRY_BUILTIN_BIGINT) + if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (target_info.id)) { - ecma_free_value (elem); - ecma_deref_object (source_obj_p); - return ECMA_VALUE_ERROR; + value_to_set = ecma_bigint_to_bigint (elem, true); + + if (ECMA_IS_VALUE_ERROR (value_to_set)) + { + ecma_deref_object (source_obj_p); + ecma_free_value (elem); + return value_to_set; + } + } + else +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + { + ecma_number_t elem_num; + if (ECMA_IS_VALUE_ERROR (ecma_op_to_numeric (elem, &elem_num, ECMA_TO_NUMERIC_NO_OPTS))) + { + ecma_free_value (elem); + ecma_deref_object (source_obj_p); + return ECMA_VALUE_ERROR; + } + + value_to_set = ecma_make_number_value (elem_num); } - target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, elem_num); - ecma_free_value (elem); + ecma_value_t set_element = target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, value_to_set); + + ecma_free_value (value_to_set); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + ecma_deref_object (source_obj_p); + return set_element; + } + k++; target_byte_index += target_info.element_size; } @@ -1233,16 +1260,33 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray.")); } - ecma_number_t value_num; - ecma_value_t ret_value = ecma_op_to_numeric (value, &value_num, ECMA_TO_NUMERIC_NO_OPTS); - - if (!ecma_is_value_empty (ret_value)) - { - return ret_value; - } - ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + ecma_value_t value_to_set; + +#if ENABLED (JERRY_BUILTIN_BIGINT) + if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info.id)) + { + value_to_set = ecma_bigint_to_bigint (value, true); + + if (ECMA_IS_VALUE_ERROR (value_to_set)) + { + return value_to_set; + } + } + else +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + { + ecma_number_t value_num; + ecma_value_t ret_value = ecma_op_to_numeric (value, &value_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (!ecma_is_value_empty (ret_value)) + { + return ret_value; + } + + value_to_set = ecma_make_number_value (value_num); + } uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; @@ -1280,10 +1324,19 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen while (byte_index < limit) { - typedarray_setter_cb (info.buffer_p + byte_index, value_num); + ecma_value_t set_element = typedarray_setter_cb (info.buffer_p + byte_index, value_to_set); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + ecma_free_value (value_to_set); + return set_element; + } + byte_index += info.element_size; } + ecma_free_value (value_to_set); + return ecma_copy_value (this_arg); } /* ecma_builtin_typedarray_prototype_fill */ @@ -1420,8 +1473,7 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen while (byte_index < limit) { JERRY_ASSERT (buffer_index < info.length); - ecma_number_t element_num = typedarray_getter_cb (info.buffer_p + byte_index); - ecma_value_t element_value = ecma_make_number_value (element_num); + ecma_value_t element_value = typedarray_getter_cb (info.buffer_p + byte_index); values_buffer[buffer_index++] = element_value; byte_index += info.element_size; } @@ -1438,31 +1490,37 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen if (ECMA_IS_VALUE_ERROR (sort_value)) { ret_value = sort_value; + goto free_values; } - else + + JERRY_ASSERT (sort_value == ECMA_VALUE_EMPTY); + + ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (info.id); + + byte_index = 0; + buffer_index = 0; + limit = info.length * info.element_size; + /* Put sorted values from the native array back into the typedarray buffer. */ + while (byte_index < limit) { - JERRY_ASSERT (sort_value == ECMA_VALUE_EMPTY); + JERRY_ASSERT (buffer_index < info.length); + ecma_value_t element_value = values_buffer[buffer_index++]; + ecma_value_t set_element = typedarray_setter_cb (info.buffer_p + byte_index, element_value); - ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (info.id); - - byte_index = 0; - buffer_index = 0; - limit = info.length * info.element_size; - /* Put sorted values from the native array back into the typedarray buffer. */ - while (byte_index < limit) + if (ECMA_IS_VALUE_ERROR (set_element)) { - JERRY_ASSERT (buffer_index < info.length); - ecma_value_t element_value = values_buffer[buffer_index++]; - ecma_number_t element_num = ecma_get_number_from_value (element_value); - typedarray_setter_cb (info.buffer_p + byte_index, element_num); - byte_index += info.element_size; + ret_value = set_element; + goto free_values; } - JERRY_ASSERT (buffer_index == info.length); - - ret_value = ecma_copy_value (this_arg); + byte_index += info.element_size; } + JERRY_ASSERT (buffer_index == info.length); + + ret_value = ecma_copy_value (this_arg); + +free_values: /* Free values that were copied to the local array. */ for (uint32_t index = 0; index < info.length; index++) { @@ -1517,16 +1575,15 @@ ecma_builtin_typedarray_prototype_find_helper (ecma_value_t this_arg, /**< this for (uint32_t byte_index = 0; byte_index < limit; byte_index += info.element_size) { JERRY_ASSERT (buffer_index < info.length); - ecma_number_t element_num = typedarray_getter_cb (info.buffer_p + byte_index); - ecma_value_t element_value = ecma_make_number_value (element_num); + ecma_value_t element_value = typedarray_getter_cb (info.buffer_p + byte_index); ecma_value_t call_args[] = { element_value, ecma_make_uint32_value (buffer_index), this_arg }; - ecma_value_t call_value = ecma_op_function_call (func_object_p, predicate_this_arg, call_args, 3); + ecma_free_value (element_value); + if (ECMA_IS_VALUE_ERROR (call_value)) { - ecma_free_value (element_value); return call_value; } @@ -1540,11 +1597,10 @@ ecma_builtin_typedarray_prototype_find_helper (ecma_value_t this_arg, /**< this return element_value; } - ecma_free_value (element_value); return ecma_make_uint32_value (buffer_index); } + buffer_index++; - ecma_free_value (element_value); } return is_find ? ECMA_VALUE_UNDEFINED : ecma_make_integer_value (-1); @@ -1607,6 +1663,13 @@ ecma_builtin_typedarray_prototype_index_of (ecma_value_t this_arg, /**< this arg ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + +#if ENABLED (JERRY_BUILTIN_BIGINT) + bool is_bigint = ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info.id); +#else /* !ENABLED (JERRY_BUILTIN_BIGINT) */ + bool is_bigint = false; +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + if (ecma_arraybuffer_is_detached (info.array_buffer_p)) { return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached.")); @@ -1617,7 +1680,7 @@ ecma_builtin_typedarray_prototype_index_of (ecma_value_t this_arg, /**< this arg /* 5. */ if (args_number == 0 - || !ecma_is_value_number (args[0]) + || (!ecma_is_value_number (args[0]) && !is_bigint) || info.length == 0) { return ecma_make_integer_value (-1); @@ -1645,8 +1708,6 @@ ecma_builtin_typedarray_prototype_index_of (ecma_value_t this_arg, /**< this arg : (uint32_t) (info.length + num_var)); } - ecma_number_t search_num = ecma_get_number_from_value (args[0]); - ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.id); /* 11. */ @@ -1654,12 +1715,15 @@ ecma_builtin_typedarray_prototype_index_of (ecma_value_t this_arg, /**< this arg (uint32_t) position < limit; position += info.element_size) { - ecma_number_t element_num = getter_cb (info.buffer_p + position); + ecma_value_t element = getter_cb (info.buffer_p + position); - if (search_num == element_num) + if (ecma_op_same_value_zero (args[0], element, true)) { + ecma_free_value (element); return ecma_make_number_value ((ecma_number_t) position / info.element_size); } + + ecma_free_value (element); } /* 12. */ @@ -1687,6 +1751,13 @@ ecma_builtin_typedarray_prototype_last_index_of (ecma_value_t this_arg, /**< thi ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + +#if ENABLED (JERRY_BUILTIN_BIGINT) + bool is_bigint = ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info.id); +#else /* !ENABLED (JERRY_BUILTIN_BIGINT) */ + bool is_bigint = false; +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + if (ecma_arraybuffer_is_detached (info.array_buffer_p)) { return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached.")); @@ -1696,7 +1767,7 @@ ecma_builtin_typedarray_prototype_last_index_of (ecma_value_t this_arg, /**< thi /* 5. */ if (args_number == 0 - || !ecma_is_value_number (args[0]) + || (!ecma_is_value_number (args[0]) && !is_bigint) || info.length == 0) { return ecma_make_integer_value (-1); @@ -1726,8 +1797,6 @@ ecma_builtin_typedarray_prototype_last_index_of (ecma_value_t this_arg, /**< thi : (uint32_t) (info.length + num_var)); } - ecma_number_t search_num = ecma_get_number_from_value (args[0]); - ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.id); /* 10. */ @@ -1735,12 +1804,15 @@ ecma_builtin_typedarray_prototype_last_index_of (ecma_value_t this_arg, /**< thi position >= 0; position += -info.element_size) { - ecma_number_t element_num = getter_cb (info.buffer_p + position); + ecma_value_t element = getter_cb (info.buffer_p + position); - if (search_num == element_num) + if (ecma_op_same_value_zero (args[0], element, true)) { + ecma_free_value (element); return ecma_make_number_value ((ecma_number_t) position / info.element_size); } + + ecma_free_value (element); } /* 11. */ @@ -1912,8 +1984,7 @@ ecma_builtin_typedarray_prototype_to_locale_string_helper (ecma_object_t *this_o lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (this_obj); ecma_value_t ret_value = ECMA_VALUE_EMPTY; - ecma_number_t element_num = ecma_get_typedarray_element (typedarray_buffer_p + index, class_id); - ecma_value_t element_value = ecma_make_number_value (element_num); + ecma_value_t element_value = ecma_get_typedarray_element (typedarray_buffer_p + index, class_id); ecma_value_t element_obj = ecma_op_create_number_object (element_value); @@ -2050,8 +2121,14 @@ ecma_builtin_typedarray_prototype_includes (ecma_value_t this_arg, /**< this arg ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); uint32_t limit = info.length * info.element_size; +#if ENABLED (JERRY_BUILTIN_BIGINT) + bool is_bigint = ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info.id); +#else /* !ENABLED (JERRRY_BUILTIN_BIGINT) */ + bool is_bigint = false; +#endif /* ENABLED (JERRRY_BUILTIN_BIGINT) */ + if (args_number == 0 - || !ecma_is_value_number (args[0]) + || (!ecma_is_value_number (args[0]) && !is_bigint) || info.length == 0) { return ECMA_VALUE_FALSE; @@ -2067,21 +2144,21 @@ ecma_builtin_typedarray_prototype_includes (ecma_value_t this_arg, /**< this arg } } - ecma_number_t search_num = ecma_get_number_from_value (args[0]); - ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.id); uint32_t search_pos = (uint32_t) from_index * info.element_size; while (search_pos < limit) { - ecma_number_t element_num = getter_cb (info.buffer_p + search_pos); + ecma_value_t element = getter_cb (info.buffer_p + search_pos); - if (search_num == element_num) + if (ecma_op_same_value_zero (args[0], element, false)) { + ecma_free_value (element); return ECMA_VALUE_TRUE; } + ecma_free_value (element); search_pos += info.element_size; } diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c index f27197d43..d52d4110c 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c @@ -164,17 +164,14 @@ ecma_builtin_typedarray_of (ecma_value_t this_arg, /**< 'this' argument */ while (k < arguments_list_len) { - ecma_number_t num; - ecma_value_t next_val = ecma_op_to_numeric (arguments_list_p[k], &num, ECMA_TO_NUMERIC_NO_OPTS); + ecma_value_t set_element = setter_cb (info.buffer_p, arguments_list_p[k]); - if (ECMA_IS_VALUE_ERROR (next_val)) + if (ECMA_IS_VALUE_ERROR (set_element)) { ecma_deref_object (ret_obj_p); - return next_val; + return set_element; } - setter_cb (info.buffer_p, num); - k++; info.buffer_p += info.element_size; } diff --git a/jerry-core/ecma/operations/ecma-container-object.c b/jerry-core/ecma/operations/ecma-container-object.c index 7b40bc574..6c269e556 100644 --- a/jerry-core/ecma/operations/ecma-container-object.c +++ b/jerry-core/ecma/operations/ecma-container-object.c @@ -138,7 +138,7 @@ ecma_op_internal_buffer_find (ecma_collection_t *container_p, /**< internal cont { ecma_value_t *entry_p = start_p + i; - if (ecma_op_same_value_zero (*entry_p, key_arg)) + if (ecma_op_same_value_zero (*entry_p, key_arg, false)) { return entry_p; } diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index 5e84ced84..586d0794e 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -125,6 +125,13 @@ ecma_op_same_value (ecma_value_t x, /**< ecma value */ return ecma_compare_ecma_strings (x_str_p, y_str_p); } +#if ENABLED (JERRY_BUILTIN_BIGINT) + if (ecma_is_value_bigint (x)) + { + return (ecma_is_value_bigint (y) && ecma_bigint_compare_to_bigint (x, y) == 0); + } +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + JERRY_ASSERT (ecma_is_value_object (x) || ECMA_CHECK_SYMBOL_IN_ASSERT (x)); return false; @@ -142,7 +149,8 @@ ecma_op_same_value (ecma_value_t x, /**< ecma value */ */ bool ecma_op_same_value_zero (ecma_value_t x, /**< ecma value */ - ecma_value_t y) /**< ecma value */ + ecma_value_t y, /**< ecma value */ + bool strict_equality) /**< strict equality */ { if (ecma_is_value_number (x) && ecma_is_value_number (y)) { @@ -152,15 +160,15 @@ ecma_op_same_value_zero (ecma_value_t x, /**< ecma value */ bool is_x_nan = ecma_number_is_nan (x_num); bool is_y_nan = ecma_number_is_nan (y_num); + if (strict_equality + && is_x_nan + && is_y_nan) + { + return false; + } + if (is_x_nan || is_y_nan) { - /* - * If both are NaN - * return true; - * else - * one of the numbers is NaN, and another - is not - * return false; - */ return (is_x_nan && is_y_nan); } diff --git a/jerry-core/ecma/operations/ecma-conversion.h b/jerry-core/ecma/operations/ecma-conversion.h index af5321f17..82e0acbe8 100644 --- a/jerry-core/ecma/operations/ecma-conversion.h +++ b/jerry-core/ecma/operations/ecma-conversion.h @@ -49,7 +49,7 @@ typedef enum ecma_value_t ecma_op_check_object_coercible (ecma_value_t value); bool ecma_op_same_value (ecma_value_t x, ecma_value_t y); #if ENABLED (JERRY_BUILTIN_MAP) -bool ecma_op_same_value_zero (ecma_value_t x, ecma_value_t y); +bool ecma_op_same_value_zero (ecma_value_t x, ecma_value_t y, bool strict_equality); #endif /* ENABLED (JERRY_BUILTIN_MAP) */ ecma_value_t ecma_op_to_primitive (ecma_value_t value, ecma_preferred_type_hint_t preferred_type); bool ecma_op_to_boolean (ecma_value_t value); diff --git a/jerry-core/ecma/operations/ecma-dataview-object.c b/jerry-core/ecma/operations/ecma-dataview-object.c index 9898c3596..3b964bf9f 100644 --- a/jerry-core/ecma/operations/ecma-dataview-object.c +++ b/jerry-core/ecma/operations/ecma-dataview-object.c @@ -311,12 +311,18 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi JERRY_VLA (lit_utf8_byte_t, swap_block_p, element_size); memcpy (swap_block_p, block_p, element_size * sizeof (lit_utf8_byte_t)); ecma_dataview_swap_order (system_is_little_endian, is_little_endian, element_size, swap_block_p); - return ecma_make_number_value (ecma_get_typedarray_element (swap_block_p, id)); + return ecma_get_typedarray_element (swap_block_p, id); } if (ecma_is_value_number (value_to_set)) { - ecma_set_typedarray_element (block_p, ecma_get_number_from_value (value_to_set), id); + ecma_value_t set_element = ecma_set_typedarray_element (block_p, value_to_set, id); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + return set_element; + } + ecma_dataview_swap_order (system_is_little_endian, is_little_endian, element_size, block_p); } diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 0c0bfccf1..75d4481c5 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -194,8 +194,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ if (array_index < info.length) { uint32_t byte_pos = array_index << info.shift; - ecma_number_t num = ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); - value = ecma_make_number_value (num); + value = ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); } if (!ecma_is_value_undefined (value)) @@ -522,8 +521,7 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ } uint32_t byte_pos = array_index << info.shift; - ecma_number_t num = ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); - return ecma_make_number_value (num); + return ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); } ecma_number_t num = ecma_string_to_number (property_name_p); @@ -1230,15 +1228,6 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) { - ecma_number_t num_var; - ecma_value_t error = ecma_op_to_numeric (value, &num_var, ECMA_TO_NUMERIC_NO_OPTS); - - if (ECMA_IS_VALUE_ERROR (error)) - { - jcontext_release_exception (); - return ecma_reject (is_throw); - } - ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); if (array_index >= info.length) @@ -1247,9 +1236,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ } uint32_t byte_pos = array_index << info.shift; - ecma_set_typedarray_element (info.buffer_p + byte_pos, num_var, info.id); - - return ECMA_VALUE_TRUE; + return ecma_set_typedarray_element (info.buffer_p + byte_pos, value, info.id); } ecma_number_t num = ecma_string_to_number (property_name_p); @@ -1682,11 +1669,16 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */ if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) { - bool define_status = ecma_op_typedarray_define_index_prop (obj_p, - array_index, - property_desc_p); + ecma_value_t define_status = ecma_op_typedarray_define_index_prop (obj_p, + array_index, + property_desc_p); - if (define_status) + if (ECMA_IS_VALUE_ERROR (define_status)) + { + return define_status; + } + + if (ecma_is_value_true (define_status)) { return ECMA_VALUE_TRUE; } @@ -2436,6 +2428,10 @@ ecma_object_check_class_name_is_object (ecma_object_t *obj_p) /**< object */ #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE) #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) + || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_BIGINT64ARRAY_PROTOTYPE) + || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_BIGUINT64ARRAY_PROTOTYPE) +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ #endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ESNEXT) || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ARRAY_PROTOTYPE_UNSCOPABLES) diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 4d42fd2d5..4f5f43324 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -19,6 +19,8 @@ #include "ecma-typedarray-object.h" #include "ecma-arraybuffer-object.h" #include "ecma-function-object.h" +#include "ecma-bigint.h" +#include "ecma-big-uint.h" #include "ecma-builtin-helpers.h" #include "ecma-try-catch-macro.h" #include "ecma-objects.h" @@ -38,92 +40,157 @@ * @{ */ +/** + * Read and copy a number from a given buffer to a value. + **/ +#define ECMA_TYPEDARRAY_GET_ELEMENT(src_p, num, type) \ + do \ + { \ + if (JERRY_LIKELY ((((uintptr_t) (src_p)) & (sizeof (type) - 1)) == 0)) \ + { \ + num = *(type *) src_p; \ + } \ + else \ + { \ + memcpy (&num, src_p, sizeof (type)); \ + } \ + } \ + while (0) + +/** + * Copy a number from a value to the given buffer + **/ +#define ECMA_TYPEDARRAY_SET_ELEMENT(src_p, num, type) \ + do \ + { \ + if (JERRY_LIKELY ((((uintptr_t) (src_p)) & (sizeof (type) - 1)) == 0)) \ + { \ + *(type *) src_p = num; \ + } \ + else \ + { \ + memcpy (src_p, &num, sizeof (type)); \ + } \ + } \ + while (0) + /** * Read an int8_t value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_int8_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { int8_t num = (int8_t) *src; - return (ecma_number_t) num; + return ecma_make_integer_value (num); } /* ecma_typedarray_get_int8_element */ /** * Read an uint8_t value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_uint8_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { uint8_t num = (uint8_t) *src; - return (ecma_number_t) num; + return ecma_make_integer_value (num); } /* ecma_typedarray_get_uint8_element */ /** * Read an int16_t value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_int16_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { int16_t num; - memcpy (&num, src, sizeof (int16_t)); - return (ecma_number_t) num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, int16_t); + return ecma_make_integer_value (num); } /* ecma_typedarray_get_int16_element */ /** * Read an uint16_t value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_uint16_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { uint16_t num; - memcpy (&num, src, sizeof (uint16_t)); - return (ecma_number_t) num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, uint16_t); + return ecma_make_integer_value (num); } /* ecma_typedarray_get_uint16_element */ /** * Read an int32_t value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_int32_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { int32_t num; - memcpy (&num, src, sizeof (int32_t)); - return (ecma_number_t) num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, int32_t); + return ecma_make_number_value (num); } /* ecma_typedarray_get_int32_element */ /** * Read an uint32_t value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_uint32_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { uint32_t num; - memcpy (&num, src, sizeof (uint32_t)); - return (ecma_number_t) num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, uint32_t); + return ecma_make_number_value (num); } /* ecma_typedarray_get_uint32_element */ /** * Read a float value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_float_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { float num; - memcpy (&num, src, sizeof (float)); - return (ecma_number_t) num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, float); + return ecma_make_number_value (num); } /* ecma_typedarray_get_float_element */ /** * Read a double value from the given arraybuffer */ -static ecma_number_t +static ecma_value_t ecma_typedarray_get_double_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { double num; - memcpy (&num, src, sizeof (double)); - return (ecma_number_t) num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, double); + return ecma_make_number_value (num); } /* ecma_typedarray_get_double_element */ +#if ENABLED (JERRY_BUILTIN_BIGINT) +/** + * Read a bigint64 value from the given arraybuffer + */ +static ecma_value_t +ecma_typedarray_get_bigint64_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ +{ + uint64_t num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, uint64_t); + bool sign = (num >> 63) != 0; + + if (sign) + { + num = (uint64_t) (-(int64_t) num); + } + + return ecma_bigint_create_from_digits (&num, 1, sign); +} /* ecma_typedarray_get_bigint64_element */ + +/** + * Read a biguint64 value from the given arraybuffer + */ +static ecma_value_t +ecma_typedarray_get_biguint64_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ +{ + uint64_t num; + ECMA_TYPEDARRAY_GET_ELEMENT (src, num, uint64_t); + return ecma_bigint_create_from_digits (&num, 1, false); +} /* ecma_typedarray_get_biguint64_element */ +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + /** * Normalize the given ecma_number_t to an uint32_t value */ @@ -160,131 +227,279 @@ ecma_typedarray_setter_number_to_uint32 (ecma_number_t value) /**< the number va /** * Write an int8_t value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_int8_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - int8_t num = (int8_t) ecma_typedarray_setter_number_to_uint32 (value); + ecma_number_t result_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &result_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + int8_t num = (int8_t) ecma_typedarray_setter_number_to_uint32 (result_num); *dst_p = (lit_utf8_byte_t) num; + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_int8_element */ /** * Write an uint8_t value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_uint8_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - uint8_t num = (uint8_t) ecma_typedarray_setter_number_to_uint32 (value); + ecma_number_t result_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &result_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + uint8_t num = (uint8_t) ecma_typedarray_setter_number_to_uint32 (result_num); *dst_p = (lit_utf8_byte_t) num; + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_uint8_element */ /** * Write an uint8_t clamped value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_uint8_clamped_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { + ecma_number_t result_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &result_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + uint8_t clamped; - if (value > 255) + if (result_num > 255) { clamped = 255; } - else if (value <= 0) + else if (result_num <= 0) { clamped = 0; } else { - clamped = (uint8_t) value; + clamped = (uint8_t) result_num; - if (clamped + 0.5 < value - || (clamped + 0.5 == value && (clamped % 2) == 1)) + if (clamped + 0.5 < result_num + || (clamped + 0.5 == result_num && (clamped % 2) == 1)) { clamped ++; } } *dst_p = (lit_utf8_byte_t) clamped; + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_uint8_clamped_element */ /** * Write an int16_t value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_int16_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - int16_t num = (int16_t) ecma_typedarray_setter_number_to_uint32 (value); - memcpy (dst_p, &num, sizeof (int16_t)); + ecma_number_t resut_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &resut_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + int16_t num = (int16_t) ecma_typedarray_setter_number_to_uint32 (resut_num); + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, int16_t); + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_int16_element */ /** * Write an uint8_t value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_uint16_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - uint16_t num = (uint16_t) ecma_typedarray_setter_number_to_uint32 (value); - memcpy (dst_p, &num, sizeof (uint16_t)); + ecma_number_t resut_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &resut_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + uint16_t num = (uint16_t) ecma_typedarray_setter_number_to_uint32 (resut_num); + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, uint16_t); + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_uint16_element */ /** * Write an int32_t value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_int32_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - int32_t num = (int32_t) ecma_typedarray_setter_number_to_uint32 (value); - memcpy (dst_p, &num, sizeof (int32_t)); + ecma_number_t resut_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &resut_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + int32_t num = (int32_t) ecma_typedarray_setter_number_to_uint32 (resut_num); + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, int32_t); + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_int32_element */ /** * Write an uint32_t value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_uint32_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - uint32_t num = (uint32_t) ecma_typedarray_setter_number_to_uint32 (value); - memcpy (dst_p, &num, sizeof (uint32_t)); + ecma_number_t resut_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &resut_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + uint32_t num = (uint32_t) ecma_typedarray_setter_number_to_uint32 (resut_num); + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, uint32_t); + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_uint32_element */ /** * Write a float value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_float_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - float num = (float) value; - memcpy (dst_p, &num, sizeof (float)); + ecma_number_t result_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &result_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + float num = (float) result_num; + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, float); + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_float_element */ #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Write a double value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToNumber operation fails + * ECMA_VALUE_TRUE - otherwise */ -static void +static ecma_value_t ecma_typedarray_set_double_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value) /**< the number value to set */ + ecma_value_t value) /**< the number value to set */ { - double num = (double) value; - memcpy (dst_p, &num, sizeof (double)); + ecma_number_t result_num; + ecma_value_t to_num = ecma_op_to_numeric (value, &result_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + + double num = (double) result_num; + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, double); + return ECMA_VALUE_TRUE; } /* ecma_typedarray_set_double_element */ #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) +/** + * Write a bigint64/biguint64 value into the given arraybuffer + * + * @return ECMA_VALUE_ERROR - if the ToBigInt operation fails + * ECMA_VALUE_TRUE - otherwise + */ +static ecma_value_t +ecma_typedarray_set_bigint_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ + ecma_value_t value) /**< the bigint value to set */ +{ + ecma_value_t bigint = ecma_bigint_to_bigint (value, false); + + if (ECMA_IS_VALUE_ERROR (bigint)) + { + return bigint; + } + + uint64_t num; + bool sign; + ecma_bigint_get_digits_and_sign (bigint, &num, 1, &sign); + + if (sign) + { + num = (uint64_t) (-(int64_t) num); + } + + ECMA_TYPEDARRAY_SET_ELEMENT (dst_p, num, uint64_t); + + ecma_free_value (bigint); + + return ECMA_VALUE_TRUE; +} /* ecma_typedarray_set_bigint_element */ +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + /** * Builtin id of the first %TypedArray% builtin routine intrinsic object */ #define ECMA_FIRST_TYPEDARRAY_BUILTIN_ROUTINE_ID ECMA_BUILTIN_ID_INT8ARRAY -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) +#if ENABLED (JERRY_BUILTIN_BIGINT) +/** + * Builtin id of the last %TypedArray% builtin routine intrinsic object + */ +#define ECMA_LAST_TYPEDARRAY_BUILTIN_ROUTINE_ID ECMA_BUILTIN_ID_BIGUINT64ARRAY +#elif !ENABLED (JERRY_BUILTIN_BIGINT) && ENABLED (JERRY_NUMBER_TYPE_FLOAT64) /** * Builtin id of the last %TypedArray% builtin routine intrinsic object */ @@ -317,6 +532,10 @@ static const ecma_typedarray_getter_fn_t ecma_typedarray_getters[] = #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) ecma_typedarray_get_double_element, /**< Float64Array */ #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) + ecma_typedarray_get_bigint64_element, /**< BigInt64Array*/ + ecma_typedarray_get_biguint64_element, /**< BigUint64Array */ +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ }; /** @@ -335,6 +554,10 @@ static const ecma_typedarray_setter_fn_t ecma_typedarray_setters[] = #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) ecma_typedarray_set_double_element, /**< Float64Array */ #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) + ecma_typedarray_set_bigint_element, /**< BigInt64Array */ + ecma_typedarray_set_bigint_element, /**< BigUInt64Array */ +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ }; /** @@ -353,6 +576,10 @@ static const uint8_t ecma_typedarray_element_shift_sizes[] = #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) 3, /**< Float64Array */ #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) + 3, /**< BigInt64Array */ + 3, /**< BigUInt64Array */ +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ }; /** @@ -371,6 +598,10 @@ static const uint16_t ecma_typedarray_magic_string_list[] = #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) (uint16_t) LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, /**< Float64Array */ #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +#if ENABLED (JERRY_BUILTIN_BIGINT) + (uint16_t) LIT_MAGIC_STRING_BIGINT64_ARRAY_UL, /**< BigInt64Array */ + (uint16_t) LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL, /**< BigUInt64Array */ +#endif /* ENABLED (JERRY_BUILTIN_BIGINT */ }; /** @@ -389,7 +620,7 @@ ecma_get_typedarray_getter_fn (ecma_typedarray_type_t typedarray_id) * * @return ecma_number_t: the value of the element */ -inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE +inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE ecma_get_typedarray_element (lit_utf8_byte_t *src_p, ecma_typedarray_type_t typedarray_id) { @@ -410,12 +641,12 @@ ecma_get_typedarray_setter_fn (ecma_typedarray_type_t typedarray_id) /** * set typedarray's element value */ -inline void JERRY_ATTR_ALWAYS_INLINE +inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, - ecma_number_t value, + ecma_value_t value, ecma_typedarray_type_t typedarray_id) { - ecma_typedarray_setters[typedarray_id](dst_p, value); + return ecma_typedarray_setters[typedarray_id](dst_p, value); } /* ecma_set_typedarray_element */ /** @@ -662,6 +893,12 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**< } else { + if ((ECMA_TYPEDARRAY_IS_BIGINT_TYPE (src_id) ^ ECMA_TYPEDARRAY_IS_BIGINT_TYPE (typedarray_id)) == 1) + { + ecma_deref_object (new_typedarray_p); + return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible typedArray types.")); + } + uint32_t src_element_size = 1u << ecma_typedarray_get_element_size_shift (typedarray_p); uint32_t dst_element_size = 1u << element_size_shift; ecma_typedarray_getter_fn_t src_typedarray_getter_cb = ecma_get_typedarray_getter_fn (src_id); @@ -670,8 +907,16 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**< for (uint32_t i = 0; i < array_length; i++) { /* Convert values from source to destination format. */ - ecma_number_t tmp = src_typedarray_getter_cb (src_buf_p); - target_typedarray_setter_cb (dst_buf_p, tmp); + ecma_value_t tmp = src_typedarray_getter_cb (src_buf_p); + ecma_value_t set_element = target_typedarray_setter_cb (dst_buf_p, tmp); + + ecma_free_value (tmp); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + ecma_deref_object (new_typedarray_p); + return set_element; + } src_buf_p += src_element_size; dst_buf_p += dst_element_size; @@ -719,21 +964,18 @@ ecma_op_typedarray_from_helper (ecma_value_t this_val, /**< this_arg for the abo mapped_value = current_value; } - ecma_number_t num_var; - ecma_value_t mapped_number = ecma_op_to_numeric (mapped_value, &num_var, ECMA_TO_NUMERIC_NO_OPTS); - ecma_free_value (mapped_value); - - if (ECMA_IS_VALUE_ERROR (mapped_number)) - { - return mapped_number; - } - if (index >= info_p->length) { return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type.")); } - setter_cb (info_p->buffer_p + (index << info_p->shift), num_var); + ecma_value_t set_element = setter_cb (info_p->buffer_p + (index << info_p->shift), mapped_value); + ecma_free_value (mapped_value); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + return set_element; + } return ECMA_VALUE_TRUE; } /* ecma_op_typedarray_from_helper */ @@ -1330,9 +1572,9 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA * * See also: ES2015 9.4.5.3: 3.c * - * @return boolean, false if failed + * @return ecma value, */ -bool +ecma_value_t ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray object */ uint32_t index, /**< the index number */ const ecma_property_descriptor_t *property_desc_p) /**< the description of @@ -1351,31 +1593,28 @@ ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray ob || ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED) && !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE))) { - return false; + return ECMA_VALUE_FALSE; } if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) { - ecma_number_t num_var; - ecma_value_t error = ecma_op_to_numeric (property_desc_p->value, &num_var, ECMA_TO_NUMERIC_NO_OPTS); - - if (ECMA_IS_VALUE_ERROR (error)) - { - jcontext_release_exception (); - return false; - } ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); if (index >= info.length) { - return false; + return ECMA_VALUE_FALSE; } lit_utf8_byte_t *src_buffer = info.buffer_p + (index << info.shift); - ecma_set_typedarray_element (src_buffer, num_var, info.id); + ecma_value_t set_element = ecma_set_typedarray_element (src_buffer, property_desc_p->value, info.id); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + return set_element; + } } - return true; + return ECMA_VALUE_TRUE; } /* ecma_op_typedarray_define_index_prop */ /** diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index fa12544f6..e5849d02e 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -31,11 +31,11 @@ uint8_t ecma_typedarray_helper_get_shift_size (ecma_typedarray_type_t typedarray_id); ecma_typedarray_getter_fn_t ecma_get_typedarray_getter_fn (ecma_typedarray_type_t typedarray_id); ecma_typedarray_setter_fn_t ecma_get_typedarray_setter_fn (ecma_typedarray_type_t typedarray_id); -ecma_number_t ecma_get_typedarray_element (lit_utf8_byte_t *src_p, - ecma_typedarray_type_t typedarray_id); -void ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, - ecma_number_t value, - ecma_typedarray_type_t typedarray_id); +ecma_value_t ecma_get_typedarray_element (lit_utf8_byte_t *src_p, + ecma_typedarray_type_t typedarray_id); +ecma_value_t ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, + ecma_value_t value, + ecma_typedarray_type_t typedarray_id); bool ecma_typedarray_helper_is_typedarray (ecma_builtin_id_t builtin_id); ecma_typedarray_type_t ecma_get_typedarray_id (ecma_object_t *obj_p); ecma_builtin_id_t ecma_typedarray_helper_get_prototype_id (ecma_typedarray_type_t typedarray_id); @@ -66,9 +66,9 @@ bool ecma_is_typedarray (ecma_value_t target); void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, ecma_collection_t *prop_names_p, ecma_property_counter_t *prop_counter_p); -bool ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, - uint32_t index, - const ecma_property_descriptor_t *property_desc_p); +ecma_value_t ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, + uint32_t index, + const ecma_property_descriptor_t *property_desc_p); ecma_value_t ecma_op_create_typedarray_with_type_and_length (ecma_typedarray_type_t typedarray_id, uint32_t array_length); ecma_typedarray_info_t ecma_typedarray_get_info (ecma_object_t *typedarray_p); diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index 96f7aa367..62410e425 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -825,6 +825,11 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_TIME_STRING_UL, "toTimeString") #endif #if ENABLED (JERRY_ESNEXT) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ASYNC_FUNCTION_UL, "AsyncFunction") +#endif +#if ENABLED (JERRY_BUILTIN_TYPEDARRAY) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_BIGINT64_ARRAY_UL, "BigInt64Array") +#endif +#if ENABLED (JERRY_ESNEXT) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ASYNC_ITERATOR, "asyncIterator") #endif #if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ESNEXT) @@ -852,6 +857,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_EXPONENTIAL_UL, "toExponential") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARRAY_ITERATOR_UL, "Array Iterator") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ASYNC_GENERATOR_UL, "AsyncGenerator") #endif +#if ENABLED (JERRY_BUILTIN_BIGINT) && ENABLED (JERRY_BUILTIN_TYPEDARRAY) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL, "BigUint64Array") +#endif #if ENABLED (JERRY_BUILTIN_ERRORS) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REFERENCE_ERROR_UL, "ReferenceError") #endif @@ -1049,6 +1057,10 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_CONFIGURABLE) #endif #if ENABLED (JERRY_ESNEXT) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_ASYNC_FUNCTION_UL) +#elif ENABLED (JERRY_BUILTIN_TYPEDARRAY) +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_BIGINT64_ARRAY_UL) +#elif ENABLED (JERRY_ESNEXT) +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_ASYNC_ITERATOR) #elif ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ESNEXT) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_FROM_CODE_POINT_UL) #elif ENABLED (JERRY_BUILTIN_DATE) @@ -1058,6 +1070,8 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (13, LIT_MAGIC_STRING_IS_PROTOTYPE_OF_UL #endif #if ENABLED (JERRY_ESNEXT) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (14, LIT_MAGIC_STRING_ARRAY_ITERATOR_UL) +#elif ENABLED (JERRY_BUILTIN_BIGINT) && ENABLED (JERRY_BUILTIN_TYPEDARRAY) +LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (14, LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL) #elif ENABLED (JERRY_BUILTIN_ERRORS) LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (14, LIT_MAGIC_STRING_REFERENCE_ERROR_UL) #else diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini index dba2a063d..a54ea5596 100644 --- a/jerry-core/lit/lit-magic-strings.ini +++ b/jerry-core/lit/lit-magic-strings.ini @@ -330,6 +330,7 @@ LIT_MAGIC_STRING_IS_EXTENSIBLE = "isExtensible" LIT_MAGIC_STRING_TO_DATE_STRING_UL = "toDateString" LIT_MAGIC_STRING_TO_TIME_STRING_UL = "toTimeString" LIT_MAGIC_STRING_ASYNC_FUNCTION_UL = "AsyncFunction" +LIT_MAGIC_STRING_BIGINT64_ARRAY_UL = "BigInt64Array" LIT_MAGIC_STRING_ASYNC_ITERATOR = "asyncIterator" LIT_MAGIC_STRING_GET_UTC_MINUTES_UL = "getUTCMinutes" LIT_MAGIC_STRING_GET_UTC_SECONDS_UL = "getUTCSeconds" @@ -341,6 +342,7 @@ LIT_MAGIC_STRING_SET_UTC_SECONDS_UL = "setUTCSeconds" LIT_MAGIC_STRING_TO_EXPONENTIAL_UL = "toExponential" LIT_MAGIC_STRING_ARRAY_ITERATOR_UL = "Array Iterator" LIT_MAGIC_STRING_ASYNC_GENERATOR_UL = "AsyncGenerator" +LIT_MAGIC_STRING_BIGUINT64_ARRAY_UL = "BigUint64Array" LIT_MAGIC_STRING_REFERENCE_ERROR_UL = "ReferenceError" LIT_MAGIC_STRING_DEFINE_PROPERTY_UL = "defineProperty" LIT_MAGIC_STRING_DELETE_PROPERTY_UL = "deleteProperty" diff --git a/tests/jerry/es.next/regression-test-issue-2143.js b/tests/jerry/es.next/regression-test-issue-2143.js index 01308d73e..439f7f350 100644 --- a/tests/jerry/es.next/regression-test-issue-2143.js +++ b/tests/jerry/es.next/regression-test-issue-2143.js @@ -13,4 +13,10 @@ // limitations under the License. var a = new Uint8Array(2); -a[0] = { valueOf : function() { throw "intoint"; } }; + +try { + a[0] = { valueOf : function() { throw "intoint"; } }; + assert(false); +} catch (e) { + assert(e === "intoint") +} diff --git a/tests/jerry/es.next/typedArray-fill.js b/tests/jerry/es.next/typedArray-fill.js index 01288d152..ed9203cf9 100644 --- a/tests/jerry/es.next/typedArray-fill.js +++ b/tests/jerry/es.next/typedArray-fill.js @@ -103,3 +103,12 @@ assert(h.toString() === '1,0,0,0'); var j = new Uint16Array(ab2, 2, 1); assert(j.fill(1).toString() === '1'); assert(h.toString() === '1,0,1,0'); + +var k = new BigInt64Array([1n, 2n, 3n, 4n, 5n]); +assert(k.fill(1n, 1, 4).toString() === '1,1,1,1,5'); +assert(k.fill(18446744073709551616n, 0, 5).toString() === '0,0,0,0,0'); +assert(k.fill(-5n, 3, 5).toString() === '0,0,0,-5,-5'); + +var l = new BigUint64Array([1n, 2n, 3n, 4n, 5n]); +assert(l.fill(-18446744073709551614n, 3, 5).toString() === '1,2,3,2,2'); +assert(l.fill(18446744073709551614n, 4).toString() === '1,2,3,2,18446744073709551614'); diff --git a/tests/jerry/es.next/typedArray-find-index.js b/tests/jerry/es.next/typedArray-find-index.js index cb54de996..dbe477c53 100644 --- a/tests/jerry/es.next/typedArray-find-index.js +++ b/tests/jerry/es.next/typedArray-find-index.js @@ -114,3 +114,17 @@ typedArrayTypes.forEach (function (TypedArray) { // Checking behavior when there are more than 2 arguments assert (array.findIndex (function (e) { return e < 2 }, {}, 8, 4, 5, 6, 6) === 0); }) + +function isNegative(element, index, array) { + return element < 0; +} + +function isBigger(element, index, array) { + return element > 40n; +} + +var bigint_array = new BigInt64Array([10n, -20n, 30n, -40n, 50n]); +var biguint_array = new BigUint64Array([10n, 20n, 30n, 40n, 50n]); + +assert(bigint_array.findIndex(isNegative) === 1); +assert(biguint_array.findIndex(isBigger) === 4); diff --git a/tests/jerry/es.next/typedarray-prototype-copy-within.js b/tests/jerry/es.next/typedarray-prototype-copy-within.js index cee467245..9d840618d 100644 --- a/tests/jerry/es.next/typedarray-prototype-copy-within.js +++ b/tests/jerry/es.next/typedarray-prototype-copy-within.js @@ -72,3 +72,11 @@ typedarrays.forEach(function(e){ assert(e.copyWithin(3, Infinity, 5).toString() === '2,1,4,2,1,5'); assert(e.copyWithin(1, 3, -Infinity).toString() === '2,1,4,2,1,5'); }); + +var bigint_array = new BigInt64Array([1n, 2n, 3n, -4n, 5n]); +assert(bigint_array.copyWithin(2, 1, 4).toString() === '1,2,2,3,-4'); +assert(bigint_array.copyWithin(0, 4).toString() === '-4,2,2,3,-4'); + +var biguint_array = new BigUint64Array([1n, 2n, 3n, 4n, 5n]); +assert(biguint_array.copyWithin(0, 2, 4).toString() === '3,4,3,4,5'); +assert(biguint_array.copyWithin(-3, 0, 3).toString() === '3,4,3,4,3'); diff --git a/tests/jerry/es.next/typedarray-prototype-entires.js b/tests/jerry/es.next/typedarray-prototype-entires.js index b420ab4cb..315415373 100644 --- a/tests/jerry/es.next/typedarray-prototype-entires.js +++ b/tests/jerry/es.next/typedarray-prototype-entires.js @@ -69,3 +69,13 @@ empty_typedarrays.forEach(function (e){ }); assert ([].entries ().toString () === "[object Array Iterator]"); + +var bigint_array = new BigInt64Array([1n, 2n, 3n, 4n]); +var entries = bigint_array.entries(); +assert(entries.next().value[1] === 1n); +assert(entries.next().value[1] === 2n); + +var biguint_array = new BigUint64Array([1n, 2n, 3n, 4n]); +var entries = biguint_array.entries(); +assert(entries.next().value[1] === 1n); +assert(entries.next().value[1] === 2n); diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 8572bdc27..eb9e46b68 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -2026,103 +2026,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2135,10 +2065,7 @@ - - - @@ -2159,80 +2086,27 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2242,55 +2116,23 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2306,130 +2148,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2443,10 +2199,7 @@ - - - @@ -2467,30 +2220,12 @@ - - - - - - - - - - - - - - - - - - @@ -2499,18 +2234,6 @@ - - - - - - - - - - - - @@ -2521,10 +2244,7 @@ - - - @@ -2541,7 +2261,6 @@ - @@ -2554,31 +2273,9 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -2589,134 +2286,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2769,61 +2388,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2833,15 +2409,8 @@ - - - - - - - @@ -2854,13 +2423,6 @@ - - - - - - - @@ -2871,16 +2433,12 @@ - - - - @@ -2892,34 +2450,13 @@ - - - - - - - - - - - - - - - - - - - - - @@ -2927,51 +2464,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -