diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 2c49f1b91..c1776a5c6 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -3426,7 +3426,7 @@ typedef struct { jerry_typedarray_type_t api_type; /**< api type */ ecma_builtin_id_t prototype_id; /**< prototype ID */ - lit_magic_string_id_t lit_id; /**< literal ID */ + ecma_typedarray_type_t id; /**< typedArray ID */ uint8_t element_size_shift; /**< element size shift */ } jerry_typedarray_mapping_t; @@ -3437,7 +3437,7 @@ static jerry_typedarray_mapping_t jerry_typedarray_mappings[] = { #define TYPEDARRAY_ENTRY(NAME, LIT_NAME, SIZE_SHIFT) \ { JERRY_TYPEDARRAY_ ## NAME, ECMA_BUILTIN_ID_ ## NAME ## ARRAY_PROTOTYPE, \ - LIT_MAGIC_STRING_ ## LIT_NAME ## _ARRAY_UL, SIZE_SHIFT } + ECMA_ ## LIT_NAME ## _ARRAY, SIZE_SHIFT } TYPEDARRAY_ENTRY (UINT8, UINT8, 0), TYPEDARRAY_ENTRY (UINT8CLAMPED, UINT8_CLAMPED, 0), @@ -3455,7 +3455,7 @@ static jerry_typedarray_mapping_t jerry_typedarray_mappings[] = }; /** - * Helper function to get the TypedArray prototype, literal id, and element size shift + * Helper function to get the TypedArray prototype, typedArray id, and element size shift * information. * * @return true - if the TypedArray information was found @@ -3464,11 +3464,11 @@ static jerry_typedarray_mapping_t jerry_typedarray_mappings[] = static bool jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of the TypedArray */ ecma_builtin_id_t *prototype_id, /**< [out] found prototype object id */ - lit_magic_string_id_t *lit_id, /**< [out] found literal id */ + ecma_typedarray_type_t *id, /**< [out] found typedArray id */ uint8_t *element_size_shift) /**< [out] found element size shift value */ { JERRY_ASSERT (prototype_id != NULL); - JERRY_ASSERT (lit_id != NULL); + JERRY_ASSERT (id != NULL); JERRY_ASSERT (element_size_shift != NULL); for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++) @@ -3476,7 +3476,7 @@ jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of t if (type_name == jerry_typedarray_mappings[i].api_type) { *prototype_id = jerry_typedarray_mappings[i].prototype_id; - *lit_id = jerry_typedarray_mappings[i].lit_id; + *id = jerry_typedarray_mappings[i].id; *element_size_shift = jerry_typedarray_mappings[i].element_size_shift; return true; } @@ -3505,10 +3505,10 @@ jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedAr #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) ecma_builtin_id_t prototype_id = 0; - lit_magic_string_id_t lit_id = 0; + ecma_typedarray_type_t id = 0; uint8_t element_size_shift = 0; - if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &lit_id, &element_size_shift)) + if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift)) { return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray."))); } @@ -3518,7 +3518,7 @@ jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedAr ecma_value_t array_value = ecma_typedarray_create_object_with_length (length, prototype_obj_p, element_size_shift, - lit_id); + id); JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value)); @@ -3549,10 +3549,10 @@ jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, / #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) ecma_builtin_id_t prototype_id = 0; - lit_magic_string_id_t lit_id = 0; + ecma_typedarray_type_t id = 0; uint8_t element_size_shift = 0; - if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &lit_id, &element_size_shift)) + if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift)) { return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray."))); } @@ -3570,7 +3570,7 @@ jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, / ecma_make_uint32_value (length) }; - ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, lit_id); + ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, id); ecma_free_value (arguments_p[1]); ecma_free_value (arguments_p[2]); @@ -3627,11 +3627,11 @@ jerry_get_typedarray_type (jerry_value_t value) /**< object to get the TypedArra } ecma_object_t *array_p = ecma_get_object_from_value (value); + ecma_typedarray_type_t class_type = ecma_get_typedarray_id (array_p); - lit_magic_string_id_t class_name_id = ecma_object_get_class_name (array_p); for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++) { - if (class_name_id == jerry_typedarray_mappings[i].lit_id) + if (class_type == jerry_typedarray_mappings[i].id) { return jerry_typedarray_mappings[i].api_type; } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index f321958fe..19d150eb3 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -835,12 +835,12 @@ typedef struct { uint8_t type; /**< pseudo array type, e.g. Arguments, TypedArray, ArrayIterator */ uint8_t extra_info; /**< extra information about the object. - * e.g. element_width_shift for typed arrays, + * e.g. the specific builtin id for typed arrays, * [[IterationKind]] property for %Iterator% */ union { uint16_t length; /**< for arguments: length of names */ - uint16_t class_id; /**< for typedarray: the specific class name */ + uint16_t class_id; /**< for typedarray: the specific class name id */ uint16_t iterator_index; /**< for %Iterator%: [[%Iterator%NextIndex]] property */ } u1; union @@ -1619,6 +1619,32 @@ typedef struct #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) +/** + * Function callback descriptor of a %TypedArray% object getter + */ +typedef ecma_number_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); + +/** + * Builtin id for the different types of TypedArray's + */ +typedef enum +{ + ECMA_INT8_ARRAY, /**< Int8Array */ + ECMA_UINT8_ARRAY, /**< Uint8Array */ + ECMA_UINT8_CLAMPED_ARRAY, /**< Uint8ClampedArray */ + ECMA_INT16_ARRAY, /**< Int16Array */ + ECMA_UINT16_ARRAY, /**< Uint16Array */ + ECMA_INT32_ARRAY, /**< Int32Array */ + ECMA_UINT32_ARRAY, /**< Uint32Array */ + ECMA_FLOAT32_ARRAY, /**< Float32Array */ + ECMA_FLOAT64_ARRAY, /**< Float64Array */ +} ecma_typedarray_type_t; + /** * Extra information for ArrayBuffers. */ @@ -1658,6 +1684,20 @@ typedef struct ecma_length_t array_length; /**< the array length */ } ecma_extended_typedarray_object_t; +/** + * General structure for query %TypedArray% object's properties. + **/ +typedef struct +{ + ecma_object_t *typedarray_buffer_p; /**< pointer to the typedArray's arraybuffer */ + lit_utf8_byte_t *buffer_p; /**< pointer to the arraybuffer's internal data buffer */ + ecma_typedarray_type_t typedarray_id; /**< type of the typedArray */ + uint32_t typedarray_length; /**< length of the typedArray */ + ecma_length_t offset; /**< offset of the internal array buffer */ + uint8_t shift; /**< the element size shift in the typedArray */ + uint8_t element_size; /**< size of each element in the typedArray */ +} ecma_typedarray_info_t; + #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-dataview-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-dataview-prototype.c index b89114a88..fc443f95d 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-dataview-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-dataview-prototype.c @@ -41,6 +41,7 @@ enum ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER, ECMA_DATAVIEW_PROTOTYPE_GET_INT8, ECMA_DATAVIEW_PROTOTYPE_GET_UINT8, + ECMA_DATAVIEW_PROTOTYPE_GET_UINT8_CLAMPED, /* unused value */ ECMA_DATAVIEW_PROTOTYPE_GET_INT16, ECMA_DATAVIEW_PROTOTYPE_GET_UINT16, ECMA_DATAVIEW_PROTOTYPE_GET_INT32, @@ -51,6 +52,7 @@ enum #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ ECMA_DATAVIEW_PROTOTYPE_SET_INT8, ECMA_DATAVIEW_PROTOTYPE_SET_UINT8, + ECMA_DATAVIEW_PROTOTYPE_SET_UINT8_CLAMPED, /* unused value */ ECMA_DATAVIEW_PROTOTYPE_SET_INT16, ECMA_DATAVIEW_PROTOTYPE_SET_UINT16, ECMA_DATAVIEW_PROTOTYPE_SET_INT32, @@ -75,23 +77,6 @@ enum * @{ */ -/** - * Corresponding typedarray mappings for the {get,set}{[U]int, Float}{8, 16, 32, 64} routines - */ -static const uint8_t ecma_dataview_type_mapping[] = -{ - ECMA_BUILTIN_ID_INT8ARRAY, - ECMA_BUILTIN_ID_UINT8ARRAY, - ECMA_BUILTIN_ID_INT16ARRAY, - ECMA_BUILTIN_ID_UINT16ARRAY, - ECMA_BUILTIN_ID_INT32ARRAY, - ECMA_BUILTIN_ID_UINT32ARRAY, - ECMA_BUILTIN_ID_FLOAT32ARRAY, -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - ECMA_BUILTIN_ID_FLOAT64ARRAY, -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ -}; - /** * The DataView.prototype object's {buffer, byteOffset, byteLength} getters * @@ -168,9 +153,9 @@ ecma_builtin_dataview_prototype_dispatch_routine (uint16_t builtin_routine_id, / case ECMA_DATAVIEW_PROTOTYPE_GET_UINT32: { ecma_value_t little_endian = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_FALSE; - uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8]; + ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8); - return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, ECMA_VALUE_EMPTY, type); + return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, ECMA_VALUE_EMPTY, id); } case ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32: #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) @@ -183,25 +168,25 @@ ecma_builtin_dataview_prototype_dispatch_routine (uint16_t builtin_routine_id, / { ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED; ecma_value_t little_endian = arguments_number > 2 ? arguments_list_p[2] : ECMA_VALUE_FALSE; - uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8]; + ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8); - return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, value_to_set, type); + return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, value_to_set, id); } case ECMA_DATAVIEW_PROTOTYPE_GET_INT8: case ECMA_DATAVIEW_PROTOTYPE_GET_UINT8: { - uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8]; + ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8); - return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, ECMA_VALUE_EMPTY, type); + return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, ECMA_VALUE_EMPTY, id); } default: { JERRY_ASSERT (builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_INT8 || builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_UINT8); ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED; - uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8]; + ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8); - return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, value_to_set, type); + return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, value_to_set, id); } } } /* ecma_builtin_dataview_prototype_dispatch_routine */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index dd490990e..ddd19606f 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -288,42 +288,31 @@ BUILTIN (ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, true, typedarray_prototype) -/* The %TypedArray% intrinsic object (ES2015 22.2.1) */ +/* The %TypedArray% intrinsic object (ES2015 22.2.1) + Note: The routines must be in this order. */ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_TYPEDARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, true, typedarray) -BUILTIN (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - int8array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT8ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, true, int8array) -BUILTIN (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - uint8array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT8ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, true, uint8array) -BUILTIN (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - int16array_prototype) +BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY, + ECMA_OBJECT_TYPE_FUNCTION, + ECMA_BUILTIN_ID_TYPEDARRAY, + true, + uint8clampedarray) BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT16ARRAY, ECMA_OBJECT_TYPE_FUNCTION, @@ -331,48 +320,24 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT16ARRAY, true, int16array) -BUILTIN (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - uint16array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT16ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, true, uint16array) -BUILTIN (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - int32array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT32ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, true, int32array) -BUILTIN (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - uint32array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT32ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, true, uint32array) -BUILTIN (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - float32array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT32ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, @@ -380,12 +345,6 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT32ARRAY, float32array) #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) -BUILTIN (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE, - ECMA_OBJECT_TYPE_GENERAL, - ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, - true, - float64array_prototype) - BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT64ARRAY, ECMA_OBJECT_TYPE_FUNCTION, ECMA_BUILTIN_ID_TYPEDARRAY, @@ -393,18 +352,62 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT64ARRAY, float64array) #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + +BUILTIN (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + int8array_prototype) + +BUILTIN (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + uint8array_prototype) + BUILTIN (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE, ECMA_OBJECT_TYPE_GENERAL, ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, true, uint8clampedarray_prototype) -BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY, - ECMA_OBJECT_TYPE_FUNCTION, - ECMA_BUILTIN_ID_TYPEDARRAY, - true, - uint8clampedarray) +BUILTIN (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + int16array_prototype) +BUILTIN (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + uint16array_prototype) + +BUILTIN (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + int32array_prototype) + +BUILTIN (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + uint32array_prototype) + +BUILTIN (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + float32array_prototype) + +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) +BUILTIN (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE, + ECMA_OBJECT_TYPE_GENERAL, + ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE, + true, + float64array_prototype) +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.c index 384ba994b..5a08a8755 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.c @@ -66,7 +66,7 @@ ecma_builtin_float32array_dispatch_construct (const ecma_value_t *arguments_list ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_FLOAT32ARRAY); + ECMA_FLOAT32_ARRAY); } /* ecma_builtin_float32array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array.c index cc7dcaa3d..8eef1959f 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array.c @@ -67,7 +67,7 @@ ecma_builtin_float64array_dispatch_construct (const ecma_value_t *arguments_list ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_FLOAT64ARRAY); + ECMA_FLOAT64_ARRAY); } /* ecma_builtin_float64array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array.c index af46ec318..d2b838a1b 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array.c @@ -66,7 +66,7 @@ ecma_builtin_int16array_dispatch_construct (const ecma_value_t *arguments_list_p ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_INT16ARRAY); + ECMA_INT16_ARRAY); } /* ecma_builtin_int16array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array.c index d7679204d..6348829b0 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array.c @@ -66,7 +66,7 @@ ecma_builtin_int32array_dispatch_construct (const ecma_value_t *arguments_list_p ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_INT32ARRAY); + ECMA_INT32_ARRAY); } /* ecma_builtin_int32array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array.c index 9e1008093..25ee07ad8 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array.c @@ -66,7 +66,7 @@ ecma_builtin_int8array_dispatch_construct (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_INT8ARRAY); + ECMA_INT8_ARRAY); } /* ecma_builtin_int8array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c index 17b52b45c..d8906a691 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c @@ -25,182 +25,6 @@ #define ECMA_BUILTINS_INTERNAL #include "ecma-builtins-internal.h" -/** - * Returns true if the builtin is a TypedArray type. - * - * @return bool - */ -bool -ecma_typedarray_helper_is_typedarray (uint8_t builtin_id) /**< the builtin id of a type **/ -{ - switch (builtin_id) - { - case ECMA_BUILTIN_ID_INT8ARRAY: - case ECMA_BUILTIN_ID_UINT8ARRAY: - case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY: - case ECMA_BUILTIN_ID_INT16ARRAY: - case ECMA_BUILTIN_ID_UINT16ARRAY: - case ECMA_BUILTIN_ID_INT32ARRAY: - case ECMA_BUILTIN_ID_UINT32ARRAY: - case ECMA_BUILTIN_ID_FLOAT32ARRAY: -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - case ECMA_BUILTIN_ID_FLOAT64ARRAY: -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - { - return true; - } - default: - { - return false; - } - } -} /* ecma_typedarray_helper_is_typedarray */ - -/** - * Get the element shift size of a TypedArray type. - * - * @return uint8_t - */ -uint8_t -ecma_typedarray_helper_get_shift_size (uint8_t builtin_id) /**< the builtin id of the typedarray **/ -{ - switch (builtin_id) - { - case ECMA_BUILTIN_ID_INT8ARRAY: - case ECMA_BUILTIN_ID_UINT8ARRAY: - case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY: - { - return 0; - } - case ECMA_BUILTIN_ID_INT16ARRAY: - case ECMA_BUILTIN_ID_UINT16ARRAY: - { - return 1; - } - case ECMA_BUILTIN_ID_INT32ARRAY: - case ECMA_BUILTIN_ID_UINT32ARRAY: - case ECMA_BUILTIN_ID_FLOAT32ARRAY: - { - return 2; - } -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - case ECMA_BUILTIN_ID_FLOAT64ARRAY: - { - return 3; - } -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - JERRY_UNREACHABLE (); - } - } -} /* ecma_typedarray_helper_get_shift_size */ - -/** - * Get the built-in TypedArray type from a magic string. - * - * @return uint8_t - */ -uint8_t -ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p) /**< typedarray object **/ -{ -#define TYPEDARRAY_ID_CASE(magic_id, builtin_id) \ - case magic_id: \ - { \ - return builtin_id; \ - } - - switch (ecma_object_get_class_name (obj_p)) - { - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT8_ARRAY_UL, ECMA_BUILTIN_ID_INT8ARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_ARRAY_UL, ECMA_BUILTIN_ID_UINT8ARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL, ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT16_ARRAY_UL, ECMA_BUILTIN_ID_INT16ARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT16_ARRAY_UL, ECMA_BUILTIN_ID_UINT16ARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT32_ARRAY_UL, ECMA_BUILTIN_ID_INT32ARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT32_ARRAY_UL, ECMA_BUILTIN_ID_UINT32ARRAY) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT32_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT32ARRAY) -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT64ARRAY) -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - JERRY_UNREACHABLE (); - } - } -#undef TYPEDARRAY_ID_CASE -} /* ecma_typedarray_helper_get_builtin_id */ - -/** - * Get the magic string of a TypedArray type. - * - * @return lit_magic_string_id_t - */ -lit_magic_string_id_t -ecma_typedarray_helper_get_magic_string (uint8_t builtin_id) /**< the builtin id of the typedarray **/ -{ -#define TYPEDARRAY_ID_CASE(builtin_id, magic_id) \ - case builtin_id: \ - { \ - return (lit_magic_string_id_t) magic_id; \ - } - - switch (builtin_id) - { - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT8ARRAY, LIT_MAGIC_STRING_INT8_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8ARRAY, LIT_MAGIC_STRING_UINT8_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY, LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT16ARRAY, LIT_MAGIC_STRING_INT16_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT16ARRAY, LIT_MAGIC_STRING_UINT16_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT32ARRAY, LIT_MAGIC_STRING_INT32_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT32ARRAY, LIT_MAGIC_STRING_UINT32_ARRAY_UL) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT32ARRAY, LIT_MAGIC_STRING_FLOAT32_ARRAY_UL) -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT64ARRAY, LIT_MAGIC_STRING_FLOAT64_ARRAY_UL) -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - JERRY_UNREACHABLE (); - } - } -#undef TYPEDARRAY_ID_CASE -} /* ecma_typedarray_helper_get_magic_string */ - -/** - * Get the prototype ID of a TypedArray type. - * - * @return uint8_t - */ -uint8_t -ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id) /**< the builtin id of the typedarray **/ -{ -#define TYPEDARRAY_ID_CASE(builtin_id) \ - case builtin_id: \ - { \ - return builtin_id ## _PROTOTYPE; \ - } - - switch (builtin_id) - { - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT8ARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8ARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT16ARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT16ARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT32ARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT32ARRAY) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT32ARRAY) -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT64ARRAY) -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - JERRY_UNREACHABLE (); - } - } -#undef TYPEDARRAY_ID_CASE -} /* ecma_typedarray_helper_get_prototype_id */ - /** * Common implementation of the [[Construct]] call of TypedArrays. * @@ -210,17 +34,16 @@ ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id) /**< the builtin id ecma_value_t ecma_typedarray_helper_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len, /**< number of arguments */ - uint8_t builtin_id) /**< the builtin id of the typedarray */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); - JERRY_ASSERT (ecma_typedarray_helper_is_typedarray (builtin_id)); - ecma_object_t *prototype_obj_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (builtin_id)); + ecma_object_t *prototype_obj_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id)); ecma_value_t val = ecma_op_create_typedarray (arguments_list_p, arguments_list_len, prototype_obj_p, - ecma_typedarray_helper_get_shift_size (builtin_id), - ecma_typedarray_helper_get_magic_string (builtin_id)); + ecma_typedarray_helper_get_shift_size (typedarray_id), + typedarray_id); return val; } /* ecma_typedarray_helper_dispatch_construct */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h index 9276a3f33..7ddee8e31 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h @@ -26,16 +26,10 @@ * @{ */ -bool ecma_typedarray_helper_is_typedarray (uint8_t builtin_id); -uint8_t ecma_typedarray_helper_get_shift_size (uint8_t builtin_id); -uint8_t ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p); -lit_magic_string_id_t ecma_typedarray_helper_get_magic_string (uint8_t builtin_id); -uint8_t ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id); - ecma_value_t ecma_typedarray_helper_dispatch_construct (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len, - uint8_t builtin_id); + ecma_typedarray_type_t typedarray_id); /** * @} 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 8a050537b..ce3fbd1ce 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 @@ -28,6 +28,7 @@ #include "ecma-try-catch-macro.h" #include "jrt.h" #include "jrt-libc-includes.h" +#include "jcontext.h" #include "ecma-gc.h" #include "jmem.h" #include "ecma-iterator-object.h" @@ -202,14 +203,20 @@ ecma_builtin_typedarray_prototype_exec_routine (ecma_value_t this_arg, /**< this } ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - uint32_t len = ecma_typedarray_get_length (obj_p); + ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); + + ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); + ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val); + lit_utf8_byte_t *target_p = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + info.offset; + ecma_length_t byte_pos = 0; ecma_value_t ret_value = ECMA_VALUE_EMPTY; - for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++) + for (uint32_t index = 0; index < info.typedarray_length && ecma_is_value_empty (ret_value); index++) { - ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_value_t get_value = ecma_op_typedarray_get_index_prop (obj_p, index); + ecma_value_t current_index = ecma_make_uint32_value (index); + ecma_number_t element_num = typedarray_getter_cb (target_p + byte_pos); + ecma_value_t get_value = ecma_make_number_value (element_num); JERRY_ASSERT (ecma_is_value_number (get_value)); @@ -230,6 +237,8 @@ ecma_builtin_typedarray_prototype_exec_routine (ecma_value_t this_arg, /**< this ret_value = ECMA_VALUE_TRUE; } + byte_pos += info.element_size; + ECMA_FINALIZE (call_value); ecma_fast_free_value (current_index); @@ -424,51 +433,65 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this argument return ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable.")); } - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - uint32_t len = ecma_typedarray_get_length (obj_p); - ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val); - ecma_value_t ret_value = ECMA_VALUE_EMPTY; + ecma_object_t *src_obj_p = ecma_get_object_from_value (this_arg); + ecma_typedarray_info_t src_info = ecma_typedarray_get_info (src_obj_p); - ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (obj_p, len); + ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val); + + ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (src_obj_p, src_info.typedarray_length); if (ECMA_IS_VALUE_ERROR (new_typedarray)) { return new_typedarray; } - ecma_object_t *new_obj_p = ecma_get_object_from_value (new_typedarray); + ecma_object_t *target_obj_p = ecma_get_object_from_value (new_typedarray); + ecma_typedarray_info_t target_info = ecma_typedarray_get_info (target_obj_p); - for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++) + ecma_typedarray_getter_fn_t src_typedarray_getter_cb = ecma_get_typedarray_getter_fn (src_info.typedarray_id); + ecma_typedarray_setter_fn_t target_typedarray_setter_cb = ecma_get_typedarray_setter_fn (target_info.typedarray_id); + + lit_utf8_byte_t *src_buff_p = ecma_arraybuffer_get_buffer (src_info.typedarray_buffer_p) + src_info.offset; + ecma_length_t src_byte_pos = 0; + + for (uint32_t index = 0; index < src_info.typedarray_length; index++) { - ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_value_t get_value = ecma_op_typedarray_get_index_prop (obj_p, index); + ecma_value_t current_index = ecma_make_uint32_value (index); + ecma_number_t element_num = src_typedarray_getter_cb (src_buff_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_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3), ret_value); - - bool set_status = ecma_op_typedarray_set_index_prop (new_obj_p, index, mapped_value); - - if (!set_status) + ecma_value_t mapped_value = ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3); + if (ECMA_IS_VALUE_ERROR (mapped_value)) { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("error in typedarray set")); + ecma_free_value (current_index); + ecma_free_value (get_value); + return mapped_value; } - ECMA_FINALIZE (mapped_value); + ecma_number_t mapped_num; + if (ECMA_IS_VALUE_ERROR (ecma_get_number (mapped_value, &mapped_num))) + { + ecma_free_value (mapped_value); + ecma_free_value (current_index); + ecma_free_value (get_value); + return ECMA_VALUE_ERROR; + } + else + { + ecma_length_t target_byte_pos = (index << target_info.shift) + target_info.offset; + lit_utf8_byte_t *target_buff_p = ecma_arraybuffer_get_buffer (target_info.typedarray_buffer_p) + target_byte_pos; + target_typedarray_setter_cb (target_buff_p, mapped_num); + } + 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); } - if (ecma_is_value_empty (ret_value)) - { - ret_value = new_typedarray; - } - else - { - ecma_free_value (new_typedarray); - } - - return ret_value; + return new_typedarray; } /* ecma_builtin_typedarray_prototype_map */ /** @@ -495,9 +518,13 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, } ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - uint32_t len = ecma_typedarray_get_length (obj_p); + ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); - if (len == 0) + ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + info.offset; + ecma_length_t byte_pos; + + if (info.typedarray_length == 0) { if (ecma_is_value_undefined (initial_val)) { @@ -507,14 +534,17 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, return ecma_copy_value (initial_val); } - JERRY_ASSERT (len > 0); + JERRY_ASSERT (info.typedarray_length > 0); ecma_value_t accumulator = ECMA_VALUE_UNDEFINED; - uint32_t index = is_right ? (len - 1) : 0; + uint32_t index = is_right ? (info.typedarray_length - 1) : 0; if (ecma_is_value_undefined (initial_val)) { - accumulator = ecma_op_typedarray_get_index_prop (obj_p, index); + + byte_pos = (index << info.shift) + info.offset; + ecma_number_t acc_num = getter_cb (src_buffer + byte_pos); + accumulator = ecma_make_number_value (acc_num); JERRY_ASSERT (ecma_is_value_number (accumulator)); @@ -531,7 +561,7 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, { index++; - if (index == len) + if (index == info.typedarray_length) { return accumulator; } @@ -547,7 +577,10 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, while (true) { ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_value_t get_value = ecma_op_typedarray_get_index_prop (obj_p, index); + byte_pos = (index << info.shift) + info.offset; + ecma_number_t get_num = getter_cb (src_buffer + byte_pos); + ecma_value_t get_value = ecma_make_number_value (get_num); + ecma_value_t call_args[] = { accumulator, get_value, current_index, this_arg }; JERRY_ASSERT (ecma_is_value_number (get_value)); @@ -581,7 +614,7 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, { index++; - if (index == len) + if (index == info.typedarray_length) { break; } @@ -656,26 +689,29 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum } ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - uint32_t len = ecma_typedarray_get_length (obj_p); - lit_utf8_byte_t *buffer_p = ecma_typedarray_get_buffer (obj_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (obj_p); - uint8_t element_size = (uint8_t) (1 << shift); + ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); + + ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); + ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val); ecma_value_t ret_value = ECMA_VALUE_EMPTY; - if (len == 0) + if (info.typedarray_length == 0) { return ecma_op_create_typedarray_with_type_and_length (obj_p, 0); } - JMEM_DEFINE_LOCAL_ARRAY (pass_value_list_p, len * element_size, lit_utf8_byte_t); + JMEM_DEFINE_LOCAL_ARRAY (pass_value_list_p, info.typedarray_length * info.element_size, lit_utf8_byte_t); lit_utf8_byte_t *pass_value_p = pass_value_list_p; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + info.offset; + ecma_length_t byte_pos = 0; - for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++) + for (uint32_t index = 0; index < info.typedarray_length && ecma_is_value_empty (ret_value); index++) { ecma_value_t current_index = ecma_make_uint32_value (index); - ecma_value_t get_value = ecma_op_typedarray_get_index_prop (obj_p, index); + ecma_number_t get_num = getter_cb (src_buffer + byte_pos); + ecma_value_t get_value = ecma_make_number_value (get_num); JERRY_ASSERT (ecma_is_value_number (get_value)); @@ -685,11 +721,12 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum if (ecma_op_to_boolean (call_value)) { - memcpy (pass_value_p, buffer_p, element_size); - pass_value_p += element_size; + memcpy (pass_value_p, info.buffer_p, info.element_size); + pass_value_p += info.element_size; } - buffer_p += element_size; + info.buffer_p += info.element_size; + byte_pos += info.element_size; ECMA_FINALIZE (call_value); @@ -699,7 +736,7 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum if (ecma_is_value_empty (ret_value)) { - uint32_t pass_num = (uint32_t) ((pass_value_p - pass_value_list_p) >> shift); + uint32_t pass_num = (uint32_t) ((pass_value_p - pass_value_list_p) >> info.shift); ret_value = ecma_op_create_typedarray_with_type_and_length (obj_p, pass_num); @@ -738,23 +775,21 @@ ecma_builtin_typedarray_prototype_reverse (ecma_value_t this_arg) /**< this argu } ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - uint32_t len = ecma_typedarray_get_length (obj_p); - lit_utf8_byte_t *buffer_p = ecma_typedarray_get_buffer (obj_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (obj_p); - uint8_t element_size = (uint8_t) (1 << shift); - uint32_t middle = (len / 2) << shift; - uint32_t buffer_last = (len << shift) - element_size; + ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); - for (uint32_t lower = 0; lower < middle; lower += element_size) + uint32_t middle = (info.typedarray_length / 2) << info.shift; + uint32_t buffer_last = (info.typedarray_length << info.shift) - info.element_size; + + for (uint32_t lower = 0; lower < middle; lower += info.element_size) { uint32_t upper = buffer_last - lower; - lit_utf8_byte_t *lower_p = buffer_p + lower; - lit_utf8_byte_t *upper_p = buffer_p + upper; + lit_utf8_byte_t *lower_p = info.buffer_p + lower; + lit_utf8_byte_t *upper_p = info.buffer_p + upper; lit_utf8_byte_t tmp[8]; - memcpy (&tmp[0], lower_p, element_size); - memcpy (lower_p, upper_p, element_size); - memcpy (upper_p, &tmp[0], element_size); + memcpy (&tmp[0], lower_p, info.element_size); + memcpy (lower_p, upper_p, info.element_size); + memcpy (upper_p, &tmp[0], info.element_size); } return ecma_copy_value (this_arg); @@ -792,52 +827,17 @@ ecma_op_typedarray_set_with_typedarray (ecma_value_t this_arg, /**< this argumen } ecma_object_t *target_typedarray_p = ecma_get_object_from_value (this_arg); + ecma_typedarray_info_t target_info = ecma_typedarray_get_info (target_typedarray_p); + ecma_object_t *src_typedarray_p = ecma_get_object_from_value (arr_val); + ecma_typedarray_info_t src_info = ecma_typedarray_get_info (src_typedarray_p); - /* 9. targetBuffer */ - ecma_object_t *target_arraybuffer_p = ecma_typedarray_get_arraybuffer (target_typedarray_p); - lit_utf8_byte_t *target_buffer_p = ecma_arraybuffer_get_buffer (target_arraybuffer_p); + lit_utf8_byte_t *target_buffer_p = ecma_arraybuffer_get_buffer (target_info.typedarray_buffer_p); + lit_utf8_byte_t *src_buffer_p = ecma_arraybuffer_get_buffer (src_info.typedarray_buffer_p); - /* 11. targetLength */ - ecma_length_t target_length = ecma_typedarray_get_length (target_typedarray_p); - - /* 12. srcBuffer */ - ecma_object_t *src_arraybuffer_p = ecma_typedarray_get_arraybuffer (src_typedarray_p); - lit_utf8_byte_t *src_buffer_p = ecma_arraybuffer_get_buffer (src_arraybuffer_p); - - /* 15. targetType */ - lit_magic_string_id_t target_class_id = ecma_object_get_class_name (target_typedarray_p); - - /* 16. targetElementSize */ - uint8_t target_shift = ecma_typedarray_get_element_size_shift (target_typedarray_p); - uint8_t target_element_size = (uint8_t) (1 << target_shift); - - /* 17. targetByteOffset */ - ecma_length_t target_byte_offset = ecma_typedarray_get_offset (target_typedarray_p); - - /* 19. srcType */ - lit_magic_string_id_t src_class_id = ecma_object_get_class_name (src_typedarray_p); - - /* 20. srcElementSize */ - uint8_t src_shift = ecma_typedarray_get_element_size_shift (src_typedarray_p); - uint8_t src_element_size = (uint8_t) (1 << src_shift); - - /* 21. srcLength */ - ecma_length_t src_length = ecma_typedarray_get_length (src_typedarray_p); - uint32_t src_length_uint32 = ecma_number_to_uint32 (src_length); - - if ((ecma_number_t) src_length_uint32 != src_length) - { - return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid source length")); - } - - /* 22. srcByteOffset */ - ecma_length_t src_byte_offset = ecma_typedarray_get_offset (src_typedarray_p); - - /* 23. */ uint32_t target_offset_uint32 = ecma_number_to_uint32 (target_offset_num); - if ((int64_t) src_length_uint32 + target_offset_uint32 > target_length) + if ((int64_t) src_info.typedarray_length + target_offset_uint32 > target_info.typedarray_length) { return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index")); } @@ -849,24 +849,28 @@ ecma_op_typedarray_set_with_typedarray (ecma_value_t this_arg, /**< this argumen } /* 26. targetByteIndex */ - uint32_t target_byte_index = target_offset_uint32 * target_element_size + target_byte_offset; + uint32_t target_byte_index = target_offset_uint32 * target_info.element_size + target_info.offset; /* 27. limit */ - uint32_t limit = target_byte_index + target_element_size * src_length_uint32; + uint32_t limit = target_byte_index + target_info.element_size * src_info.typedarray_length; - if (src_class_id == target_class_id) + if (src_info.typedarray_id == target_info.typedarray_id) { - memmove (target_buffer_p + target_byte_index, src_buffer_p + src_byte_offset, - target_element_size * src_length_uint32); + memmove (target_buffer_p + target_byte_index, src_buffer_p + src_info.offset, + target_info.element_size * src_info.typedarray_length); } else { + ecma_typedarray_getter_fn_t src_typedarray_getter_cb = ecma_get_typedarray_getter_fn (src_info.typedarray_id); + ecma_typedarray_setter_fn_t target_typedarray_setter_cb = ecma_get_typedarray_setter_fn (target_info.typedarray_id); + while (target_byte_index < limit) { - ecma_number_t elem_num = ecma_get_typedarray_element (src_buffer_p + src_byte_offset, src_class_id); - ecma_set_typedarray_element (target_buffer_p + target_byte_index, elem_num, target_class_id); - src_byte_offset += src_element_size; - target_byte_index += target_element_size; + ecma_length_t src_byte_offset = src_info.offset; + ecma_number_t elem_num = src_typedarray_getter_cb (src_buffer_p + src_byte_offset); + target_typedarray_setter_cb (target_buffer_p + target_byte_index, elem_num); + src_byte_offset += src_info.element_size; + target_byte_index += target_info.element_size; } } @@ -913,19 +917,9 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument } uint32_t target_offset_uint32 = ecma_number_to_uint32 (target_offset_num); - /* 11. targetLength */ + /* 11. ~ 15. */ ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - ecma_length_t target_length = ecma_typedarray_get_length (typedarray_p); - - /* 13. targetElementSize */ - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); - - /* 14. targetType */ - lit_magic_string_id_t target_class_id = ecma_object_get_class_name (typedarray_p); - - /* 9., 15. */ - lit_utf8_byte_t *target_buffer_p = ecma_typedarray_get_buffer (typedarray_p); + ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p); /* 16.~ 17. */ ECMA_TRY_CATCH (source_obj, ecma_op_to_object (arr_val), ret_val); @@ -952,15 +946,17 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument } /* 20. if srcLength + targetOffset > targetLength, throw a RangeError */ - if ((int64_t) source_length_uint32 + target_offset_uint32 > target_length) + if ((int64_t) source_length_uint32 + target_offset_uint32 > target_info.typedarray_length) { ret_val = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index")); } /* 21.~ 25. */ - uint32_t target_byte_index = target_offset_uint32 * element_size; + uint32_t target_byte_index = target_offset_uint32 * target_info.element_size; uint32_t k = 0; + ecma_typedarray_setter_fn_t target_typedarray_setter_cb = ecma_get_typedarray_setter_fn (target_info.typedarray_id); + while (k < source_length_uint32 && ecma_is_value_empty (ret_val)) { ecma_string_t *k_str_p = ecma_new_ecma_string_from_uint32 (k); @@ -971,7 +967,7 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument ECMA_OP_TO_NUMBER_TRY_CATCH (elem_num, elem, ret_val); - ecma_set_typedarray_element (target_buffer_p + target_byte_index, elem_num, target_class_id); + target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, elem_num); ECMA_OP_TO_NUMBER_FINALIZE (elem_num); ECMA_FINALIZE (elem); @@ -979,7 +975,7 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument ecma_deref_ecma_string (k_str_p); k++; - target_byte_index += element_size; + target_byte_index += target_info.element_size; } ECMA_OP_TO_NUMBER_FINALIZE (source_length_num); @@ -1239,30 +1235,26 @@ ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this arg } ecma_object_t *src_typedarray_p = ecma_get_object_from_value (this_arg); - - /* 5. buffer */ - ecma_object_t *src_typedarray_arraybuffer_p = ecma_typedarray_get_arraybuffer (src_typedarray_p); - - /* 6. srcLength */ - ecma_length_t src_length = ecma_typedarray_get_length (src_typedarray_p); + ecma_typedarray_info_t info = ecma_typedarray_get_info (src_typedarray_p); /* 9. beginIndex, 12. endIndex */ uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; /* 7. relativeBegin */ ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value); - begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, src_length, false); + + begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, info.typedarray_length, false); if (ecma_is_value_undefined (end)) { - end_index_uint32 = (uint32_t) src_length; + end_index_uint32 = (uint32_t) info.typedarray_length; } else { /* 10. relativeEnd */ ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value); - end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, src_length, false); + end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, info.typedarray_length, false); ECMA_OP_TO_NUMBER_FINALIZE (relative_end); } @@ -1282,25 +1274,17 @@ ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this arg subarray_length = end_index_uint32 - begin_index_uint32; } - /* 15. elementSize */ - uint8_t shift = ecma_typedarray_get_element_size_shift (src_typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); - - /* 16. srcByteOffset */ - ecma_length_t src_byte_offset = ecma_typedarray_get_offset (src_typedarray_p); - /* 17. beginByteOffset */ - ecma_length_t begin_byte_offset = src_byte_offset + begin_index_uint32 * element_size; + ecma_length_t begin_byte_offset = info.offset + begin_index_uint32 * info.element_size; - uint8_t src_builtin_id = ecma_typedarray_helper_get_builtin_id (src_typedarray_p); ecma_value_t arguments_p[3] = { - ecma_make_object_value (src_typedarray_arraybuffer_p), + ecma_make_object_value (info.typedarray_buffer_p), ecma_make_uint32_value (begin_byte_offset), ecma_make_uint32_value (subarray_length) }; - ret_value = ecma_typedarray_helper_dispatch_construct (arguments_p, 3, src_builtin_id); + ret_value = ecma_typedarray_helper_dispatch_construct (arguments_p, 3, info.typedarray_id); ecma_free_value (arguments_p[1]); ecma_free_value (arguments_p[2]); @@ -1336,24 +1320,25 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen } ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - ecma_object_t *typedarray_arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p); - lit_utf8_byte_t *buffer_p = ecma_arraybuffer_get_buffer (typedarray_arraybuffer_p); - ecma_length_t length = ecma_typedarray_get_length (typedarray_p); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + + lit_utf8_byte_t *buffer_p = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p); uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value); - begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, length, false); + + begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, info.typedarray_length, false); if (ecma_is_value_undefined (end)) { - end_index_uint32 = (uint32_t) length; + end_index_uint32 = (uint32_t) info.typedarray_length; } else { ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value); - end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, length, false); + end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, info.typedarray_length, false); ECMA_OP_TO_NUMBER_FINALIZE (relative_end); } @@ -1372,18 +1357,14 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen subarray_length = end_index_uint32 - begin_index_uint32; } - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - ecma_length_t byte_offset = ecma_typedarray_get_offset (typedarray_p); - lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p); - - uint8_t element_size = (uint8_t) (1 << shift); - uint32_t byte_index = byte_offset + begin_index_uint32 * element_size; - uint32_t limit = byte_index + subarray_length * element_size; + ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (info.typedarray_id); + uint32_t byte_index = info.offset + begin_index_uint32 * info.element_size; + uint32_t limit = byte_index + subarray_length * info.element_size; while (byte_index < limit) { - ecma_set_typedarray_element (buffer_p + byte_index, value_num, class_id); - byte_index += element_size; + typedarray_setter_cb (buffer_p + byte_index, value_num); + byte_index += info.element_size; } return ecma_copy_value (this_arg); @@ -1505,67 +1486,64 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen } ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - ecma_length_t typedarray_length = ecma_typedarray_get_length (typedarray_p); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); - if (!typedarray_length) + if (!info.typedarray_length) { return ecma_copy_value (this_arg); } ecma_value_t ret_value = ECMA_VALUE_EMPTY; - JMEM_DEFINE_LOCAL_ARRAY (values_buffer, typedarray_length, ecma_value_t); - - lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p); - lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); + JMEM_DEFINE_LOCAL_ARRAY (values_buffer, info.typedarray_length, ecma_value_t); uint32_t byte_index = 0, buffer_index = 0; - uint32_t limit = typedarray_length * element_size; + uint32_t limit = info.typedarray_length * info.element_size; + ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); /* Copy unsorted array into a native c array. */ while (byte_index < limit) { - JERRY_ASSERT (buffer_index < typedarray_length); - ecma_number_t element_num = ecma_get_typedarray_element (typedarray_buffer_p + byte_index, - class_id); + JERRY_ASSERT (buffer_index < info.typedarray_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); values_buffer[buffer_index++] = element_value; - byte_index += element_size; + byte_index += info.element_size; } - JERRY_ASSERT (buffer_index == typedarray_length); + JERRY_ASSERT (buffer_index == info.typedarray_length); const ecma_builtin_helper_sort_compare_fn_t sort_cb = &ecma_builtin_typedarray_prototype_sort_compare_helper; ECMA_TRY_CATCH (sort_value, ecma_builtin_helper_array_heap_sort_helper (values_buffer, - (uint32_t) (typedarray_length - 1), + (uint32_t) (info.typedarray_length - 1), compare_func, sort_cb), ret_value); ECMA_FINALIZE (sort_value); + ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (info.typedarray_id); + if (ecma_is_value_empty (ret_value)) { byte_index = 0; buffer_index = 0; - limit = typedarray_length * element_size; + limit = info.typedarray_length * info.element_size; /* Put sorted values from the native array back into the typedarray buffer. */ while (byte_index < limit) { - JERRY_ASSERT (buffer_index < typedarray_length); + JERRY_ASSERT (buffer_index < info.typedarray_length); ecma_value_t element_value = values_buffer[buffer_index++]; ecma_number_t element_num = ecma_get_number_from_value (element_value); - ecma_set_typedarray_element (typedarray_buffer_p + byte_index, element_num, class_id); - byte_index += element_size; + typedarray_setter_cb (info.buffer_p + byte_index, element_num); + byte_index += info.element_size; } - JERRY_ASSERT (buffer_index == typedarray_length); + JERRY_ASSERT (buffer_index == info.typedarray_length); } /* Free values that were copied to the local array. */ - for (uint32_t index = 0; index < typedarray_length; index++) + for (uint32_t index = 0; index < info.typedarray_length; index++) { ecma_free_value (values_buffer[index]); } @@ -1608,19 +1586,17 @@ ecma_builtin_typedarray_prototype_find_helper (ecma_value_t this_arg, /**< this ecma_object_t *func_object_p = ecma_get_object_from_value (predicate); ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - uint32_t typedarray_length = ecma_typedarray_get_length (typedarray_p); - lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p); - lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); uint32_t buffer_index = 0; - uint32_t limit = typedarray_length * element_size; + uint32_t limit = info.typedarray_length * info.element_size; - for (uint32_t byte_index = 0; byte_index < limit; byte_index += element_size) + ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); + + for (uint32_t byte_index = 0; byte_index < limit; byte_index += info.element_size) { - JERRY_ASSERT (buffer_index < typedarray_length); - ecma_number_t element_num = ecma_get_typedarray_element (typedarray_buffer_p + byte_index, class_id); + JERRY_ASSERT (buffer_index < info.typedarray_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 call_args[] = { element_value, ecma_make_uint32_value (buffer_index), this_arg }; @@ -1711,23 +1687,19 @@ ecma_builtin_typedarray_prototype_index_helper (ecma_value_t this_arg, /**< this } ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - uint32_t length = ecma_typedarray_get_length (typedarray_p); - lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p); - lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); - uint32_t limit = length * element_size; + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + uint32_t limit = info.typedarray_length * info.element_size; uint32_t from_index; if (args_number == 0 - || length == 0 - || !ecma_is_value_number (args[0])) + || !ecma_is_value_number (args[0]) + || info.typedarray_length == 0) { return ecma_make_integer_value (-1); } if (args_number == 1) { - from_index = is_last_index_of ? length - 1 : 0; + from_index = is_last_index_of ? info.typedarray_length - 1 : 0; } else { @@ -1741,29 +1713,29 @@ ecma_builtin_typedarray_prototype_index_helper (ecma_value_t this_arg, /**< this if (!ecma_number_is_nan (num_var) && is_last_index_of && num_var < 0 - && fabs (num_var) > length) + && fabs (num_var) > info.typedarray_length) { return ecma_make_integer_value (-1); } else { - from_index = ecma_builtin_helper_array_index_normalize (num_var, length, is_last_index_of); + from_index = ecma_builtin_helper_array_index_normalize (num_var, info.typedarray_length, is_last_index_of); } } ecma_number_t search_num = ecma_get_number_from_value (args[0]); - int32_t increment = is_last_index_of ? -element_size : element_size; + int32_t increment = is_last_index_of ? -info.element_size : info.element_size; - for (int32_t position = (int32_t) from_index * element_size; + for (int32_t position = (int32_t) from_index * info.element_size; (is_last_index_of ? position >= 0 : (uint32_t) position < limit); position += increment) { - ecma_number_t element_num = ecma_get_typedarray_element (typedarray_buffer_p + position, class_id); + ecma_number_t element_num = ecma_get_typedarray_element (info.buffer_p + position, info.typedarray_id); if (search_num == element_num) { - return ecma_make_number_value ((ecma_number_t) position / element_size); + return ecma_make_number_value ((ecma_number_t) position / info.element_size); } } @@ -1856,17 +1828,17 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this } ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p); - uint32_t length = ecma_typedarray_get_length (typedarray_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); uint32_t target = 0; uint32_t start = 0; - uint32_t end = length; + uint32_t end = info.typedarray_length; if (args_number > 0) { - ecma_value_t target_value = ecma_builtin_get_uint32_value_from_argument (args[0], length, &target, false); + ecma_value_t target_value = ecma_builtin_get_uint32_value_from_argument (args[0], + info.typedarray_length, + &target, + false); if (ECMA_IS_VALUE_ERROR (target_value)) { @@ -1875,7 +1847,10 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this if (args_number > 1) { - ecma_value_t start_value = ecma_builtin_get_uint32_value_from_argument (args[1], length, &start, false); + ecma_value_t start_value = ecma_builtin_get_uint32_value_from_argument (args[1], + info.typedarray_length, + &start, + false); if (ECMA_IS_VALUE_ERROR (start_value)) { @@ -1884,7 +1859,10 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this if (args_number > 2) { - ecma_value_t end_value = ecma_builtin_get_uint32_value_from_argument (args[2], length, &end, true); + ecma_value_t end_value = ecma_builtin_get_uint32_value_from_argument (args[2], + info.typedarray_length, + &end, + true); if (ECMA_IS_VALUE_ERROR (end_value)) { @@ -1895,18 +1873,18 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this } int32_t distance = (int32_t) (end - start); - int32_t offset = (int32_t) (length - target); + int32_t offset = (int32_t) (info.typedarray_length - target); int32_t count = JERRY_MIN (distance, offset); - if (target >= length || end == 0 || start >= end) + if (target >= info.typedarray_length || start >= end || end == 0) { return ecma_copy_value (this_arg); } else { - memmove (typedarray_buffer_p + (target * element_size), - typedarray_buffer_p + (start * element_size), - (size_t) (count * element_size)); + memmove (info.buffer_p + (target * info.element_size), + info.buffer_p + (start * info.element_size), + (size_t) (count * info.element_size)); } return ecma_copy_value (this_arg); @@ -1932,13 +1910,16 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume } ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - uint32_t length = ecma_typedarray_get_length (typedarray_p); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); uint32_t start = 0; - uint32_t end = length; + uint32_t end = info.typedarray_length; if (args_number > 0) { - ecma_value_t start_value = ecma_builtin_get_uint32_value_from_argument (args[0], length, &start, false); + ecma_value_t start_value = ecma_builtin_get_uint32_value_from_argument (args[0], + info.typedarray_length, + &start, + false); if (ECMA_IS_VALUE_ERROR (start_value)) { @@ -1947,7 +1928,10 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume if (args_number > 1) { - ecma_value_t end_value = ecma_builtin_get_uint32_value_from_argument (args[1], length, &end, true); + ecma_value_t end_value = ecma_builtin_get_uint32_value_from_argument (args[1], + info.typedarray_length, + &end, + true); if (ECMA_IS_VALUE_ERROR (end_value)) { @@ -1968,17 +1952,13 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume if (count > 0) { - lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); - ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); lit_utf8_byte_t *new_typedarray_buffer_p = ecma_typedarray_get_buffer (new_typedarray_p); - uint32_t src_byte_index = (start * element_size); + uint32_t src_byte_index = (start * info.element_size); memcpy (new_typedarray_buffer_p, - typedarray_buffer_p + src_byte_index, - count * element_size); + info.buffer_p + src_byte_index, + count * info.element_size); } return new_typedarray; @@ -1997,7 +1977,7 @@ static ecma_value_t ecma_builtin_typedarray_prototype_to_locale_string_helper (ecma_object_t *this_obj, /**< TypedArray object */ uint32_t index) /** array index */ { - lit_magic_string_id_t class_id = ecma_object_get_class_name (this_obj); + ecma_typedarray_type_t class_id = ecma_get_typedarray_id (this_obj); lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (this_obj); ecma_value_t ret_value = ECMA_VALUE_EMPTY; @@ -2073,12 +2053,10 @@ ecma_builtin_typedarray_prototype_to_locale_string (ecma_value_t this_arg) /**< } ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); - uint32_t length = ecma_typedarray_get_length (typedarray_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); - uint8_t element_size = (uint8_t) (1 << shift); - uint32_t limit = length * element_size; + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + uint32_t limit = info.typedarray_length * info.element_size; - if (length == 0) + if (info.typedarray_length == 0) { return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); } @@ -2092,7 +2070,7 @@ ecma_builtin_typedarray_prototype_to_locale_string (ecma_value_t this_arg) /**< ecma_string_t *return_string_p = ecma_get_string_from_value (first_element); - for (uint32_t k = element_size; k < limit; k += element_size) + for (uint32_t k = info.element_size; k < limit; k += info.element_size) { return_string_p = ecma_append_magic_string_to_string (return_string_p, LIT_MAGIC_STRING_COMMA_CHAR); ecma_value_t next_element = ecma_builtin_typedarray_prototype_to_locale_string_helper (typedarray_p, k); 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 48b8a5b83..613c8522c 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c @@ -99,17 +99,17 @@ ecma_builtin_typedarray_from (ecma_value_t this_arg, /**< 'this' argument */ return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a typedarray constructor")); } - ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (builtin_id)); - const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (builtin_id); - const lit_magic_string_id_t class_id = ecma_typedarray_helper_get_magic_string (builtin_id); + ecma_typedarray_type_t typedarray_id = ecma_typedarray_helper_builtin_to_typedarray_id (builtin_id); + ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id)); + const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (typedarray_id); return ecma_op_typedarray_from (source, map_fn, this_in_fn, proto_p, element_size_shift, - class_id); + typedarray_id); } /* ecma_builtin_typedarray_from */ diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array.c index 19a8f7938..9a8abf5d0 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array.c @@ -66,7 +66,7 @@ ecma_builtin_uint16array_dispatch_construct (const ecma_value_t *arguments_list_ ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_UINT16ARRAY); + ECMA_UINT16_ARRAY); } /* ecma_builtin_uint16array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array.c index f75e8ac07..acba99c91 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array.c @@ -30,6 +30,8 @@ #define BUILTIN_UNDERSCORED_ID uint32array #include "ecma-builtin-internal-routines-template.inc.h" +#include "ecma-builtin-typedarray-helpers.h" + /** \addtogroup ecma ECMA * @{ * @@ -65,14 +67,8 @@ ecma_builtin_uint32array_dispatch_construct (const ecma_value_t *arguments_list_ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); - ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE); - ecma_value_t val = ecma_op_create_typedarray (arguments_list_p, - arguments_list_len, - prototype_obj_p, - 2, - LIT_MAGIC_STRING_UINT32_ARRAY_UL); - - return val; + return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, + ECMA_UINT32_ARRAY); } /* ecma_builtin_uint32array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array.c index 1fd0a8e36..1429bdde8 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array.c @@ -66,7 +66,7 @@ ecma_builtin_uint8array_dispatch_construct (const ecma_value_t *arguments_list_p ecma_length_t arguments_list_len) /**< number of arguments */ { return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, - ECMA_BUILTIN_ID_UINT8ARRAY); + ECMA_UINT8_ARRAY); } /* ecma_builtin_uint8array_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray.c index a98c31945..52217f8ad 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray.c @@ -30,6 +30,8 @@ #define BUILTIN_UNDERSCORED_ID uint8clampedarray #include "ecma-builtin-internal-routines-template.inc.h" +#include "ecma-builtin-typedarray-helpers.h" + /** \addtogroup ecma ECMA * @{ * @@ -65,15 +67,8 @@ ecma_builtin_uint8clampedarray_dispatch_construct (const ecma_value_t *arguments { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); - ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE); - ecma_value_t val = ecma_op_create_typedarray (arguments_list_p, - arguments_list_len, - prototype_obj_p, - 0, - LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL); - - - return val; + return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len, + ECMA_UINT8_CLAMPED_ARRAY); } /* ecma_builtin_uint8clampedarray_dispatch_construct */ /** diff --git a/jerry-core/ecma/operations/ecma-dataview-object.c b/jerry-core/ecma/operations/ecma-dataview-object.c index af2580763..6c4ae23f9 100644 --- a/jerry-core/ecma/operations/ecma-dataview-object.c +++ b/jerry-core/ecma/operations/ecma-dataview-object.c @@ -15,7 +15,6 @@ #include "ecma-arraybuffer-object.h" #include "ecma-builtins.h" -#include "ecma-builtin-typedarray-helpers.h" #include "ecma-exceptions.h" #include "ecma-gc.h" #include "ecma-helpers.h" @@ -250,7 +249,7 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi ecma_value_t is_little_endian_value, /**< the operation's * 'isLittleEndian' argument */ ecma_value_t value_to_set, /**< the operation's 'value' argument */ - uint8_t type) /**< the operation's 'type' argument */ + ecma_typedarray_type_t id) /**< the operation's 'type' argument */ { /* 1 - 2. */ ecma_dataview_object_t *view_p = ecma_op_dataview_get_object (view); @@ -293,7 +292,7 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi uint32_t view_size = view_p->header.u.class_prop.u.length; /* 12. */ - uint8_t element_size = (uint8_t) (1 << (ecma_typedarray_helper_get_shift_size (type))); + uint8_t element_size = (uint8_t) (1 << (ecma_typedarray_helper_get_shift_size (id))); /* 13. */ if ((uint32_t) get_index + element_size > view_size) @@ -303,7 +302,6 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi /* 14. */ uint32_t buffer_index = (uint32_t) get_index + view_offset; - lit_magic_string_id_t id = ecma_typedarray_helper_get_magic_string (type); lit_utf8_byte_t *block_p = ecma_arraybuffer_get_buffer (buffer_p) + buffer_index; bool system_is_little_endian = ecma_dataview_check_little_endian (); diff --git a/jerry-core/ecma/operations/ecma-dataview-object.h b/jerry-core/ecma/operations/ecma-dataview-object.h index fa2c61908..3bc658acd 100644 --- a/jerry-core/ecma/operations/ecma-dataview-object.h +++ b/jerry-core/ecma/operations/ecma-dataview-object.h @@ -30,7 +30,8 @@ ecma_value_t ecma_op_dataview_create (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len); ecma_dataview_object_t *ecma_op_dataview_get_object (ecma_value_t this_arg); ecma_value_t ecma_op_dataview_get_set_view_value (ecma_value_t view, ecma_value_t request_index, - ecma_value_t little_endian, ecma_value_t value_to_set, uint8_t type); + ecma_value_t little_endian, ecma_value_t value_to_set, + ecma_typedarray_type_t id); /** * @} diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 52b6ab642..c52a951c2 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -25,9 +25,12 @@ #include "ecma-objects-arguments.h" #include "ecma-objects-general.h" #include "ecma-objects.h" +#include "jcontext.h" #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) #include "ecma-typedarray-object.h" +#include "ecma-arraybuffer-object.h" +#include "ecma-try-catch-macro.h" #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ /** \addtogroup ecma ECMA @@ -181,7 +184,17 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) { - ecma_value_t value = ecma_op_typedarray_get_index_prop (object_p, array_index); + ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); + ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); + ecma_value_t value = ECMA_VALUE_UNDEFINED; + + if (array_index < info.typedarray_length) + { + ecma_length_t byte_pos = (array_index << info.shift) + info.offset; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + byte_pos; + ecma_number_t num = getter_cb (src_buffer); + value = ecma_make_number_value (num); + } if (!ecma_is_value_undefined (value)) { @@ -542,7 +555,18 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) { - return ecma_op_typedarray_get_index_prop (object_p, array_index); + ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); + ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.typedarray_id); + + if (array_index >= info.typedarray_length) + { + return ECMA_VALUE_UNDEFINED; + } + + ecma_length_t byte_pos = (array_index << info.shift) + info.offset; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + byte_pos; + ecma_number_t num = getter_cb (src_buffer); + return ecma_make_number_value (num); } ecma_number_t num = ecma_string_to_number (property_name_p); @@ -1057,14 +1081,28 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) { - bool set_status = ecma_op_typedarray_set_index_prop (object_p, array_index, value); + ecma_number_t num_var; + ecma_value_t error = ecma_get_number (value, &num_var); - if (set_status) + if (ECMA_IS_VALUE_ERROR (error)) { - return ECMA_VALUE_TRUE; + ecma_free_value (JERRY_CONTEXT (error_value)); + return ecma_reject (is_throw); } - return ecma_reject (is_throw); + ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); + ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.typedarray_id); + + if (array_index >= info.typedarray_length) + { + return ecma_reject (is_throw); + } + + ecma_length_t byte_pos = (array_index << info.shift) + info.offset; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + byte_pos; + setter_cb (src_buffer, num_var); + + return ECMA_VALUE_TRUE; } ecma_number_t num = ecma_string_to_number (property_name_p); diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 1ab64870d..15dbabb67 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -38,121 +38,98 @@ */ /** - * Convert the value in location, - * cast it from type to ecma_number_t - * then assign to variale number + * Read an int8_t value from the given arraybuffer */ -#define GET_ELEMENT(type, location) \ - ((ecma_number_t) (*((type *) location))); +static ecma_number_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; +} /* ecma_typedarray_get_int8_element */ /** - * set typedarray's element value - * - * @return ecma_number_t: the value of the element + * Read an uint8_t value from the given arraybuffer */ -ecma_number_t -ecma_get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal arraybuffer */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ +static ecma_number_t +ecma_typedarray_get_uint8_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { - switch (class_id) - { - case LIT_MAGIC_STRING_INT8_ARRAY_UL: - { - return GET_ELEMENT (int8_t, src); - } - case LIT_MAGIC_STRING_UINT8_ARRAY_UL: - case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL: - { - return GET_ELEMENT (uint8_t, src); - } - case LIT_MAGIC_STRING_INT16_ARRAY_UL: - { - return GET_ELEMENT (int16_t, src); - } - case LIT_MAGIC_STRING_UINT16_ARRAY_UL: - { - return GET_ELEMENT (uint16_t, src); - } - case LIT_MAGIC_STRING_INT32_ARRAY_UL: - { - return GET_ELEMENT (int32_t, src); - } - case LIT_MAGIC_STRING_UINT32_ARRAY_UL: - { - return GET_ELEMENT (uint32_t, src); - } - case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL: - { - return GET_ELEMENT (float, src); - } -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL: - { - return GET_ELEMENT (double, src); - } -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - JERRY_UNREACHABLE (); - } - } -} /* ecma_get_typedarray_element */ - -#undef GET_ELEMENT + uint8_t num = (uint8_t) *src; + return (ecma_number_t) num; +} /* ecma_typedarray_get_uint8_element */ /** - * set typedarray's element value + * Read an int16_t value from the given arraybuffer */ -void -ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */ - ecma_number_t value, /**< the number value to set */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ +static ecma_number_t +ecma_typedarray_get_int16_element (lit_utf8_byte_t *src) /**< the location in the internal arraybuffer */ { - switch (class_id) - { - case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL: - { - uint8_t clamped; + int16_t num; + memcpy (&num, src, sizeof (int16_t)); + return (ecma_number_t) num; +} /* ecma_typedarray_get_int16_element */ - if (value > 255) - { - clamped = 255; - } - else if (value <= 0) - { - clamped = 0; - } - else - { - clamped = (uint8_t) value; +/** + * Read an uint16_t value from the given arraybuffer + */ +static ecma_number_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_uint16_element */ - if (clamped + 0.5 < value - || (clamped + 0.5 == value && (clamped % 2) == 1)) - { - clamped ++; - } - } - *((uint8_t *) dst_p) = clamped; - return; - } - case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL: - { - *((float *) dst_p) = (float) value; - return; - } -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL: - { - *((double *) dst_p) = (double) value; - return; - } -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - break; - } - } +/** + * Read an int32_t value from the given arraybuffer + */ +static ecma_number_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_int32_element */ +/** + * Read an uint32_t value from the given arraybuffer + */ +static ecma_number_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_uint32_element */ + +/** + * Read a float value from the given arraybuffer + */ +static ecma_number_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_float_element */ + +/** + * Read a double value from the given arraybuffer + */ +static ecma_number_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_double_element */ + + +/** + * Normalize the given ecma_number_t to an uint32_t value + */ +static uint32_t +ecma_typedarray_setter_number_to_uint32 (ecma_number_t value) /**< the number value to normalize */ +{ uint32_t uint32_value = 0; if (!ecma_number_is_nan (value) && !ecma_number_is_infinity (value)) @@ -178,45 +155,337 @@ ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the in } } - switch (class_id) + return uint32_value; +} /* ecma_typedarray_setter_number_to_uint32 */ + +/** + * Write an int8_t value into the given arraybuffer + */ +static void +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 */ +{ + int8_t num = (int8_t) ecma_typedarray_setter_number_to_uint32 (value); + *dst_p = (lit_utf8_byte_t) num; +} /* ecma_typedarray_set_int8_element */ + + +/** + * Write an uint8_t value into the given arraybuffer + */ +static void +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 */ +{ + uint8_t num = (uint8_t) ecma_typedarray_setter_number_to_uint32 (value); + *dst_p = (lit_utf8_byte_t) num; +} /* ecma_typedarray_set_uint8_element */ + +/** + * Write an uint8_t clamped value into the given arraybuffer + */ +static void +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 */ +{ + uint8_t clamped; + + if (value > 255) { - case LIT_MAGIC_STRING_INT8_ARRAY_UL: + clamped = 255; + } + else if (value <= 0) + { + clamped = 0; + } + else + { + clamped = (uint8_t) value; + + if (clamped + 0.5 < value + || (clamped + 0.5 == value && (clamped % 2) == 1)) { - *((int8_t *) dst_p) = (int8_t) uint32_value; - break; - } - case LIT_MAGIC_STRING_UINT8_ARRAY_UL: - { - *((uint8_t *) dst_p) = (uint8_t) uint32_value; - break; - } - case LIT_MAGIC_STRING_INT16_ARRAY_UL: - { - *((int16_t *) dst_p) = (int16_t) uint32_value; - break; - } - case LIT_MAGIC_STRING_UINT16_ARRAY_UL: - { - *((uint16_t *) dst_p) = (uint16_t) uint32_value; - break; - } - case LIT_MAGIC_STRING_INT32_ARRAY_UL: - { - *((int32_t *) dst_p) = (int32_t) uint32_value; - break; - } - case LIT_MAGIC_STRING_UINT32_ARRAY_UL: - { - *((uint32_t *) dst_p) = uint32_value; - break; - } - default: - { - JERRY_UNREACHABLE (); + clamped ++; } } + + *dst_p = (lit_utf8_byte_t) clamped; +} /* ecma_typedarray_set_uint8_clamped_element */ + +/** + * Write an int16_t value into the given arraybuffer + */ +static void +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 */ +{ + int16_t num = (int16_t) ecma_typedarray_setter_number_to_uint32 (value); + memcpy (dst_p, &num, sizeof (int16_t)); +} /* ecma_typedarray_set_int16_element */ + + +/** + * Write an uint8_t value into the given arraybuffer + */ +static void +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 */ +{ + uint16_t num = (uint16_t) ecma_typedarray_setter_number_to_uint32 (value); + memcpy (dst_p, &num, sizeof (uint16_t)); +} /* ecma_typedarray_set_uint16_element */ + +/** + * Write an int32_t value into the given arraybuffer + */ +static void +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 */ +{ + int32_t num = (int32_t) ecma_typedarray_setter_number_to_uint32 (value); + memcpy (dst_p, &num, sizeof (int32_t)); +} /* ecma_typedarray_set_int32_element */ + + +/** + * Write an uint32_t value into the given arraybuffer + */ +static void +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 */ +{ + uint32_t num = (uint32_t) ecma_typedarray_setter_number_to_uint32 (value); + memcpy (dst_p, &num, sizeof (uint32_t)); +} /* ecma_typedarray_set_uint32_element */ + + +/** + * Write a float value into the given arraybuffer + */ +static void +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 */ +{ + float num = (float) value; + memcpy (dst_p, &num, sizeof (float)); +} /* ecma_typedarray_set_float_element */ + +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) +/** + * Write a double value into the given arraybuffer + */ +static void +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 */ +{ + double num = (double) value; + memcpy (dst_p, &num, sizeof (double)); +} /* ecma_typedarray_set_double_element */ +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + + +/** + * 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) +/** + * Builtin id of the last %TypedArray% builtin routine intrinsic object + */ +#define ECMA_LAST_TYPEDARRAY_BUILTIN_ROUTINE_ID ECMA_BUILTIN_ID_FLOAT64ARRAY +#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +/** + * Builtin id of the last %TypedArray% builtin routine intrinsic object + */ +#define ECMA_LAST_TYPEDARRAY_BUILTIN_ROUTINE_ID ECMA_BUILTIN_ID_FLOAT32ARRAY +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ + +/** + * Builtin id of the first %TypedArray% builtin prototype intrinsic object + */ +#define ECMA_FIRST_TYPEDARRAY_BUILTIN_PROTOTYPE_ID ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE + +/** + * List of typedarray getters based on their builtin id + */ +static const ecma_typedarray_getter_fn_t ecma_typedarray_getters[] = +{ + ecma_typedarray_get_int8_element, /**< Int8Array */ + ecma_typedarray_get_uint8_element, /**< Uint8Array */ + ecma_typedarray_get_uint8_element, /**< Uint8ClampedArray */ + ecma_typedarray_get_int16_element, /**< Int16Array */ + ecma_typedarray_get_uint16_element, /**< Int32Array */ + ecma_typedarray_get_int32_element, /**< Uint32Array */ + ecma_typedarray_get_uint32_element, /**< Uint32Array */ + ecma_typedarray_get_float_element, /**< Float32Array */ +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) + ecma_typedarray_get_double_element, /**< Float64Array */ +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +}; + +/** + * List of typedarray setters based on their builtin id + */ +static const ecma_typedarray_setter_fn_t ecma_typedarray_setters[] = +{ + ecma_typedarray_set_int8_element, /**< Int8Array */ + ecma_typedarray_set_uint8_element, /**< Uint8Array */ + ecma_typedarray_set_uint8_clamped_element, /**< Uint8ClampedArray */ + ecma_typedarray_set_int16_element, /**< Int16Array */ + ecma_typedarray_set_uint16_element, /**< Int32Array */ + ecma_typedarray_set_int32_element, /**< Uint32Array */ + ecma_typedarray_set_uint32_element, /**< Uint32Array */ + ecma_typedarray_set_float_element, /**< Float32Array */ +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) + ecma_typedarray_set_double_element, /**< Float64Array */ +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +}; + +/** + * List of typedarray element shift sizes based on their builtin id + */ +static const uint8_t ecma_typedarray_element_shift_sizes[] = +{ + 0, /**< Int8Array */ + 0, /**< Uint8Array */ + 0, /**< Uint8ClampedArray */ + 1, /**< Int16Array */ + 1, /**< Uint16Array */ + 2, /**< Int32Array */ + 2, /**< Uint32Array */ + 2, /**< Float32Array */ +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) + 3, /**< Float64Array */ +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +}; + +/** + * List of typedarray class magic strings based on their builtin id + */ +static const uint16_t ecma_typedarray_magic_string_list[] = +{ + (uint16_t) LIT_MAGIC_STRING_INT8_ARRAY_UL, /**< Int8Array */ + (uint16_t) LIT_MAGIC_STRING_UINT8_ARRAY_UL, /**< Uint8Array */ + (uint16_t) LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL, /**< Uint8ClampedArray */ + (uint16_t) LIT_MAGIC_STRING_INT16_ARRAY_UL, /**< Int16Array */ + (uint16_t) LIT_MAGIC_STRING_UINT16_ARRAY_UL, /**< Uint16Array */ + (uint16_t) LIT_MAGIC_STRING_INT32_ARRAY_UL, /**< Int32Array */ + (uint16_t) LIT_MAGIC_STRING_UINT32_ARRAY_UL, /**< Uint32Array */ + (uint16_t) LIT_MAGIC_STRING_FLOAT32_ARRAY_UL, /**< Float32Array */ +#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) + (uint16_t) LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, /**< Float64Array */ +#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ +}; + +/** + * Get typedarray's getter function callback + * + * @return ecma_typedarray_getter_fn_t: the getter function for the given builtin TypedArray id + */ +inline ecma_typedarray_getter_fn_t JERRY_ATTR_ALWAYS_INLINE +ecma_get_typedarray_getter_fn (ecma_typedarray_type_t typedarray_id) +{ + return ecma_typedarray_getters[typedarray_id]; +} /* ecma_get_typedarray_getter_fn */ + +/** + * get typedarray's element value + * + * @return ecma_number_t: the value of the element + */ +inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE +ecma_get_typedarray_element (lit_utf8_byte_t *src_p, + ecma_typedarray_type_t typedarray_id) +{ + return ecma_typedarray_getters[typedarray_id](src_p); +} /* ecma_get_typedarray_element */ + +/** + * Get typedarray's setter function callback + * + * @return ecma_typedarray_setter_fn_t: the setter function for the given builtin TypedArray id + */ +inline ecma_typedarray_setter_fn_t JERRY_ATTR_ALWAYS_INLINE +ecma_get_typedarray_setter_fn (ecma_typedarray_type_t typedarray_id) +{ + return ecma_typedarray_setters[typedarray_id]; +} /* ecma_get_typedarray_setter_fn */ + +/** + * set typedarray's element value + */ +inline void JERRY_ATTR_ALWAYS_INLINE +ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, + ecma_number_t value, + ecma_typedarray_type_t typedarray_id) +{ + ecma_typedarray_setters[typedarray_id](dst_p, value); } /* ecma_set_typedarray_element */ +/** + * Get the element shift size of a TypedArray type. + * + * @return uint8_t + */ +inline uint8_t JERRY_ATTR_ALWAYS_INLINE +ecma_typedarray_helper_get_shift_size (ecma_typedarray_type_t typedarray_id) +{ + return ecma_typedarray_element_shift_sizes[typedarray_id]; +} /* ecma_typedarray_helper_get_shift_size */ + +/** + * Check if the builtin is a TypedArray type. + * + * @return bool: - true if based on the given id it is a TypedArray + * - false if based on the given id it is not a TypedArray + */ +bool +ecma_typedarray_helper_is_typedarray (ecma_builtin_id_t builtin_id) /**< the builtin id of a type **/ +{ + return ((builtin_id >= ECMA_FIRST_TYPEDARRAY_BUILTIN_ROUTINE_ID) + && (builtin_id <= ECMA_LAST_TYPEDARRAY_BUILTIN_ROUTINE_ID)); +} /* ecma_typedarray_helper_is_typedarray */ + +/** + * Get the prototype ID of a TypedArray type. + * + * @return ecma_builtin_id_t + */ +ecma_builtin_id_t +ecma_typedarray_helper_get_prototype_id (ecma_typedarray_type_t typedarray_id) /**< the id of the typedarray **/ +{ + return (ecma_builtin_id_t) (ECMA_FIRST_TYPEDARRAY_BUILTIN_PROTOTYPE_ID + typedarray_id); +} /* ecma_typedarray_helper_get_prototype_id */ + +/** + * Get the built-in TypedArray type of the given object. + * + * @return ecma_typedarray_type_t + */ +ecma_typedarray_type_t +ecma_get_typedarray_id (ecma_object_t *obj_p) /**< typedarray object **/ +{ + JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p))); + + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + + return (ecma_typedarray_type_t) ext_object_p->u.pseudo_array.extra_info; +} /* ecma_get_typedarray_id */ + +/** + * Get the built-in TypedArray type of the given object. + * + * @return ecma_typedarray_type_t + */ +ecma_typedarray_type_t +ecma_typedarray_helper_builtin_to_typedarray_id (ecma_builtin_id_t builtin_id) +{ + JERRY_ASSERT (ecma_typedarray_helper_is_typedarray (builtin_id)); + + return (ecma_typedarray_type_t) (builtin_id - ECMA_FIRST_TYPEDARRAY_BUILTIN_ROUTINE_ID); +} /* ecma_typedarray_helper_builtin_to_typedarray_id */ + /** * Create a TypedArray object by given array_length * @@ -229,7 +498,7 @@ ecma_value_t ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< length of the typedarray */ ecma_object_t *proto_p, /**< prototype object */ uint8_t element_size_shift, /**< the size shift of the element length */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { if (array_length > (UINT32_MAX >> element_size_shift)) { @@ -243,18 +512,18 @@ ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< leng return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached.")); } - ecma_value_t new_arraybuffer_p = ecma_make_object_value (ecma_arraybuffer_new_object (byte_length)); + ecma_object_t *new_arraybuffer_p = ecma_arraybuffer_new_object (byte_length); ecma_object_t *object_p = ecma_create_object (proto_p, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_PSEUDO_ARRAY); ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - ext_object_p->u.pseudo_array.u1.class_id = (uint16_t) class_id; + ext_object_p->u.pseudo_array.u1.class_id = ecma_typedarray_magic_string_list[typedarray_id]; ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY; - ext_object_p->u.pseudo_array.extra_info = element_size_shift; - ext_object_p->u.pseudo_array.u2.arraybuffer = new_arraybuffer_p; + ext_object_p->u.pseudo_array.extra_info = (uint8_t) typedarray_id; + ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (new_arraybuffer_p); - ecma_free_value (new_arraybuffer_p); + ecma_deref_object (new_arraybuffer_p); return ecma_make_object_value (object_p); } /* ecma_typedarray_create_object_with_length */ @@ -273,7 +542,7 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th ecma_length_t array_length, /**< length of the typedarray */ ecma_object_t *proto_p, /**< prototype object */ uint8_t element_size_shift, /**< the size shift of the element length */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { ecma_length_t expected_length = (ecma_arraybuffer_get_length (arraybuffer_p) >> element_size_shift); @@ -285,9 +554,9 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th ecma_object_t *object_p = ecma_create_object (proto_p, object_size, ECMA_OBJECT_TYPE_PSEUDO_ARRAY); ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - ext_object_p->u.pseudo_array.u1.class_id = (uint16_t) class_id; + ext_object_p->u.pseudo_array.u1.class_id = ecma_typedarray_magic_string_list[typedarray_id]; ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY; - ext_object_p->u.pseudo_array.extra_info = element_size_shift; + ext_object_p->u.pseudo_array.extra_info = (uint8_t) typedarray_id; ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (arraybuffer_p); if (needs_ext_typedarray_obj) @@ -314,14 +583,14 @@ static ecma_value_t ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**< a typedarray object */ ecma_object_t *proto_p, /**< prototype object */ uint8_t element_size_shift, /**< the size shift of the element length */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { ecma_length_t array_length = ecma_typedarray_get_length (typedarray_p); ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (array_length, proto_p, element_size_shift, - class_id); + typedarray_id); if (ECMA_IS_VALUE_ERROR (new_typedarray)) { @@ -338,9 +607,9 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**< src_buf_p += ecma_typedarray_get_offset (typedarray_p); - lit_magic_string_id_t src_class_id = ecma_object_get_class_name (typedarray_p); + ecma_typedarray_type_t src_id = ecma_get_typedarray_id (typedarray_p); - if (src_class_id == class_id) + if (src_id == typedarray_id) { memcpy (dst_buf_p, src_buf_p, array_length << element_size_shift); } @@ -348,12 +617,15 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**< { 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); + ecma_typedarray_setter_fn_t target_typedarray_setter_cb = ecma_get_typedarray_setter_fn (typedarray_id); + for (uint32_t i = 0; i < array_length; i++) { /* Convert values from source to destination format. */ - ecma_number_t tmp = ecma_get_typedarray_element (src_buf_p, src_class_id); - ecma_set_typedarray_element (dst_buf_p, tmp, class_id); + ecma_number_t tmp = src_typedarray_getter_cb (src_buf_p); + target_typedarray_setter_cb (dst_buf_p, tmp); src_buf_p += src_element_size; dst_buf_p += dst_element_size; @@ -377,7 +649,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje ecma_value_t this_val, /**< this_arg for the above map function */ ecma_object_t *proto_p, /**< prototype object */ uint8_t element_size_shift, /**< the size shift of the element length */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { ecma_value_t ret_value = ECMA_VALUE_EMPTY; @@ -410,7 +682,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len, proto_p, element_size_shift, - class_id); + typedarray_id); if (ECMA_IS_VALUE_ERROR (new_typedarray)) { @@ -419,6 +691,10 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje else { ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); + ecma_typedarray_info_t info = ecma_typedarray_get_info (new_typedarray_p); + ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.typedarray_id); + ecma_value_t error = ECMA_VALUE_EMPTY; + ecma_number_t num_var; /* 17 */ ecma_value_t current_index; @@ -441,24 +717,41 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, this_val, call_args, 2), ret_value); - bool set_status = ecma_op_typedarray_set_index_prop (new_typedarray_p, index, mapped_value); + error = ecma_get_number (mapped_value, &num_var); - if (!set_status) + if (ECMA_IS_VALUE_ERROR (error)) { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));; + ret_value = ECMA_VALUE_ERROR; } + if (index >= info.typedarray_length) + { + ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type.")); + } + + ecma_length_t byte_pos = (index << info.shift) + info.offset; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + byte_pos; + setter_cb (src_buffer, num_var); + ECMA_FINALIZE (mapped_value); } else { - /* 17.e 17.f */ - bool set_status = ecma_op_typedarray_set_index_prop (new_typedarray_p, index, current_value); + error = ecma_get_number (current_value, &num_var); - if (!set_status) + if (ECMA_IS_VALUE_ERROR (error)) { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));; + ret_value = ECMA_VALUE_ERROR; } + + if (index >= info.typedarray_length) + { + ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type.")); + } + + ecma_length_t byte_pos = (index << info.shift) + info.offset; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + byte_pos; + setter_cb (src_buffer, num_var); } } @@ -509,9 +802,7 @@ ecma_typedarray_get_element_size_shift (ecma_object_t *typedarray_p) /**< the po { JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (typedarray_p))); - ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) typedarray_p; - - return ext_object_p->u.pseudo_array.extra_info; + return ecma_typedarray_helper_get_shift_size (ecma_get_typedarray_id (typedarray_p)); } /* ecma_typedarray_get_element_size_shift */ @@ -531,7 +822,7 @@ ecma_typedarray_get_length (ecma_object_t *typedarray_p) /**< the pointer to the { ecma_object_t *arraybuffer_p = ecma_get_object_from_value (ext_object_p->u.pseudo_array.u2.arraybuffer); ecma_length_t buffer_length = ecma_arraybuffer_get_length (arraybuffer_p); - uint8_t shift = ext_object_p->u.pseudo_array.extra_info; + uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); return buffer_length >> shift; } @@ -592,7 +883,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li ecma_length_t arguments_list_len, /**< the length of the arguments_list_p */ ecma_object_t *proto_p, /**< prototype object */ uint8_t element_size_shift, /**< the size shift of the element length */ - lit_magic_string_id_t class_id) /**< class name of the typedarray */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); @@ -601,7 +892,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li if (arguments_list_len == 0) { /* 22.2.1.1 */ - ret = ecma_typedarray_create_object_with_length (0, proto_p, element_size_shift, class_id); + ret = ecma_typedarray_create_object_with_length (0, proto_p, element_size_shift, typedarray_id); } else if (!ecma_is_value_object (arguments_list_p[0])) { @@ -624,7 +915,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li ret = ecma_typedarray_create_object_with_length (length, proto_p, element_size_shift, - class_id); + typedarray_id); } ECMA_OP_TO_NUMBER_FINALIZE (num); @@ -638,7 +929,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li ret = ecma_typedarray_create_object_with_typedarray (typedarray_p, proto_p, element_size_shift, - class_id); + typedarray_id); } else if (ecma_is_arraybuffer (arguments_list_p[0])) { @@ -709,7 +1000,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li array_length, proto_p, element_size_shift, - class_id); + typedarray_id); } } @@ -724,7 +1015,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li undef, proto_p, element_size_shift, - class_id); + typedarray_id); } } @@ -779,38 +1070,6 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA } } /* ecma_op_typedarray_list_lazy_property_names */ -/** - * Get the integer number property value of the typedarray - * - * See also: ES2015 9.4.5.8 - * - * @return ecma value - * returns undefined if index is greater or equal than length - */ -ecma_value_t -ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, /**< a TypedArray object */ - uint32_t index) /**< the index number */ -{ - JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p))); - - ecma_length_t array_length = ecma_typedarray_get_length (obj_p); - - if (index >= array_length) - { - return ECMA_VALUE_UNDEFINED; - } - - ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (obj_p); - ecma_length_t offset = ecma_typedarray_get_offset (obj_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (obj_p); - ecma_length_t byte_pos = (index << shift) + offset; - lit_magic_string_id_t class_id = ecma_object_get_class_name (obj_p); - lit_utf8_byte_t *target_p = ecma_arraybuffer_get_buffer (arraybuffer_p) + byte_pos; - ecma_number_t value = ecma_get_typedarray_element (target_p, class_id); - - return ecma_make_number_value (value); -} /* ecma_op_typedarray_get_index_prop */ - /** * Define the integer number property value of the typedarray * @@ -842,57 +1101,32 @@ ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray ob if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) { - return ecma_op_typedarray_set_index_prop (obj_p, index, property_desc_p->value); + ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); + ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.typedarray_id); + + ecma_number_t num_var; + ecma_value_t error = ecma_get_number (property_desc_p->value, &num_var); + + if (ECMA_IS_VALUE_ERROR (error)) + { + ecma_free_value (JERRY_CONTEXT (error_value)); + return false; + } + + if (index >= info.typedarray_length) + { + return false; + } + + ecma_length_t byte_pos = (index << info.shift) + info.offset; + lit_utf8_byte_t *src_buffer = ecma_arraybuffer_get_buffer (info.typedarray_buffer_p) + byte_pos; + setter_cb (src_buffer, num_var); + } return true; } /* ecma_op_typedarray_define_index_prop */ -/** - * Set the integer number property value of the typedarray - * - * See also: ES2015 9.4.5.9 - * - * @return boolean, false if failed - */ -bool -ecma_op_typedarray_set_index_prop (ecma_object_t *obj_p, /**< a TypedArray object */ - uint32_t index, /**< the index number */ - ecma_value_t value) /**< value of the property */ -{ - JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p))); - - ecma_length_t array_length = ecma_typedarray_get_length (obj_p); - - if (index >= array_length) - { - return false; - } - - ecma_value_t error = ECMA_VALUE_EMPTY; - - ECMA_OP_TO_NUMBER_TRY_CATCH (value_num, value, error); - - ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (obj_p); - ecma_length_t offset = ecma_typedarray_get_offset (obj_p); - uint8_t shift = ecma_typedarray_get_element_size_shift (obj_p); - ecma_length_t byte_pos = (index << shift) + offset; - lit_magic_string_id_t class_id = ecma_object_get_class_name (obj_p); - lit_utf8_byte_t *target_p = ecma_arraybuffer_get_buffer (arraybuffer_p) + byte_pos; - ecma_set_typedarray_element (target_p, value_num, class_id); - - ECMA_OP_TO_NUMBER_FINALIZE (value_num); - - if (ECMA_IS_VALUE_ERROR (error)) - { - ecma_free_value (JERRY_CONTEXT (error_value)); - return false; - } - - JERRY_ASSERT (ecma_is_value_empty (error)); - return true; -} /* ecma_op_typedarray_set_index_prop */ - /** * Create a typedarray object based on the "type" and arraylength * The "type" is same with arg1 @@ -906,75 +1140,6 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed { JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p))); - ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; - lit_magic_string_id_t class_id = (lit_magic_string_id_t) ext_object_p->u.pseudo_array.u1.class_id; - ecma_object_t *proto_p; - uint8_t element_size_shift = 0; - - switch (class_id) - { - case LIT_MAGIC_STRING_INT8_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE); - element_size_shift = 0; - break; - } - case LIT_MAGIC_STRING_UINT8_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE); - element_size_shift = 0; - break; - } - case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE); - element_size_shift = 0; - break; - } - case LIT_MAGIC_STRING_INT16_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE); - element_size_shift = 1; - break; - } - case LIT_MAGIC_STRING_UINT16_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE); - element_size_shift = 1; - break; - } - case LIT_MAGIC_STRING_INT32_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE); - element_size_shift = 2; - break; - } - case LIT_MAGIC_STRING_UINT32_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE); - element_size_shift = 2; - break; - } - case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE); - element_size_shift = 2; - break; - } -#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) - case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL: - { - proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE); - element_size_shift = 3; - break; - } -#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ - default: - { - JERRY_UNREACHABLE (); - } - } - #if ENABLED (JERRY_ES2015_CLASS) ecma_value_t constructor_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_CONSTRUCTOR); @@ -998,10 +1163,14 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed } #endif /* ENABLED (JERRY_ES2015_CLASS) */ + ecma_typedarray_type_t typedarray_id = ecma_get_typedarray_id (obj_p); + ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id)); + uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (typedarray_id); + ecma_value_t new_obj = ecma_typedarray_create_object_with_length (array_length, proto_p, element_size_shift, - class_id); + typedarray_id); #if ENABLED (JERRY_ES2015_CLASS) ecma_object_t *constructor_prototype_object_p = ecma_get_object_from_value (constructor_prototype); @@ -1014,6 +1183,25 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed return new_obj; } /* ecma_op_create_typedarray_with_type_and_length */ +/** + * Method for getting the additional typedArray informations. + */ +ecma_typedarray_info_t +ecma_typedarray_get_info (ecma_object_t *typedarray_p) +{ + ecma_typedarray_info_t info; + + info.typedarray_buffer_p = ecma_typedarray_get_arraybuffer (typedarray_p); + info.buffer_p = ecma_typedarray_get_buffer (typedarray_p); + info.typedarray_id = ecma_get_typedarray_id (typedarray_p); + info.typedarray_length = ecma_typedarray_get_length (typedarray_p); + info.offset = ecma_typedarray_get_offset (typedarray_p); + info.shift = ecma_typedarray_get_element_size_shift (typedarray_p); + info.element_size = (uint8_t) (1 << info.shift); + + return info; +} /* ecma_typedarray_get_info */ + /** * @} * @} diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index 8c7612f04..3171891a0 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -17,6 +17,7 @@ #define ECMA_TYPEDARRAY_OBJECT_H #include "ecma-globals.h" +#include "ecma-builtins.h" #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) @@ -27,12 +28,25 @@ * @{ */ +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); +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); +ecma_typedarray_type_t ecma_typedarray_helper_builtin_to_typedarray_id (ecma_builtin_id_t builtin_id); + ecma_value_t ecma_op_typedarray_from (ecma_value_t items_val, ecma_value_t map_fn_val, ecma_value_t this_val, ecma_object_t *proto_p, uint8_t element_size_shift, - lit_magic_string_id_t class_id); + ecma_typedarray_type_t typedarray_id); ecma_length_t ecma_typedarray_get_length (ecma_object_t *typedarray_p); ecma_length_t ecma_typedarray_get_offset (ecma_object_t *typedarray_p); lit_utf8_byte_t *ecma_typedarray_get_buffer (ecma_object_t *typedarray_p); @@ -42,26 +56,20 @@ ecma_value_t ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len, ecma_object_t *proto_p, uint8_t element_size_shift, - lit_magic_string_id_t class_id); + ecma_typedarray_type_t typedarray_id); bool ecma_is_typedarray (ecma_value_t target); -void ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, - ecma_number_t value, - lit_magic_string_id_t class_id); -ecma_number_t ecma_get_typedarray_element (lit_utf8_byte_t *src, - lit_magic_string_id_t class_id); void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, ecma_collection_t *main_collection_p); -ecma_value_t ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, uint32_t index); bool ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, uint32_t index, const ecma_property_descriptor_t *property_desc_p); -bool ecma_op_typedarray_set_index_prop (ecma_object_t *obj_p, uint32_t index, ecma_value_t value); ecma_value_t ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, ecma_length_t array_length); +ecma_typedarray_info_t ecma_typedarray_get_info (ecma_object_t *typedarray_p); ecma_value_t ecma_typedarray_create_object_with_length (ecma_length_t array_length, ecma_object_t *proto_p, uint8_t element_size_shift, - lit_magic_string_id_t class_id); + ecma_typedarray_type_t typedarray_id); /** * @}