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 #include "jerryscript.h"
17 #include "jerryscript-port.h"
18 #include "jerryscript-port-default.h"
19 #include "test-common.h"
20
21 #include <stdio.h>
22
23 /**
24 * Type to describe test cases.
25 */
26 typedef struct
27 {
28 jerry_typedarray_type_t typedarray_type; /**< what kind of TypedArray */
29 char *constructor_name; /**< JS constructor name for TypedArray */
30 uint32_t element_count; /**< number of elements for the TypedArray */
31 uint32_t bytes_per_element; /**< bytes per elment of the given typedarray_type */
32 } test_entry_t;
33
34 /**
35 * Register a JavaScript value in the global object.
36 */
37 static void
register_js_value(const char * name_p,jerry_value_t value)38 register_js_value (const char *name_p, /**< name of the function */
39 jerry_value_t value) /**< function callback */
40 {
41 jerry_value_t global_obj_val = jerry_get_global_object ();
42
43 jerry_value_t name_val = jerry_create_string ((const jerry_char_t *) name_p);
44 jerry_value_t result_val = jerry_set_property (global_obj_val, name_val, value);
45
46 jerry_release_value (name_val);
47 jerry_release_value (global_obj_val);
48
49 jerry_release_value (result_val);
50 } /* register_js_value */
51
52 static jerry_value_t
assert_handler(const jerry_value_t func_obj_val,const jerry_value_t this_val,const jerry_value_t args_p[],const jerry_length_t args_cnt)53 assert_handler (const jerry_value_t func_obj_val, /**< function object */
54 const jerry_value_t this_val, /**< this arg */
55 const jerry_value_t args_p[], /**< function arguments */
56 const jerry_length_t args_cnt) /**< number of function arguments */
57 {
58 JERRY_UNUSED (func_obj_val);
59 JERRY_UNUSED (this_val);
60
61 if (jerry_value_is_boolean (args_p[0])
62 && jerry_get_boolean_value (args_p[0]))
63 {
64 return jerry_create_boolean (true);
65 }
66 else
67 {
68 if (args_cnt > 1
69 && jerry_value_is_string (args_p[1]))
70 {
71 jerry_length_t utf8_sz = jerry_get_string_size (args_p[1]);
72 JERRY_VLA (char, string_from_utf8, utf8_sz);
73 string_from_utf8[utf8_sz] = 0;
74
75 jerry_string_to_char_buffer (args_p[1], (jerry_char_t *) string_from_utf8, utf8_sz);
76
77 printf ("JS assert: %s\n", string_from_utf8);
78 }
79 TEST_ASSERT (false);
80 }
81 } /* assert_handler */
82
83 /**
84 * Do simple TypedArray property validation.
85 */
86 static void
test_typedarray_info(jerry_value_t typedarray,jerry_typedarray_type_t typedarray_type,jerry_length_t element_count,jerry_length_t bytes_per_element)87 test_typedarray_info (jerry_value_t typedarray, /**< target TypedArray to query */
88 jerry_typedarray_type_t typedarray_type, /**< expected TypedArray type */
89 jerry_length_t element_count, /**< expected element count */
90 jerry_length_t bytes_per_element) /**< bytes per element for the given type */
91 {
92 TEST_ASSERT (!jerry_value_is_error (typedarray));
93 TEST_ASSERT (jerry_value_is_typedarray (typedarray));
94 TEST_ASSERT (jerry_get_typedarray_type (typedarray) == typedarray_type);
95 TEST_ASSERT (jerry_get_typedarray_length (typedarray) == element_count);
96
97 jerry_length_t byte_length = (uint32_t) -1;
98 jerry_length_t byte_offset = (uint32_t) -1;
99 jerry_value_t arraybuffer = jerry_get_typedarray_buffer (typedarray, &byte_offset, &byte_length);
100 TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
101
102 TEST_ASSERT (byte_length == element_count * bytes_per_element);
103 TEST_ASSERT (byte_offset == 0);
104
105 jerry_release_value (arraybuffer);
106 } /* test_typedarray_info */
107
108 /**
109 * Test construction of TypedArrays and validate properties.
110 */
111 static void
test_typedarray_queries(test_entry_t test_entries[])112 test_typedarray_queries (test_entry_t test_entries[]) /**< test cases */
113 {
114 jerry_value_t global_obj_val = jerry_get_global_object ();
115
116 for (uint32_t i = 0; test_entries[i].constructor_name != NULL; i++)
117 {
118 /* Create TypedArray via construct call */
119 {
120 jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) test_entries[i].constructor_name);
121 jerry_value_t prop_value = jerry_get_property (global_obj_val, prop_name);
122 TEST_ASSERT (!jerry_value_is_error (prop_value));
123 jerry_value_t length_arg = jerry_create_number (test_entries[i].element_count);
124
125 jerry_value_t typedarray = jerry_construct_object (prop_value, &length_arg, 1);
126
127 jerry_release_value (prop_name);
128 jerry_release_value (prop_value);
129 jerry_release_value (length_arg);
130
131 test_typedarray_info (typedarray,
132 test_entries[i].typedarray_type,
133 test_entries[i].element_count,
134 test_entries[i].bytes_per_element);
135 jerry_release_value (typedarray);
136 }
137
138 /* Create TypedArray via api call */
139 {
140 jerry_value_t typedarray = jerry_create_typedarray (test_entries[i].typedarray_type,
141 test_entries[i].element_count);
142 test_typedarray_info (typedarray,
143 test_entries[i].typedarray_type,
144 test_entries[i].element_count,
145 test_entries[i].bytes_per_element);
146 jerry_release_value (typedarray);
147 }
148 }
149
150 jerry_release_value (global_obj_val);
151 } /* test_typedarray_queries */
152
153 /**
154 * Test value at given position in the buffer based on TypedArray type.
155 */
156 static
test_buffer_value(uint64_t value,const void * buffer,uint32_t start_offset,jerry_typedarray_type_t typedarray_type,uint32_t bytes_per_element)157 void test_buffer_value (uint64_t value, /**< value to test for */
158 const void *buffer, /**< buffer to read value from */
159 uint32_t start_offset, /**< start offset of the value */
160 jerry_typedarray_type_t typedarray_type, /**< type of TypedArray */
161 uint32_t bytes_per_element) /**< bytes per element for the given type */
162 {
163 uint32_t offset = start_offset / bytes_per_element;
164
165 #define TEST_VALUE_AT(TYPE, BUFFER, OFFSET, VALUE) TEST_ASSERT (((TYPE *) BUFFER)[OFFSET] == (TYPE) (VALUE))
166
167 switch (typedarray_type)
168 {
169 case JERRY_TYPEDARRAY_UINT8: TEST_VALUE_AT (uint8_t, buffer, offset, value); break;
170 case JERRY_TYPEDARRAY_INT8: TEST_VALUE_AT (int8_t, buffer, offset, value); break;
171 case JERRY_TYPEDARRAY_UINT16: TEST_VALUE_AT (uint16_t, buffer, offset, value); break;
172 case JERRY_TYPEDARRAY_INT16: TEST_VALUE_AT (int16_t, buffer, offset, value); break;
173 case JERRY_TYPEDARRAY_UINT32: TEST_VALUE_AT (uint32_t, buffer, offset, value); break;
174 case JERRY_TYPEDARRAY_INT32: TEST_VALUE_AT (int32_t, buffer, offset, value); break;
175 case JERRY_TYPEDARRAY_FLOAT32: TEST_VALUE_AT (float, buffer, offset, value); break;
176 case JERRY_TYPEDARRAY_FLOAT64: TEST_VALUE_AT (double, buffer, offset, value); break;
177
178 case JERRY_TYPEDARRAY_UINT8CLAMPED:
179 {
180 int64_t signed_value = (int64_t) value;
181 uint8_t expected = (uint8_t) value;
182
183 /* clamp the value if required*/
184 if (signed_value > 0xFF)
185 {
186 expected = 0xFF;
187 }
188 else if (signed_value < 0)
189 {
190 expected = 0;
191 }
192
193 TEST_VALUE_AT (uint8_t, buffer, offset, expected); break;
194 }
195 default: TEST_ASSERT (false); break;
196 }
197
198 #undef TEST_VALUE_AT
199 } /* test_buffer_value */
200
201 static void
test_typedarray_complex_creation(test_entry_t test_entries[],bool use_external_buffer)202 test_typedarray_complex_creation (test_entry_t test_entries[], /**< test cases */
203 bool use_external_buffer) /**< run tests using arraybuffer with external memory */
204 {
205 const uint32_t arraybuffer_size = 256;
206
207 JERRY_VLA (uint8_t, buffer_ext, arraybuffer_size);
208 memset (buffer_ext, 0, arraybuffer_size);
209
210 for (uint32_t i = 0; test_entries[i].constructor_name != NULL; i++)
211 {
212 const uint32_t offset = 8;
213 uint32_t element_count = test_entries[i].element_count;
214 uint32_t bytes_per_element = test_entries[i].bytes_per_element;
215
216 /* new %TypedArray% (buffer, offset, length); */
217 jerry_value_t typedarray;
218 {
219 jerry_value_t arraybuffer;
220
221 if (use_external_buffer)
222 {
223 arraybuffer = jerry_create_arraybuffer_external (arraybuffer_size, buffer_ext, NULL);
224 }
225 else
226 {
227 arraybuffer = jerry_create_arraybuffer (arraybuffer_size);
228 }
229
230 jerry_value_t js_offset = jerry_create_number (offset);
231 jerry_value_t js_element_count = jerry_create_number (element_count);
232
233 register_js_value ("expected_offset", js_offset);
234 register_js_value ("expected_length", js_element_count);
235
236 typedarray = jerry_create_typedarray_for_arraybuffer_sz (test_entries[i].typedarray_type,
237 arraybuffer,
238 offset,
239 element_count);
240 TEST_ASSERT (!jerry_value_is_error (typedarray));
241
242 jerry_release_value (js_offset);
243 jerry_release_value (js_element_count);
244 jerry_release_value (arraybuffer);
245 }
246
247 register_js_value ("array", typedarray);
248
249 const jerry_char_t eval_src[] = TEST_STRING_LITERAL (
250 "assert (array.length == expected_length,"
251 " 'expected length: ' + expected_length + ' got: ' + array.length);"
252 "assert (array.byteOffset == expected_offset);"
253 "array[0] = 0x11223344;"
254 );
255 jerry_value_t result = jerry_eval (eval_src,
256 sizeof (eval_src) - 1,
257 JERRY_PARSE_STRICT_MODE);
258 TEST_ASSERT (!jerry_value_is_error (result));
259 jerry_release_value (result);
260
261 {
262 jerry_length_t byte_length = 0;
263 jerry_length_t byte_offset = 0;
264 jerry_value_t buffer = jerry_get_typedarray_buffer (typedarray, &byte_offset, &byte_length);
265 TEST_ASSERT (byte_length == element_count * bytes_per_element);
266 TEST_ASSERT (byte_offset == offset);
267
268 JERRY_VLA (uint8_t, test_buffer, arraybuffer_size);
269
270 jerry_typedarray_type_t type = jerry_get_typedarray_type (typedarray);
271 jerry_value_t read_count = jerry_arraybuffer_read (buffer, 0, test_buffer, offset + byte_length);
272 TEST_ASSERT (read_count == offset + byte_length);
273 test_buffer_value (0x11223344, test_buffer, offset, type, bytes_per_element);
274
275 if (use_external_buffer)
276 {
277 test_buffer_value (0x11223344, buffer_ext, offset, type, bytes_per_element);
278 TEST_ASSERT (memcmp (buffer_ext, test_buffer, offset + byte_length) == 0);
279 }
280
281 jerry_release_value (buffer);
282 }
283
284 jerry_release_value (typedarray);
285 }
286 } /* test_typedarray_complex_creation */
287
288 /**
289 * Test get/set/delete property by index.
290 */
test_property_by_index(test_entry_t test_entries[])291 static void test_property_by_index (test_entry_t test_entries[])
292 {
293 int test_int_numbers[5] = {-5, -70, 13, 0, 56};
294 double test_double_numbers[5] = {-83.153, -35.15, 0, 13.1, 89.8975};
295 uint8_t test_uint_numbers[5] = {83, 15, 36, 0, 43};
296
297 for (uint32_t i = 0; test_entries[i].constructor_name != NULL; i++)
298 {
299 jerry_value_t test_number;
300 uint32_t test_numbers_length = sizeof (test_int_numbers) / sizeof (int);
301 jerry_value_t typedarray = jerry_create_typedarray (test_entries[i].typedarray_type, test_numbers_length);
302 jerry_typedarray_type_t type = jerry_get_typedarray_type (typedarray);
303
304 jerry_value_t set_result;
305 jerry_value_t get_result;
306
307 switch (type)
308 {
309 case JERRY_TYPEDARRAY_INT8:
310 case JERRY_TYPEDARRAY_INT16:
311 case JERRY_TYPEDARRAY_INT32:
312 {
313 for (uint8_t j = 0; j < test_numbers_length; j++)
314 {
315 test_number = jerry_create_number (test_int_numbers[j]);
316 TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
317 set_result = jerry_set_property_by_index (typedarray, j, test_number);
318 get_result = jerry_get_property_by_index (typedarray, j);
319
320 TEST_ASSERT (jerry_value_is_boolean (set_result));
321 TEST_ASSERT (jerry_get_boolean_value (set_result));
322 TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
323 TEST_ASSERT (jerry_get_number_value (get_result) == test_int_numbers[j]);
324
325 jerry_release_value (test_number);
326 jerry_release_value (set_result);
327 jerry_release_value (get_result);
328 }
329 break;
330 }
331 case JERRY_TYPEDARRAY_FLOAT32:
332 case JERRY_TYPEDARRAY_FLOAT64:
333 {
334 for (uint8_t j = 0; j < test_numbers_length; j++)
335 {
336 test_number = jerry_create_number (test_double_numbers[j]);
337 TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
338 set_result = jerry_set_property_by_index (typedarray, j, test_number);
339 get_result = jerry_get_property_by_index (typedarray, j);
340
341 TEST_ASSERT (jerry_value_is_boolean (set_result));
342 TEST_ASSERT (jerry_get_boolean_value (set_result));
343 TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
344
345 double epsilon = pow (10, -5);
346 double get_abs = fabs (jerry_get_number_value (get_result) - test_double_numbers[j]);
347 TEST_ASSERT (get_abs < epsilon);
348
349 jerry_release_value (test_number);
350 jerry_release_value (set_result);
351 jerry_release_value (get_result);
352
353 /* Testing positive and negative infinity */
354 for (uint8_t k = 0; k < 2; k++)
355 {
356 jerry_value_t inf = jerry_create_number_infinity (k);
357 jerry_value_t set_inf = jerry_set_property_by_index (typedarray, 0, inf);
358 TEST_ASSERT (jerry_value_is_boolean (set_inf));
359 TEST_ASSERT (jerry_get_boolean_value (set_inf));
360 jerry_value_t get_inf = jerry_get_property_by_index (typedarray, 0);
361 TEST_ASSERT (isinf (jerry_get_number_value (get_inf)));
362
363 jerry_release_value (inf);
364 jerry_release_value (set_inf);
365 jerry_release_value (get_inf);
366 }
367 }
368 break;
369 }
370 default:
371 {
372 for (uint8_t j = 0; j < test_numbers_length; j++)
373 {
374 test_number = jerry_create_number (test_uint_numbers[j]);
375 TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
376 set_result = jerry_set_property_by_index (typedarray, j, test_number);
377 get_result = jerry_get_property_by_index (typedarray, j);
378
379 TEST_ASSERT (jerry_value_is_boolean (set_result));
380 TEST_ASSERT (jerry_get_boolean_value (set_result));
381 TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
382 TEST_ASSERT (jerry_get_number_value (get_result) == test_uint_numbers[j]);
383
384 jerry_release_value (test_number);
385 jerry_release_value (set_result);
386 jerry_release_value (get_result);
387 }
388 break;
389 }
390 }
391
392 jerry_value_t set_undefined = jerry_set_property_by_index (typedarray, 100, jerry_create_number (50));
393 TEST_ASSERT (jerry_value_is_error (set_undefined));
394 jerry_value_t get_undefined = jerry_get_property_by_index (typedarray, 100);
395 TEST_ASSERT (jerry_value_is_undefined (get_undefined));
396
397 jerry_release_value (set_undefined);
398 jerry_release_value (get_undefined);
399 jerry_release_value (typedarray);
400 }
401 } /* test_property_by_index */
402
403 static void
test_detached_arraybuffer(void)404 test_detached_arraybuffer (void)
405 {
406 static jerry_typedarray_type_t types[] =
407 {
408 JERRY_TYPEDARRAY_UINT8,
409 JERRY_TYPEDARRAY_UINT8CLAMPED,
410 JERRY_TYPEDARRAY_INT8,
411 JERRY_TYPEDARRAY_UINT16,
412 JERRY_TYPEDARRAY_INT16,
413 JERRY_TYPEDARRAY_UINT32,
414 JERRY_TYPEDARRAY_INT32,
415 JERRY_TYPEDARRAY_FLOAT32,
416 JERRY_TYPEDARRAY_FLOAT64,
417 };
418
419 /* Creating an TypedArray for a detached array buffer with a given length/offset is invalid */
420 {
421 uint8_t buf[1];
422 const uint32_t length = 1;
423 jerry_value_t arraybuffer = jerry_create_arraybuffer_external (length, buf, NULL);
424 TEST_ASSERT (!jerry_value_is_error (arraybuffer));
425 TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
426 TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == length);
427
428 jerry_value_t is_detachable = jerry_is_arraybuffer_detachable (arraybuffer);
429 TEST_ASSERT (!jerry_value_is_error (is_detachable));
430 TEST_ASSERT (jerry_get_boolean_value (is_detachable));
431 jerry_release_value (is_detachable);
432
433 jerry_value_t res = jerry_detach_arraybuffer (arraybuffer);
434 TEST_ASSERT (!jerry_value_is_error (res));
435 jerry_release_value (res);
436
437 for (size_t idx = 0; idx < (sizeof (types) / sizeof (types[0])); idx++)
438 {
439 jerry_value_t typedarray = jerry_create_typedarray_for_arraybuffer_sz (types[idx], arraybuffer, 0, 4);
440 TEST_ASSERT (jerry_value_is_error (typedarray));
441 TEST_ASSERT (jerry_get_error_type (typedarray) == JERRY_ERROR_TYPE);
442 jerry_release_value (typedarray);
443 }
444
445 jerry_release_value (arraybuffer);
446 }
447
448 /* Creating an TypedArray for a detached array buffer without length/offset is valid */
449 {
450 uint8_t buf[1];
451 const uint32_t length = 1;
452 jerry_value_t arraybuffer = jerry_create_arraybuffer_external (length, buf, NULL);
453 TEST_ASSERT (!jerry_value_is_error (arraybuffer));
454 TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
455 TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == length);
456
457 jerry_value_t is_detachable = jerry_is_arraybuffer_detachable (arraybuffer);
458 TEST_ASSERT (!jerry_value_is_error (is_detachable));
459 TEST_ASSERT (jerry_get_boolean_value (is_detachable));
460 jerry_release_value (is_detachable);
461
462 jerry_value_t res = jerry_detach_arraybuffer (arraybuffer);
463 TEST_ASSERT (!jerry_value_is_error (res));
464 jerry_release_value (res);
465
466 for (size_t idx = 0; idx < (sizeof (types) / sizeof (types[0])); idx++)
467 {
468 jerry_value_t typedarray = jerry_create_typedarray_for_arraybuffer (types[idx], arraybuffer);
469 TEST_ASSERT (jerry_value_is_error (typedarray));
470 TEST_ASSERT (jerry_get_error_type (typedarray) == JERRY_ERROR_TYPE);
471 jerry_release_value (typedarray);
472 }
473
474 jerry_release_value (arraybuffer);
475 }
476 } /* test_detached_arraybuffer */
477
478 int
main(void)479 main (void)
480 {
481 jerry_init (JERRY_INIT_EMPTY);
482
483 if (!jerry_is_feature_enabled (JERRY_FEATURE_TYPEDARRAY))
484 {
485 jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TypedArray is disabled!\n");
486 jerry_cleanup ();
487 return 0;
488 }
489
490 jerry_value_t function_val = jerry_create_external_function (assert_handler);
491 register_js_value ("assert", function_val);
492 jerry_release_value (function_val);
493
494 test_entry_t test_entries[] =
495 {
496 #define TEST_ENTRY(TYPE, CONSTRUCTOR, COUNT, BYTES_PER_ELEMENT) \
497 { TYPE, CONSTRUCTOR, COUNT, BYTES_PER_ELEMENT }
498
499 TEST_ENTRY (JERRY_TYPEDARRAY_UINT8, "Uint8Array", 12, 1),
500 TEST_ENTRY (JERRY_TYPEDARRAY_UINT8CLAMPED, "Uint8ClampedArray", 12, 1),
501 TEST_ENTRY (JERRY_TYPEDARRAY_INT8, "Int8Array", 12, 1),
502 TEST_ENTRY (JERRY_TYPEDARRAY_UINT16, "Uint16Array", 12, 2),
503 TEST_ENTRY (JERRY_TYPEDARRAY_INT16, "Int16Array", 12, 2),
504 TEST_ENTRY (JERRY_TYPEDARRAY_UINT16, "Uint16Array", 12, 2),
505 TEST_ENTRY (JERRY_TYPEDARRAY_INT32, "Int32Array", 12, 4),
506 TEST_ENTRY (JERRY_TYPEDARRAY_UINT32, "Uint32Array", 12, 4),
507 TEST_ENTRY (JERRY_TYPEDARRAY_FLOAT32, "Float32Array", 12, 4),
508 /* TODO: add check if the float64 is supported */
509 TEST_ENTRY (JERRY_TYPEDARRAY_FLOAT64, "Float64Array", 12, 8),
510
511 TEST_ENTRY (JERRY_TYPEDARRAY_INVALID, NULL, 0, 0)
512 #undef TEST_ENTRY
513 };
514
515 /* Test TypedArray queries */
516 test_typedarray_queries (test_entries);
517
518 /* Test TypedArray operations in js */
519 {
520 const uint32_t element_count = 14;
521
522 jerry_value_t array = jerry_create_typedarray (JERRY_TYPEDARRAY_UINT8, element_count);
523
524 {
525 uint8_t expected_value = 42;
526 JERRY_VLA (uint8_t, expected_data, element_count);
527 memset (expected_data, expected_value, element_count);
528
529 jerry_length_t byte_length;
530 jerry_length_t offset;
531 jerry_value_t buffer = jerry_get_typedarray_buffer (array, &offset, &byte_length);
532 TEST_ASSERT (byte_length == element_count);
533 jerry_length_t written = jerry_arraybuffer_write (buffer, offset, expected_data, element_count);
534 TEST_ASSERT (written == element_count);
535 jerry_release_value (buffer);
536
537 jerry_value_t js_element_count = jerry_create_number (element_count);
538 jerry_value_t js_expected_value = jerry_create_number (expected_value);
539
540 register_js_value ("array", array);
541 register_js_value ("expected_length", js_element_count);
542 register_js_value ("expected_value", js_expected_value);
543
544 jerry_release_value (js_element_count);
545 jerry_release_value (js_expected_value);
546 }
547
548 /* Check read and to write */
549 const jerry_char_t eval_src[] = TEST_STRING_LITERAL (
550 "assert (array.length == expected_length, 'expected length: ' + expected_length + ' got: ' + array.length);"
551 "for (var i = 0; i < array.length; i++)"
552 "{"
553 " assert (array[i] == expected_value);"
554 " array[i] = i;"
555 "};"
556 );
557 jerry_value_t result = jerry_eval (eval_src,
558 sizeof (eval_src) - 1,
559 JERRY_PARSE_STRICT_MODE);
560
561 TEST_ASSERT (!jerry_value_is_error (result));
562 jerry_release_value (result);
563
564 /* Check write results */
565 {
566 jerry_length_t byte_length;
567 jerry_length_t offset;
568 jerry_value_t buffer = jerry_get_typedarray_buffer (array, &offset, &byte_length);
569 TEST_ASSERT (byte_length == element_count);
570
571 JERRY_VLA (uint8_t, result_data, element_count);
572
573 jerry_length_t read_count = jerry_arraybuffer_read (buffer, offset, result_data, byte_length);
574 TEST_ASSERT (read_count == byte_length);
575
576 for (uint8_t i = 0; i < read_count; i++)
577 {
578 TEST_ASSERT (result_data[i] == i);
579 }
580
581 jerry_release_value (buffer);
582 }
583
584 jerry_release_value (array);
585 }
586
587 test_typedarray_complex_creation (test_entries, false);
588 test_typedarray_complex_creation (test_entries, true);
589
590 test_property_by_index (test_entries);
591
592 /* test invalid things */
593 {
594 jerry_value_t values[] =
595 {
596 jerry_create_number (11),
597 jerry_create_boolean (false),
598 jerry_create_string ((const jerry_char_t *) "test"),
599 jerry_create_object (),
600 jerry_create_null (),
601 jerry_create_arraybuffer (16),
602 jerry_create_error (JERRY_ERROR_TYPE, (const jerry_char_t *) "error"),
603 jerry_create_undefined (),
604 jerry_create_promise (),
605 };
606
607 for (size_t idx = 0; idx < sizeof (values) / sizeof (values[0]); idx++)
608 {
609 /* A non-TypedArray object should not be regarded a TypedArray. */
610 bool is_typedarray = jerry_value_is_typedarray (values[idx]);
611 TEST_ASSERT (is_typedarray == false);
612
613 /* JERRY_TYPEDARRAY_INVALID should be returned for non-TypedArray objects */
614 jerry_typedarray_type_t type = jerry_get_typedarray_type (values[idx]);
615 TEST_ASSERT (type == JERRY_TYPEDARRAY_INVALID);
616
617 /* Zero should be returned for non-TypedArray objects */
618 jerry_length_t length = jerry_get_typedarray_length (values[idx]);
619 TEST_ASSERT (length == 0);
620
621 /**
622 * Getting the ArrayBuffer from a non-TypedArray object(s) should return an error
623 * and should not modify the output parameter values.
624 */
625 {
626 jerry_length_t offset = 22;
627 jerry_length_t byte_count = 23;
628 jerry_value_t error = jerry_get_typedarray_buffer (values[idx], &offset, &byte_count);
629 TEST_ASSERT (jerry_value_is_error (error));
630 TEST_ASSERT (offset == 22);
631 TEST_ASSERT (byte_count == 23);
632 jerry_release_value (error);
633 }
634
635 /**
636 * Creating a TypedArray from a non-ArrayBuffer should result an error.
637 */
638 if (!jerry_value_is_arraybuffer (values[idx]))
639 {
640 jerry_value_t error = jerry_create_typedarray_for_arraybuffer (JERRY_TYPEDARRAY_UINT8, values[idx]);
641 TEST_ASSERT (jerry_value_is_error (error));
642 jerry_release_value (error);
643 }
644
645 jerry_release_value (values[idx]);
646 }
647 }
648
649 test_detached_arraybuffer ();
650
651 jerry_cleanup ();
652
653 return 0;
654 } /* main */
655