Skip to content

Commit b06bd84

Browse files
Add %TypedArray%.prototype.subarray([ begin [, end ] ]) support.
JerryScript-DCO-1.0-Signed-off-by: Anthony Calandra [email protected]
1 parent ac9fce1 commit b06bd84

File tree

7 files changed

+182
-0
lines changed

7 files changed

+182
-0
lines changed

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "ecma-builtins.h"
2121
#include "ecma-gc.h"
22+
#include "ecma-objects.h"
2223
#include "ecma-typedarray-object.h"
2324

2425
#define ECMA_BUILTINS_INTERNAL
@@ -95,6 +96,41 @@ ecma_typedarray_helper_get_shift_size (uint8_t builtin_id) /**< the builtin id o
9596
}
9697
} /* ecma_typedarray_helper_get_shift_size */
9798

99+
/**
100+
* Get the built-in TypedArray type from a magic string.
101+
*
102+
* @return uint8_t
103+
*/
104+
uint8_t
105+
ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p) /**< typedarray object **/
106+
{
107+
#define TYPEDARRAY_ID_CASE(magic_id, builtin_id) \
108+
case magic_id: \
109+
{ \
110+
return builtin_id; \
111+
}
112+
113+
switch (ecma_object_get_class_name (obj_p))
114+
{
115+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT8_ARRAY_UL, ECMA_BUILTIN_ID_INT8ARRAY)
116+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_ARRAY_UL, ECMA_BUILTIN_ID_UINT8ARRAY)
117+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL, ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY)
118+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT16_ARRAY_UL, ECMA_BUILTIN_ID_INT16ARRAY)
119+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT16_ARRAY_UL, ECMA_BUILTIN_ID_UINT16ARRAY)
120+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT32_ARRAY_UL, ECMA_BUILTIN_ID_INT32ARRAY)
121+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT32_ARRAY_UL, ECMA_BUILTIN_ID_UINT32ARRAY)
122+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT32_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT32ARRAY)
123+
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
124+
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT64ARRAY)
125+
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
126+
default:
127+
{
128+
JERRY_UNREACHABLE ();
129+
}
130+
}
131+
#undef TYPEDARRAY_ID_CASE
132+
} /* ecma_typedarray_helper_get_builtin_id */
133+
98134
/**
99135
* Get the magic string of a TypedArray type.
100136
*

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
bool ecma_typedarray_helper_is_typedarray (uint8_t builtin_id);
3030
uint8_t ecma_typedarray_helper_get_shift_size (uint8_t builtin_id);
31+
uint8_t ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p);
3132
uint8_t ecma_typedarray_helper_get_magic_string (uint8_t builtin_id);
3233
uint8_t ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id);
3334

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
#include "ecma-builtin-helpers.h"
17+
#include "ecma-builtin-typedarray-helpers.h"
1718
#include "ecma-builtins.h"
1819
#include "ecma-exceptions.h"
1920
#include "ecma-globals.h"
@@ -988,6 +989,97 @@ ecma_builtin_typedarray_prototype_object_to_string (ecma_value_t this_arg) /**<
988989
return ret_value;
989990
} /* ecma_builtin_typedarray_prototype_object_to_string */
990991

