Skip to content

Commit af16a3a

Browse files
Sanggyu Leeyichoi
authored andcommitted
Implement typedarary.set(array, offset)
JerryScript-DCO-1.0-Signed-off-by: Sanggyu Lee sg5.lee@samsung.com
1 parent a48f24f commit af16a3a

File tree

7 files changed

+288
-14
lines changed

7 files changed

+288
-14
lines changed

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,116 @@ ecma_builtin_typedarray_prototype_reverse (ecma_value_t this_arg) /**< this argu
647647
return ecma_copy_value (this_arg);
648648
} /* ecma_builtin_typedarray_prototype_reverse */
649649

650+
/**
651+
* The %TypedArray%.prototype object's 'set' routine
652+
*
653+
* See also:
654+
* ES2015, 22.2.3.22, 22.2.3.22.1
655+
*
656+
* @return ecma value of undefined.
657+
*/
658+
ecma_value_t
659+
ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument */
660+
ecma_value_t arr_val, /**< array object */
661+
ecma_value_t offset_val) /**< offset value */
662+
{
663+
/* 1. */
664+
if (ecma_is_typedarray (arr_val))
665+
{
666+
/* 22.2.3.22.2 %TypedArray%.prototype(typedArray [, offset ]) is not supported */
667+
return ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray.set(typedArray [,offset]) is not supported."));
668+
}
669+
670+
/* 2.~ 4. */
671+
if (!ecma_is_typedarray (this_arg))
672+
{
673+
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
674+
}
675+
676+
/* 6.~ 8. targetOffset */
677+
ecma_value_t ret_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
678+
ECMA_OP_TO_NUMBER_TRY_CATCH (target_offset_num, offset_val, ret_val);
679+
if (ecma_number_is_nan (target_offset_num))
680+
{
681+
target_offset_num = 0;
682+
}
683+
if (target_offset_num <= -1.0 || target_offset_num >= (double) UINT32_MAX + 0.5)
684+
{
685+
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset"));
686+
}
687+
uint32_t target_offset_uint32 = ecma_number_to_uint32 (target_offset_num);
688+
689+
/* 11. targetLength */
690+
ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg);
691+
ecma_length_t target_length = ecma_typedarray_get_length (typedarray_p);
692+
693+
/* 13. targetElementSize */
694+
uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p);
695+
uint8_t element_size = (uint8_t) (1 << shift);
696+
697+
/* 14. targetType */
698+
lit_magic_string_id_t target_class_id = ecma_object_get_class_name (typedarray_p);
699+
700+
/* 9., 15. */
701+
lit_utf8_byte_t *target_buffer_p = ecma_typedarray_get_buffer (typedarray_p);
702+
703+
/* 16.~ 17. */
704+
ECMA_TRY_CATCH (source_obj, ecma_op_to_object (arr_val), ret_val);
705+
706+
/* 18.~ 19. */
707+
ecma_string_t length_str;
708+
ecma_init_ecma_length_string (&length_str);
709+
ecma_object_t *source_obj_p = ecma_get_object_from_value (source_obj);
710+
ECMA_TRY_CATCH (source_length,
711+
ecma_op_object_get (source_obj_p, &length_str),
712+
ret_val);
713+
ECMA_OP_TO_NUMBER_TRY_CATCH (source_length_num, source_length, ret_val);
714+
if (ecma_number_is_nan (source_length_num) || source_length_num <= 0)
715+
{
716+
source_length_num = 0;
717+
}
718+
uint32_t source_length_uint32 = ecma_number_to_uint32 (source_length_num);
719+
if ((ecma_number_t) source_length_uint32 != source_length_num)
720+
{
721+
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid source length"));
722+
}
723+
724+
/* 20. if srcLength + targetOffset > targetLength, throw a RangeError */
725+
if ((int64_t) source_length_uint32 + target_offset_uint32 > target_length)
726+
{
727+
ret_val = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index"));
728+
}
729+
730+
/* 21.~ 25. */
731+
uint32_t target_byte_index = target_offset_uint32 * element_size;
732+
uint32_t k = 0;
733+
while (k < source_length_uint32 && ecma_is_value_empty (ret_val))
734+
{
735+
ecma_string_t k_str;
736+
ecma_init_ecma_string_from_uint32 (&k_str, k);
737+
ECMA_TRY_CATCH (elem,
738+
ecma_op_object_get (source_obj_p, &k_str),
739+
ret_val);
740+
ECMA_OP_TO_NUMBER_TRY_CATCH (elem_num, elem, ret_val);
741+
ecma_set_typedarray_element (target_buffer_p + target_byte_index, elem_num, target_class_id);
742+
ECMA_OP_TO_NUMBER_FINALIZE (elem_num);
743+
ECMA_FINALIZE (elem);
744+
k++;
745+
target_byte_index += element_size;
746+
}
747+
748+
ECMA_OP_TO_NUMBER_FINALIZE (source_length_num);
749+
ECMA_FINALIZE (source_length);
750+
ECMA_FINALIZE (source_obj);
751+
ECMA_OP_TO_NUMBER_FINALIZE (target_offset_num);
752+
753+
if (ecma_is_value_empty (ret_val))
754+
{
755+
ret_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
756+
}
757+
return ret_val;
758+
} /* ecma_builtin_typedarray_prototype_set */
759+
650760
/**
651761
* @}
652762
* @}

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.inc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_typedarray_prototype_reduce, 2, 1
5353
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_typedarray_prototype_reduce_right, 2, 1)
5454
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_typedarray_prototype_filter, 2, 1)
5555
ROUTINE (LIT_MAGIC_STRING_REVERSE, ecma_builtin_typedarray_prototype_reverse, 0, 0)
56+
ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_typedarray_prototype_set, 2, 1)
5657

5758
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
5859

jerry-core/ecma/operations/ecma-typedarray-object.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
*
5050
* @return ecma_number_t: the value of the element
5151
*/
52-
static ecma_number_t
53-
get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal arraybuffer */
54-
lit_magic_string_id_t class_id) /**< class name of the typedarray */
52+
ecma_number_t
53+
ecma_get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal arraybuffer */
54+
lit_magic_string_id_t class_id) /**< class name of the typedarray */
5555
{
5656
switch (class_id)
5757
{
@@ -96,17 +96,17 @@ get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal
9696
return 0;
9797
}
9898
}
99-
} /* get_typedarray_element */
99+
} /* ecma_get_typedarray_element */
100100

