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 "ecma-alloc.h"
17#include "ecma-array-object.h"
18#include "ecma-builtins.h"
19#include "ecma-builtin-helpers.h"
20#include "ecma-conversion.h"
21#include "ecma-exceptions.h"
22#include "ecma-function-object.h"
23#include "ecma-gc.h"
24#include "ecma-globals.h"
25#include "ecma-helpers.h"
26#include "ecma-iterator-object.h"
27#include "ecma-lex-env.h"
28#include "ecma-objects.h"
29#include "ecma-promise-object.h"
30#include "ecma-proxy-object.h"
31#include "ecma-try-catch-macro.h"
32#include "jcontext.h"
33#include "opcodes.h"
34#include "vm-defines.h"
35#include "vm-stack.h"
36
37/** \addtogroup vm Virtual machine
38 * @{
39 *
40 * \addtogroup vm_opcodes Opcodes
41 * @{
42 */
43
44/**
45 * 'Variable declaration' opcode handler.
46 *
47 * See also: ECMA-262 v5, 10.5 - Declaration binding instantiation (block 8).
48 *
49 * @return ECMA_VALUE_ERROR - if no the operation fails
50 *         ECMA_VALUE_EMPTY - otherwise
51 */
52inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
53vm_var_decl (ecma_object_t *lex_env_p, /**< target lexical environment */
54             ecma_string_t *var_name_str_p, /**< variable name */
55             bool is_configurable_bindings) /**< true if the binding can be deleted */
56{
57  ecma_value_t has_binding = ecma_op_has_binding (lex_env_p, var_name_str_p);
58
59#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
60  if (ECMA_IS_VALUE_ERROR (has_binding))
61  {
62    return has_binding;
63  }
64#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
65
66  if (ecma_is_value_false (has_binding))
67  {
68    ecma_value_t completion_value = ecma_op_create_mutable_binding (lex_env_p,
69                                                                    var_name_str_p,
70                                                                    is_configurable_bindings);
71
72    JERRY_ASSERT (ecma_is_value_empty (completion_value));
73
74    /* Skipping SetMutableBinding as we have already checked that there were not
75     * any binding with specified name in current lexical environment
76     * and CreateMutableBinding sets the created binding's value to undefined */
77    JERRY_ASSERT (ecma_is_value_undefined (ecma_op_get_binding_value (lex_env_p,
78                                                                      var_name_str_p,
79                                                                      vm_is_strict_mode ())));
80  }
81
82  return ECMA_VALUE_EMPTY;
83} /* vm_var_decl */
84
85/**
86 * Set var binding to a function literal value.
87 *
88 * @return ECMA_VALUE_ERROR - if no the operation fails
89 *         ECMA_VALUE_EMPTY - otherwise
90 */
91inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
92vm_set_var (ecma_object_t *lex_env_p, /**< target lexical environment */
93            ecma_string_t *var_name_str_p, /**< variable name */
94            bool is_strict, /**< true, if the engine is in strict mode */
95            ecma_value_t lit_value) /**< function value */
96{
97  ecma_value_t put_value_result;
98  put_value_result = ecma_op_put_value_lex_env_base (lex_env_p, var_name_str_p, is_strict, lit_value);
99
100  JERRY_ASSERT (ecma_is_value_boolean (put_value_result)
101                || ecma_is_value_empty (put_value_result)
102                || ECMA_IS_VALUE_ERROR (put_value_result));
103
104  ecma_free_value (lit_value);
105
106  return put_value_result;
107} /* vm_set_var */
108
109/**
110 * 'typeof' opcode handler.
111 *
112 * See also: ECMA-262 v5, 11.4.3
113 *
114 * @return ecma value
115 *         Returned value must be freed with ecma_free_value
116 */
117ecma_value_t
118opfunc_typeof (ecma_value_t left_value) /**< left value */
119{
120  return ecma_make_magic_string_value (ecma_get_typeof_lit_id (left_value));
121} /* opfunc_typeof */
122
123/**
124 * Update getter or setter for object literals.
125 */
126void
127opfunc_set_accessor (bool is_getter, /**< is getter accessor */
128                     ecma_value_t object, /**< object value */
129                     ecma_string_t *accessor_name_p, /**< accessor name */
130                     ecma_value_t accessor) /**< accessor value */
131{
132  ecma_object_t *object_p = ecma_get_object_from_value (object);
133
134  JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p));
135
136  ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p);
137
138  if (property_p != NULL
139      && ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
140  {
141    ecma_delete_property (object_p, ECMA_PROPERTY_VALUE_PTR (property_p));
142    property_p = NULL;
143  }
144
145  if (property_p == NULL)
146  {
147    ecma_object_t *getter_func_p = NULL;
148    ecma_object_t *setter_func_p = NULL;
149
150    if (is_getter)
151    {
152      getter_func_p = ecma_get_object_from_value (accessor);
153    }
154    else
155    {
156      setter_func_p = ecma_get_object_from_value (accessor);
157    }
158
159    ecma_create_named_accessor_property (object_p,
160                                         accessor_name_p,
161                                         getter_func_p,
162                                         setter_func_p,
163                                         ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE,
164                                         NULL);
165  }
166  else if (is_getter)
167  {
168    ecma_object_t *getter_func_p = ecma_get_object_from_value (accessor);
169
170    ecma_set_named_accessor_property_getter (object_p,
171                                             ECMA_PROPERTY_VALUE_PTR (property_p),
172                                             getter_func_p);
173  }
174  else
175  {
176    ecma_object_t *setter_func_p = ecma_get_object_from_value (accessor);
177
178    ecma_set_named_accessor_property_setter (object_p,
179                                             ECMA_PROPERTY_VALUE_PTR (property_p),
180                                             setter_func_p);
181  }
182} /* opfunc_set_accessor */
183
184/**
185 * Deletes an object property.
186 *
187 * @return ecma value
188 *         Returned value must be freed with ecma_free_value
189 */
190ecma_value_t
191vm_op_delete_prop (ecma_value_t object, /**< base object */
192                   ecma_value_t property, /**< property name */
193                   bool is_strict) /**< strict mode */
194{
195#if !ENABLED (JERRY_ES2015)
196  if (ecma_is_value_undefined (object))
197  {
198    return ECMA_VALUE_TRUE;
199  }
200#endif /* !ENABLED (JERRY_ES2015) */
201
202  ecma_value_t check_coercible = ecma_op_check_object_coercible (object);
203  if (ECMA_IS_VALUE_ERROR (check_coercible))
204  {
205    return check_coercible;
206  }
207  JERRY_ASSERT (check_coercible == ECMA_VALUE_EMPTY);
208
209  ecma_string_t *name_string_p = ecma_op_to_prop_name (property);
210
211  if (JERRY_UNLIKELY (name_string_p == NULL))
212  {
213    return ECMA_VALUE_ERROR;
214  }
215
216  ecma_value_t obj_value = ecma_op_to_object (object);
217  /* The ecma_op_check_object_coercible call already checked the op_to_object error cases. */
218  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (obj_value));
219  JERRY_ASSERT (ecma_is_value_object (obj_value));
220  ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
221  JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
222
223  ecma_value_t delete_op_ret = ecma_op_object_delete (obj_p, name_string_p, is_strict);
224  JERRY_ASSERT (ecma_is_value_boolean (delete_op_ret) || ECMA_IS_VALUE_ERROR (delete_op_ret));
225  ecma_deref_object (obj_p);
226  ecma_deref_ecma_string (name_string_p);
227
228  return delete_op_ret;
229} /* vm_op_delete_prop */
230
231/**
232 * Deletes a variable.
233 *
234 * @return ecma value
235 *         Returned value must be freed with ecma_free_value
236 */
237ecma_value_t
238vm_op_delete_var (ecma_value_t name_literal, /**< name literal */
239                  ecma_object_t *lex_env_p) /**< lexical environment */
240{
241  ecma_value_t completion_value = ECMA_VALUE_EMPTY;
242
243  ecma_string_t *var_name_str_p = ecma_get_string_from_value (name_literal);
244
245  ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (lex_env_p, var_name_str_p);
246
247#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
248  if (JERRY_UNLIKELY (ref_base_lex_env_p == ECMA_OBJECT_POINTER_ERROR))
249  {
250    return ECMA_VALUE_ERROR;
251  }
252#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
253
254  if (ref_base_lex_env_p == NULL)
255  {
256    completion_value = ECMA_VALUE_TRUE;
257  }
258  else
259  {
260    JERRY_ASSERT (ecma_is_lexical_environment (ref_base_lex_env_p));
261
262    completion_value = ecma_op_delete_binding (ref_base_lex_env_p, var_name_str_p);
263  }
264
265  return completion_value;
266} /* vm_op_delete_var */
267
268/**
269 * 'for-in' opcode handler
270 *
271 * See also:
272 *          ECMA-262 v5, 12.6.4
273 *
274 * @return chain list of property names
275 */
276ecma_collection_t *
277opfunc_for_in (ecma_value_t left_value, /**< left value */
278               ecma_value_t *result_obj_p) /**< expression object */
279{
280  /* 3. */
281  if (ecma_is_value_undefined (left_value)
282      || ecma_is_value_null (left_value))
283  {
284    return NULL;
285  }
286
287  /* 4. */
288  ecma_value_t obj_expr_value = ecma_op_to_object (left_value);
289  /* ecma_op_to_object will only raise error on null/undefined values but those are handled above. */
290  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (obj_expr_value));
291  ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value);
292#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
293  JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (obj_p));
294#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
295  ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
296
297  if (prop_names_p->item_count != 0)
298  {
299    *result_obj_p = ecma_make_object_value (obj_p);
300    return prop_names_p;
301  }
302
303  ecma_deref_object (obj_p);
304  ecma_collection_destroy (prop_names_p);
305
306  return NULL;
307} /* opfunc_for_in */
308
309#if ENABLED (JERRY_ES2015)
310
311/**
312 * 'VM_OC_APPEND_ARRAY' opcode handler specialized for spread objects
313 *
314 * @return ECMA_VALUE_ERROR - if the operation failed
315 *         ECMA_VALUE_EMPTY, otherwise
316 */
317static ecma_value_t JERRY_ATTR_NOINLINE
318opfunc_append_to_spread_array (ecma_value_t *stack_top_p, /**< current stack top */
319                               uint16_t values_length) /**< number of elements to set */
320{
321  JERRY_ASSERT (!(values_length & OPFUNC_HAS_SPREAD_ELEMENT));
322
323  ecma_object_t *array_obj_p = ecma_get_object_from_value (stack_top_p[-1]);
324  JERRY_ASSERT (ecma_get_object_type (array_obj_p) == ECMA_OBJECT_TYPE_ARRAY);
325
326  ecma_extended_object_t *ext_array_obj_p = (ecma_extended_object_t *) array_obj_p;
327  uint32_t old_length = ext_array_obj_p->u.array.length;
328
329  for (uint32_t i = 0, idx = old_length; i < values_length; i++, idx++)
330  {
331    if (ecma_is_value_array_hole (stack_top_p[i]))
332    {
333      continue;
334    }
335
336    if (stack_top_p[i] == ECMA_VALUE_SPREAD_ELEMENT)
337    {
338      i++;
339      ecma_value_t ret_value = ECMA_VALUE_ERROR;
340      ecma_value_t spread_value = stack_top_p[i];
341
342      ecma_value_t iterator = ecma_op_get_iterator (spread_value, ECMA_VALUE_EMPTY);
343
344      if (!ECMA_IS_VALUE_ERROR (iterator))
345      {
346        while (true)
347        {
348          ecma_value_t next_value = ecma_op_iterator_step (iterator);
349
350          if (ECMA_IS_VALUE_ERROR (next_value))
351          {
352            break;
353          }
354
355          if (ecma_is_value_false (next_value))
356          {
357            idx--;
358            ret_value = ECMA_VALUE_EMPTY;
359            break;
360          }
361
362          ecma_value_t value = ecma_op_iterator_value (next_value);
363
364          ecma_free_value (next_value);
365
366          if (ECMA_IS_VALUE_ERROR (value))
367          {
368            break;
369          }
370
371          ecma_value_t put_comp;
372          put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
373                                                            idx++,
374                                                            value,
375                                                            ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
376
377          JERRY_ASSERT (ecma_is_value_true (put_comp));
378          ecma_free_value (value);
379        }
380      }
381
382      ecma_free_value (iterator);
383      ecma_free_value (spread_value);
384
385      if (ECMA_IS_VALUE_ERROR (ret_value))
386      {
387        for (uint32_t k = i + 1; k < values_length; k++)
388        {
389          ecma_free_value (stack_top_p[k]);
390        }
391
392        return ret_value;
393      }
394    }
395    else
396    {
397      ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
398                                                                     idx,
399                                                                     stack_top_p[i],
400                                                                     ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
401      JERRY_ASSERT (ecma_is_value_true (put_comp));
402      ecma_free_value (stack_top_p[i]);
403    }
404  }
405
406  return ECMA_VALUE_EMPTY;
407} /* opfunc_append_to_spread_array */
408
409/**
410 * Spread function call/construct arguments into an ecma-collection
411 *
412 * @return NULL - if the operation failed
413 *         pointer to the ecma-collection with the spreaded arguments, otherwise
414 */
415JERRY_ATTR_NOINLINE ecma_collection_t *
416opfunc_spread_arguments (ecma_value_t *stack_top_p, /**< pointer to the current stack top */
417                         uint8_t arguments_list_len) /**< number of arguments */
418{
419  ecma_collection_t *buff_p = ecma_new_collection ();
420
421  for (uint32_t i = 0; i < arguments_list_len; i++)
422  {
423    ecma_value_t arg = *stack_top_p++;
424
425    if (arg != ECMA_VALUE_SPREAD_ELEMENT)
426    {
427      ecma_collection_push_back (buff_p, arg);
428      continue;
429    }
430
431    ecma_value_t ret_value = ECMA_VALUE_ERROR;
432    ecma_value_t spread_value = *stack_top_p++;
433    i++;
434
435    ecma_value_t iterator = ecma_op_get_iterator (spread_value, ECMA_VALUE_EMPTY);
436
437    if (!ECMA_IS_VALUE_ERROR (iterator))
438    {
439      while (true)
440      {
441        ecma_value_t next_value = ecma_op_iterator_step (iterator);
442
443        if (ECMA_IS_VALUE_ERROR (next_value))
444        {
445          break;
446        }
447
448        if (ecma_is_value_false (next_value))
449        {
450          ret_value = ECMA_VALUE_EMPTY;
451          break;
452        }
453
454        ecma_value_t value = ecma_op_iterator_value (next_value);
455
456        ecma_free_value (next_value);
457
458        if (ECMA_IS_VALUE_ERROR (value))
459        {
460          break;
461        }
462
463        ecma_collection_push_back (buff_p, value);
464      }
465    }
466
467    ecma_free_value (iterator);
468    ecma_free_value (spread_value);
469
470    if (ECMA_IS_VALUE_ERROR (ret_value))
471    {
472      for (uint32_t k = i + 1; k < arguments_list_len; k++)
473      {
474        ecma_free_value (*stack_top_p++);
475      }
476
477      ecma_collection_free (buff_p);
478      buff_p = NULL;
479      break;
480    }
481  }
482
483  return buff_p;
484} /* opfunc_spread_arguments */
485
486#endif /* ENABLED (JERRY_ES2015) */
487
488/**
489 * 'VM_OC_APPEND_ARRAY' opcode handler, for setting array object properties
490 *
491 * @return ECMA_VALUE_ERROR - if the operation failed
492 *         ECMA_VALUE_EMPTY, otherwise
493 */
494ecma_value_t JERRY_ATTR_NOINLINE
495opfunc_append_array (ecma_value_t *stack_top_p, /**< current stack top */
496                     uint16_t values_length) /**< number of elements to set
497                                              *   with potential OPFUNC_HAS_SPREAD_ELEMENT flag */
498{
499#if ENABLED (JERRY_ES2015)
500  if (values_length >= OPFUNC_HAS_SPREAD_ELEMENT)
501  {
502    return opfunc_append_to_spread_array (stack_top_p, (uint16_t) (values_length & ~OPFUNC_HAS_SPREAD_ELEMENT));
503  }
504#endif /* ENABLED (JERRY_ES2015) */
505
506  ecma_object_t *array_obj_p = ecma_get_object_from_value (stack_top_p[-1]);
507  JERRY_ASSERT (ecma_get_object_type (array_obj_p) == ECMA_OBJECT_TYPE_ARRAY);
508
509  ecma_extended_object_t *ext_array_obj_p = (ecma_extended_object_t *) array_obj_p;
510  uint32_t old_length = ext_array_obj_p->u.array.length;
511
512  if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_array_obj_p)))
513  {
514    uint32_t filled_holes = 0;
515    ecma_value_t *values_p = ecma_fast_array_extend (array_obj_p, old_length + values_length);
516
517    for (uint32_t i = 0; i < values_length; i++)
518    {
519      values_p[old_length + i] = stack_top_p[i];
520
521      if (!ecma_is_value_array_hole (stack_top_p[i]))
522      {
523        filled_holes++;
524
525        if (ecma_is_value_object (stack_top_p[i]))
526        {
527          ecma_deref_object (ecma_get_object_from_value (stack_top_p[i]));
528        }
529      }
530    }
531
532    ext_array_obj_p->u.array.u.hole_count -= filled_holes * ECMA_FAST_ARRAY_HOLE_ONE;
533
534    if (JERRY_UNLIKELY ((values_length - filled_holes) > ECMA_FAST_ARRAY_MAX_NEW_HOLES_COUNT))
535    {
536      ecma_fast_array_convert_to_normal (array_obj_p);
537    }
538  }
539  else
540  {
541    for (uint32_t i = 0; i < values_length; i++)
542    {
543      if (!ecma_is_value_array_hole (stack_top_p[i]))
544      {
545        ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (old_length + i);
546
547        ecma_property_value_t *prop_value_p;
548
549        prop_value_p = ecma_create_named_data_property (array_obj_p,
550                                                        index_str_p,
551                                                        ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
552                                                        NULL);
553
554        ecma_deref_ecma_string (index_str_p);
555        prop_value_p->value = stack_top_p[i];
556
557        if (ecma_is_value_object (stack_top_p[i]))
558        {
559          ecma_free_value (stack_top_p[i]);
560        }
561
562      }
563
564      ext_array_obj_p->u.array.length = old_length + values_length;
565    }
566  }
567
568  return ECMA_VALUE_EMPTY;
569} /* opfunc_append_array */
570
571#if ENABLED (JERRY_ES2015)
572
573/**
574 * Create an executable object using the current frame context
575 *
576 * @return executable object
577 */
578ecma_value_t
579opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
580{
581  const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
582  size_t size;
583
584  ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_header_p);
585
586  if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
587  {
588    cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
589    size = ((size_t) args_p->register_end + (size_t) args_p->stack_limit) * sizeof (ecma_value_t);
590  }
591  else
592  {
593    cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
594    size = ((size_t) args_p->register_end + (size_t) args_p->stack_limit) * sizeof (ecma_value_t);
595  }
596
597  size_t total_size = JERRY_ALIGNUP (sizeof (vm_executable_object_t) + size, sizeof (uintptr_t));
598
599  ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_function_obj_p),
600                                                                   ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE);
601
602  ecma_object_t *object_p = ecma_create_object (proto_p,
603                                                total_size,
604                                                ECMA_OBJECT_TYPE_CLASS);
605
606  ecma_deref_object (proto_p);
607
608  vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;
609
610  executable_object_p->extended_object.u.class_prop.class_id = LIT_MAGIC_STRING_GENERATOR_UL;
611  executable_object_p->extended_object.u.class_prop.extra_info = 0;
612
613  JERRY_ASSERT (!frame_ctx_p->is_eval_code);
614  JERRY_ASSERT (frame_ctx_p->context_depth == 0);
615
616  vm_frame_ctx_t *new_frame_ctx_p = &(executable_object_p->frame_ctx);
617  *new_frame_ctx_p = *frame_ctx_p;
618
619  /* The old register values are discarded. */
620  ecma_value_t *new_registers_p = VM_GET_REGISTERS (new_frame_ctx_p);
621  memcpy (new_registers_p, VM_GET_REGISTERS (frame_ctx_p), size);
622
623  size_t stack_top = (size_t) (frame_ctx_p->stack_top_p - VM_GET_REGISTERS (frame_ctx_p));
624  ecma_value_t *new_stack_top_p = new_registers_p + stack_top;
625
626  new_frame_ctx_p->stack_top_p = new_stack_top_p;
627
628  /* Initial state is "not running", so all object references are released. */
629
630  while (new_registers_p < new_stack_top_p)
631  {
632    ecma_deref_if_object (*new_registers_p++);
633  }
634
635  new_frame_ctx_p->this_binding = ecma_copy_value_if_not_object (new_frame_ctx_p->this_binding);
636
637  JERRY_CONTEXT (vm_top_context_p) = new_frame_ctx_p->prev_context_p;
638
639  return ecma_make_object_value (object_p);
640} /* opfunc_create_executable_object */
641
642/**
643 * Resume the execution of an inactive executable object
644 *
645 * @return value provided by the execution
646 */
647ecma_value_t
648opfunc_resume_executable_object (vm_executable_object_t *executable_object_p, /**< executable object */
649                                 ecma_value_t value) /**< value pushed onto the stack (takes the reference) */
650{
651  const ecma_compiled_code_t *bytecode_header_p = executable_object_p->frame_ctx.bytecode_header_p;
652  ecma_value_t *register_p = VM_GET_REGISTERS (&executable_object_p->frame_ctx);
653  ecma_value_t *register_end_p;
654
655  if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
656  {
657    cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
658    register_end_p = register_p + args_p->register_end;
659  }
660  else
661  {
662    cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
663    register_end_p = register_p + args_p->register_end;
664  }
665
666  while (register_p < register_end_p)
667  {
668    ecma_ref_if_object (*register_p++);
669  }
670
671  if (executable_object_p->frame_ctx.context_depth > 0)
672  {
673    vm_ref_lex_env_chain (executable_object_p->frame_ctx.lex_env_p,
674                          executable_object_p->frame_ctx.context_depth,
675                          register_p,
676                          true);
677
678    register_p += executable_object_p->frame_ctx.context_depth;
679  }
680
681  ecma_value_t *stack_top_p = executable_object_p->frame_ctx.stack_top_p;
682
683  while (register_p < stack_top_p)
684  {
685    ecma_ref_if_object (*register_p++);
686  }
687
688  *register_p++ = value;
689  executable_object_p->frame_ctx.stack_top_p = register_p;
690
691  JERRY_ASSERT (ECMA_EXECUTABLE_OBJECT_IS_SUSPENDED (executable_object_p->extended_object.u.class_prop.extra_info));
692
693  executable_object_p->extended_object.u.class_prop.extra_info |= ECMA_EXECUTABLE_OBJECT_RUNNING;
694
695  executable_object_p->frame_ctx.prev_context_p = JERRY_CONTEXT (vm_top_context_p);
696  JERRY_CONTEXT (vm_top_context_p) = &executable_object_p->frame_ctx;
697
698  /* inside the generators the "new.target" is always "undefined" as it can't be invoked with "new" */
699  ecma_object_t *old_new_target = JERRY_CONTEXT (current_new_target);
700  JERRY_CONTEXT (current_new_target) = NULL;
701
702  ecma_value_t result = vm_execute (&executable_object_p->frame_ctx);
703
704  JERRY_CONTEXT (current_new_target) = old_new_target;
705  executable_object_p->extended_object.u.class_prop.extra_info &= (uint16_t) ~ECMA_EXECUTABLE_OBJECT_RUNNING;
706
707  if (executable_object_p->frame_ctx.call_operation != VM_EXEC_RETURN)
708  {
709    JERRY_ASSERT (executable_object_p->frame_ctx.call_operation == VM_NO_EXEC_OP);
710
711    /* All resources are released. */
712    executable_object_p->extended_object.u.class_prop.extra_info |= ECMA_EXECUTABLE_OBJECT_COMPLETED;
713    return result;
714  }
715
716  JERRY_CONTEXT (vm_top_context_p) = executable_object_p->frame_ctx.prev_context_p;
717
718  register_p = VM_GET_REGISTERS (&executable_object_p->frame_ctx);
719
720  while (register_p < register_end_p)
721  {
722    ecma_deref_if_object (*register_p++);
723  }
724
725  if (executable_object_p->frame_ctx.context_depth > 0)
726  {
727    vm_ref_lex_env_chain (executable_object_p->frame_ctx.lex_env_p,
728                          executable_object_p->frame_ctx.context_depth,
729                          register_p,
730                          false);
731
732    register_p += executable_object_p->frame_ctx.context_depth;
733  }
734
735  stack_top_p = executable_object_p->frame_ctx.stack_top_p;
736
737  while (register_p < stack_top_p)
738  {
739    ecma_deref_if_object (*register_p++);
740  }
741
742  return result;
743} /* opfunc_resume_executable_object */
744
745/**
746 * Create a Promise object if needed and resolve it with a value
747 *
748 * @return Promise object
749 */
750ecma_value_t
751opfunc_return_promise (ecma_value_t value) /**< value */
752{
753  ecma_value_t promise = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE));
754  ecma_value_t result = ecma_promise_reject_or_resolve (promise, value, true);
755
756  ecma_free_value (value);
757  return result;
758} /* opfunc_return_promise */
759
760/**
761 * Implicit class constructor handler when the classHeritage is not present.
762 *
763 * See also: ECMAScript v6, 14.5.14.10.b.i
764 *
765 * @return ECMA_VALUE_ERROR - if the function was invoked without 'new'
766 *         ECMA_VALUE_UNDEFINED - otherwise
767 */
768static ecma_value_t
769ecma_op_implicit_constructor_handler_cb (const ecma_value_t function_obj, /**< the function itself */
770                                         const ecma_value_t this_val, /**< this_arg of the function */
771                                         const ecma_value_t args_p[], /**< argument list */
772                                         const ecma_length_t args_count) /**< argument number */
773{
774  JERRY_UNUSED_4 (function_obj, this_val, args_p, args_count);
775
776  if (JERRY_CONTEXT (current_new_target) == NULL)
777  {
778    return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
779  }
780
781  return ECMA_VALUE_UNDEFINED;
782} /* ecma_op_implicit_constructor_handler_cb */
783
784/**
785 * Implicit class constructor handler when the classHeritage is present.
786 *
787 * See also: ECMAScript v6, 14.5.14.10.a.i
788 *
789 * @return ECMA_VALUE_ERROR - if the operation fails
790 *         result of the super call - otherwise
791 */
792static ecma_value_t
793ecma_op_implicit_constructor_handler_heritage_cb (const ecma_value_t function_obj, /**< the function itself */
794                                                  const ecma_value_t this_val, /**< this_arg of the function */
795                                                  const ecma_value_t args_p[], /**< argument list */
796                                                  const ecma_length_t args_count) /**< argument number */
797{
798  JERRY_UNUSED_4 (function_obj, this_val, args_p, args_count);
799
800  if (JERRY_CONTEXT (current_new_target) == NULL)
801  {
802    return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
803  }
804
805  ecma_object_t *func_obj_p = ecma_get_object_from_value (function_obj);
806  ecma_value_t super_ctor = ecma_op_function_get_super_constructor (func_obj_p);
807
808  if (ECMA_IS_VALUE_ERROR (super_ctor))
809  {
810    return super_ctor;
811  }
812
813  ecma_object_t *super_ctor_p = ecma_get_object_from_value (super_ctor);
814
815  ecma_value_t result = ecma_op_function_construct (super_ctor_p,
816                                                    JERRY_CONTEXT (current_new_target),
817                                                    args_p,
818                                                    args_count);
819
820  if (ecma_is_value_object (result))
821  {
822    ecma_value_t proto_value = ecma_op_object_get_by_magic_id (JERRY_CONTEXT (current_new_target),
823                                                               LIT_MAGIC_STRING_PROTOTYPE);
824    if (ECMA_IS_VALUE_ERROR (proto_value))
825    {
826      ecma_free_value (result);
827      result = ECMA_VALUE_ERROR;
828    }
829    else if (ecma_is_value_object (proto_value))
830    {
831      ECMA_SET_POINTER (ecma_get_object_from_value (result)->u2.prototype_cp,
832                        ecma_get_object_from_value (proto_value));
833    }
834    ecma_free_value (proto_value);
835  }
836
837  ecma_deref_object (super_ctor_p);
838
839  return result;
840} /* ecma_op_implicit_constructor_handler_heritage_cb */
841
842/**
843 * Create implicit class constructor
844 *
845 * See also: ECMAScript v6, 14.5.14
846 *
847 * @return - new external function ecma-object
848 */
849ecma_value_t
850opfunc_create_implicit_class_constructor (uint8_t opcode) /**< current cbc opcode */
851{
852  /* 8. */
853  ecma_object_t *func_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
854                                                  sizeof (ecma_extended_object_t),
855                                                  ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
856
857  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
858
859  /* 10.a.i */
860  if (opcode == CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE)
861  {
862    ext_func_obj_p->u.external_handler_cb = ecma_op_implicit_constructor_handler_heritage_cb;
863  }
864  /* 10.b.i */
865  else
866  {
867    ext_func_obj_p->u.external_handler_cb = ecma_op_implicit_constructor_handler_cb;
868  }
869
870  ecma_property_value_t *prop_value_p;
871  prop_value_p = ecma_create_named_data_property (func_obj_p,
872                                                  ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
873                                                  ECMA_PROPERTY_FLAG_CONFIGURABLE,
874                                                  NULL);
875
876  prop_value_p->value = ecma_make_uint32_value (0);
877
878  return ecma_make_object_value (func_obj_p);
879} /* opfunc_create_implicit_class_constructor */
880
881/**
882 * Set the [[HomeObject]] attribute of the given functon object
883 */
884static inline void JERRY_ATTR_ALWAYS_INLINE
885opfunc_set_home_object (ecma_object_t *func_p, /**< function object */
886                        ecma_object_t *parent_env_p) /**< parent environment */
887{
888  if (ecma_get_object_type (func_p) == ECMA_OBJECT_TYPE_FUNCTION)
889  {
890    JERRY_ASSERT (!ecma_get_object_is_builtin (func_p));
891
892    ECMA_SET_NON_NULL_POINTER_TAG (((ecma_extended_object_t *) func_p)->u.function.scope_cp, parent_env_p, 0);
893  }
894} /* opfunc_set_home_object */
895
896/**
897 * ClassDefinitionEvaluation environment initialization part
898 *
899 * See also: ECMAScript v6, 14.5.14
900 *
901 * @return - ECMA_VALUE_ERROR - if the operation fails
902 *           ECMA_VALUE_EMPTY - otherwise
903 */
904void
905opfunc_push_class_environment (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
906                               ecma_value_t **vm_stack_top, /**< VM stack top */
907                               ecma_value_t class_name) /**< class name */
908{
909  JERRY_ASSERT (ecma_is_value_undefined (class_name) || ecma_is_value_string (class_name));
910  ecma_object_t *class_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p);
911
912  /* 4.a */
913  if (!ecma_is_value_undefined (class_name))
914  {
915    ecma_op_create_immutable_binding (class_env_p,
916                                      ecma_get_string_from_value (class_name),
917                                      ECMA_VALUE_UNINITIALIZED);
918  }
919  frame_ctx_p->lex_env_p = class_env_p;
920
921  *(*vm_stack_top)++ = ECMA_VALUE_RELEASE_LEX_ENV;
922} /* opfunc_push_class_environment */
923
924/**
925 * ClassDefinitionEvaluation object initialization part
926 *
927 * See also: ECMAScript v6, 14.5.14
928 *
929 * @return - ECMA_VALUE_ERROR - if the operation fails
930 *           ECMA_VALUE_EMPTY - otherwise
931 */
932ecma_value_t
933opfunc_init_class (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
934                   ecma_value_t *stack_top_p) /**< stack top */
935{
936  /* 5.b, 6.e.ii */
937  ecma_object_t *ctor_parent_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
938  ecma_object_t *proto_parent_p = NULL;
939  bool free_proto_parent = false;
940
941  ecma_value_t super_class = stack_top_p[-2];
942  ecma_object_t *ctor_p = ecma_get_object_from_value (stack_top_p[-1]);
943
944  bool heritage_present = !ecma_is_value_array_hole (super_class);
945
946  /* 5. ClassHeritage opt is not present */
947  if (!heritage_present)
948  {
949    /* 5.a */
950    proto_parent_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
951  }
952  else if (!ecma_is_value_null (super_class))
953  {
954    /* 6.f, 6.g.i */
955    if (!ecma_is_constructor (super_class)
956        || ecma_op_function_is_generator (ecma_get_object_from_value (super_class)))
957    {
958      return ecma_raise_type_error ("Class extends value is not a constructor or null");
959    }
960
961    ecma_object_t *parent_p = ecma_get_object_from_value (super_class);
962
963    /* 6.g.ii */
964    ecma_value_t proto_parent = ecma_op_object_get_by_magic_id (parent_p, LIT_MAGIC_STRING_PROTOTYPE);
965
966    /* 6.g.iii */
967    if (ECMA_IS_VALUE_ERROR (proto_parent))
968    {
969      return proto_parent;
970    }
971
972    /* 6.g.iv */
973    if (ecma_is_value_object (proto_parent))
974    {
975      proto_parent_p = ecma_get_object_from_value (proto_parent);
976      free_proto_parent = true;
977    }
978    else if (ecma_is_value_null (proto_parent))
979    {
980      proto_parent_p = NULL;
981    }
982    else
983    {
984      ecma_free_value (proto_parent);
985      return ecma_raise_type_error ("Property 'prototype' is not an object or null");
986    }
987
988    /* 6.g.v */
989    ctor_parent_p = parent_p;
990  }
991
992  /* 7. */
993  ecma_object_t *proto_p = ecma_create_object (proto_parent_p, 0, ECMA_OBJECT_TYPE_GENERAL);
994  ecma_value_t proto = ecma_make_object_value (proto_p);
995
996  ECMA_SET_POINTER (ctor_p->u2.prototype_cp, ctor_parent_p);
997
998  if (free_proto_parent)
999  {
1000    ecma_deref_object (proto_parent_p);
1001  }
1002  ecma_free_value (super_class);
1003
1004  /* 16. */
1005  ecma_property_value_t *property_value_p;
1006  property_value_p = ecma_create_named_data_property (ctor_p,
1007                                                      ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE),
1008                                                      ECMA_PROPERTY_FIXED,
1009                                                      NULL);
1010  property_value_p->value = proto;
1011
1012  /* 18. */
1013  property_value_p = ecma_create_named_data_property (proto_p,
1014                                                      ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR),
1015                                                      ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
1016                                                      NULL);
1017  property_value_p->value = ecma_make_object_value (ctor_p);
1018
1019  if (ecma_get_object_type (ctor_p) == ECMA_OBJECT_TYPE_FUNCTION)
1020  {
1021    ecma_object_t *proto_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p,
1022                                                             proto_p,
1023                                                             ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
1024
1025    ECMA_SET_NON_NULL_POINTER_TAG (((ecma_extended_object_t *) ctor_p)->u.function.scope_cp, proto_env_p, 0);
1026
1027    /* 15. set F’s [[ConstructorKind]] internal slot to "derived". */
1028    if (heritage_present)
1029    {
1030      ECMA_SET_THIRD_BIT_TO_POINTER_TAG (((ecma_extended_object_t *) ctor_p)->u.function.scope_cp);
1031    }
1032
1033    ecma_deref_object (proto_env_p);
1034  }
1035
1036  stack_top_p[-2] = stack_top_p[-1];
1037  stack_top_p[-1] = proto;
1038
1039  return ECMA_VALUE_EMPTY;
1040} /* opfunc_init_class */
1041
1042/**
1043 * Set [[Enumerable]] and [[HomeObject]] attributes for all class method
1044 */
1045static void
1046opfunc_set_class_attributes (ecma_object_t *obj_p, /**< object */
1047                             ecma_object_t *parent_env_p) /**< parent environment */
1048{
1049  jmem_cpointer_t prop_iter_cp = obj_p->u1.property_list_cp;
1050
1051#if ENABLED (JERRY_PROPRETY_HASHMAP)
1052  if (prop_iter_cp != JMEM_CP_NULL)
1053  {
1054    ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
1055    if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
1056    {
1057      prop_iter_cp = prop_iter_p->next_property_cp;
1058    }
1059  }
1060#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
1061
1062  while (prop_iter_cp != JMEM_CP_NULL)
1063  {
1064    ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
1065    JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
1066
1067    ecma_property_pair_t *property_pair_p = (ecma_property_pair_t *) prop_iter_p;
1068
1069    for (uint32_t index = 0; index < ECMA_PROPERTY_PAIR_ITEM_COUNT; index++)
1070    {
1071      uint8_t property = property_pair_p->header.types[index];
1072
1073      if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA)
1074      {
1075        if (ecma_is_value_object (property_pair_p->values[index].value)
1076            && ecma_is_property_enumerable (property))
1077        {
1078          property_pair_p->header.types[index] = (uint8_t) (property & ~ECMA_PROPERTY_FLAG_ENUMERABLE);
1079          opfunc_set_home_object (ecma_get_object_from_value (property_pair_p->values[index].value), parent_env_p);
1080        }
1081      }
1082      else if (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
1083      {
1084        ecma_property_value_t *accessor_objs_p = property_pair_p->values + index;
1085
1086        ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (accessor_objs_p);
1087
1088        if (get_set_pair_p->getter_cp != JMEM_CP_NULL)
1089        {
1090          opfunc_set_home_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp), parent_env_p);
1091        }
1092
1093        if (get_set_pair_p->setter_cp != JMEM_CP_NULL)
1094        {
1095          opfunc_set_home_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp), parent_env_p);
1096        }
1097      }
1098      else
1099      {
1100        JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL);
1101
1102        JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP
1103                      || property == ECMA_PROPERTY_TYPE_DELETED);
1104      }
1105    }
1106
1107    prop_iter_cp = prop_iter_p->next_property_cp;
1108  }
1109} /* opfunc_set_class_attributes */
1110
1111/**
1112 * Pop the current lexical environment referenced by the frame context
1113 */
1114void
1115opfunc_pop_lexical_environment (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
1116{
1117  ecma_object_t *outer_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, frame_ctx_p->lex_env_p->u2.outer_reference_cp);
1118  ecma_deref_object (frame_ctx_p->lex_env_p);
1119  frame_ctx_p->lex_env_p = outer_env_p;
1120} /* opfunc_pop_lexical_environment */
1121
1122/**
1123 * ClassDefinitionEvaluation finalization part
1124 *
1125 * See also: ECMAScript v6, 14.5.14
1126 */
1127void
1128opfunc_finalize_class (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
1129                       ecma_value_t **vm_stack_top_p, /**< current vm stack top */
1130                       ecma_value_t class_name) /**< class name */
1131{
1132  JERRY_ASSERT (ecma_is_value_undefined (class_name) || ecma_is_value_string (class_name));
1133  ecma_value_t *stack_top_p = *vm_stack_top_p;
1134
1135  ecma_object_t *ctor_p = ecma_get_object_from_value (stack_top_p[-2]);
1136  ecma_object_t *proto_p = ecma_get_object_from_value (stack_top_p[-1]);
1137
1138  ecma_object_t *class_env_p = frame_ctx_p->lex_env_p;
1139
1140  /* 23.a */
1141  if (!ecma_is_value_undefined (class_name))
1142  {
1143    ecma_op_initialize_binding (class_env_p, ecma_get_string_from_value (class_name), stack_top_p[-2]);
1144  }
1145
1146  ecma_object_t *ctor_env_p = ecma_create_object_lex_env (class_env_p,
1147                                                          ctor_p,
1148                                                          ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
1149  ecma_object_t *proto_env_p = ecma_create_object_lex_env (class_env_p,
1150                                                           proto_p,
1151                                                           ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
1152
1153  opfunc_set_class_attributes (ctor_p, ctor_env_p);
1154  opfunc_set_class_attributes (proto_p, proto_env_p);
1155
1156  ecma_deref_object (proto_env_p);
1157  ecma_deref_object (ctor_env_p);
1158
1159  opfunc_pop_lexical_environment (frame_ctx_p);
1160
1161  ecma_deref_object (proto_p);
1162
1163  /* only the current class remains on the stack */
1164  JERRY_ASSERT (stack_top_p[-3] == ECMA_VALUE_RELEASE_LEX_ENV);
1165  stack_top_p[-3] = stack_top_p[-2];
1166  *vm_stack_top_p -= 2;
1167} /* opfunc_finalize_class */
1168
1169/**
1170 * MakeSuperPropertyReference operation
1171 *
1172 * See also: ECMAScript v6, 12.3.5.3
1173 *
1174 * @return ECMA_VALUE_ERROR - if the operation fails
1175 *         ECMA_VALUE_EMPTY - otherwise
1176 */
1177ecma_value_t
1178opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, /**< current vm stack top */
1179                             vm_frame_ctx_t *frame_ctx_p, /**< frame context */
1180                             ecma_value_t prop_name, /**< property name to resolve */
1181                             uint8_t opcode) /**< current cbc opcode */
1182{
1183  ecma_value_t parent = ecma_op_resolve_super_base (frame_ctx_p->lex_env_p);
1184
1185  if (ECMA_IS_VALUE_ERROR (parent))
1186  {
1187    return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot invoke nullable super method."));
1188  }
1189
1190  if (ECMA_IS_VALUE_ERROR (ecma_op_check_object_coercible (parent)))
1191  {
1192    return ECMA_VALUE_ERROR;
1193  }
1194
1195  ecma_value_t *stack_top_p = *vm_stack_top_p;
1196
1197  if (opcode >= CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE)
1198  {
1199    JERRY_ASSERT (opcode == CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE
1200                  || opcode == CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
1201    *stack_top_p++ = parent;
1202    *stack_top_p++ = ecma_copy_value (prop_name);
1203    *vm_stack_top_p = stack_top_p;
1204
1205    return ECMA_VALUE_EMPTY;
1206  }
1207
1208  ecma_object_t *parent_p = ecma_get_object_from_value (parent);
1209  ecma_string_t *prop_name_p = ecma_op_to_prop_name (prop_name);
1210
1211  if (prop_name_p == NULL)
1212  {
1213    ecma_deref_object (parent_p);
1214    return ECMA_VALUE_ERROR;
1215  }
1216
1217  ecma_value_t result = ecma_op_object_get_with_receiver (parent_p, prop_name_p, frame_ctx_p->this_binding);
1218  ecma_deref_ecma_string (prop_name_p);
1219  ecma_deref_object (parent_p);
1220
1221  if (ECMA_IS_VALUE_ERROR (result))
1222  {
1223    return result;
1224  }
1225
1226  if (opcode == CBC_EXT_SUPER_PROP_LITERAL_REFERENCE || opcode == CBC_EXT_SUPER_PROP_REFERENCE)
1227  {
1228    *stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
1229    *stack_top_p++ = ECMA_VALUE_UNDEFINED;
1230  }
1231
1232  *stack_top_p++ = result;
1233  *vm_stack_top_p = stack_top_p;
1234
1235  return ECMA_VALUE_EMPTY;
1236} /* opfunc_form_super_reference */
1237
1238/**
1239 * Assignment operation for SuperRefence base
1240 *
1241 * @return ECMA_VALUE_ERROR - if the operation fails
1242 *         ECMA_VALUE_EMPTY - otherwise
1243 */
1244ecma_value_t
1245opfunc_assign_super_reference (ecma_value_t **vm_stack_top_p, /**< vm stack top */
1246                               vm_frame_ctx_t *frame_ctx_p, /**< frame context */
1247                               uint32_t opcode_data) /**< opcode data to store the result */
1248{
1249  ecma_value_t *stack_top_p = *vm_stack_top_p;
1250
1251  ecma_value_t base_obj = ecma_op_to_object (stack_top_p[-3]);
1252
1253  if (ECMA_IS_VALUE_ERROR (base_obj))
1254  {
1255    return base_obj;
1256  }
1257
1258  ecma_object_t *base_obj_p = ecma_get_object_from_value (base_obj);
1259  ecma_string_t *prop_name_p = ecma_op_to_prop_name (stack_top_p[-2]);
1260
1261  if (prop_name_p == NULL)
1262  {
1263    ecma_deref_object (base_obj_p);
1264    return ECMA_VALUE_ERROR;
1265  }
1266
1267  bool is_strict = (frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
1268
1269  ecma_value_t result = ecma_op_object_put_with_receiver (base_obj_p,
1270                                                          prop_name_p,
1271                                                          stack_top_p[-1],
1272                                                          frame_ctx_p->this_binding,
1273                                                          is_strict);
1274
1275  ecma_deref_ecma_string (prop_name_p);
1276  ecma_deref_object (base_obj_p);
1277
1278  if (ECMA_IS_VALUE_ERROR (result))
1279  {
1280    return result;
1281  }
1282
1283  for (int32_t i = 1; i <= 3; i++)
1284  {
1285    ecma_free_value (stack_top_p[-i]);
1286  }
1287
1288  stack_top_p -= 3;
1289
1290  if (opcode_data & VM_OC_PUT_STACK)
1291  {
1292    *stack_top_p++ = result;
1293  }
1294  else if (opcode_data & VM_OC_PUT_BLOCK)
1295  {
1296    ecma_fast_free_value (frame_ctx_p->block_result);
1297    frame_ctx_p->block_result = result;
1298  }
1299
1300  *vm_stack_top_p = stack_top_p;
1301
1302  return result;
1303} /* opfunc_assign_super_reference */
1304#endif /* ENABLED (JERRY_ES2015) */
1305
1306/**
1307 * @}
1308 * @}
1309 */
1310