992+
/**
993+
* The %TypedArray%.prototype object's 'subarray' routine.
994+
*
995+
* See also:
996+
* ES2015, 22.2.3.26
997+
*
998+
* @return ecma value
999+
* Returned value must be freed with ecma_free_value.
1000+
*/
1001+
static ecma_value_t
1002+
ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this argument */
1003+
ecma_value_t begin, /**< begin */
1004+
ecma_value_t end) /**< end */
1005+
{
1006+
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
1007+
1008+
/* 2.~ 4. */
1009+
if (!ecma_is_typedarray (this_arg))
1010+
{
1011+
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
1012+
}
1013+
1014+
ecma_object_t *src_typedarray_p = ecma_get_object_from_value (this_arg);
1015+
1016+
/* 5. buffer */
1017+
ecma_object_t *src_typedarray_arraybuffer_p = ecma_typedarray_get_arraybuffer (src_typedarray_p);
1018+
1019+
/* 6. srcLength */
1020+
ecma_length_t src_length = ecma_typedarray_get_length (src_typedarray_p);
1021+
1022+
/* 9. beginIndex, 12. endIndex */
1023+
uint32_t begin_index_uint32 = 0, end_index_uint32 = 0;
1024+
1025+
/* 7. relativeBegin */
1026+
ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value);
1027+
begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, src_length);
1028+
1029+
if (ecma_is_value_undefined (end))
1030+
{
1031+
end_index_uint32 = (uint32_t) src_length;
1032+
}
1033+
else
1034+
{
1035+
/* 10. relativeEnd */
1036+
ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value);
1037+
1038+
end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, src_length);
1039+
1040+
ECMA_OP_TO_NUMBER_FINALIZE (relative_end);
1041+
}
1042+
1043+
ECMA_OP_TO_NUMBER_FINALIZE (relative_begin);
1044+
1045+
if (!ecma_is_value_empty (ret_value))
1046+
{
1047+
return ret_value;
1048+
}
1049+
1050+
/* 13. newLength */
1051+
ecma_length_t subarray_length = 0;
1052+
1053+
if (end_index_uint32 > begin_index_uint32)
1054+
{
1055+
subarray_length = end_index_uint32 - begin_index_uint32;
1056+
}
1057+
1058+
/* 15. elementSize */
1059+
uint8_t shift = ecma_typedarray_get_element_size_shift (src_typedarray_p);
1060+
uint8_t element_size = (uint8_t) (1 << shift);
1061+
1062+
/* 16. srcByteOffset */
1063+
ecma_length_t src_byte_offset = ecma_typedarray_get_offset (src_typedarray_p);
1064+
1065+
/* 17. beginByteOffset */
1066+
ecma_length_t begin_byte_offset = src_byte_offset + begin_index_uint32 * element_size;
1067+
1068+
uint8_t src_builtin_id = ecma_typedarray_helper_get_builtin_id (src_typedarray_p);
1069+
ecma_value_t arguments_p[3] =
1070+
{
1071+
ecma_make_object_value (src_typedarray_arraybuffer_p),
1072+
ecma_make_uint32_value (begin_byte_offset),
1073+
ecma_make_uint32_value (subarray_length)
1074+
};
1075+
1076+
ret_value = ecma_typedarray_helper_dispatch_construct (arguments_p, 3, src_builtin_id);
1077+
1078+
ecma_free_value (arguments_p[1]);
1079+
ecma_free_value (arguments_p[2]);
1080+
return ret_value;
1081+
} /* ecma_builtin_typedarray_prototype_subarray */
1082+
9911083
/**
9921084
* @}
9931085
* @}

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
@@ -58,6 +58,7 @@ ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_typedarray_prototype_red
5858
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_typedarray_prototype_filter, 2, 1)
5959
ROUTINE (LIT_MAGIC_STRING_REVERSE, ecma_builtin_typedarray_prototype_reverse, 0, 0)
6060
ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_typedarray_prototype_set, 2, 1)
61+
ROUTINE (LIT_MAGIC_STRING_SUBARRAY, ecma_builtin_typedarray_prototype_subarray, 2, 2)
6162

6263
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
6364

jerry-core/lit/lit-magic-strings.inc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PARSE_INT, "parseInt")
334334
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_HOURS_UL, "setHours")
335335
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_MONTH_UL, "setMonth")
336336
#endif
337+
#if !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
338+
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SUBARRAY, "subarray")
339+
#endif
337340
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_STRING_UL, "toString")
338341
#if !defined (CONFIG_DISABLE_ANNEXB_BUILTIN)
339342
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNESCAPE, "unescape")

jerry-core/lit/lit-magic-strings.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ LIT_MAGIC_STRING_IS_SEALED_UL = "isSealed"
162162
LIT_MAGIC_STRING_PARSE_INT = "parseInt"
163163
LIT_MAGIC_STRING_SET_HOURS_UL = "setHours"
164164
LIT_MAGIC_STRING_SET_MONTH_UL = "setMonth"
165+
LIT_MAGIC_STRING_SUBARRAY = "subarray"
165166
LIT_MAGIC_STRING_TO_STRING_UL = "toString"
166167
LIT_MAGIC_STRING_UNESCAPE = "unescape"
167168
LIT_MAGIC_STRING_WRITABLE = "writable"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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 a = new Int32Array([1, 2, 3, 4, 5]);
17+
assert(a.subarray().toString() === '1,2,3,4,5');
18+
assert(a.subarray(3).toString() === '4,5');
19+
assert(a.subarray(1, 3).toString() === '2,3');
20+
assert(a.subarray(-3).toString() === '3,4,5');
21+
assert(a.subarray(-3, -1).toString() === '3,4');
22+
assert(a.subarray(3, 2).toString() === '');
23+
assert(a.subarray(-2, -3).toString() === '');
24+
assert(a.subarray(4, 1).toString() === '');
25+
assert(a.subarray(-1, -4).toString() === '');
26+
assert(a.subarray(1).subarray(1).toString() === '3,4,5');
27+
assert(a.subarray(1, 4).subarray(1, 2).toString() === '3');
28+
29+
var b = new Uint8Array([]);
30+
assert(b.subarray(123456, -123456).toString() === '');
31+
assert(b.subarray().subarray().toString() === '');
32+
33+
var ab = new ArrayBuffer(28);
34+
var tmp = new Int32Array(ab);
35+
tmp.set([0, 1, 2, 3, 4, 5, 0]);
36+
var c = new Int32Array(ab, 4, 5);
37+
assert(c.toString() === '1,2,3,4,5');
38+
assert(c.subarray().toString() === '1,2,3,4,5');
39+
assert(c.subarray(3).toString() === '4,5');
40+
assert(c.subarray(1, 3).toString() === '2,3');
41+
assert(c.subarray(-3).toString() === '3,4,5');
42+
assert(c.subarray(-3, -1).toString() === '3,4');
43+
assert(c.subarray(3, 2).toString() === '');
44+
assert(c.subarray(-2, -3).toString() === '');
45+
assert(c.subarray(4, 1).toString() === '');
46+
assert(c.subarray(-1, -4).toString() === '');
47+
assert(c.subarray(1).subarray(1).toString() === '3,4,5');
48+
assert(c.subarray(1, 4).subarray(1, 2).toString() === '3');

0 commit comments

Comments
 (0)