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-builtin-helpers.h"
18#include "ecma-exceptions.h"
19#include "ecma-function-object.h"
20#include "ecma-gc.h"
21#include "ecma-helpers.h"
22#include "lit-char-helpers.h"
23#include "ecma-lex-env.h"
24#include "ecma-objects.h"
25#include "ecma-objects-general.h"
26#include "ecma-objects-arguments.h"
27#include "ecma-proxy-object.h"
28#include "ecma-try-catch-macro.h"
29#include "jcontext.h"
30
31/** \addtogroup ecma ECMA
32 * @{
33 *
34 * \addtogroup ecmafunctionobject ECMA Function object related routines
35 * @{
36 */
37
38#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
39/**
40 * Get the resource name from the compiled code header
41 *
42 * @return resource name as ecma-string
43 */
44ecma_value_t
45ecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p)
46{
47  JERRY_ASSERT (bytecode_header_p != NULL);
48
49  uint8_t *byte_p = (uint8_t *) bytecode_header_p;
50  byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
51
52  ecma_value_t *resource_name_p = (ecma_value_t *) byte_p;
53  resource_name_p -= ecma_compiled_code_get_formal_params (bytecode_header_p);
54
55#if ENABLED (JERRY_ES2015)
56  if (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
57  {
58    resource_name_p--;
59  }
60#endif /* ENABLED (JERRY_ES2015) */
61
62  return resource_name_p[-1];
63} /* ecma_op_resource_name */
64#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
65
66/**
67 * IsCallable operation.
68 *
69 * See also: ECMA-262 v5, 9.11
70 *
71 * @return true - if the given object is callable;
72 *         false - otherwise
73 */
74inline bool JERRY_ATTR_ALWAYS_INLINE
75ecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
76{
77  JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
78
79  const ecma_object_type_t type = ecma_get_object_type (obj_p);
80
81#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
82  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
83  {
84    return ecma_op_is_callable (((ecma_proxy_object_t *) obj_p)->target);
85  }
86#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
87
88  return type >= ECMA_OBJECT_TYPE_FUNCTION;
89} /* ecma_op_object_is_callable */
90
91/**
92 * IsCallable operation.
93 *
94 * See also: ECMA-262 v5, 9.11
95 *
96 * @return true - if value is callable object;
97 *         false - otherwise
98 */
99bool
100ecma_op_is_callable (ecma_value_t value) /**< ecma value */
101{
102  return (ecma_is_value_object (value)
103          && ecma_op_object_is_callable (ecma_get_object_from_value (value)));
104} /* ecma_op_is_callable */
105
106/**
107 * Checks whether the given object implements [[Construct]].
108 *
109 * @return true - if the given object is constructor;
110 *         false - otherwise
111 */
112inline bool JERRY_ATTR_ALWAYS_INLINE
113ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
114{
115  JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
116
117  ecma_object_type_t type = ecma_get_object_type (obj_p);
118
119  while (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
120  {
121    ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) obj_p;
122
123    obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
124                                                        bound_func_p->header.u.bound_function.target_function);
125
126    type = ecma_get_object_type (obj_p);
127  }
128
129#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
130  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
131  {
132    return ecma_is_constructor (((ecma_proxy_object_t *) obj_p)->target);
133  }
134#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
135
136  if (type == ECMA_OBJECT_TYPE_FUNCTION)
137  {
138    return (!ecma_get_object_is_builtin (obj_p) || !ecma_builtin_function_is_routine (obj_p));
139  }
140
141  return (type >= ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
142} /* ecma_object_is_constructor */
143
144/**
145 * Checks whether the value is Object that implements [[Construct]].
146 *
147 * @return true - if value is constructor object;
148 *         false - otherwise
149 */
150bool
151ecma_is_constructor (ecma_value_t value) /**< ecma value */
152{
153  return (ecma_is_value_object (value)
154          && ecma_object_is_constructor (ecma_get_object_from_value (value)));
155} /* ecma_is_constructor */
156
157/**
158 * Helper method to count and convert the arguments for the Function/GeneratorFunction constructor call.
159 *
160 * See also:
161 *          ECMA 262 v5.1 15.3.2.1 steps 5.a-d
162 *          ECMA 262 v6 19.2.1.1.1 steps 8
163 *
164 * @return ecma value - concatenated arguments as a string.
165 *         Returned value must be freed with ecma_free_value.
166 */
167static ecma_string_t *
168ecma_op_create_dynamic_function_arguments_helper (const ecma_value_t *arguments_list_p, /**< arguments list */
169                                                  ecma_length_t arguments_list_len) /**< number of arguments */
170{
171  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
172
173  if (arguments_list_len <= 1)
174  {
175    return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
176  }
177
178  ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]);
179
180  if (JERRY_UNLIKELY (str_p == NULL))
181  {
182    return str_p;
183  }
184
185  if (arguments_list_len == 2)
186  {
187    return str_p;
188  }
189
190  ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (str_p);
191  ecma_deref_ecma_string (str_p);
192
193  for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++)
194  {
195    str_p = ecma_op_to_string (arguments_list_p[idx]);
196
197    if (JERRY_UNLIKELY (str_p == NULL))
198    {
199      ecma_stringbuilder_destroy (&builder);
200      return str_p;
201    }
202
203    ecma_stringbuilder_append_char (&builder, LIT_CHAR_COMMA);
204    ecma_stringbuilder_append (&builder, str_p);
205    ecma_deref_ecma_string (str_p);
206  }
207
208  return ecma_stringbuilder_finalize (&builder);
209} /* ecma_op_create_dynamic_function_arguments_helper */
210
211/**
212 * Function object creation operation.
213 *
214 * See also: ECMA-262 v5, 13.2
215 *
216 * @return pointer to newly created Function object
217 */
218static ecma_object_t *
219ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
220                                const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
221                                ecma_builtin_id_t proto_id) /**< builtin id of the prototype object */
222{
223  JERRY_ASSERT (ecma_is_lexical_environment (scope_p));
224
225  /* 1., 4., 13. */
226  ecma_object_t *prototype_obj_p = ecma_builtin_get (proto_id);
227
228  size_t function_object_size = sizeof (ecma_extended_object_t);
229
230#if ENABLED (JERRY_SNAPSHOT_EXEC)
231  if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
232  {
233    function_object_size = sizeof (ecma_static_function_t);
234  }
235#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
236
237  ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
238                                              function_object_size,
239                                              ECMA_OBJECT_TYPE_FUNCTION);
240
241  /* 2., 6., 7., 8. */
242  /*
243   * We don't setup [[Get]], [[Call]], [[Construct]], [[HasInstance]] for each function object.
244   * Instead we set the object's type to ECMA_OBJECT_TYPE_FUNCTION
245   * that defines which version of the routine should be used on demand.
246   */
247
248  /* 3. */
249  /*
250   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
251   *
252   * See also: ecma_object_get_class_name
253   */
254
255  ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p;
256
257  /* 9. */
258  ECMA_SET_NON_NULL_POINTER_TAG (ext_func_p->u.function.scope_cp, scope_p, 0);
259
260  /* 10., 11., 12. */
261
262#if ENABLED (JERRY_SNAPSHOT_EXEC)
263  if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
264  {
265    ext_func_p->u.function.bytecode_cp = ECMA_NULL_POINTER;
266    ((ecma_static_function_t *) func_p)->bytecode_p = bytecode_data_p;
267  }
268  else
269#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
270  {
271    ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
272    ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
273  }
274
275  /* 14., 15., 16., 17., 18. */
276  /*
277   * 'length' and 'prototype' properties are instantiated lazily
278   *
279   * See also: ecma_op_function_try_to_lazy_instantiate_property
280   */
281
282  return func_p;
283} /* ecma_op_create_function_object */
284
285/**
286 * CreateDynamicFunction operation
287 *
288 * See also:
289 *          ECMA-262 v5, 15.3.
290 *          ECMA-262 v6, 19.2.1.1
291 *
292 * @return ECMA_VALUE_ERROR - if the operation fails
293 *         constructed function object - otherwise
294 */
295ecma_value_t
296ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< arguments list */
297                                 ecma_length_t arguments_list_len, /**< number of arguments */
298                                 ecma_parse_opts_t parse_opts) /**< parse options */
299{
300  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
301
302  ecma_string_t *arguments_str_p = ecma_op_create_dynamic_function_arguments_helper (arguments_list_p,
303                                                                                     arguments_list_len);
304
305  if (JERRY_UNLIKELY (arguments_str_p == NULL))
306  {
307    return ECMA_VALUE_ERROR;
308  }
309
310  ecma_string_t *function_body_str_p;
311
312  if (arguments_list_len > 0)
313  {
314    function_body_str_p = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]);
315
316    if (JERRY_UNLIKELY (function_body_str_p == NULL))
317    {
318      ecma_deref_ecma_string (arguments_str_p);
319      return ECMA_VALUE_ERROR;
320    }
321  }
322  else
323  {
324    /* Very unlikely code path, not optimized. */
325    function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
326  }
327
328  ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
329  ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
330
331#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
332  JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
333#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
334
335  ecma_compiled_code_t *bytecode_data_p = NULL;
336
337  ecma_value_t ret_value = parser_parse_script (arguments_buffer_p,
338                                                arguments_buffer_size,
339                                                function_body_buffer_p,
340                                                function_body_buffer_size,
341                                                parse_opts,
342                                                &bytecode_data_p);
343
344  if (!ECMA_IS_VALUE_ERROR (ret_value))
345  {
346    JERRY_ASSERT (ecma_is_value_true (ret_value));
347
348    ecma_object_t *global_env_p = ecma_get_global_environment ();
349    ecma_builtin_id_t fallback_proto = ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE;
350
351#if ENABLED (JERRY_ES2015)
352    ecma_object_t *new_target_p = JERRY_CONTEXT (current_new_target);
353    bool is_generator_func = parse_opts & ECMA_PARSE_GENERATOR_FUNCTION;
354
355    if (is_generator_func)
356    {
357      fallback_proto = ECMA_BUILTIN_ID_GENERATOR;
358    }
359
360    if (new_target_p == NULL)
361    {
362      if (is_generator_func)
363      {
364        new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_FUNCTION);
365      }
366      else
367      {
368        new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION);
369      }
370    }
371
372    ecma_object_t *proto = ecma_op_get_prototype_from_constructor (new_target_p, fallback_proto);
373
374    if (JERRY_UNLIKELY (proto == NULL))
375    {
376      ecma_bytecode_deref (bytecode_data_p);
377      ecma_deref_ecma_string (arguments_str_p);
378      ecma_deref_ecma_string (function_body_str_p);
379      return ECMA_VALUE_ERROR;
380    }
381#endif /* ENABLED (JERRY_ES2015) */
382
383    ecma_object_t *func_obj_p = ecma_op_create_function_object (global_env_p, bytecode_data_p, fallback_proto);
384
385#if ENABLED (JERRY_ES2015)
386    ECMA_SET_NON_NULL_POINTER (func_obj_p->u2.prototype_cp, proto);
387    ecma_deref_object (proto);
388#endif /* ENABLED (JERRY_ES2015) */
389
390    ecma_bytecode_deref (bytecode_data_p);
391    ret_value = ecma_make_object_value (func_obj_p);
392  }
393
394  ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
395  ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
396
397  ecma_deref_ecma_string (arguments_str_p);
398  ecma_deref_ecma_string (function_body_str_p);
399
400  return ret_value;
401} /* ecma_op_create_dynamic_function */
402
403/**
404 * Function object creation operation.
405 *
406 * See also: ECMA-262 v5, 13.2
407 *
408 * @return pointer to newly created Function object
409 */
410ecma_object_t *
411ecma_op_create_simple_function_object (ecma_object_t *scope_p, /**< function's scope */
412                                       const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
413{
414  return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
415} /* ecma_op_create_simple_function_object */
416
417#if ENABLED (JERRY_ES2015)
418
419/**
420 * GeneratorFunction object creation operation.
421 *
422 * See also: ECMA-262 v5, 13.2
423 *
424 * @return pointer to newly created Function object
425 */
426ecma_object_t *
427ecma_op_create_generator_function_object (ecma_object_t *scope_p, /**< function's scope */
428                                          const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
429{
430  return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_GENERATOR);
431} /* ecma_op_create_generator_function_object */
432
433/**
434 * Arrow function object creation operation.
435 *
436 * See also: ES2015, 9.2.12
437 *
438 * @return pointer to newly created Function object
439 */
440ecma_object_t *
441ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's scope */
442                                      const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
443                                      ecma_value_t this_binding) /**< value of 'this' binding */
444{
445  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
446
447  size_t arrow_function_object_size = sizeof (ecma_arrow_function_t);
448
449#if ENABLED (JERRY_SNAPSHOT_EXEC)
450  if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
451  {
452    arrow_function_object_size = sizeof (ecma_static_arrow_function_t);
453  }
454#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
455
456  ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
457                                              arrow_function_object_size,
458                                              ECMA_OBJECT_TYPE_FUNCTION);
459
460  ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_p;
461
462  ECMA_SET_NON_NULL_POINTER_TAG (arrow_func_p->header.u.function.scope_cp, scope_p, 0);
463
464#if ENABLED (JERRY_SNAPSHOT_EXEC)
465  if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
466  {
467    arrow_func_p->header.u.function.bytecode_cp = ECMA_NULL_POINTER;
468    ((ecma_static_arrow_function_t *) func_p)->bytecode_p = bytecode_data_p;
469  }
470  else
471  {
472#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
473    ECMA_SET_INTERNAL_VALUE_POINTER (arrow_func_p->header.u.function.bytecode_cp, bytecode_data_p);
474    ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
475#if ENABLED (JERRY_SNAPSHOT_EXEC)
476  }
477#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
478
479  arrow_func_p->this_binding = ecma_copy_value_if_not_object (this_binding);
480  arrow_func_p->new_target = ECMA_VALUE_UNDEFINED;
481
482  if (JERRY_CONTEXT (current_new_target) != NULL)
483  {
484    arrow_func_p->new_target = ecma_make_object_value (JERRY_CONTEXT (current_new_target));
485  }
486  return func_p;
487} /* ecma_op_create_arrow_function_object */
488
489#endif /* ENABLED (JERRY_ES2015) */
490
491/**
492 * External function object creation operation.
493 *
494 * Note:
495 *      external function object is implementation-defined object type
496 *      that represent functions implemented in native code, using Embedding API
497 *
498 * @return pointer to newly created external function object
499 */
500ecma_object_t *
501ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**< pointer to external native handler */
502{
503  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
504
505  ecma_object_t *function_obj_p;
506  function_obj_p = ecma_create_object (prototype_obj_p,
507                                       sizeof (ecma_extended_object_t),
508                                       ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
509
510  /*
511   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
512   *
513   * See also: ecma_object_get_class_name
514   */
515
516  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
517  ext_func_obj_p->u.external_handler_cb = handler_cb;
518
519  return function_obj_p;
520} /* ecma_op_create_external_function_object */
521
522/**
523 * Get compiled code of a function object.
524 *
525 * @return compiled code
526 */
527inline const ecma_compiled_code_t * JERRY_ATTR_ALWAYS_INLINE
528ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< function pointer */
529{
530#if ENABLED (JERRY_SNAPSHOT_EXEC)
531  if (function_p->u.function.bytecode_cp != ECMA_NULL_POINTER)
532  {
533    return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
534                                            function_p->u.function.bytecode_cp);
535  }
536  else
537  {
538    return ((ecma_static_function_t *) function_p)->bytecode_p;
539  }
540#else /* !ENABLED (JERRY_SNAPSHOT_EXEC) */
541  return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
542                                          function_p->u.function.bytecode_cp);
543#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
544} /* ecma_op_function_get_compiled_code */
545
546#if ENABLED (JERRY_ES2015)
547/**
548 * Check whether the given object [[FunctionKind]] internal slot value is "generator".
549 *
550 * @return true - if the given object is a generator function
551 *         false - otherwise
552 */
553bool
554ecma_op_function_is_generator (ecma_object_t *obj_p) /**< object */
555{
556  if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
557      && !ecma_get_object_is_builtin (obj_p))
558  {
559    ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) obj_p;
560    const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
561
562    return (bytecode_data_p->status_flags & CBC_CODE_FLAGS_GENERATOR) != 0;
563  }
564
565  return false;
566} /* ecma_op_function_is_generator */
567
568#endif /* ENABLED (JERRY_ES2015) */
569
570/**
571 * 15.3.5.3 implementation of [[HasInstance]] for Function objects
572 *
573 * @return true/false - if arguments are valid
574 *         error - otherwise
575 *         Returned value must be freed with ecma_free_value
576 */
577ecma_value_t
578ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object */
579                               ecma_value_t value) /**< argument 'V' */
580{
581  JERRY_ASSERT (func_obj_p != NULL
582                && !ecma_is_lexical_environment (func_obj_p));
583
584  if (!ecma_is_value_object (value))
585  {
586    return ECMA_VALUE_FALSE;
587  }
588
589  while (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
590  {
591    JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
592
593    /* 1. 3. */
594    ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
595
596    func_obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
597                                                             bound_func_p->header.u.bound_function.target_function);
598  }
599
600  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
601                || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
602                || ECMA_OBJECT_IS_PROXY (func_obj_p));
603
604  ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
605
606  ecma_value_t prototype_obj_value = ecma_op_object_get_by_magic_id (func_obj_p,
607                                                                     LIT_MAGIC_STRING_PROTOTYPE);
608
609  if (ECMA_IS_VALUE_ERROR (prototype_obj_value))
610  {
611    return prototype_obj_value;
612  }
613
614  if (!ecma_is_value_object (prototype_obj_value))
615  {
616    ecma_free_value (prototype_obj_value);
617    return ecma_raise_type_error (ECMA_ERR_MSG ("Object expected."));
618  }
619
620  ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
621  JERRY_ASSERT (prototype_obj_p != NULL);
622
623#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
624  ecma_value_t result = ECMA_VALUE_ERROR;
625#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
626  ecma_value_t result = ECMA_VALUE_FALSE;
627#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
628
629  while (true)
630  {
631    jmem_cpointer_t v_obj_cp;
632#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
633    if (ECMA_OBJECT_IS_PROXY (v_obj_p))
634    {
635      ecma_value_t parent = ecma_proxy_object_get_prototype_of (v_obj_p);
636
637      if (ECMA_IS_VALUE_ERROR (parent))
638      {
639        break;
640      }
641
642      v_obj_cp = ecma_proxy_object_prototype_to_cp (parent);
643    }
644    else
645    {
646#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
647      v_obj_cp = ecma_op_ordinary_object_get_prototype_of (v_obj_p);
648#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
649    }
650#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
651
652    if (v_obj_cp == JMEM_CP_NULL)
653    {
654#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
655      result = ECMA_VALUE_FALSE;
656#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
657      break;
658    }
659
660    v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp);
661
662    if (v_obj_p == prototype_obj_p)
663    {
664      result = ECMA_VALUE_TRUE;
665      break;
666    }
667  }
668
669  ecma_deref_object (prototype_obj_p);
670  return result;
671} /* ecma_op_function_has_instance */
672
673#if ENABLED (JERRY_ES2015)
674
675/**
676 * GetSuperConstructor operation for class methods
677 *
678 * See also: ECMAScript v6, 12.3.5.2
679 *
680 * @return ECMA_VALUE_ERROR - if the operation fails
681 *         super constructor - otherwise
682 */
683ecma_value_t
684ecma_op_function_get_super_constructor (ecma_object_t *func_obj_p) /**< function object */
685{
686  ecma_object_t *super_ctor_p;
687
688#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
689  if (ECMA_OBJECT_IS_PROXY (func_obj_p))
690  {
691    ecma_value_t super_ctor = ecma_proxy_object_get_prototype_of (func_obj_p);
692
693    if (ECMA_IS_VALUE_ERROR (super_ctor))
694    {
695      return super_ctor;
696    }
697
698    super_ctor_p = ecma_is_value_null (super_ctor) ? NULL : ecma_get_object_from_value (super_ctor);
699  }
700  else
701  {
702#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
703    jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (func_obj_p);
704    if (proto_cp == JMEM_CP_NULL)
705    {
706      super_ctor_p = NULL;
707    }
708    else
709    {
710      super_ctor_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
711      ecma_ref_object (super_ctor_p);
712    }
713#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
714  }
715#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
716
717  if (super_ctor_p == NULL || !ecma_object_is_constructor (super_ctor_p))
718  {
719    if (super_ctor_p != NULL)
720    {
721      ecma_deref_object (super_ctor_p);
722    }
723    return ecma_raise_type_error (ECMA_ERR_MSG ("Super binding must be a constructor."));
724  }
725
726  return ecma_make_object_value (super_ctor_p);
727} /* ecma_op_function_get_super_constructor */
728#endif /* ENABLED (JERRY_ES2015) */
729
730/**
731 * Ordinary internal method: GetPrototypeFromConstructor (constructor, intrinsicDefaultProto)
732 *
733 * See also: ECMAScript v6, 9.1.15
734 *
735 * @return NULL - if the operation fail (exception on the global context is raised)
736 *         pointer to the prototype object - otherwise
737 */
738ecma_object_t *
739ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< constructor to get prototype from  */
740                                        ecma_builtin_id_t default_proto_id) /**< intrinsicDefaultProto */
741{
742  JERRY_ASSERT (ecma_object_is_constructor (ctor_obj_p));
743  JERRY_ASSERT (default_proto_id < ECMA_BUILTIN_ID__COUNT);
744
745  ecma_value_t proto = ecma_op_object_get_by_magic_id (ctor_obj_p, LIT_MAGIC_STRING_PROTOTYPE);
746
747  if (ECMA_IS_VALUE_ERROR (proto))
748  {
749    return NULL;
750  }
751
752  ecma_object_t *proto_obj_p;
753
754  if (!ecma_is_value_object (proto))
755  {
756    ecma_free_value (proto);
757    proto_obj_p = ecma_builtin_get (default_proto_id);
758    ecma_ref_object (proto_obj_p);
759  }
760  else
761  {
762    proto_obj_p = ecma_get_object_from_value (proto);
763  }
764
765  return proto_obj_p;
766} /* ecma_op_get_prototype_from_constructor */
767
768/**
769 * Perform a JavaScript function object method call.
770 *
771 * The input function object should be a pure JavaScript method
772 *
773 * @return the result of the function call.
774 */
775static ecma_value_t
776ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
777                              ecma_value_t this_arg_value, /**< 'this' argument's value */
778                              const ecma_value_t *arguments_list_p, /**< arguments list */
779                              ecma_length_t arguments_list_len) /**< length of arguments list */
780{
781  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
782
783  if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
784  {
785    return ecma_builtin_dispatch_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
786  }
787
788  /* Entering Function Code (ECMA-262 v5, 10.4.3) */
789  ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
790
791  ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
792                                                                       ext_func_p->u.function.scope_cp);
793
794  /* 8. */
795  ecma_value_t this_binding = this_arg_value;
796  bool free_this_binding = false;
797
798  const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
799  uint16_t status_flags = bytecode_data_p->status_flags;
800
801#if ENABLED (JERRY_ES2015)
802  bool is_construct_call = JERRY_CONTEXT (current_new_target) != NULL;
803  if (JERRY_UNLIKELY (status_flags & (CBC_CODE_FLAGS_CLASS_CONSTRUCTOR | CBC_CODE_FLAGS_GENERATOR)))
804  {
805    if (!is_construct_call && (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
806    {
807      return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
808    }
809
810    if ((status_flags & CBC_CODE_FLAGS_GENERATOR) && is_construct_call)
811    {
812      return ecma_raise_type_error (ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'."));
813    }
814  }
815#endif /* ENABLED (JERRY_ES2015) */
816
817  /* 1. */
818#if ENABLED (JERRY_ES2015)
819  ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
820
821  if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
822  {
823    ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
824
825    if (ecma_is_value_undefined (arrow_func_p->new_target))
826    {
827      JERRY_CONTEXT (current_new_target) = NULL;
828    }
829    else
830    {
831      JERRY_CONTEXT (current_new_target) = ecma_get_object_from_value (arrow_func_p->new_target);
832    }
833    this_binding = arrow_func_p->this_binding;
834  }
835  else
836  {
837    JERRY_CONTEXT (current_function_obj_p) = func_obj_p;
838#endif /* ENABLED (JERRY_ES2015) */
839    if (!(status_flags & CBC_CODE_FLAGS_STRICT_MODE))
840    {
841      if (ecma_is_value_undefined (this_binding)
842          || ecma_is_value_null (this_binding))
843      {
844        /* 2. */
845        this_binding = ecma_make_object_value (ecma_builtin_get_global ());
846      }
847      else if (!ecma_is_value_object (this_binding))
848      {
849        /* 3., 4. */
850        this_binding = ecma_op_to_object (this_binding);
851        free_this_binding = true;
852
853        JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
854      }
855    }
856#if ENABLED (JERRY_ES2015)
857  }
858#endif /* ENABLED (JERRY_ES2015) */
859
860  /* 5. */
861  ecma_object_t *local_env_p;
862  if (status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED)
863  {
864    local_env_p = scope_p;
865  }
866  else
867  {
868    local_env_p = ecma_create_decl_lex_env (scope_p);
869    if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_IS_ARGUMENTS_NEEDED)
870    {
871      ecma_op_create_arguments_object (func_obj_p,
872                                       local_env_p,
873                                       arguments_list_p,
874                                       arguments_list_len,
875                                       bytecode_data_p);
876    }
877#if ENABLED (JERRY_ES2015)
878    // ECMAScript v6, 9.2.2.8
879    if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
880    {
881      ecma_value_t lexical_this;
882      lexical_this = (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp) ? ECMA_VALUE_UNINITIALIZED
883                                                                                            : this_binding);
884      ecma_op_init_this_binding (local_env_p, lexical_this);
885    }
886#endif /* ENABLED (JERRY_ES2015) */
887  }
888
889  ecma_value_t ret_value = vm_run (bytecode_data_p,
890                                   this_binding,
891                                   local_env_p,
892                                   arguments_list_p,
893                                   arguments_list_len);
894
895#if ENABLED (JERRY_ES2015)
896  JERRY_CONTEXT (current_function_obj_p) = old_function_object_p;
897
898  /* ECMAScript v6, 9.2.2.13 */
899  if (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
900  {
901    if (!ECMA_IS_VALUE_ERROR (ret_value) && !ecma_is_value_object (ret_value))
902    {
903      if (!ecma_is_value_undefined (ret_value))
904      {
905        ecma_free_value (ret_value);
906        ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived constructors may only return object or undefined."));
907      }
908      else
909      {
910        ret_value = ecma_op_get_this_binding (local_env_p);
911      }
912    }
913  }
914
915#endif /* ENABLED (JERRY_ES2015) */
916
917  if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
918  {
919    ecma_deref_object (local_env_p);
920  }
921
922  if (JERRY_UNLIKELY (free_this_binding))
923  {
924    ecma_free_value (this_binding);
925  }
926
927  return ret_value;
928} /* ecma_op_function_call_simple */
929
930/**
931 * Perform a native C method call which was registered via the API.
932 *
933 * @return the result of the function call.
934 */
935static ecma_value_t JERRY_ATTR_NOINLINE
936ecma_op_function_call_external (ecma_object_t *func_obj_p, /**< Function object */
937                                ecma_value_t this_arg_value, /**< 'this' argument's value */
938                                const ecma_value_t *arguments_list_p, /**< arguments list */
939                                ecma_length_t arguments_list_len) /**< length of arguments list */
940
941{
942  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
943  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
944  JERRY_ASSERT (ext_func_obj_p->u.external_handler_cb != NULL);
945
946  ecma_value_t ret_value = ext_func_obj_p->u.external_handler_cb (ecma_make_object_value (func_obj_p),
947                                                                  this_arg_value,
948                                                                  arguments_list_p,
949                                                                  arguments_list_len);
950  if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
951  {
952    ecma_raise_error_from_error_reference (ret_value);
953    return ECMA_VALUE_ERROR;
954  }
955
956#if ENABLED (JERRY_DEBUGGER)
957  JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
958#endif /* ENABLED (JERRY_DEBUGGER) */
959  return ret_value;
960} /* ecma_op_function_call_external */
961
962/**
963 * Append the bound arguments into the given collection
964 *
965 * Note:
966 *       - The whole bound chain is resolved
967 *       - The first element of the collection contains the bounded this value
968 *
969 * @return target function of the bound function
970 */
971JERRY_ATTR_NOINLINE static ecma_object_t *
972ecma_op_bound_function_get_argument_list (ecma_object_t *func_obj_p, /**< bound bunction object */
973                                          ecma_collection_t *list_p) /**< list of arguments */
974{
975  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
976
977  ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
978
979  func_obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
980                                                           bound_func_p->header.u.bound_function.target_function);
981
982  ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
983
984  ecma_length_t args_length = 1;
985
986  if (ecma_is_value_integer_number (args_len_or_this))
987  {
988    args_length = (ecma_length_t) ecma_get_integer_from_value (args_len_or_this);
989  }
990
991  /* 5. */
992  if (args_length != 1)
993  {
994    const ecma_value_t *args_p = (const ecma_value_t *) (bound_func_p + 1);
995    list_p->buffer_p[0] = *args_p;
996
997    if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
998    {
999      func_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, list_p);
1000    }
1001    ecma_collection_append (list_p, args_p + 1, args_length - 1);
1002  }
1003  else
1004  {
1005    list_p->buffer_p[0] = args_len_or_this;
1006  }
1007
1008  return func_obj_p;
1009} /* ecma_op_bound_function_get_argument_list */
1010
1011/**
1012 * [[Call]] internal method for bound function objects
1013 *
1014 * @return ecma value
1015 *         Returned value must be freed with ecma_free_value
1016 */
1017static ecma_value_t JERRY_ATTR_NOINLINE
1018ecma_op_function_call_bound (ecma_object_t *func_obj_p, /**< Function object */
1019                             const ecma_value_t *arguments_list_p, /**< arguments list */
1020                             ecma_length_t arguments_list_len) /**< length of arguments list */
1021{
1022  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1023
1024  JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
1025
1026  ecma_collection_t *bound_arg_list_p = ecma_new_collection ();
1027  ecma_collection_push_back (bound_arg_list_p, ECMA_VALUE_EMPTY);
1028
1029  ecma_object_t *target_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, bound_arg_list_p);
1030
1031  ecma_collection_append (bound_arg_list_p, arguments_list_p, arguments_list_len);
1032
1033  JERRY_ASSERT (!ecma_is_value_empty (bound_arg_list_p->buffer_p[0]));
1034
1035  ecma_value_t ret_value = ecma_op_function_call (target_obj_p,
1036                                                  bound_arg_list_p->buffer_p[0],
1037                                                  bound_arg_list_p->buffer_p + 1,
1038                                                  (ecma_length_t) (bound_arg_list_p->item_count - 1));
1039
1040  ecma_collection_destroy (bound_arg_list_p);
1041
1042  return ret_value;
1043} /* ecma_op_function_call_bound */
1044
1045/**
1046 * [[Call]] implementation for Function objects,
1047 * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
1048 * or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
1049 * and for built-in Function objects
1050 * from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
1051 *
1052 * @return ecma value
1053 *         Returned value must be freed with ecma_free_value
1054 */
1055ecma_value_t
1056ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
1057                       ecma_value_t this_arg_value, /**< 'this' argument's value */
1058                       const ecma_value_t *arguments_list_p, /**< arguments list */
1059                       ecma_length_t arguments_list_len) /**< length of arguments list */
1060{
1061  JERRY_ASSERT (func_obj_p != NULL
1062                && !ecma_is_lexical_environment (func_obj_p));
1063  JERRY_ASSERT (ecma_op_object_is_callable (func_obj_p));
1064
1065  ECMA_CHECK_STACK_USAGE ();
1066
1067  const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
1068
1069#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1070  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
1071  {
1072    return ecma_proxy_object_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1073  }
1074#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1075
1076#if ENABLED (JERRY_ES2015)
1077  ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1078  if (JERRY_UNLIKELY (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_DIRECT_EVAL)))
1079  {
1080    JERRY_CONTEXT (current_new_target) = NULL;
1081  }
1082#endif /* ENABLED (JERRY_ES2015) */
1083
1084  ecma_value_t result;
1085
1086  if (JERRY_LIKELY (type == ECMA_OBJECT_TYPE_FUNCTION))
1087  {
1088    result = ecma_op_function_call_simple (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1089  }
1090  else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
1091  {
1092    result = ecma_op_function_call_external (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1093  }
1094  else
1095  {
1096    result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len);
1097  }
1098
1099#if ENABLED (JERRY_ES2015)
1100  JERRY_CONTEXT (current_new_target) = old_new_target_p;
1101#endif /* ENABLED (JERRY_ES2015) */
1102
1103  return result;
1104} /* ecma_op_function_call */
1105
1106/**
1107 * [[Construct]] internal method for bound function objects
1108 *
1109 * @return ecma value
1110 *         Returned value must be freed with ecma_free_value
1111 */
1112static ecma_value_t JERRY_ATTR_NOINLINE
1113ecma_op_function_construct_bound (ecma_object_t *func_obj_p, /**< Function object */
1114                                  ecma_object_t *new_target_p, /**< new target */
1115                                  const ecma_value_t *arguments_list_p, /**< arguments list */
1116                                  ecma_length_t arguments_list_len) /**< length of arguments list */
1117{
1118  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1119
1120  ecma_collection_t *bound_arg_list_p = ecma_new_collection ();
1121  ecma_collection_push_back (bound_arg_list_p, ECMA_VALUE_EMPTY);
1122
1123  ecma_object_t *target_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, bound_arg_list_p);
1124
1125  ecma_collection_append (bound_arg_list_p, arguments_list_p, arguments_list_len);
1126
1127  if (func_obj_p == new_target_p)
1128  {
1129    new_target_p = target_obj_p;
1130  }
1131
1132  ecma_value_t ret_value = ecma_op_function_construct (target_obj_p,
1133                                                       new_target_p,
1134                                                       bound_arg_list_p->buffer_p + 1,
1135                                                       (ecma_length_t) (bound_arg_list_p->item_count - 1));
1136
1137  ecma_collection_destroy (bound_arg_list_p);
1138
1139  return ret_value;
1140} /* ecma_op_function_construct_bound */
1141
1142/**
1143 * [[Construct]] internal method for external function objects
1144 *
1145 * @return ecma value
1146 *         Returned value must be freed with ecma_free_value
1147 */
1148static ecma_value_t JERRY_ATTR_NOINLINE
1149ecma_op_function_construct_external (ecma_object_t *func_obj_p, /**< Function object */
1150                                     ecma_object_t *new_target_p, /**< new target */
1151                                     const ecma_value_t *arguments_list_p, /**< arguments list */
1152                                     ecma_length_t arguments_list_len) /**< length of arguments list */
1153{
1154  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1155
1156  ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
1157
1158  if (JERRY_UNLIKELY (proto_p == NULL))
1159  {
1160    return ECMA_VALUE_ERROR;
1161  }
1162
1163  ecma_object_t *new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
1164  ecma_value_t this_arg = ecma_make_object_value (new_this_obj_p);
1165  ecma_deref_object (proto_p);
1166
1167#if ENABLED (JERRY_ES2015)
1168  ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1169  JERRY_CONTEXT (current_new_target) = new_target_p;
1170#endif /* ENABLED (JERRY_ES2015) */
1171
1172  ecma_value_t ret_value = ecma_op_function_call_external (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
1173
1174#if ENABLED (JERRY_ES2015)
1175  JERRY_CONTEXT (current_new_target) = old_new_target_p;
1176#endif /* ENABLED (JERRY_ES2015) */
1177
1178  if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
1179  {
1180    ecma_deref_object (new_this_obj_p);
1181    return ret_value;
1182  }
1183
1184  ecma_free_value (ret_value);
1185
1186  return this_arg;
1187} /* ecma_op_function_construct_external */
1188
1189/**
1190 * General [[Construct]] implementation function objects
1191 *
1192 * See also: ECMAScript v6, 9.2.2
1193 *
1194 * @return ecma value
1195 *         Returned value must be freed with ecma_free_value
1196 */
1197ecma_value_t
1198ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
1199                            ecma_object_t *new_target_p, /**< new target */
1200                            const ecma_value_t *arguments_list_p, /**< arguments list */
1201                            ecma_length_t arguments_list_len) /**< length of arguments list */
1202{
1203  JERRY_ASSERT (func_obj_p != NULL
1204                && !ecma_is_lexical_environment (func_obj_p));
1205
1206  const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
1207
1208#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1209  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
1210  {
1211    return ecma_proxy_object_construct (func_obj_p,
1212                                        new_target_p,
1213                                        arguments_list_p,
1214                                        arguments_list_len);
1215  }
1216#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1217
1218  if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION))
1219  {
1220    return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1221  }
1222
1223  if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION))
1224  {
1225    return ecma_op_function_construct_external (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1226  }
1227
1228  JERRY_ASSERT (type == ECMA_OBJECT_TYPE_FUNCTION);
1229
1230  if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
1231  {
1232    return ecma_builtin_dispatch_construct (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1233  }
1234
1235  ecma_object_t *new_this_obj_p = NULL;
1236  ecma_value_t this_arg;
1237  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
1238  const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
1239
1240  if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1241  {
1242    if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
1243    {
1244      return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor."));
1245    }
1246
1247    return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
1248  }
1249
1250#if ENABLED (JERRY_ES2015)
1251  /* 6. */
1252  ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1253  JERRY_CONTEXT (current_new_target) = new_target_p;
1254
1255  /* 5. */
1256  if (!ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_obj_p->u.function.scope_cp))
1257  {
1258#endif /* ENABLED (JERRY_ES2015) */
1259    /* 5.a */
1260    ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
1261
1262    /* 5.b */
1263    if (JERRY_UNLIKELY (proto_p == NULL))
1264    {
1265      return ECMA_VALUE_ERROR;
1266    }
1267
1268    new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
1269    ecma_deref_object (proto_p);
1270    this_arg = ecma_make_object_value (new_this_obj_p);
1271#if ENABLED (JERRY_ES2015)
1272  }
1273  else
1274  {
1275    this_arg = ECMA_VALUE_UNDEFINED;
1276  }
1277#endif /* ENABLED (JERRY_ES2015) */
1278
1279  ecma_value_t ret_value = ecma_op_function_call_simple (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
1280
1281#if ENABLED (JERRY_ES2015)
1282  JERRY_CONTEXT (current_new_target) = old_new_target_p;
1283#endif /* ENABLED (JERRY_ES2015) */
1284
1285  /* 13.a */
1286  if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
1287  {
1288#if ENABLED (JERRY_ES2015)
1289    if (new_this_obj_p != NULL)
1290    {
1291      ecma_deref_object (new_this_obj_p);
1292    }
1293#else /* !ENABLED (JERRY_ES2015) */
1294    ecma_deref_object (new_this_obj_p);
1295#endif /* ENABLED (JERRY_ES2015) */
1296    return ret_value;
1297  }
1298
1299  /* 13.b */
1300  ecma_free_value (ret_value);
1301  return this_arg;
1302} /* ecma_op_function_construct */
1303
1304/**
1305 * Lazy instantiation of 'prototype' property for non-builtin and external functions
1306 *
1307 * @return pointer to newly instantiated property
1308 */
1309static ecma_property_t *
1310ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the function object */
1311{
1312  JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
1313                || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1314
1315  /* ECMA-262 v5, 13.2, 16-18 */
1316
1317  ecma_object_t *proto_object_p = NULL;
1318  bool init_constructor = true;
1319
1320#if ENABLED (JERRY_ES2015)
1321  if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
1322  {
1323    const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1324
1325    if (byte_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
1326    {
1327      proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
1328                                           0,
1329                                           ECMA_OBJECT_TYPE_GENERAL);
1330      init_constructor = false;
1331    }
1332    else if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1333    {
1334      return NULL;
1335    }
1336  }
1337#endif /* ENABLED (JERRY_ES2015) */
1338
1339#if ENABLED (JERRY_ES2015)
1340  if (proto_object_p == NULL)
1341#endif /* ENABLED (JERRY_ES2015) */
1342  {
1343    proto_object_p = ecma_op_create_object_object_noarg ();
1344  }
1345
1346  /* 17. */
1347  if (init_constructor)
1348  {
1349    ecma_property_value_t *constructor_prop_value_p;
1350    constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
1351                                                                ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR),
1352                                                                ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
1353                                                                NULL);
1354
1355    constructor_prop_value_p->value = ecma_make_object_value (object_p);
1356  }
1357
1358  /* 18. */
1359  ecma_property_t *prototype_prop_p;
1360  ecma_property_value_t *prototype_prop_value_p;
1361  prototype_prop_value_p = ecma_create_named_data_property (object_p,
1362                                                            ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE),
1363                                                            ECMA_PROPERTY_FLAG_WRITABLE,
1364                                                            &prototype_prop_p);
1365
1366  prototype_prop_value_p->value = ecma_make_object_value (proto_object_p);
1367
1368  ecma_deref_object (proto_object_p);
1369
1370  return prototype_prop_p;
1371} /* ecma_op_lazy_instantiate_prototype_object */
1372
1373/**
1374 * Lazy instantiation of non-builtin ecma function object's properties
1375 *
1376 * Warning:
1377 *         Only non-configurable properties could be instantiated lazily in this function,
1378 *         as configurable properties could be deleted and it would be incorrect
1379 *         to reinstantiate them in the function in second time.
1380 *
1381 * @return pointer to newly instantiated property, if a property was instantiated,
1382 *         NULL - otherwise
1383 */
1384ecma_property_t *
1385ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< the function object */
1386                                                   ecma_string_t *property_name_p) /**< property name */
1387{
1388  JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
1389
1390#if ENABLED (JERRY_ES2015)
1391  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH))
1392  {
1393    ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1394    if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1395    {
1396      /* Initialize 'length' property */
1397      const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
1398      uint32_t len;
1399      if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
1400      {
1401        cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
1402        len = args_p->argument_end;
1403      }
1404      else
1405      {
1406        cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
1407        len = args_p->argument_end;
1408      }
1409
1410      /* Set tag bit to represent initialized 'length' property */
1411      ECMA_SET_FIRST_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
1412      ecma_property_t *value_prop_p;
1413      ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1414                                                                        property_name_p,
1415                                                                        ECMA_PROPERTY_FLAG_CONFIGURABLE,
1416                                                                        &value_prop_p);
1417      value_p->value = ecma_make_uint32_value (len);
1418      return value_prop_p;
1419    }
1420
1421    return NULL;
1422  }
1423#endif /* ENABLED (JERRY_ES2015) */
1424
1425  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE)
1426      && ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
1427  {
1428    return ecma_op_lazy_instantiate_prototype_object (object_p);
1429  }
1430
1431  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_CALLER)
1432      || ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_ARGUMENTS))
1433  {
1434    const ecma_compiled_code_t *bytecode_data_p;
1435    bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1436
1437#if ENABLED (JERRY_ES2015)
1438    if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
1439    {
1440      ecma_property_t *value_prop_p;
1441      /* The property_name_p argument contans the name. */
1442      ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1443                                                                        property_name_p,
1444                                                                        ECMA_PROPERTY_FIXED,
1445                                                                        &value_prop_p);
1446      value_p->value = ECMA_VALUE_NULL;
1447      return value_prop_p;
1448    }
1449#else /* !ENABLED (JERRY_ES2015) */
1450    if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
1451    {
1452      ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
1453
1454      ecma_property_t *caller_prop_p;
1455      /* The property_name_p argument contans the name. */
1456      ecma_create_named_accessor_property (object_p,
1457                                           property_name_p,
1458                                           thrower_p,
1459                                           thrower_p,
1460                                           ECMA_PROPERTY_FIXED,
1461                                           &caller_prop_p);
1462      return caller_prop_p;
1463    }
1464#endif /* ENABLED (JERRY_ES2015) */
1465
1466  }
1467
1468  return NULL;
1469} /* ecma_op_function_try_to_lazy_instantiate_property */
1470
1471/**
1472 * Create specification defined non-configurable properties for external functions.
1473 *
1474 * See also:
1475 *          ECMA-262 v5, 15.3.4.5
1476 *
1477 * @return pointer property, if one was instantiated,
1478 *         NULL - otherwise.
1479 */
1480ecma_property_t *
1481ecma_op_external_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
1482                                                            ecma_string_t *property_name_p) /**< property's name */
1483{
1484  JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1485
1486  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE))
1487  {
1488    return ecma_op_lazy_instantiate_prototype_object (object_p);
1489  }
1490
1491  return NULL;
1492} /* ecma_op_external_function_try_to_lazy_instantiate_property */
1493
1494/**
1495 * Create specification defined non-configurable properties for bound functions.
1496 *
1497 * See also:
1498 *          ECMA-262 v5, 15.3.4.5
1499 *
1500 * @return pointer property, if one was instantiated,
1501 *         NULL - otherwise.
1502 */
1503ecma_property_t *
1504ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
1505                                                         ecma_string_t *property_name_p) /**< property's name */
1506{
1507  JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1508
1509  if (ecma_string_is_length (property_name_p))
1510  {
1511    ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
1512    ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
1513    ecma_integer_value_t length = 0;
1514    ecma_integer_value_t args_length = 1;
1515    uint8_t length_attributes;
1516
1517    if (ecma_is_value_integer_number (args_len_or_this))
1518    {
1519      args_length = ecma_get_integer_from_value (args_len_or_this);
1520    }
1521
1522#if ENABLED (JERRY_ES2015)
1523    if (ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function))
1524    {
1525      return NULL;
1526    }
1527
1528    length_attributes = ECMA_PROPERTY_FLAG_CONFIGURABLE;
1529    length = bound_func_p->target_length - (args_length - 1);
1530
1531    /* Set tag bit to represent initialized 'length' property */
1532    ECMA_SET_FIRST_BIT_TO_POINTER_TAG (bound_func_p->header.u.bound_function.target_function);
1533#else /* !ENABLED (JERRY_ES2015) */
1534    length_attributes = ECMA_PROPERTY_FIXED;
1535
1536    ecma_object_t *target_func_p;
1537    target_func_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
1538                                                                bound_func_p->header.u.bound_function.target_function);
1539
1540    if (ecma_object_get_class_name (target_func_p) == LIT_MAGIC_STRING_FUNCTION_UL)
1541    {
1542      /* The property_name_p argument contains the 'length' string. */
1543      ecma_value_t get_len_value = ecma_op_object_get (target_func_p, property_name_p);
1544
1545      JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (get_len_value));
1546      JERRY_ASSERT (ecma_is_value_integer_number (get_len_value));
1547
1548      length = ecma_get_integer_from_value (get_len_value) - (args_length - 1);
1549    }
1550#endif /* ENABLED (JERRY_ES2015) */
1551
1552    if (length < 0)
1553    {
1554      length = 0;
1555    }
1556
1557    ecma_property_t *len_prop_p;
1558    ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p,
1559                                                                               property_name_p,
1560                                                                               length_attributes,
1561                                                                               &len_prop_p);
1562
1563    len_prop_value_p->value = ecma_make_integer_value (length);
1564    return len_prop_p;
1565  }
1566
1567  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_CALLER)
1568      || ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_ARGUMENTS))
1569  {
1570    ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
1571
1572    ecma_property_t *caller_prop_p;
1573    /* The string_p argument contans the name. */
1574    ecma_create_named_accessor_property (object_p,
1575                                         property_name_p,
1576                                         thrower_p,
1577                                         thrower_p,
1578                                         ECMA_PROPERTY_FIXED,
1579                                         &caller_prop_p);
1580    return caller_prop_p;
1581  }
1582
1583  return NULL;
1584} /* ecma_op_bound_function_try_to_lazy_instantiate_property */
1585
1586/**
1587 * List names of a Function object's lazy instantiated properties,
1588 * adding them to corresponding string collections
1589 *
1590 * See also:
1591 *          ecma_op_function_try_to_lazy_instantiate_property
1592 */
1593void
1594ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functionobject */
1595                                           uint32_t opts, /**< listing options using flags
1596                                                           *   from ecma_list_properties_options_t */
1597                                           ecma_collection_t *main_collection_p, /**< 'main' collection */
1598                                           ecma_collection_t *non_enum_collection_p) /**< skipped
1599                                                                                      *   'non-enumerable'
1600                                                                                      *   collection */
1601{
1602  JERRY_UNUSED (main_collection_p);
1603
1604  ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1605
1606#if ENABLED (JERRY_ES2015)
1607  ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1608  if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1609  {
1610    /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */
1611    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1612  }
1613#else /* !ENABLED (JERRY_ES2015) */
1614  /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1615  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1616#endif /* ENABLED (JERRY_ES2015) */
1617
1618  const ecma_compiled_code_t *bytecode_data_p;
1619  bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1620
1621#if ENABLED (JERRY_ES2015)
1622  if (bytecode_data_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1623  {
1624    return;
1625  }
1626#endif /* ENABLED (JERRY_ES2015) */
1627
1628  /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
1629  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
1630
1631#if ENABLED (JERRY_ES2015)
1632  bool append_caller_and_arguments = !(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE);
1633#else /* !ENABLED (JERRY_ES2015) */
1634  bool append_caller_and_arguments = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE);
1635#endif /* ENABLED (JERRY_ES2015) */
1636
1637  if (append_caller_and_arguments)
1638  {
1639    /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1640    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
1641
1642    /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1643    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
1644  }
1645} /* ecma_op_function_list_lazy_property_names */
1646
1647/**
1648 * List names of an External Function object's lazy instantiated properties,
1649 * adding them to corresponding string collections
1650 *
1651 * See also:
1652 *          ecma_op_external_function_try_to_lazy_instantiate_property
1653 */
1654void
1655ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /**< function object */
1656                                                    uint32_t opts, /**< listing options using flags
1657                                                                    *   from ecma_list_properties_options_t */
1658                                                    ecma_collection_t *main_collection_p, /**< 'main' collection */
1659                                                    ecma_collection_t *non_enum_collection_p) /**< skipped
1660                                                                                               *   collection */
1661{
1662  JERRY_UNUSED (main_collection_p);
1663
1664  ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1665
1666#if !ENABLED (JERRY_ES2015)
1667  JERRY_UNUSED (object_p);
1668#else /* ENABLED (JERRY_ES2015) */
1669  if (!ecma_op_ordinary_object_has_own_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE)))
1670#endif /* !ENABLED (JERRY_ES2015) */
1671  {
1672    /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
1673    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
1674  }
1675} /* ecma_op_external_function_list_lazy_property_names */
1676
1677/**
1678 * List names of a Bound Function object's lazy instantiated properties,
1679 * adding them to corresponding string collections
1680 *
1681 * See also:
1682 *          ecma_op_bound_function_try_to_lazy_instantiate_property
1683 */
1684void
1685ecma_op_bound_function_list_lazy_property_names (ecma_object_t *object_p, /**< bound function object*/
1686                                                 uint32_t opts, /**< listing options using flags
1687                                                                 *   from ecma_list_properties_options_t */
1688                                                 ecma_collection_t *main_collection_p, /**< 'main' collection */
1689                                                 ecma_collection_t *non_enum_collection_p) /**< skipped
1690                                                                                            *   'non-enumerable'
1691                                                                                            *   collection */
1692{
1693  JERRY_UNUSED (main_collection_p);
1694
1695  ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1696
1697#if ENABLED (JERRY_ES2015)
1698  /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */
1699  ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
1700  if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function))
1701  {
1702    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1703  }
1704#else /* !ENABLED (JERRY_ES2015) */
1705  JERRY_UNUSED (object_p);
1706  /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1707  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1708#endif /* ENABLED (JERRY_ES2015) */
1709
1710  /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1711  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
1712
1713  /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1714  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
1715} /* ecma_op_bound_function_list_lazy_property_names */
1716
1717/**
1718 * @}
1719 * @}
1720 */
1721