mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implement typedarary.set(array, offset)
JerryScript-DCO-1.0-Signed-off-by: Sanggyu Lee sg5.lee@samsung.com
This commit is contained in:
parent
a48f24f8da
commit
af16a3ae1a
@ -647,6 +647,116 @@ ecma_builtin_typedarray_prototype_reverse (ecma_value_t this_arg) /**< this argu
|
||||
return ecma_copy_value (this_arg);
|
||||
} /* ecma_builtin_typedarray_prototype_reverse */
|
||||
|
||||
/**
|
||||
* The %TypedArray%.prototype object's 'set' routine
|
||||
*
|
||||
* See also:
|
||||
* ES2015, 22.2.3.22, 22.2.3.22.1
|
||||
*
|
||||
* @return ecma value of undefined.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arr_val, /**< array object */
|
||||
ecma_value_t offset_val) /**< offset value */
|
||||
{
|
||||
/* 1. */
|
||||
if (ecma_is_typedarray (arr_val))
|
||||
{
|
||||
/* 22.2.3.22.2 %TypedArray%.prototype(typedArray [, offset ]) is not supported */
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray.set(typedArray [,offset]) is not supported."));
|
||||
}
|
||||
|
||||
/* 2.~ 4. */
|
||||
if (!ecma_is_typedarray (this_arg))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
|
||||
}
|
||||
|
||||
/* 6.~ 8. targetOffset */
|
||||
ecma_value_t ret_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (target_offset_num, offset_val, ret_val);
|
||||
if (ecma_number_is_nan (target_offset_num))
|
||||
{
|
||||
target_offset_num = 0;
|
||||
}
|
||||
if (target_offset_num <= -1.0 || target_offset_num >= (double) UINT32_MAX + 0.5)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset"));
|
||||
}
|
||||
uint32_t target_offset_uint32 = ecma_number_to_uint32 (target_offset_num);
|
||||
|
||||
/* 11. targetLength */
|
||||
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);
|
||||
|
||||
/* 16.~ 17. */
|
||||
ECMA_TRY_CATCH (source_obj, ecma_op_to_object (arr_val), ret_val);
|
||||
|
||||
/* 18.~ 19. */
|
||||
ecma_string_t length_str;
|
||||
ecma_init_ecma_length_string (&length_str);
|
||||
ecma_object_t *source_obj_p = ecma_get_object_from_value (source_obj);
|
||||
ECMA_TRY_CATCH (source_length,
|
||||
ecma_op_object_get (source_obj_p, &length_str),
|
||||
ret_val);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (source_length_num, source_length, ret_val);
|
||||
if (ecma_number_is_nan (source_length_num) || source_length_num <= 0)
|
||||
{
|
||||
source_length_num = 0;
|
||||
}
|
||||
uint32_t source_length_uint32 = ecma_number_to_uint32 (source_length_num);
|
||||
if ((ecma_number_t) source_length_uint32 != source_length_num)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid source length"));
|
||||
}
|
||||
|
||||
/* 20. if srcLength + targetOffset > targetLength, throw a RangeError */
|
||||
if ((int64_t) source_length_uint32 + target_offset_uint32 > target_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 k = 0;
|
||||
while (k < source_length_uint32 && ecma_is_value_empty (ret_val))
|
||||
{
|
||||
ecma_string_t k_str;
|
||||
ecma_init_ecma_string_from_uint32 (&k_str, k);
|
||||
ECMA_TRY_CATCH (elem,
|
||||
ecma_op_object_get (source_obj_p, &k_str),
|
||||
ret_val);
|
||||
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);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (elem_num);
|
||||
ECMA_FINALIZE (elem);
|
||||
k++;
|
||||
target_byte_index += element_size;
|
||||
}
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (source_length_num);
|
||||
ECMA_FINALIZE (source_length);
|
||||
ECMA_FINALIZE (source_obj);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (target_offset_num);
|
||||
|
||||
if (ecma_is_value_empty (ret_val))
|
||||
{
|
||||
ret_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
return ret_val;
|
||||
} /* ecma_builtin_typedarray_prototype_set */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -53,6 +53,7 @@ ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_typedarray_prototype_reduce, 2, 1
|
||||
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_typedarray_prototype_reduce_right, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_typedarray_prototype_filter, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_REVERSE, ecma_builtin_typedarray_prototype_reverse, 0, 0)
|
||||
ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_typedarray_prototype_set, 2, 1)
|
||||
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
|
||||
|
||||
@ -49,9 +49,9 @@
|
||||
*
|
||||
* @return ecma_number_t: the value of the element
|
||||
*/
|
||||
static ecma_number_t
|
||||
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 */
|
||||
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 */
|
||||
{
|
||||
switch (class_id)
|
||||
{
|
||||
@ -96,17 +96,17 @@ get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} /* get_typedarray_element */
|
||||
} /* ecma_get_typedarray_element */
|
||||
|
||||
#undef GET_ELEMENT
|
||||
|
||||
/**
|
||||
* set typedarray's element value
|
||||
*/
|
||||
static void
|
||||
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 */
|
||||
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 */
|
||||
{
|
||||
switch (class_id)
|
||||
{
|
||||
@ -215,7 +215,7 @@ set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the interna
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
} /* set_typedarray_element */
|
||||
} /* ecma_set_typedarray_element */
|
||||
|
||||
/**
|
||||
* Create a TypedArray object by given array_length
|
||||
@ -352,8 +352,8 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
|
||||
for (uint32_t i = 0; i < array_length; i++)
|
||||
{
|
||||
/* Convert values from source to destination format. */
|
||||
ecma_number_t tmp = get_typedarray_element (src_buf_p, src_class_id);
|
||||
set_typedarray_element (dst_buf_p, tmp, class_id);
|
||||
ecma_number_t tmp = ecma_get_typedarray_element (src_buf_p, src_class_id);
|
||||
ecma_set_typedarray_element (dst_buf_p, tmp, class_id);
|
||||
|
||||
src_buf_p += src_element_size;
|
||||
dst_buf_p += dst_element_size;
|
||||
@ -486,7 +486,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
|
||||
} /* ecma_op_typedarray_from */
|
||||
|
||||
/**
|
||||
* Get the array length of the typedarray object
|
||||
* Get the arraybuffer of the typedarray object
|
||||
*
|
||||
* @return the pointer to the internal arraybuffer
|
||||
*/
|
||||
@ -810,7 +810,7 @@ ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, /**< a TypedArray objec
|
||||
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 = get_typedarray_element (target_p, class_id);
|
||||
ecma_number_t value = ecma_get_typedarray_element (target_p, class_id);
|
||||
|
||||
return ecma_make_number_value (value);
|
||||
} /* ecma_op_typedarray_get_index_prop */
|
||||
@ -889,7 +889,7 @@ ecma_op_typedarray_set_index_prop (ecma_object_t *obj_p, /**< a TypedArray objec
|
||||
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;
|
||||
set_typedarray_element (target_p, value_num, class_id);
|
||||
ecma_set_typedarray_element (target_p, value_num, class_id);
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (value_num);
|
||||
|
||||
|
||||
@ -43,6 +43,11 @@ ecma_value_t ecma_op_create_typedarray (const ecma_value_t *arguments_list_p,
|
||||
uint8_t element_size_shift,
|
||||
lit_magic_string_id_t class_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_header_t *main_collection_p);
|
||||
ecma_value_t ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, uint32_t index);
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var uint8 = new Uint8Array(4);
|
||||
|
||||
// 22.2.3.22
|
||||
assert(uint8.set.length === 1)
|
||||
|
||||
try
|
||||
{
|
||||
uint8.set([1], -1);
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint8.set([1], - (Math.pow(2, 32) + 1));
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint8.set([1], -Infinity);
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint8.set([1], Infinity);
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
uint8.set([1], (Math.pow(2, 32) + 1));
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 22.2.3.22.1 step 20
|
||||
uint8.set([17, 18, 19], 2);
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError)
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var uint8 = new Uint8Array(4);
|
||||
|
||||
uint8.set([10, "11", 12]);
|
||||
assert(uint8[0] === 10 && uint8[1] === 11 && uint8[2] === 12);
|
||||
|
||||
uint8.set([13, 14.3, 15], 1);
|
||||
assert(uint8[0] === 10 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([16], NaN);
|
||||
assert(uint8[0] === 16 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([17], "");
|
||||
assert(uint8[0] === 17 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([18], "0");
|
||||
assert(uint8[0] === 18 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([19], false);
|
||||
assert(uint8[0] === 19 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([20], 0.2);
|
||||
assert(uint8[0] === 20 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([21], 0.9);
|
||||
assert(uint8[0] === 21 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([22], null);
|
||||
assert(uint8[0] === 22 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([23], {});
|
||||
assert(uint8[0] === 23 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([24], []);
|
||||
assert(uint8[0] === 24 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
uint8.set([25], true);
|
||||
assert(uint8[0] === 24 && uint8[1] === 25 && uint8[2] === 14 && uint8[3] === 15);
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var float64 = new Float64Array(4);
|
||||
float64.set([10.1, "11.2", 12.3]);
|
||||
assert(float64[0] === 10.1 && float64[1] === 11.2 && float64[2] === 12.3);
|
||||
|
||||
float64.set([13.1, 14.2, 15.3], 1);
|
||||
assert(float64[0] === 10.1 && float64[1] === 13.1 && float64[2] === 14.2 && float64[3] === 15.3);
|
||||
|
||||
try
|
||||
{
|
||||
// 22.2.3.22.1 step 20
|
||||
float64.set([17.1, 18.2, 19.3], 2);
|
||||
assert(false);
|
||||
} catch (e)
|
||||
{
|
||||
assert(e instanceof RangeError)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user