• 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 "config.h"
17 #include "jerryscript.h"
18 
19 #include "test-common.h"
20 
21 const jerry_char_t test_source[] = TEST_STRING_LITERAL (
22   "function assert (arg) { "
23   "  if (!arg) { "
24   "    throw Error('Assert failed');"
25   "  } "
26   "} "
27   "this.t = 1; "
28   "function f () { "
29   "return this.t; "
30   "} "
31   "this.foo = f; "
32   "this.bar = function (a) { "
33   "return a + t; "
34   "}; "
35   "function A () { "
36   "this.t = 12; "
37   "} "
38   "this.A = A; "
39   "this.a = new A (); "
40   "function call_external () { "
41   "  return this.external ('1', true); "
42   "} "
43   "function call_throw_test() { "
44   "  var catched = false; "
45   "  try { "
46   "    this.throw_test(); "
47   "  } catch (e) { "
48   "    catched = true; "
49   "    assert(e.name == 'TypeError'); "
50   "    assert(e.message == 'error'); "
51   "  } "
52   "  assert(catched); "
53   "} "
54   "function throw_reference_error() { "
55   " throw new ReferenceError ();"
56   "} "
57   "p = {'alpha':32, 'bravo':false, 'charlie':{}, 'delta':123.45, 'echo':'foobar'};"
58   "np = {}; Object.defineProperty (np, 'foxtrot', { "
59   "get: function() { throw 'error'; }, enumerable: true }) "
60 );
61 
62 bool test_api_is_free_callback_was_called = false;
63 
64 static jerry_value_t
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)65 handler (const jerry_value_t func_obj_val, /**< function object */
66          const jerry_value_t this_val, /**< this value */
67          const jerry_value_t args_p[], /**< arguments list */
68          const jerry_length_t args_cnt) /**< arguments length */
69 {
70   char buffer[32];
71   jerry_size_t sz;
72 
73   printf ("ok %u %u %p %u\n",
74           (unsigned int) func_obj_val, (unsigned int) this_val, (void *) args_p, (unsigned int) args_cnt);
75 
76   TEST_ASSERT (args_cnt == 2);
77 
78   TEST_ASSERT (jerry_value_is_string (args_p[0]));
79   sz = jerry_get_string_size (args_p[0]);
80   TEST_ASSERT (sz == 1);
81   sz = jerry_string_to_char_buffer (args_p[0],
82                                     (jerry_char_t *) buffer,
83                                     sz);
84   TEST_ASSERT (sz == 1);
85   TEST_ASSERT (!strncmp (buffer, "1", (size_t) sz));
86 
87   TEST_ASSERT (jerry_value_is_boolean (args_p[1]));
88 
89   return jerry_create_string ((jerry_char_t *) "string from handler");
90 } /* handler */
91 
92 static jerry_value_t
handler_throw_test(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)93 handler_throw_test (const jerry_value_t func_obj_val, /**< function object */
94                     const jerry_value_t this_val, /**< this value */
95                     const jerry_value_t args_p[], /**< arguments list */
96                     const jerry_length_t args_cnt) /**< arguments length */
97 {
98   printf ("ok %u %u %p %u\n",
99           (unsigned int) func_obj_val, (unsigned int) this_val, (void *) args_p, (unsigned int) args_cnt);
100 
101   return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "error");
102 } /* handler_throw_test */
103 
104 static void
handler_construct_1_freecb(void * native_p)105 handler_construct_1_freecb (void *native_p)
106 {
107   TEST_ASSERT ((uintptr_t) native_p == (uintptr_t) 0x0000000000000000ull);
108   printf ("ok object free callback\n");
109 
110   test_api_is_free_callback_was_called = true;
111 } /* handler_construct_1_freecb */
112 
113 static void
handler_construct_2_freecb(void * native_p)114 handler_construct_2_freecb (void *native_p)
115 {
116   TEST_ASSERT ((uintptr_t) native_p == (uintptr_t) 0x0012345678abcdefull);
117   printf ("ok object free callback\n");
118 
119   test_api_is_free_callback_was_called = true;
120 } /* handler_construct_2_freecb */
121 
122 /**
123  * The name of the jerry_object_native_info_t struct.
124  */
125 #define JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE(c_type) _jerry_object_native_info_##c_type
126 
127 /**
128  * Define a native pointer's type based on the C type and free callback.
129  */
130 #define JERRY_DEFINE_NATIVE_HANDLE_INFO(c_type, native_free_cb) \
131   static const jerry_object_native_info_t JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (c_type) = \
132   { \
133     .free_cb = (jerry_object_native_free_callback_t) native_free_cb \
134   }
135 
136 JERRY_DEFINE_NATIVE_HANDLE_INFO (bind1, handler_construct_1_freecb);
137 JERRY_DEFINE_NATIVE_HANDLE_INFO (bind2, handler_construct_2_freecb);
138 JERRY_DEFINE_NATIVE_HANDLE_INFO (bind3, NULL);
139 
140 static jerry_value_t
handler_construct(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)141 handler_construct (const jerry_value_t func_obj_val, /**< function object */
142                    const jerry_value_t this_val, /**< this value */
143                    const jerry_value_t args_p[], /**< arguments list */
144                    const jerry_length_t args_cnt) /**< arguments length */
145 {
146   printf ("ok construct %u %u %p %u\n",
147           (unsigned int) func_obj_val, (unsigned int) this_val, (void *) args_p, (unsigned int) args_cnt);
148 
149   TEST_ASSERT (jerry_value_is_object (this_val));
150 
151   TEST_ASSERT (args_cnt == 1);
152   TEST_ASSERT (jerry_value_is_boolean (args_p[0]));
153   TEST_ASSERT (jerry_get_boolean_value (args_p[0]) == true);
154 
155   jerry_value_t field_name = jerry_create_string ((jerry_char_t *) "value_field");
156   jerry_value_t res = jerry_set_property (this_val, field_name, args_p[0]);
157   TEST_ASSERT (!jerry_value_is_error (res));
158   TEST_ASSERT (jerry_value_is_boolean (res) && jerry_get_boolean_value (res));
159   jerry_release_value (res);
160   jerry_release_value (field_name);
161 
162   /* Set a native pointer. */
163   jerry_set_object_native_pointer (this_val,
164                                    (void *) 0x0000000000000000ull,
165                                    &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1));
166 
167   /* Check that the native pointer was set. */
168   void *ptr = NULL;
169   bool is_ok = jerry_get_object_native_pointer (this_val, &ptr, &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1));
170   TEST_ASSERT (is_ok
171                && (uintptr_t) ptr == (uintptr_t) 0x0000000000000000ull);
172 
173   /* Set a second native pointer. */
174   jerry_set_object_native_pointer (this_val,
175                                    (void *) 0x0012345678abcdefull,
176                                    &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2));
177 
178   /* Check that a second native pointer was set. */
179   is_ok = jerry_get_object_native_pointer (this_val, &ptr, &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2));
180   TEST_ASSERT (is_ok
181                && (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull);
182 
183   /* Check that the first native pointer is still set. */
184   is_ok = jerry_get_object_native_pointer (this_val, &ptr, &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1));
185   TEST_ASSERT (is_ok
186                && (uintptr_t) ptr == (uintptr_t) 0x0000000000000000ull);
187   return jerry_create_boolean (true);
188 } /* handler_construct */
189 
190 /**
191  * Extended Magic Strings
192  */
193 #define JERRY_MAGIC_STRING_ITEMS \
194   JERRY_MAGIC_STRING_DEF (GLOBAL, global) \
195   JERRY_MAGIC_STRING_DEF (GREEK_ZERO_SIGN, \xed\xa0\x80\xed\xb6\x8a) \
196   JERRY_MAGIC_STRING_DEF (CONSOLE, console)
197 
198 #define JERRY_MAGIC_STRING_DEF(NAME, STRING) \
199   static const char jerry_magic_string_ex_ ## NAME[] = # STRING;
200 
201 JERRY_MAGIC_STRING_ITEMS
202 
203 #undef JERRY_MAGIC_STRING_DEF
204 
205 const jerry_length_t magic_string_lengths[] =
206 {
207 #define JERRY_MAGIC_STRING_DEF(NAME, STRING) \
208     (jerry_length_t) (sizeof (jerry_magic_string_ex_ ## NAME) - 1u),
209 
210   JERRY_MAGIC_STRING_ITEMS
211 
212 #undef JERRY_MAGIC_STRING_DEF
213 };
214 
215 const jerry_char_t *magic_string_items[] =
216 {
217 #define JERRY_MAGIC_STRING_DEF(NAME, STRING) \
218     (const jerry_char_t *) jerry_magic_string_ex_ ## NAME,
219 
220   JERRY_MAGIC_STRING_ITEMS
221 
222 #undef JERRY_MAGIC_STRING_DEF
223 };
224 
225 static bool
foreach(const jerry_value_t name,const jerry_value_t value,void * user_data)226 foreach (const jerry_value_t name, /**< field name */
227          const jerry_value_t value, /**< field value */
228          void *user_data) /**< user data */
229 {
230   char str_buf_p[128];
231   jerry_size_t sz = jerry_string_to_char_buffer (name, (jerry_char_t *) str_buf_p, 128);
232   str_buf_p[sz] = '\0';
233 
234   TEST_ASSERT (!strncmp ((const char *) user_data, "user_data", 9));
235   TEST_ASSERT (sz > 0);
236 
237   if (!strncmp (str_buf_p, "alpha", (size_t) sz))
238   {
239     TEST_ASSERT (jerry_value_is_number (value));
240     TEST_ASSERT (jerry_get_number_value (value) == 32.0);
241     return true;
242   }
243   else if (!strncmp (str_buf_p, "bravo", (size_t) sz))
244   {
245     TEST_ASSERT (jerry_value_is_boolean (value));
246     TEST_ASSERT (jerry_get_boolean_value (value) == false);
247     return true;
248   }
249   else if (!strncmp (str_buf_p, "charlie", (size_t) sz))
250   {
251     TEST_ASSERT (jerry_value_is_object (value));
252     return true;
253   }
254   else if (!strncmp (str_buf_p, "delta", (size_t) sz))
255   {
256     TEST_ASSERT (jerry_value_is_number (value));
257     TEST_ASSERT (jerry_get_number_value (value) == 123.45);
258     return true;
259   }
260   else if (!strncmp (str_buf_p, "echo", (size_t) sz))
261   {
262     TEST_ASSERT (jerry_value_is_string (value));
263     jerry_size_t echo_sz = jerry_string_to_char_buffer (value,
264                                                         (jerry_char_t *) str_buf_p,
265                                                         128);
266     str_buf_p[echo_sz] = '\0';
267     TEST_ASSERT (!strncmp (str_buf_p, "foobar", (size_t) echo_sz));
268     return true;
269   }
270 
271   TEST_ASSERT (false);
272   return false;
273 } /* foreach */
274 
275 static bool
foreach_exception(const jerry_value_t name,const jerry_value_t value,void * user_data)276 foreach_exception (const jerry_value_t name, /**< field name */
277                    const jerry_value_t value, /**< field value */
278                    void *user_data) /**< user data */
279 {
280   JERRY_UNUSED (value);
281   JERRY_UNUSED (user_data);
282   char str_buf_p[128];
283   jerry_size_t sz = jerry_string_to_char_buffer (name, (jerry_char_t *) str_buf_p, 128);
284   str_buf_p[sz] = '\0';
285 
286   if (!strncmp (str_buf_p, "foxtrot", (size_t) sz))
287   {
288     TEST_ASSERT (false);
289   }
290 
291   return true;
292 } /* foreach_exception */
293 
294 static bool
foreach_subset(const jerry_value_t name,const jerry_value_t value,void * user_data)295 foreach_subset (const jerry_value_t name, /**< field name */
296                 const jerry_value_t value, /**< field value */
297                 void *user_data) /**< user data */
298 {
299   JERRY_UNUSED (name);
300   JERRY_UNUSED (value);
301   int *count_p = (int *) (user_data);
302 
303   if (*count_p == 3)
304   {
305     return false;
306   }
307   (*count_p)++;
308   return true;
309 } /* foreach_subset */
310 
311 static jerry_value_t
get_property(const jerry_value_t obj_val,const char * str_p)312 get_property (const jerry_value_t obj_val, /**< object value */
313               const char *str_p) /**< property name */
314 {
315   jerry_value_t prop_name_val = jerry_create_string ((const jerry_char_t *) str_p);
316   jerry_value_t ret_val = jerry_get_property (obj_val, prop_name_val);
317   jerry_release_value (prop_name_val);
318   return ret_val;
319 } /* get_property */
320 
321 static jerry_value_t
set_property(const jerry_value_t obj_val,const char * str_p,const jerry_value_t val)322 set_property (const jerry_value_t obj_val, /**< object value */
323               const char *str_p, /**< property name */
324               const jerry_value_t val) /**< value to set */
325 {
326   jerry_value_t prop_name_val = jerry_create_string ((const jerry_char_t *) str_p);
327   jerry_value_t ret_val = jerry_set_property (obj_val, prop_name_val, val);
328   jerry_release_value (prop_name_val);
329   return ret_val;
330 } /* set_property */
331 
332 static bool
test_run_simple(const char * script_p)333 test_run_simple (const char *script_p) /**< source code to run */
334 {
335   size_t script_size = strlen (script_p);
336 
337   return jerry_run_simple ((const jerry_char_t *) script_p, script_size, JERRY_INIT_EMPTY);
338 } /* test_run_simple */
339 
340 int
main(void)341 main (void)
342 {
343   TEST_INIT ();
344 
345   bool is_ok;
346   jerry_size_t sz, cesu8_sz;
347   jerry_length_t cesu8_length;
348   jerry_value_t val_t, val_foo, val_bar, val_A, val_A_prototype, val_a, val_a_foo, val_value_field, val_p, val_np;
349   jerry_value_t val_call_external;
350   jerry_value_t global_obj_val, obj_val;
351   jerry_value_t external_func_val, external_construct_val;
352   jerry_value_t throw_test_handler_val;
353   jerry_value_t parsed_code_val, proto_val, prim_val;
354   jerry_value_t res, args[2];
355   double number_val;
356   char buffer[32];
357 
358   is_ok = test_run_simple ("throw 'Hello World';");
359   TEST_ASSERT (!is_ok);
360 
361   jerry_init (JERRY_INIT_EMPTY);
362 
363   parsed_code_val = jerry_parse (NULL,
364                                  0,
365                                  test_source,
366                                  sizeof (test_source) - 1,
367                                  JERRY_PARSE_NO_OPTS);
368   TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
369 
370   res = jerry_run (parsed_code_val);
371   TEST_ASSERT (!jerry_value_is_error (res));
372   jerry_release_value (res);
373   jerry_release_value (parsed_code_val);
374 
375   global_obj_val = jerry_get_global_object ();
376 
377   /* Get global.boo (non-existing field) */
378   val_t = get_property (global_obj_val, "boo");
379   TEST_ASSERT (!jerry_value_is_error (val_t));
380   TEST_ASSERT (jerry_value_is_undefined (val_t));
381 
382   /* Get global.t */
383   val_t = get_property (global_obj_val, "t");
384   TEST_ASSERT (!jerry_value_is_error (val_t));
385   TEST_ASSERT (jerry_value_is_number (val_t)
386                && jerry_get_number_value (val_t) == 1.0);
387   jerry_release_value (val_t);
388 
389   /* Get global.foo */
390   val_foo = get_property (global_obj_val, "foo");
391   TEST_ASSERT (!jerry_value_is_error (val_foo));
392   TEST_ASSERT (jerry_value_is_object (val_foo));
393 
394   /* Call foo (4, 2) */
395   args[0] = jerry_create_number (4);
396   args[1] = jerry_create_number (2);
397   res = jerry_call_function (val_foo, jerry_create_undefined (), args, 2);
398   TEST_ASSERT (!jerry_value_is_error (res));
399   TEST_ASSERT (jerry_value_is_number (res)
400                && jerry_get_number_value (res) == 1.0);
401   jerry_release_value (res);
402 
403   /* Get global.bar */
404   val_bar = get_property (global_obj_val, "bar");
405   TEST_ASSERT (!jerry_value_is_error (val_bar));
406   TEST_ASSERT (jerry_value_is_object (val_bar));
407 
408   /* Call bar (4, 2) */
409   res = jerry_call_function (val_bar, jerry_create_undefined (), args, 2);
410   TEST_ASSERT (!jerry_value_is_error (res));
411   TEST_ASSERT (jerry_value_is_number (res)
412                && jerry_get_number_value (res) == 5.0);
413   jerry_release_value (res);
414   jerry_release_value (val_bar);
415 
416   /* Set global.t = "abcd" */
417   jerry_release_value (args[0]);
418   args[0] = jerry_create_string ((jerry_char_t *) "abcd");
419   res = set_property (global_obj_val, "t", args[0]);
420   TEST_ASSERT (!jerry_value_is_error (res));
421   TEST_ASSERT (jerry_get_boolean_value (res));
422   jerry_release_value (res);
423 
424   /* Call foo (4, 2) */
425   res = jerry_call_function (val_foo, jerry_create_undefined (), args, 2);
426   TEST_ASSERT (!jerry_value_is_error (res));
427   TEST_ASSERT (jerry_value_is_string (res));
428   sz = jerry_get_string_size (res);
429   TEST_ASSERT (sz == 4);
430   sz = jerry_string_to_char_buffer (res, (jerry_char_t *) buffer, sz);
431   TEST_ASSERT (sz == 4);
432   jerry_release_value (res);
433   TEST_ASSERT (!strncmp (buffer, "abcd", (size_t) sz));
434   jerry_release_value (args[0]);
435   jerry_release_value (args[1]);
436 
437   /* Get global.A */
438   val_A = get_property (global_obj_val, "A");
439   TEST_ASSERT (!jerry_value_is_error (val_A));
440   TEST_ASSERT (jerry_value_is_object (val_A));
441 
442   /* Get A.prototype */
443   is_ok = jerry_value_is_constructor (val_A);
444   TEST_ASSERT (is_ok);
445   val_A_prototype = get_property (val_A, "prototype");
446   TEST_ASSERT (!jerry_value_is_error (val_A_prototype));
447   TEST_ASSERT (jerry_value_is_object (val_A_prototype));
448   jerry_release_value (val_A);
449 
450   /* Set A.prototype.foo = global.foo */
451   res = set_property (val_A_prototype, "foo", val_foo);
452   TEST_ASSERT (!jerry_value_is_error (res));
453   TEST_ASSERT (jerry_get_boolean_value (res));
454   jerry_release_value (res);
455   jerry_release_value (val_A_prototype);
456   jerry_release_value (val_foo);
457 
458   /* Get global.a */
459   val_a = get_property (global_obj_val, "a");
460   TEST_ASSERT (!jerry_value_is_error (val_a));
461   TEST_ASSERT (jerry_value_is_object (val_a));
462 
463   /* Get a.t */
464   res = get_property (val_a, "t");
465   TEST_ASSERT (!jerry_value_is_error (res));
466   TEST_ASSERT (jerry_value_is_number (res)
467                && jerry_get_number_value (res) == 12.0);
468   jerry_release_value (res);
469 
470   /* foreach properties */
471   val_p = get_property (global_obj_val, "p");
472   is_ok = jerry_foreach_object_property (val_p, foreach, (void *) "user_data");
473   TEST_ASSERT (is_ok);
474 
475   /* break foreach at third element */
476   int count = 0;
477   is_ok = jerry_foreach_object_property (val_p, foreach_subset, &count);
478   TEST_ASSERT (is_ok);
479   TEST_ASSERT (count == 3);
480   jerry_release_value (val_p);
481 
482   /* foreach with throw test */
483   val_np = get_property (global_obj_val, "np");
484   is_ok = !jerry_foreach_object_property (val_np, foreach_exception, NULL);
485   TEST_ASSERT (is_ok);
486   jerry_release_value (val_np);
487 
488   /* Get a.foo */
489   val_a_foo = get_property (val_a, "foo");
490   TEST_ASSERT (!jerry_value_is_error (val_a_foo));
491   TEST_ASSERT (jerry_value_is_object (val_a_foo));
492 
493   /* Call a.foo () */
494   res = jerry_call_function (val_a_foo, val_a, NULL, 0);
495   TEST_ASSERT (!jerry_value_is_error (res));
496   TEST_ASSERT (jerry_value_is_number (res)
497                && jerry_get_number_value (res) == 12.0);
498   jerry_release_value (res);
499   jerry_release_value (val_a_foo);
500 
501   jerry_release_value (val_a);
502 
503   /* Create native handler bound function object and set it to 'external' variable */
504   external_func_val = jerry_create_external_function (handler);
505   TEST_ASSERT (jerry_value_is_function (external_func_val)
506                && jerry_value_is_constructor (external_func_val));
507 
508   res = set_property (global_obj_val, "external", external_func_val);
509   TEST_ASSERT (!jerry_value_is_error (res));
510   TEST_ASSERT (jerry_get_boolean_value (res));
511   jerry_release_value (external_func_val);
512 
513   /* Call 'call_external' function that should call external function created above */
514   val_call_external = get_property (global_obj_val, "call_external");
515   TEST_ASSERT (!jerry_value_is_error (val_call_external));
516   TEST_ASSERT (jerry_value_is_object (val_call_external));
517   res = jerry_call_function (val_call_external, global_obj_val, NULL, 0);
518   jerry_release_value (val_call_external);
519   TEST_ASSERT (!jerry_value_is_error (res));
520   TEST_ASSERT (jerry_value_is_string (res));
521   sz = jerry_get_string_size (res);
522   TEST_ASSERT (sz == 19);
523   sz = jerry_string_to_char_buffer (res, (jerry_char_t *) buffer, sz);
524   TEST_ASSERT (sz == 19);
525   jerry_release_value (res);
526   TEST_ASSERT (!strncmp (buffer, "string from handler", (size_t) sz));
527 
528   /* Create native handler bound function object and set it to 'external_construct' variable */
529   external_construct_val = jerry_create_external_function (handler_construct);
530   TEST_ASSERT (jerry_value_is_function (external_construct_val)
531                && jerry_value_is_constructor (external_construct_val));
532 
533   res = set_property (global_obj_val, "external_construct", external_construct_val);
534   TEST_ASSERT (!jerry_value_is_error (res));
535   TEST_ASSERT (jerry_get_boolean_value (res));
536   jerry_release_value (res);
537 
538   /* Call external function created above, as constructor */
539   args[0] = jerry_create_boolean (true);
540   res = jerry_construct_object (external_construct_val, args, 1);
541   TEST_ASSERT (!jerry_value_is_error (res));
542   TEST_ASSERT (jerry_value_is_object (res));
543   val_value_field = get_property (res, "value_field");
544 
545   /* Get 'value_field' of constructed object */
546   TEST_ASSERT (!jerry_value_is_error (val_value_field));
547   TEST_ASSERT (jerry_value_is_boolean (val_value_field)
548                && jerry_get_boolean_value (val_value_field));
549   jerry_release_value (val_value_field);
550   jerry_release_value (external_construct_val);
551 
552   void *ptr = NULL;
553   is_ok = jerry_get_object_native_pointer (res, &ptr, &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2));
554   TEST_ASSERT (is_ok
555                && (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull);
556 
557   /* Passing NULL for info_p is allowed. */
558   is_ok = jerry_get_object_native_pointer (res, &ptr, NULL);
559   TEST_ASSERT (!is_ok);
560 
561   jerry_release_value (res);
562 
563   /* Test: It is ok to set native pointer's free callback as NULL. */
564   jerry_value_t obj_freecb = jerry_create_object ();
565   jerry_set_object_native_pointer (obj_freecb,
566                                    (void *) 0x1234,
567                                    &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind3));
568 
569   jerry_release_value (obj_freecb);
570 
571   /* Test: Throwing exception from native handler. */
572   throw_test_handler_val = jerry_create_external_function (handler_throw_test);
573   TEST_ASSERT (jerry_value_is_function (throw_test_handler_val));
574 
575   res = set_property (global_obj_val, "throw_test", throw_test_handler_val);
576   TEST_ASSERT (!jerry_value_is_error (res));
577   TEST_ASSERT (jerry_get_boolean_value (res));
578   jerry_release_value (res);
579   jerry_release_value (throw_test_handler_val);
580 
581   val_t = get_property (global_obj_val, "call_throw_test");
582   TEST_ASSERT (!jerry_value_is_error (val_t));
583   TEST_ASSERT (jerry_value_is_object (val_t));
584 
585   res = jerry_call_function (val_t, global_obj_val, NULL, 0);
586   TEST_ASSERT (!jerry_value_is_error (res));
587   jerry_release_value (val_t);
588   jerry_release_value (res);
589 
590   /* Test: Unhandled exception in called function */
591   val_t = get_property (global_obj_val, "throw_reference_error");
592   TEST_ASSERT (!jerry_value_is_error (val_t));
593   TEST_ASSERT (jerry_value_is_object (val_t));
594 
595   res = jerry_call_function (val_t, global_obj_val, NULL, 0);
596 
597   TEST_ASSERT (jerry_value_is_error (res));
598   jerry_release_value (val_t);
599 
600   /* 'res' should contain exception object */
601   res = jerry_get_value_from_error (res, true);
602   TEST_ASSERT (jerry_value_is_object (res));
603   jerry_release_value (res);
604 
605   /* Test: Call of non-function */
606   obj_val = jerry_create_object ();
607   res = jerry_call_function (obj_val, global_obj_val, NULL, 0);
608   TEST_ASSERT (jerry_value_is_error (res));
609 
610   /* 'res' should contain exception object */
611   res = jerry_get_value_from_error (res, true);
612   TEST_ASSERT (jerry_value_is_object (res));
613   jerry_release_value (res);
614 
615   jerry_release_value (obj_val);
616 
617   /* Test: Unhandled exception in function called, as constructor */
618   val_t = get_property (global_obj_val, "throw_reference_error");
619   TEST_ASSERT (!jerry_value_is_error (val_t));
620   TEST_ASSERT (jerry_value_is_object (val_t));
621 
622   res = jerry_construct_object (val_t, NULL, 0);
623   TEST_ASSERT (jerry_value_is_error (res));
624   jerry_release_value (val_t);
625 
626   /* 'res' should contain exception object */
627   res = jerry_get_value_from_error (res, true);
628   TEST_ASSERT (jerry_value_is_object (res));
629   jerry_release_value (res);
630 
631   /* Test: Call of non-function as constructor */
632   obj_val = jerry_create_object ();
633   res = jerry_construct_object (obj_val, NULL, 0);
634   TEST_ASSERT (jerry_value_is_error (res));
635 
636   /* 'res' should contain exception object */
637   res = jerry_get_value_from_error (res, true);
638   TEST_ASSERT (jerry_value_is_object (res));
639   jerry_release_value (res);
640 
641   jerry_release_value (obj_val);
642 
643   /* Test: Array Object API */
644   jerry_value_t array_obj_val = jerry_create_array (10);
645   TEST_ASSERT (jerry_value_is_array (array_obj_val));
646   TEST_ASSERT (jerry_get_array_length (array_obj_val) == 10);
647 
648   jerry_value_t v_in = jerry_create_number (10.5);
649   res = jerry_set_property_by_index (array_obj_val, 5, v_in);
650   TEST_ASSERT (!jerry_value_is_error (res));
651   TEST_ASSERT (jerry_value_is_boolean (res) && jerry_get_boolean_value (res));
652   jerry_release_value (res);
653   jerry_value_t v_out = jerry_get_property_by_index (array_obj_val, 5);
654 
655   TEST_ASSERT (jerry_value_is_number (v_out)
656                && jerry_get_number_value (v_out) == 10.5);
657 
658   jerry_delete_property_by_index (array_obj_val, 5);
659   jerry_value_t v_und = jerry_get_property_by_index (array_obj_val, 5);
660 
661   TEST_ASSERT (jerry_value_is_undefined (v_und));
662 
663   jerry_release_value (v_in);
664   jerry_release_value (v_out);
665   jerry_release_value (v_und);
666   jerry_release_value (array_obj_val);
667 
668   /* Test: object keys */
669   res = jerry_get_object_keys (global_obj_val);
670   TEST_ASSERT (!jerry_value_is_error (res));
671   TEST_ASSERT (jerry_value_is_array (res));
672   TEST_ASSERT (jerry_get_array_length (res) == 15);
673   jerry_release_value (res);
674 
675   /* Test: jerry_value_to_primitive */
676   obj_val = jerry_eval ((jerry_char_t *) "new String ('hello')", 20, JERRY_PARSE_NO_OPTS);
677   TEST_ASSERT (!jerry_value_is_error (obj_val));
678   TEST_ASSERT (jerry_value_is_object (obj_val));
679   TEST_ASSERT (!jerry_value_is_string (obj_val));
680   prim_val = jerry_value_to_primitive (obj_val);
681   TEST_ASSERT (!jerry_value_is_error (prim_val));
682   TEST_ASSERT (jerry_value_is_string (prim_val));
683   jerry_release_value (prim_val);
684 
685   /* Test: jerry_get_prototype */
686   proto_val = jerry_get_prototype (jerry_create_undefined ());
687   TEST_ASSERT (jerry_value_is_error (proto_val));
688   jerry_value_t error = jerry_get_value_from_error (proto_val, true);
689   TEST_ASSERT (jerry_get_error_type (error) == JERRY_ERROR_TYPE);
690   jerry_release_value (error);
691 
692   proto_val = jerry_get_prototype (obj_val);
693   TEST_ASSERT (!jerry_value_is_error (proto_val));
694   TEST_ASSERT (jerry_value_is_object (proto_val));
695   jerry_release_value (proto_val);
696   jerry_release_value (obj_val);
697 
698   if (jerry_is_feature_enabled (JERRY_FEATURE_PROXY))
699   {
700     jerry_value_t target = jerry_create_object ();
701     jerry_value_t handler = jerry_create_object ();
702     jerry_value_t proxy = jerry_create_proxy (target, handler);
703     jerry_value_t obj_proto = jerry_eval ((jerry_char_t *) "Object.prototype", 16, JERRY_PARSE_NO_OPTS);
704 
705     jerry_release_value (target);
706     jerry_release_value (handler);
707     proto_val = jerry_get_prototype (proxy);
708     TEST_ASSERT (!jerry_value_is_error (proto_val));
709     TEST_ASSERT (proto_val == obj_proto);
710     jerry_release_value (proto_val);
711     jerry_release_value (obj_proto);
712     jerry_release_value (proxy);
713   }
714 
715   /* Test: jerry_set_prototype */
716   obj_val = jerry_create_object ();
717   res = jerry_set_prototype (obj_val, jerry_create_null ());
718   TEST_ASSERT (!jerry_value_is_error (res));
719   TEST_ASSERT (jerry_value_is_boolean (res));
720   TEST_ASSERT (jerry_get_boolean_value (res));
721 
722   jerry_value_t new_proto = jerry_create_object ();
723   res = jerry_set_prototype (obj_val, new_proto);
724   jerry_release_value (new_proto);
725   TEST_ASSERT (!jerry_value_is_error (res));
726   TEST_ASSERT (jerry_value_is_boolean (res));
727   TEST_ASSERT (jerry_get_boolean_value (res));
728   proto_val = jerry_get_prototype (obj_val);
729   TEST_ASSERT (!jerry_value_is_error (proto_val));
730   TEST_ASSERT (jerry_value_is_object (proto_val));
731   jerry_release_value (proto_val);
732   jerry_release_value (obj_val);
733 
734   if (jerry_is_feature_enabled (JERRY_FEATURE_PROXY))
735   {
736     jerry_value_t target = jerry_create_object ();
737     jerry_value_t handler = jerry_create_object ();
738     jerry_value_t proxy = jerry_create_proxy (target, handler);
739     new_proto = jerry_eval ((jerry_char_t *) "Function.prototype", 18, JERRY_PARSE_NO_OPTS);
740 
741     res = jerry_set_prototype (proxy, new_proto);
742     TEST_ASSERT (!jerry_value_is_error (res));
743     jerry_value_t target_proto = jerry_get_prototype (target);
744     TEST_ASSERT (target_proto == new_proto);
745 
746     jerry_release_value (target);
747     jerry_release_value (handler);
748     jerry_release_value (proxy);
749     jerry_release_value (new_proto);
750     jerry_release_value (target_proto);
751   }
752 
753   /* Test: eval */
754   const jerry_char_t eval_code_src1[] = "(function () { return 123; })";
755   val_t = jerry_eval (eval_code_src1, sizeof (eval_code_src1) - 1, JERRY_PARSE_STRICT_MODE);
756   TEST_ASSERT (!jerry_value_is_error (val_t));
757   TEST_ASSERT (jerry_value_is_object (val_t));
758   TEST_ASSERT (jerry_value_is_function (val_t));
759 
760   res = jerry_call_function (val_t, jerry_create_undefined (), NULL, 0);
761   TEST_ASSERT (!jerry_value_is_error (res));
762   TEST_ASSERT (jerry_value_is_number (res)
763                && jerry_get_number_value (res) == 123.0);
764   jerry_release_value (res);
765 
766   jerry_release_value (val_t);
767 
768   /* cleanup. */
769   jerry_release_value (global_obj_val);
770 
771   /* Test: run gc. */
772   jerry_gc (JERRY_GC_PRESSURE_LOW);
773 
774   /* Test: spaces */
775   const jerry_char_t eval_code_src2[] = "\x0a \x0b \x0c \xc2\xa0 \xe2\x80\xa8 \xe2\x80\xa9 \xef\xbb\xbf 4321";
776   val_t = jerry_eval (eval_code_src2, sizeof (eval_code_src2) - 1, JERRY_PARSE_STRICT_MODE);
777   TEST_ASSERT (!jerry_value_is_error (val_t));
778   TEST_ASSERT (jerry_value_is_number (val_t)
779                && jerry_get_number_value (val_t) == 4321.0);
780   jerry_release_value (val_t);
781 
782   /* Test: number */
783   val_t = jerry_create_number (6.25);
784   number_val = jerry_get_number_value (val_t);
785   TEST_ASSERT (number_val * 3 == 18.75);
786   jerry_release_value (val_t);
787 
788   val_t = jerry_create_number_infinity (true);
789   number_val = jerry_get_number_value (val_t);
790   TEST_ASSERT (number_val * 3 == number_val && number_val != 0.0);
791   jerry_release_value (val_t);
792 
793   val_t = jerry_create_number_nan ();
794   number_val = jerry_get_number_value (val_t);
795   TEST_ASSERT (number_val != number_val);
796   jerry_release_value (val_t);
797 
798   /* Test: create function */
799   const jerry_char_t func_resource[] = "unknown";
800   const jerry_char_t func_arg_list[] = "a , b,c";
801   const jerry_char_t func_src[] = "  return 5 +  a+\nb+c";
802 
803   jerry_value_t func_val = jerry_parse_function (func_resource,
804                                                  sizeof (func_resource) - 1,
805                                                  func_arg_list,
806                                                  sizeof (func_arg_list) - 1,
807                                                  func_src,
808                                                  sizeof (func_src) - 1,
809                                                  JERRY_PARSE_NO_OPTS);
810 
811   TEST_ASSERT (!jerry_value_is_error (func_val));
812 
813   jerry_value_t func_args[3] =
814   {
815     jerry_create_number (4),
816     jerry_create_number (6),
817     jerry_create_number (-2)
818   };
819 
820   val_t = jerry_call_function (func_val, func_args[0], func_args, 3);
821   number_val = jerry_get_number_value (val_t);
822   TEST_ASSERT (number_val == 13.0);
823 
824   jerry_release_value (val_t);
825   jerry_release_value (func_val);
826 
827   jerry_cleanup ();
828 
829   TEST_ASSERT (test_api_is_free_callback_was_called);
830 
831   /* Test: jerry_get_value_from_error */
832   {
833     jerry_init (JERRY_INIT_EMPTY);
834     jerry_value_t num_val = jerry_create_number (123);
835     num_val = jerry_create_error_from_value (num_val, true);
836     TEST_ASSERT (jerry_value_is_error (num_val));
837     jerry_value_t num2_val = jerry_get_value_from_error (num_val, false);
838     TEST_ASSERT (jerry_value_is_error (num_val));
839     TEST_ASSERT (!jerry_value_is_error (num2_val));
840     double num = jerry_get_number_value (num2_val);
841     TEST_ASSERT (num == 123);
842     num2_val = jerry_get_value_from_error (num_val, true);
843     TEST_ASSERT (!jerry_value_is_error (num2_val));
844     num = jerry_get_number_value (num2_val);
845     TEST_ASSERT (num == 123);
846     jerry_release_value (num2_val);
847     jerry_cleanup ();
848   }
849 
850   /* Test parsing/executing scripts with lexically scoped global variables multiple times. */
851   if (jerry_is_feature_enabled (JERRY_FEATURE_SYMBOL))
852   {
853     jerry_init (JERRY_INIT_EMPTY);
854     const jerry_char_t scoped_src_p[] = "let a;";
855     jerry_value_t parse_result = jerry_parse (NULL,
856                                               0,
857                                               scoped_src_p,
858                                               sizeof (scoped_src_p) - 1,
859                                               JERRY_PARSE_NO_OPTS);
860     TEST_ASSERT (!jerry_value_is_error (parse_result));
861     jerry_release_value (parse_result);
862 
863     parse_result = jerry_parse (NULL,
864                                 0,
865                                 scoped_src_p,
866                                 sizeof (scoped_src_p) - 1,
867                                 JERRY_PARSE_NO_OPTS);
868     TEST_ASSERT (!jerry_value_is_error (parse_result));
869 
870     jerry_value_t run_result = jerry_run (parse_result);
871     TEST_ASSERT (!jerry_value_is_error (run_result));
872     jerry_release_value (run_result);
873 
874     /* Should be a syntax error due to redeclaration. */
875     run_result = jerry_run (parse_result);
876     TEST_ASSERT (jerry_value_is_error (run_result));
877     jerry_release_value (run_result);
878     jerry_release_value (parse_result);
879 
880     /* The variable should have no effect on parsing. */
881     parse_result = jerry_parse (NULL,
882                                 0,
883                                 scoped_src_p,
884                                 sizeof (scoped_src_p) - 1,
885                                 JERRY_PARSE_NO_OPTS);
886     TEST_ASSERT (!jerry_value_is_error (parse_result));
887     jerry_release_value (parse_result);
888     jerry_cleanup ();
889   }
890 
891   /* Test: parser error location */
892   if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES))
893   {
894     jerry_init (JERRY_INIT_SHOW_OPCODES);
895 
896     const jerry_char_t parser_err_src[] = "b = 'hello';\nvar a = (;";
897     parsed_code_val = jerry_parse (NULL,
898                                    0,
899                                    parser_err_src,
900                                    sizeof (parser_err_src) - 1,
901                                    JERRY_PARSE_NO_OPTS);
902     TEST_ASSERT (jerry_value_is_error (parsed_code_val));
903     parsed_code_val = jerry_get_value_from_error (parsed_code_val, true);
904     jerry_value_t err_str_val = jerry_value_to_string (parsed_code_val);
905     jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
906     jerry_char_t err_str_buf[256];
907     sz = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size);
908     err_str_buf[sz] = 0;
909 
910     jerry_release_value (err_str_val);
911     jerry_release_value (parsed_code_val);
912     TEST_ASSERT (!strcmp ((char *) err_str_buf,
913                           "SyntaxError: Primary expression expected. [<anonymous>:2:10]"));
914 
915     const jerry_char_t file_str[] = "filename.js";
916     parsed_code_val = jerry_parse (file_str,
917                                    sizeof (file_str) - 1,
918                                    parser_err_src,
919                                    sizeof (parser_err_src) - 1,
920                                    JERRY_PARSE_NO_OPTS);
921     TEST_ASSERT (jerry_value_is_error (parsed_code_val));
922     parsed_code_val = jerry_get_value_from_error (parsed_code_val, true);
923     err_str_val = jerry_value_to_string (parsed_code_val);
924     err_str_size = jerry_get_string_size (err_str_val);
925 
926     sz = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size);
927     err_str_buf[sz] = 0;
928 
929     jerry_release_value (err_str_val);
930     jerry_release_value (parsed_code_val);
931     TEST_ASSERT (!strcmp ((char *) err_str_buf,
932                           "SyntaxError: Primary expression expected. [filename.js:2:10]"));
933 
934     const jerry_char_t eval_err_src[] = "eval(\"var b;\\nfor (,); \");";
935     parsed_code_val = jerry_parse (file_str,
936                                    sizeof (file_str),
937                                    eval_err_src,
938                                    sizeof (eval_err_src) - 1,
939                                    JERRY_PARSE_NO_OPTS);
940     TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
941 
942     res = jerry_run (parsed_code_val);
943     TEST_ASSERT (jerry_value_is_error (res));
944     res = jerry_get_value_from_error (res, true);
945     err_str_val = jerry_value_to_string (res);
946     err_str_size = jerry_get_string_size (err_str_val);
947 
948     sz = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size);
949     err_str_buf[sz] = 0;
950 
951     jerry_release_value (err_str_val);
952     jerry_release_value (parsed_code_val);
953     jerry_release_value (res);
954     TEST_ASSERT (!strcmp ((char *) err_str_buf,
955                           "SyntaxError: Primary expression expected. [<eval>:2:6]"));
956 
957     jerry_cleanup ();
958   }
959 
960   /* External Magic String */
961   jerry_init (JERRY_INIT_SHOW_OPCODES);
962 
963   uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_t *));
964   jerry_register_magic_strings (magic_string_items,
965                                 num_magic_string_items,
966                                 magic_string_lengths);
967 
968   const jerry_char_t ms_code_src[] = "var global = {}; var console = [1]; var process = 1;";
969   parsed_code_val = jerry_parse (NULL,
970                                  0,
971                                  ms_code_src,
972                                  sizeof (ms_code_src) - 1,
973                                  JERRY_PARSE_NO_OPTS);
974   TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
975 
976   res = jerry_run (parsed_code_val);
977   TEST_ASSERT (!jerry_value_is_error (res));
978   jerry_release_value (res);
979   jerry_release_value (parsed_code_val);
980 
981   /* call jerry_create_string functions which will returns with the registered external magic strings */
982   args[0] = jerry_create_string ((jerry_char_t *) "console");
983   args[1] = jerry_create_string ((jerry_char_t *) "\xed\xa0\x80\xed\xb6\x8a"); /**< greek zero sign */
984 
985   cesu8_length = jerry_get_string_length (args[0]);
986   cesu8_sz = jerry_get_string_size (args[0]);
987 
988   JERRY_VLA (char, string_console, cesu8_sz);
989   jerry_string_to_char_buffer (args[0], (jerry_char_t *) string_console, cesu8_sz);
990 
991   TEST_ASSERT (!strncmp (string_console, "console", cesu8_sz));
992   TEST_ASSERT (cesu8_length == 7);
993   TEST_ASSERT (cesu8_length == cesu8_sz);
994 
995   jerry_release_value (args[0]);
996 
997   const jerry_char_t test_magic_str_access_src[] = "'console'.charAt(6) == 'e'";
998   res = jerry_eval (test_magic_str_access_src,
999                     sizeof (test_magic_str_access_src) - 1,
1000                     JERRY_PARSE_NO_OPTS);
1001   TEST_ASSERT (jerry_value_is_boolean (res));
1002   TEST_ASSERT (jerry_get_boolean_value (res) == true);
1003 
1004   jerry_release_value (res);
1005 
1006   cesu8_length = jerry_get_string_length (args[1]);
1007   cesu8_sz = jerry_get_string_size (args[1]);
1008 
1009   JERRY_VLA (char, string_greek_zero_sign, cesu8_sz);
1010   jerry_string_to_char_buffer (args[1], (jerry_char_t *) string_greek_zero_sign, cesu8_sz);
1011 
1012   TEST_ASSERT (!strncmp (string_greek_zero_sign, "\xed\xa0\x80\xed\xb6\x8a", cesu8_sz));
1013   TEST_ASSERT (cesu8_length == 2);
1014   TEST_ASSERT (cesu8_sz == 6);
1015 
1016   jerry_release_value (args[1]);
1017 
1018   {
1019     /*json parser check*/
1020     const char data_check[]="John";
1021     jerry_value_t key = jerry_create_string ((const jerry_char_t *) "name");
1022     const jerry_char_t data[] = "{\"name\": \"John\", \"age\": 5}";
1023     jerry_value_t parsed_json = jerry_json_parse (data, sizeof (data) - 1);
1024     jerry_value_t has_prop_js = jerry_has_property (parsed_json, key);
1025     TEST_ASSERT (jerry_get_boolean_value (has_prop_js));
1026     jerry_release_value (has_prop_js);
1027     jerry_value_t parsed_data = jerry_get_property (parsed_json, key);
1028     TEST_ASSERT (jerry_value_is_string (parsed_data) == true);
1029     jerry_size_t buff_size = jerry_get_string_size (parsed_data);
1030     JERRY_VLA (char, buff, buff_size + 1);
1031     jerry_string_to_char_buffer (parsed_data, (jerry_char_t *) buff, buff_size);
1032     buff[buff_size] = '\0';
1033     TEST_ASSERT (strcmp (data_check, buff) == false);
1034     jerry_release_value (parsed_json);
1035     jerry_release_value (key);
1036     jerry_release_value (parsed_data);
1037   }
1038 
1039   /*json stringify test*/
1040   {
1041     jerry_value_t obj = jerry_create_object ();
1042     char check_value[] = "{\"name\":\"John\"}";
1043     jerry_value_t key = jerry_create_string ((const jerry_char_t *) "name");
1044     jerry_value_t value = jerry_create_string ((const jerry_char_t *) "John");
1045     res = jerry_set_property (obj, key, value);
1046     TEST_ASSERT (!jerry_value_is_error (res));
1047     TEST_ASSERT (jerry_value_is_boolean (res) && jerry_get_boolean_value (res));
1048     jerry_release_value (res);
1049     jerry_value_t stringified = jerry_json_stringify (obj);
1050     TEST_ASSERT (jerry_value_is_string (stringified));
1051     jerry_size_t buff_size = jerry_get_string_size (stringified);
1052     JERRY_VLA (char, buff, buff_size + 1);
1053     jerry_string_to_char_buffer (stringified, (jerry_char_t *) buff, buff_size);
1054     buff[buff_size] = '\0';
1055     TEST_ASSERT (strcmp ((const char *) check_value, (const char *) buff)  == 0);
1056     jerry_release_value (stringified);
1057     jerry_release_value (obj);
1058     jerry_release_value (key);
1059     jerry_release_value (value);
1060   }
1061   jerry_cleanup ();
1062 
1063   return 0;
1064 } /* main */
1065