101101
#undef GET_ELEMENT
102102

103103
/**
104104
* set typedarray's element value
105105
*/
106-
static void
107-
set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */
108-
ecma_number_t value, /**< the number value to set */
109-
lit_magic_string_id_t class_id) /**< class name of the typedarray */
106+
void
107+
ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */
108+
ecma_number_t value, /**< the number value to set */
109+
lit_magic_string_id_t class_id) /**< class name of the typedarray */
110110
{
111111
switch (class_id)
112112
{
@@ -215,7 +215,7 @@ set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the interna
215215
JERRY_UNREACHABLE ();
216216
}
217217
}
218-
} /* set_typedarray_element */
218+
} /* ecma_set_typedarray_element */
219219

220220
/**
221221
* Create a TypedArray object by given array_length
@@ -352,8 +352,8 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
352352
for (uint32_t i = 0; i < array_length; i++)
353353
{
354354
/* Convert values from source to destination format. */
355-
ecma_number_t tmp = get_typedarray_element (src_buf_p, src_class_id);
356-
set_typedarray_element (dst_buf_p, tmp, class_id);
355+
ecma_number_t tmp = ecma_get_typedarray_element (src_buf_p, src_class_id);
356+
ecma_set_typedarray_element (dst_buf_p, tmp, class_id);
357357

358358
src_buf_p += src_element_size;
359359
dst_buf_p += dst_element_size;
@@ -486,7 +486,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
486486
} /* ecma_op_typedarray_from */
487487

