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 <stdio.h> 17 18#include "debugger.h" 19#include "ecma-alloc.h" 20#include "ecma-array-object.h" 21#include "ecma-arraybuffer-object.h" 22#include "ecma-builtin-helpers.h" 23#include "ecma-builtins.h" 24#include "ecma-comparison.h" 25#include "ecma-container-object.h" 26#include "ecma-dataview-object.h" 27#include "ecma-exceptions.h" 28#include "ecma-eval.h" 29#include "ecma-function-object.h" 30#include "ecma-gc.h" 31#include "ecma-helpers.h" 32#include "ecma-init-finalize.h" 33#include "ecma-lex-env.h" 34#include "lit-char-helpers.h" 35#include "ecma-literal-storage.h" 36#include "ecma-objects.h" 37#include "ecma-objects-general.h" 38#include "ecma-regexp-object.h" 39#include "ecma-promise-object.h" 40#include "ecma-proxy-object.h" 41#include "ecma-symbol-object.h" 42#include "ecma-typedarray-object.h" 43#include "opcodes.h" 44#include "jcontext.h" 45#include "jerryscript.h" 46#include "jerryscript-debugger-transport.h" 47#include "jmem.h" 48#include "js-parser.h" 49#include "re-compiler.h" 50 51#ifdef JERRY_FOR_IAR_CONFIG 52 53#include "config-gt.h" 54 55#endif 56 57#if defined(JERRY_REF_TRACKER) 58#include "tracker.h" 59#endif 60 61#if defined(JERRY_HEAPDUMP) 62#include "heapdump.h" 63#endif 64 65JERRY_STATIC_ASSERT (sizeof (jerry_value_t) == sizeof (ecma_value_t), 66 size_of_jerry_value_t_must_be_equal_to_size_of_ecma_value_t); 67 68JERRY_STATIC_ASSERT ((int) ECMA_ERROR_NONE == (int) JERRY_ERROR_NONE 69 && (int) ECMA_ERROR_COMMON == (int) JERRY_ERROR_COMMON 70 && (int) ECMA_ERROR_EVAL == (int) JERRY_ERROR_EVAL 71 && (int) ECMA_ERROR_RANGE == (int) JERRY_ERROR_RANGE 72 && (int) ECMA_ERROR_REFERENCE == (int) JERRY_ERROR_REFERENCE 73 && (int) ECMA_ERROR_SYNTAX == (int) JERRY_ERROR_SYNTAX 74 && (int) ECMA_ERROR_TYPE == (int) JERRY_ERROR_TYPE 75 && (int) ECMA_ERROR_URI == (int) JERRY_ERROR_URI, 76 ecma_standard_error_t_must_be_equal_to_jerry_error_t); 77 78JERRY_STATIC_ASSERT ((int) ECMA_INIT_EMPTY == (int) JERRY_INIT_EMPTY 79 && (int) ECMA_INIT_SHOW_OPCODES == (int) JERRY_INIT_SHOW_OPCODES 80 && (int) ECMA_INIT_SHOW_REGEXP_OPCODES == (int) JERRY_INIT_SHOW_REGEXP_OPCODES 81 && (int) ECMA_INIT_MEM_STATS == (int) JERRY_INIT_MEM_STATS, 82 ecma_init_flag_t_must_be_equal_to_jerry_init_flag_t); 83 84#if ENABLED (JERRY_BUILTIN_REGEXP) 85JERRY_STATIC_ASSERT ((int) RE_FLAG_GLOBAL == (int) JERRY_REGEXP_FLAG_GLOBAL 86 && (int) RE_FLAG_MULTILINE == (int) JERRY_REGEXP_FLAG_MULTILINE 87 && (int) RE_FLAG_IGNORE_CASE == (int) JERRY_REGEXP_FLAG_IGNORE_CASE, 88 re_flags_t_must_be_equal_to_jerry_regexp_flags_t); 89#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 90 91#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 92/* The internal ECMA_PROMISE_STATE_* values are "one byte away" from the API values */ 93JERRY_STATIC_ASSERT ((int) ECMA_PROMISE_IS_PENDING == (int) JERRY_PROMISE_STATE_PENDING 94 && (int) ECMA_PROMISE_IS_FULFILLED == (int) JERRY_PROMISE_STATE_FULFILLED, 95 promise_internal_state_matches_external); 96#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 97 98/** 99 * Offset between internal and external arithmetic operator types 100 */ 101#define ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET (JERRY_BIN_OP_SUB - NUMBER_ARITHMETIC_SUBTRACTION) 102 103JERRY_STATIC_ASSERT (((NUMBER_ARITHMETIC_SUBTRACTION + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_SUB) 104 && ((NUMBER_ARITHMETIC_MULTIPLICATION + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_MUL) 105 && ((NUMBER_ARITHMETIC_DIVISION + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_DIV) 106 && ((NUMBER_ARITHMETIC_REMAINDER + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_REM), 107 number_arithmetics_operation_type_matches_external); 108 109#if !ENABLED (JERRY_PARSER) && !ENABLED (JERRY_SNAPSHOT_EXEC) 110#error "JERRY_SNAPSHOT_EXEC must be enabled if JERRY_PARSER is disabled!" 111#endif /* !ENABLED (JERRY_PARSER) && !ENABLED (JERRY_SNAPSHOT_EXEC) */ 112 113#if ENABLED (JERRY_ERROR_MESSAGES) 114 115/** 116 * Error message, if an argument is has an error flag 117 */ 118static const char * const error_value_msg_p = "argument cannot have an error flag"; 119 120/** 121 * Error message, if types of arguments are incorrect 122 */ 123static const char * const wrong_args_msg_p = "wrong type of argument"; 124 125#endif /* ENABLED (JERRY_ERROR_MESSAGES) */ 126 127/** \addtogroup jerry Jerry engine interface 128 * @{ 129 */ 130 131/** 132 * Assert that it is correct to call API in current state. 133 * 134 * Note: 135 * By convention, there are some states when API could not be invoked. 136 * 137 * The API can be and only be invoked when the ECMA_STATUS_API_AVAILABLE 138 * flag is set. 139 * 140 * This procedure checks whether the API is available, and terminates 141 * the engine if it is unavailable. Otherwise it is a no-op. 142 * 143 * Note: 144 * The API could not be invoked in the following cases: 145 * - before jerry_init and after jerry_cleanup 146 * - between enter to and return from a native free callback 147 */ 148static inline void JERRY_ATTR_ALWAYS_INLINE 149jerry_assert_api_available (void) 150{ 151 JERRY_ASSERT (JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE); 152} /* jerry_assert_api_available */ 153 154/** 155 * Turn on API availability 156 */ 157static inline void JERRY_ATTR_ALWAYS_INLINE 158jerry_make_api_available (void) 159{ 160 JERRY_CONTEXT (status_flags) |= ECMA_STATUS_API_AVAILABLE; 161} /* jerry_make_api_available */ 162 163/** 164 * Turn off API availability 165 */ 166static inline void JERRY_ATTR_ALWAYS_INLINE 167jerry_make_api_unavailable (void) 168{ 169 JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_API_AVAILABLE; 170} /* jerry_make_api_unavailable */ 171 172/** 173 * Create an API compatible return value. 174 * 175 * @return return value for Jerry API functions 176 */ 177static jerry_value_t 178jerry_return (jerry_value_t value) /**< return value */ 179{ 180 if (ECMA_IS_VALUE_ERROR (value)) 181 { 182 value = ecma_create_error_reference_from_context (); 183 } 184 185 return value; 186} /* jerry_return */ 187 188/** 189 * Throw an API compatible return value. 190 * 191 * @return return value for Jerry API functions 192 */ 193static inline jerry_value_t JERRY_ATTR_ALWAYS_INLINE 194jerry_throw (jerry_value_t value) /**< return value */ 195{ 196 JERRY_ASSERT (ECMA_IS_VALUE_ERROR (value)); 197 return ecma_create_error_reference_from_context (); 198} /* jerry_throw */ 199 200#ifdef JERRY_FOR_IAR_CONFIG 201char* jerry_vla_malloc (uint32_t size) 202{ 203 char* ret; 204 ret = OhosMalloc (MEM_TYPE_JERRY, size); 205 if (!ret) 206 { 207 return NULL; 208 } 209 return ret; 210} 211 212void jerry_vla_free (char* p) 213{ 214 OhosFree (p); 215} 216#endif 217 218/** 219 * Jerry engine initialization 220 */ 221void 222jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */ 223{ 224#if defined(JERRY_REF_TRACKER) 225 InitTracker(); 226#endif 227 /* This function cannot be called twice unless jerry_cleanup is called. */ 228 JERRY_ASSERT (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE)); 229 230 /* Zero out all non-external members. */ 231 memset ((char *) &JERRY_CONTEXT_STRUCT + offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER), 0, 232 sizeof (jerry_context_t) - offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER)); 233 234 JERRY_CONTEXT (jerry_init_flags) = flags; 235 236 jerry_make_api_available (); 237 238 jmem_init (); 239 ecma_init (); 240} /* jerry_init */ 241 242/** 243 * Terminate Jerry engine 244 */ 245void 246jerry_cleanup (void) 247{ 248 ecma_gc_run(); 249 250 jerry_assert_api_available (); 251 252#if ENABLED (JERRY_DEBUGGER) 253 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 254 { 255 jerry_debugger_send_type (JERRY_DEBUGGER_CLOSE_CONNECTION); 256 257 jerry_debugger_transport_close (); 258 } 259#endif /* ENABLED (JERRY_DEBUGGER) */ 260 261 for (jerry_context_data_header_t *this_p = JERRY_CONTEXT (context_data_p); 262 this_p != NULL; 263 this_p = this_p->next_p) 264 { 265 if (this_p->manager_p->deinit_cb) 266 { 267 void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL; 268 this_p->manager_p->deinit_cb (data); 269 } 270 } 271 272#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 273 ecma_free_all_enqueued_jobs (); 274#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 275 ecma_finalize (); 276 jerry_make_api_unavailable (); 277 278 for (jerry_context_data_header_t *this_p = JERRY_CONTEXT (context_data_p), *next_p = NULL; 279 this_p != NULL; 280 this_p = next_p) 281 { 282 next_p = this_p->next_p; 283 if (this_p->manager_p->finalize_cb) 284 { 285 void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL; 286 this_p->manager_p->finalize_cb (data); 287 } 288 jmem_heap_free_block (this_p, sizeof (jerry_context_data_header_t) + this_p->manager_p->bytes_needed); 289 } 290 291 jmem_finalize (); 292} /* jerry_cleanup */ 293 294/** 295 * Retrieve a context data item, or create a new one. 296 * 297 * @param manager_p pointer to the manager whose context data item should be returned. 298 * 299 * @return a pointer to the user-provided context-specific data item for the given manager, creating such a pointer if 300 * none was found. 301 */ 302void * 303jerry_get_context_data (const jerry_context_data_manager_t *manager_p) 304{ 305 void *ret = NULL; 306 jerry_context_data_header_t *item_p; 307 308 for (item_p = JERRY_CONTEXT (context_data_p); item_p != NULL; item_p = item_p->next_p) 309 { 310 if (item_p->manager_p == manager_p) 311 { 312 return (manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p) : NULL; 313 } 314 } 315 316 item_p = jmem_heap_alloc_block (sizeof (jerry_context_data_header_t) + manager_p->bytes_needed); 317 item_p->manager_p = manager_p; 318 item_p->next_p = JERRY_CONTEXT (context_data_p); 319 JERRY_CONTEXT (context_data_p) = item_p; 320 321 if (manager_p->bytes_needed > 0) 322 { 323 ret = JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p); 324 memset (ret, 0, manager_p->bytes_needed); 325 } 326 327 if (manager_p->init_cb) 328 { 329 manager_p->init_cb (ret); 330 } 331 332 return ret; 333} /* jerry_get_context_data */ 334 335/** 336 * Register external magic string array 337 */ 338void 339jerry_register_magic_strings (const jerry_char_t * const *ex_str_items_p, /**< character arrays, representing 340 * external magic strings' contents */ 341 uint32_t count, /**< number of the strings */ 342 const jerry_length_t *str_lengths_p) /**< lengths of all strings */ 343{ 344 jerry_assert_api_available (); 345 346 lit_magic_strings_ex_set ((const lit_utf8_byte_t * const *) ex_str_items_p, 347 count, 348 (const lit_utf8_size_t *) str_lengths_p); 349} /* jerry_register_magic_strings */ 350 351/** 352 * Run garbage collection 353 */ 354void 355jerry_gc (jerry_gc_mode_t mode) /**< operational mode */ 356{ 357 jerry_assert_api_available (); 358 359 if (mode == JERRY_GC_PRESSURE_LOW) 360 { 361 /* Call GC directly, because 'ecma_free_unused_memory' might decide it's not yet worth it. */ 362 ecma_gc_run (); 363 return; 364 } 365 366 ecma_free_unused_memory (JMEM_PRESSURE_HIGH); 367} /* jerry_gc */ 368 369/** 370 * Get heap memory stats. 371 * 372 * @return true - get the heap stats successful 373 * false - otherwise. Usually it is because the MEM_STATS feature is not enabled. 374 */ 375bool 376jerry_get_memory_stats (jerry_heap_stats_t *out_stats_p) /**< [out] heap memory stats */ 377{ 378#if ENABLED (JERRY_MEM_STATS) 379 if (out_stats_p == NULL) 380 { 381 return false; 382 } 383 384 jmem_heap_stats_t jmem_heap_stats; 385 memset (&jmem_heap_stats, 0, sizeof (jmem_heap_stats)); 386 jmem_heap_get_stats (&jmem_heap_stats); 387 388 *out_stats_p = (jerry_heap_stats_t) 389 { 390 .version = 1, 391 .size = jmem_heap_stats.size, 392 .allocated_bytes = jmem_heap_stats.allocated_bytes, 393 .peak_allocated_bytes = jmem_heap_stats.peak_allocated_bytes 394 }; 395 396 return true; 397#else /* !ENABLED (JERRY_MEM_STATS) */ 398 JERRY_UNUSED (out_stats_p); 399 return false; 400#endif /* ENABLED (JERRY_MEM_STATS) */ 401} /* jerry_get_memory_stats */ 402 403/** 404 * Simple Jerry runner 405 * 406 * @return true - if run was successful 407 * false - otherwise 408 */ 409bool 410jerry_run_simple (const jerry_char_t *script_source_p, /**< script source */ 411 size_t script_source_size, /**< script source size */ 412 jerry_init_flag_t flags) /**< combination of Jerry flags */ 413{ 414 bool result = false; 415 416 jerry_init (flags); 417 418 jerry_value_t parse_ret_val = jerry_parse (NULL, 0, script_source_p, script_source_size, JERRY_PARSE_NO_OPTS); 419 420 if (!ecma_is_value_error_reference (parse_ret_val)) 421 { 422 jerry_value_t run_ret_val = jerry_run (parse_ret_val); 423 424 if (!ecma_is_value_error_reference (run_ret_val)) 425 { 426 result = true; 427 } 428 429 jerry_release_value (run_ret_val); 430 } 431 432 jerry_release_value (parse_ret_val); 433 jerry_cleanup (); 434 435 return result; 436} /* jerry_run_simple */ 437 438/** 439 * Parse script and construct an EcmaScript function. The lexical 440 * environment is set to the global lexical environment. 441 * 442 * @return function object value - if script was parsed successfully, 443 * thrown error - otherwise 444 */ 445jerry_value_t 446jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a file name) */ 447 size_t resource_name_length, /**< length of resource name */ 448 const jerry_char_t *source_p, /**< script source */ 449 size_t source_size, /**< script source size */ 450 uint32_t parse_opts) /**< jerry_parse_opts_t option bits */ 451{ 452#if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) 453 if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 454 && resource_name_length > 0) 455 { 456 jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME, 457 JERRY_DEBUGGER_NO_SUBTYPE, 458 resource_name_p, 459 resource_name_length); 460 } 461#else /* !(ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)) */ 462 JERRY_UNUSED (resource_name_p); 463 JERRY_UNUSED (resource_name_length); 464#endif /* ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) */ 465 466#if ENABLED (JERRY_PARSER) 467 jerry_assert_api_available (); 468 469#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) 470 if (resource_name_length == 0) 471 { 472 JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON); 473 } 474 else 475 { 476 JERRY_CONTEXT (resource_name) = ecma_find_or_create_literal_string (resource_name_p, 477 (lit_utf8_size_t) resource_name_length); 478 } 479#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 480 481 ecma_compiled_code_t *bytecode_data_p; 482 ecma_value_t parse_status; 483 484 parse_status = parser_parse_script (NULL, 485 0, 486 source_p, 487 source_size, 488 parse_opts, 489 &bytecode_data_p); 490 491 if (ECMA_IS_VALUE_ERROR (parse_status)) 492 { 493 return ecma_create_error_reference_from_context (); 494 } 495 496 ecma_free_value (parse_status); 497 498 ecma_object_t *lex_env_p = ecma_get_global_environment (); 499 ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p); 500 ecma_bytecode_deref (bytecode_data_p); 501 502 return ecma_make_object_value (func_obj_p); 503#else /* !ENABLED (JERRY_PARSER) */ 504 JERRY_UNUSED (source_p); 505 JERRY_UNUSED (source_size); 506 JERRY_UNUSED (parse_opts); 507 508 return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The parser has been disabled."))); 509#endif /* ENABLED (JERRY_PARSER) */ 510} /* jerry_parse */ 511 512/** 513 * Parse function and construct an EcmaScript function. The lexical 514 * environment is set to the global lexical environment. 515 * 516 * @return function object value - if script was parsed successfully, 517 * thrown error - otherwise 518 */ 519jerry_value_t 520jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (usually a file name) */ 521 size_t resource_name_length, /**< length of resource name */ 522 const jerry_char_t *arg_list_p, /**< script source */ 523 size_t arg_list_size, /**< script source size */ 524 const jerry_char_t *source_p, /**< script source */ 525 size_t source_size, /**< script source size */ 526 uint32_t parse_opts) /**< jerry_parse_opts_t option bits */ 527{ 528#if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) 529 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 530 { 531 jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME, 532 JERRY_DEBUGGER_NO_SUBTYPE, 533 resource_name_p, 534 resource_name_length); 535 } 536#else /* !(ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)) */ 537 JERRY_UNUSED (resource_name_p); 538 JERRY_UNUSED (resource_name_length); 539#endif /* ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) */ 540 541#if ENABLED (JERRY_PARSER) 542 jerry_assert_api_available (); 543 544 ecma_compiled_code_t *bytecode_data_p; 545 ecma_value_t parse_status; 546 547#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) 548 if (resource_name_length == 0) 549 { 550 JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON); 551 } 552 else 553 { 554 JERRY_CONTEXT (resource_name) = ecma_find_or_create_literal_string (resource_name_p, 555 (lit_utf8_size_t) resource_name_length); 556 } 557#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 558 559 if (arg_list_p == NULL) 560 { 561 /* Must not be a NULL value. */ 562 arg_list_p = (const jerry_char_t *) ""; 563 } 564 565 parse_status = parser_parse_script (arg_list_p, 566 arg_list_size, 567 source_p, 568 source_size, 569 parse_opts, 570 &bytecode_data_p); 571 572 if (ECMA_IS_VALUE_ERROR (parse_status)) 573 { 574 return ecma_create_error_reference_from_context (); 575 } 576 577 ecma_free_value (parse_status); 578 579 ecma_object_t *lex_env_p = ecma_get_global_environment (); 580 ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p); 581 ecma_bytecode_deref (bytecode_data_p); 582 583 return ecma_make_object_value (func_obj_p); 584#else /* !ENABLED (JERRY_PARSER) */ 585 JERRY_UNUSED (arg_list_p); 586 JERRY_UNUSED (arg_list_size); 587 JERRY_UNUSED (source_p); 588 JERRY_UNUSED (source_size); 589 JERRY_UNUSED (parse_opts); 590 591 return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The parser has been disabled."))); 592#endif /* ENABLED (JERRY_PARSER) */ 593} /* jerry_parse_function */ 594 595/** 596 * Run an EcmaScript function created by jerry_parse. 597 * 598 * Note: 599 * returned value must be freed with jerry_release_value, when it is no longer needed. 600 * 601 * @return result of bytecode - if run was successful 602 * thrown error - otherwise 603 */ 604jerry_value_t 605jerry_run (const jerry_value_t func_val) /**< function to run */ 606{ 607 jerry_assert_api_available (); 608 609 if (!ecma_is_value_object (func_val)) 610 { 611 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 612 } 613 614 ecma_object_t *func_obj_p = ecma_get_object_from_value (func_val); 615 616 if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_FUNCTION 617 || ecma_get_object_is_builtin (func_obj_p)) 618 { 619 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 620 } 621 622 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p; 623 624 ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, 625 ext_func_p->u.function.scope_cp); 626 627 if (scope_p != ecma_get_global_environment ()) 628 { 629 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 630 } 631 632 return jerry_return (vm_run_global (ecma_op_function_get_compiled_code (ext_func_p))); 633} /* jerry_run */ 634 635/** 636 * Perform eval 637 * 638 * Note: 639 * returned value must be freed with jerry_release_value, when it is no longer needed. 640 * 641 * @return result of eval, may be error value. 642 */ 643jerry_value_t 644jerry_eval (const jerry_char_t *source_p, /**< source code */ 645 size_t source_size, /**< length of source code */ 646 uint32_t parse_opts) /**< jerry_parse_opts_t option bits */ 647{ 648 jerry_assert_api_available (); 649 650 return jerry_return (ecma_op_eval_chars_buffer ((const lit_utf8_byte_t *) source_p, 651 source_size, 652 parse_opts)); 653} /* jerry_eval */ 654 655/** 656 * Run enqueued Promise jobs until the first thrown error or until all get executed. 657 * 658 * Note: 659 * returned value must be freed with jerry_release_value, when it is no longer needed. 660 * 661 * @return result of last executed job, may be error value. 662 */ 663jerry_value_t 664jerry_run_all_enqueued_jobs (void) 665{ 666 jerry_assert_api_available (); 667 668#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 669 return ecma_process_all_enqueued_jobs (); 670#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 671 return ECMA_VALUE_UNDEFINED; 672#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 673} /* jerry_run_all_enqueued_jobs */ 674 675/** 676 * Get global object 677 * 678 * Note: 679 * returned value must be freed with jerry_release_value, when it is no longer needed. 680 * 681 * @return api value of global object 682 */ 683jerry_value_t 684jerry_get_global_object (void) 685{ 686 jerry_assert_api_available (); 687 ecma_object_t *global_obj_p = ecma_builtin_get_global (); 688 ecma_ref_object (global_obj_p); 689 return ecma_make_object_value (global_obj_p); 690} /* jerry_get_global_object */ 691 692/** 693 * Check if the specified value is an abort value. 694 * 695 * @return true - if both the error and abort values are set, 696 * false - otherwise 697 */ 698bool 699jerry_value_is_abort (const jerry_value_t value) /**< api value */ 700{ 701 jerry_assert_api_available (); 702 703 if (!ecma_is_value_error_reference (value)) 704 { 705 return false; 706 } 707 708 ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value); 709 710 return (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT) != 0; 711} /* jerry_value_is_abort */ 712 713/** 714 * Check if the specified value is an array object value. 715 * 716 * @return true - if the specified value is an array object, 717 * false - otherwise 718 */ 719bool 720jerry_value_is_array (const jerry_value_t value) /**< jerry api value */ 721{ 722 jerry_assert_api_available (); 723 724 return (ecma_is_value_object (value) 725 && ecma_get_object_type (ecma_get_object_from_value (value)) == ECMA_OBJECT_TYPE_ARRAY); 726} /* jerry_value_is_array */ 727 728/** 729 * Check if the specified value is boolean. 730 * 731 * @return true - if the specified value is boolean, 732 * false - otherwise 733 */ 734bool 735jerry_value_is_boolean (const jerry_value_t value) /**< api value */ 736{ 737 jerry_assert_api_available (); 738 739 return ecma_is_value_boolean (value); 740} /* jerry_value_is_boolean */ 741 742/** 743 * Check if the specified value is a constructor function object value. 744 * 745 * @return true - if the specified value is a function value that implements [[Construct]], 746 * false - otherwise 747 */ 748bool 749jerry_value_is_constructor (const jerry_value_t value) /**< jerry api value */ 750{ 751 jerry_assert_api_available (); 752 753 return ecma_is_constructor (value); 754} /* jerry_value_is_constructor */ 755 756/** 757 * Check if the specified value is an error or abort value. 758 * 759 * @return true - if the specified value is an error value, 760 * false - otherwise 761 */ 762bool 763jerry_value_is_error (const jerry_value_t value) /**< api value */ 764{ 765 jerry_assert_api_available (); 766 767 return ecma_is_value_error_reference (value); 768} /* jerry_value_is_error */ 769 770/** 771 * Check if the specified value is a function object value. 772 * 773 * @return true - if the specified value is callable, 774 * false - otherwise 775 */ 776bool 777jerry_value_is_function (const jerry_value_t value) /**< api value */ 778{ 779 jerry_assert_api_available (); 780 781 return ecma_op_is_callable (value); 782} /* jerry_value_is_function */ 783 784/** 785 * Check if the specified value is number. 786 * 787 * @return true - if the specified value is number, 788 * false - otherwise 789 */ 790bool 791jerry_value_is_number (const jerry_value_t value) /**< api value */ 792{ 793 jerry_assert_api_available (); 794 795 return ecma_is_value_number (value); 796} /* jerry_value_is_number */ 797 798/** 799 * Check if the specified value is null. 800 * 801 * @return true - if the specified value is null, 802 * false - otherwise 803 */ 804bool 805jerry_value_is_null (const jerry_value_t value) /**< api value */ 806{ 807 jerry_assert_api_available (); 808 809 return ecma_is_value_null (value); 810} /* jerry_value_is_null */ 811 812/** 813 * Check if the specified value is object. 814 * 815 * @return true - if the specified value is object, 816 * false - otherwise 817 */ 818bool 819jerry_value_is_object (const jerry_value_t value) /**< api value */ 820{ 821 jerry_assert_api_available (); 822 823 return ecma_is_value_object (value); 824} /* jerry_value_is_object */ 825 826/** 827 * Check if the specified value is promise. 828 * 829 * @return true - if the specified value is promise, 830 * false - otherwise 831 */ 832bool 833jerry_value_is_promise (const jerry_value_t value) /**< api value */ 834{ 835 jerry_assert_api_available (); 836#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 837 return (ecma_is_value_object (value) 838 && ecma_is_promise (ecma_get_object_from_value (value))); 839#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 840 JERRY_UNUSED (value); 841 return false; 842#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 843} /* jerry_value_is_promise */ 844 845/** 846 * Check if the specified value is a proxy object. 847 * 848 * @return true - if the specified value is a proxy object, 849 * false - otherwise 850 */ 851bool 852jerry_value_is_proxy (const jerry_value_t value) /**< api value */ 853{ 854 jerry_assert_api_available (); 855#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 856 return (ecma_is_value_object (value) 857 && ECMA_OBJECT_IS_PROXY (ecma_get_object_from_value (value))); 858#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 859 JERRY_UNUSED (value); 860 return false; 861#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 862} /* jerry_value_is_proxy */ 863 864/** 865 * Check if the specified value is string. 866 * 867 * @return true - if the specified value is string, 868 * false - otherwise 869 */ 870bool 871jerry_value_is_string (const jerry_value_t value) /**< api value */ 872{ 873 jerry_assert_api_available (); 874 875 return ecma_is_value_string (value); 876} /* jerry_value_is_string */ 877 878/** 879 * Check if the specified value is symbol. 880 * 881 * @return true - if the specified value is symbol, 882 * false - otherwise 883 */ 884bool 885jerry_value_is_symbol (const jerry_value_t value) /**< api value */ 886{ 887 jerry_assert_api_available (); 888 889#if ENABLED (JERRY_ES2015) 890 return ecma_is_value_symbol (value); 891#else /* !ENABLED (JERRY_ES2015) */ 892 JERRY_UNUSED (value); 893 return false; 894#endif /* ENABLED (JERRY_ES2015) */ 895} /* jerry_value_is_symbol */ 896 897/** 898 * Check if the specified value is undefined. 899 * 900 * @return true - if the specified value is undefined, 901 * false - otherwise 902 */ 903bool 904jerry_value_is_undefined (const jerry_value_t value) /**< api value */ 905{ 906 jerry_assert_api_available (); 907 908 return ecma_is_value_undefined (value); 909} /* jerry_value_is_undefined */ 910 911/** 912 * Perform the base type of the JavaScript value. 913 * 914 * @return jerry_type_t value 915 */ 916jerry_type_t 917jerry_value_get_type (const jerry_value_t value) /**< input value to check */ 918{ 919 jerry_assert_api_available (); 920 921 if (ecma_is_value_error_reference (value)) 922 { 923 return JERRY_TYPE_ERROR; 924 } 925 926 lit_magic_string_id_t lit_id = ecma_get_typeof_lit_id (value); 927 928 JERRY_ASSERT (lit_id != LIT_MAGIC_STRING__EMPTY); 929 930 switch (lit_id) 931 { 932 case LIT_MAGIC_STRING_UNDEFINED: 933 { 934 return JERRY_TYPE_UNDEFINED; 935 } 936 case LIT_MAGIC_STRING_BOOLEAN: 937 { 938 return JERRY_TYPE_BOOLEAN; 939 } 940 case LIT_MAGIC_STRING_NUMBER: 941 { 942 return JERRY_TYPE_NUMBER; 943 } 944 case LIT_MAGIC_STRING_STRING: 945 { 946 return JERRY_TYPE_STRING; 947 } 948#if ENABLED (JERRY_ES2015) 949 case LIT_MAGIC_STRING_SYMBOL: 950 { 951 return JERRY_TYPE_SYMBOL; 952 } 953#endif /* ENABLED (JERRY_ES2015) */ 954 case LIT_MAGIC_STRING_FUNCTION: 955 { 956 return JERRY_TYPE_FUNCTION; 957 } 958 default: 959 { 960 JERRY_ASSERT (lit_id == LIT_MAGIC_STRING_OBJECT); 961 962 /* Based on the ECMA 262 5.1 standard the 'null' value is an object. 963 * Thus we'll do an extra check for 'null' here. 964 */ 965 return ecma_is_value_null (value) ? JERRY_TYPE_NULL : JERRY_TYPE_OBJECT; 966 } 967 } 968} /* jerry_value_get_type */ 969 970/** 971 * Check if the specified feature is enabled. 972 * 973 * @return true - if the specified feature is enabled, 974 * false - otherwise 975 */ 976bool 977jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check */ 978{ 979 JERRY_ASSERT (feature < JERRY_FEATURE__COUNT); 980 981 return (false 982#if ENABLED (JERRY_CPOINTER_32_BIT) 983 || feature == JERRY_FEATURE_CPOINTER_32_BIT 984#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 985#if ENABLED (JERRY_ERROR_MESSAGES) 986 || feature == JERRY_FEATURE_ERROR_MESSAGES 987#endif /* ENABLED (JERRY_ERROR_MESSAGES) */ 988#if ENABLED (JERRY_PARSER) 989 || feature == JERRY_FEATURE_JS_PARSER 990#endif /* ENABLED (JERRY_PARSER) */ 991#if ENABLED (JERRY_MEM_STATS) 992 || feature == JERRY_FEATURE_MEM_STATS 993#endif /* ENABLED (JERRY_MEM_STATS) */ 994#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) 995 || feature == JERRY_FEATURE_PARSER_DUMP 996#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ 997#if ENABLED (JERRY_REGEXP_DUMP_BYTE_CODE) 998 || feature == JERRY_FEATURE_REGEXP_DUMP 999#endif /* ENABLED (JERRY_REGEXP_DUMP_BYTE_CODE) */ 1000#if ENABLED (JERRY_SNAPSHOT_SAVE) 1001 || feature == JERRY_FEATURE_SNAPSHOT_SAVE 1002#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */ 1003#if ENABLED (JERRY_SNAPSHOT_EXEC) 1004 || feature == JERRY_FEATURE_SNAPSHOT_EXEC 1005#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ 1006#if ENABLED (JERRY_DEBUGGER) 1007 || feature == JERRY_FEATURE_DEBUGGER 1008#endif /* ENABLED (JERRY_DEBUGGER) */ 1009#if ENABLED (JERRY_VM_EXEC_STOP) 1010 || feature == JERRY_FEATURE_VM_EXEC_STOP 1011#endif /* ENABLED (JERRY_VM_EXEC_STOP) */ 1012#if ENABLED (JERRY_BUILTIN_JSON) 1013 || feature == JERRY_FEATURE_JSON 1014#endif /* ENABLED (JERRY_BUILTIN_JSON) */ 1015#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 1016 || feature == JERRY_FEATURE_PROMISE 1017#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 1018#if ENABLED (JERRY_ES2015) 1019 || feature == JERRY_FEATURE_SYMBOL 1020#endif /* ENABLED (JERRY_ES2015) */ 1021#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 1022 || feature == JERRY_FEATURE_TYPEDARRAY 1023#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 1024#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) 1025 || feature == JERRY_FEATURE_DATAVIEW 1026#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */ 1027#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1028 || feature == JERRY_FEATURE_PROXY 1029#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1030#if ENABLED (JERRY_BUILTIN_DATE) 1031 || feature == JERRY_FEATURE_DATE 1032#endif /* ENABLED (JERRY_BUILTIN_DATE) */ 1033#if ENABLED (JERRY_BUILTIN_REGEXP) 1034 || feature == JERRY_FEATURE_REGEXP 1035#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 1036#if ENABLED (JERRY_LINE_INFO) 1037 || feature == JERRY_FEATURE_LINE_INFO 1038#endif /* ENABLED (JERRY_LINE_INFO) */ 1039#if ENABLED (JERRY_LOGGING) 1040 || feature == JERRY_FEATURE_LOGGING 1041#endif /* ENABLED (JERRY_LOGGING) */ 1042#if ENABLED (JERRY_ES2015_BUILTIN_MAP) 1043 || feature == JERRY_FEATURE_MAP 1044#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ 1045#if ENABLED (JERRY_ES2015_BUILTIN_SET) 1046 || feature == JERRY_FEATURE_SET 1047#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ 1048#if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) 1049 || feature == JERRY_FEATURE_WEAKMAP 1050#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */ 1051#if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) 1052 || feature == JERRY_FEATURE_WEAKSET 1053#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */ 1054 ); 1055} /* jerry_is_feature_enabled */ 1056 1057/** 1058 * Perform binary operation on the given operands (==, ===, <, >, etc.). 1059 * 1060 * @return error - if argument has an error flag or operation is unsuccessful or unsupported 1061 * true/false - the result of the binary operation on the given operands otherwise 1062 */ 1063jerry_value_t 1064jerry_binary_operation (jerry_binary_operation_t op, /**< operation */ 1065 const jerry_value_t lhs, /**< first operand */ 1066 const jerry_value_t rhs) /**< second operand */ 1067{ 1068 jerry_assert_api_available (); 1069 1070 if (ecma_is_value_error_reference (lhs) || ecma_is_value_error_reference (rhs)) 1071 { 1072 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 1073 } 1074 1075 switch (op) 1076 { 1077 case JERRY_BIN_OP_EQUAL: 1078 { 1079 return jerry_return (ecma_op_abstract_equality_compare (lhs, rhs)); 1080 } 1081 case JERRY_BIN_OP_STRICT_EQUAL: 1082 { 1083 return ecma_make_boolean_value (ecma_op_strict_equality_compare (lhs, rhs)); 1084 } 1085 case JERRY_BIN_OP_LESS: 1086 { 1087 return jerry_return (opfunc_relation (lhs, rhs, true, false)); 1088 } 1089 case JERRY_BIN_OP_LESS_EQUAL: 1090 { 1091 return jerry_return (opfunc_relation (lhs, rhs, false, true)); 1092 } 1093 case JERRY_BIN_OP_GREATER: 1094 { 1095 return jerry_return (opfunc_relation (lhs, rhs, false, false)); 1096 } 1097 case JERRY_BIN_OP_GREATER_EQUAL: 1098 { 1099 return jerry_return (opfunc_relation (lhs, rhs, true, true)); 1100 } 1101 case JERRY_BIN_OP_INSTANCEOF: 1102 { 1103 if (!ecma_is_value_object (lhs) 1104 || !ecma_op_is_callable (rhs)) 1105 { 1106 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 1107 } 1108 1109 ecma_object_t *proto_obj_p = ecma_get_object_from_value (rhs); 1110 return jerry_return (ecma_op_object_has_instance (proto_obj_p, lhs)); 1111 } 1112 case JERRY_BIN_OP_ADD: 1113 { 1114 return jerry_return (opfunc_addition (lhs, rhs)); 1115 } 1116 case JERRY_BIN_OP_SUB: 1117 case JERRY_BIN_OP_MUL: 1118 case JERRY_BIN_OP_DIV: 1119 case JERRY_BIN_OP_REM: 1120 { 1121 return jerry_return (do_number_arithmetic (op - ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET, lhs, rhs)); 1122 } 1123 default: 1124 { 1125 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Unsupported binary operation"))); 1126 } 1127 } 1128} /* jerry_binary_operation */ 1129 1130/** 1131 * Create abort from an api value. 1132 * 1133 * Create abort value from an api value. If the second argument is true 1134 * it will release the input api value. 1135 * 1136 * @return api abort value 1137 */ 1138jerry_value_t 1139jerry_create_abort_from_value (jerry_value_t value, /**< api value */ 1140 bool release) /**< release api value */ 1141{ 1142 jerry_assert_api_available (); 1143 1144 if (JERRY_UNLIKELY (ecma_is_value_error_reference (value))) 1145 { 1146 /* This is a rare case so it is optimized for 1147 * binary size rather than performance. */ 1148 if (jerry_value_is_abort (value)) 1149 { 1150 return release ? value : jerry_acquire_value (value); 1151 } 1152 1153 value = jerry_get_value_from_error (value, release); 1154 release = true; 1155 } 1156 1157 if (!release) 1158 { 1159 value = ecma_copy_value (value); 1160 } 1161 1162 return ecma_create_error_reference (value, false); 1163} /* jerry_create_abort_from_value */ 1164 1165/** 1166 * Create error from an api value. 1167 * 1168 * Create error value from an api value. If the second argument is true 1169 * it will release the input api value. 1170 * 1171 * @return api error value 1172 */ 1173jerry_value_t 1174jerry_create_error_from_value (jerry_value_t value, /**< api value */ 1175 bool release) /**< release api value */ 1176{ 1177 jerry_assert_api_available (); 1178 1179 if (JERRY_UNLIKELY (ecma_is_value_error_reference (value))) 1180 { 1181 /* This is a rare case so it is optimized for 1182 * binary size rather than performance. */ 1183 if (!jerry_value_is_abort (value)) 1184 { 1185 return release ? value : jerry_acquire_value (value); 1186 } 1187 1188 value = jerry_get_value_from_error (value, release); 1189 release = true; 1190 } 1191 1192 if (!release) 1193 { 1194 value = ecma_copy_value (value); 1195 } 1196 1197 return ecma_create_error_reference (value, true); 1198} /* jerry_create_error_from_value */ 1199 1200/** 1201 * Get the value from an error value. 1202 * 1203 * Extract the api value from an error. If the second argument is true 1204 * it will release the input error value. 1205 * 1206 * Note: 1207 * returned value must be freed with jerry_release_value, when it is no longer needed. 1208 * 1209 * @return jerry_value_t value 1210 */ 1211jerry_value_t 1212jerry_get_value_from_error (jerry_value_t value, /**< api value */ 1213 bool release) /**< release api value */ 1214{ 1215 jerry_assert_api_available (); 1216 1217 if (!ecma_is_value_error_reference (value)) 1218 { 1219 return release ? value : ecma_copy_value (value); 1220 } 1221 1222 jerry_value_t ret_val = jerry_acquire_value (ecma_get_error_reference_from_value (value)->value); 1223 1224 if (release) 1225 { 1226 jerry_release_value (value); 1227 } 1228 return ret_val; 1229} /* jerry_get_value_from_error */ 1230 1231/** 1232 * Return the type of the Error object if possible. 1233 * 1234 * @return one of the jerry_error_t value as the type of the Error object 1235 * JERRY_ERROR_NONE - if the input value is not an Error object 1236 */ 1237jerry_error_t 1238jerry_get_error_type (jerry_value_t value) /**< api value */ 1239{ 1240 if (JERRY_UNLIKELY (ecma_is_value_error_reference (value))) 1241 { 1242 value = ecma_get_error_reference_from_value (value)->value; 1243 } 1244 1245 if (!ecma_is_value_object (value)) 1246 { 1247 return JERRY_ERROR_NONE; 1248 } 1249 1250 ecma_object_t *object_p = ecma_get_object_from_value (value); 1251 ecma_standard_error_t error_type = ecma_get_error_type (object_p); 1252 1253 return (jerry_error_t) error_type; 1254} /* jerry_get_error_type */ 1255 1256/** 1257 * Get boolean from the specified value. 1258 * 1259 * @return true or false. 1260 */ 1261bool 1262jerry_get_boolean_value (const jerry_value_t value) /**< api value */ 1263{ 1264 jerry_assert_api_available (); 1265 1266 return ecma_is_value_true (value); 1267} /* jerry_get_boolean_value */ 1268 1269/** 1270 * Get number from the specified value as a double. 1271 * 1272 * @return stored number as double 1273 */ 1274double 1275jerry_get_number_value (const jerry_value_t value) /**< api value */ 1276{ 1277 jerry_assert_api_available (); 1278 1279 if (!ecma_is_value_number (value)) 1280 { 1281 return 0; 1282 } 1283 1284 return (double) ecma_get_number_from_value (value); 1285} /* jerry_get_number_value */ 1286 1287/** 1288 * Call ToBoolean operation on the api value. 1289 * 1290 * @return true - if the logical value is true 1291 * false - otherwise 1292 */ 1293bool 1294jerry_value_to_boolean (const jerry_value_t value) /**< input value */ 1295{ 1296 jerry_assert_api_available (); 1297 1298 if (ecma_is_value_error_reference (value)) 1299 { 1300 return false; 1301 } 1302 1303 return ecma_op_to_boolean (value); 1304} /* jerry_value_to_boolean */ 1305 1306/** 1307 * Call ToNumber operation on the api value. 1308 * 1309 * Note: 1310 * returned value must be freed with jerry_release_value, when it is no longer needed. 1311 * 1312 * @return converted number value - if success 1313 * thrown error - otherwise 1314 */ 1315jerry_value_t 1316jerry_value_to_number (const jerry_value_t value) /**< input value */ 1317{ 1318 jerry_assert_api_available (); 1319 1320 if (ecma_is_value_error_reference (value)) 1321 { 1322 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 1323 } 1324 1325 return jerry_return (ecma_op_to_number (value)); 1326} /* jerry_value_to_number */ 1327 1328/** 1329 * Call ToObject operation on the api value. 1330 * 1331 * Note: 1332 * returned value must be freed with jerry_release_value, when it is no longer needed. 1333 * 1334 * @return converted object value - if success 1335 * thrown error - otherwise 1336 */ 1337jerry_value_t 1338jerry_value_to_object (const jerry_value_t value) /**< input value */ 1339{ 1340 jerry_assert_api_available (); 1341 1342 if (ecma_is_value_error_reference (value)) 1343 { 1344 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 1345 } 1346 1347 return jerry_return (ecma_op_to_object (value)); 1348} /* jerry_value_to_object */ 1349 1350/** 1351 * Call ToPrimitive operation on the api value. 1352 * 1353 * Note: 1354 * returned value must be freed with jerry_release_value, when it is no longer needed. 1355 * 1356 * @return converted primitive value - if success 1357 * thrown error - otherwise 1358 */ 1359jerry_value_t 1360jerry_value_to_primitive (const jerry_value_t value) /**< input value */ 1361{ 1362 jerry_assert_api_available (); 1363 1364 if (ecma_is_value_error_reference (value)) 1365 { 1366 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 1367 } 1368 1369 return jerry_return (ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NO)); 1370} /* jerry_value_to_primitive */ 1371 1372/** 1373 * Call the ToString ecma builtin operation on the api value. 1374 * 1375 * Note: 1376 * returned value must be freed with jerry_release_value, when it is no longer needed. 1377 * 1378 * @return converted string value - if success 1379 * thrown error - otherwise 1380 */ 1381jerry_value_t 1382jerry_value_to_string (const jerry_value_t value) /**< input value */ 1383{ 1384 1385 jerry_assert_api_available (); 1386 1387 if (ecma_is_value_error_reference (value)) 1388 { 1389 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 1390 } 1391 1392 ecma_string_t *str_p = ecma_op_to_string (value); 1393 if (JERRY_UNLIKELY (str_p == NULL)) 1394 { 1395 return ecma_create_error_reference_from_context (); 1396 } 1397 1398 return jerry_return (ecma_make_string_value (str_p)); 1399} /* jerry_value_to_string */ 1400 1401/** 1402 * Acquire specified Jerry API value. 1403 * 1404 * Note: 1405 * returned value must be freed with jerry_release_value, when it is no longer needed. 1406 * 1407 * @return acquired api value 1408 */ 1409jerry_value_t 1410jerry_acquire_value (jerry_value_t value) /**< API value */ 1411{ 1412 jerry_assert_api_available (); 1413 1414 if (JERRY_UNLIKELY (ecma_is_value_error_reference (value))) 1415 { 1416 ecma_ref_error_reference (ecma_get_error_reference_from_value (value)); 1417 return value; 1418 } 1419 1420 return ecma_copy_value (value); 1421} /* jerry_acquire_value */ 1422 1423/** 1424 * Release specified Jerry API value 1425 */ 1426void 1427jerry_release_value (jerry_value_t value) /**< API value */ 1428{ 1429 jerry_assert_api_available (); 1430 1431 if (JERRY_UNLIKELY (ecma_is_value_error_reference (value))) 1432 { 1433 ecma_deref_error_reference (ecma_get_error_reference_from_value (value)); 1434 return; 1435 } 1436 1437 ecma_free_value (value); 1438} /* jerry_release_value */ 1439 1440/** 1441 * Create an array object value 1442 * 1443 * Note: 1444 * returned value must be freed with jerry_release_value, when it is no longer needed. 1445 * 1446 * @return value of the constructed array object 1447 */ 1448jerry_value_t 1449jerry_create_array (uint32_t size) /**< size of array */ 1450{ 1451 jerry_assert_api_available (); 1452 1453 ecma_value_t array_length = ecma_make_uint32_value (size); 1454 1455 const jerry_length_t argument_size = 1; 1456 ecma_value_t array_value = ecma_op_create_array_object (&array_length, argument_size, true); 1457 ecma_free_value (array_length); 1458 1459 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value)); 1460 1461 return array_value; 1462} /* jerry_create_array */ 1463 1464/** 1465 * Create a jerry_value_t representing a boolean value from the given boolean parameter. 1466 * 1467 * @return value of the created boolean 1468 */ 1469jerry_value_t 1470jerry_create_boolean (bool value) /**< bool value from which a jerry_value_t will be created */ 1471{ 1472 jerry_assert_api_available (); 1473 1474 return jerry_return (ecma_make_boolean_value (value)); 1475} /* jerry_create_boolean */ 1476 1477/** 1478 * Create an error object 1479 * 1480 * Note: 1481 * - returned value must be freed with jerry_release_value, when it is no longer needed 1482 * - the error flag is set for the returned value 1483 * 1484 * @return value of the constructed error object 1485 */ 1486jerry_value_t 1487jerry_create_error (jerry_error_t error_type, /**< type of error */ 1488 const jerry_char_t *message_p) /**< value of 'message' property 1489 * of constructed error object */ 1490{ 1491 return jerry_create_error_sz (error_type, 1492 (lit_utf8_byte_t *) message_p, 1493 lit_zt_utf8_string_size (message_p)); 1494} /* jerry_create_error */ 1495 1496/** 1497 * Create an error object 1498 * 1499 * Note: 1500 * - returned value must be freed with jerry_release_value, when it is no longer needed 1501 * - the error flag is set for the returned value 1502 * 1503 * @return value of the constructed error object 1504 */ 1505jerry_value_t 1506jerry_create_error_sz (jerry_error_t error_type, /**< type of error */ 1507 const jerry_char_t *message_p, /**< value of 'message' property 1508 * of constructed error object */ 1509 jerry_size_t message_size) /**< size of the message in bytes */ 1510{ 1511 jerry_assert_api_available (); 1512 1513 if (message_p == NULL || message_size == 0) 1514 { 1515 return ecma_create_error_object_reference (ecma_new_standard_error ((ecma_standard_error_t) error_type)); 1516 } 1517 else 1518 { 1519 ecma_string_t *message_string_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) message_p, 1520 (lit_utf8_size_t) message_size); 1521 1522 ecma_object_t *error_object_p = ecma_new_standard_error_with_message ((ecma_standard_error_t) error_type, 1523 message_string_p); 1524 1525 ecma_deref_ecma_string (message_string_p); 1526 1527 return ecma_create_error_object_reference (error_object_p); 1528 } 1529} /* jerry_create_error_sz */ 1530 1531/** 1532 * Create an external function object 1533 * 1534 * Note: 1535 * returned value must be freed with jerry_release_value, when it is no longer needed. 1536 * 1537 * @return value of the constructed function object 1538 */ 1539jerry_value_t 1540jerry_create_external_function (jerry_external_handler_t handler_p) /**< pointer to native handler 1541 * for the function */ 1542{ 1543 jerry_assert_api_available (); 1544 1545 ecma_object_t *func_obj_p = ecma_op_create_external_function_object (handler_p); 1546 return ecma_make_object_value (func_obj_p); 1547} /* jerry_create_external_function */ 1548 1549/** 1550 * Creates a jerry_value_t representing a number value. 1551 * 1552 * Note: 1553 * returned value must be freed with jerry_release_value, when it is no longer needed. 1554 * 1555 * @return jerry_value_t created from the given double argument. 1556 */ 1557jerry_value_t 1558jerry_create_number (double value) /**< double value from which a jerry_value_t will be created */ 1559{ 1560 jerry_assert_api_available (); 1561 1562 return ecma_make_number_value ((ecma_number_t) value); 1563} /* jerry_create_number */ 1564 1565/** 1566 * Creates a jerry_value_t representing a positive or negative infinity value. 1567 * 1568 * Note: 1569 * returned value must be freed with jerry_release_value, when it is no longer needed. 1570 * 1571 * @return jerry_value_t representing an infinity value. 1572 */ 1573jerry_value_t 1574jerry_create_number_infinity (bool sign) /**< true for negative Infinity 1575 * false for positive Infinity */ 1576{ 1577 jerry_assert_api_available (); 1578 1579 return ecma_make_number_value (ecma_number_make_infinity (sign)); 1580} /* jerry_create_number_infinity */ 1581 1582/** 1583 * Creates a jerry_value_t representing a not-a-number value. 1584 * 1585 * Note: 1586 * returned value must be freed with jerry_release_value, when it is no longer needed. 1587 * 1588 * @return jerry_value_t representing a not-a-number value. 1589 */ 1590jerry_value_t 1591jerry_create_number_nan (void) 1592{ 1593 jerry_assert_api_available (); 1594 1595 return ecma_make_nan_value (); 1596} /* jerry_create_number_nan */ 1597 1598/** 1599 * Creates a jerry_value_t representing an undefined value. 1600 * 1601 * @return value of undefined 1602 */ 1603jerry_value_t 1604jerry_create_undefined (void) 1605{ 1606 jerry_assert_api_available (); 1607 1608 return ECMA_VALUE_UNDEFINED; 1609} /* jerry_create_undefined */ 1610 1611/** 1612 * Creates and returns a jerry_value_t with type null object. 1613 * 1614 * @return jerry_value_t representing null 1615 */ 1616jerry_value_t 1617jerry_create_null (void) 1618{ 1619 jerry_assert_api_available (); 1620 1621 return ECMA_VALUE_NULL; 1622} /* jerry_create_null */ 1623 1624/** 1625 * Create new JavaScript object, like with new Object(). 1626 * 1627 * Note: 1628 * returned value must be freed with jerry_release_value, when it is no longer needed. 1629 * 1630 * @return value of the created object 1631 */ 1632jerry_value_t 1633jerry_create_object (void) 1634{ 1635 jerry_assert_api_available (); 1636 1637 return ecma_make_object_value (ecma_op_create_object_object_noarg ()); 1638} /* jerry_create_object */ 1639 1640/** 1641 * Create an empty Promise object which can be resolve/reject later 1642 * by calling jerry_resolve_or_reject_promise. 1643 * 1644 * Note: 1645 * returned value must be freed with jerry_release_value, when it is no longer needed. 1646 * 1647 * @return value of the created object 1648 */ 1649jerry_value_t 1650jerry_create_promise (void) 1651{ 1652 jerry_assert_api_available (); 1653 1654#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 1655 ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target); 1656 1657 if (old_new_target_p == NULL) 1658 { 1659 JERRY_CONTEXT (current_new_target) = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE); 1660 } 1661 1662 ecma_value_t promise_value = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_PROMISE_EXECUTOR_EMPTY); 1663 1664 JERRY_CONTEXT (current_new_target) = old_new_target_p; 1665 return promise_value; 1666#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 1667 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported."))); 1668#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 1669} /* jerry_create_promise */ 1670 1671/** 1672 * Create a new Proxy object with the given target and handler 1673 * 1674 * Note: 1675 * returned value must be freed with jerry_release_value, when it is no longer needed. 1676 * 1677 * @return value of the created Proxy object 1678 */ 1679jerry_value_t 1680jerry_create_proxy (const jerry_value_t target, /**< target argument */ 1681 const jerry_value_t handler) /**< handler argument */ 1682{ 1683 jerry_assert_api_available (); 1684 1685 if (ecma_is_value_error_reference (target) 1686 || ecma_is_value_error_reference (handler)) 1687 { 1688 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 1689 } 1690 1691#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1692 ecma_object_t *proxy_p = ecma_proxy_create (target, handler); 1693 return jerry_return (proxy_p == NULL ? ECMA_VALUE_ERROR : ecma_make_object_value (proxy_p)); 1694#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1695 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Proxy is not supported."))); 1696#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1697} /* jerry_create_proxy */ 1698 1699/** 1700 * Create string from a valid UTF-8 string 1701 * 1702 * Note: 1703 * returned value must be freed with jerry_release_value when it is no longer needed. 1704 * 1705 * @return value of the created string 1706 */ 1707jerry_value_t 1708jerry_create_string_from_utf8 (const jerry_char_t *str_p) /**< pointer to string */ 1709{ 1710 return jerry_create_string_sz_from_utf8 (str_p, lit_zt_utf8_string_size ((lit_utf8_byte_t *) str_p)); 1711} /* jerry_create_string_from_utf8 */ 1712 1713/** 1714 * Create string from a valid UTF-8 string 1715 * 1716 * Note: 1717 * returned value must be freed with jerry_release_value when it is no longer needed. 1718 * 1719 * @return value of the created string 1720 */ 1721jerry_value_t 1722jerry_create_string_sz_from_utf8 (const jerry_char_t *str_p, /**< pointer to string */ 1723 jerry_size_t str_size) /**< string size */ 1724{ 1725 jerry_assert_api_available (); 1726 1727 ecma_string_t *ecma_str_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 ((lit_utf8_byte_t *) str_p, 1728 (lit_utf8_size_t) str_size); 1729 1730 return ecma_make_string_value (ecma_str_p); 1731} /* jerry_create_string_sz_from_utf8 */ 1732 1733/** 1734 * Create string from a valid CESU-8 string 1735 * 1736 * Note: 1737 * returned value must be freed with jerry_release_value, when it is no longer needed. 1738 * 1739 * @return value of the created string 1740 */ 1741jerry_value_t 1742jerry_create_string (const jerry_char_t *str_p) /**< pointer to string */ 1743{ 1744 return jerry_create_string_sz (str_p, lit_zt_utf8_string_size ((lit_utf8_byte_t *) str_p)); 1745} /* jerry_create_string */ 1746 1747/** 1748 * Create string from a valid CESU-8 string 1749 * 1750 * Note: 1751 * returned value must be freed with jerry_release_value when it is no longer needed. 1752 * 1753 * @return value of the created string 1754 */ 1755jerry_value_t 1756jerry_create_string_sz (const jerry_char_t *str_p, /**< pointer to string */ 1757 jerry_size_t str_size) /**< string size */ 1758{ 1759 jerry_assert_api_available (); 1760 1761 ecma_string_t *ecma_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) str_p, 1762 (lit_utf8_size_t) str_size); 1763 return ecma_make_string_value (ecma_str_p); 1764} /* jerry_create_string_sz */ 1765 1766/** 1767 * Create symbol from an api value 1768 * 1769 * Note: 1770 * The given argument is converted to string. This operation can throw an error. 1771 * returned value must be freed with jerry_release_value when it is no longer needed. 1772 * 1773 * @return value of the created symbol, if success 1774 * thrown error, otherwise 1775 */ 1776jerry_value_t 1777jerry_create_symbol (const jerry_value_t value) /**< api value */ 1778{ 1779 jerry_assert_api_available (); 1780 1781 if (ecma_is_value_error_reference (value)) 1782 { 1783 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 1784 } 1785 1786#if ENABLED (JERRY_ES2015) 1787 return jerry_return (ecma_op_create_symbol (&value, 1)); 1788#else /* !ENABLED (JERRY_ES2015) */ 1789 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Symbol is not supported."))); 1790#endif /* ENABLED (JERRY_ES2015) */ 1791} /* jerry_create_symbol */ 1792 1793/** 1794 * Calculates the size of the given pattern and creates a RegExp object. 1795 * 1796 * @return value of the constructed RegExp object. 1797 */ 1798jerry_value_t 1799jerry_create_regexp (const jerry_char_t *pattern_p, /**< zero-terminated UTF-8 string as RegExp pattern */ 1800 uint16_t flags) /**< optional RegExp flags */ 1801{ 1802 return jerry_create_regexp_sz (pattern_p, lit_zt_utf8_string_size (pattern_p), flags); 1803} /* jerry_create_regexp */ 1804 1805/** 1806 * Creates a RegExp object with the given pattern and flags. 1807 * 1808 * @return value of the constructed RegExp object. 1809 */ 1810jerry_value_t 1811jerry_create_regexp_sz (const jerry_char_t *pattern_p, /**< zero-terminated UTF-8 string as RegExp pattern */ 1812 jerry_size_t pattern_size, /**< length of the pattern */ 1813 uint16_t flags) /**< optional RegExp flags */ 1814{ 1815 jerry_assert_api_available (); 1816 1817#if ENABLED (JERRY_BUILTIN_REGEXP) 1818 if (!lit_is_valid_utf8_string (pattern_p, pattern_size)) 1819 { 1820 return jerry_throw (ecma_raise_common_error (ECMA_ERR_MSG ("Input must be a valid utf8 string"))); 1821 } 1822 1823 ecma_object_t *regexp_obj_p = ecma_op_regexp_alloc (NULL); 1824 1825 if (JERRY_UNLIKELY (regexp_obj_p == NULL)) 1826 { 1827 return ECMA_VALUE_ERROR; 1828 } 1829 1830 ecma_string_t *ecma_pattern = ecma_new_ecma_string_from_utf8 (pattern_p, pattern_size); 1831 1832 jerry_value_t ret_val = ecma_op_create_regexp_with_flags (regexp_obj_p, 1833 ecma_make_string_value (ecma_pattern), 1834 flags); 1835 ecma_deref_ecma_string (ecma_pattern); 1836 1837 return ret_val; 1838 1839#else /* !ENABLED (JERRY_BUILTIN_REGEXP) */ 1840 JERRY_UNUSED (pattern_p); 1841 JERRY_UNUSED (pattern_size); 1842 JERRY_UNUSED (flags); 1843 1844 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("RegExp is not supported."))); 1845#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 1846} /* jerry_create_regexp_sz */ 1847 1848/** 1849 * Get length of an array object 1850 * 1851 * Note: 1852 * Returns 0, if the value parameter is not an array object. 1853 * 1854 * @return length of the given array 1855 */ 1856uint32_t 1857jerry_get_array_length (const jerry_value_t value) /**< api value */ 1858{ 1859 jerry_assert_api_available (); 1860 1861 if (!jerry_value_is_object (value)) 1862 { 1863 return 0; 1864 } 1865 1866 ecma_object_t *object_p = ecma_get_object_from_value (value); 1867 1868 if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY)) 1869 { 1870 return ecma_array_get_length (object_p); 1871 } 1872 1873 return 0; 1874} /* jerry_get_array_length */ 1875 1876/** 1877 * Get size of Jerry string 1878 * 1879 * Note: 1880 * Returns 0, if the value parameter is not a string. 1881 * 1882 * @return number of bytes in the buffer needed to represent the string 1883 */ 1884jerry_size_t 1885jerry_get_string_size (const jerry_value_t value) /**< input string */ 1886{ 1887 jerry_assert_api_available (); 1888 1889 if (!ecma_is_value_string (value)) 1890 { 1891 return 0; 1892 } 1893 1894 return ecma_string_get_size (ecma_get_string_from_value (value)); 1895} /* jerry_get_string_size */ 1896 1897/** 1898 * Get UTF-8 encoded string size from Jerry string 1899 * 1900 * Note: 1901 * Returns 0, if the value parameter is not a string. 1902 * 1903 * @return number of bytes in the buffer needed to represent the UTF-8 encoded string 1904 */ 1905jerry_size_t 1906jerry_get_utf8_string_size (const jerry_value_t value) /**< input string */ 1907{ 1908 jerry_assert_api_available (); 1909 1910 if (!ecma_is_value_string (value)) 1911 { 1912 return 0; 1913 } 1914 1915 return ecma_string_get_utf8_size (ecma_get_string_from_value (value)); 1916} /* jerry_get_utf8_string_size */ 1917 1918/** 1919 * Get length of Jerry string 1920 * 1921 * Note: 1922 * Returns 0, if the value parameter is not a string. 1923 * 1924 * @return number of characters in the string 1925 */ 1926jerry_length_t 1927jerry_get_string_length (const jerry_value_t value) /**< input string */ 1928{ 1929 jerry_assert_api_available (); 1930 1931 if (!ecma_is_value_string (value)) 1932 { 1933 return 0; 1934 } 1935 1936 return ecma_string_get_length (ecma_get_string_from_value (value)); 1937} /* jerry_get_string_length */ 1938 1939/** 1940 * Get UTF-8 string length from Jerry string 1941 * 1942 * Note: 1943 * Returns 0, if the value parameter is not a string. 1944 * 1945 * @return number of characters in the string 1946 */ 1947jerry_length_t 1948jerry_get_utf8_string_length (const jerry_value_t value) /**< input string */ 1949{ 1950 jerry_assert_api_available (); 1951 1952 if (!ecma_is_value_string (value)) 1953 { 1954 return 0; 1955 } 1956 1957 return ecma_string_get_utf8_length (ecma_get_string_from_value (value)); 1958} /* jerry_get_utf8_string_length */ 1959 1960/** 1961 * Copy the characters of a string into a specified buffer. 1962 * 1963 * Note: 1964 * The '\0' character could occur in character buffer. 1965 * Returns 0, if the value parameter is not a string or 1966 * the buffer is not large enough for the whole string. 1967 * 1968 * Note: 1969 * If the size of the string in jerry value is larger than the size of the 1970 * target buffer, the copy will fail. 1971 * To copy substring use jerry_substring_to_char_buffer() instead. 1972 * 1973 * @return number of bytes, actually copied to the buffer. 1974 */ 1975jerry_size_t 1976jerry_string_to_char_buffer (const jerry_value_t value, /**< input string value */ 1977 jerry_char_t *buffer_p, /**< [out] output characters buffer */ 1978 jerry_size_t buffer_size) /**< size of output buffer */ 1979{ 1980 jerry_assert_api_available (); 1981 1982 if (!ecma_is_value_string (value) || buffer_p == NULL) 1983 { 1984 return 0; 1985 } 1986 1987 ecma_string_t *str_p = ecma_get_string_from_value (value); 1988 1989 if (ecma_string_get_size (str_p) > buffer_size) 1990 { 1991 return 0; 1992 } 1993 1994 return ecma_string_copy_to_cesu8_buffer (str_p, 1995 (lit_utf8_byte_t *) buffer_p, 1996 buffer_size); 1997} /* jerry_string_to_char_buffer */ 1998 1999/** 2000 * Copy the characters of an utf-8 encoded string into a specified buffer. 2001 * 2002 * Note: 2003 * The '\0' character could occur anywhere in the returned string 2004 * Returns 0, if the value parameter is not a string or the buffer 2005 * is not large enough for the whole string. 2006 * 2007 * Note: 2008 * If the size of the string in jerry value is larger than the size of the 2009 * target buffer, the copy will fail. 2010 * To copy a substring use jerry_substring_to_utf8_char_buffer() instead. 2011 * 2012 * @return number of bytes copied to the buffer. 2013 */ 2014jerry_size_t 2015jerry_string_to_utf8_char_buffer (const jerry_value_t value, /**< input string value */ 2016 jerry_char_t *buffer_p, /**< [out] output characters buffer */ 2017 jerry_size_t buffer_size) /**< size of output buffer */ 2018{ 2019 jerry_assert_api_available (); 2020 2021 if (!ecma_is_value_string (value) || buffer_p == NULL) 2022 { 2023 return 0; 2024 } 2025 2026 ecma_string_t *str_p = ecma_get_string_from_value (value); 2027 2028 if (ecma_string_get_utf8_size (str_p) > buffer_size) 2029 { 2030 return 0; 2031 } 2032 2033 return ecma_string_copy_to_utf8_buffer (str_p, 2034 (lit_utf8_byte_t *) buffer_p, 2035 buffer_size); 2036} /* jerry_string_to_utf8_char_buffer */ 2037 2038/** 2039 * Copy the characters of an cesu-8 encoded substring into a specified buffer. 2040 * 2041 * Note: 2042 * The '\0' character could occur anywhere in the returned string 2043 * Returns 0, if the value parameter is not a string. 2044 * It will extract the substring beetween the specified start position 2045 * and the end position (or the end of the string, whichever comes first). 2046 * 2047 * @return number of bytes copied to the buffer. 2048 */ 2049jerry_size_t 2050jerry_substring_to_char_buffer (const jerry_value_t value, /**< input string value */ 2051 jerry_length_t start_pos, /**< position of the first character */ 2052 jerry_length_t end_pos, /**< position of the last character */ 2053 jerry_char_t *buffer_p, /**< [out] output characters buffer */ 2054 jerry_size_t buffer_size) /**< size of output buffer */ 2055{ 2056 jerry_assert_api_available (); 2057 2058 if (!ecma_is_value_string (value) || buffer_p == NULL) 2059 { 2060 return 0; 2061 } 2062 2063 ecma_string_t *str_p = ecma_get_string_from_value (value); 2064 2065 return ecma_substring_copy_to_cesu8_buffer (str_p, 2066 start_pos, 2067 end_pos, 2068 (lit_utf8_byte_t *) buffer_p, 2069 buffer_size); 2070} /* jerry_substring_to_char_buffer */ 2071 2072/** 2073 * Copy the characters of an utf-8 encoded substring into a specified buffer. 2074 * 2075 * Note: 2076 * The '\0' character could occur anywhere in the returned string 2077 * Returns 0, if the value parameter is not a string. 2078 * It will extract the substring beetween the specified start position 2079 * and the end position (or the end of the string, whichever comes first). 2080 * 2081 * @return number of bytes copied to the buffer. 2082 */ 2083jerry_size_t 2084jerry_substring_to_utf8_char_buffer (const jerry_value_t value, /**< input string value */ 2085 jerry_length_t start_pos, /**< position of the first character */ 2086 jerry_length_t end_pos, /**< position of the last character */ 2087 jerry_char_t *buffer_p, /**< [out] output characters buffer */ 2088 jerry_size_t buffer_size) /**< size of output buffer */ 2089{ 2090 jerry_assert_api_available (); 2091 2092 if (!ecma_is_value_string (value) || buffer_p == NULL) 2093 { 2094 return 0; 2095 } 2096 2097 ecma_string_t *str_p = ecma_get_string_from_value (value); 2098 2099 return ecma_substring_copy_to_utf8_buffer (str_p, 2100 start_pos, 2101 end_pos, 2102 (lit_utf8_byte_t *) buffer_p, 2103 buffer_size); 2104} /* jerry_substring_to_utf8_char_buffer */ 2105 2106/** 2107 * Checks whether the object or it's prototype objects have the given property. 2108 * 2109 * @return raised error - if the operation fail 2110 * true/false API value - depend on whether the property exists 2111 */ 2112jerry_value_t 2113jerry_has_property (const jerry_value_t obj_val, /**< object value */ 2114 const jerry_value_t prop_name_val) /**< property name (string value) */ 2115{ 2116 jerry_assert_api_available (); 2117 2118 if (!ecma_is_value_object (obj_val) 2119 || !ecma_is_value_prop_name (prop_name_val)) 2120 { 2121 return ECMA_VALUE_FALSE; 2122 } 2123 2124 return ecma_op_object_has_property (ecma_get_object_from_value (obj_val), 2125 ecma_get_prop_name_from_value (prop_name_val)); 2126} /* jerry_has_property */ 2127 2128/** 2129 * Checks whether the object has the given property. 2130 * 2131 * @return ECMA_VALUE_ERROR - if the operation raises error 2132 * ECMA_VALUE_{TRUE, FALSE} - based on whether the property exists 2133 */ 2134jerry_value_t 2135jerry_has_own_property (const jerry_value_t obj_val, /**< object value */ 2136 const jerry_value_t prop_name_val) /**< property name (string value) */ 2137{ 2138 jerry_assert_api_available (); 2139 2140 if (!ecma_is_value_object (obj_val) 2141 || !ecma_is_value_prop_name (prop_name_val)) 2142 { 2143 return ECMA_VALUE_FALSE; 2144 } 2145 2146 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 2147 ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name_val); 2148 2149#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2150 if (ECMA_OBJECT_IS_PROXY (obj_p)) 2151 { 2152 ecma_property_descriptor_t prop_desc; 2153 2154 ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc); 2155 2156 if (ecma_is_value_true (status)) 2157 { 2158 ecma_free_property_descriptor (&prop_desc); 2159 } 2160 2161 return jerry_return (status); 2162 } 2163#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2164 2165 return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p)); 2166} /* jerry_has_own_property */ 2167 2168/** 2169 * Checks whether the object has the given internal property. 2170 * 2171 * @return true - if the internal property exists 2172 * false - otherwise 2173 */ 2174bool 2175jerry_has_internal_property (const jerry_value_t obj_val, /**< object value */ 2176 const jerry_value_t prop_name_val) /**< property name value */ 2177{ 2178 jerry_assert_api_available (); 2179 2180 if (!ecma_is_value_object (obj_val) 2181 || !ecma_is_value_prop_name (prop_name_val)) 2182 { 2183 return false; 2184 } 2185 2186 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 2187 2188 ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL); 2189 2190 if (ecma_op_object_is_fast_array (obj_p)) 2191 { 2192 return false; 2193 } 2194 2195 ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p); 2196 2197 if (property_p == NULL) 2198 { 2199 return false; 2200 } 2201 2202 ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); 2203 property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val)); 2204 2205 return property_p != NULL; 2206} /* jerry_has_internal_property */ 2207 2208/** 2209 * Delete a property from an object. 2210 * 2211 * @return true - if property was deleted successfully 2212 * false - otherwise 2213 */ 2214bool 2215jerry_delete_property (const jerry_value_t obj_val, /**< object value */ 2216 const jerry_value_t prop_name_val) /**< property name (string value) */ 2217{ 2218 jerry_assert_api_available (); 2219 2220 if (!ecma_is_value_object (obj_val) 2221 || !ecma_is_value_prop_name (prop_name_val)) 2222 { 2223 return false; 2224 } 2225 2226 ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val), 2227 ecma_get_prop_name_from_value (prop_name_val), 2228 false); 2229 2230#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2231 if (ECMA_IS_VALUE_ERROR (ret_value)) 2232 { 2233 // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release 2234 jcontext_release_exception (); 2235 } 2236#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2237 2238 return ecma_is_value_true (ret_value); 2239} /* jerry_delete_property */ 2240 2241/** 2242 * Delete indexed property from the specified object. 2243 * 2244 * @return true - if property was deleted successfully 2245 * false - otherwise 2246 */ 2247bool 2248jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value */ 2249 uint32_t index) /**< index to be written */ 2250{ 2251 jerry_assert_api_available (); 2252 2253 if (!ecma_is_value_object (obj_val)) 2254 { 2255 return false; 2256 } 2257 2258 ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index); 2259 ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val), 2260 str_idx_p, 2261 false); 2262 ecma_deref_ecma_string (str_idx_p); 2263 2264#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2265 if (ECMA_IS_VALUE_ERROR (ret_value)) 2266 { 2267 // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release 2268 jcontext_release_exception (); 2269 } 2270#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2271 2272 return ecma_is_value_true (ret_value); 2273} /* jerry_delete_property_by_index */ 2274 2275/** 2276 * Delete an internal property from an object. 2277 * 2278 * @return true - if property was deleted successfully 2279 * false - otherwise 2280 */ 2281bool 2282jerry_delete_internal_property (const jerry_value_t obj_val, /**< object value */ 2283 const jerry_value_t prop_name_val) /**< property name value */ 2284{ 2285 jerry_assert_api_available (); 2286 2287 if (!ecma_is_value_object (obj_val) 2288 || !ecma_is_value_prop_name (prop_name_val)) 2289 { 2290 return false; 2291 } 2292 2293 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 2294 2295 ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL); 2296 2297 if (ecma_op_object_is_fast_array (obj_p)) 2298 { 2299 return true; 2300 } 2301 2302 ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p); 2303 2304 if (property_p == NULL) 2305 { 2306 return true; 2307 } 2308 2309 ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); 2310 property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val)); 2311 2312 if (property_p == NULL) 2313 { 2314 return true; 2315 } 2316 2317 ecma_delete_property (internal_object_p, ECMA_PROPERTY_VALUE_PTR (property_p)); 2318 2319 return true; 2320} /* jerry_delete_internal_property */ 2321 2322/** 2323 * Get value of a property to the specified object with the given name. 2324 * 2325 * Note: 2326 * returned value must be freed with jerry_release_value, when it is no longer needed. 2327 * 2328 * @return value of the property - if success 2329 * value marked with error flag - otherwise 2330 */ 2331jerry_value_t 2332jerry_get_property (const jerry_value_t obj_val, /**< object value */ 2333 const jerry_value_t prop_name_val) /**< property name (string value) */ 2334{ 2335 jerry_assert_api_available (); 2336 2337 if (!ecma_is_value_object (obj_val) 2338 || !ecma_is_value_prop_name (prop_name_val)) 2339 { 2340 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2341 } 2342 2343 jerry_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_val), 2344 ecma_get_prop_name_from_value (prop_name_val)); 2345 return jerry_return (ret_value); 2346} /* jerry_get_property */ 2347 2348/** 2349 * Get value by an index from the specified object. 2350 * 2351 * Note: 2352 * returned value must be freed with jerry_release_value, when it is no longer needed. 2353 * 2354 * @return value of the property specified by the index - if success 2355 * value marked with error flag - otherwise 2356 */ 2357jerry_value_t 2358jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */ 2359 uint32_t index) /**< index to be written */ 2360{ 2361 jerry_assert_api_available (); 2362 2363 if (!ecma_is_value_object (obj_val)) 2364 { 2365 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2366 } 2367 2368 ecma_value_t ret_value = ecma_op_object_get_by_uint32_index (ecma_get_object_from_value (obj_val), index); 2369 2370 return jerry_return (ret_value); 2371} /* jerry_get_property_by_index */ 2372 2373/** 2374 * Get value of an internal property to the specified object with the given name. 2375 * 2376 * Note: 2377 * returned value must be freed with jerry_release_value, when it is no longer needed. 2378 * 2379 * @return value of the internal property - if the internal property exists 2380 * undefined value - if the internal does not property exists 2381 * value marked with error flag - otherwise 2382 */ 2383jerry_value_t 2384jerry_get_internal_property (const jerry_value_t obj_val, /**< object value */ 2385 const jerry_value_t prop_name_val) /**< property name value */ 2386{ 2387 jerry_assert_api_available (); 2388 2389 if (!ecma_is_value_object (obj_val) 2390 || !ecma_is_value_prop_name (prop_name_val)) 2391 { 2392 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2393 } 2394 2395 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 2396 2397 ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL); 2398 2399 if (ecma_op_object_is_fast_array (obj_p)) 2400 { 2401 return jerry_return (ECMA_VALUE_UNDEFINED); 2402 } 2403 2404 ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p); 2405 2406 if (property_p == NULL) 2407 { 2408 return jerry_return (ECMA_VALUE_UNDEFINED); 2409 } 2410 2411 ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); 2412 property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val)); 2413 2414 if (property_p == NULL) 2415 { 2416 return jerry_return (ECMA_VALUE_UNDEFINED); 2417 } 2418 2419 return jerry_return (ecma_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value)); 2420} /* jerry_get_internal_property */ 2421 2422/** 2423 * Set a property to the specified object with the given name. 2424 * 2425 * Note: 2426 * returned value must be freed with jerry_release_value, when it is no longer needed. 2427 * 2428 * @return true value - if the operation was successful 2429 * value marked with error flag - otherwise 2430 */ 2431jerry_value_t 2432jerry_set_property (const jerry_value_t obj_val, /**< object value */ 2433 const jerry_value_t prop_name_val, /**< property name (string value) */ 2434 const jerry_value_t value_to_set) /**< value to set */ 2435{ 2436 jerry_assert_api_available (); 2437 2438 if (ecma_is_value_error_reference (value_to_set) 2439 || !ecma_is_value_object (obj_val) 2440 || !ecma_is_value_prop_name (prop_name_val)) 2441 { 2442 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2443 } 2444 2445 return jerry_return (ecma_op_object_put (ecma_get_object_from_value (obj_val), 2446 ecma_get_prop_name_from_value (prop_name_val), 2447 value_to_set, 2448 true)); 2449} /* jerry_set_property */ 2450 2451/** 2452 * Set indexed value in the specified object 2453 * 2454 * Note: 2455 * returned value must be freed with jerry_release_value, when it is no longer needed. 2456 * 2457 * @return true value - if the operation was successful 2458 * value marked with error flag - otherwise 2459 */ 2460jerry_value_t 2461jerry_set_property_by_index (const jerry_value_t obj_val, /**< object value */ 2462 uint32_t index, /**< index to be written */ 2463 const jerry_value_t value_to_set) /**< value to set */ 2464{ 2465 jerry_assert_api_available (); 2466 2467 if (ecma_is_value_error_reference (value_to_set) 2468 || !ecma_is_value_object (obj_val)) 2469 { 2470 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2471 } 2472 2473 ecma_value_t ret_value = ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (obj_val), 2474 index, 2475 value_to_set, 2476 true); 2477 2478 return jerry_return (ret_value); 2479} /* jerry_set_property_by_index */ 2480 2481/** 2482 * Set an internal property to the specified object with the given name. 2483 * 2484 * Note: 2485 * - the property cannot be accessed from the JavaScript context, only from the public API 2486 * - returned value must be freed with jerry_release_value, when it is no longer needed. 2487 * 2488 * @return true value - if the operation was successful 2489 * value marked with error flag - otherwise 2490 */ 2491bool 2492jerry_set_internal_property (const jerry_value_t obj_val, /**< object value */ 2493 const jerry_value_t prop_name_val, /**< property name value */ 2494 const jerry_value_t value_to_set) /**< value to set */ 2495{ 2496 jerry_assert_api_available (); 2497 2498 if (ecma_is_value_error_reference (value_to_set) 2499 || !ecma_is_value_object (obj_val) 2500 || !ecma_is_value_prop_name (prop_name_val)) 2501 { 2502 return false; 2503 } 2504 2505 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 2506 2507 ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL); 2508 2509 if (ecma_op_object_is_fast_array (obj_p)) 2510 { 2511 ecma_fast_array_convert_to_normal (obj_p); 2512 } 2513 2514 ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p); 2515 ecma_object_t *internal_object_p; 2516 2517 if (property_p == NULL) 2518 { 2519 ecma_property_value_t *value_p = ecma_create_named_data_property (obj_p, 2520 internal_string_p, 2521 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, 2522 NULL); 2523 2524 internal_object_p = ecma_create_object (NULL, 2525 sizeof (ecma_extended_object_t), 2526 ECMA_OBJECT_TYPE_CLASS); 2527 { 2528 ecma_extended_object_t *container_p = (ecma_extended_object_t *) internal_object_p; 2529 container_p->u.class_prop.class_id = LIT_INTERNAL_MAGIC_STRING_INTERNAL_OBJECT; 2530 container_p->u.class_prop.extra_info = 0; 2531 container_p->u.class_prop.u.length = 0; 2532 } 2533 2534 value_p->value = ecma_make_object_value (internal_object_p); 2535 ecma_deref_object (internal_object_p); 2536 } 2537 else 2538 { 2539 internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); 2540 } 2541 2542 ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name_val); 2543 property_p = ecma_find_named_property (internal_object_p, prop_name_p); 2544 2545 if (property_p == NULL) 2546 { 2547 ecma_property_value_t *value_p = ecma_create_named_data_property (internal_object_p, 2548 prop_name_p, 2549 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, 2550 NULL); 2551 2552 value_p->value = ecma_copy_value_if_not_object (value_to_set); 2553 } 2554 else 2555 { 2556 ecma_named_data_property_assign_value (internal_object_p, ECMA_PROPERTY_VALUE_PTR (property_p), value_to_set); 2557 } 2558 2559 return true; 2560} /* jerry_set_internal_property */ 2561 2562/** 2563 * Initialize property descriptor. 2564 */ 2565void 2566jerry_init_property_descriptor_fields (jerry_property_descriptor_t *prop_desc_p) /**< [out] property descriptor */ 2567{ 2568 prop_desc_p->is_value_defined = false; 2569 prop_desc_p->value = ECMA_VALUE_UNDEFINED; 2570 prop_desc_p->is_writable_defined = false; 2571 prop_desc_p->is_writable = false; 2572 prop_desc_p->is_enumerable_defined = false; 2573 prop_desc_p->is_enumerable = false; 2574 prop_desc_p->is_configurable_defined = false; 2575 prop_desc_p->is_configurable = false; 2576 prop_desc_p->is_get_defined = false; 2577 prop_desc_p->getter = ECMA_VALUE_UNDEFINED; 2578 prop_desc_p->is_set_defined = false; 2579 prop_desc_p->setter = ECMA_VALUE_UNDEFINED; 2580} /* jerry_init_property_descriptor_fields */ 2581 2582/** 2583 * Define a property to the specified object with the given name. 2584 * 2585 * Note: 2586 * returned value must be freed with jerry_release_value, when it is no longer needed. 2587 * 2588 * @return true value - if the operation was successful 2589 * value marked with error flag - otherwise 2590 */ 2591jerry_value_t 2592jerry_define_own_property (const jerry_value_t obj_val, /**< object value */ 2593 const jerry_value_t prop_name_val, /**< property name (string value) */ 2594 const jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */ 2595{ 2596 jerry_assert_api_available (); 2597 2598 if (!ecma_is_value_object (obj_val) 2599 || !ecma_is_value_prop_name (prop_name_val)) 2600 { 2601 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2602 } 2603 2604 if ((prop_desc_p->is_writable_defined || prop_desc_p->is_value_defined) 2605 && (prop_desc_p->is_get_defined || prop_desc_p->is_set_defined)) 2606 { 2607 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2608 } 2609 2610 ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); 2611 2612 uint32_t flags = ECMA_PROP_NO_OPTS; 2613 2614 if (prop_desc_p->is_enumerable_defined) 2615 { 2616 flags |= (uint32_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | (prop_desc_p->is_enumerable ? ECMA_PROP_IS_ENUMERABLE 2617 : ECMA_PROP_NO_OPTS)); 2618 } 2619 2620 if (prop_desc_p->is_configurable_defined) 2621 { 2622 flags |= (uint32_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | (prop_desc_p->is_configurable ? ECMA_PROP_IS_CONFIGURABLE 2623 : ECMA_PROP_NO_OPTS)); 2624 } 2625 2626 /* Copy data property info. */ 2627 flags |= (prop_desc_p->is_value_defined ? ECMA_PROP_IS_VALUE_DEFINED : ECMA_PROP_NO_OPTS); 2628 2629 if (prop_desc_p->is_value_defined) 2630 { 2631 if (ecma_is_value_error_reference (prop_desc_p->value)) 2632 { 2633 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2634 } 2635 2636 prop_desc.value = prop_desc_p->value; 2637 } 2638 2639 if (prop_desc_p->is_writable_defined) 2640 { 2641 flags |= (uint32_t) (ECMA_PROP_IS_WRITABLE_DEFINED | (prop_desc_p->is_writable ? ECMA_PROP_IS_WRITABLE 2642 : ECMA_PROP_NO_OPTS)); 2643 } 2644 2645 /* Copy accessor property info. */ 2646 if (prop_desc_p->is_get_defined) 2647 { 2648 ecma_value_t getter = prop_desc_p->getter; 2649 flags |= ECMA_PROP_IS_GET_DEFINED; 2650 2651 if (ecma_is_value_error_reference (getter)) 2652 { 2653 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2654 } 2655 2656 if (ecma_op_is_callable (getter)) 2657 { 2658 prop_desc.get_p = ecma_get_object_from_value (getter); 2659 } 2660 else if (!ecma_is_value_null (getter)) 2661 { 2662 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2663 } 2664 } 2665 2666 if (prop_desc_p->is_set_defined) 2667 { 2668 ecma_value_t setter = prop_desc_p->setter; 2669 flags |= ECMA_PROP_IS_SET_DEFINED; 2670 2671 if (ecma_is_value_error_reference (setter)) 2672 { 2673 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2674 } 2675 2676 if (ecma_op_is_callable (setter)) 2677 { 2678 prop_desc.set_p = ecma_get_object_from_value (setter); 2679 } 2680 else if (!ecma_is_value_null (setter)) 2681 { 2682 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2683 } 2684 } 2685 2686 prop_desc.flags |= (uint16_t) (flags | ECMA_PROP_IS_THROW); 2687 2688 return ecma_op_object_define_own_property (ecma_get_object_from_value (obj_val), 2689 ecma_get_prop_name_from_value (prop_name_val), 2690 &prop_desc); 2691} /* jerry_define_own_property */ 2692 2693/** 2694 * Construct property descriptor from specified property. 2695 * 2696 * @return true - if success, the prop_desc_p fields contains the property info 2697 * false - otherwise, the prop_desc_p is unchanged 2698 */ 2699bool 2700jerry_get_own_property_descriptor (const jerry_value_t obj_val, /**< object value */ 2701 const jerry_value_t prop_name_val, /**< property name (string value) */ 2702 jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */ 2703{ 2704 jerry_assert_api_available (); 2705 2706 if (!ecma_is_value_object (obj_val) 2707 || !ecma_is_value_prop_name (prop_name_val)) 2708 { 2709 return false; 2710 } 2711 2712 ecma_property_descriptor_t prop_desc; 2713 2714 ecma_value_t status = ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_val), 2715 ecma_get_prop_name_from_value (prop_name_val), 2716 &prop_desc); 2717 2718#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2719 if (ECMA_IS_VALUE_ERROR (status)) 2720 { 2721 // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release 2722 jcontext_release_exception (); 2723 } 2724#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2725 2726 if (!ecma_is_value_true (status)) 2727 { 2728 return false; 2729 } 2730 2731 prop_desc_p->is_configurable_defined = true; 2732 prop_desc_p->is_configurable = (prop_desc.flags & ECMA_PROP_IS_CONFIGURABLE) != 0; 2733 prop_desc_p->is_enumerable_defined = true; 2734 prop_desc_p->is_enumerable = (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE) != 0; 2735 2736 prop_desc_p->is_writable_defined = (prop_desc.flags & ECMA_PROP_IS_WRITABLE_DEFINED) != 0; 2737 prop_desc_p->is_writable = prop_desc_p->is_writable_defined ? (prop_desc.flags & ECMA_PROP_IS_WRITABLE) != 0 : false; 2738 2739 prop_desc_p->is_value_defined = (prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED) != 0; 2740 prop_desc_p->is_get_defined = (prop_desc.flags & ECMA_PROP_IS_GET_DEFINED) != 0; 2741 prop_desc_p->is_set_defined = (prop_desc.flags & ECMA_PROP_IS_SET_DEFINED) != 0; 2742 2743 prop_desc_p->value = ECMA_VALUE_UNDEFINED; 2744 prop_desc_p->getter = ECMA_VALUE_UNDEFINED; 2745 prop_desc_p->setter = ECMA_VALUE_UNDEFINED; 2746 2747 if (prop_desc_p->is_value_defined) 2748 { 2749 prop_desc_p->value = prop_desc.value; 2750 } 2751 2752 if (prop_desc_p->is_get_defined) 2753 { 2754 if (prop_desc.get_p != NULL) 2755 { 2756 prop_desc_p->getter = ecma_make_object_value (prop_desc.get_p); 2757 } 2758 else 2759 { 2760 prop_desc_p->getter = ECMA_VALUE_NULL; 2761 } 2762 } 2763 2764 if (prop_desc_p->is_set_defined) 2765 { 2766 if (prop_desc.set_p != NULL) 2767 { 2768 prop_desc_p->setter = ecma_make_object_value (prop_desc.set_p); 2769 } 2770 else 2771 { 2772 prop_desc_p->setter = ECMA_VALUE_NULL; 2773 } 2774 } 2775 2776 return true; 2777} /* jerry_get_own_property_descriptor */ 2778 2779/** 2780 * Free fields of property descriptor (setter, getter and value). 2781 */ 2782void 2783jerry_free_property_descriptor_fields (const jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */ 2784{ 2785 if (prop_desc_p->is_value_defined) 2786 { 2787 jerry_release_value (prop_desc_p->value); 2788 } 2789 2790 if (prop_desc_p->is_get_defined) 2791 { 2792 jerry_release_value (prop_desc_p->getter); 2793 } 2794 2795 if (prop_desc_p->is_set_defined) 2796 { 2797 jerry_release_value (prop_desc_p->setter); 2798 } 2799} /* jerry_free_property_descriptor_fields */ 2800 2801/** 2802 * Invoke function specified by a function value 2803 * 2804 * Note: 2805 * - returned value must be freed with jerry_release_value, when it is no longer needed. 2806 * - If function is invoked as constructor, it should support [[Construct]] method, 2807 * otherwise, if function is simply called - it should support [[Call]] method. 2808 * 2809 * @return returned jerry value of the invoked function 2810 */ 2811static jerry_value_t 2812jerry_invoke_function (bool is_invoke_as_constructor, /**< true - invoke function as constructor 2813 * (this_arg_p should be NULL, as it is ignored), 2814 * false - perform function call */ 2815 const jerry_value_t func_obj_val, /**< function object to call */ 2816 const jerry_value_t this_val, /**< object value of 'this' binding */ 2817 const jerry_value_t args_p[], /**< function's call arguments */ 2818 const jerry_size_t args_count) /**< number of the arguments */ 2819{ 2820 JERRY_ASSERT (args_count == 0 || args_p != NULL); 2821 2822 if (ecma_is_value_error_reference (func_obj_val) 2823 || ecma_is_value_error_reference (this_val)) 2824 { 2825 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 2826 } 2827 2828 for (uint32_t i = 0; i < args_count; i++) 2829 { 2830 if (ecma_is_value_error_reference (args_p[i])) 2831 { 2832 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 2833 } 2834 } 2835 2836 if (is_invoke_as_constructor) 2837 { 2838 JERRY_ASSERT (jerry_value_is_constructor (func_obj_val)); 2839 2840 return jerry_return (ecma_op_function_construct (ecma_get_object_from_value (func_obj_val), 2841 ecma_get_object_from_value (func_obj_val), 2842 args_p, 2843 args_count)); 2844 } 2845 else 2846 { 2847 JERRY_ASSERT (jerry_value_is_function (func_obj_val)); 2848 2849 return jerry_return (ecma_op_function_call (ecma_get_object_from_value (func_obj_val), 2850 this_val, 2851 args_p, 2852 args_count)); 2853 } 2854} /* jerry_invoke_function */ 2855 2856/** 2857 * Call function specified by a function value 2858 * 2859 * Note: 2860 * returned value must be freed with jerry_release_value, when it is no longer needed. 2861 * error flag must not be set for any arguments of this function. 2862 * 2863 * @return returned jerry value of the called function 2864 */ 2865jerry_value_t 2866jerry_call_function (const jerry_value_t func_obj_val, /**< function object to call */ 2867 const jerry_value_t this_val, /**< object for 'this' binding */ 2868 const jerry_value_t args_p[], /**< function's call arguments */ 2869 jerry_size_t args_count) /**< number of the arguments */ 2870{ 2871 jerry_assert_api_available (); 2872 2873#if ENABLED (JERRY_DEBUGGER) 2874 /** 2875 * Clear flag JERRY_DEBUGGER_VM_STOP and set debugger_stop_context Null everytime jerry's debugger call a function. 2876 * This could solve the problem that jerry's debugger stops at an unexpected line when re-entering a function after a 2877 * step-operation. 2878 */ 2879 JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP); 2880 JERRY_CONTEXT (debugger_stop_context) = NULL; 2881 2882 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) { 2883 if (jerry_debugger_receive (NULL)) { 2884 JERRY_DEBUG_MSG ("resume"); 2885 } 2886 } 2887#endif 2888 2889 if (jerry_value_is_function (func_obj_val) && !ecma_is_value_error_reference (this_val)) 2890 { 2891 for (jerry_size_t i = 0; i < args_count; i++) 2892 { 2893 if (ecma_is_value_error_reference (args_p[i])) 2894 { 2895 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 2896 } 2897 } 2898 2899 return jerry_invoke_function (false, func_obj_val, this_val, args_p, args_count); 2900 } 2901 2902 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2903} /* jerry_call_function */ 2904 2905/** 2906 * Construct object value invoking specified function value as a constructor 2907 * 2908 * Note: 2909 * returned value must be freed with jerry_release_value, when it is no longer needed. 2910 * error flag must not be set for any arguments of this function. 2911 * 2912 * @return returned jerry value of the invoked constructor 2913 */ 2914jerry_value_t 2915jerry_construct_object (const jerry_value_t func_obj_val, /**< function object to call */ 2916 const jerry_value_t args_p[], /**< function's call arguments 2917 * (NULL if arguments number is zero) */ 2918 jerry_size_t args_count) /**< number of the arguments */ 2919{ 2920 jerry_assert_api_available (); 2921 2922 if (jerry_value_is_constructor (func_obj_val)) 2923 { 2924 for (jerry_size_t i = 0; i < args_count; i++) 2925 { 2926 if (ecma_is_value_error_reference (args_p[i])) 2927 { 2928 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 2929 } 2930 } 2931 2932 ecma_value_t this_val = ECMA_VALUE_UNDEFINED; 2933 return jerry_invoke_function (true, func_obj_val, this_val, args_p, args_count); 2934 } 2935 2936 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2937} /* jerry_construct_object */ 2938 2939/** 2940 * Get keys of the specified object value 2941 * 2942 * Note: 2943 * returned value must be freed with jerry_release_value, when it is no longer needed. 2944 * 2945 * @return array object value - if success 2946 * value marked with error flag - otherwise 2947 */ 2948jerry_value_t 2949jerry_get_object_keys (const jerry_value_t obj_val) /**< object value */ 2950{ 2951 jerry_assert_api_available (); 2952 2953 if (!ecma_is_value_object (obj_val)) 2954 { 2955 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2956 } 2957 2958 return ecma_builtin_helper_object_get_properties (ecma_get_object_from_value (obj_val), 2959 ECMA_LIST_ENUMERABLE); 2960} /* jerry_get_object_keys */ 2961 2962/** 2963 * Get the prototype of the specified object 2964 * 2965 * Note: 2966 * returned value must be freed with jerry_release_value, when it is no longer needed. 2967 * 2968 * @return prototype object or null value - if success 2969 * value marked with error flag - otherwise 2970 */ 2971jerry_value_t 2972jerry_get_prototype (const jerry_value_t obj_val) /**< object value */ 2973{ 2974 jerry_assert_api_available (); 2975 2976 if (!ecma_is_value_object (obj_val)) 2977 { 2978 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 2979 } 2980 2981 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 2982 2983#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2984 if (ECMA_OBJECT_IS_PROXY (obj_p)) 2985 { 2986 return jerry_return (ecma_proxy_object_get_prototype_of (obj_p)); 2987 } 2988#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2989 2990 if (obj_p->u2.prototype_cp == JMEM_CP_NULL) 2991 { 2992 return ECMA_VALUE_NULL; 2993 } 2994 2995 ecma_object_t *proto_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_p->u2.prototype_cp); 2996 ecma_ref_object (proto_obj_p); 2997 2998 return ecma_make_object_value (proto_obj_p); 2999} /* jerry_get_prototype */ 3000 3001/** 3002 * Set the prototype of the specified object 3003 * 3004 * @return true value - if success 3005 * value marked with error flag - otherwise 3006 */ 3007jerry_value_t 3008jerry_set_prototype (const jerry_value_t obj_val, /**< object value */ 3009 const jerry_value_t proto_obj_val) /**< prototype object value */ 3010{ 3011 jerry_assert_api_available (); 3012 3013 if (!ecma_is_value_object (obj_val) 3014 || ecma_is_value_error_reference (proto_obj_val) 3015 || (!ecma_is_value_object (proto_obj_val) && !ecma_is_value_null (proto_obj_val))) 3016 { 3017 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 3018 } 3019 ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); 3020 3021#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 3022 if (ECMA_OBJECT_IS_PROXY (obj_p)) 3023 { 3024 return jerry_return (ecma_proxy_object_set_prototype_of (obj_p, proto_obj_val)); 3025 } 3026#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 3027 3028 return ecma_op_ordinary_object_set_prototype_of (obj_p, proto_obj_val); 3029} /* jerry_set_prototype */ 3030 3031/** 3032 * Utility to check if a given object can be used for the foreach api calls. 3033 * 3034 * Some objects/classes uses extra internal objects to correctly store data. 3035 * These extre object should never be exposed externally to the API user. 3036 * 3037 * @returns true - if the user can access the object in the callback. 3038 * false - if the object is an internal object which should no be accessed by the user. 3039 */ 3040static 3041bool jerry_object_is_valid_foreach (ecma_object_t *object_p) /**< object to test */ 3042{ 3043 if (ecma_is_lexical_environment (object_p)) 3044 { 3045 return false; 3046 } 3047 3048 ecma_object_type_t object_type = ecma_get_object_type (object_p); 3049 3050 if (object_type == ECMA_OBJECT_TYPE_CLASS) 3051 { 3052 ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 3053 switch (ext_object_p->u.class_prop.class_id) 3054 { 3055 /* An object's internal property object should not be iterable by foreach. */ 3056 case LIT_INTERNAL_MAGIC_STRING_INTERNAL_OBJECT: return false; 3057 } 3058 } 3059 3060 return true; 3061} /* jerry_object_is_valid_foreach */ 3062 3063/** 3064 * Traverse objects. 3065 * 3066 * @return true - traversal was interrupted by the callback. 3067 * false - otherwise - traversal visited all objects. 3068 */ 3069bool 3070jerry_objects_foreach (jerry_objects_foreach_t foreach_p, /**< function pointer of the iterator function */ 3071 void *user_data_p) /**< pointer to user data */ 3072{ 3073 jerry_assert_api_available (); 3074 3075 JERRY_ASSERT (foreach_p != NULL); 3076 3077 jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp); 3078 3079 while (iter_cp != JMEM_CP_NULL) 3080 { 3081 ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp); 3082 3083 if (jerry_object_is_valid_foreach (iter_p) 3084 && !foreach_p (ecma_make_object_value (iter_p), user_data_p)) 3085 { 3086 return true; 3087 } 3088 3089 iter_cp = iter_p->gc_next_cp; 3090 } 3091 3092 return false; 3093} /* jerry_objects_foreach */ 3094 3095/** 3096 * Traverse objects having a given native type info. 3097 * 3098 * @return true - traversal was interrupted by the callback. 3099 * false - otherwise - traversal visited all objects. 3100 */ 3101bool 3102jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_info_p, /**< the type info 3103 * of the native pointer */ 3104 jerry_objects_foreach_by_native_info_t foreach_p, /**< function to apply for 3105 * each matching object */ 3106 void *user_data_p) /**< pointer to user data */ 3107{ 3108 jerry_assert_api_available (); 3109 3110 JERRY_ASSERT (native_info_p != NULL); 3111 JERRY_ASSERT (foreach_p != NULL); 3112 3113 ecma_native_pointer_t *native_pointer_p; 3114 3115 jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp); 3116 3117 while (iter_cp != JMEM_CP_NULL) 3118 { 3119 ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp); 3120 3121 if (jerry_object_is_valid_foreach (iter_p)) 3122 { 3123 native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p); 3124 if (native_pointer_p 3125 && !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p)) 3126 { 3127 return true; 3128 } 3129 } 3130 3131 iter_cp = iter_p->gc_next_cp; 3132 } 3133 3134 return false; 3135} /* jerry_objects_foreach_by_native_info */ 3136 3137/** 3138 * Get native pointer and its type information, associated with the given native type info. 3139 * 3140 * Note: 3141 * If native pointer is present, its type information is returned in out_native_pointer_p 3142 * 3143 * @return true - if there is an associated pointer, 3144 * false - otherwise 3145 */ 3146bool 3147jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get native pointer from */ 3148 void **out_native_pointer_p, /**< [out] native pointer */ 3149 const jerry_object_native_info_t *native_info_p) /**< the type info 3150 * of the native pointer */ 3151{ 3152 jerry_assert_api_available (); 3153 3154 if (!ecma_is_value_object (obj_val)) 3155 { 3156 return false; 3157 } 3158 3159 ecma_native_pointer_t *native_pointer_p; 3160 native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_val), (void *) native_info_p); 3161 3162 if (native_pointer_p == NULL) 3163 { 3164 return false; 3165 } 3166 3167 if (out_native_pointer_p != NULL) 3168 { 3169 *out_native_pointer_p = native_pointer_p->data_p; 3170 } 3171 3172 return true; 3173} /* jerry_get_object_native_pointer */ 3174 3175/** 3176 * Set native pointer and an optional type info for the specified object. 3177 * 3178 * 3179 * Note: 3180 * If native pointer was already set for the object, its value is updated. 3181 * 3182 * Note: 3183 * If a non-NULL free callback is specified in the native type info, 3184 * it will be called by the garbage collector when the object is freed. 3185 * Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition) 3186 * The type info always overwrites the previous value, so passing 3187 * a NULL value deletes the current type info. 3188 */ 3189void 3190jerry_set_object_native_pointer (const jerry_value_t obj_val, /**< object to set native pointer in */ 3191 void *native_pointer_p, /**< native pointer */ 3192 const jerry_object_native_info_t *native_info_p) /**< object's native type info */ 3193{ 3194 jerry_assert_api_available (); 3195 3196 if (ecma_is_value_object (obj_val)) 3197 { 3198 ecma_object_t *object_p = ecma_get_object_from_value (obj_val); 3199 3200 ecma_create_native_pointer_property (object_p, native_pointer_p, (void *) native_info_p); 3201 } 3202} /* jerry_set_object_native_pointer */ 3203 3204/** 3205 * Delete the previously set native pointer by the native type info from the specified object. 3206 * 3207 * Note: 3208 * If the specified object has no matching native pointer for the given native type info 3209 * the function has no effect. 3210 * 3211 * Note: 3212 * This operation cannot throw an exception. 3213 * 3214 * @return true - if the native pointer has been deleted succesfully 3215 * false - otherwise 3216 */ 3217bool 3218jerry_delete_object_native_pointer (const jerry_value_t obj_val, /**< object to delete native pointer from */ 3219 const jerry_object_native_info_t *native_info_p) /**< object's native type info */ 3220{ 3221 jerry_assert_api_available (); 3222 3223 if (ecma_is_value_object (obj_val)) 3224 { 3225 ecma_object_t *object_p = ecma_get_object_from_value (obj_val); 3226 3227 return ecma_delete_native_pointer_property (object_p, (void *) native_info_p); 3228 } 3229 3230 return false; 3231} /* jerry_delete_object_native_pointer */ 3232 3233/** 3234 * Applies the given function to the every property in the object. 3235 * 3236 * @return true - if object fields traversal was performed successfully, i.e.: 3237 * - no unhandled exceptions were thrown in object fields traversal; 3238 * - object fields traversal was stopped on callback that returned false; 3239 * false - otherwise, 3240 * if getter of field threw a exception or unhandled exceptions were thrown during traversal; 3241 */ 3242bool 3243jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */ 3244 jerry_object_property_foreach_t foreach_p, /**< foreach function */ 3245 void *user_data_p) /**< user data for foreach function */ 3246{ 3247 jerry_assert_api_available (); 3248 3249 if (!ecma_is_value_object (obj_val)) 3250 { 3251 return false; 3252 } 3253 3254 ecma_object_t *object_p = ecma_get_object_from_value (obj_val); 3255 ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE); 3256 3257#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 3258 if (names_p == NULL) 3259 { 3260 // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release 3261 jcontext_release_exception (); 3262 return false; 3263 } 3264#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 3265 3266 ecma_value_t *buffer_p = names_p->buffer_p; 3267 3268 ecma_value_t property_value = ECMA_VALUE_EMPTY; 3269 3270 bool continuous = true; 3271 3272 for (uint32_t i = 0; continuous && (i < names_p->item_count); i++) 3273 { 3274 ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); 3275 3276 property_value = ecma_op_object_get (object_p, property_name_p); 3277 3278 if (ECMA_IS_VALUE_ERROR (property_value)) 3279 { 3280 break; 3281 } 3282 3283 continuous = foreach_p (buffer_p[i], property_value, user_data_p); 3284 ecma_free_value (property_value); 3285 } 3286 3287 ecma_collection_free (names_p); 3288 3289 if (!ECMA_IS_VALUE_ERROR (property_value)) 3290 { 3291 return true; 3292 } 3293 3294 jcontext_release_exception (); 3295 return false; 3296} /* jerry_foreach_object_property */ 3297 3298/** 3299 * Resolve or reject the promise with an argument. 3300 * 3301 * @return undefined value - if success 3302 * value marked with error flag - otherwise 3303 */ 3304jerry_value_t 3305jerry_resolve_or_reject_promise (jerry_value_t promise, /**< the promise value */ 3306 jerry_value_t argument, /**< the argument */ 3307 bool is_resolve) /**< whether the promise should be resolved or rejected */ 3308{ 3309 jerry_assert_api_available (); 3310 3311#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 3312 if (!ecma_is_value_object (promise) || !ecma_is_promise (ecma_get_object_from_value (promise))) 3313 { 3314 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 3315 } 3316 3317 if (ecma_is_value_error_reference (argument)) 3318 { 3319 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 3320 } 3321 3322 lit_magic_string_id_t prop_name = (is_resolve ? LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION 3323 : LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION); 3324 3325 ecma_value_t function = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (promise), prop_name); 3326 3327 ecma_value_t ret = ecma_op_function_call (ecma_get_object_from_value (function), 3328 ECMA_VALUE_UNDEFINED, 3329 &argument, 3330 1); 3331 3332 ecma_free_value (function); 3333 3334 return ret; 3335#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 3336 JERRY_UNUSED (promise); 3337 JERRY_UNUSED (argument); 3338 JERRY_UNUSED (is_resolve); 3339 3340 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported."))); 3341#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 3342} /* jerry_resolve_or_reject_promise */ 3343 3344/** 3345 * Get the result of a promise. 3346 * 3347 * @return - Promise result 3348 * - Type error if the promise support was not enabled or the input was not a promise object 3349 */ 3350jerry_value_t 3351jerry_get_promise_result (const jerry_value_t promise) /**< promise object to get the result from */ 3352{ 3353 jerry_assert_api_available (); 3354 3355#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 3356 if (!jerry_value_is_promise (promise)) 3357 { 3358 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 3359 } 3360 3361 return ecma_promise_get_result (ecma_get_object_from_value (promise)); 3362#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 3363 JERRY_UNUSED (promise); 3364 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported."))); 3365#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 3366} /* jerry_get_promise_result */ 3367 3368/** 3369 * Get the state of a promise object. 3370 * 3371 * @return - the state of the promise (one of the jerry_promise_state_t enum values) 3372 * - JERRY_PROMISE_STATE_NONE is only returned if the input is not a promise object 3373 * or the promise support was not enabled. 3374 */ 3375jerry_promise_state_t 3376jerry_get_promise_state (const jerry_value_t promise) /**< promise object to get the state from */ 3377{ 3378 jerry_assert_api_available (); 3379 3380#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 3381 if (!jerry_value_is_promise (promise)) 3382 { 3383 return JERRY_PROMISE_STATE_NONE; 3384 } 3385 3386 uint16_t flags = ecma_promise_get_flags (ecma_get_object_from_value (promise)); 3387 flags &= (ECMA_PROMISE_IS_PENDING | ECMA_PROMISE_IS_FULFILLED); 3388 3389 return (flags ? flags : JERRY_PROMISE_STATE_REJECTED); 3390#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 3391 JERRY_UNUSED (promise); 3392 return JERRY_PROMISE_STATE_NONE; 3393#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 3394} /* jerry_get_promise_state */ 3395 3396/** 3397 * Call the SymbolDescriptiveString ecma builtin operation on the symbol value. 3398 * 3399 * Note: 3400 * returned value must be freed with jerry_release_value, when it is no longer needed. 3401 * 3402 * @return string value containing the symbol's descriptive string - if success 3403 * thrown error - otherwise 3404 */ 3405jerry_value_t 3406jerry_get_symbol_descriptive_string (const jerry_value_t symbol) /**< symbol value */ 3407{ 3408 jerry_assert_api_available (); 3409 3410#if ENABLED (JERRY_ES2015) 3411 if (!ecma_is_value_symbol (symbol)) 3412 { 3413 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 3414 } 3415 3416 /* Note: This operation cannot throw an error */ 3417 return ecma_get_symbol_descriptive_string (symbol); 3418#else /* !ENABLED (JERRY_ES2015) */ 3419 JERRY_UNUSED (symbol); 3420 3421 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Symbol is not supported."))); 3422#endif /* ENABLED (JERRY_ES2015) */ 3423} /** jerry_get_symbol_descriptive_string */ 3424 3425/** 3426 * Validate UTF-8 string 3427 * 3428 * @return true - if UTF-8 string is well-formed 3429 * false - otherwise 3430 */ 3431bool 3432jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, /**< UTF-8 string */ 3433 jerry_size_t buf_size) /**< string size */ 3434{ 3435 return lit_is_valid_utf8_string ((lit_utf8_byte_t *) utf8_buf_p, 3436 (lit_utf8_size_t) buf_size); 3437} /* jerry_is_valid_utf8_string */ 3438 3439/** 3440 * Validate CESU-8 string 3441 * 3442 * @return true - if CESU-8 string is well-formed 3443 * false - otherwise 3444 */ 3445bool 3446jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string */ 3447 jerry_size_t buf_size) /**< string size */ 3448{ 3449 return lit_is_valid_cesu8_string ((lit_utf8_byte_t *) cesu8_buf_p, 3450 (lit_utf8_size_t) buf_size); 3451} /* jerry_is_valid_cesu8_string */ 3452 3453/** 3454 * Allocate memory on the engine's heap. 3455 * 3456 * Note: 3457 * This function may take away memory from the executed JavaScript code. 3458 * If any other dynamic memory allocation API is available (e.g., libc 3459 * malloc), it should be used instead. 3460 * 3461 * @return allocated memory on success 3462 * NULL otherwise 3463 */ 3464void * 3465jerry_heap_alloc (size_t size) /**< size of the memory block */ 3466{ 3467 jerry_assert_api_available (); 3468 3469 return jmem_heap_alloc_block_null_on_error (size); 3470} /* jerry_heap_alloc */ 3471 3472/** 3473 * Free memory allocated on the engine's heap. 3474 */ 3475void 3476jerry_heap_free (void *mem_p, /**< value returned by jerry_heap_alloc */ 3477 size_t size) /**< same size as passed to jerry_heap_alloc */ 3478{ 3479 jerry_assert_api_available (); 3480 3481 jmem_heap_free_block (mem_p, size); 3482} /* jerry_heap_free */ 3483 3484/** 3485 * Create an external engine context. 3486 * 3487 * @return the pointer to the context. 3488 */ 3489jerry_context_t * 3490jerry_create_context (uint32_t heap_size, /**< the size of heap */ 3491 jerry_context_alloc_t alloc, /**< the alloc function */ 3492 void *cb_data_p) /**< the cb_data for alloc function */ 3493{ 3494 JERRY_UNUSED (heap_size); 3495 3496#if ENABLED (JERRY_EXTERNAL_CONTEXT) 3497 3498 size_t total_size = sizeof (jerry_context_t) + JMEM_ALIGNMENT; 3499 3500#if !ENABLED (JERRY_SYSTEM_ALLOCATOR) 3501 heap_size = JERRY_ALIGNUP (heap_size, JMEM_ALIGNMENT); 3502 3503 /* Minimum heap size is 1Kbyte. */ 3504 if (heap_size < 1024) 3505 { 3506 return NULL; 3507 } 3508 3509 total_size += heap_size; 3510#endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ 3511 3512 total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT); 3513 3514 jerry_context_t *context_p = (jerry_context_t *) alloc (total_size, cb_data_p); 3515 3516 if (context_p == NULL) 3517 { 3518 return NULL; 3519 } 3520 3521 memset (context_p, 0, total_size); 3522 3523 uintptr_t context_ptr = ((uintptr_t) context_p) + sizeof (jerry_context_t); 3524 context_ptr = JERRY_ALIGNUP (context_ptr, (uintptr_t) JMEM_ALIGNMENT); 3525 3526 uint8_t *byte_p = (uint8_t *) context_ptr; 3527 3528#if !ENABLED (JERRY_SYSTEM_ALLOCATOR) 3529 context_p->heap_p = (jmem_heap_t *) byte_p; 3530 context_p->heap_size = heap_size; 3531 byte_p += heap_size; 3532#endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ 3533 3534 JERRY_ASSERT (byte_p <= ((uint8_t *) context_p) + total_size); 3535 3536 JERRY_UNUSED (byte_p); 3537 return context_p; 3538 3539#else /* !ENABLED (JERRY_EXTERNAL_CONTEXT) */ 3540 3541 JERRY_UNUSED (alloc); 3542 JERRY_UNUSED (cb_data_p); 3543 3544 return NULL; 3545 3546#endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */ 3547} /* jerry_create_context */ 3548 3549/** 3550 * If JERRY_VM_EXEC_STOP is enabled the callback passed to this function is 3551 * periodically called with the user_p argument. If frequency is greater 3552 * than 1, the callback is only called at every frequency ticks. 3553 */ 3554void 3555jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< periodically called user function */ 3556 void *user_p, /**< pointer passed to the function */ 3557 uint32_t frequency) /**< frequency of the function call */ 3558{ 3559#if ENABLED (JERRY_VM_EXEC_STOP) 3560 if (frequency == 0) 3561 { 3562 frequency = 1; 3563 } 3564 3565 JERRY_CONTEXT (vm_exec_stop_frequency) = frequency; 3566 JERRY_CONTEXT (vm_exec_stop_counter) = frequency; 3567 JERRY_CONTEXT (vm_exec_stop_user_p) = user_p; 3568 JERRY_CONTEXT (vm_exec_stop_cb) = stop_cb; 3569#else /* !ENABLED (JERRY_VM_EXEC_STOP) */ 3570 JERRY_UNUSED (stop_cb); 3571 JERRY_UNUSED (user_p); 3572 JERRY_UNUSED (frequency); 3573#endif /* ENABLED (JERRY_VM_EXEC_STOP) */ 3574} /* jerry_set_vm_exec_stop_callback */ 3575 3576/** 3577 * Get backtrace. The backtrace is an array of strings where 3578 * each string contains the position of the corresponding frame. 3579 * The array length is zero if the backtrace is not available. 3580 * 3581 * @return array value 3582 */ 3583jerry_value_t 3584jerry_get_backtrace (uint32_t max_depth) /**< depth limit of the backtrace */ 3585{ 3586 return vm_get_backtrace (max_depth); 3587} /* jerry_get_backtrace */ 3588 3589/** 3590 * Get the resource name (usually a file name) of the currently executed script or the given function object 3591 * 3592 * Note: returned value must be freed with jerry_release_value, when it is no longer needed 3593 * 3594 * @return JS string constructed from 3595 * - the currently executed function object's resource name, if the given value is undefined 3596 * - resource name of the function object, if the given value is a function object 3597 * - "<anonymous>", otherwise 3598 */ 3599jerry_value_t 3600jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */ 3601{ 3602#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) 3603 if (ecma_is_value_undefined (value)) 3604 { 3605 if (JERRY_CONTEXT (vm_top_context_p) != NULL) 3606 { 3607 return ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->resource_name); 3608 } 3609 } 3610#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 3611#if ENABLED (JERRY_LINE_INFO) 3612 else if (ecma_is_value_object (value)) 3613 { 3614 ecma_object_t *obj_p = ecma_get_object_from_value (value); 3615 3616 if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION 3617 && !ecma_get_object_is_builtin (obj_p)) 3618 { 3619 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p; 3620 3621 const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); 3622 3623 return ecma_copy_value (ecma_op_resource_name (bytecode_data_p)); 3624 } 3625 } 3626#endif /* ENABLED (JERRY_LINE_INFO) */ 3627 3628 JERRY_UNUSED (value); 3629 return ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON); 3630} /* jerry_get_resource_name */ 3631 3632/** 3633 * Access the "new.target" value. 3634 * 3635 * The "new.target" value depends on the current call site. That is 3636 * this method will only have a function object result if, at the call site 3637 * it was called inside a constructor method invoked with "new". 3638 * 3639 * @return "undefined" - if at the call site it was not a constructor call. 3640 * function object - if the current call site is in a constructor call. 3641 */ 3642jerry_value_t 3643jerry_get_new_target (void) 3644{ 3645#if ENABLED (JERRY_ES2015) 3646 ecma_object_t *current_new_target = JERRY_CONTEXT (current_new_target); 3647 3648 if (current_new_target == NULL) 3649 { 3650 return jerry_create_undefined (); 3651 } 3652 3653 ecma_ref_object (current_new_target); 3654 return ecma_make_object_value (current_new_target); 3655#else /* !ENABLED (JERRY_ES2015) */ 3656 return jerry_create_undefined (); 3657#endif /* ENABLED (JERRY_ES2015) */ 3658} /* jerry_get_new_target */ 3659 3660/** 3661 * Check if the given value is an ArrayBuffer object. 3662 * 3663 * @return true - if it is an ArrayBuffer object 3664 * false - otherwise 3665 */ 3666bool 3667jerry_value_is_arraybuffer (const jerry_value_t value) /**< value to check if it is an ArrayBuffer */ 3668{ 3669 jerry_assert_api_available (); 3670 3671#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3672 return ecma_is_arraybuffer (value); 3673#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3674 JERRY_UNUSED (value); 3675 return false; 3676#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3677} /* jerry_value_is_arraybuffer */ 3678 3679/** 3680 * Creates an ArrayBuffer object with the given length (size). 3681 * 3682 * Notes: 3683 * * the length is specified in bytes. 3684 * * returned value must be freed with jerry_release_value, when it is no longer needed. 3685 * * if the typed arrays are disabled this will return a TypeError. 3686 * 3687 * @return value of the constructed ArrayBuffer object 3688 */ 3689jerry_value_t 3690jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffer to create */ 3691{ 3692 jerry_assert_api_available (); 3693 3694#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3695 return jerry_return (ecma_make_object_value (ecma_arraybuffer_new_object (size))); 3696#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3697 JERRY_UNUSED (size); 3698 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported."))); 3699#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3700} /* jerry_create_arraybuffer */ 3701 3702/** 3703 * Creates an ArrayBuffer object with user specified buffer. 3704 * 3705 * Notes: 3706 * * the size is specified in bytes. 3707 * * the buffer passed should be at least the specified bytes big. 3708 * * if the typed arrays are disabled this will return a TypeError. 3709 * * if the size is zero or buffer_p is a null pointer this will return an empty ArrayBuffer. 3710 * 3711 * @return value of the construced ArrayBuffer object 3712 */ 3713jerry_value_t 3714jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the buffer to used */ 3715 uint8_t *buffer_p, /**< buffer to use as the ArrayBuffer's backing */ 3716 jerry_object_native_free_callback_t free_cb) /**< buffer free callback */ 3717{ 3718 jerry_assert_api_available (); 3719 3720#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3721 ecma_object_t *arraybuffer; 3722 3723 if (JERRY_UNLIKELY (size == 0 || buffer_p == NULL)) 3724 { 3725 arraybuffer = ecma_arraybuffer_new_object_external (0, NULL, (ecma_object_native_free_callback_t) free_cb); 3726 } 3727 else 3728 { 3729 arraybuffer = ecma_arraybuffer_new_object_external (size, 3730 buffer_p, 3731 (ecma_object_native_free_callback_t) free_cb); 3732 } 3733 3734 return jerry_return (ecma_make_object_value (arraybuffer)); 3735#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3736 JERRY_UNUSED (size); 3737 JERRY_UNUSED (buffer_p); 3738 JERRY_UNUSED (free_cb); 3739 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported."))); 3740#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3741} /* jerry_create_arraybuffer_external */ 3742 3743/** 3744 * Copy bytes into the ArrayBuffer from a buffer. 3745 * 3746 * Note: 3747 * * if the object passed is not an ArrayBuffer will return 0. 3748 * 3749 * @return number of bytes copied into the ArrayBuffer. 3750 */ 3751jerry_length_t 3752jerry_arraybuffer_write (const jerry_value_t value, /**< target ArrayBuffer */ 3753 jerry_length_t offset, /**< start offset of the ArrayBuffer */ 3754 const uint8_t *buf_p, /**< buffer to copy from */ 3755 jerry_length_t buf_size) /**< number of bytes to copy from the buffer */ 3756{ 3757 jerry_assert_api_available (); 3758 3759#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3760 if (!ecma_is_arraybuffer (value)) 3761 { 3762 return 0; 3763 } 3764 3765 ecma_object_t *buffer_p = ecma_get_object_from_value (value); 3766 jerry_length_t length = ecma_arraybuffer_get_length (buffer_p); 3767 3768 if (offset >= length) 3769 { 3770 return 0; 3771 } 3772 3773 jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size); 3774 3775 if (copy_count > 0) 3776 { 3777 lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p); 3778 3779 memcpy ((void *) (mem_buffer_p + offset), (void *) buf_p, copy_count); 3780 } 3781 3782 return copy_count; 3783#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3784 JERRY_UNUSED (value); 3785 JERRY_UNUSED (offset); 3786 JERRY_UNUSED (buf_p); 3787 JERRY_UNUSED (buf_size); 3788 return 0; 3789#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3790} /* jerry_arraybuffer_write */ 3791 3792/** 3793 * Copy bytes from a buffer into an ArrayBuffer. 3794 * 3795 * Note: 3796 * * if the object passed is not an ArrayBuffer will return 0. 3797 * 3798 * @return number of bytes read from the ArrayBuffer. 3799 */ 3800jerry_length_t 3801jerry_arraybuffer_read (const jerry_value_t value, /**< ArrayBuffer to read from */ 3802 jerry_length_t offset, /**< start offset of the ArrayBuffer */ 3803 uint8_t *buf_p, /**< destination buffer to copy to */ 3804 jerry_length_t buf_size) /**< number of bytes to copy into the buffer */ 3805{ 3806 jerry_assert_api_available (); 3807 3808#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3809 if (!ecma_is_arraybuffer (value)) 3810 { 3811 return 0; 3812 } 3813 3814 ecma_object_t *buffer_p = ecma_get_object_from_value (value); 3815 jerry_length_t length = ecma_arraybuffer_get_length (buffer_p); 3816 3817 if (offset >= length) 3818 { 3819 return 0; 3820 } 3821 3822 jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size); 3823 3824 if (copy_count > 0) 3825 { 3826 lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p); 3827 3828 memcpy ((void *) buf_p, (void *) (mem_buffer_p + offset), copy_count); 3829 } 3830 3831 return copy_count; 3832#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3833 JERRY_UNUSED (value); 3834 JERRY_UNUSED (offset); 3835 JERRY_UNUSED (buf_p); 3836 JERRY_UNUSED (buf_size); 3837 return 0; 3838#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3839} /* jerry_arraybuffer_read */ 3840 3841/** 3842 * Get the length (size) of the ArrayBuffer in bytes. 3843 * 3844 * Note: 3845 * This is the 'byteLength' property of an ArrayBuffer. 3846 * 3847 * @return the length of the ArrayBuffer in bytes. 3848 */ 3849jerry_length_t 3850jerry_get_arraybuffer_byte_length (const jerry_value_t value) /**< ArrayBuffer */ 3851{ 3852 jerry_assert_api_available (); 3853 3854#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3855 if (ecma_is_arraybuffer (value)) 3856 { 3857 ecma_object_t *buffer_p = ecma_get_object_from_value (value); 3858 return ecma_arraybuffer_get_length (buffer_p); 3859 } 3860#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3861 JERRY_UNUSED (value); 3862#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3863 return 0; 3864} /* jerry_get_arraybuffer_byte_length */ 3865 3866/** 3867 * Get a pointer for the start of the ArrayBuffer. 3868 * 3869 * Note: 3870 * * This is a high-risk operation as the bounds are not checked 3871 * when accessing the pointer elements. 3872 * 3873 * @return pointer to the back-buffer of the ArrayBuffer. 3874 * pointer is NULL if the parameter is not an ArrayBuffer 3875 */ 3876uint8_t * 3877jerry_get_arraybuffer_pointer (const jerry_value_t array_buffer) /**< Array Buffer to use */ 3878{ 3879 jerry_assert_api_available (); 3880 3881#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3882 if (ecma_is_value_error_reference (array_buffer) 3883 || !ecma_is_arraybuffer (array_buffer)) 3884 { 3885 return NULL; 3886 } 3887 3888 ecma_object_t *buffer_p = ecma_get_object_from_value (array_buffer); 3889 lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p); 3890 return (uint8_t *const) mem_buffer_p; 3891#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3892 JERRY_UNUSED (array_buffer); 3893#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3894 3895 return NULL; 3896} /* jerry_get_arraybuffer_pointer */ 3897 3898/** 3899 * Get if the ArrayBuffer is detachable. 3900 * 3901 * @return boolean value - if success 3902 * value marked with error flag - otherwise 3903 */ 3904jerry_value_t 3905jerry_is_arraybuffer_detachable (const jerry_value_t value) /**< ArrayBuffer */ 3906{ 3907 jerry_assert_api_available (); 3908 3909#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3910 if (ecma_is_arraybuffer (value)) 3911 { 3912 ecma_object_t *buffer_p = ecma_get_object_from_value (value); 3913 return ecma_arraybuffer_is_detachable (buffer_p) ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE; 3914 } 3915#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3916 JERRY_UNUSED (value); 3917#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3918 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects an ArrayBuffer"))); 3919} /* jerry_is_arraybuffer_detachable */ 3920 3921/** 3922 * Detach the underlying data block from ArrayBuffer and set its bytelength to 0. 3923 * This operation requires the ArrayBuffer to be external that created by 3924 * `jerry_create_arraybuffer_external`. 3925 * 3926 * @return null value - if success 3927 * value marked with error flag - otherwise 3928 */ 3929jerry_value_t 3930jerry_detach_arraybuffer (const jerry_value_t value) /**< ArrayBuffer */ 3931{ 3932 jerry_assert_api_available (); 3933 3934#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 3935 if (ecma_is_arraybuffer (value)) 3936 { 3937 ecma_object_t *buffer_p = ecma_get_object_from_value (value); 3938 bool detached = ecma_arraybuffer_detach (buffer_p); 3939 if (!detached) 3940 { 3941 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects a detachable ArrayBuffer."))); 3942 } 3943 return ECMA_VALUE_NULL; 3944 } 3945#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3946 JERRY_UNUSED (value); 3947#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 3948 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects an ArrayBuffer"))); 3949} /* jerry_detach_arraybuffer */ 3950 3951/** 3952 * DataView related functions 3953 */ 3954 3955/** 3956 * Creates a DataView object with the given ArrayBuffer, ByteOffset and ByteLength arguments. 3957 * 3958 * Notes: 3959 * * returned value must be freed with jerry_release_value, when it is no longer needed. 3960 * * if the DataView bulitin is disabled this will return a TypeError. 3961 * 3962 * @return value of the constructed DataView object - if success 3963 * created error - otherwise 3964 */ 3965jerry_value_t 3966jerry_create_dataview (const jerry_value_t array_buffer, /**< arraybuffer to create DataView from */ 3967 const jerry_length_t byte_offset, /**< offset in bytes, to the first byte in the buffer */ 3968 const jerry_length_t byte_length) /**< number of elements in the byte array */ 3969{ 3970 jerry_assert_api_available (); 3971 3972#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) 3973 if (ecma_is_value_error_reference (array_buffer)) 3974 { 3975 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 3976 } 3977 3978 ecma_value_t arguments_p[3] = 3979 { 3980 array_buffer, 3981 ecma_make_uint32_value (byte_offset), 3982 ecma_make_uint32_value (byte_length) 3983 }; 3984 3985 return jerry_return (ecma_op_dataview_create (arguments_p, 3)); 3986#else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */ 3987 JERRY_UNUSED (array_buffer); 3988 JERRY_UNUSED (byte_offset); 3989 JERRY_UNUSED (byte_length); 3990 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("DataView is not supported."))); 3991#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */ 3992} /* jerry_create_dataview */ 3993 3994/** 3995 * Check if the given value is a DataView object. 3996 * 3997 * @return true - if it is a DataView object 3998 * false - otherwise 3999 */ 4000bool 4001jerry_value_is_dataview (const jerry_value_t value) /**< value to check if it is a DataView object */ 4002{ 4003 jerry_assert_api_available (); 4004 4005#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) 4006 return ecma_is_dataview (value); 4007#else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */ 4008 JERRY_UNUSED (value); 4009 return false; 4010#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */ 4011} /* jerry_value_is_dataview */ 4012 4013/** 4014 * Get the underlying ArrayBuffer from a DataView. 4015 * 4016 * Additionally the byteLength and byteOffset properties are also returned 4017 * which were specified when the DataView was created. 4018 * 4019 * Note: 4020 * the returned value must be freed with a jerry_release_value call 4021 * 4022 * @return ArrayBuffer of a DataView 4023 * TypeError if the object is not a DataView. 4024 */ 4025jerry_value_t 4026jerry_get_dataview_buffer (const jerry_value_t value, /**< DataView to get the arraybuffer from */ 4027 jerry_length_t *byte_offset, /**< [out] byteOffset property */ 4028 jerry_length_t *byte_length) /**< [out] byteLength property */ 4029{ 4030 jerry_assert_api_available (); 4031 4032#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) 4033 if (ecma_is_value_error_reference (value)) 4034 { 4035 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); 4036 } 4037 4038 ecma_dataview_object_t *dataview_p = ecma_op_dataview_get_object (value); 4039 4040 if (JERRY_UNLIKELY (dataview_p == NULL)) 4041 { 4042 return ecma_create_error_reference_from_context (); 4043 } 4044 4045 if (byte_offset != NULL) 4046 { 4047 *byte_offset = dataview_p->byte_offset; 4048 } 4049 4050 if (byte_length != NULL) 4051 { 4052 *byte_length = dataview_p->header.u.class_prop.u.length; 4053 } 4054 4055 ecma_object_t *arraybuffer_p = dataview_p->buffer_p; 4056 ecma_ref_object (arraybuffer_p); 4057 4058 return ecma_make_object_value (arraybuffer_p); 4059#else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */ 4060 JERRY_UNUSED (value); 4061 JERRY_UNUSED (byte_offset); 4062 JERRY_UNUSED (byte_length); 4063 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("DataView is not supported."))); 4064#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */ 4065} /* jerry_get_dataview_buffer */ 4066 4067/** 4068 * TypedArray related functions 4069 */ 4070 4071/** 4072 * Check if the given value is a TypedArray object. 4073 * 4074 * @return true - if it is a TypedArray object 4075 * false - otherwise 4076 */ 4077bool 4078jerry_value_is_typedarray (jerry_value_t value) /**< value to check if it is a TypedArray */ 4079{ 4080 jerry_assert_api_available (); 4081 4082#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4083 return ecma_is_typedarray (value); 4084#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4085 JERRY_UNUSED (value); 4086 return false; 4087#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4088} /* jerry_value_is_typedarray */ 4089 4090#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4091/** 4092 * TypedArray mapping type 4093 */ 4094typedef struct 4095{ 4096 jerry_typedarray_type_t api_type; /**< api type */ 4097 ecma_builtin_id_t prototype_id; /**< prototype ID */ 4098 ecma_typedarray_type_t id; /**< typedArray ID */ 4099 uint8_t element_size_shift; /**< element size shift */ 4100} jerry_typedarray_mapping_t; 4101 4102/** 4103 * List of TypedArray mappings 4104 */ 4105static jerry_typedarray_mapping_t jerry_typedarray_mappings[] = 4106{ 4107#define TYPEDARRAY_ENTRY(NAME, LIT_NAME, SIZE_SHIFT) \ 4108 { JERRY_TYPEDARRAY_ ## NAME, ECMA_BUILTIN_ID_ ## NAME ## ARRAY_PROTOTYPE, \ 4109 ECMA_ ## LIT_NAME ## _ARRAY, SIZE_SHIFT } 4110 4111 TYPEDARRAY_ENTRY (UINT8, UINT8, 0), 4112 TYPEDARRAY_ENTRY (UINT8CLAMPED, UINT8_CLAMPED, 0), 4113 TYPEDARRAY_ENTRY (INT8, INT8, 0), 4114 TYPEDARRAY_ENTRY (UINT16, UINT16, 1), 4115 TYPEDARRAY_ENTRY (INT16, INT16, 1), 4116 TYPEDARRAY_ENTRY (UINT32, UINT32, 2), 4117 TYPEDARRAY_ENTRY (INT32, INT32, 2), 4118 TYPEDARRAY_ENTRY (FLOAT32, FLOAT32, 2), 4119#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) 4120 TYPEDARRAY_ENTRY (FLOAT64, FLOAT64, 3), 4121#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ 4122 4123#undef TYPEDARRAY_ENTRY 4124}; 4125 4126/** 4127 * Helper function to get the TypedArray prototype, typedArray id, and element size shift 4128 * information. 4129 * 4130 * @return true - if the TypedArray information was found 4131 * false - if there is no such TypedArray type 4132 */ 4133static bool 4134jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of the TypedArray */ 4135 ecma_builtin_id_t *prototype_id, /**< [out] found prototype object id */ 4136 ecma_typedarray_type_t *id, /**< [out] found typedArray id */ 4137 uint8_t *element_size_shift) /**< [out] found element size shift value */ 4138{ 4139 JERRY_ASSERT (prototype_id != NULL); 4140 JERRY_ASSERT (id != NULL); 4141 JERRY_ASSERT (element_size_shift != NULL); 4142 4143 for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++) 4144 { 4145 if (type_name == jerry_typedarray_mappings[i].api_type) 4146 { 4147 *prototype_id = jerry_typedarray_mappings[i].prototype_id; 4148 *id = jerry_typedarray_mappings[i].id; 4149 *element_size_shift = jerry_typedarray_mappings[i].element_size_shift; 4150 return true; 4151 } 4152 } 4153 4154 return false; 4155} /* jerry_typedarray_find_by_type */ 4156 4157#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4158 4159/** 4160 * Create a TypedArray object with a given type and length. 4161 * 4162 * Notes: 4163 * * returns TypeError if an incorrect type (type_name) is specified. 4164 * * byteOffset property will be set to 0. 4165 * * byteLength property will be a multiple of the length parameter (based on the type). 4166 * 4167 * @return - new TypedArray object 4168 */ 4169jerry_value_t 4170jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */ 4171 jerry_length_t length) /**< element count of the new TypedArray */ 4172{ 4173 jerry_assert_api_available (); 4174 4175#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4176 ecma_builtin_id_t prototype_id = 0; 4177 ecma_typedarray_type_t id = 0; 4178 uint8_t element_size_shift = 0; 4179 4180 if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift)) 4181 { 4182 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray."))); 4183 } 4184 4185 ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id); 4186 4187 ecma_value_t array_value = ecma_typedarray_create_object_with_length (length, 4188 NULL, 4189 prototype_obj_p, 4190 element_size_shift, 4191 id); 4192 4193 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value)); 4194 4195 return array_value; 4196#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4197 JERRY_UNUSED (type_name); 4198 JERRY_UNUSED (length); 4199 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported."))); 4200#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4201} /* jerry_create_typedarray */ 4202 4203/** 4204 * Create a TypedArray object using the given arraybuffer and size information. 4205 * 4206 * Notes: 4207 * * returns TypeError if an incorrect type (type_name) is specified. 4208 * * this is the 'new %TypedArray%(arraybuffer, byteOffset, length)' equivalent call. 4209 * 4210 * @return - new TypedArray object 4211 */ 4212jerry_value_t 4213jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */ 4214 const jerry_value_t arraybuffer, /**< ArrayBuffer to use */ 4215 jerry_length_t byte_offset, /**< offset for the ArrayBuffer */ 4216 jerry_length_t length) /**< number of elements to use from ArrayBuffer */ 4217{ 4218 jerry_assert_api_available (); 4219 4220#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4221 if (ecma_is_value_error_reference (arraybuffer)) 4222 { 4223 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 4224 } 4225 4226 ecma_builtin_id_t prototype_id = 0; 4227 ecma_typedarray_type_t id = 0; 4228 uint8_t element_size_shift = 0; 4229 4230 if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift)) 4231 { 4232 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray."))); 4233 } 4234 4235 if (!ecma_is_arraybuffer (arraybuffer)) 4236 { 4237 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an ArrayBuffer"))); 4238 } 4239 4240 ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id); 4241 ecma_value_t arguments_p[3] = 4242 { 4243 arraybuffer, 4244 ecma_make_uint32_value (byte_offset), 4245 ecma_make_uint32_value (length) 4246 }; 4247 4248 ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, id); 4249 ecma_free_value (arguments_p[1]); 4250 ecma_free_value (arguments_p[2]); 4251 4252 return jerry_return (array_value); 4253#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4254 JERRY_UNUSED (type_name); 4255 JERRY_UNUSED (arraybuffer); 4256 JERRY_UNUSED (byte_offset); 4257 JERRY_UNUSED (length); 4258 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported."))); 4259#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4260} /* jerry_create_typedarray_for_arraybuffer_sz */ 4261 4262/** 4263 * Create a TypedArray object using the given arraybuffer and size information. 4264 * 4265 * Notes: 4266 * * returns TypeError if an incorrect type (type_name) is specified. 4267 * * this is the 'new %TypedArray%(arraybuffer)' equivalent call. 4268 * 4269 * @return - new TypedArray object 4270 */ 4271jerry_value_t 4272jerry_create_typedarray_for_arraybuffer (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */ 4273 const jerry_value_t arraybuffer) /**< ArrayBuffer to use */ 4274{ 4275 jerry_assert_api_available (); 4276 4277#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4278 if (ecma_is_value_error_reference (arraybuffer)) 4279 { 4280 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 4281 } 4282 4283 jerry_length_t byteLength = jerry_get_arraybuffer_byte_length (arraybuffer); 4284 return jerry_create_typedarray_for_arraybuffer_sz (type_name, arraybuffer, 0, byteLength); 4285#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4286 JERRY_UNUSED (type_name); 4287 JERRY_UNUSED (arraybuffer); 4288 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported."))); 4289#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4290} /* jerry_create_typedarray_for_arraybuffer */ 4291 4292/** 4293 * Get the type of the TypedArray. 4294 * 4295 * @return - type of the TypedArray 4296 * - JERRY_TYPEDARRAY_INVALID if the argument is not a TypedArray 4297 */ 4298jerry_typedarray_type_t 4299jerry_get_typedarray_type (jerry_value_t value) /**< object to get the TypedArray type */ 4300{ 4301 jerry_assert_api_available (); 4302 4303#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4304 if (!ecma_is_typedarray (value)) 4305 { 4306 return JERRY_TYPEDARRAY_INVALID; 4307 } 4308 4309 ecma_object_t *array_p = ecma_get_object_from_value (value); 4310 ecma_typedarray_type_t class_type = ecma_get_typedarray_id (array_p); 4311 4312 for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++) 4313 { 4314 if (class_type == jerry_typedarray_mappings[i].id) 4315 { 4316 return jerry_typedarray_mappings[i].api_type; 4317 } 4318 } 4319#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4320 JERRY_UNUSED (value); 4321#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4322 4323 return JERRY_TYPEDARRAY_INVALID; 4324} /* jerry_get_typedarray_type */ 4325 4326/** 4327 * Get the element count of the TypedArray. 4328 * 4329 * @return length of the TypedArray. 4330 */ 4331jerry_length_t 4332jerry_get_typedarray_length (jerry_value_t value) /**< TypedArray to query */ 4333{ 4334 jerry_assert_api_available (); 4335 4336#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4337 if (ecma_is_typedarray (value)) 4338 { 4339 ecma_object_t *array_p = ecma_get_object_from_value (value); 4340 return ecma_typedarray_get_length (array_p); 4341 } 4342#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4343 JERRY_UNUSED (value); 4344#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4345 4346 return 0; 4347} /* jerry_get_typedarray_length */ 4348 4349/** 4350 * Get the underlying ArrayBuffer from a TypedArray. 4351 * 4352 * Additionally the byteLength and byteOffset properties are also returned 4353 * which were specified when the TypedArray was created. 4354 * 4355 * Note: 4356 * the returned value must be freed with a jerry_release_value call 4357 * 4358 * @return ArrayBuffer of a TypedArray 4359 * TypeError if the object is not a TypedArray. 4360 */ 4361jerry_value_t 4362jerry_get_typedarray_buffer (jerry_value_t value, /**< TypedArray to get the arraybuffer from */ 4363 jerry_length_t *byte_offset, /**< [out] byteOffset property */ 4364 jerry_length_t *byte_length) /**< [out] byteLength property */ 4365{ 4366 jerry_assert_api_available (); 4367 4368#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 4369 if (!ecma_is_typedarray (value)) 4370 { 4371 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Object is not a TypedArray."))); 4372 } 4373 4374 ecma_object_t *array_p = ecma_get_object_from_value (value); 4375 uint8_t shift = ecma_typedarray_get_element_size_shift (array_p); 4376 4377 if (byte_length != NULL) 4378 { 4379 *byte_length = (jerry_length_t) (ecma_typedarray_get_length (array_p) << shift); 4380 } 4381 4382 if (byte_offset != NULL) 4383 { 4384 *byte_offset = (jerry_length_t) ecma_typedarray_get_offset (array_p); 4385 } 4386 4387 ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (array_p); 4388 ecma_ref_object (arraybuffer_p); 4389 return jerry_return (ecma_make_object_value (arraybuffer_p)); 4390#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4391 JERRY_UNUSED (value); 4392 JERRY_UNUSED (byte_length); 4393 JERRY_UNUSED (byte_offset); 4394 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray is not supported."))); 4395#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 4396} /* jerry_get_typedarray_buffer */ 4397 4398/** 4399 * Create an object from JSON 4400 * 4401 * Note: 4402 * The returned value must be freed with jerry_release_value 4403 * @return jerry_value_t from json formated string or an error massage 4404 */ 4405jerry_value_t 4406jerry_json_parse (const jerry_char_t *string_p, /**< json string */ 4407 jerry_size_t string_size) /**< json string size */ 4408{ 4409 jerry_assert_api_available (); 4410 4411#if ENABLED (JERRY_BUILTIN_JSON) 4412 ecma_value_t ret_value = ecma_builtin_json_parse_buffer (string_p, string_size); 4413 4414 if (ecma_is_value_undefined (ret_value)) 4415 { 4416 ret_value = jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("JSON string parse error."))); 4417 } 4418 4419 return ret_value; 4420#else /* !ENABLED (JERRY_BUILTIN_JSON) */ 4421 JERRY_UNUSED (string_p); 4422 JERRY_UNUSED (string_size); 4423 4424 return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled."))); 4425#endif /* ENABLED (JERRY_BUILTIN_JSON) */ 4426} /* jerry_json_parse */ 4427 4428/** 4429 * Create a Json formated string from an object 4430 * 4431 * Note: 4432 * The returned value must be freed with jerry_release_value 4433 * @return json formated jerry_value_t or an error massage 4434 */ 4435jerry_value_t 4436jerry_json_stringify (const jerry_value_t object_to_stringify) /**< a jerry_object_t to stringify */ 4437{ 4438 jerry_assert_api_available (); 4439#if ENABLED (JERRY_BUILTIN_JSON) 4440 ecma_value_t ret_value = ecma_builtin_json_string_from_object (object_to_stringify); 4441 4442 if (ecma_is_value_error_reference (object_to_stringify)) 4443 { 4444 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 4445 } 4446 4447 if (ecma_is_value_undefined (ret_value)) 4448 { 4449 ret_value = jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("JSON stringify error."))); 4450 } 4451 4452 return ret_value; 4453#else /* ENABLED (JERRY_BUILTIN_JSON) */ 4454 JERRY_UNUSED (object_to_stringify); 4455 4456 return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled."))); 4457#endif /* ENABLED (JERRY_BUILTIN_JSON) */ 4458} /* jerry_json_stringify */ 4459 4460/** 4461 * Create a container type specified in jerry_container_type_t. 4462 * The container can be created with a list of arguments, which will be passed to the container constructor to be 4463 * inserted to the container. 4464 * 4465 * Note: 4466 * The returned value must be freed with jerry_release_value 4467 * @return jerry_value_t representing a container with the given type. 4468 */ 4469jerry_value_t 4470jerry_create_container (jerry_container_type_t container_type, /**< Type of the container */ 4471 const jerry_value_t *arguments_list_p, /**< arguments list */ 4472 jerry_length_t arguments_list_len) /**< Length of arguments list */ 4473{ 4474 jerry_assert_api_available (); 4475 4476#if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) 4477 for (jerry_length_t i = 0; i < arguments_list_len; i++) 4478 { 4479 if (ecma_is_value_error_reference (arguments_list_p[i])) 4480 { 4481 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); 4482 } 4483 } 4484 4485 lit_magic_string_id_t lit_id; 4486 ecma_builtin_id_t proto_id; 4487 ecma_builtin_id_t ctor_id; 4488 4489 switch (container_type) 4490 { 4491#if ENABLED (JERRY_ES2015_BUILTIN_MAP) 4492 case JERRY_CONTAINER_TYPE_MAP: 4493 { 4494 lit_id = LIT_MAGIC_STRING_MAP_UL; 4495 proto_id = ECMA_BUILTIN_ID_MAP_PROTOTYPE; 4496 ctor_id = ECMA_BUILTIN_ID_MAP; 4497 break; 4498 } 4499#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ 4500#if ENABLED (JERRY_ES2015_BUILTIN_SET) 4501 case JERRY_CONTAINER_TYPE_SET: 4502 { 4503 lit_id = LIT_MAGIC_STRING_SET_UL; 4504 proto_id = ECMA_BUILTIN_ID_SET_PROTOTYPE; 4505 ctor_id = ECMA_BUILTIN_ID_SET; 4506 break; 4507 } 4508#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ 4509#if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) 4510 case JERRY_CONTAINER_TYPE_WEAKMAP: 4511 { 4512 lit_id = LIT_MAGIC_STRING_WEAKMAP_UL; 4513 proto_id = ECMA_BUILTIN_ID_WEAKMAP_PROTOTYPE; 4514 ctor_id = ECMA_BUILTIN_ID_WEAKMAP; 4515 break; 4516 } 4517#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */ 4518#if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) 4519 case JERRY_CONTAINER_TYPE_WEAKSET: 4520 { 4521 lit_id = LIT_MAGIC_STRING_WEAKSET_UL; 4522 proto_id = ECMA_BUILTIN_ID_WEAKSET_PROTOTYPE; 4523 ctor_id = ECMA_BUILTIN_ID_WEAKSET; 4524 break; 4525 } 4526#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */ 4527 default: 4528 { 4529 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Invalid container type."))); 4530 } 4531 } 4532 ecma_object_t * old_new_target_p = JERRY_CONTEXT (current_new_target); 4533 4534 if (old_new_target_p == NULL) 4535 { 4536 JERRY_CONTEXT (current_new_target) = ecma_builtin_get (ctor_id); 4537 } 4538 4539 ecma_value_t container_value = ecma_op_container_create (arguments_list_p, 4540 arguments_list_len, 4541 lit_id, 4542 proto_id); 4543 4544 JERRY_CONTEXT (current_new_target) = old_new_target_p; 4545 return container_value; 4546#else /* !ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */ 4547 JERRY_UNUSED (arguments_list_p); 4548 JERRY_UNUSED (arguments_list_len); 4549 JERRY_UNUSED (container_type); 4550 return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Containers are disabled."))); 4551#endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */ 4552} /* jerry_create_container */ 4553 4554/** 4555 * Get the type of the given container object. 4556 * 4557 * @return Corresponding type to the given container object. 4558 */ 4559jerry_container_type_t 4560jerry_get_container_type (const jerry_value_t value) /**< the container object */ 4561{ 4562 jerry_assert_api_available (); 4563 4564#if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) 4565 if (ecma_is_value_object (value)) 4566 { 4567 ecma_object_t *obj_p = ecma_get_object_from_value (value); 4568 4569 if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS) 4570 { 4571 uint16_t type = ((ecma_extended_object_t *) obj_p)->u.class_prop.class_id; 4572 4573 switch (type) 4574 { 4575#if ENABLED (JERRY_ES2015_BUILTIN_MAP) 4576 case LIT_MAGIC_STRING_MAP_UL: 4577 { 4578 return JERRY_CONTAINER_TYPE_MAP; 4579 } 4580#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ 4581#if ENABLED (JERRY_ES2015_BUILTIN_SET) 4582 case LIT_MAGIC_STRING_SET_UL: 4583 { 4584 return JERRY_CONTAINER_TYPE_SET; 4585 } 4586#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ 4587#if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) 4588 case LIT_MAGIC_STRING_WEAKMAP_UL: 4589 { 4590 return JERRY_CONTAINER_TYPE_WEAKMAP; 4591 } 4592#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */ 4593#if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) 4594 case LIT_MAGIC_STRING_WEAKSET_UL: 4595 { 4596 return JERRY_CONTAINER_TYPE_WEAKSET; 4597 } 4598#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */ 4599 default: 4600 { 4601 return JERRY_CONTAINER_TYPE_INVALID; 4602 } 4603 } 4604 } 4605 } 4606 4607#else /* !ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */ 4608 JERRY_UNUSED (value); 4609#endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */ 4610 return JERRY_CONTAINER_TYPE_INVALID; 4611} /* jerry_get_container_type */ 4612 4613#if defined(JERRY_HEAPDUMP) 4614void JerryHeapdumpRun(const char* filepath) 4615{ 4616 SetHeapdumpTraring(true); 4617 LogHeapdumpInit(filepath); 4618 LogHeapdump("[\n"); 4619 DumpInfoObject(ecma_builtin_get_global(), HEAPDUMP_OBJECT_GLOBAL); 4620 DumpInfoObject(ecma_get_global_environment(), HEAPDUMP_OBJECT_GLOBAL); 4621 ecma_gc_run(); 4622 LogHeapdump("{}]\n"); 4623 SetHeapdumpTraring(false); 4624 LogHeapdumpClose(); 4625} 4626#endif 4627 4628#if defined(JERRY_REF_TRACKER) 4629void JerryRefTrackerStart(const char* filepath) 4630{ 4631 SetRefTrackerEnabled(true); 4632 LogTrackerInit(filepath); 4633} 4634#endif 4635 4636#if defined(JERRY_REF_TRACKER) 4637void JerryRefTrackerStop(void) 4638{ 4639 SetRefTrackerEnabled(false); 4640 LogTrackerClose(); 4641} 4642#endif 4643 4644/** 4645 * @} 4646 */ 4647