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 "common.h" 17 18#include "ecma-alloc.h" 19#include "ecma-array-object.h" 20#include "ecma-builtins.h" 21#include "ecma-builtin-object.h" 22#include "ecma-comparison.h" 23#include "ecma-conversion.h" 24#include "ecma-exceptions.h" 25#include "ecma-function-object.h" 26#include "ecma-gc.h" 27#include "ecma-helpers.h" 28#include "ecma-iterator-object.h" 29#include "ecma-lcache.h" 30#include "ecma-lex-env.h" 31#include "ecma-objects.h" 32#include "ecma-objects-general.h" 33#include "ecma-regexp-object.h" 34#include "ecma-try-catch-macro.h" 35#include "jcontext.h" 36#include "opcodes.h" 37#include "vm.h" 38#include "vm-stack.h" 39#if defined(JERRY_FOR_IAR_CONFIG) 40#include "jerryscript-core.h" 41#endif 42 43/** \addtogroup vm Virtual machine 44 * @{ 45 * 46 * \addtogroup vm_executor Executor 47 * @{ 48 */ 49 50/** 51 * Special constant to represent direct eval code. 52 */ 53#define VM_DIRECT_EVAL ((void *) 0x1) 54 55/** 56 * Get the value of object[property]. 57 * 58 * @return ecma value 59 */ 60static ecma_value_t 61vm_op_get_value (ecma_value_t object, /**< base object */ 62 ecma_value_t property) /**< property name */ 63{ 64 if (ecma_is_value_object (object)) 65 { 66 ecma_object_t *object_p = ecma_get_object_from_value (object); 67 ecma_string_t *property_name_p = NULL; 68 69 if (ecma_is_value_integer_number (property)) 70 { 71 ecma_integer_value_t int_value = ecma_get_integer_from_value (property); 72 73 if (int_value >= 0 && int_value <= ECMA_DIRECT_STRING_MAX_IMM) 74 { 75 if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY) 76 { 77 ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 78 79 if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_object_p) 80 && (uint32_t) int_value < ext_object_p->u.array.length)) 81 { 82 ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp); 83 84 if (JERRY_LIKELY (!ecma_is_value_array_hole (values_p[int_value]))) 85 { 86 return ecma_fast_copy_value (values_p[int_value]); 87 } 88 } 89 } 90 91 property_name_p = (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, 92 (uintptr_t) int_value); 93 } 94 } 95 else if (ecma_is_value_string (property)) 96 { 97 property_name_p = ecma_get_string_from_value (property); 98 } 99 100#if ENABLED (JERRY_ES2015) 101 if (ecma_is_value_symbol (property)) 102 { 103 property_name_p = ecma_get_symbol_from_value (property); 104 } 105#endif /* ENABLED (JERRY_ES2015) */ 106 107 if (property_name_p != NULL) 108 { 109#if ENABLED (JERRY_LCACHE) 110 ecma_property_t *property_p = ecma_lcache_lookup (object_p, property_name_p); 111 112 if (property_p != NULL && 113 ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) 114 { 115 return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value); 116 } 117#endif /* ENABLED (JERRY_LCACHE) */ 118 119 /* There is no need to free the name. */ 120 return ecma_op_object_get (object_p, property_name_p); 121 } 122 } 123 124 if (JERRY_UNLIKELY (ecma_is_value_undefined (object) || ecma_is_value_null (object))) 125 { 126#if ENABLED (JERRY_ERROR_MESSAGES) 127 ecma_value_t error_value = ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE, 128 "Cannot read property '%' of %", 129 property, 130 object); 131#else /* !ENABLED (JERRY_ERROR_MESSAGES) */ 132 ecma_value_t error_value = ecma_raise_type_error (NULL); 133#endif /* ENABLED (JERRY_ERROR_MESSAGES) */ 134 return error_value; 135 } 136 137 ecma_string_t *property_name_p = ecma_op_to_prop_name (property); 138 139 if (property_name_p == NULL) 140 { 141 return ECMA_VALUE_ERROR; 142 } 143 144 ecma_value_t get_value_result = ecma_op_get_value_object_base (object, property_name_p); 145 146 ecma_deref_ecma_string (property_name_p); 147 return get_value_result; 148} /* vm_op_get_value */ 149 150/** 151 * Set the value of object[property]. 152 * 153 * Note: 154 * this function frees its object and property arguments 155 * 156 * @return an ecma value which contains an error 157 * if the property setting is unsuccessful 158 */ 159static ecma_value_t 160vm_op_set_value (ecma_value_t base, /**< base object */ 161 ecma_value_t property, /**< property name */ 162 ecma_value_t value, /**< ecma value */ 163 bool is_strict) /**< strict mode */ 164{ 165 ecma_value_t result = ECMA_VALUE_EMPTY; 166 ecma_object_t *object_p; 167 ecma_string_t *property_p; 168 169 if (JERRY_UNLIKELY (!ecma_is_value_object (base))) 170 { 171 if (JERRY_UNLIKELY (ecma_is_value_null (base) || ecma_is_value_undefined (base))) 172 { 173#if ENABLED (JERRY_ERROR_MESSAGES) 174 result = ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE, 175 "Cannot set property '%' of %", 176 property, 177 base); 178#else /* !ENABLED (JERRY_ERROR_MESSAGES) */ 179 result = ecma_raise_type_error (NULL); 180#endif /* ENABLED (JERRY_ERROR_MESSAGES) */ 181 ecma_free_value (property); 182 return result; 183 } 184 185 if (JERRY_UNLIKELY (!ecma_is_value_prop_name (property))) 186 { 187 property_p = ecma_op_to_string (property); 188 ecma_fast_free_value (property); 189 190 if (JERRY_UNLIKELY (property_p == NULL)) 191 { 192 ecma_free_value (base); 193 return ECMA_VALUE_ERROR; 194 } 195 } 196 else 197 { 198 property_p = ecma_get_prop_name_from_value (property); 199 } 200 201 ecma_value_t object = ecma_op_to_object (base); 202 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (object)); 203 204 object_p = ecma_get_object_from_value (object); 205 ecma_op_ordinary_object_prevent_extensions (object_p); 206 207 result = ecma_op_object_put_with_receiver (object_p, 208 property_p, 209 value, 210 base, 211 is_strict); 212 213 ecma_free_value (base); 214 } 215 else 216 { 217 object_p = ecma_get_object_from_value (base); 218 219 if (JERRY_UNLIKELY (!ecma_is_value_prop_name (property))) 220 { 221 property_p = ecma_op_to_string (property); 222 ecma_fast_free_value (property); 223 224 if (JERRY_UNLIKELY (property_p == NULL)) 225 { 226 ecma_deref_object (object_p); 227 return ECMA_VALUE_ERROR; 228 } 229 } 230 else 231 { 232 property_p = ecma_get_prop_name_from_value (property); 233 } 234 235 if (!ecma_is_lexical_environment (object_p)) 236 { 237 result = ecma_op_object_put_with_receiver (object_p, 238 property_p, 239 value, 240 base, 241 is_strict); 242 } 243 else 244 { 245 result = ecma_op_set_mutable_binding (object_p, 246 property_p, 247 value, 248 is_strict); 249 } 250 } 251 252 ecma_deref_object (object_p); 253 ecma_deref_ecma_string (property_p); 254 return result; 255} /* vm_op_set_value */ 256 257/** Compact bytecode define */ 258#define CBC_OPCODE(arg1, arg2, arg3, arg4) arg4, 259 260/** 261 * Decode table for both opcodes and extended opcodes. 262 */ 263static const uint16_t vm_decode_table[] JERRY_ATTR_CONST_DATA = 264{ 265 CBC_OPCODE_LIST 266 CBC_EXT_OPCODE_LIST 267}; 268 269#undef CBC_OPCODE 270 271#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 272/** 273 * Run ES2015 module code 274 * 275 * Note: 276 * returned value must be freed with ecma_free_value, when it is no longer needed. 277 * 278 * @return ecma value 279 */ 280ecma_value_t 281vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode to run */ 282 ecma_object_t *lex_env_p) /**< pointer to the specified lexenv to run in */ 283{ 284 const ecma_value_t module_init_result = ecma_module_initialize_current (); 285 if (ECMA_IS_VALUE_ERROR (module_init_result)) 286 { 287 return module_init_result; 288 } 289 290 return vm_run (bytecode_p, 291 ECMA_VALUE_UNDEFINED, 292 lex_env_p, 293 NULL, 294 0); 295} /* vm_run_module */ 296#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 297 298/** 299 * Run global code 300 * 301 * Note: 302 * returned value must be freed with ecma_free_value, when it is no longer needed. 303 * 304 * @return ecma value 305 */ 306ecma_value_t 307vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode to run */ 308{ 309 ecma_object_t *glob_obj_p = ecma_builtin_get_global (); 310 311#if ENABLED (JERRY_ES2015) 312 if (bytecode_p->status_flags & CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED) 313 { 314 ecma_create_global_lexical_block (); 315 } 316#endif /* ENABLED (JERRY_ES2015) */ 317 318 ecma_object_t *const global_scope_p = ecma_get_global_scope (); 319 320#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 321 if (JERRY_CONTEXT (module_top_context_p) != NULL) 322 { 323 JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->parent_p == NULL); 324 ecma_module_t *module_p = JERRY_CONTEXT (module_top_context_p)->module_p; 325 326 JERRY_ASSERT (module_p->scope_p == NULL); 327 ecma_ref_object (global_scope_p); 328 module_p->scope_p = global_scope_p; 329 330 const ecma_value_t module_init_result = ecma_module_initialize_current (); 331 ecma_module_cleanup (); 332 JERRY_CONTEXT (module_top_context_p) = NULL; 333 334 if (ECMA_IS_VALUE_ERROR (module_init_result)) 335 { 336 return module_init_result; 337 } 338 } 339#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 340 341 return vm_run (bytecode_p, 342 ecma_make_object_value (glob_obj_p), 343 global_scope_p, 344 NULL, 345 0); 346} /* vm_run_global */ 347 348/** 349 * Run specified eval-mode bytecode 350 * 351 * @return ecma value 352 */ 353ecma_value_t 354vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */ 355 uint32_t parse_opts) /**< ecma_parse_opts_t option bits */ 356{ 357 ecma_value_t this_binding; 358 ecma_object_t *lex_env_p; 359 360 /* ECMA-262 v5, 10.4.2 */ 361 if (parse_opts & ECMA_PARSE_DIRECT_EVAL) 362 { 363 this_binding = ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->this_binding); 364 lex_env_p = JERRY_CONTEXT (vm_top_context_p)->lex_env_p; 365 366#if ENABLED (JERRY_DEBUGGER) 367 uint32_t chain_index = parse_opts >> ECMA_PARSE_CHAIN_INDEX_SHIFT; 368 parse_opts &= (1 << ECMA_PARSE_CHAIN_INDEX_SHIFT) - 1; 369 370 while (chain_index != 0) 371 { 372 if (JERRY_UNLIKELY (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)) 373 { 374 return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid scope chain index for eval")); 375 } 376 377 lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 378 379 if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) 380 || (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)) 381 { 382 chain_index--; 383 } 384 } 385#endif /* ENABLED (JERRY_DEBUGGER) */ 386 } 387 else 388 { 389 ecma_object_t *global_obj_p = ecma_builtin_get_global (); 390 ecma_ref_object (global_obj_p); 391 this_binding = ecma_make_object_value (global_obj_p); 392 lex_env_p = ecma_get_global_scope (); 393 } 394 395 ecma_ref_object (lex_env_p); 396 397 if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0) 398 { 399 ecma_object_t *strict_lex_env_p = ecma_create_decl_lex_env (lex_env_p); 400 401 ecma_deref_object (lex_env_p); 402 lex_env_p = strict_lex_env_p; 403 } 404 405 if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED) != 0) 406 { 407 ecma_object_t *lex_block_p = ecma_create_decl_lex_env (lex_env_p); 408 lex_block_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; 409 410 ecma_deref_object (lex_env_p); 411 lex_env_p = lex_block_p; 412 } 413 414 ecma_value_t completion_value = vm_run (bytecode_data_p, 415 this_binding, 416 lex_env_p, 417 (parse_opts & ECMA_PARSE_DIRECT_EVAL) ? VM_DIRECT_EVAL : NULL, 418 0); 419 420 ecma_deref_object (lex_env_p); 421 ecma_free_value (this_binding); 422 423#if ENABLED (JERRY_SNAPSHOT_EXEC) 424 if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)) 425 { 426 ecma_bytecode_deref (bytecode_data_p); 427 } 428#else /* !ENABLED (JERRY_SNAPSHOT_EXEC) */ 429 ecma_bytecode_deref (bytecode_data_p); 430#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ 431 432 return completion_value; 433} /* vm_run_eval */ 434 435/** 436 * Construct object 437 * 438 * @return object value 439 */ 440static ecma_value_t 441vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ 442 ecma_value_t lit_value) /**< literal */ 443{ 444 ecma_compiled_code_t *bytecode_p; 445 446#if ENABLED (JERRY_SNAPSHOT_EXEC) 447 if (JERRY_LIKELY (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))) 448 { 449#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ 450 bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, 451 lit_value); 452#if ENABLED (JERRY_SNAPSHOT_EXEC) 453 } 454 else 455 { 456 uint8_t *byte_p = ((uint8_t *) frame_ctx_p->bytecode_header_p) + lit_value; 457 bytecode_p = (ecma_compiled_code_t *) byte_p; 458 } 459#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ 460 461#if ENABLED (JERRY_BUILTIN_REGEXP) 462 if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)) 463 { 464 ecma_object_t *regexp_obj_p = ecma_op_regexp_alloc (NULL); 465 466 if (JERRY_UNLIKELY (regexp_obj_p == NULL)) 467 { 468 return ECMA_VALUE_ERROR; 469 } 470 471 return ecma_op_create_regexp_from_bytecode (regexp_obj_p, (re_compiled_code_t *) bytecode_p);; 472 } 473#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 474 475 JERRY_ASSERT (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION); 476 477 ecma_object_t *func_obj_p; 478 479#if ENABLED (JERRY_ES2015) 480 if (bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION) 481 { 482 func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p, 483 bytecode_p, 484 frame_ctx_p->this_binding); 485 } 486 else if (bytecode_p->status_flags & CBC_CODE_FLAGS_GENERATOR) 487 { 488 func_obj_p = ecma_op_create_generator_function_object (frame_ctx_p->lex_env_p, bytecode_p); 489 } 490 else 491 { 492#endif /* ENABLED (JERRY_ES2015) */ 493 func_obj_p = ecma_op_create_simple_function_object (frame_ctx_p->lex_env_p, bytecode_p); 494#if ENABLED (JERRY_ES2015) 495 } 496#endif /* ENABLED (JERRY_ES2015) */ 497 498 return ecma_make_object_value (func_obj_p); 499} /* vm_construct_literal_object */ 500 501/** 502 * Get implicit this value 503 * 504 * @return true - if the implicit 'this' value is updated, 505 * false - otherwise 506 */ 507static inline bool JERRY_ATTR_ALWAYS_INLINE 508vm_get_implicit_this_value (ecma_value_t *this_value_p) /**< [in,out] this value */ 509{ 510 if (ecma_is_value_object (*this_value_p)) 511 { 512 ecma_object_t *this_obj_p = ecma_get_object_from_value (*this_value_p); 513 514 if (ecma_is_lexical_environment (this_obj_p)) 515 { 516 ecma_value_t completion_value = ecma_op_implicit_this_value (this_obj_p); 517 518 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (completion_value)); 519 520 *this_value_p = completion_value; 521 return true; 522 } 523 } 524 return false; 525} /* vm_get_implicit_this_value */ 526 527/** 528 * Special bytecode sequence for error handling while the vm_loop 529 * is preserved for an execute operation 530 */ 531static const uint8_t vm_error_byte_code_p[] = 532{ 533 CBC_EXT_OPCODE, CBC_EXT_ERROR 534}; 535 536#if ENABLED (JERRY_ES2015) 537/** 538 * 'super(...)' function call handler. 539 */ 540static void 541vm_super_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 542{ 543 JERRY_ASSERT (frame_ctx_p->call_operation == VM_EXEC_SUPER_CALL); 544 JERRY_ASSERT (frame_ctx_p->byte_code_p[0] == CBC_EXT_OPCODE); 545 546 const uint8_t *byte_code_p = frame_ctx_p->byte_code_p + 3; 547 uint8_t opcode = byte_code_p[-2]; 548 uint32_t arguments_list_len; 549 550 bool spread_arguments = opcode >= CBC_EXT_SPREAD_SUPER_CALL; 551 552 ecma_collection_t *collection_p = NULL; 553 ecma_value_t *arguments_p; 554 555 if (spread_arguments) 556 { 557 ecma_value_t collection = *(--frame_ctx_p->stack_top_p); 558 collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, collection); 559 arguments_p = collection_p->buffer_p; 560 arguments_list_len = collection_p->item_count; 561 } 562 else 563 { 564 arguments_list_len = byte_code_p[-1]; 565 arguments_p = frame_ctx_p->stack_top_p; 566 } 567 568 ecma_value_t func_value = *(--frame_ctx_p->stack_top_p); 569 ecma_value_t completion_value; 570 571 ecma_property_t *prop_p = ecma_op_get_this_property (frame_ctx_p->lex_env_p); 572 573 if (ecma_op_this_binding_is_initialized (prop_p)) 574 { 575 completion_value = ecma_raise_reference_error (ECMA_ERR_MSG ("Super constructor may only be called once")); 576 } 577 else if (!ecma_is_constructor (func_value)) 578 { 579 completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Class extends value is not a constructor.")); 580 } 581 else 582 { 583 ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value); 584 completion_value = ecma_op_function_construct (func_obj_p, 585 JERRY_CONTEXT (current_new_target), 586 arguments_p, 587 arguments_list_len); 588 589 if (ecma_is_value_object (completion_value)) 590 { 591 ecma_value_t proto_value = ecma_op_object_get_by_magic_id (JERRY_CONTEXT (current_new_target), 592 LIT_MAGIC_STRING_PROTOTYPE); 593 if (ECMA_IS_VALUE_ERROR (proto_value)) 594 { 595 ecma_free_value (completion_value); 596 completion_value = ECMA_VALUE_ERROR; 597 } 598 else if (ecma_is_value_object (proto_value)) 599 { 600 ECMA_SET_POINTER (ecma_get_object_from_value (completion_value)->u2.prototype_cp, 601 ecma_get_object_from_value (proto_value)); 602 } 603 ecma_free_value (proto_value); 604 } 605 } 606 607 /* Free registers. */ 608 for (uint32_t i = 0; i < arguments_list_len; i++) 609 { 610 ecma_fast_free_value (arguments_p[i]); 611 } 612 613 if (collection_p != NULL) 614 { 615 ecma_collection_destroy (collection_p); 616 } 617 618 ecma_free_value (func_value); 619 620 if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value))) 621 { 622#if ENABLED (JERRY_DEBUGGER) 623 JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p; 624#endif /* ENABLED (JERRY_DEBUGGER) */ 625 frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p; 626 } 627 else 628 { 629 ecma_op_bind_this_value (prop_p, completion_value); 630 frame_ctx_p->this_binding = completion_value; 631 632 frame_ctx_p->byte_code_p = byte_code_p; 633 uint32_t opcode_data = vm_decode_table[(CBC_END + 1) + opcode]; 634 635 if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) 636 { 637 ecma_fast_free_value (completion_value); 638 } 639 else if (opcode_data & VM_OC_PUT_STACK) 640 { 641 *frame_ctx_p->stack_top_p++ = completion_value; 642 } 643 else 644 { 645 ecma_fast_free_value (frame_ctx_p->block_result); 646 frame_ctx_p->block_result = completion_value; 647 } 648 } 649} /* vm_super_call */ 650 651/** 652 * Perform one of the following call/construct operation with spreaded argument list 653 * - f(...args) 654 * - o.f(...args) 655 * - new O(...args) 656 */ 657static void 658vm_spread_operation (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 659{ 660 JERRY_ASSERT (frame_ctx_p->byte_code_p[0] == CBC_EXT_OPCODE); 661 662 uint8_t opcode = frame_ctx_p->byte_code_p[1]; 663 ecma_value_t completion_value; 664 ecma_value_t collection = *(--frame_ctx_p->stack_top_p); 665 666 ecma_collection_t *collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, collection); 667 ecma_value_t func_value = *(--frame_ctx_p->stack_top_p); 668 bool is_call_prop = opcode >= CBC_EXT_SPREAD_CALL_PROP; 669 670 if (frame_ctx_p->byte_code_p[1] == CBC_EXT_SPREAD_NEW) 671 { 672 if (!ecma_is_value_object (func_value) 673 || !ecma_object_is_constructor (ecma_get_object_from_value (func_value))) 674 { 675 completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor.")); 676 } 677 else 678 { 679 ecma_object_t *constructor_obj_p = ecma_get_object_from_value (func_value); 680 681 completion_value = ecma_op_function_construct (constructor_obj_p, 682 constructor_obj_p, 683 collection_p->buffer_p, 684 collection_p->item_count); 685 } 686 } 687 else 688 { 689 ecma_value_t this_value = is_call_prop ? frame_ctx_p->stack_top_p[-2] : ECMA_VALUE_UNDEFINED; 690 691 if (!ecma_is_value_object (func_value) 692 || !ecma_op_object_is_callable (ecma_get_object_from_value (func_value))) 693 { 694 completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function.")); 695 } 696 else 697 { 698 ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value); 699 700 completion_value = ecma_op_function_call (func_obj_p, 701 this_value, 702 collection_p->buffer_p, 703 collection_p->item_count); 704 } 705 706 if (is_call_prop) 707 { 708 ecma_free_value (*(--frame_ctx_p->stack_top_p)); 709 ecma_free_value (*(--frame_ctx_p->stack_top_p)); 710 } 711 } 712 713 ecma_collection_free (collection_p); 714 ecma_free_value (func_value); 715 716 if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value))) 717 { 718#if ENABLED (JERRY_DEBUGGER) 719 JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p; 720#endif /* ENABLED (JERRY_DEBUGGER) */ 721 frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p; 722 } 723 else 724 { 725 uint32_t opcode_data = vm_decode_table[(CBC_END + 1) + opcode]; 726 727 if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) 728 { 729 ecma_fast_free_value (completion_value); 730 } 731 else if (opcode_data & VM_OC_PUT_STACK) 732 { 733 *frame_ctx_p->stack_top_p++ = completion_value; 734 } 735 else 736 { 737 ecma_fast_free_value (frame_ctx_p->block_result); 738 frame_ctx_p->block_result = completion_value; 739 } 740 741 /* EXT_OPCODE, SPREAD_OPCODE, BYTE_ARG */ 742 frame_ctx_p->byte_code_p += 3; 743 } 744} /* vm_spread_operation */ 745#endif /* ENABLED (JERRY_ES2015) */ 746 747/** 748 * 'Function call' opcode handler. 749 * 750 * See also: ECMA-262 v5, 11.2.3 751 */ 752static void 753opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 754{ 755 const uint8_t *byte_code_p = frame_ctx_p->byte_code_p + 1; 756 uint8_t opcode = byte_code_p[-1]; 757 uint32_t arguments_list_len; 758 759 if (opcode >= CBC_CALL0) 760 { 761 arguments_list_len = (unsigned int) ((opcode - CBC_CALL0) / 6); 762 } 763 else 764 { 765 arguments_list_len = *byte_code_p++; 766 } 767 768 bool is_call_prop = ((opcode - CBC_CALL) % 6) >= 3; 769 770 ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len; 771 ecma_value_t this_value = is_call_prop ? stack_top_p[-3] : ECMA_VALUE_UNDEFINED; 772 ecma_value_t func_value = stack_top_p[-1]; 773 ecma_value_t completion_value; 774 775#if defined(JERRY_FUNCTION_BACKTRACE) && !defined(__APPLE__) 776 frame_ctx_p->callee_value = func_value; 777#endif 778 779 if (!ecma_is_value_object (func_value) 780 || !ecma_op_object_is_callable (ecma_get_object_from_value (func_value))) 781 { 782 completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function.")); 783 } 784 else 785 { 786 ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value); 787 788 completion_value = ecma_op_function_call (func_obj_p, 789 this_value, 790 stack_top_p, 791 arguments_list_len); 792 } 793 794 JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL; 795 796 /* Free registers. */ 797 for (uint32_t i = 0; i < arguments_list_len; i++) 798 { 799 ecma_fast_free_value (stack_top_p[i]); 800 } 801 802 if (is_call_prop) 803 { 804 ecma_free_value (*(--stack_top_p)); 805 ecma_free_value (*(--stack_top_p)); 806 } 807 808 if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value))) 809 { 810#if ENABLED (JERRY_DEBUGGER) 811 JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p; 812#endif /* ENABLED (JERRY_DEBUGGER) */ 813 frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p; 814 } 815 else 816 { 817 frame_ctx_p->byte_code_p = byte_code_p; 818 ecma_free_value (*(--stack_top_p)); 819 uint32_t opcode_data = vm_decode_table[opcode]; 820 821 if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) 822 { 823 ecma_fast_free_value (completion_value); 824 } 825 else if (opcode_data & VM_OC_PUT_STACK) 826 { 827 *stack_top_p++ = completion_value; 828 } 829 else 830 { 831 ecma_fast_free_value (frame_ctx_p->block_result); 832 frame_ctx_p->block_result = completion_value; 833 } 834 } 835 836 frame_ctx_p->stack_top_p = stack_top_p; 837} /* opfunc_call */ 838 839/** 840 * 'Constructor call' opcode handler. 841 * 842 * See also: ECMA-262 v5, 11.2.2 843 */ 844static void 845opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 846{ 847 const uint8_t *byte_code_p = frame_ctx_p->byte_code_p + 1; 848 uint8_t opcode = byte_code_p[-1]; 849 unsigned int arguments_list_len; 850 851 if (opcode >= CBC_NEW0) 852 { 853 arguments_list_len = (unsigned int) (opcode - CBC_NEW0); 854 } 855 else 856 { 857 arguments_list_len = *byte_code_p++; 858 } 859 860 ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len; 861 ecma_value_t constructor_value = stack_top_p[-1]; 862 ecma_value_t completion_value; 863 864 if (!ecma_is_value_object (constructor_value) 865 || !ecma_object_is_constructor (ecma_get_object_from_value (constructor_value))) 866 { 867 completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor.")); 868 } 869 else 870 { 871 ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor_value); 872 873#if defined(JERRY_FUNCTION_BACKTRACE) && !defined(__APPLE__) 874 frame_ctx_p->callee_value = constructor_value; 875#endif 876 877 completion_value = ecma_op_function_construct (constructor_obj_p, 878 constructor_obj_p, 879 stack_top_p, 880 arguments_list_len); 881 } 882 883 /* Free registers. */ 884 for (uint32_t i = 0; i < arguments_list_len; i++) 885 { 886 ecma_fast_free_value (stack_top_p[i]); 887 } 888 889 if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value))) 890 { 891#if ENABLED (JERRY_DEBUGGER) 892 JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p; 893#endif /* ENABLED (JERRY_DEBUGGER) */ 894 frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p; 895 } 896 else 897 { 898 ecma_free_value (stack_top_p[-1]); 899 frame_ctx_p->byte_code_p = byte_code_p; 900 stack_top_p[-1] = completion_value; 901 } 902 903 frame_ctx_p->stack_top_p = stack_top_p; 904} /* opfunc_construct */ 905 906/** 907 * Read literal index from the byte code stream into destination. 908 * 909 * @param destination destination 910 */ 911#define READ_LITERAL_INDEX(destination) \ 912 do \ 913 { \ 914 (destination) = *byte_code_p++; \ 915 if ((destination) >= encoding_limit) \ 916 { \ 917 (destination) = (uint16_t) ((((destination) << 8) | *byte_code_p++) - encoding_delta); \ 918 } \ 919 } \ 920 while (0) 921 922/** 923 * Get literal value by literal index. 924 * 925 * @param literal_index literal index 926 * @param target_value target value 927 * 928 * TODO: For performance reasons, we define this as a macro. 929 * When we are able to construct a function with similar speed, 930 * we can remove this macro. 931 */ 932#define READ_LITERAL(literal_index, target_value) \ 933 do \ 934 { \ 935 if ((literal_index) < ident_end) \ 936 { \ 937 if ((literal_index) < register_end) \ 938 { \ 939 /* Note: There should be no specialization for arguments. */ \ 940 (target_value) = ecma_fast_copy_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); \ 941 } \ 942 else \ 943 { \ 944 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); \ 945 \ 946 result = ecma_op_resolve_reference_value (frame_ctx_p->lex_env_p, \ 947 name_p); \ 948 \ 949 if (ECMA_IS_VALUE_ERROR (result)) \ 950 { \ 951 goto error; \ 952 } \ 953 (target_value) = result; \ 954 } \ 955 } \ 956 else if (literal_index < const_literal_end) \ 957 { \ 958 (target_value) = ecma_fast_copy_value (literal_start_p[literal_index]); \ 959 } \ 960 else \ 961 { \ 962 /* Object construction. */ \ 963 (target_value) = vm_construct_literal_object (frame_ctx_p, \ 964 literal_start_p[literal_index]); \ 965 } \ 966 } \ 967 while (0) 968 969/** 970 * Run generic byte code. 971 * 972 * @return ecma value 973 */ 974static ecma_value_t JERRY_ATTR_NOINLINE 975vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 976{ 977 const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p; 978 const uint8_t *byte_code_p = frame_ctx_p->byte_code_p; 979 ecma_value_t *literal_start_p = frame_ctx_p->literal_start_p; 980 981 ecma_value_t *stack_top_p; 982 uint16_t encoding_limit; 983 uint16_t encoding_delta; 984 uint16_t register_end; 985 uint16_t ident_end; 986 uint16_t const_literal_end; 987 int32_t branch_offset = 0; 988 uint8_t branch_offset_length = 0; 989 ecma_value_t left_value; 990 ecma_value_t right_value; 991 ecma_value_t result = ECMA_VALUE_EMPTY; 992 bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0); 993 994 /* Prepare for byte code execution. */ 995 if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING)) 996 { 997 encoding_limit = CBC_SMALL_LITERAL_ENCODING_LIMIT; 998 encoding_delta = CBC_SMALL_LITERAL_ENCODING_DELTA; 999 } 1000 else 1001 { 1002 encoding_limit = CBC_FULL_LITERAL_ENCODING_LIMIT; 1003 encoding_delta = CBC_FULL_LITERAL_ENCODING_DELTA; 1004 } 1005 1006 if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 1007 { 1008 cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) (bytecode_header_p); 1009 register_end = args_p->register_end; 1010 ident_end = args_p->ident_end; 1011 const_literal_end = args_p->const_literal_end; 1012 } 1013 else 1014 { 1015 cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) (bytecode_header_p); 1016 register_end = args_p->register_end; 1017 ident_end = args_p->ident_end; 1018 const_literal_end = args_p->const_literal_end; 1019 } 1020 1021 stack_top_p = frame_ctx_p->stack_top_p; 1022 1023 /* Outer loop for exception handling. */ 1024 while (true) 1025 { 1026 /* Internal loop for byte code execution. */ 1027 while (true) 1028 { 1029 const uint8_t *byte_code_start_p = byte_code_p; 1030 uint8_t opcode = *byte_code_p++; 1031 uint32_t opcode_data = opcode; 1032 1033 if (opcode == CBC_EXT_OPCODE) 1034 { 1035 opcode = *byte_code_p++; 1036 opcode_data = (uint32_t) ((CBC_END + 1) + opcode); 1037 } 1038 1039 opcode_data = vm_decode_table[opcode_data]; 1040 1041 left_value = ECMA_VALUE_UNDEFINED; 1042 right_value = ECMA_VALUE_UNDEFINED; 1043 1044 uint32_t operands = VM_OC_GET_ARGS_INDEX (opcode_data); 1045 1046 if (operands >= VM_OC_GET_LITERAL) 1047 { 1048 uint16_t literal_index; 1049 READ_LITERAL_INDEX (literal_index); 1050 READ_LITERAL (literal_index, left_value); 1051 1052 if (operands != VM_OC_GET_LITERAL) 1053 { 1054 switch (operands) 1055 { 1056 case VM_OC_GET_LITERAL_LITERAL: 1057 { 1058 uint16_t second_literal_index; 1059 READ_LITERAL_INDEX (second_literal_index); 1060 READ_LITERAL (second_literal_index, right_value); 1061 break; 1062 } 1063 case VM_OC_GET_STACK_LITERAL: 1064 { 1065 JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end); 1066 right_value = left_value; 1067 left_value = *(--stack_top_p); 1068 break; 1069 } 1070 default: 1071 { 1072 JERRY_ASSERT (operands == VM_OC_GET_THIS_LITERAL); 1073 1074 right_value = left_value; 1075 left_value = ecma_copy_value (frame_ctx_p->this_binding); 1076 break; 1077 } 1078 } 1079 } 1080 } 1081 else if (operands >= VM_OC_GET_STACK) 1082 { 1083 JERRY_ASSERT (operands == VM_OC_GET_STACK 1084 || operands == VM_OC_GET_STACK_STACK); 1085 1086 JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end); 1087 left_value = *(--stack_top_p); 1088 1089 if (operands == VM_OC_GET_STACK_STACK) 1090 { 1091 JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end); 1092 right_value = left_value; 1093 left_value = *(--stack_top_p); 1094 } 1095 } 1096 else if (operands == VM_OC_GET_BRANCH) 1097 { 1098 branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (opcode); 1099 JERRY_ASSERT (branch_offset_length >= 1 && branch_offset_length <= 3); 1100 1101 branch_offset = *(byte_code_p++); 1102 1103 if (JERRY_UNLIKELY (branch_offset_length != 1)) 1104 { 1105 branch_offset <<= 8; 1106 branch_offset |= *(byte_code_p++); 1107 1108 if (JERRY_UNLIKELY (branch_offset_length == 3)) 1109 { 1110 branch_offset <<= 8; 1111 branch_offset |= *(byte_code_p++); 1112 } 1113 } 1114 1115 if (opcode_data & VM_OC_BACKWARD_BRANCH) 1116 { 1117#if ENABLED (JERRY_VM_EXEC_STOP) 1118 if (JERRY_CONTEXT (vm_exec_stop_cb) != NULL 1119 && --JERRY_CONTEXT (vm_exec_stop_counter) == 0) 1120 { 1121 result = JERRY_CONTEXT (vm_exec_stop_cb) (JERRY_CONTEXT (vm_exec_stop_user_p)); 1122 1123 if (ecma_is_value_undefined (result)) 1124 { 1125 JERRY_CONTEXT (vm_exec_stop_counter) = JERRY_CONTEXT (vm_exec_stop_frequency); 1126 } 1127 else 1128 { 1129 JERRY_CONTEXT (vm_exec_stop_counter) = 1; 1130 1131 if (ecma_is_value_error_reference (result)) 1132 { 1133 ecma_raise_error_from_error_reference (result); 1134 } 1135 else 1136 { 1137 jcontext_raise_exception (result); 1138 } 1139 1140 JERRY_ASSERT (jcontext_has_pending_exception ()); 1141 jcontext_set_abort_flag (true); 1142 result = ECMA_VALUE_ERROR; 1143 goto error; 1144 } 1145 } 1146#endif /* ENABLED (JERRY_VM_EXEC_STOP) */ 1147 1148 branch_offset = -branch_offset; 1149 } 1150 } 1151 1152 switch (VM_OC_GROUP_GET_INDEX (opcode_data)) 1153 { 1154 case VM_OC_POP: 1155 { 1156 JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end); 1157 ecma_free_value (*(--stack_top_p)); 1158 continue; 1159 } 1160 case VM_OC_POP_BLOCK: 1161 { 1162 ecma_fast_free_value (frame_ctx_p->block_result); 1163 frame_ctx_p->block_result = *(--stack_top_p); 1164 continue; 1165 } 1166 case VM_OC_PUSH: 1167 { 1168 *stack_top_p++ = left_value; 1169 continue; 1170 } 1171 case VM_OC_PUSH_TWO: 1172 { 1173 *stack_top_p++ = left_value; 1174 *stack_top_p++ = right_value; 1175 continue; 1176 } 1177 case VM_OC_PUSH_THREE: 1178 { 1179 uint16_t literal_index; 1180 1181 *stack_top_p++ = left_value; 1182 left_value = ECMA_VALUE_UNDEFINED; 1183 1184 READ_LITERAL_INDEX (literal_index); 1185 READ_LITERAL (literal_index, left_value); 1186 1187 *stack_top_p++ = right_value; 1188 *stack_top_p++ = left_value; 1189 continue; 1190 } 1191 case VM_OC_PUSH_UNDEFINED: 1192 { 1193 *stack_top_p++ = ECMA_VALUE_UNDEFINED; 1194 continue; 1195 } 1196 case VM_OC_PUSH_TRUE: 1197 { 1198 *stack_top_p++ = ECMA_VALUE_TRUE; 1199 continue; 1200 } 1201 case VM_OC_PUSH_FALSE: 1202 { 1203 *stack_top_p++ = ECMA_VALUE_FALSE; 1204 continue; 1205 } 1206 case VM_OC_PUSH_NULL: 1207 { 1208 *stack_top_p++ = ECMA_VALUE_NULL; 1209 continue; 1210 } 1211 case VM_OC_PUSH_THIS: 1212 { 1213 *stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding); 1214 continue; 1215 } 1216 case VM_OC_PUSH_0: 1217 { 1218 *stack_top_p++ = ecma_make_integer_value (0); 1219 continue; 1220 } 1221 case VM_OC_PUSH_POS_BYTE: 1222 { 1223 ecma_integer_value_t number = *byte_code_p++; 1224 *stack_top_p++ = ecma_make_integer_value (number + 1); 1225 continue; 1226 } 1227 case VM_OC_PUSH_NEG_BYTE: 1228 { 1229 ecma_integer_value_t number = *byte_code_p++; 1230 *stack_top_p++ = ecma_make_integer_value (-(number + 1)); 1231 continue; 1232 } 1233 case VM_OC_PUSH_LIT_0: 1234 { 1235 stack_top_p[0] = left_value; 1236 stack_top_p[1] = ecma_make_integer_value (0); 1237 stack_top_p += 2; 1238 continue; 1239 } 1240 case VM_OC_PUSH_LIT_POS_BYTE: 1241 { 1242 ecma_integer_value_t number = *byte_code_p++; 1243 stack_top_p[0] = left_value; 1244 stack_top_p[1] = ecma_make_integer_value (number + 1); 1245 stack_top_p += 2; 1246 continue; 1247 } 1248 case VM_OC_PUSH_LIT_NEG_BYTE: 1249 { 1250 ecma_integer_value_t number = *byte_code_p++; 1251 stack_top_p[0] = left_value; 1252 stack_top_p[1] = ecma_make_integer_value (-(number + 1)); 1253 stack_top_p += 2; 1254 continue; 1255 } 1256 case VM_OC_PUSH_OBJECT: 1257 { 1258 ecma_object_t *obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE), 1259 0, 1260 ECMA_OBJECT_TYPE_GENERAL); 1261 1262 *stack_top_p++ = ecma_make_object_value (obj_p); 1263 continue; 1264 } 1265 case VM_OC_PUSH_NAMED_FUNC_EXPR: 1266 { 1267 ecma_object_t *func_p = ecma_get_object_from_value (left_value); 1268 1269 JERRY_ASSERT (ecma_get_object_type (func_p) == ECMA_OBJECT_TYPE_FUNCTION); 1270 1271 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p; 1272 1273 JERRY_ASSERT (frame_ctx_p->lex_env_p == 1274 ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, ext_func_p->u.function.scope_cp)); 1275 1276 ecma_object_t *name_lex_env = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p); 1277 1278 ecma_op_create_immutable_binding (name_lex_env, ecma_get_string_from_value (right_value), left_value); 1279 1280 ECMA_SET_NON_NULL_POINTER_TAG (ext_func_p->u.function.scope_cp, name_lex_env, 0); 1281 1282 ecma_free_value (right_value); 1283 ecma_deref_object (name_lex_env); 1284 *stack_top_p++ = left_value; 1285 continue; 1286 } 1287 case VM_OC_CREATE_BINDING: 1288 { 1289#if !ENABLED (JERRY_ES2015) 1290 JERRY_ASSERT (opcode == CBC_CREATE_VAR); 1291#endif /* !ENABLED (JERRY_ES2015) */ 1292 1293 uint32_t literal_index; 1294 1295 READ_LITERAL_INDEX (literal_index); 1296 1297 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1298 1299 JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1300 JERRY_ASSERT (ecma_find_named_property (frame_ctx_p->lex_env_p, name_p) == NULL); 1301 1302 uint8_t prop_attributes = ECMA_PROPERTY_FLAG_WRITABLE; 1303 1304#if ENABLED (JERRY_ES2015) 1305 if (opcode == CBC_CREATE_LET) 1306 { 1307 prop_attributes = ECMA_PROPERTY_ENUMERABLE_WRITABLE; 1308 } 1309 else if (opcode == CBC_CREATE_CONST) 1310 { 1311 prop_attributes = ECMA_PROPERTY_FLAG_ENUMERABLE; 1312 } 1313 1314 ecma_property_value_t *property_value_p; 1315 property_value_p = ecma_create_named_data_property (frame_ctx_p->lex_env_p, name_p, prop_attributes, NULL); 1316 1317 if (opcode != CBC_CREATE_VAR) 1318 { 1319 property_value_p->value = ECMA_VALUE_UNINITIALIZED; 1320 } 1321#else /* !ENABLED (JERRY_ES2015) */ 1322 ecma_create_named_data_property (frame_ctx_p->lex_env_p, name_p, prop_attributes, NULL); 1323#endif /* ENABLED (JERRY_ES2015) */ 1324 1325 continue; 1326 } 1327 case VM_OC_VAR_EVAL: 1328 { 1329 uint32_t literal_index; 1330 ecma_value_t lit_value = ECMA_VALUE_UNDEFINED; 1331 1332 if (opcode == CBC_CREATE_VAR_FUNC_EVAL) 1333 { 1334 uint32_t value_index; 1335 READ_LITERAL_INDEX (value_index); 1336 JERRY_ASSERT (value_index >= const_literal_end); 1337 1338 lit_value = vm_construct_literal_object (frame_ctx_p, 1339 literal_start_p[value_index]); 1340 } 1341 1342 READ_LITERAL_INDEX (literal_index); 1343 JERRY_ASSERT (literal_index >= register_end); 1344 1345 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1346 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 1347 1348 while (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1349 { 1350#if ENABLED (JERRY_ES2015) && !(defined JERRY_NDEBUG) 1351 if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1352 { 1353 ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1354 1355 JERRY_ASSERT (property_p == NULL || !(*property_p & ECMA_PROPERTY_FLAG_ENUMERABLE)); 1356 } 1357#endif /* ENABLED (JERRY_ES2015) && !JERRY_NDEBUG */ 1358 1359 JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 1360 lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 1361 } 1362 1363#if ENABLED (JERRY_ES2015) && !(defined JERRY_NDEBUG) 1364 if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1365 { 1366 ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1367 1368 JERRY_ASSERT (property_p == NULL || !(*property_p & ECMA_PROPERTY_FLAG_ENUMERABLE)); 1369 } 1370#endif /* ENABLED (JERRY_ES2015) && !JERRY_NDEBUG */ 1371 1372 result = vm_var_decl (lex_env_p, name_p, frame_ctx_p->is_eval_code); 1373 1374 if (ECMA_IS_VALUE_ERROR (result)) 1375 { 1376 goto error; 1377 } 1378 1379 if (lit_value != ECMA_VALUE_UNDEFINED) 1380 { 1381 result = vm_set_var (lex_env_p, name_p, is_strict, lit_value); 1382 1383 if (ECMA_IS_VALUE_ERROR (result)) 1384 { 1385 goto error; 1386 } 1387 } 1388 1389 continue; 1390 } 1391#if ENABLED (JERRY_ES2015) 1392 case VM_OC_EXT_VAR_EVAL: 1393 { 1394 uint32_t literal_index; 1395 ecma_value_t lit_value = ECMA_VALUE_UNDEFINED; 1396 1397 JERRY_ASSERT (byte_code_start_p[0] == CBC_EXT_OPCODE); 1398 1399 if (opcode == CBC_EXT_CREATE_VAR_FUNC_EVAL) 1400 { 1401 uint32_t value_index; 1402 READ_LITERAL_INDEX (value_index); 1403 JERRY_ASSERT (value_index >= const_literal_end); 1404 1405 lit_value = vm_construct_literal_object (frame_ctx_p, 1406 literal_start_p[value_index]); 1407 } 1408 1409 READ_LITERAL_INDEX (literal_index); 1410 JERRY_ASSERT (literal_index >= register_end); 1411 1412 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1413 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 1414 ecma_object_t *prev_lex_env_p = NULL; 1415 1416 while (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1417 { 1418#if !(defined JERRY_NDEBUG) 1419 if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1420 { 1421 ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1422 1423 JERRY_ASSERT (property_p == NULL || !(*property_p & ECMA_PROPERTY_FLAG_ENUMERABLE)); 1424 } 1425#endif /* !JERRY_NDEBUG */ 1426 1427 JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 1428 prev_lex_env_p = lex_env_p; 1429 lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 1430 } 1431 1432 JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1433 JERRY_ASSERT (prev_lex_env_p != NULL 1434 && ecma_get_lex_env_type (prev_lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1435 1436 ecma_property_t *property_p = ecma_find_named_property (prev_lex_env_p, name_p); 1437 ecma_property_value_t *property_value_p; 1438 1439 if (property_p == NULL) 1440 { 1441 property_value_p = ecma_create_named_data_property (prev_lex_env_p, 1442 name_p, 1443 ECMA_PROPERTY_CONFIGURABLE_WRITABLE, 1444 NULL); 1445 1446 if (lit_value == ECMA_VALUE_UNDEFINED) 1447 { 1448 continue; 1449 } 1450 } 1451 else 1452 { 1453 if (lit_value == ECMA_VALUE_UNDEFINED) 1454 { 1455 continue; 1456 } 1457 1458 property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 1459 ecma_free_value_if_not_object (property_value_p->value); 1460 } 1461 1462 property_value_p->value = lit_value; 1463 ecma_deref_object (ecma_get_object_from_value (lit_value)); 1464 continue; 1465 } 1466#endif /* ENABLED (JERRY_ES2015) */ 1467#if ENABLED (JERRY_SNAPSHOT_EXEC) 1468 case VM_OC_SET_BYTECODE_PTR: 1469 { 1470 memcpy (&byte_code_p, byte_code_p++, sizeof (uint8_t *)); 1471 frame_ctx_p->byte_code_start_p = byte_code_p; 1472 continue; 1473 } 1474#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ 1475 case VM_OC_INIT_ARG_OR_FUNC: 1476 { 1477 uint32_t literal_index, value_index; 1478 ecma_value_t lit_value; 1479 1480 READ_LITERAL_INDEX (value_index); 1481 READ_LITERAL_INDEX (literal_index); 1482 1483 JERRY_ASSERT (value_index != literal_index); 1484 JERRY_ASSERT (value_index >= register_end || literal_index >= register_end); 1485 1486 if (value_index < register_end) 1487 { 1488 /* Take (not copy) the reference. */ 1489 lit_value = ecma_copy_value_if_not_object (VM_GET_REGISTER (frame_ctx_p, value_index)); 1490 } 1491 else 1492 { 1493 lit_value = vm_construct_literal_object (frame_ctx_p, 1494 literal_start_p[value_index]); 1495 } 1496 1497 if (literal_index < register_end) 1498 { 1499 ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); 1500 VM_GET_REGISTER (frame_ctx_p, literal_index) = lit_value; 1501 continue; 1502 } 1503 1504 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1505 1506 JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1507 JERRY_ASSERT (ecma_find_named_property (frame_ctx_p->lex_env_p, name_p) == NULL); 1508 1509 ecma_property_value_t *property_value_p; 1510 property_value_p = ecma_create_named_data_property (frame_ctx_p->lex_env_p, 1511 name_p, 1512 ECMA_PROPERTY_FLAG_WRITABLE, 1513 NULL); 1514 1515 JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED); 1516 property_value_p->value = lit_value; 1517 1518#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 1519 if (ecma_is_value_object(lit_value)) { 1520 ecma_object_t* obj = ecma_get_object_from_value(lit_value); 1521 ecma_object_type_t obj_type = ecma_get_object_type(obj); 1522 if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) { 1523 ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 1524 ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, property_name, 1525 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, NULL); 1526 prop_val->value = ecma_copy_value(literal_start_p[literal_index]); 1527 } 1528 } 1529#endif 1530 1531 if (value_index >= register_end) 1532 { 1533 ecma_free_value (lit_value); 1534 } 1535 1536 continue; 1537 } 1538#if ENABLED (JERRY_ES2015) 1539 case VM_OC_CHECK_VAR: 1540 { 1541 JERRY_ASSERT (ecma_get_global_scope () == frame_ctx_p->lex_env_p); 1542 1543 uint32_t literal_index; 1544 READ_LITERAL_INDEX (literal_index); 1545 1546 if ((frame_ctx_p->lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) == 0) 1547 { 1548 continue; 1549 } 1550 1551 ecma_string_t *const literal_name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1552 ecma_property_t *const binding_p = ecma_find_named_property (frame_ctx_p->lex_env_p, literal_name_p); 1553 1554 if (binding_p != NULL) 1555 { 1556 result = ecma_raise_syntax_error (ECMA_ERR_MSG ("Local variable is redeclared.")); 1557 goto error; 1558 } 1559 1560 continue; 1561 } 1562 case VM_OC_CHECK_LET: 1563 { 1564 JERRY_ASSERT (ecma_get_global_scope () == frame_ctx_p->lex_env_p); 1565 1566 uint32_t literal_index; 1567 READ_LITERAL_INDEX (literal_index); 1568 1569 ecma_string_t *literal_name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1570 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 1571 ecma_property_t *binding_p = NULL; 1572 1573 if (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1574 { 1575 binding_p = ecma_find_named_property (lex_env_p, literal_name_p); 1576 1577 JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 1578 lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 1579 } 1580 1581 if (binding_p != NULL) 1582 { 1583 result = ecma_raise_syntax_error (ECMA_ERR_MSG ("Local variable is redeclared.")); 1584 goto error; 1585 } 1586 1587 result = ecma_op_has_binding (lex_env_p, literal_name_p); 1588 1589#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1590 if (ECMA_IS_VALUE_ERROR (result)) 1591 { 1592 goto error; 1593 } 1594#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1595 1596 if (ecma_is_value_true (result)) 1597 { 1598 result = ecma_raise_syntax_error (ECMA_ERR_MSG ("Local variable is redeclared.")); 1599 goto error; 1600 } 1601 1602 continue; 1603 } 1604 case VM_OC_ASSIGN_LET_CONST: 1605 { 1606 uint32_t literal_index; 1607 READ_LITERAL_INDEX (literal_index); 1608 1609 JERRY_ASSERT (literal_index >= register_end); 1610 JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1611 1612 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1613 ecma_property_t *property_p = ecma_find_named_property (frame_ctx_p->lex_env_p, name_p); 1614 1615 JERRY_ASSERT (property_p != NULL 1616 && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); 1617 JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p)->value == ECMA_VALUE_UNINITIALIZED); 1618 1619 ECMA_PROPERTY_VALUE_PTR (property_p)->value = left_value; 1620 1621 if (ecma_is_value_object (left_value)) 1622 { 1623 ecma_deref_object (ecma_get_object_from_value (left_value)); 1624 } 1625 continue; 1626 } 1627 case VM_OC_INIT_BINDING: 1628 { 1629 uint32_t literal_index; 1630 1631 READ_LITERAL_INDEX (literal_index); 1632 1633 JERRY_ASSERT (literal_index >= register_end); 1634 1635 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1636 1637 JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1638 JERRY_ASSERT (ecma_find_named_property (frame_ctx_p->lex_env_p, name_p) == NULL); 1639 1640 uint8_t prop_attributes = ECMA_PROPERTY_FLAG_WRITABLE; 1641 1642 if (opcode == CBC_INIT_LET) 1643 { 1644 prop_attributes = ECMA_PROPERTY_ENUMERABLE_WRITABLE; 1645 } 1646 else if (opcode == CBC_INIT_CONST) 1647 { 1648 prop_attributes = ECMA_PROPERTY_FLAG_ENUMERABLE; 1649 } 1650 1651 ecma_property_value_t *property_value_p; 1652 property_value_p = ecma_create_named_data_property (frame_ctx_p->lex_env_p, 1653 name_p, 1654 prop_attributes, 1655 NULL); 1656 1657 JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED); 1658 1659 ecma_value_t value = *(--stack_top_p); 1660 1661 property_value_p->value = value; 1662 ecma_deref_if_object (value); 1663 continue; 1664 } 1665 case VM_OC_THROW_CONST_ERROR: 1666 { 1667 result = ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned.")); 1668 goto error; 1669 } 1670 case VM_OC_COPY_TO_GLOBAL: 1671 { 1672 uint32_t literal_index; 1673 READ_LITERAL_INDEX (literal_index); 1674 1675 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1676 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 1677 1678 while (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1679 { 1680#ifndef JERRY_NDEBUG 1681 if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1682 { 1683 ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1684 1685 JERRY_ASSERT (property_p == NULL || !(*property_p & ECMA_PROPERTY_FLAG_ENUMERABLE)); 1686 } 1687#endif /* !JERRY_NDEBUG */ 1688 1689 JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 1690 lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 1691 } 1692 1693 if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 1694 { 1695 ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p); 1696 ecma_property_value_t *prop_value_p; 1697 1698 if (property_p == NULL) 1699 { 1700 prop_value_p = ecma_create_named_data_property (lex_env_p, 1701 name_p, 1702 ECMA_PROPERTY_FLAG_WRITABLE, 1703 NULL); 1704 } 1705 else 1706 { 1707#ifndef JERRY_NDEBUG 1708 JERRY_ASSERT (!(*property_p & ECMA_PROPERTY_FLAG_ENUMERABLE)); 1709#endif /* !JERRY_NDEBUG */ 1710 prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 1711 } 1712 1713 ecma_named_data_property_assign_value (lex_env_p, prop_value_p, left_value); 1714 } 1715 else 1716 { 1717 result = ecma_op_set_mutable_binding (lex_env_p, name_p, left_value, is_strict); 1718 1719 if (ECMA_IS_VALUE_ERROR (result)) 1720 { 1721 goto error; 1722 } 1723 } 1724 1725 goto free_left_value; 1726 } 1727 case VM_OC_COPY_FROM_ARG: 1728 { 1729 uint32_t literal_index; 1730 READ_LITERAL_INDEX (literal_index); 1731 JERRY_ASSERT (literal_index >= register_end); 1732 1733 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 1734 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 1735 ecma_object_t *arg_lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 1736 1737 JERRY_ASSERT ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1738 && ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1739 JERRY_ASSERT (arg_lex_env_p != NULL 1740 && !(arg_lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) 1741 && ecma_get_lex_env_type (arg_lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 1742 1743 ecma_property_value_t *property_value_p; 1744 property_value_p = ecma_create_named_data_property (lex_env_p, 1745 name_p, 1746 ECMA_PROPERTY_FLAG_WRITABLE, 1747 NULL); 1748 1749 ecma_property_t *property_p = ecma_find_named_property (arg_lex_env_p, name_p); 1750 JERRY_ASSERT (property_p != NULL); 1751 1752 ecma_property_value_t *arg_prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 1753 property_value_p->value = ecma_copy_value_if_not_object (arg_prop_value_p->value); 1754 continue; 1755 } 1756 case VM_OC_CLONE_CONTEXT: 1757 { 1758 JERRY_ASSERT (byte_code_start_p[0] == CBC_EXT_OPCODE); 1759 1760 bool copy_values = (byte_code_start_p[1] == CBC_EXT_CLONE_FULL_CONTEXT); 1761 frame_ctx_p->lex_env_p = ecma_clone_decl_lexical_environment (frame_ctx_p->lex_env_p, copy_values); 1762 continue; 1763 } 1764 case VM_OC_SET__PROTO__: 1765 { 1766 result = ecma_builtin_object_object_set_proto (stack_top_p[-1], left_value); 1767 if (ECMA_IS_VALUE_ERROR (result)) 1768 { 1769 goto error; 1770 } 1771 goto free_left_value; 1772 } 1773 case VM_OC_SET_COMPUTED_PROPERTY: 1774 { 1775 /* Swap values. */ 1776 left_value ^= right_value; 1777 right_value ^= left_value; 1778 left_value ^= right_value; 1779 /* FALLTHRU */ 1780 } 1781#endif /* ENABLED (JERRY_ES2015) */ 1782 case VM_OC_SET_PROPERTY: 1783 { 1784 JERRY_STATIC_ASSERT (VM_OC_NON_STATIC_FLAG == VM_OC_BACKWARD_BRANCH, 1785 vm_oc_non_static_flag_must_be_equal_to_vm_oc_backward_branch); 1786 1787 JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1); 1788 1789 ecma_string_t *prop_name_p = ecma_op_to_prop_name (right_value); 1790 1791 if (JERRY_UNLIKELY (prop_name_p == NULL)) 1792 { 1793 result = ECMA_VALUE_ERROR; 1794 goto error; 1795 } 1796 1797#if ENABLED (JERRY_ES2015) 1798 if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE)) 1799 && !(opcode_data & VM_OC_NON_STATIC_FLAG)) 1800 { 1801 result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable")); 1802 goto error; 1803 } 1804 1805 const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2; 1806#else /* !ENABLED (JERRY_ES2015) */ 1807 const int index = -1; 1808#endif /* ENABLED (JERRY_ES2015) */ 1809 1810 ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]); 1811 1812 JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p)); 1813 1814 ecma_property_t *property_p = ecma_find_named_property (object_p, prop_name_p); 1815 1816 if (property_p != NULL 1817 && ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA) 1818 { 1819 ecma_delete_property (object_p, ECMA_PROPERTY_VALUE_PTR (property_p)); 1820 property_p = NULL; 1821 } 1822 1823 ecma_property_value_t *prop_value_p; 1824 1825 if (property_p == NULL) 1826 { 1827 prop_value_p = ecma_create_named_data_property (object_p, 1828 prop_name_p, 1829 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, 1830 NULL); 1831 } 1832 else 1833 { 1834 prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 1835 } 1836#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 1837 if (ecma_is_value_object(left_value) && ecma_op_is_callable(left_value)) { 1838 ecma_object_t* obj = ecma_get_object_from_value(left_value); 1839 ecma_object_type_t obj_type = ecma_get_object_type(obj); 1840 if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) { 1841 ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 1842 if (ecma_find_named_property (obj, property_name) == NULL) { 1843 ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, property_name, 1844 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, NULL); 1845 prop_val->value = ecma_copy_value(right_value); 1846 } else { 1847 ecma_deref_ecma_string (property_name); 1848 } 1849 } 1850 } 1851#endif 1852 1853 ecma_named_data_property_assign_value (object_p, prop_value_p, left_value); 1854 1855 ecma_deref_ecma_string (prop_name_p); 1856 1857 goto free_both_values; 1858 } 1859 case VM_OC_SET_GETTER: 1860 case VM_OC_SET_SETTER: 1861 { 1862 JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1); 1863 1864 ecma_string_t *prop_name_p = ecma_op_to_prop_name (left_value); 1865 1866 if (JERRY_UNLIKELY (prop_name_p == NULL)) 1867 { 1868 result = ECMA_VALUE_ERROR; 1869 goto error; 1870 } 1871 1872#if ENABLED (JERRY_ES2015) 1873 if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE)) 1874 && !(opcode_data & VM_OC_NON_STATIC_FLAG)) 1875 { 1876 result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable")); 1877 goto error; 1878 } 1879 1880 const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2; 1881#else /* !ENABLED (JERRY_ES2015) */ 1882 const int index = -1; 1883#endif /* ENABLED (JERRY_ES2015) */ 1884 1885 opfunc_set_accessor (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_SET_GETTER, 1886 stack_top_p[index], 1887 prop_name_p, 1888 right_value); 1889 1890 ecma_deref_ecma_string (prop_name_p); 1891 1892 goto free_both_values; 1893 } 1894 case VM_OC_PUSH_ARRAY: 1895 { 1896 // Note: this operation cannot throw an exception 1897 *stack_top_p++ = ecma_make_object_value (ecma_op_new_fast_array_object (0)); 1898 continue; 1899 } 1900#if ENABLED (JERRY_ES2015) 1901 case VM_OC_LOCAL_EVAL: 1902 { 1903 ECMA_CLEAR_LOCAL_PARSE_OPTS (); 1904 uint8_t parse_opts = *byte_code_p++; 1905 ECMA_SET_LOCAL_PARSE_OPTS (parse_opts); 1906 continue; 1907 } 1908 case VM_OC_SUPER_CALL: 1909 { 1910 uint8_t arguments_list_len = *byte_code_p++; 1911 1912 if (opcode >= CBC_EXT_SPREAD_SUPER_CALL) 1913 { 1914 stack_top_p -= arguments_list_len; 1915 ecma_collection_t *arguments_p = opfunc_spread_arguments (stack_top_p, arguments_list_len); 1916 1917 if (JERRY_UNLIKELY (arguments_p == NULL)) 1918 { 1919 result = ECMA_VALUE_ERROR; 1920 goto error; 1921 } 1922 1923 stack_top_p++; 1924 ECMA_SET_INTERNAL_VALUE_POINTER (stack_top_p[-1], arguments_p); 1925 } 1926 else 1927 { 1928 stack_top_p -= arguments_list_len; 1929 } 1930 1931 frame_ctx_p->call_operation = VM_EXEC_SUPER_CALL; 1932 frame_ctx_p->byte_code_p = byte_code_start_p; 1933 frame_ctx_p->stack_top_p = stack_top_p; 1934 return ECMA_VALUE_UNDEFINED; 1935 } 1936 case VM_OC_PUSH_CLASS_ENVIRONMENT: 1937 { 1938 opfunc_push_class_environment (frame_ctx_p, &stack_top_p, left_value); 1939 goto free_left_value; 1940 } 1941 case VM_OC_PUSH_IMPLICIT_CTOR: 1942 { 1943 *stack_top_p++ = opfunc_create_implicit_class_constructor (opcode); 1944 continue; 1945 } 1946 case VM_OC_INIT_CLASS: 1947 { 1948 result = opfunc_init_class (frame_ctx_p, stack_top_p); 1949 1950 if (ECMA_IS_VALUE_ERROR (result)) 1951 { 1952 goto error; 1953 } 1954 continue; 1955 } 1956 case VM_OC_FINALIZE_CLASS: 1957 { 1958 opfunc_finalize_class (frame_ctx_p, &stack_top_p, left_value); 1959 goto free_left_value; 1960 } 1961 case VM_OC_PUSH_SUPER_CONSTRUCTOR: 1962 { 1963 result = ecma_op_function_get_super_constructor (JERRY_CONTEXT (current_function_obj_p)); 1964 1965 if (ECMA_IS_VALUE_ERROR (result)) 1966 { 1967 goto error; 1968 } 1969 1970 *stack_top_p++ = result; 1971 continue; 1972 } 1973 case VM_OC_RESOLVE_LEXICAL_THIS: 1974 { 1975 result = ecma_op_get_this_binding (frame_ctx_p->lex_env_p); 1976 1977 if (ECMA_IS_VALUE_ERROR (result)) 1978 { 1979 goto error; 1980 } 1981 1982 *stack_top_p++ = result; 1983 continue; 1984 } 1985 case VM_OC_SUPER_REFERENCE: 1986 { 1987 result = opfunc_form_super_reference (&stack_top_p, frame_ctx_p, left_value, opcode); 1988 1989 if (ECMA_IS_VALUE_ERROR (result)) 1990 { 1991 goto error; 1992 } 1993 1994 goto free_left_value; 1995 } 1996 case VM_OC_PUSH_SPREAD_ELEMENT: 1997 { 1998 *stack_top_p++ = ECMA_VALUE_SPREAD_ELEMENT; 1999 continue; 2000 } 2001 case VM_OC_GET_ITERATOR: 2002 { 2003 result = ecma_op_get_iterator (stack_top_p[-1], ECMA_VALUE_EMPTY); 2004 2005 if (ECMA_IS_VALUE_ERROR (result)) 2006 { 2007 goto error; 2008 } 2009 2010 *stack_top_p++ = result; 2011 continue; 2012 } 2013 case VM_OC_ITERATOR_STEP: 2014 { 2015 JERRY_ASSERT (opcode >= CBC_EXT_ITERATOR_STEP && opcode <= CBC_EXT_ITERATOR_STEP_3); 2016 const uint8_t index = (uint8_t) (1 + (opcode - CBC_EXT_ITERATOR_STEP)); 2017 result = ecma_op_iterator_step (stack_top_p[-index]); 2018 2019 if (ECMA_IS_VALUE_ERROR (result)) 2020 { 2021 goto error; 2022 } 2023 2024 ecma_value_t value = ECMA_VALUE_UNDEFINED; 2025 2026 if (!ecma_is_value_false (result)) 2027 { 2028 value = ecma_op_iterator_value (result); 2029 ecma_free_value (result); 2030 2031 if (ECMA_IS_VALUE_ERROR (value)) 2032 { 2033 result = value; 2034 goto error; 2035 } 2036 } 2037 2038 *stack_top_p++ = value; 2039 continue; 2040 } 2041 case VM_OC_ITERATOR_CLOSE: 2042 { 2043 result = ecma_op_iterator_close (left_value); 2044 2045 if (ECMA_IS_VALUE_ERROR (result)) 2046 { 2047 goto error; 2048 } 2049 2050 goto free_left_value; 2051 } 2052 case VM_OC_DEFAULT_INITIALIZER: 2053 { 2054 JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end); 2055 2056 if (stack_top_p[-1] != ECMA_VALUE_UNDEFINED) 2057 { 2058 byte_code_p = byte_code_start_p + branch_offset; 2059 continue; 2060 } 2061 2062 stack_top_p--; 2063 continue; 2064 } 2065 case VM_OC_REST_INITIALIZER: 2066 { 2067 JERRY_ASSERT (opcode >= CBC_EXT_REST_INITIALIZER && opcode <= CBC_EXT_REST_INITIALIZER_3); 2068 const uint8_t iterator_index = (uint8_t) (1 + (opcode - CBC_EXT_REST_INITIALIZER)); 2069 ecma_object_t *array_p = ecma_op_new_fast_array_object (0); 2070 ecma_value_t iterator = stack_top_p[-iterator_index]; 2071 uint32_t index = 0; 2072 2073 while (true) 2074 { 2075 result = ecma_op_iterator_step (iterator); 2076 2077 if (ECMA_IS_VALUE_ERROR (result)) 2078 { 2079 ecma_deref_object (array_p); 2080 goto error; 2081 } 2082 2083 if (ecma_is_value_false (result)) 2084 { 2085 break; 2086 } 2087 2088 ecma_value_t value = ecma_op_iterator_value (result); 2089 ecma_free_value (result); 2090 2091 if (ECMA_IS_VALUE_ERROR (value)) 2092 { 2093 ecma_deref_object (array_p); 2094 result = value; 2095 goto error; 2096 } 2097 2098 bool set_result = ecma_fast_array_set_property (array_p, index++, value); 2099 JERRY_ASSERT (set_result); 2100 ecma_free_value (value); 2101 } 2102 2103 *stack_top_p++ = ecma_make_object_value (array_p); 2104 continue; 2105 } 2106 case VM_OC_INITIALIZER_PUSH_PROP: 2107 { 2108 result = vm_op_get_value (stack_top_p[-1], left_value); 2109 2110 if (ECMA_IS_VALUE_ERROR (result)) 2111 { 2112 goto error; 2113 } 2114 2115 *stack_top_p++ = result; 2116 goto free_left_value; 2117 } 2118 case VM_OC_SPREAD_ARGUMENTS: 2119 { 2120 uint8_t arguments_list_len = *byte_code_p++; 2121 stack_top_p -= arguments_list_len; 2122 2123 ecma_collection_t *arguments_p = opfunc_spread_arguments (stack_top_p, arguments_list_len); 2124 2125 if (JERRY_UNLIKELY (arguments_p == NULL)) 2126 { 2127 result = ECMA_VALUE_ERROR; 2128 goto error; 2129 } 2130 2131 stack_top_p++; 2132 ECMA_SET_INTERNAL_VALUE_POINTER (stack_top_p[-1], arguments_p); 2133 2134 frame_ctx_p->call_operation = VM_EXEC_SPREAD_OP; 2135 frame_ctx_p->byte_code_p = byte_code_start_p; 2136 frame_ctx_p->stack_top_p = stack_top_p; 2137 return ECMA_VALUE_UNDEFINED; 2138 } 2139 case VM_OC_CREATE_GENERATOR: 2140 { 2141 frame_ctx_p->call_operation = VM_EXEC_RETURN; 2142 frame_ctx_p->byte_code_p = byte_code_p; 2143 frame_ctx_p->stack_top_p = stack_top_p; 2144 result = opfunc_create_executable_object (frame_ctx_p); 2145 2146 if (ECMA_IS_VALUE_ERROR (result)) 2147 { 2148 goto error; 2149 } 2150 2151 return result; 2152 } 2153 case VM_OC_YIELD: 2154 { 2155 frame_ctx_p->call_operation = VM_EXEC_RETURN; 2156 frame_ctx_p->byte_code_p = byte_code_p; 2157 frame_ctx_p->stack_top_p = --stack_top_p; 2158 return *stack_top_p; 2159 } 2160 case VM_OC_AWAIT: 2161 { 2162 continue; 2163 } 2164 case VM_OC_EXT_RETURN: 2165 { 2166 result = left_value; 2167 left_value = ECMA_VALUE_UNDEFINED; 2168 2169 ecma_value_t *stack_bottom_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth; 2170 2171 while (stack_top_p > stack_bottom_p) 2172 { 2173 ecma_fast_free_value (*(--stack_top_p)); 2174 } 2175 2176 goto error; 2177 } 2178 case VM_OC_RETURN_PROMISE: 2179 { 2180 result = opfunc_return_promise (left_value); 2181 left_value = ECMA_VALUE_UNDEFINED; 2182 goto error; 2183 } 2184 case VM_OC_STRING_CONCAT: 2185 { 2186 ecma_string_t *left_str_p = ecma_op_to_string (left_value); 2187 2188 if (JERRY_UNLIKELY (left_str_p == NULL)) 2189 { 2190 result = ECMA_VALUE_ERROR; 2191 goto error; 2192 } 2193 ecma_string_t *right_str_p = ecma_op_to_string (right_value); 2194 2195 if (JERRY_UNLIKELY (right_str_p == NULL)) 2196 { 2197 ecma_deref_ecma_string (left_str_p); 2198 result = ECMA_VALUE_ERROR; 2199 goto error; 2200 } 2201 2202 ecma_string_t *result_str_p = ecma_concat_ecma_strings (left_str_p, right_str_p); 2203 ecma_deref_ecma_string (right_str_p); 2204 2205 *stack_top_p++ = ecma_make_string_value (result_str_p); 2206 goto free_both_values; 2207 } 2208 case VM_OC_GET_TEMPLATE_OBJECT: 2209 { 2210 uint8_t tagged_idx = *byte_code_p++; 2211 ecma_collection_t *collection_p = ecma_compiled_code_get_tagged_template_collection (bytecode_header_p); 2212 JERRY_ASSERT (tagged_idx < collection_p->item_count); 2213 2214 *stack_top_p++ = ecma_copy_value (collection_p->buffer_p[tagged_idx]); 2215 continue; 2216 } 2217 case VM_OC_PUSH_NEW_TARGET: 2218 { 2219 ecma_object_t *new_target_object = JERRY_CONTEXT (current_new_target); 2220 if (new_target_object == NULL) 2221 { 2222 *stack_top_p++ = ECMA_VALUE_UNDEFINED; 2223 } 2224 else 2225 { 2226 ecma_ref_object (new_target_object); 2227 *stack_top_p++ = ecma_make_object_value (new_target_object); 2228 } 2229 continue; 2230 } 2231 case VM_OC_REQUIRE_OBJECT_COERCIBLE: 2232 { 2233 result = ecma_op_check_object_coercible (stack_top_p[-1]); 2234 2235 if (ECMA_IS_VALUE_ERROR (result)) 2236 { 2237 goto error; 2238 } 2239 continue; 2240 } 2241 case VM_OC_ASSIGN_SUPER: 2242 { 2243 result = opfunc_assign_super_reference (&stack_top_p, frame_ctx_p, opcode_data); 2244 2245 if (ECMA_IS_VALUE_ERROR (result)) 2246 { 2247 goto error; 2248 } 2249 continue; 2250 } 2251#endif /* ENABLED (JERRY_ES2015) */ 2252 case VM_OC_PUSH_ELISON: 2253 { 2254 *stack_top_p++ = ECMA_VALUE_ARRAY_HOLE; 2255 continue; 2256 } 2257 case VM_OC_APPEND_ARRAY: 2258 { 2259 uint16_t values_length = *byte_code_p++; 2260 stack_top_p -= values_length; 2261 2262#if ENABLED (JERRY_ES2015) 2263 if (*byte_code_start_p == CBC_EXT_OPCODE) 2264 { 2265 values_length = (uint16_t) (values_length | OPFUNC_HAS_SPREAD_ELEMENT); 2266 } 2267#endif /* ENABLED (JERRY_ES2015) */ 2268 result = opfunc_append_array (stack_top_p, values_length); 2269 2270#if ENABLED (JERRY_ES2015) 2271 if (ECMA_IS_VALUE_ERROR (result)) 2272 { 2273 goto error; 2274 } 2275#else /* !ENABLED (JERRY_ES2015) */ 2276 JERRY_ASSERT (ecma_is_value_empty (result)); 2277#endif /* ENABLED (JERRY_ES2015) */ 2278 continue; 2279 } 2280 case VM_OC_IDENT_REFERENCE: 2281 { 2282 uint16_t literal_index; 2283 2284 READ_LITERAL_INDEX (literal_index); 2285 2286 JERRY_ASSERT (literal_index < ident_end); 2287 2288 if (literal_index < register_end) 2289 { 2290 *stack_top_p++ = ECMA_VALUE_REGISTER_REF; 2291 *stack_top_p++ = ecma_make_integer_value (literal_index); 2292 *stack_top_p++ = ecma_fast_copy_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); 2293 } 2294 else 2295 { 2296 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 2297 2298 ecma_object_t *ref_base_lex_env_p; 2299 2300 result = ecma_op_get_value_lex_env_base (frame_ctx_p->lex_env_p, 2301 &ref_base_lex_env_p, 2302 name_p); 2303 2304 if (ECMA_IS_VALUE_ERROR (result)) 2305 { 2306 goto error; 2307 } 2308 2309 ecma_ref_object (ref_base_lex_env_p); 2310 ecma_ref_ecma_string (name_p); 2311 *stack_top_p++ = ecma_make_object_value (ref_base_lex_env_p); 2312 *stack_top_p++ = ecma_make_string_value (name_p); 2313 *stack_top_p++ = result; 2314 } 2315 continue; 2316 } 2317 case VM_OC_PROP_GET: 2318 { 2319 result = vm_op_get_value (left_value, right_value); 2320 2321 if (ECMA_IS_VALUE_ERROR (result)) 2322 { 2323 goto error; 2324 } 2325 2326 *stack_top_p++ = result; 2327 goto free_both_values; 2328 } 2329 case VM_OC_PROP_REFERENCE: 2330 { 2331 /* Forms with reference requires preserving the base and offset. */ 2332 2333 if (opcode == CBC_PUSH_PROP_REFERENCE) 2334 { 2335 left_value = stack_top_p[-2]; 2336 right_value = stack_top_p[-1]; 2337 } 2338 else if (opcode == CBC_PUSH_PROP_LITERAL_REFERENCE) 2339 { 2340 *stack_top_p++ = left_value; 2341 right_value = left_value; 2342 left_value = stack_top_p[-2]; 2343 } 2344 else 2345 { 2346 JERRY_ASSERT (opcode == CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE 2347 || opcode == CBC_PUSH_PROP_THIS_LITERAL_REFERENCE); 2348 *stack_top_p++ = left_value; 2349 *stack_top_p++ = right_value; 2350 } 2351 /* FALLTHRU */ 2352 } 2353 case VM_OC_PROP_PRE_INCR: 2354 case VM_OC_PROP_PRE_DECR: 2355 case VM_OC_PROP_POST_INCR: 2356 case VM_OC_PROP_POST_DECR: 2357 { 2358 result = vm_op_get_value (left_value, 2359 right_value); 2360 2361 if (opcode < CBC_PRE_INCR) 2362 { 2363 left_value = ECMA_VALUE_UNDEFINED; 2364 right_value = ECMA_VALUE_UNDEFINED; 2365 } 2366 2367 if (ECMA_IS_VALUE_ERROR (result)) 2368 { 2369 goto error; 2370 } 2371 2372 if (opcode < CBC_PRE_INCR) 2373 { 2374 break; 2375 } 2376 2377 stack_top_p += 2; 2378 left_value = result; 2379 right_value = ECMA_VALUE_UNDEFINED; 2380 /* FALLTHRU */ 2381 } 2382 case VM_OC_PRE_INCR: 2383 case VM_OC_PRE_DECR: 2384 case VM_OC_POST_INCR: 2385 case VM_OC_POST_DECR: 2386 { 2387 uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR; 2388 2389 byte_code_p = byte_code_start_p + 1; 2390 2391 if (ecma_is_value_integer_number (left_value)) 2392 { 2393 result = left_value; 2394 left_value = ECMA_VALUE_UNDEFINED; 2395 2396 ecma_integer_value_t int_value = (ecma_integer_value_t) result; 2397 ecma_integer_value_t int_increase = 0; 2398 2399 if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG) 2400 { 2401 if (int_value > ECMA_INTEGER_NUMBER_MIN_SHIFTED) 2402 { 2403 int_increase = -(1 << ECMA_DIRECT_SHIFT); 2404 } 2405 } 2406 else if (int_value < ECMA_INTEGER_NUMBER_MAX_SHIFTED) 2407 { 2408 int_increase = 1 << ECMA_DIRECT_SHIFT; 2409 } 2410 2411 if (JERRY_LIKELY (int_increase != 0)) 2412 { 2413 /* Postfix operators require the unmodifed number value. */ 2414 if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG) 2415 { 2416 if (opcode_data & VM_OC_PUT_STACK) 2417 { 2418 if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG) 2419 { 2420 JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT 2421 || opcode == CBC_POST_DECR_IDENT_PUSH_RESULT); 2422 2423 *stack_top_p++ = result; 2424 } 2425 else 2426 { 2427 /* The parser ensures there is enough space for the 2428 * extra value on the stack. See js-parser-expr.c. */ 2429 2430 JERRY_ASSERT (opcode == CBC_POST_INCR_PUSH_RESULT 2431 || opcode == CBC_POST_DECR_PUSH_RESULT); 2432 2433 stack_top_p++; 2434 stack_top_p[-1] = stack_top_p[-2]; 2435 stack_top_p[-2] = stack_top_p[-3]; 2436 stack_top_p[-3] = result; 2437 } 2438 opcode_data &= (uint32_t) ~VM_OC_PUT_STACK; 2439 } 2440 else if (opcode_data & VM_OC_PUT_BLOCK) 2441 { 2442 ecma_free_value (frame_ctx_p->block_result); 2443 frame_ctx_p->block_result = result; 2444 opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK; 2445 } 2446 } 2447 2448 result = (ecma_value_t) (int_value + int_increase); 2449 break; 2450 } 2451 } 2452 else if (ecma_is_value_float_number (left_value)) 2453 { 2454 result = left_value; 2455 left_value = ECMA_VALUE_UNDEFINED; 2456 } 2457 else 2458 { 2459 result = ecma_op_to_number (left_value); 2460 2461 if (ECMA_IS_VALUE_ERROR (result)) 2462 { 2463 goto error; 2464 } 2465 } 2466 2467 ecma_number_t increase = ECMA_NUMBER_ONE; 2468 ecma_number_t result_number = ecma_get_number_from_value (result); 2469 2470 if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG) 2471 { 2472 /* For decrement operators */ 2473 increase = ECMA_NUMBER_MINUS_ONE; 2474 } 2475 2476 /* Post operators require the unmodifed number value. */ 2477 if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG) 2478 { 2479 if (opcode_data & VM_OC_PUT_STACK) 2480 { 2481 if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG) 2482 { 2483 JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT 2484 || opcode == CBC_POST_DECR_IDENT_PUSH_RESULT); 2485 2486 *stack_top_p++ = ecma_copy_value (result); 2487 } 2488 else 2489 { 2490 /* The parser ensures there is enough space for the 2491 * extra value on the stack. See js-parser-expr.c. */ 2492 2493 JERRY_ASSERT (opcode == CBC_POST_INCR_PUSH_RESULT 2494 || opcode == CBC_POST_DECR_PUSH_RESULT); 2495 2496 stack_top_p++; 2497 stack_top_p[-1] = stack_top_p[-2]; 2498 stack_top_p[-2] = stack_top_p[-3]; 2499 stack_top_p[-3] = ecma_copy_value (result); 2500 } 2501 opcode_data &= (uint32_t) ~VM_OC_PUT_STACK; 2502 } 2503 else if (opcode_data & VM_OC_PUT_BLOCK) 2504 { 2505 ecma_free_value (frame_ctx_p->block_result); 2506 frame_ctx_p->block_result = ecma_copy_value (result); 2507 opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK; 2508 } 2509 } 2510 2511 if (ecma_is_value_integer_number (result)) 2512 { 2513 result = ecma_make_number_value (result_number + increase); 2514 } 2515 else 2516 { 2517 result = ecma_update_float_number (result, result_number + increase); 2518 } 2519 break; 2520 } 2521 case VM_OC_ASSIGN: 2522 { 2523#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 2524 if (ecma_is_value_object(left_value) && ecma_op_is_callable(left_value)) { 2525 ecma_object_t* obj = ecma_get_object_from_value(left_value); 2526 ecma_object_type_t obj_type = ecma_get_object_type(obj); 2527 if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) { 2528 ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 2529 if (ecma_find_named_property (obj, property_name) == NULL) { 2530 ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, property_name, 2531 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, NULL); 2532 prop_val->value = ecma_copy_value(right_value); 2533 } else { 2534 ecma_deref_ecma_string (property_name); 2535 } 2536 } 2537 } 2538#endif 2539 2540 result = left_value; 2541 left_value = ECMA_VALUE_UNDEFINED; 2542 break; 2543 } 2544 case VM_OC_MOV_IDENT: 2545 { 2546 uint32_t literal_index; 2547 2548 READ_LITERAL_INDEX (literal_index); 2549 2550 JERRY_ASSERT (literal_index < register_end); 2551 JERRY_ASSERT (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))); 2552 2553 ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); 2554 VM_GET_REGISTER (frame_ctx_p, literal_index) = left_value; 2555 continue; 2556 } 2557 case VM_OC_ASSIGN_PROP: 2558 { 2559#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 2560 if (ecma_is_value_object(left_value) && ecma_op_is_callable(left_value)) { 2561 ecma_object_t* obj = ecma_get_object_from_value(left_value); 2562 ecma_object_type_t obj_type = ecma_get_object_type(obj); 2563 if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) { 2564 ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 2565 if (ecma_find_named_property (obj, property_name) == NULL) { 2566 ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, property_name, 2567 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, NULL); 2568 prop_val->value = ecma_copy_value(right_value); 2569 } else { 2570 ecma_deref_ecma_string (property_name); 2571 } 2572 } 2573 } 2574#endif 2575 2576 result = stack_top_p[-1]; 2577 stack_top_p[-1] = left_value; 2578 left_value = ECMA_VALUE_UNDEFINED; 2579 break; 2580 } 2581 case VM_OC_ASSIGN_PROP_THIS: 2582 { 2583#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 2584 if (ecma_is_value_object(left_value) && ecma_op_is_callable(left_value)) { 2585 ecma_object_t* obj = ecma_get_object_from_value(left_value); 2586 ecma_object_type_t obj_type = ecma_get_object_type(obj); 2587 if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) { 2588 ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 2589 if (ecma_find_named_property (obj, property_name) == NULL) { 2590 ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, property_name, 2591 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, NULL); 2592 prop_val->value = ecma_copy_value(right_value); 2593 } else { 2594 ecma_deref_ecma_string (property_name); 2595 } 2596 } 2597 } 2598#endif 2599 2600 result = stack_top_p[-1]; 2601 stack_top_p[-1] = ecma_copy_value (frame_ctx_p->this_binding); 2602 *stack_top_p++ = left_value; 2603 left_value = ECMA_VALUE_UNDEFINED; 2604 break; 2605 } 2606 case VM_OC_RETURN: 2607 { 2608 JERRY_ASSERT (opcode == CBC_RETURN 2609 || opcode == CBC_RETURN_WITH_BLOCK 2610 || opcode == CBC_RETURN_WITH_LITERAL); 2611 2612 if (opcode == CBC_RETURN_WITH_BLOCK) 2613 { 2614 left_value = frame_ctx_p->block_result; 2615 frame_ctx_p->block_result = ECMA_VALUE_UNDEFINED; 2616 } 2617 2618 result = left_value; 2619 left_value = ECMA_VALUE_UNDEFINED; 2620 goto error; 2621 } 2622 case VM_OC_THROW: 2623 { 2624 jcontext_raise_exception (left_value); 2625 2626 result = ECMA_VALUE_ERROR; 2627 left_value = ECMA_VALUE_UNDEFINED; 2628 goto error; 2629 } 2630 case VM_OC_THROW_REFERENCE_ERROR: 2631 { 2632 result = ecma_raise_reference_error (ECMA_ERR_MSG ("Undefined reference.")); 2633 goto error; 2634 } 2635 case VM_OC_EVAL: 2636 { 2637 JERRY_CONTEXT (status_flags) |= ECMA_STATUS_DIRECT_EVAL; 2638 JERRY_ASSERT ((*byte_code_p >= CBC_CALL && *byte_code_p <= CBC_CALL2_PROP_BLOCK) 2639 || (*byte_code_p == CBC_EXT_OPCODE 2640 && byte_code_p[1] >= CBC_EXT_SPREAD_CALL 2641 && byte_code_p[1] <= CBC_EXT_SPREAD_CALL_PROP_BLOCK)); 2642 continue; 2643 } 2644 case VM_OC_CALL: 2645 { 2646 frame_ctx_p->call_operation = VM_EXEC_CALL; 2647 frame_ctx_p->byte_code_p = byte_code_start_p; 2648 frame_ctx_p->stack_top_p = stack_top_p; 2649 return ECMA_VALUE_UNDEFINED; 2650 } 2651 case VM_OC_NEW: 2652 { 2653 frame_ctx_p->call_operation = VM_EXEC_CONSTRUCT; 2654 frame_ctx_p->byte_code_p = byte_code_start_p; 2655 frame_ctx_p->stack_top_p = stack_top_p; 2656 return ECMA_VALUE_UNDEFINED; 2657 } 2658 case VM_OC_ERROR: 2659 { 2660 JERRY_ASSERT (frame_ctx_p->byte_code_p[1] == CBC_EXT_ERROR); 2661#if ENABLED (JERRY_DEBUGGER) 2662 frame_ctx_p->byte_code_p = JERRY_CONTEXT (debugger_exception_byte_code_p); 2663#endif /* ENABLED (JERRY_DEBUGGER) */ 2664 2665 result = ECMA_VALUE_ERROR; 2666 goto error; 2667 } 2668 case VM_OC_RESOLVE_BASE_FOR_CALL: 2669 { 2670 ecma_value_t this_value = stack_top_p[-3]; 2671 2672 if (this_value == ECMA_VALUE_REGISTER_REF) 2673 { 2674 /* Lexical environment cannot be 'this' value. */ 2675 stack_top_p[-2] = ECMA_VALUE_UNDEFINED; 2676 stack_top_p[-3] = ECMA_VALUE_UNDEFINED; 2677 } 2678 else if (vm_get_implicit_this_value (&this_value)) 2679 { 2680 ecma_free_value (stack_top_p[-3]); 2681 stack_top_p[-3] = this_value; 2682 } 2683 2684 continue; 2685 } 2686 case VM_OC_PROP_DELETE: 2687 { 2688 result = vm_op_delete_prop (left_value, right_value, is_strict); 2689 2690 if (ECMA_IS_VALUE_ERROR (result)) 2691 { 2692 goto error; 2693 } 2694 2695 JERRY_ASSERT (ecma_is_value_boolean (result)); 2696 2697 *stack_top_p++ = result; 2698 goto free_both_values; 2699 } 2700 case VM_OC_DELETE: 2701 { 2702 uint16_t literal_index; 2703 2704 READ_LITERAL_INDEX (literal_index); 2705 2706 if (literal_index < register_end) 2707 { 2708 *stack_top_p++ = ECMA_VALUE_FALSE; 2709 continue; 2710 } 2711 2712 result = vm_op_delete_var (literal_start_p[literal_index], 2713 frame_ctx_p->lex_env_p); 2714 2715 if (ECMA_IS_VALUE_ERROR (result)) 2716 { 2717 goto error; 2718 } 2719 2720 JERRY_ASSERT (ecma_is_value_boolean (result)); 2721 2722 *stack_top_p++ = result; 2723 continue; 2724 } 2725 case VM_OC_JUMP: 2726 { 2727 byte_code_p = byte_code_start_p + branch_offset; 2728 continue; 2729 } 2730 case VM_OC_BRANCH_IF_STRICT_EQUAL: 2731 { 2732 ecma_value_t value = *(--stack_top_p); 2733 2734 JERRY_ASSERT (stack_top_p > VM_GET_REGISTERS (frame_ctx_p) + register_end); 2735 2736 if (ecma_op_strict_equality_compare (value, stack_top_p[-1])) 2737 { 2738 byte_code_p = byte_code_start_p + branch_offset; 2739 ecma_free_value (*--stack_top_p); 2740 } 2741 ecma_free_value (value); 2742 continue; 2743 } 2744 case VM_OC_BRANCH_IF_TRUE: 2745 case VM_OC_BRANCH_IF_FALSE: 2746 case VM_OC_BRANCH_IF_LOGICAL_TRUE: 2747 case VM_OC_BRANCH_IF_LOGICAL_FALSE: 2748 { 2749 uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_BRANCH_IF_TRUE; 2750 ecma_value_t value = *(--stack_top_p); 2751 2752 bool boolean_value = ecma_op_to_boolean (value); 2753 2754 if (opcode_flags & VM_OC_BRANCH_IF_FALSE_FLAG) 2755 { 2756 boolean_value = !boolean_value; 2757 } 2758 2759 if (boolean_value) 2760 { 2761 byte_code_p = byte_code_start_p + branch_offset; 2762 if (opcode_flags & VM_OC_LOGICAL_BRANCH_FLAG) 2763 { 2764 /* "Push" the value back to the stack. */ 2765 ++stack_top_p; 2766 continue; 2767 } 2768 } 2769 2770 ecma_fast_free_value (value); 2771 continue; 2772 } 2773 case VM_OC_PLUS: 2774 case VM_OC_MINUS: 2775 { 2776 result = opfunc_unary_operation (left_value, VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_PLUS); 2777 2778 if (ECMA_IS_VALUE_ERROR (result)) 2779 { 2780 goto error; 2781 } 2782 2783 *stack_top_p++ = result; 2784 goto free_left_value; 2785 } 2786 case VM_OC_NOT: 2787 { 2788 *stack_top_p++ = ecma_make_boolean_value (!ecma_op_to_boolean (left_value)); 2789 JERRY_ASSERT (ecma_is_value_boolean (stack_top_p[-1])); 2790 goto free_left_value; 2791 } 2792 case VM_OC_BIT_NOT: 2793 { 2794 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 2795 direct_type_mask_must_fill_all_bits_before_the_value_starts); 2796 2797 if (ecma_is_value_integer_number (left_value)) 2798 { 2799 *stack_top_p++ = (~left_value) & (ecma_value_t) (~ECMA_DIRECT_TYPE_MASK); 2800 goto free_left_value; 2801 } 2802 2803 result = do_number_bitwise_logic (NUMBER_BITWISE_NOT, 2804 left_value, 2805 left_value); 2806 2807 if (ECMA_IS_VALUE_ERROR (result)) 2808 { 2809 goto error; 2810 } 2811 2812 *stack_top_p++ = result; 2813 goto free_left_value; 2814 } 2815 case VM_OC_VOID: 2816 { 2817 *stack_top_p++ = ECMA_VALUE_UNDEFINED; 2818 goto free_left_value; 2819 } 2820 case VM_OC_TYPEOF_IDENT: 2821 { 2822 uint16_t literal_index; 2823 2824 READ_LITERAL_INDEX (literal_index); 2825 2826 JERRY_ASSERT (literal_index < ident_end); 2827 2828 if (literal_index < register_end) 2829 { 2830 left_value = ecma_copy_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); 2831 } 2832 else 2833 { 2834 ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]); 2835 2836 ecma_object_t *ref_base_lex_env_p; 2837 2838 result = ecma_op_get_value_lex_env_base (frame_ctx_p->lex_env_p, 2839 &ref_base_lex_env_p, 2840 name_p); 2841 2842 if (ref_base_lex_env_p == NULL) 2843 { 2844 jcontext_release_exception (); 2845 result = ECMA_VALUE_UNDEFINED; 2846 } 2847 else if (ECMA_IS_VALUE_ERROR (result)) 2848 { 2849 goto error; 2850 } 2851 2852 left_value = result; 2853 } 2854 /* FALLTHRU */ 2855 } 2856 case VM_OC_TYPEOF: 2857 { 2858 result = opfunc_typeof (left_value); 2859 2860 if (ECMA_IS_VALUE_ERROR (result)) 2861 { 2862 goto error; 2863 } 2864 2865 *stack_top_p++ = result; 2866 goto free_left_value; 2867 } 2868 case VM_OC_ADD: 2869 { 2870 if (ecma_are_values_integer_numbers (left_value, right_value)) 2871 { 2872 ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); 2873 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 2874 *stack_top_p++ = ecma_make_int32_value ((int32_t) (left_integer + right_integer)); 2875 continue; 2876 } 2877 2878 if (ecma_is_value_float_number (left_value) 2879 && ecma_is_value_number (right_value)) 2880 { 2881 ecma_number_t new_value = (ecma_get_float_from_value (left_value) + 2882 ecma_get_number_from_value (right_value)); 2883 2884 *stack_top_p++ = ecma_update_float_number (left_value, new_value); 2885 ecma_free_number (right_value); 2886 continue; 2887 } 2888 2889 if (ecma_is_value_float_number (right_value) 2890 && ecma_is_value_integer_number (left_value)) 2891 { 2892 ecma_number_t new_value = ((ecma_number_t) ecma_get_integer_from_value (left_value) + 2893 ecma_get_float_from_value (right_value)); 2894 2895 *stack_top_p++ = ecma_update_float_number (right_value, new_value); 2896 continue; 2897 } 2898 2899 result = opfunc_addition (left_value, right_value); 2900 2901 if (ECMA_IS_VALUE_ERROR (result)) 2902 { 2903 goto error; 2904 } 2905 2906 *stack_top_p++ = result; 2907 goto free_both_values; 2908 } 2909 case VM_OC_SUB: 2910 { 2911 JERRY_STATIC_ASSERT (ECMA_INTEGER_NUMBER_MAX * 2 <= INT32_MAX 2912 && ECMA_INTEGER_NUMBER_MIN * 2 >= INT32_MIN, 2913 doubled_ecma_numbers_must_fit_into_int32_range); 2914 2915 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 2916 && !ECMA_IS_VALUE_ERROR (right_value)); 2917 2918 if (ecma_are_values_integer_numbers (left_value, right_value)) 2919 { 2920 ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); 2921 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 2922 *stack_top_p++ = ecma_make_int32_value ((int32_t) (left_integer - right_integer)); 2923 continue; 2924 } 2925 2926 if (ecma_is_value_float_number (left_value) 2927 && ecma_is_value_number (right_value)) 2928 { 2929 ecma_number_t new_value = (ecma_get_float_from_value (left_value) - 2930 ecma_get_number_from_value (right_value)); 2931 2932 *stack_top_p++ = ecma_update_float_number (left_value, new_value); 2933 ecma_free_number (right_value); 2934 continue; 2935 } 2936 2937 if (ecma_is_value_float_number (right_value) 2938 && ecma_is_value_integer_number (left_value)) 2939 { 2940 ecma_number_t new_value = ((ecma_number_t) ecma_get_integer_from_value (left_value) - 2941 ecma_get_float_from_value (right_value)); 2942 2943 *stack_top_p++ = ecma_update_float_number (right_value, new_value); 2944 continue; 2945 } 2946 2947 result = do_number_arithmetic (NUMBER_ARITHMETIC_SUBTRACTION, 2948 left_value, 2949 right_value); 2950 2951 if (ECMA_IS_VALUE_ERROR (result)) 2952 { 2953 goto error; 2954 } 2955 2956 *stack_top_p++ = result; 2957 goto free_both_values; 2958 } 2959 case VM_OC_MUL: 2960 { 2961 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 2962 && !ECMA_IS_VALUE_ERROR (right_value)); 2963 2964 JERRY_STATIC_ASSERT (ECMA_INTEGER_MULTIPLY_MAX * ECMA_INTEGER_MULTIPLY_MAX <= ECMA_INTEGER_NUMBER_MAX 2965 && -(ECMA_INTEGER_MULTIPLY_MAX * ECMA_INTEGER_MULTIPLY_MAX) >= ECMA_INTEGER_NUMBER_MIN, 2966 square_of_integer_multiply_max_must_fit_into_integer_value_range); 2967 2968 if (ecma_are_values_integer_numbers (left_value, right_value)) 2969 { 2970 ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); 2971 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 2972 2973 if (-ECMA_INTEGER_MULTIPLY_MAX <= left_integer 2974 && left_integer <= ECMA_INTEGER_MULTIPLY_MAX 2975 && -ECMA_INTEGER_MULTIPLY_MAX <= right_integer 2976 && right_integer <= ECMA_INTEGER_MULTIPLY_MAX 2977 && left_value != 0 2978 && right_value != 0) 2979 { 2980 *stack_top_p++ = ecma_integer_multiply (left_integer, right_integer); 2981 continue; 2982 } 2983 2984 ecma_number_t multiply = (ecma_number_t) left_integer * (ecma_number_t) right_integer; 2985 *stack_top_p++ = ecma_make_number_value (multiply); 2986 continue; 2987 } 2988 2989 if (ecma_is_value_float_number (left_value) 2990 && ecma_is_value_number (right_value)) 2991 { 2992 ecma_number_t new_value = (ecma_get_float_from_value (left_value) * 2993 ecma_get_number_from_value (right_value)); 2994 2995 *stack_top_p++ = ecma_update_float_number (left_value, new_value); 2996 ecma_free_number (right_value); 2997 continue; 2998 } 2999 3000 if (ecma_is_value_float_number (right_value) 3001 && ecma_is_value_integer_number (left_value)) 3002 { 3003 ecma_number_t new_value = ((ecma_number_t) ecma_get_integer_from_value (left_value) * 3004 ecma_get_float_from_value (right_value)); 3005 3006 *stack_top_p++ = ecma_update_float_number (right_value, new_value); 3007 continue; 3008 } 3009 3010 result = do_number_arithmetic (NUMBER_ARITHMETIC_MULTIPLICATION, 3011 left_value, 3012 right_value); 3013 3014 if (ECMA_IS_VALUE_ERROR (result)) 3015 { 3016 goto error; 3017 } 3018 3019 *stack_top_p++ = result; 3020 goto free_both_values; 3021 } 3022 case VM_OC_DIV: 3023 { 3024 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 3025 && !ECMA_IS_VALUE_ERROR (right_value)); 3026 3027 result = do_number_arithmetic (NUMBER_ARITHMETIC_DIVISION, 3028 left_value, 3029 right_value); 3030 3031 if (ECMA_IS_VALUE_ERROR (result)) 3032 { 3033 goto error; 3034 } 3035 3036 *stack_top_p++ = result; 3037 goto free_both_values; 3038 } 3039 case VM_OC_MOD: 3040 { 3041 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value) 3042 && !ECMA_IS_VALUE_ERROR (right_value)); 3043 3044 if (ecma_are_values_integer_numbers (left_value, right_value)) 3045 { 3046 ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); 3047 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 3048 3049 if (right_integer != 0) 3050 { 3051 ecma_integer_value_t mod_result = left_integer % right_integer; 3052 3053 if (mod_result != 0 || left_integer >= 0) 3054 { 3055 *stack_top_p++ = ecma_make_integer_value (mod_result); 3056 continue; 3057 } 3058 } 3059 } 3060 3061 result = do_number_arithmetic (NUMBER_ARITHMETIC_REMAINDER, 3062 left_value, 3063 right_value); 3064 3065 if (ECMA_IS_VALUE_ERROR (result)) 3066 { 3067 goto error; 3068 } 3069 3070 *stack_top_p++ = result; 3071 goto free_both_values; 3072 } 3073#if ENABLED (JERRY_ES2015) 3074 case VM_OC_EXP: 3075 { 3076 result = do_number_arithmetic (NUMBER_ARITHMETIC_EXPONENTIATION, 3077 left_value, 3078 right_value); 3079 3080 if (ECMA_IS_VALUE_ERROR (result)) 3081 { 3082 goto error; 3083 } 3084 3085 *stack_top_p++ = result; 3086 goto free_both_values; 3087 } 3088#endif /* ENABLED (JERRY_ES2015) */ 3089 case VM_OC_EQUAL: 3090 { 3091 result = opfunc_equality (left_value, right_value); 3092 3093 if (ECMA_IS_VALUE_ERROR (result)) 3094 { 3095 goto error; 3096 } 3097 3098 *stack_top_p++ = result; 3099 goto free_both_values; 3100 } 3101 case VM_OC_NOT_EQUAL: 3102 { 3103 result = opfunc_equality (left_value, right_value); 3104 3105 if (ECMA_IS_VALUE_ERROR (result)) 3106 { 3107 goto error; 3108 } 3109 3110 *stack_top_p++ = ecma_invert_boolean_value (result); 3111 goto free_both_values; 3112 } 3113 case VM_OC_STRICT_EQUAL: 3114 { 3115 bool is_equal = ecma_op_strict_equality_compare (left_value, right_value); 3116 3117 result = ecma_make_boolean_value (is_equal); 3118 3119 *stack_top_p++ = result; 3120 goto free_both_values; 3121 } 3122 case VM_OC_STRICT_NOT_EQUAL: 3123 { 3124 bool is_equal = ecma_op_strict_equality_compare (left_value, right_value); 3125 3126 result = ecma_make_boolean_value (!is_equal); 3127 3128 *stack_top_p++ = result; 3129 goto free_both_values; 3130 } 3131 case VM_OC_BIT_OR: 3132 { 3133 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 3134 direct_type_mask_must_fill_all_bits_before_the_value_starts); 3135 3136 if (ecma_are_values_integer_numbers (left_value, right_value)) 3137 { 3138 *stack_top_p++ = left_value | right_value; 3139 continue; 3140 } 3141 3142 result = do_number_bitwise_logic (NUMBER_BITWISE_LOGIC_OR, 3143 left_value, 3144 right_value); 3145 3146 if (ECMA_IS_VALUE_ERROR (result)) 3147 { 3148 goto error; 3149 } 3150 3151 *stack_top_p++ = result; 3152 goto free_both_values; 3153 } 3154 case VM_OC_BIT_XOR: 3155 { 3156 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 3157 direct_type_mask_must_fill_all_bits_before_the_value_starts); 3158 3159 if (ecma_are_values_integer_numbers (left_value, right_value)) 3160 { 3161 *stack_top_p++ = (left_value ^ right_value) & (ecma_value_t) (~ECMA_DIRECT_TYPE_MASK); 3162 continue; 3163 } 3164 3165 result = do_number_bitwise_logic (NUMBER_BITWISE_LOGIC_XOR, 3166 left_value, 3167 right_value); 3168 3169 if (ECMA_IS_VALUE_ERROR (result)) 3170 { 3171 goto error; 3172 } 3173 3174 *stack_top_p++ = result; 3175 goto free_both_values; 3176 } 3177 case VM_OC_BIT_AND: 3178 { 3179 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 3180 direct_type_mask_must_fill_all_bits_before_the_value_starts); 3181 3182 if (ecma_are_values_integer_numbers (left_value, right_value)) 3183 { 3184 *stack_top_p++ = left_value & right_value; 3185 continue; 3186 } 3187 3188 result = do_number_bitwise_logic (NUMBER_BITWISE_LOGIC_AND, 3189 left_value, 3190 right_value); 3191 3192 if (ECMA_IS_VALUE_ERROR (result)) 3193 { 3194 goto error; 3195 } 3196 3197 *stack_top_p++ = result; 3198 goto free_both_values; 3199 } 3200 case VM_OC_LEFT_SHIFT: 3201 { 3202 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 3203 direct_type_mask_must_fill_all_bits_before_the_value_starts); 3204 3205 if (ecma_are_values_integer_numbers (left_value, right_value)) 3206 { 3207 ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); 3208 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 3209 *stack_top_p++ = ecma_make_int32_value ((int32_t) (left_integer << (right_integer & 0x1f))); 3210 continue; 3211 } 3212 3213 result = do_number_bitwise_logic (NUMBER_BITWISE_SHIFT_LEFT, 3214 left_value, 3215 right_value); 3216 3217 if (ECMA_IS_VALUE_ERROR (result)) 3218 { 3219 goto error; 3220 } 3221 3222 *stack_top_p++ = result; 3223 goto free_both_values; 3224 } 3225 case VM_OC_RIGHT_SHIFT: 3226 { 3227 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 3228 direct_type_mask_must_fill_all_bits_before_the_value_starts); 3229 3230 if (ecma_are_values_integer_numbers (left_value, right_value)) 3231 { 3232 ecma_integer_value_t left_integer = ecma_get_integer_from_value (left_value); 3233 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 3234 *stack_top_p++ = ecma_make_integer_value (left_integer >> (right_integer & 0x1f)); 3235 continue; 3236 } 3237 3238 result = do_number_bitwise_logic (NUMBER_BITWISE_SHIFT_RIGHT, 3239 left_value, 3240 right_value); 3241 3242 if (ECMA_IS_VALUE_ERROR (result)) 3243 { 3244 goto error; 3245 } 3246 3247 *stack_top_p++ = result; 3248 goto free_both_values; 3249 } 3250 case VM_OC_UNS_RIGHT_SHIFT: 3251 { 3252 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1), 3253 direct_type_mask_must_fill_all_bits_before_the_value_starts); 3254 3255 if (ecma_are_values_integer_numbers (left_value, right_value)) 3256 { 3257 uint32_t left_uint32 = (uint32_t) ecma_get_integer_from_value (left_value); 3258 ecma_integer_value_t right_integer = ecma_get_integer_from_value (right_value); 3259 *stack_top_p++ = ecma_make_uint32_value (left_uint32 >> (right_integer & 0x1f)); 3260 continue; 3261 } 3262 3263 result = do_number_bitwise_logic (NUMBER_BITWISE_SHIFT_URIGHT, 3264 left_value, 3265 right_value); 3266 3267 if (ECMA_IS_VALUE_ERROR (result)) 3268 { 3269 goto error; 3270 } 3271 3272 *stack_top_p++ = result; 3273 goto free_both_values; 3274 } 3275 case VM_OC_LESS: 3276 { 3277 if (ecma_are_values_integer_numbers (left_value, right_value)) 3278 { 3279 bool is_less = (ecma_integer_value_t) left_value < (ecma_integer_value_t) right_value; 3280#if !ENABLED (JERRY_VM_EXEC_STOP) 3281 /* This is a lookahead to the next opcode to improve performance. 3282 * If it is CBC_BRANCH_IF_TRUE_BACKWARD, execute it. */ 3283 if (*byte_code_p <= CBC_BRANCH_IF_TRUE_BACKWARD_3 && *byte_code_p >= CBC_BRANCH_IF_TRUE_BACKWARD) 3284 { 3285 byte_code_start_p = byte_code_p++; 3286 branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (*byte_code_start_p); 3287 JERRY_ASSERT (branch_offset_length >= 1 && branch_offset_length <= 3); 3288 3289 if (is_less) 3290 { 3291 branch_offset = *(byte_code_p++); 3292 3293 if (JERRY_UNLIKELY (branch_offset_length != 1)) 3294 { 3295 branch_offset <<= 8; 3296 branch_offset |= *(byte_code_p++); 3297 if (JERRY_UNLIKELY (branch_offset_length == 3)) 3298 { 3299 branch_offset <<= 8; 3300 branch_offset |= *(byte_code_p++); 3301 } 3302 } 3303 3304 /* Note: The opcode is a backward branch. */ 3305 byte_code_p = byte_code_start_p - branch_offset; 3306 } 3307 else 3308 { 3309 byte_code_p += branch_offset_length; 3310 } 3311 3312 continue; 3313 } 3314#endif /* !ENABLED (JERRY_VM_EXEC_STOP) */ 3315 *stack_top_p++ = ecma_make_boolean_value (is_less); 3316 continue; 3317 } 3318 3319 if (ecma_is_value_number (left_value) && ecma_is_value_number (right_value)) 3320 { 3321 ecma_number_t left_number = ecma_get_number_from_value (left_value); 3322 ecma_number_t right_number = ecma_get_number_from_value (right_value); 3323 3324 *stack_top_p++ = ecma_make_boolean_value (left_number < right_number); 3325 goto free_both_values; 3326 } 3327 3328 result = opfunc_relation (left_value, right_value, true, false); 3329 3330 if (ECMA_IS_VALUE_ERROR (result)) 3331 { 3332 goto error; 3333 } 3334 3335 *stack_top_p++ = result; 3336 goto free_both_values; 3337 } 3338 case VM_OC_GREATER: 3339 { 3340 if (ecma_are_values_integer_numbers (left_value, right_value)) 3341 { 3342 ecma_integer_value_t left_integer = (ecma_integer_value_t) left_value; 3343 ecma_integer_value_t right_integer = (ecma_integer_value_t) right_value; 3344 3345 *stack_top_p++ = ecma_make_boolean_value (left_integer > right_integer); 3346 continue; 3347 } 3348 3349 if (ecma_is_value_number (left_value) && ecma_is_value_number (right_value)) 3350 { 3351 ecma_number_t left_number = ecma_get_number_from_value (left_value); 3352 ecma_number_t right_number = ecma_get_number_from_value (right_value); 3353 3354 *stack_top_p++ = ecma_make_boolean_value (left_number > right_number); 3355 goto free_both_values; 3356 } 3357 3358 result = opfunc_relation (left_value, right_value, false, false); 3359 3360 if (ECMA_IS_VALUE_ERROR (result)) 3361 { 3362 goto error; 3363 } 3364 3365 *stack_top_p++ = result; 3366 goto free_both_values; 3367 } 3368 case VM_OC_LESS_EQUAL: 3369 { 3370 if (ecma_are_values_integer_numbers (left_value, right_value)) 3371 { 3372 ecma_integer_value_t left_integer = (ecma_integer_value_t) left_value; 3373 ecma_integer_value_t right_integer = (ecma_integer_value_t) right_value; 3374 3375 *stack_top_p++ = ecma_make_boolean_value (left_integer <= right_integer); 3376 continue; 3377 } 3378 3379 if (ecma_is_value_number (left_value) && ecma_is_value_number (right_value)) 3380 { 3381 ecma_number_t left_number = ecma_get_number_from_value (left_value); 3382 ecma_number_t right_number = ecma_get_number_from_value (right_value); 3383 3384 *stack_top_p++ = ecma_make_boolean_value (left_number <= right_number); 3385 goto free_both_values; 3386 } 3387 3388 result = opfunc_relation (left_value, right_value, false, true); 3389 3390 if (ECMA_IS_VALUE_ERROR (result)) 3391 { 3392 goto error; 3393 } 3394 3395 *stack_top_p++ = result; 3396 goto free_both_values; 3397 } 3398 case VM_OC_GREATER_EQUAL: 3399 { 3400 if (ecma_are_values_integer_numbers (left_value, right_value)) 3401 { 3402 ecma_integer_value_t left_integer = (ecma_integer_value_t) left_value; 3403 ecma_integer_value_t right_integer = (ecma_integer_value_t) right_value; 3404 3405 *stack_top_p++ = ecma_make_boolean_value (left_integer >= right_integer); 3406 continue; 3407 } 3408 3409 if (ecma_is_value_number (left_value) && ecma_is_value_number (right_value)) 3410 { 3411 ecma_number_t left_number = ecma_get_number_from_value (left_value); 3412 ecma_number_t right_number = ecma_get_number_from_value (right_value); 3413 3414 *stack_top_p++ = ecma_make_boolean_value (left_number >= right_number); 3415 goto free_both_values; 3416 } 3417 3418 result = opfunc_relation (left_value, right_value, true, true); 3419 3420 if (ECMA_IS_VALUE_ERROR (result)) 3421 { 3422 goto error; 3423 } 3424 3425 *stack_top_p++ = result; 3426 goto free_both_values; 3427 } 3428 case VM_OC_IN: 3429 { 3430 result = opfunc_in (left_value, right_value); 3431 3432 if (ECMA_IS_VALUE_ERROR (result)) 3433 { 3434 goto error; 3435 } 3436 3437 *stack_top_p++ = result; 3438 goto free_both_values; 3439 } 3440 case VM_OC_INSTANCEOF: 3441 { 3442 result = opfunc_instanceof (left_value, right_value); 3443 3444 if (ECMA_IS_VALUE_ERROR (result)) 3445 { 3446 goto error; 3447 } 3448 3449 *stack_top_p++ = result; 3450 goto free_both_values; 3451 } 3452 case VM_OC_BLOCK_CREATE_CONTEXT: 3453 { 3454#if ENABLED (JERRY_ES2015) 3455 ecma_value_t *stack_context_top_p; 3456 stack_context_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth; 3457 3458 JERRY_ASSERT (stack_context_top_p == stack_top_p || stack_context_top_p == stack_top_p - 1); 3459 3460 if (byte_code_start_p[0] != CBC_EXT_OPCODE) 3461 { 3462 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3463 3464 if (stack_context_top_p != stack_top_p) 3465 { 3466 /* Preserve the value of switch statement. */ 3467 stack_context_top_p[1] = stack_context_top_p[0]; 3468 } 3469 3470 stack_context_top_p[0] = VM_CREATE_CONTEXT_WITH_ENV (VM_CONTEXT_BLOCK, branch_offset); 3471 3472 VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_BLOCK_CONTEXT_STACK_ALLOCATION); 3473 stack_top_p += PARSER_BLOCK_CONTEXT_STACK_ALLOCATION; 3474 } 3475 else 3476 { 3477 JERRY_ASSERT (byte_code_start_p[1] == CBC_EXT_TRY_CREATE_ENV); 3478 3479 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_context_top_p[-1]) == VM_CONTEXT_TRY 3480 || VM_GET_CONTEXT_TYPE (stack_context_top_p[-1]) == VM_CONTEXT_CATCH 3481 || VM_GET_CONTEXT_TYPE (stack_context_top_p[-1]) == VM_CONTEXT_FINALLY_JUMP 3482 || VM_GET_CONTEXT_TYPE (stack_context_top_p[-1]) == VM_CONTEXT_FINALLY_THROW 3483 || VM_GET_CONTEXT_TYPE (stack_context_top_p[-1]) == VM_CONTEXT_FINALLY_RETURN); 3484 3485 JERRY_ASSERT (!(stack_context_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV)); 3486 3487 stack_context_top_p[-1] |= VM_CONTEXT_HAS_LEX_ENV; 3488 } 3489#else /* !ENABLED (JERRY_ES2015) */ 3490 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-2]) == VM_CONTEXT_CATCH 3491 && !(stack_top_p[-2] & VM_CONTEXT_HAS_LEX_ENV)); 3492 3493 stack_top_p[-2] |= VM_CONTEXT_HAS_LEX_ENV; 3494#endif /* ENABLED (JERRY_ES2015) */ 3495 3496 frame_ctx_p->lex_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p); 3497 frame_ctx_p->lex_env_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; 3498 3499 continue; 3500 } 3501 case VM_OC_WITH: 3502 { 3503 ecma_value_t value = *(--stack_top_p); 3504 ecma_object_t *object_p; 3505 ecma_object_t *with_env_p; 3506 3507 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3508 3509 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3510 3511 result = ecma_op_to_object (value); 3512 ecma_free_value (value); 3513 3514 if (ECMA_IS_VALUE_ERROR (result)) 3515 { 3516 goto error; 3517 } 3518 3519 object_p = ecma_get_object_from_value (result); 3520 3521 with_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p, 3522 object_p, 3523 ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); 3524 ecma_deref_object (object_p); 3525 3526 VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION); 3527 stack_top_p += PARSER_WITH_CONTEXT_STACK_ALLOCATION; 3528 3529 stack_top_p[-1] = VM_CREATE_CONTEXT_WITH_ENV (VM_CONTEXT_WITH, branch_offset); 3530 3531 with_env_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; 3532 frame_ctx_p->lex_env_p = with_env_p; 3533 continue; 3534 } 3535 case VM_OC_FOR_IN_CREATE_CONTEXT: 3536 { 3537 ecma_value_t value = *(--stack_top_p); 3538 3539 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3540 3541#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 3542 if (ecma_is_value_object (value) 3543 && ECMA_OBJECT_IS_PROXY (ecma_get_object_from_value (value))) 3544 { 3545 /* Note: - For proxy objects we should create a new object which implements the iterable protocol, 3546 and iterates through the enumerated collection below. 3547 - This inkoves that the VM context type should be adjusted and checked in all FOR-IN related 3548 instruction. 3549 - For other objects we should keep the current implementation due to performance reasons.*/ 3550 result = ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy support in for-in.")); 3551 ecma_free_value (value); 3552 goto error; 3553 } 3554#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 3555 3556 ecma_value_t expr_obj_value = ECMA_VALUE_UNDEFINED; 3557 ecma_collection_t *prop_names_p = opfunc_for_in (value, &expr_obj_value); 3558 ecma_free_value (value); 3559 3560 if (prop_names_p == NULL) 3561 { 3562 /* The collection is already released */ 3563 byte_code_p = byte_code_start_p + branch_offset; 3564 continue; 3565 } 3566 3567 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3568 3569 VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION); 3570 stack_top_p += PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; 3571 stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_FOR_IN, branch_offset); 3572 ECMA_SET_INTERNAL_VALUE_ANY_POINTER (stack_top_p[-2], prop_names_p); 3573 stack_top_p[-3] = 0; 3574 stack_top_p[-4] = expr_obj_value; 3575 3576#if ENABLED (JERRY_ES2015) 3577 if (byte_code_p[0] == CBC_EXT_OPCODE && byte_code_p[1] == CBC_EXT_CLONE_CONTEXT) 3578 { 3579 /* No need to duplicate the first context. */ 3580 byte_code_p += 2; 3581 } 3582#endif /* ENABLED (JERRY_ES2015) */ 3583 continue; 3584 } 3585 case VM_OC_FOR_IN_GET_NEXT: 3586 { 3587 ecma_value_t *context_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth; 3588 3589 ecma_collection_t *collection_p; 3590 collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_top_p[-2]); 3591 3592 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (context_top_p[-1]) == VM_CONTEXT_FOR_IN); 3593 3594 uint32_t index = context_top_p[-3]; 3595 ecma_value_t *buffer_p = collection_p->buffer_p; 3596 3597 *stack_top_p++ = buffer_p[index]; 3598 context_top_p[-3]++; 3599 continue; 3600 } 3601 case VM_OC_FOR_IN_HAS_NEXT: 3602 { 3603 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3604 3605 ecma_collection_t *collection_p; 3606 collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, stack_top_p[-2]); 3607 3608 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FOR_IN); 3609 3610 ecma_value_t *buffer_p = collection_p->buffer_p; 3611 ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[-4]); 3612 uint32_t index = stack_top_p[-3]; 3613#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 3614 JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); 3615#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 3616 3617 while (index < collection_p->item_count) 3618 { 3619 ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[index]); 3620 3621 result = ecma_op_object_has_property (object_p, prop_name_p); 3622 3623 if (JERRY_LIKELY (ecma_is_value_true (result))) 3624 { 3625 byte_code_p = byte_code_start_p + branch_offset; 3626 break; 3627 } 3628 3629 ecma_deref_ecma_string (prop_name_p); 3630 index++; 3631 } 3632 3633 if (index == collection_p->item_count) 3634 { 3635 ecma_deref_object (object_p); 3636 ecma_collection_destroy (collection_p); 3637 VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION); 3638 stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; 3639 } 3640 else 3641 { 3642 stack_top_p[-3] = index; 3643 } 3644 continue; 3645 } 3646#if ENABLED (JERRY_ES2015) 3647 case VM_OC_FOR_OF_CREATE_CONTEXT: 3648 { 3649 ecma_value_t value = *(--stack_top_p); 3650 3651 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3652 3653 ecma_value_t iterator = ecma_op_get_iterator (value, ECMA_VALUE_EMPTY); 3654 3655 ecma_free_value (value); 3656 3657 if (ECMA_IS_VALUE_ERROR (iterator)) 3658 { 3659 result = iterator; 3660 goto error; 3661 } 3662 3663 ecma_value_t next_value = ecma_op_iterator_step (iterator); 3664 3665 if (ECMA_IS_VALUE_ERROR (next_value)) 3666 { 3667 ecma_free_value (iterator); 3668 result = next_value; 3669 goto error; 3670 } 3671 3672 if (ecma_is_value_false (next_value)) 3673 { 3674 ecma_free_value (iterator); 3675 byte_code_p = byte_code_start_p + branch_offset; 3676 continue; 3677 } 3678 3679 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3680 3681 VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION); 3682 stack_top_p += PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION; 3683 stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_FOR_OF, branch_offset) | VM_CONTEXT_CLOSE_ITERATOR; 3684 stack_top_p[-2] = next_value; 3685 stack_top_p[-3] = iterator; 3686 3687 if (byte_code_p[0] == CBC_EXT_OPCODE && byte_code_p[1] == CBC_EXT_CLONE_CONTEXT) 3688 { 3689 /* No need to duplicate the first context. */ 3690 byte_code_p += 2; 3691 } 3692 continue; 3693 } 3694 case VM_OC_FOR_OF_GET_NEXT: 3695 { 3696 ecma_value_t *context_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth; 3697 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (context_top_p[-1]) == VM_CONTEXT_FOR_OF); 3698 3699 ecma_value_t next_value = ecma_op_iterator_value (context_top_p[-2]); 3700 3701 if (ECMA_IS_VALUE_ERROR (next_value)) 3702 { 3703 result = next_value; 3704 goto error; 3705 } 3706 3707 *stack_top_p++ = next_value; 3708 continue; 3709 } 3710 case VM_OC_FOR_OF_HAS_NEXT: 3711 { 3712 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3713 3714 ecma_value_t next_value = ecma_op_iterator_step (stack_top_p[-3]); 3715 3716 if (ECMA_IS_VALUE_ERROR (next_value)) 3717 { 3718 result = next_value; 3719 goto error; 3720 } 3721 3722 if (!ecma_is_value_false (next_value)) 3723 { 3724 ecma_free_value (stack_top_p[-2]); 3725 stack_top_p[-2] = next_value; 3726 byte_code_p = byte_code_start_p + branch_offset; 3727 continue; 3728 } 3729 3730 ecma_free_value (stack_top_p[-2]); 3731 ecma_free_value (stack_top_p[-3]); 3732 VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION); 3733 stack_top_p -= PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION; 3734 continue; 3735 } 3736#endif /* ENABLED (JERRY_ES2015) */ 3737 case VM_OC_TRY: 3738 { 3739 /* Try opcode simply creates the try context. */ 3740 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3741 3742 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3743 3744 VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION); 3745 stack_top_p += PARSER_TRY_CONTEXT_STACK_ALLOCATION; 3746 3747 stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_TRY, branch_offset); 3748 continue; 3749 } 3750 case VM_OC_CATCH: 3751 { 3752 /* Catches are ignored and turned to jumps. */ 3753 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3754 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_TRY); 3755 3756 byte_code_p = byte_code_start_p + branch_offset; 3757 continue; 3758 } 3759 case VM_OC_FINALLY: 3760 { 3761 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3762 3763 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3764 3765 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_TRY 3766 || VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH); 3767 3768 if (stack_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV) 3769 { 3770 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 3771 JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 3772 frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 3773 ecma_deref_object (lex_env_p); 3774 3775 stack_top_p[-1] &= (ecma_value_t) ~VM_CONTEXT_HAS_LEX_ENV; 3776 } 3777 3778 stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_FINALLY_JUMP, branch_offset); 3779 stack_top_p[-2] = (ecma_value_t) branch_offset; 3780 continue; 3781 } 3782 case VM_OC_CONTEXT_END: 3783 { 3784 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3785 JERRY_ASSERT (!(stack_top_p[-1] & VM_CONTEXT_CLOSE_ITERATOR)); 3786 3787 ecma_value_t context_type = VM_GET_CONTEXT_TYPE (stack_top_p[-1]); 3788 3789 if (!VM_CONTEXT_IS_FINALLY (context_type)) 3790 { 3791 stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p); 3792 3793 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3794 continue; 3795 } 3796 3797#if ENABLED (JERRY_ES2015) 3798 if (stack_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV) 3799 { 3800 ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 3801 JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 3802 frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 3803 ecma_deref_object (lex_env_p); 3804 } 3805#endif /* ENABLED (JERRY_ES2015) */ 3806 3807 VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, 3808 PARSER_TRY_CONTEXT_STACK_ALLOCATION); 3809 stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION; 3810 3811 if (context_type == VM_CONTEXT_FINALLY_RETURN) 3812 { 3813 result = *stack_top_p; 3814 goto error; 3815 } 3816 3817 if (context_type == VM_CONTEXT_FINALLY_THROW) 3818 { 3819 jcontext_raise_exception (*stack_top_p); 3820 result = ECMA_VALUE_ERROR; 3821 3822#if ENABLED (JERRY_DEBUGGER) 3823 JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN); 3824#endif /* ENABLED (JERRY_DEBUGGER) */ 3825 goto error; 3826 } 3827 3828 JERRY_ASSERT (context_type == VM_CONTEXT_FINALLY_JUMP); 3829 3830 uint32_t jump_target = *stack_top_p; 3831 3832 if (vm_stack_find_finally (frame_ctx_p, 3833 &stack_top_p, 3834 VM_CONTEXT_FINALLY_JUMP, 3835 jump_target)) 3836 { 3837 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_JUMP); 3838 byte_code_p = frame_ctx_p->byte_code_p; 3839 stack_top_p[-2] = jump_target; 3840 } 3841 else 3842 { 3843 byte_code_p = frame_ctx_p->byte_code_start_p + jump_target; 3844 } 3845 3846 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3847 continue; 3848 } 3849 case VM_OC_JUMP_AND_EXIT_CONTEXT: 3850 { 3851 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3852 JERRY_ASSERT (!jcontext_has_pending_exception ()); 3853 3854 branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p); 3855 3856 if (vm_stack_find_finally (frame_ctx_p, 3857 &stack_top_p, 3858 VM_CONTEXT_FINALLY_JUMP, 3859 (uint32_t) branch_offset)) 3860 { 3861 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_JUMP); 3862 byte_code_p = frame_ctx_p->byte_code_p; 3863 stack_top_p[-2] = (uint32_t) branch_offset; 3864 } 3865 else 3866 { 3867 byte_code_p = frame_ctx_p->byte_code_start_p + branch_offset; 3868 } 3869 3870#if ENABLED (JERRY_ES2015) 3871 if (jcontext_has_pending_exception ()) 3872 { 3873 result = ECMA_VALUE_ERROR; 3874 goto error; 3875 } 3876#endif /* ENABLED (JERRY_ES2015) */ 3877 3878 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 3879 continue; 3880 } 3881#if ENABLED (JERRY_DEBUGGER) 3882 case VM_OC_BREAKPOINT_ENABLED: 3883 { 3884 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE) 3885 { 3886 continue; 3887 } 3888 3889 JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 3890 3891 JERRY_ASSERT (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)); 3892 3893 frame_ctx_p->byte_code_p = byte_code_start_p; 3894 3895 jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT); 3896 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_EXCEPTION_THROWN) 3897 { 3898 result = ECMA_VALUE_ERROR; 3899 goto error; 3900 } 3901 continue; 3902 } 3903 case VM_OC_BREAKPOINT_DISABLED: 3904 { 3905 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE) 3906 { 3907 continue; 3908 } 3909 3910 JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 3911 3912 JERRY_ASSERT (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)); 3913 3914 frame_ctx_p->byte_code_p = byte_code_start_p; 3915 3916 if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_STOP) 3917 && (JERRY_CONTEXT (debugger_stop_context) == NULL 3918 || JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p))) 3919 { 3920 jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT); 3921 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_EXCEPTION_THROWN) 3922 { 3923 result = ECMA_VALUE_ERROR; 3924 goto error; 3925 } 3926 continue; 3927 } 3928 3929 if (JERRY_CONTEXT (debugger_message_delay) > 0) 3930 { 3931 JERRY_CONTEXT (debugger_message_delay)--; 3932 continue; 3933 } 3934 3935 JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY; 3936 3937 if (jerry_debugger_receive (NULL)) 3938 { 3939 continue; 3940 } 3941 3942 if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_STOP) 3943 && (JERRY_CONTEXT (debugger_stop_context) == NULL 3944 || JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p))) 3945 { 3946 jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT); 3947 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_EXCEPTION_THROWN) 3948 { 3949 result = ECMA_VALUE_ERROR; 3950 goto error; 3951 } 3952 } 3953 continue; 3954 } 3955#endif /* ENABLED (JERRY_DEBUGGER) */ 3956#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) 3957 case VM_OC_RESOURCE_NAME: 3958 { 3959 frame_ctx_p->resource_name = ecma_op_resource_name (bytecode_header_p); 3960 continue; 3961 } 3962#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 3963#if ENABLED (JERRY_LINE_INFO) 3964 case VM_OC_LINE: 3965 { 3966 uint32_t value = 0; 3967 uint8_t byte; 3968 3969 do 3970 { 3971 byte = *byte_code_p++; 3972 value = (value << 7) | (byte & CBC_LOWER_SEVEN_BIT_MASK); 3973 } 3974 while (byte & CBC_HIGHEST_BIT_MASK); 3975 3976 frame_ctx_p->current_line = value; 3977 continue; 3978 } 3979#endif /* ENABLED (JERRY_LINE_INFO) */ 3980 case VM_OC_NONE: 3981 default: 3982 { 3983 JERRY_ASSERT (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_NONE); 3984 3985 jerry_fatal (ERR_DISABLED_BYTE_CODE); 3986 } 3987 } 3988 3989 JERRY_ASSERT (VM_OC_HAS_PUT_RESULT (opcode_data)); 3990 3991 if (opcode_data & VM_OC_PUT_IDENT) 3992 { 3993 uint16_t literal_index; 3994 3995 READ_LITERAL_INDEX (literal_index); 3996 3997 if (literal_index < register_end) 3998 { 3999 ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index)); 4000 VM_GET_REGISTER (frame_ctx_p, literal_index) = result; 4001 4002 if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)) 4003 { 4004 result = ecma_fast_copy_value (result); 4005 } 4006 } 4007 else 4008 { 4009 ecma_string_t *var_name_str_p = ecma_get_string_from_value (literal_start_p[literal_index]); 4010 4011 ecma_value_t put_value_result = ecma_op_put_value_lex_env_base (frame_ctx_p->lex_env_p, 4012 var_name_str_p, 4013 is_strict, 4014 result); 4015 4016 if (ECMA_IS_VALUE_ERROR (put_value_result)) 4017 { 4018 ecma_free_value (result); 4019 result = put_value_result; 4020 goto error; 4021 } 4022 4023#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 4024 if (ecma_is_value_object(result) && ecma_op_is_callable(result)) { 4025 // It was a function assignment. Is the function was anonymous - assign a name to it. 4026 ecma_object_t* obj = ecma_get_object_from_value(result); 4027 ecma_object_type_t obj_type = ecma_get_object_type(obj); 4028 if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) { 4029 ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 4030 if (ecma_find_named_property (obj, property_name) == NULL) { 4031 ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, property_name, 4032 ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, NULL); 4033 prop_val->value = ecma_copy_value(literal_start_p[literal_index]); 4034 } else { 4035 ecma_deref_ecma_string (property_name); 4036 } 4037 } 4038 } 4039#endif 4040 4041 if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) 4042 { 4043 ecma_fast_free_value (result); 4044 } 4045 } 4046 } 4047 else if (opcode_data & VM_OC_PUT_REFERENCE) 4048 { 4049 ecma_value_t property = *(--stack_top_p); 4050 ecma_value_t base = *(--stack_top_p); 4051 4052 if (base == ECMA_VALUE_REGISTER_REF) 4053 { 4054 property = (ecma_value_t) ecma_get_integer_from_value (property); 4055 ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, property)); 4056 VM_GET_REGISTER (frame_ctx_p, property) = result; 4057 4058 if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) 4059 { 4060 goto free_both_values; 4061 } 4062 result = ecma_fast_copy_value (result); 4063 } 4064 else 4065 { 4066 ecma_value_t set_value_result = vm_op_set_value (base, 4067 property, 4068 result, 4069 is_strict); 4070 4071 if (ECMA_IS_VALUE_ERROR (set_value_result)) 4072 { 4073 ecma_free_value (result); 4074 result = set_value_result; 4075 goto error; 4076 } 4077 4078 if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) 4079 { 4080 ecma_fast_free_value (result); 4081 goto free_both_values; 4082 } 4083 } 4084 } 4085 4086 if (opcode_data & VM_OC_PUT_STACK) 4087 { 4088 *stack_top_p++ = result; 4089 } 4090 else if (opcode_data & VM_OC_PUT_BLOCK) 4091 { 4092 ecma_fast_free_value (frame_ctx_p->block_result); 4093 frame_ctx_p->block_result = result; 4094 } 4095 4096free_both_values: 4097 ecma_fast_free_value (right_value); 4098free_left_value: 4099 ecma_fast_free_value (left_value); 4100 } 4101 4102error: 4103 ecma_fast_free_value (left_value); 4104 ecma_fast_free_value (right_value); 4105 4106 if (ECMA_IS_VALUE_ERROR (result)) 4107 { 4108 JERRY_ASSERT (jcontext_has_pending_exception ()); 4109 ecma_value_t *stack_bottom_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth; 4110 4111 while (stack_top_p > stack_bottom_p) 4112 { 4113 ecma_value_t stack_item = *(--stack_top_p); 4114#if ENABLED (JERRY_ES2015) 4115 if (stack_item == ECMA_VALUE_RELEASE_LEX_ENV) 4116 { 4117 opfunc_pop_lexical_environment (frame_ctx_p); 4118 continue; 4119 } 4120#endif /* ENABLED (JERRY_ES2015) */ 4121 ecma_fast_free_value (stack_item); 4122 } 4123 4124#if ENABLED (JERRY_DEBUGGER) 4125 const uint32_t dont_stop = (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION 4126 | JERRY_DEBUGGER_VM_IGNORE 4127 | JERRY_DEBUGGER_VM_EXCEPTION_THROWN); 4128 4129 if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 4130 && !(frame_ctx_p->bytecode_header_p->status_flags 4131 & (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION)) 4132 && !(JERRY_CONTEXT (debugger_flags) & dont_stop)) 4133 { 4134 /* Save the error to a local value, because the engine enters breakpoint mode after, 4135 therefore an evaluation error, or user-created error throw would overwrite it. */ 4136 ecma_value_t current_error_value = JERRY_CONTEXT (error_value); 4137 4138 if (jerry_debugger_send_exception_string (current_error_value)) 4139 { 4140 jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_EXCEPTION_HIT); 4141 4142 if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_EXCEPTION_THROWN) 4143 { 4144 ecma_free_value (current_error_value); 4145 } 4146 else 4147 { 4148 JERRY_CONTEXT (error_value) = current_error_value; 4149 } 4150 4151 JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN); 4152 } 4153 } 4154#endif /* ENABLED (JERRY_DEBUGGER) */ 4155 } 4156 4157 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 4158 4159 if (frame_ctx_p->context_depth == 0) 4160 { 4161 /* In most cases there is no context. */ 4162 4163 ecma_fast_free_value (frame_ctx_p->block_result); 4164 frame_ctx_p->call_operation = VM_NO_EXEC_OP; 4165 return result; 4166 } 4167 4168 if (!ECMA_IS_VALUE_ERROR (result)) 4169 { 4170 if (vm_stack_find_finally (frame_ctx_p, 4171 &stack_top_p, 4172 VM_CONTEXT_FINALLY_RETURN, 4173 0)) 4174 { 4175 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_RETURN); 4176 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 4177 4178#if ENABLED (JERRY_ES2015) 4179 if (jcontext_has_pending_exception ()) 4180 { 4181 stack_top_p[-1] = (ecma_value_t) (stack_top_p[-1] - VM_CONTEXT_FINALLY_RETURN + VM_CONTEXT_FINALLY_THROW); 4182 ecma_free_value (result); 4183 result = jcontext_take_exception (); 4184 } 4185#endif /* ENABLED (JERRY_ES2015) */ 4186 4187 byte_code_p = frame_ctx_p->byte_code_p; 4188 stack_top_p[-2] = result; 4189 continue; 4190 } 4191 4192#if ENABLED (JERRY_ES2015) 4193 if (jcontext_has_pending_exception ()) 4194 { 4195 ecma_free_value (result); 4196 result = ECMA_VALUE_ERROR; 4197 } 4198#endif /* ENABLED (JERRY_ES2015) */ 4199 } 4200 else if (jcontext_has_pending_exception () && !jcontext_has_pending_abort ()) 4201 { 4202 if (vm_stack_find_finally (frame_ctx_p, 4203 &stack_top_p, 4204 VM_CONTEXT_FINALLY_THROW, 4205 0)) 4206 { 4207 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 4208 JERRY_ASSERT (!(stack_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV)); 4209 4210#if ENABLED (JERRY_DEBUGGER) 4211 JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN); 4212#endif /* ENABLED (JERRY_DEBUGGER) */ 4213 4214 result = jcontext_take_exception (); 4215 4216 byte_code_p = frame_ctx_p->byte_code_p; 4217 4218 if (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_THROW) 4219 { 4220 stack_top_p[-2] = result; 4221 continue; 4222 } 4223 4224 JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH); 4225 4226 *stack_top_p++ = result; 4227 continue; 4228 } 4229 } 4230 else 4231 { 4232 do 4233 { 4234 JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p); 4235 4236 stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p); 4237 } 4238 while (frame_ctx_p->context_depth > 0); 4239 } 4240 4241 ecma_free_value (frame_ctx_p->block_result); 4242 frame_ctx_p->call_operation = VM_NO_EXEC_OP; 4243 4244 return result; 4245 } 4246} /* vm_loop */ 4247 4248#undef READ_LITERAL 4249#undef READ_LITERAL_INDEX 4250 4251/** 4252 * Initialize code block execution 4253 * 4254 * @return ECMA_VALUE_ERROR - if the initialization fails 4255 * ECMA_VALUE_EMPTY - otherwise 4256 */ 4257static void JERRY_ATTR_NOINLINE 4258vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ 4259 const ecma_value_t *arg_p, /**< arguments list */ 4260 ecma_length_t arg_list_len) /**< length of arguments list */ 4261{ 4262 frame_ctx_p->prev_context_p = JERRY_CONTEXT (vm_top_context_p); 4263 frame_ctx_p->block_result = ECMA_VALUE_UNDEFINED; 4264#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) 4265 frame_ctx_p->resource_name = ECMA_VALUE_UNDEFINED; 4266#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 4267#if ENABLED (JERRY_LINE_INFO) 4268 frame_ctx_p->current_line = 0; 4269#endif /* ENABLED (JERRY_LINE_INFO) */ 4270 frame_ctx_p->context_depth = 0; 4271 frame_ctx_p->is_eval_code = (arg_p == VM_DIRECT_EVAL); 4272 4273 const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p; 4274 uint16_t argument_end, register_end; 4275 ecma_value_t *literal_p; 4276 4277 if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 4278 { 4279 cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p; 4280 4281 argument_end = args_p->argument_end; 4282 register_end = args_p->register_end; 4283 4284 literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint16_arguments_t)); 4285 literal_p -= register_end; 4286 frame_ctx_p->literal_start_p = literal_p; 4287 literal_p += args_p->literal_end; 4288 } 4289 else 4290 { 4291 cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p; 4292 4293 argument_end = args_p->argument_end; 4294 register_end = args_p->register_end; 4295 4296 literal_p = (ecma_value_t *) ((uint8_t *) bytecode_header_p + sizeof (cbc_uint8_arguments_t)); 4297 literal_p -= register_end; 4298 frame_ctx_p->literal_start_p = literal_p; 4299 literal_p += args_p->literal_end; 4300 } 4301 4302 frame_ctx_p->byte_code_p = (uint8_t *) literal_p; 4303 frame_ctx_p->byte_code_start_p = (uint8_t *) literal_p; 4304 frame_ctx_p->stack_top_p = VM_GET_REGISTERS (frame_ctx_p) + register_end; 4305 4306#if defined(JERRY_FUNCTION_BACKTRACE) && !defined(__APPLE__) 4307 if (JERRY_LIKELY(frame_ctx_p->prev_context_p != NULL)) { 4308 frame_ctx_p->callee_value = frame_ctx_p->prev_context_p->callee_value; 4309 } else { 4310 frame_ctx_p->callee_value = ECMA_VALUE_UNDEFINED; 4311 } 4312#endif 4313 4314#if ENABLED (JERRY_ES2015) 4315 uint32_t function_call_argument_count = arg_list_len; 4316#endif /* ENABLED (JERRY_ES2015) */ 4317 4318 if (arg_list_len > argument_end) 4319 { 4320 arg_list_len = argument_end; 4321 } 4322 4323 for (uint32_t i = 0; i < arg_list_len; i++) 4324 { 4325 VM_GET_REGISTER (frame_ctx_p, i) = ecma_fast_copy_value (arg_p[i]); 4326 } 4327 4328 /* The arg_list_len contains the end of the copied arguments. 4329 * Fill everything else with undefined. */ 4330 if (register_end > arg_list_len) 4331 { 4332 ecma_value_t *stack_p = VM_GET_REGISTERS (frame_ctx_p) + arg_list_len; 4333 4334 for (uint32_t i = arg_list_len; i < register_end; i++) 4335 { 4336 *stack_p++ = ECMA_VALUE_UNDEFINED; 4337 } 4338 } 4339 4340#if ENABLED (JERRY_ES2015) 4341 if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_REST_PARAMETER) 4342 { 4343 JERRY_ASSERT (function_call_argument_count >= arg_list_len); 4344 ecma_value_t new_array = ecma_op_create_array_object (arg_p + arg_list_len, 4345 function_call_argument_count - arg_list_len, 4346 false); 4347 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array)); 4348 VM_GET_REGISTER (frame_ctx_p, argument_end) = new_array; 4349 } 4350#endif /* ENABLED (JERRY_ES2015) */ 4351 4352 JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL; 4353 JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p; 4354} /* vm_init_exec */ 4355 4356/** 4357 * Resume execution of a code block. 4358 * 4359 * @return ecma value 4360 */ 4361ecma_value_t JERRY_ATTR_NOINLINE 4362vm_execute (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 4363{ 4364 while (true) 4365 { 4366 ecma_value_t completion_value = vm_loop (frame_ctx_p); 4367 4368 switch (frame_ctx_p->call_operation) 4369 { 4370 case VM_EXEC_CALL: 4371 { 4372 opfunc_call (frame_ctx_p); 4373 break; 4374 } 4375#if ENABLED (JERRY_ES2015) 4376 case VM_EXEC_SUPER_CALL: 4377 { 4378 vm_super_call (frame_ctx_p); 4379 break; 4380 } 4381 case VM_EXEC_SPREAD_OP: 4382 { 4383 vm_spread_operation (frame_ctx_p); 4384 break; 4385 } 4386 case VM_EXEC_RETURN: 4387 { 4388 return completion_value; 4389 } 4390#endif /* ENABLED (JERRY_ES2015) */ 4391 case VM_EXEC_CONSTRUCT: 4392 { 4393 opfunc_construct (frame_ctx_p); 4394 break; 4395 } 4396 default: 4397 { 4398 JERRY_ASSERT (frame_ctx_p->call_operation == VM_NO_EXEC_OP); 4399 4400 const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p; 4401 uint32_t register_end; 4402 4403 if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 4404 { 4405 register_end = ((cbc_uint16_arguments_t *) bytecode_header_p)->register_end; 4406 } 4407 else 4408 { 4409 register_end = ((cbc_uint8_arguments_t *) bytecode_header_p)->register_end; 4410 } 4411 4412 /* Free arguments and registers */ 4413 ecma_value_t *registers_p = VM_GET_REGISTERS (frame_ctx_p); 4414 for (uint32_t i = 0; i < register_end; i++) 4415 { 4416 ecma_fast_free_value (registers_p[i]); 4417 } 4418 4419#if ENABLED (JERRY_DEBUGGER) 4420 if (JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p)) 4421 { 4422 /* The engine will stop when the next breakpoint is reached. */ 4423 JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_STOP); 4424 JERRY_CONTEXT (debugger_stop_context) = NULL; 4425 } 4426#endif /* ENABLED (JERRY_DEBUGGER) */ 4427 4428 JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p->prev_context_p; 4429 return completion_value; 4430 } 4431 } 4432 } 4433} /* vm_execute */ 4434 4435/** 4436 * Run the code. 4437 * 4438 * @return ecma value 4439 */ 4440ecma_value_t 4441vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */ 4442 ecma_value_t this_binding_value, /**< value of 'ThisBinding' */ 4443 ecma_object_t *lex_env_p, /**< lexical environment to use */ 4444 const ecma_value_t *arg_list_p, /**< arguments list */ 4445 ecma_length_t arg_list_len) /**< length of arguments list */ 4446{ 4447 vm_frame_ctx_t *frame_ctx_p; 4448 size_t frame_size; 4449#if defined(JERRY_FOR_IAR_CONFIG) 4450 ecma_value_t* stack; 4451 ecma_value_t ret; 4452#endif 4453 4454 if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 4455 { 4456 cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p; 4457 frame_size = (size_t) (args_p->register_end + args_p->stack_limit); 4458 } 4459 else 4460 { 4461 cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p; 4462 frame_size = (size_t) (args_p->register_end + args_p->stack_limit); 4463 } 4464 4465 frame_size = frame_size * sizeof (ecma_value_t) + sizeof (vm_frame_ctx_t); 4466 frame_size = (frame_size + sizeof (uintptr_t) - 1) / sizeof (uintptr_t); 4467 4468 /* Use JERRY_MAX() to avoid array declaration with size 0. */ 4469#if defined(JERRY_FOR_IAR_CONFIG) 4470 stack = (ecma_value_t*)jerry_vla_malloc (sizeof(ecma_value_t) * frame_size); 4471 if (!stack) 4472 { 4473 return ecma_raise_common_error (ECMA_ERR_MSG ("malloc stack failed")); 4474 } 4475#else 4476 JERRY_VLA (uintptr_t, stack, frame_size); 4477#endif 4478 4479 frame_ctx_p = (vm_frame_ctx_t *) stack; 4480 4481 frame_ctx_p->bytecode_header_p = bytecode_header_p; 4482 frame_ctx_p->lex_env_p = lex_env_p; 4483 frame_ctx_p->this_binding = this_binding_value; 4484 4485 vm_init_exec (frame_ctx_p, arg_list_p, arg_list_len); 4486#if defined(JERRY_FOR_IAR_CONFIG) 4487 ret = vm_execute (frame_ctx_p); 4488 jerry_vla_free ((char*)stack); 4489 return ret; 4490#else 4491 return vm_execute (frame_ctx_p); 4492#endif 4493} /* vm_run */ 4494 4495/** 4496 * @} 4497 * @} 4498 */ 4499