• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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