488488
/**
489-
* Get the array length of the typedarray object
489+
* Get the arraybuffer of the typedarray object
490490
*
491491
* @return the pointer to the internal arraybuffer
492492
*/
@@ -810,7 +810,7 @@ ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, /**< a TypedArray objec
810810
ecma_length_t byte_pos = (index << shift) + offset;
811811
lit_magic_string_id_t class_id = ecma_object_get_class_name (obj_p);
812812
lit_utf8_byte_t *target_p = ecma_arraybuffer_get_buffer (arraybuffer_p) + byte_pos;
813-
ecma_number_t value = get_typedarray_element (target_p, class_id);
813+
ecma_number_t value = ecma_get_typedarray_element (target_p, class_id);
814814

815815
return ecma_make_number_value (value);
816816
} /* ecma_op_typedarray_get_index_prop */
@@ -889,7 +889,7 @@ ecma_op_typedarray_set_index_prop (ecma_object_t *obj_p, /**< a TypedArray objec
889889
ecma_length_t byte_pos = (index << shift) + offset;
890890
lit_magic_string_id_t class_id = ecma_object_get_class_name (obj_p);
891891
lit_utf8_byte_t *target_p = ecma_arraybuffer_get_buffer (arraybuffer_p) + byte_pos;
892-
set_typedarray_element (target_p, value_num, class_id);
892+
ecma_set_typedarray_element (target_p, value_num, class_id);
893893

894894
ECMA_OP_TO_NUMBER_FINALIZE (value_num);
895895

jerry-core/ecma/operations/ecma-typedarray-object.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ ecma_value_t ecma_op_create_typedarray (const ecma_value_t *arguments_list_p,
4343
uint8_t element_size_shift,
4444
lit_magic_string_id_t class_id);
4545
bool ecma_is_typedarray (ecma_value_t target);
46+
void ecma_set_typedarray_element (lit_utf8_byte_t *dst_p,
47+
ecma_number_t value,
48+
lit_magic_string_id_t class_id);
49+
ecma_number_t ecma_get_typedarray_element (lit_utf8_byte_t *src,
50+
lit_magic_string_id_t class_id);
4651
void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p,
4752
ecma_collection_header_t *main_collection_p);
4853
ecma_value_t ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, uint32_t index);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/* Copyright JS Foundation and other contributors, http://js.foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
var uint8 = new Uint8Array(4);
17+
18+
// 22.2.3.22
19+
assert(uint8.set.length === 1)
20+
21+
try
22+
{
23+
uint8.set([1], -1);
24+
assert(false);
25+
} catch (e)
26+
{
27+
assert(e instanceof RangeError);
28+
}
29+
30+
try
31+
{
32+
uint8.set([1], - (Math.pow(2, 32) + 1));
33+
assert(false);
34+
} catch (e)
35+
{
36+
assert(e instanceof RangeError);
37+
}
38+
39+
try
40+
{
41+
uint8.set([1], -Infinity);
42+
assert(false);
43+
} catch (e)
44+
{
45+
assert(e instanceof RangeError);
46+
}
47+
48+
try
49+
{
50+
uint8.set([1], Infinity);
51+
assert(false);
52+
} catch (e)
53+
{
54+
assert(e instanceof RangeError);
55+
}
56+
57+
try
58+
{
59+
uint8.set([1], (Math.pow(2, 32) + 1));
60+
assert(false);
61+
} catch (e)
62+
{
63+
assert(e instanceof RangeError);
64+
}
65+
66+
try
67+
{
68+
// 22.2.3.22.1 step 20
69+
uint8.set([17, 18, 19], 2);
70+
assert(false);
71+
} catch (e)
72+
{
73+
assert(e instanceof RangeError)
74+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* Copyright JS Foundation and other contributors, http://js.foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
var uint8 = new Uint8Array(4);
17+
18+
uint8.set([10, "11", 12]);
19+
assert(uint8[0] === 10 && uint8[1] === 11 && uint8[2] === 12);
20+
21+
uint8.set([13, 14.3, 15], 1);
22+
assert(uint8[0] === 10 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
23+
24+
uint8.set([16], NaN);
25+
assert(uint8[0] === 16 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
26+
27+
uint8.set([17], "");
28+
assert(uint8[0] === 17 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
29+
30+
uint8.set([18], "0");
31+
assert(uint8[0] === 18 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
32+
33+
uint8.set([19], false);
34+
assert(uint8[0] === 19 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
35+
36+
uint8.set([20], 0.2);
37+
assert(uint8[0] === 20 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
38+
39+
uint8.set([21], 0.9);
40+
assert(uint8[0] === 21 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
41+
42+
uint8.set([22], null);
43+
assert(uint8[0] === 22 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
44+
45+
uint8.set([23], {});
46+
assert(uint8[0] === 23 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
47+
48+
uint8.set([24], []);
49+
assert(uint8[0] === 24 && uint8[1] === 13 && uint8[2] === 14 && uint8[3] === 15);
50+
51+
uint8.set([25], true);
52+
assert(uint8[0] === 24 && uint8[1] === 25 && uint8[2] === 14 && uint8[3] === 15);
53+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Copyright JS Foundation and other contributors, http://js.foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
var float64 = new Float64Array(4);
17+
float64.set([10.1, "11.2", 12.3]);
18+
assert(float64[0] === 10.1 && float64[1] === 11.2 && float64[2] === 12.3);
19+
20+
float64.set([13.1, 14.2, 15.3], 1);
21+
assert(float64[0] === 10.1 && float64[1] === 13.1 && float64[2] === 14.2 && float64[3] === 15.3);
22+
23+
try
24+
{
25+
// 22.2.3.22.1 step 20
26+
float64.set([17.1, 18.2, 19.3], 2);
27+
assert(false);
28+
} catch (e)
29+
{
30+
assert(e instanceof RangeError)
31+
}

0 commit comments

Comments
 (0)