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 */
60 static ecma_value_t
vm_op_get_value(ecma_value_t object,ecma_value_t property)61 vm_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 */
159 static ecma_value_t
vm_op_set_value(ecma_value_t base,ecma_value_t property,ecma_value_t value,bool is_strict)160 vm_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 */
263 static 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 */
280 ecma_value_t
vm_run_module(const ecma_compiled_code_t * bytecode_p,ecma_object_t * lex_env_p)281 vm_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 */
306 ecma_value_t
vm_run_global(const ecma_compiled_code_t * bytecode_p)307 vm_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 */
353 ecma_value_t
vm_run_eval(ecma_compiled_code_t * bytecode_data_p,uint32_t parse_opts)354 vm_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 */
440 static ecma_value_t
vm_construct_literal_object(vm_frame_ctx_t * frame_ctx_p,ecma_value_t lit_value)441 vm_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 */
507 static inline bool JERRY_ATTR_ALWAYS_INLINE
vm_get_implicit_this_value(ecma_value_t * this_value_p)508 vm_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 */
531 static 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 */
540 static void
vm_super_call(vm_frame_ctx_t * frame_ctx_p)541 vm_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 */
657 static void
vm_spread_operation(vm_frame_ctx_t * frame_ctx_p)658 vm_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 */
752 static void
opfunc_call(vm_frame_ctx_t * frame_ctx_p)753 opfunc_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 */
844 static void
opfunc_construct(vm_frame_ctx_t * frame_ctx_p)845 opfunc_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 */
974 static ecma_value_t JERRY_ATTR_NOINLINE
vm_loop(vm_frame_ctx_t * frame_ctx_p)975 vm_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
4096 free_both_values:
4097 ecma_fast_free_value (right_value);
4098 free_left_value:
4099 ecma_fast_free_value (left_value);
4100 }
4101
4102 error:
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 */
4257 static void JERRY_ATTR_NOINLINE
vm_init_exec(vm_frame_ctx_t * frame_ctx_p,const ecma_value_t * arg_p,ecma_length_t arg_list_len)4258 vm_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 */
4361 ecma_value_t JERRY_ATTR_NOINLINE
vm_execute(vm_frame_ctx_t * frame_ctx_p)4362 vm_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 */
4440 ecma_value_t
vm_run(const ecma_compiled_code_t * bytecode_header_p,ecma_value_t this_binding_value,ecma_object_t * lex_env_p,const ecma_value_t * arg_list_p,ecma_length_t arg_list_len)4441 vm_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