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