1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "ecma-alloc.h"
17425bb815Sopenharmony_ci#include "ecma-builtin-helpers.h"
18425bb815Sopenharmony_ci#include "ecma-exceptions.h"
19425bb815Sopenharmony_ci#include "ecma-function-object.h"
20425bb815Sopenharmony_ci#include "ecma-gc.h"
21425bb815Sopenharmony_ci#include "ecma-helpers.h"
22425bb815Sopenharmony_ci#include "lit-char-helpers.h"
23425bb815Sopenharmony_ci#include "ecma-lex-env.h"
24425bb815Sopenharmony_ci#include "ecma-objects.h"
25425bb815Sopenharmony_ci#include "ecma-objects-general.h"
26425bb815Sopenharmony_ci#include "ecma-objects-arguments.h"
27425bb815Sopenharmony_ci#include "ecma-proxy-object.h"
28425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h"
29425bb815Sopenharmony_ci#include "jcontext.h"
30425bb815Sopenharmony_ci
31425bb815Sopenharmony_ci/** \addtogroup ecma ECMA
32425bb815Sopenharmony_ci * @{
33425bb815Sopenharmony_ci *
34425bb815Sopenharmony_ci * \addtogroup ecmafunctionobject ECMA Function object related routines
35425bb815Sopenharmony_ci * @{
36425bb815Sopenharmony_ci */
37425bb815Sopenharmony_ci
38425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
39425bb815Sopenharmony_ci/**
40425bb815Sopenharmony_ci * Get the resource name from the compiled code header
41425bb815Sopenharmony_ci *
42425bb815Sopenharmony_ci * @return resource name as ecma-string
43425bb815Sopenharmony_ci */
44425bb815Sopenharmony_ciecma_value_t
45425bb815Sopenharmony_ciecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p)
46425bb815Sopenharmony_ci{
47425bb815Sopenharmony_ci  JERRY_ASSERT (bytecode_header_p != NULL);
48425bb815Sopenharmony_ci
49425bb815Sopenharmony_ci  uint8_t *byte_p = (uint8_t *) bytecode_header_p;
50425bb815Sopenharmony_ci  byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
51425bb815Sopenharmony_ci
52425bb815Sopenharmony_ci  ecma_value_t *resource_name_p = (ecma_value_t *) byte_p;
53425bb815Sopenharmony_ci  resource_name_p -= ecma_compiled_code_get_formal_params (bytecode_header_p);
54425bb815Sopenharmony_ci
55425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
56425bb815Sopenharmony_ci  if (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
57425bb815Sopenharmony_ci  {
58425bb815Sopenharmony_ci    resource_name_p--;
59425bb815Sopenharmony_ci  }
60425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
61425bb815Sopenharmony_ci
62425bb815Sopenharmony_ci  return resource_name_p[-1];
63425bb815Sopenharmony_ci} /* ecma_op_resource_name */
64425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
65425bb815Sopenharmony_ci
66425bb815Sopenharmony_ci/**
67425bb815Sopenharmony_ci * IsCallable operation.
68425bb815Sopenharmony_ci *
69425bb815Sopenharmony_ci * See also: ECMA-262 v5, 9.11
70425bb815Sopenharmony_ci *
71425bb815Sopenharmony_ci * @return true - if the given object is callable;
72425bb815Sopenharmony_ci *         false - otherwise
73425bb815Sopenharmony_ci */
74425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE
75425bb815Sopenharmony_ciecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
76425bb815Sopenharmony_ci{
77425bb815Sopenharmony_ci  JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
78425bb815Sopenharmony_ci
79425bb815Sopenharmony_ci  const ecma_object_type_t type = ecma_get_object_type (obj_p);
80425bb815Sopenharmony_ci
81425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
82425bb815Sopenharmony_ci  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
83425bb815Sopenharmony_ci  {
84425bb815Sopenharmony_ci    return ecma_op_is_callable (((ecma_proxy_object_t *) obj_p)->target);
85425bb815Sopenharmony_ci  }
86425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
87425bb815Sopenharmony_ci
88425bb815Sopenharmony_ci  return type >= ECMA_OBJECT_TYPE_FUNCTION;
89425bb815Sopenharmony_ci} /* ecma_op_object_is_callable */
90425bb815Sopenharmony_ci
91425bb815Sopenharmony_ci/**
92425bb815Sopenharmony_ci * IsCallable operation.
93425bb815Sopenharmony_ci *
94425bb815Sopenharmony_ci * See also: ECMA-262 v5, 9.11
95425bb815Sopenharmony_ci *
96425bb815Sopenharmony_ci * @return true - if value is callable object;
97425bb815Sopenharmony_ci *         false - otherwise
98425bb815Sopenharmony_ci */
99425bb815Sopenharmony_cibool
100425bb815Sopenharmony_ciecma_op_is_callable (ecma_value_t value) /**< ecma value */
101425bb815Sopenharmony_ci{
102425bb815Sopenharmony_ci  return (ecma_is_value_object (value)
103425bb815Sopenharmony_ci          && ecma_op_object_is_callable (ecma_get_object_from_value (value)));
104425bb815Sopenharmony_ci} /* ecma_op_is_callable */
105425bb815Sopenharmony_ci
106425bb815Sopenharmony_ci/**
107425bb815Sopenharmony_ci * Checks whether the given object implements [[Construct]].
108425bb815Sopenharmony_ci *
109425bb815Sopenharmony_ci * @return true - if the given object is constructor;
110425bb815Sopenharmony_ci *         false - otherwise
111425bb815Sopenharmony_ci */
112425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE
113425bb815Sopenharmony_ciecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
114425bb815Sopenharmony_ci{
115425bb815Sopenharmony_ci  JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
116425bb815Sopenharmony_ci
117425bb815Sopenharmony_ci  ecma_object_type_t type = ecma_get_object_type (obj_p);
118425bb815Sopenharmony_ci
119425bb815Sopenharmony_ci  while (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
120425bb815Sopenharmony_ci  {
121425bb815Sopenharmony_ci    ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) obj_p;
122425bb815Sopenharmony_ci
123425bb815Sopenharmony_ci    obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
124425bb815Sopenharmony_ci                                                        bound_func_p->header.u.bound_function.target_function);
125425bb815Sopenharmony_ci
126425bb815Sopenharmony_ci    type = ecma_get_object_type (obj_p);
127425bb815Sopenharmony_ci  }
128425bb815Sopenharmony_ci
129425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
130425bb815Sopenharmony_ci  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
131425bb815Sopenharmony_ci  {
132425bb815Sopenharmony_ci    return ecma_is_constructor (((ecma_proxy_object_t *) obj_p)->target);
133425bb815Sopenharmony_ci  }
134425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
135425bb815Sopenharmony_ci
136425bb815Sopenharmony_ci  if (type == ECMA_OBJECT_TYPE_FUNCTION)
137425bb815Sopenharmony_ci  {
138425bb815Sopenharmony_ci    return (!ecma_get_object_is_builtin (obj_p) || !ecma_builtin_function_is_routine (obj_p));
139425bb815Sopenharmony_ci  }
140425bb815Sopenharmony_ci
141425bb815Sopenharmony_ci  return (type >= ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
142425bb815Sopenharmony_ci} /* ecma_object_is_constructor */
143425bb815Sopenharmony_ci
144425bb815Sopenharmony_ci/**
145425bb815Sopenharmony_ci * Checks whether the value is Object that implements [[Construct]].
146425bb815Sopenharmony_ci *
147425bb815Sopenharmony_ci * @return true - if value is constructor object;
148425bb815Sopenharmony_ci *         false - otherwise
149425bb815Sopenharmony_ci */
150425bb815Sopenharmony_cibool
151425bb815Sopenharmony_ciecma_is_constructor (ecma_value_t value) /**< ecma value */
152425bb815Sopenharmony_ci{
153425bb815Sopenharmony_ci  return (ecma_is_value_object (value)
154425bb815Sopenharmony_ci          && ecma_object_is_constructor (ecma_get_object_from_value (value)));
155425bb815Sopenharmony_ci} /* ecma_is_constructor */
156425bb815Sopenharmony_ci
157425bb815Sopenharmony_ci/**
158425bb815Sopenharmony_ci * Helper method to count and convert the arguments for the Function/GeneratorFunction constructor call.
159425bb815Sopenharmony_ci *
160425bb815Sopenharmony_ci * See also:
161425bb815Sopenharmony_ci *          ECMA 262 v5.1 15.3.2.1 steps 5.a-d
162425bb815Sopenharmony_ci *          ECMA 262 v6 19.2.1.1.1 steps 8
163425bb815Sopenharmony_ci *
164425bb815Sopenharmony_ci * @return ecma value - concatenated arguments as a string.
165425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
166425bb815Sopenharmony_ci */
167425bb815Sopenharmony_cistatic ecma_string_t *
168425bb815Sopenharmony_ciecma_op_create_dynamic_function_arguments_helper (const ecma_value_t *arguments_list_p, /**< arguments list */
169425bb815Sopenharmony_ci                                                  ecma_length_t arguments_list_len) /**< number of arguments */
170425bb815Sopenharmony_ci{
171425bb815Sopenharmony_ci  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
172425bb815Sopenharmony_ci
173425bb815Sopenharmony_ci  if (arguments_list_len <= 1)
174425bb815Sopenharmony_ci  {
175425bb815Sopenharmony_ci    return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
176425bb815Sopenharmony_ci  }
177425bb815Sopenharmony_ci
178425bb815Sopenharmony_ci  ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]);
179425bb815Sopenharmony_ci
180425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (str_p == NULL))
181425bb815Sopenharmony_ci  {
182425bb815Sopenharmony_ci    return str_p;
183425bb815Sopenharmony_ci  }
184425bb815Sopenharmony_ci
185425bb815Sopenharmony_ci  if (arguments_list_len == 2)
186425bb815Sopenharmony_ci  {
187425bb815Sopenharmony_ci    return str_p;
188425bb815Sopenharmony_ci  }
189425bb815Sopenharmony_ci
190425bb815Sopenharmony_ci  ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (str_p);
191425bb815Sopenharmony_ci  ecma_deref_ecma_string (str_p);
192425bb815Sopenharmony_ci
193425bb815Sopenharmony_ci  for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++)
194425bb815Sopenharmony_ci  {
195425bb815Sopenharmony_ci    str_p = ecma_op_to_string (arguments_list_p[idx]);
196425bb815Sopenharmony_ci
197425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (str_p == NULL))
198425bb815Sopenharmony_ci    {
199425bb815Sopenharmony_ci      ecma_stringbuilder_destroy (&builder);
200425bb815Sopenharmony_ci      return str_p;
201425bb815Sopenharmony_ci    }
202425bb815Sopenharmony_ci
203425bb815Sopenharmony_ci    ecma_stringbuilder_append_char (&builder, LIT_CHAR_COMMA);
204425bb815Sopenharmony_ci    ecma_stringbuilder_append (&builder, str_p);
205425bb815Sopenharmony_ci    ecma_deref_ecma_string (str_p);
206425bb815Sopenharmony_ci  }
207425bb815Sopenharmony_ci
208425bb815Sopenharmony_ci  return ecma_stringbuilder_finalize (&builder);
209425bb815Sopenharmony_ci} /* ecma_op_create_dynamic_function_arguments_helper */
210425bb815Sopenharmony_ci
211425bb815Sopenharmony_ci/**
212425bb815Sopenharmony_ci * Function object creation operation.
213425bb815Sopenharmony_ci *
214425bb815Sopenharmony_ci * See also: ECMA-262 v5, 13.2
215425bb815Sopenharmony_ci *
216425bb815Sopenharmony_ci * @return pointer to newly created Function object
217425bb815Sopenharmony_ci */
218425bb815Sopenharmony_cistatic ecma_object_t *
219425bb815Sopenharmony_ciecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
220425bb815Sopenharmony_ci                                const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
221425bb815Sopenharmony_ci                                ecma_builtin_id_t proto_id) /**< builtin id of the prototype object */
222425bb815Sopenharmony_ci{
223425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_lexical_environment (scope_p));
224425bb815Sopenharmony_ci
225425bb815Sopenharmony_ci  /* 1., 4., 13. */
226425bb815Sopenharmony_ci  ecma_object_t *prototype_obj_p = ecma_builtin_get (proto_id);
227425bb815Sopenharmony_ci
228425bb815Sopenharmony_ci  size_t function_object_size = sizeof (ecma_extended_object_t);
229425bb815Sopenharmony_ci
230425bb815Sopenharmony_ci#if ENABLED (JERRY_SNAPSHOT_EXEC)
231425bb815Sopenharmony_ci  if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
232425bb815Sopenharmony_ci  {
233425bb815Sopenharmony_ci    function_object_size = sizeof (ecma_static_function_t);
234425bb815Sopenharmony_ci  }
235425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
236425bb815Sopenharmony_ci
237425bb815Sopenharmony_ci  ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
238425bb815Sopenharmony_ci                                              function_object_size,
239425bb815Sopenharmony_ci                                              ECMA_OBJECT_TYPE_FUNCTION);
240425bb815Sopenharmony_ci
241425bb815Sopenharmony_ci  /* 2., 6., 7., 8. */
242425bb815Sopenharmony_ci  /*
243425bb815Sopenharmony_ci   * We don't setup [[Get]], [[Call]], [[Construct]], [[HasInstance]] for each function object.
244425bb815Sopenharmony_ci   * Instead we set the object's type to ECMA_OBJECT_TYPE_FUNCTION
245425bb815Sopenharmony_ci   * that defines which version of the routine should be used on demand.
246425bb815Sopenharmony_ci   */
247425bb815Sopenharmony_ci
248425bb815Sopenharmony_ci  /* 3. */
249425bb815Sopenharmony_ci  /*
250425bb815Sopenharmony_ci   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
251425bb815Sopenharmony_ci   *
252425bb815Sopenharmony_ci   * See also: ecma_object_get_class_name
253425bb815Sopenharmony_ci   */
254425bb815Sopenharmony_ci
255425bb815Sopenharmony_ci  ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p;
256425bb815Sopenharmony_ci
257425bb815Sopenharmony_ci  /* 9. */
258425bb815Sopenharmony_ci  ECMA_SET_NON_NULL_POINTER_TAG (ext_func_p->u.function.scope_cp, scope_p, 0);
259425bb815Sopenharmony_ci
260425bb815Sopenharmony_ci  /* 10., 11., 12. */
261425bb815Sopenharmony_ci
262425bb815Sopenharmony_ci#if ENABLED (JERRY_SNAPSHOT_EXEC)
263425bb815Sopenharmony_ci  if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
264425bb815Sopenharmony_ci  {
265425bb815Sopenharmony_ci    ext_func_p->u.function.bytecode_cp = ECMA_NULL_POINTER;
266425bb815Sopenharmony_ci    ((ecma_static_function_t *) func_p)->bytecode_p = bytecode_data_p;
267425bb815Sopenharmony_ci  }
268425bb815Sopenharmony_ci  else
269425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
270425bb815Sopenharmony_ci  {
271425bb815Sopenharmony_ci    ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
272425bb815Sopenharmony_ci    ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
273425bb815Sopenharmony_ci  }
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci  /* 14., 15., 16., 17., 18. */
276425bb815Sopenharmony_ci  /*
277425bb815Sopenharmony_ci   * 'length' and 'prototype' properties are instantiated lazily
278425bb815Sopenharmony_ci   *
279425bb815Sopenharmony_ci   * See also: ecma_op_function_try_to_lazy_instantiate_property
280425bb815Sopenharmony_ci   */
281425bb815Sopenharmony_ci
282425bb815Sopenharmony_ci  return func_p;
283425bb815Sopenharmony_ci} /* ecma_op_create_function_object */
284425bb815Sopenharmony_ci
285425bb815Sopenharmony_ci/**
286425bb815Sopenharmony_ci * CreateDynamicFunction operation
287425bb815Sopenharmony_ci *
288425bb815Sopenharmony_ci * See also:
289425bb815Sopenharmony_ci *          ECMA-262 v5, 15.3.
290425bb815Sopenharmony_ci *          ECMA-262 v6, 19.2.1.1
291425bb815Sopenharmony_ci *
292425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
293425bb815Sopenharmony_ci *         constructed function object - otherwise
294425bb815Sopenharmony_ci */
295425bb815Sopenharmony_ciecma_value_t
296425bb815Sopenharmony_ciecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< arguments list */
297425bb815Sopenharmony_ci                                 ecma_length_t arguments_list_len, /**< number of arguments */
298425bb815Sopenharmony_ci                                 ecma_parse_opts_t parse_opts) /**< parse options */
299425bb815Sopenharmony_ci{
300425bb815Sopenharmony_ci  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
301425bb815Sopenharmony_ci
302425bb815Sopenharmony_ci  ecma_string_t *arguments_str_p = ecma_op_create_dynamic_function_arguments_helper (arguments_list_p,
303425bb815Sopenharmony_ci                                                                                     arguments_list_len);
304425bb815Sopenharmony_ci
305425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (arguments_str_p == NULL))
306425bb815Sopenharmony_ci  {
307425bb815Sopenharmony_ci    return ECMA_VALUE_ERROR;
308425bb815Sopenharmony_ci  }
309425bb815Sopenharmony_ci
310425bb815Sopenharmony_ci  ecma_string_t *function_body_str_p;
311425bb815Sopenharmony_ci
312425bb815Sopenharmony_ci  if (arguments_list_len > 0)
313425bb815Sopenharmony_ci  {
314425bb815Sopenharmony_ci    function_body_str_p = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]);
315425bb815Sopenharmony_ci
316425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (function_body_str_p == NULL))
317425bb815Sopenharmony_ci    {
318425bb815Sopenharmony_ci      ecma_deref_ecma_string (arguments_str_p);
319425bb815Sopenharmony_ci      return ECMA_VALUE_ERROR;
320425bb815Sopenharmony_ci    }
321425bb815Sopenharmony_ci  }
322425bb815Sopenharmony_ci  else
323425bb815Sopenharmony_ci  {
324425bb815Sopenharmony_ci    /* Very unlikely code path, not optimized. */
325425bb815Sopenharmony_ci    function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
326425bb815Sopenharmony_ci  }
327425bb815Sopenharmony_ci
328425bb815Sopenharmony_ci  ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
329425bb815Sopenharmony_ci  ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
330425bb815Sopenharmony_ci
331425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
332425bb815Sopenharmony_ci  JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
333425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
334425bb815Sopenharmony_ci
335425bb815Sopenharmony_ci  ecma_compiled_code_t *bytecode_data_p = NULL;
336425bb815Sopenharmony_ci
337425bb815Sopenharmony_ci  ecma_value_t ret_value = parser_parse_script (arguments_buffer_p,
338425bb815Sopenharmony_ci                                                arguments_buffer_size,
339425bb815Sopenharmony_ci                                                function_body_buffer_p,
340425bb815Sopenharmony_ci                                                function_body_buffer_size,
341425bb815Sopenharmony_ci                                                parse_opts,
342425bb815Sopenharmony_ci                                                &bytecode_data_p);
343425bb815Sopenharmony_ci
344425bb815Sopenharmony_ci  if (!ECMA_IS_VALUE_ERROR (ret_value))
345425bb815Sopenharmony_ci  {
346425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_is_value_true (ret_value));
347425bb815Sopenharmony_ci
348425bb815Sopenharmony_ci    ecma_object_t *global_env_p = ecma_get_global_environment ();
349425bb815Sopenharmony_ci    ecma_builtin_id_t fallback_proto = ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE;
350425bb815Sopenharmony_ci
351425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
352425bb815Sopenharmony_ci    ecma_object_t *new_target_p = JERRY_CONTEXT (current_new_target);
353425bb815Sopenharmony_ci    bool is_generator_func = parse_opts & ECMA_PARSE_GENERATOR_FUNCTION;
354425bb815Sopenharmony_ci
355425bb815Sopenharmony_ci    if (is_generator_func)
356425bb815Sopenharmony_ci    {
357425bb815Sopenharmony_ci      fallback_proto = ECMA_BUILTIN_ID_GENERATOR;
358425bb815Sopenharmony_ci    }
359425bb815Sopenharmony_ci
360425bb815Sopenharmony_ci    if (new_target_p == NULL)
361425bb815Sopenharmony_ci    {
362425bb815Sopenharmony_ci      if (is_generator_func)
363425bb815Sopenharmony_ci      {
364425bb815Sopenharmony_ci        new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_FUNCTION);
365425bb815Sopenharmony_ci      }
366425bb815Sopenharmony_ci      else
367425bb815Sopenharmony_ci      {
368425bb815Sopenharmony_ci        new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION);
369425bb815Sopenharmony_ci      }
370425bb815Sopenharmony_ci    }
371425bb815Sopenharmony_ci
372425bb815Sopenharmony_ci    ecma_object_t *proto = ecma_op_get_prototype_from_constructor (new_target_p, fallback_proto);
373425bb815Sopenharmony_ci
374425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (proto == NULL))
375425bb815Sopenharmony_ci    {
376425bb815Sopenharmony_ci      ecma_bytecode_deref (bytecode_data_p);
377425bb815Sopenharmony_ci      ecma_deref_ecma_string (arguments_str_p);
378425bb815Sopenharmony_ci      ecma_deref_ecma_string (function_body_str_p);
379425bb815Sopenharmony_ci      return ECMA_VALUE_ERROR;
380425bb815Sopenharmony_ci    }
381425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
382425bb815Sopenharmony_ci
383425bb815Sopenharmony_ci    ecma_object_t *func_obj_p = ecma_op_create_function_object (global_env_p, bytecode_data_p, fallback_proto);
384425bb815Sopenharmony_ci
385425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
386425bb815Sopenharmony_ci    ECMA_SET_NON_NULL_POINTER (func_obj_p->u2.prototype_cp, proto);
387425bb815Sopenharmony_ci    ecma_deref_object (proto);
388425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
389425bb815Sopenharmony_ci
390425bb815Sopenharmony_ci    ecma_bytecode_deref (bytecode_data_p);
391425bb815Sopenharmony_ci    ret_value = ecma_make_object_value (func_obj_p);
392425bb815Sopenharmony_ci  }
393425bb815Sopenharmony_ci
394425bb815Sopenharmony_ci  ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
395425bb815Sopenharmony_ci  ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
396425bb815Sopenharmony_ci
397425bb815Sopenharmony_ci  ecma_deref_ecma_string (arguments_str_p);
398425bb815Sopenharmony_ci  ecma_deref_ecma_string (function_body_str_p);
399425bb815Sopenharmony_ci
400425bb815Sopenharmony_ci  return ret_value;
401425bb815Sopenharmony_ci} /* ecma_op_create_dynamic_function */
402425bb815Sopenharmony_ci
403425bb815Sopenharmony_ci/**
404425bb815Sopenharmony_ci * Function object creation operation.
405425bb815Sopenharmony_ci *
406425bb815Sopenharmony_ci * See also: ECMA-262 v5, 13.2
407425bb815Sopenharmony_ci *
408425bb815Sopenharmony_ci * @return pointer to newly created Function object
409425bb815Sopenharmony_ci */
410425bb815Sopenharmony_ciecma_object_t *
411425bb815Sopenharmony_ciecma_op_create_simple_function_object (ecma_object_t *scope_p, /**< function's scope */
412425bb815Sopenharmony_ci                                       const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
413425bb815Sopenharmony_ci{
414425bb815Sopenharmony_ci  return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
415425bb815Sopenharmony_ci} /* ecma_op_create_simple_function_object */
416425bb815Sopenharmony_ci
417425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
418425bb815Sopenharmony_ci
419425bb815Sopenharmony_ci/**
420425bb815Sopenharmony_ci * GeneratorFunction object creation operation.
421425bb815Sopenharmony_ci *
422425bb815Sopenharmony_ci * See also: ECMA-262 v5, 13.2
423425bb815Sopenharmony_ci *
424425bb815Sopenharmony_ci * @return pointer to newly created Function object
425425bb815Sopenharmony_ci */
426425bb815Sopenharmony_ciecma_object_t *
427425bb815Sopenharmony_ciecma_op_create_generator_function_object (ecma_object_t *scope_p, /**< function's scope */
428425bb815Sopenharmony_ci                                          const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
429425bb815Sopenharmony_ci{
430425bb815Sopenharmony_ci  return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_GENERATOR);
431425bb815Sopenharmony_ci} /* ecma_op_create_generator_function_object */
432425bb815Sopenharmony_ci
433425bb815Sopenharmony_ci/**
434425bb815Sopenharmony_ci * Arrow function object creation operation.
435425bb815Sopenharmony_ci *
436425bb815Sopenharmony_ci * See also: ES2015, 9.2.12
437425bb815Sopenharmony_ci *
438425bb815Sopenharmony_ci * @return pointer to newly created Function object
439425bb815Sopenharmony_ci */
440425bb815Sopenharmony_ciecma_object_t *
441425bb815Sopenharmony_ciecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's scope */
442425bb815Sopenharmony_ci                                      const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
443425bb815Sopenharmony_ci                                      ecma_value_t this_binding) /**< value of 'this' binding */
444425bb815Sopenharmony_ci{
445425bb815Sopenharmony_ci  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
446425bb815Sopenharmony_ci
447425bb815Sopenharmony_ci  size_t arrow_function_object_size = sizeof (ecma_arrow_function_t);
448425bb815Sopenharmony_ci
449425bb815Sopenharmony_ci#if ENABLED (JERRY_SNAPSHOT_EXEC)
450425bb815Sopenharmony_ci  if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
451425bb815Sopenharmony_ci  {
452425bb815Sopenharmony_ci    arrow_function_object_size = sizeof (ecma_static_arrow_function_t);
453425bb815Sopenharmony_ci  }
454425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
455425bb815Sopenharmony_ci
456425bb815Sopenharmony_ci  ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
457425bb815Sopenharmony_ci                                              arrow_function_object_size,
458425bb815Sopenharmony_ci                                              ECMA_OBJECT_TYPE_FUNCTION);
459425bb815Sopenharmony_ci
460425bb815Sopenharmony_ci  ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_p;
461425bb815Sopenharmony_ci
462425bb815Sopenharmony_ci  ECMA_SET_NON_NULL_POINTER_TAG (arrow_func_p->header.u.function.scope_cp, scope_p, 0);
463425bb815Sopenharmony_ci
464425bb815Sopenharmony_ci#if ENABLED (JERRY_SNAPSHOT_EXEC)
465425bb815Sopenharmony_ci  if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
466425bb815Sopenharmony_ci  {
467425bb815Sopenharmony_ci    arrow_func_p->header.u.function.bytecode_cp = ECMA_NULL_POINTER;
468425bb815Sopenharmony_ci    ((ecma_static_arrow_function_t *) func_p)->bytecode_p = bytecode_data_p;
469425bb815Sopenharmony_ci  }
470425bb815Sopenharmony_ci  else
471425bb815Sopenharmony_ci  {
472425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
473425bb815Sopenharmony_ci    ECMA_SET_INTERNAL_VALUE_POINTER (arrow_func_p->header.u.function.bytecode_cp, bytecode_data_p);
474425bb815Sopenharmony_ci    ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
475425bb815Sopenharmony_ci#if ENABLED (JERRY_SNAPSHOT_EXEC)
476425bb815Sopenharmony_ci  }
477425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
478425bb815Sopenharmony_ci
479425bb815Sopenharmony_ci  arrow_func_p->this_binding = ecma_copy_value_if_not_object (this_binding);
480425bb815Sopenharmony_ci  arrow_func_p->new_target = ECMA_VALUE_UNDEFINED;
481425bb815Sopenharmony_ci
482425bb815Sopenharmony_ci  if (JERRY_CONTEXT (current_new_target) != NULL)
483425bb815Sopenharmony_ci  {
484425bb815Sopenharmony_ci    arrow_func_p->new_target = ecma_make_object_value (JERRY_CONTEXT (current_new_target));
485425bb815Sopenharmony_ci  }
486425bb815Sopenharmony_ci  return func_p;
487425bb815Sopenharmony_ci} /* ecma_op_create_arrow_function_object */
488425bb815Sopenharmony_ci
489425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
490425bb815Sopenharmony_ci
491425bb815Sopenharmony_ci/**
492425bb815Sopenharmony_ci * External function object creation operation.
493425bb815Sopenharmony_ci *
494425bb815Sopenharmony_ci * Note:
495425bb815Sopenharmony_ci *      external function object is implementation-defined object type
496425bb815Sopenharmony_ci *      that represent functions implemented in native code, using Embedding API
497425bb815Sopenharmony_ci *
498425bb815Sopenharmony_ci * @return pointer to newly created external function object
499425bb815Sopenharmony_ci */
500425bb815Sopenharmony_ciecma_object_t *
501425bb815Sopenharmony_ciecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**< pointer to external native handler */
502425bb815Sopenharmony_ci{
503425bb815Sopenharmony_ci  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
504425bb815Sopenharmony_ci
505425bb815Sopenharmony_ci  ecma_object_t *function_obj_p;
506425bb815Sopenharmony_ci  function_obj_p = ecma_create_object (prototype_obj_p,
507425bb815Sopenharmony_ci                                       sizeof (ecma_extended_object_t),
508425bb815Sopenharmony_ci                                       ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
509425bb815Sopenharmony_ci
510425bb815Sopenharmony_ci  /*
511425bb815Sopenharmony_ci   * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
512425bb815Sopenharmony_ci   *
513425bb815Sopenharmony_ci   * See also: ecma_object_get_class_name
514425bb815Sopenharmony_ci   */
515425bb815Sopenharmony_ci
516425bb815Sopenharmony_ci  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
517425bb815Sopenharmony_ci  ext_func_obj_p->u.external_handler_cb = handler_cb;
518425bb815Sopenharmony_ci
519425bb815Sopenharmony_ci  return function_obj_p;
520425bb815Sopenharmony_ci} /* ecma_op_create_external_function_object */
521425bb815Sopenharmony_ci
522425bb815Sopenharmony_ci/**
523425bb815Sopenharmony_ci * Get compiled code of a function object.
524425bb815Sopenharmony_ci *
525425bb815Sopenharmony_ci * @return compiled code
526425bb815Sopenharmony_ci */
527425bb815Sopenharmony_ciinline const ecma_compiled_code_t * JERRY_ATTR_ALWAYS_INLINE
528425bb815Sopenharmony_ciecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< function pointer */
529425bb815Sopenharmony_ci{
530425bb815Sopenharmony_ci#if ENABLED (JERRY_SNAPSHOT_EXEC)
531425bb815Sopenharmony_ci  if (function_p->u.function.bytecode_cp != ECMA_NULL_POINTER)
532425bb815Sopenharmony_ci  {
533425bb815Sopenharmony_ci    return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
534425bb815Sopenharmony_ci                                            function_p->u.function.bytecode_cp);
535425bb815Sopenharmony_ci  }
536425bb815Sopenharmony_ci  else
537425bb815Sopenharmony_ci  {
538425bb815Sopenharmony_ci    return ((ecma_static_function_t *) function_p)->bytecode_p;
539425bb815Sopenharmony_ci  }
540425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_SNAPSHOT_EXEC) */
541425bb815Sopenharmony_ci  return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
542425bb815Sopenharmony_ci                                          function_p->u.function.bytecode_cp);
543425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
544425bb815Sopenharmony_ci} /* ecma_op_function_get_compiled_code */
545425bb815Sopenharmony_ci
546425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
547425bb815Sopenharmony_ci/**
548425bb815Sopenharmony_ci * Check whether the given object [[FunctionKind]] internal slot value is "generator".
549425bb815Sopenharmony_ci *
550425bb815Sopenharmony_ci * @return true - if the given object is a generator function
551425bb815Sopenharmony_ci *         false - otherwise
552425bb815Sopenharmony_ci */
553425bb815Sopenharmony_cibool
554425bb815Sopenharmony_ciecma_op_function_is_generator (ecma_object_t *obj_p) /**< object */
555425bb815Sopenharmony_ci{
556425bb815Sopenharmony_ci  if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
557425bb815Sopenharmony_ci      && !ecma_get_object_is_builtin (obj_p))
558425bb815Sopenharmony_ci  {
559425bb815Sopenharmony_ci    ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) obj_p;
560425bb815Sopenharmony_ci    const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
561425bb815Sopenharmony_ci
562425bb815Sopenharmony_ci    return (bytecode_data_p->status_flags & CBC_CODE_FLAGS_GENERATOR) != 0;
563425bb815Sopenharmony_ci  }
564425bb815Sopenharmony_ci
565425bb815Sopenharmony_ci  return false;
566425bb815Sopenharmony_ci} /* ecma_op_function_is_generator */
567425bb815Sopenharmony_ci
568425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
569425bb815Sopenharmony_ci
570425bb815Sopenharmony_ci/**
571425bb815Sopenharmony_ci * 15.3.5.3 implementation of [[HasInstance]] for Function objects
572425bb815Sopenharmony_ci *
573425bb815Sopenharmony_ci * @return true/false - if arguments are valid
574425bb815Sopenharmony_ci *         error - otherwise
575425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
576425bb815Sopenharmony_ci */
577425bb815Sopenharmony_ciecma_value_t
578425bb815Sopenharmony_ciecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object */
579425bb815Sopenharmony_ci                               ecma_value_t value) /**< argument 'V' */
580425bb815Sopenharmony_ci{
581425bb815Sopenharmony_ci  JERRY_ASSERT (func_obj_p != NULL
582425bb815Sopenharmony_ci                && !ecma_is_lexical_environment (func_obj_p));
583425bb815Sopenharmony_ci
584425bb815Sopenharmony_ci  if (!ecma_is_value_object (value))
585425bb815Sopenharmony_ci  {
586425bb815Sopenharmony_ci    return ECMA_VALUE_FALSE;
587425bb815Sopenharmony_ci  }
588425bb815Sopenharmony_ci
589425bb815Sopenharmony_ci  while (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
590425bb815Sopenharmony_ci  {
591425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
592425bb815Sopenharmony_ci
593425bb815Sopenharmony_ci    /* 1. 3. */
594425bb815Sopenharmony_ci    ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
595425bb815Sopenharmony_ci
596425bb815Sopenharmony_ci    func_obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
597425bb815Sopenharmony_ci                                                             bound_func_p->header.u.bound_function.target_function);
598425bb815Sopenharmony_ci  }
599425bb815Sopenharmony_ci
600425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
601425bb815Sopenharmony_ci                || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
602425bb815Sopenharmony_ci                || ECMA_OBJECT_IS_PROXY (func_obj_p));
603425bb815Sopenharmony_ci
604425bb815Sopenharmony_ci  ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
605425bb815Sopenharmony_ci
606425bb815Sopenharmony_ci  ecma_value_t prototype_obj_value = ecma_op_object_get_by_magic_id (func_obj_p,
607425bb815Sopenharmony_ci                                                                     LIT_MAGIC_STRING_PROTOTYPE);
608425bb815Sopenharmony_ci
609425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (prototype_obj_value))
610425bb815Sopenharmony_ci  {
611425bb815Sopenharmony_ci    return prototype_obj_value;
612425bb815Sopenharmony_ci  }
613425bb815Sopenharmony_ci
614425bb815Sopenharmony_ci  if (!ecma_is_value_object (prototype_obj_value))
615425bb815Sopenharmony_ci  {
616425bb815Sopenharmony_ci    ecma_free_value (prototype_obj_value);
617425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Object expected."));
618425bb815Sopenharmony_ci  }
619425bb815Sopenharmony_ci
620425bb815Sopenharmony_ci  ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
621425bb815Sopenharmony_ci  JERRY_ASSERT (prototype_obj_p != NULL);
622425bb815Sopenharmony_ci
623425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
624425bb815Sopenharmony_ci  ecma_value_t result = ECMA_VALUE_ERROR;
625425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
626425bb815Sopenharmony_ci  ecma_value_t result = ECMA_VALUE_FALSE;
627425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
628425bb815Sopenharmony_ci
629425bb815Sopenharmony_ci  while (true)
630425bb815Sopenharmony_ci  {
631425bb815Sopenharmony_ci    jmem_cpointer_t v_obj_cp;
632425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
633425bb815Sopenharmony_ci    if (ECMA_OBJECT_IS_PROXY (v_obj_p))
634425bb815Sopenharmony_ci    {
635425bb815Sopenharmony_ci      ecma_value_t parent = ecma_proxy_object_get_prototype_of (v_obj_p);
636425bb815Sopenharmony_ci
637425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (parent))
638425bb815Sopenharmony_ci      {
639425bb815Sopenharmony_ci        break;
640425bb815Sopenharmony_ci      }
641425bb815Sopenharmony_ci
642425bb815Sopenharmony_ci      v_obj_cp = ecma_proxy_object_prototype_to_cp (parent);
643425bb815Sopenharmony_ci    }
644425bb815Sopenharmony_ci    else
645425bb815Sopenharmony_ci    {
646425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
647425bb815Sopenharmony_ci      v_obj_cp = ecma_op_ordinary_object_get_prototype_of (v_obj_p);
648425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
649425bb815Sopenharmony_ci    }
650425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
651425bb815Sopenharmony_ci
652425bb815Sopenharmony_ci    if (v_obj_cp == JMEM_CP_NULL)
653425bb815Sopenharmony_ci    {
654425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
655425bb815Sopenharmony_ci      result = ECMA_VALUE_FALSE;
656425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
657425bb815Sopenharmony_ci      break;
658425bb815Sopenharmony_ci    }
659425bb815Sopenharmony_ci
660425bb815Sopenharmony_ci    v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp);
661425bb815Sopenharmony_ci
662425bb815Sopenharmony_ci    if (v_obj_p == prototype_obj_p)
663425bb815Sopenharmony_ci    {
664425bb815Sopenharmony_ci      result = ECMA_VALUE_TRUE;
665425bb815Sopenharmony_ci      break;
666425bb815Sopenharmony_ci    }
667425bb815Sopenharmony_ci  }
668425bb815Sopenharmony_ci
669425bb815Sopenharmony_ci  ecma_deref_object (prototype_obj_p);
670425bb815Sopenharmony_ci  return result;
671425bb815Sopenharmony_ci} /* ecma_op_function_has_instance */
672425bb815Sopenharmony_ci
673425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
674425bb815Sopenharmony_ci
675425bb815Sopenharmony_ci/**
676425bb815Sopenharmony_ci * GetSuperConstructor operation for class methods
677425bb815Sopenharmony_ci *
678425bb815Sopenharmony_ci * See also: ECMAScript v6, 12.3.5.2
679425bb815Sopenharmony_ci *
680425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
681425bb815Sopenharmony_ci *         super constructor - otherwise
682425bb815Sopenharmony_ci */
683425bb815Sopenharmony_ciecma_value_t
684425bb815Sopenharmony_ciecma_op_function_get_super_constructor (ecma_object_t *func_obj_p) /**< function object */
685425bb815Sopenharmony_ci{
686425bb815Sopenharmony_ci  ecma_object_t *super_ctor_p;
687425bb815Sopenharmony_ci
688425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
689425bb815Sopenharmony_ci  if (ECMA_OBJECT_IS_PROXY (func_obj_p))
690425bb815Sopenharmony_ci  {
691425bb815Sopenharmony_ci    ecma_value_t super_ctor = ecma_proxy_object_get_prototype_of (func_obj_p);
692425bb815Sopenharmony_ci
693425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (super_ctor))
694425bb815Sopenharmony_ci    {
695425bb815Sopenharmony_ci      return super_ctor;
696425bb815Sopenharmony_ci    }
697425bb815Sopenharmony_ci
698425bb815Sopenharmony_ci    super_ctor_p = ecma_is_value_null (super_ctor) ? NULL : ecma_get_object_from_value (super_ctor);
699425bb815Sopenharmony_ci  }
700425bb815Sopenharmony_ci  else
701425bb815Sopenharmony_ci  {
702425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
703425bb815Sopenharmony_ci    jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (func_obj_p);
704425bb815Sopenharmony_ci    if (proto_cp == JMEM_CP_NULL)
705425bb815Sopenharmony_ci    {
706425bb815Sopenharmony_ci      super_ctor_p = NULL;
707425bb815Sopenharmony_ci    }
708425bb815Sopenharmony_ci    else
709425bb815Sopenharmony_ci    {
710425bb815Sopenharmony_ci      super_ctor_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
711425bb815Sopenharmony_ci      ecma_ref_object (super_ctor_p);
712425bb815Sopenharmony_ci    }
713425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
714425bb815Sopenharmony_ci  }
715425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
716425bb815Sopenharmony_ci
717425bb815Sopenharmony_ci  if (super_ctor_p == NULL || !ecma_object_is_constructor (super_ctor_p))
718425bb815Sopenharmony_ci  {
719425bb815Sopenharmony_ci    if (super_ctor_p != NULL)
720425bb815Sopenharmony_ci    {
721425bb815Sopenharmony_ci      ecma_deref_object (super_ctor_p);
722425bb815Sopenharmony_ci    }
723425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Super binding must be a constructor."));
724425bb815Sopenharmony_ci  }
725425bb815Sopenharmony_ci
726425bb815Sopenharmony_ci  return ecma_make_object_value (super_ctor_p);
727425bb815Sopenharmony_ci} /* ecma_op_function_get_super_constructor */
728425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
729425bb815Sopenharmony_ci
730425bb815Sopenharmony_ci/**
731425bb815Sopenharmony_ci * Ordinary internal method: GetPrototypeFromConstructor (constructor, intrinsicDefaultProto)
732425bb815Sopenharmony_ci *
733425bb815Sopenharmony_ci * See also: ECMAScript v6, 9.1.15
734425bb815Sopenharmony_ci *
735425bb815Sopenharmony_ci * @return NULL - if the operation fail (exception on the global context is raised)
736425bb815Sopenharmony_ci *         pointer to the prototype object - otherwise
737425bb815Sopenharmony_ci */
738425bb815Sopenharmony_ciecma_object_t *
739425bb815Sopenharmony_ciecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< constructor to get prototype from  */
740425bb815Sopenharmony_ci                                        ecma_builtin_id_t default_proto_id) /**< intrinsicDefaultProto */
741425bb815Sopenharmony_ci{
742425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_object_is_constructor (ctor_obj_p));
743425bb815Sopenharmony_ci  JERRY_ASSERT (default_proto_id < ECMA_BUILTIN_ID__COUNT);
744425bb815Sopenharmony_ci
745425bb815Sopenharmony_ci  ecma_value_t proto = ecma_op_object_get_by_magic_id (ctor_obj_p, LIT_MAGIC_STRING_PROTOTYPE);
746425bb815Sopenharmony_ci
747425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (proto))
748425bb815Sopenharmony_ci  {
749425bb815Sopenharmony_ci    return NULL;
750425bb815Sopenharmony_ci  }
751425bb815Sopenharmony_ci
752425bb815Sopenharmony_ci  ecma_object_t *proto_obj_p;
753425bb815Sopenharmony_ci
754425bb815Sopenharmony_ci  if (!ecma_is_value_object (proto))
755425bb815Sopenharmony_ci  {
756425bb815Sopenharmony_ci    ecma_free_value (proto);
757425bb815Sopenharmony_ci    proto_obj_p = ecma_builtin_get (default_proto_id);
758425bb815Sopenharmony_ci    ecma_ref_object (proto_obj_p);
759425bb815Sopenharmony_ci  }
760425bb815Sopenharmony_ci  else
761425bb815Sopenharmony_ci  {
762425bb815Sopenharmony_ci    proto_obj_p = ecma_get_object_from_value (proto);
763425bb815Sopenharmony_ci  }
764425bb815Sopenharmony_ci
765425bb815Sopenharmony_ci  return proto_obj_p;
766425bb815Sopenharmony_ci} /* ecma_op_get_prototype_from_constructor */
767425bb815Sopenharmony_ci
768425bb815Sopenharmony_ci/**
769425bb815Sopenharmony_ci * Perform a JavaScript function object method call.
770425bb815Sopenharmony_ci *
771425bb815Sopenharmony_ci * The input function object should be a pure JavaScript method
772425bb815Sopenharmony_ci *
773425bb815Sopenharmony_ci * @return the result of the function call.
774425bb815Sopenharmony_ci */
775425bb815Sopenharmony_cistatic ecma_value_t
776425bb815Sopenharmony_ciecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
777425bb815Sopenharmony_ci                              ecma_value_t this_arg_value, /**< 'this' argument's value */
778425bb815Sopenharmony_ci                              const ecma_value_t *arguments_list_p, /**< arguments list */
779425bb815Sopenharmony_ci                              ecma_length_t arguments_list_len) /**< length of arguments list */
780425bb815Sopenharmony_ci{
781425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
782425bb815Sopenharmony_ci
783425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
784425bb815Sopenharmony_ci  {
785425bb815Sopenharmony_ci    return ecma_builtin_dispatch_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
786425bb815Sopenharmony_ci  }
787425bb815Sopenharmony_ci
788425bb815Sopenharmony_ci  /* Entering Function Code (ECMA-262 v5, 10.4.3) */
789425bb815Sopenharmony_ci  ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
790425bb815Sopenharmony_ci
791425bb815Sopenharmony_ci  ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
792425bb815Sopenharmony_ci                                                                       ext_func_p->u.function.scope_cp);
793425bb815Sopenharmony_ci
794425bb815Sopenharmony_ci  /* 8. */
795425bb815Sopenharmony_ci  ecma_value_t this_binding = this_arg_value;
796425bb815Sopenharmony_ci  bool free_this_binding = false;
797425bb815Sopenharmony_ci
798425bb815Sopenharmony_ci  const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
799425bb815Sopenharmony_ci  uint16_t status_flags = bytecode_data_p->status_flags;
800425bb815Sopenharmony_ci
801425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
802425bb815Sopenharmony_ci  bool is_construct_call = JERRY_CONTEXT (current_new_target) != NULL;
803425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (status_flags & (CBC_CODE_FLAGS_CLASS_CONSTRUCTOR | CBC_CODE_FLAGS_GENERATOR)))
804425bb815Sopenharmony_ci  {
805425bb815Sopenharmony_ci    if (!is_construct_call && (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
806425bb815Sopenharmony_ci    {
807425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
808425bb815Sopenharmony_ci    }
809425bb815Sopenharmony_ci
810425bb815Sopenharmony_ci    if ((status_flags & CBC_CODE_FLAGS_GENERATOR) && is_construct_call)
811425bb815Sopenharmony_ci    {
812425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'."));
813425bb815Sopenharmony_ci    }
814425bb815Sopenharmony_ci  }
815425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
816425bb815Sopenharmony_ci
817425bb815Sopenharmony_ci  /* 1. */
818425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
819425bb815Sopenharmony_ci  ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
820425bb815Sopenharmony_ci
821425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
822425bb815Sopenharmony_ci  {
823425bb815Sopenharmony_ci    ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
824425bb815Sopenharmony_ci
825425bb815Sopenharmony_ci    if (ecma_is_value_undefined (arrow_func_p->new_target))
826425bb815Sopenharmony_ci    {
827425bb815Sopenharmony_ci      JERRY_CONTEXT (current_new_target) = NULL;
828425bb815Sopenharmony_ci    }
829425bb815Sopenharmony_ci    else
830425bb815Sopenharmony_ci    {
831425bb815Sopenharmony_ci      JERRY_CONTEXT (current_new_target) = ecma_get_object_from_value (arrow_func_p->new_target);
832425bb815Sopenharmony_ci    }
833425bb815Sopenharmony_ci    this_binding = arrow_func_p->this_binding;
834425bb815Sopenharmony_ci  }
835425bb815Sopenharmony_ci  else
836425bb815Sopenharmony_ci  {
837425bb815Sopenharmony_ci    JERRY_CONTEXT (current_function_obj_p) = func_obj_p;
838425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
839425bb815Sopenharmony_ci    if (!(status_flags & CBC_CODE_FLAGS_STRICT_MODE))
840425bb815Sopenharmony_ci    {
841425bb815Sopenharmony_ci      if (ecma_is_value_undefined (this_binding)
842425bb815Sopenharmony_ci          || ecma_is_value_null (this_binding))
843425bb815Sopenharmony_ci      {
844425bb815Sopenharmony_ci        /* 2. */
845425bb815Sopenharmony_ci        this_binding = ecma_make_object_value (ecma_builtin_get_global ());
846425bb815Sopenharmony_ci      }
847425bb815Sopenharmony_ci      else if (!ecma_is_value_object (this_binding))
848425bb815Sopenharmony_ci      {
849425bb815Sopenharmony_ci        /* 3., 4. */
850425bb815Sopenharmony_ci        this_binding = ecma_op_to_object (this_binding);
851425bb815Sopenharmony_ci        free_this_binding = true;
852425bb815Sopenharmony_ci
853425bb815Sopenharmony_ci        JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
854425bb815Sopenharmony_ci      }
855425bb815Sopenharmony_ci    }
856425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
857425bb815Sopenharmony_ci  }
858425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
859425bb815Sopenharmony_ci
860425bb815Sopenharmony_ci  /* 5. */
861425bb815Sopenharmony_ci  ecma_object_t *local_env_p;
862425bb815Sopenharmony_ci  if (status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED)
863425bb815Sopenharmony_ci  {
864425bb815Sopenharmony_ci    local_env_p = scope_p;
865425bb815Sopenharmony_ci  }
866425bb815Sopenharmony_ci  else
867425bb815Sopenharmony_ci  {
868425bb815Sopenharmony_ci    local_env_p = ecma_create_decl_lex_env (scope_p);
869425bb815Sopenharmony_ci    if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_IS_ARGUMENTS_NEEDED)
870425bb815Sopenharmony_ci    {
871425bb815Sopenharmony_ci      ecma_op_create_arguments_object (func_obj_p,
872425bb815Sopenharmony_ci                                       local_env_p,
873425bb815Sopenharmony_ci                                       arguments_list_p,
874425bb815Sopenharmony_ci                                       arguments_list_len,
875425bb815Sopenharmony_ci                                       bytecode_data_p);
876425bb815Sopenharmony_ci    }
877425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
878425bb815Sopenharmony_ci    // ECMAScript v6, 9.2.2.8
879425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
880425bb815Sopenharmony_ci    {
881425bb815Sopenharmony_ci      ecma_value_t lexical_this;
882425bb815Sopenharmony_ci      lexical_this = (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp) ? ECMA_VALUE_UNINITIALIZED
883425bb815Sopenharmony_ci                                                                                            : this_binding);
884425bb815Sopenharmony_ci      ecma_op_init_this_binding (local_env_p, lexical_this);
885425bb815Sopenharmony_ci    }
886425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
887425bb815Sopenharmony_ci  }
888425bb815Sopenharmony_ci
889425bb815Sopenharmony_ci  ecma_value_t ret_value = vm_run (bytecode_data_p,
890425bb815Sopenharmony_ci                                   this_binding,
891425bb815Sopenharmony_ci                                   local_env_p,
892425bb815Sopenharmony_ci                                   arguments_list_p,
893425bb815Sopenharmony_ci                                   arguments_list_len);
894425bb815Sopenharmony_ci
895425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
896425bb815Sopenharmony_ci  JERRY_CONTEXT (current_function_obj_p) = old_function_object_p;
897425bb815Sopenharmony_ci
898425bb815Sopenharmony_ci  /* ECMAScript v6, 9.2.2.13 */
899425bb815Sopenharmony_ci  if (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
900425bb815Sopenharmony_ci  {
901425bb815Sopenharmony_ci    if (!ECMA_IS_VALUE_ERROR (ret_value) && !ecma_is_value_object (ret_value))
902425bb815Sopenharmony_ci    {
903425bb815Sopenharmony_ci      if (!ecma_is_value_undefined (ret_value))
904425bb815Sopenharmony_ci      {
905425bb815Sopenharmony_ci        ecma_free_value (ret_value);
906425bb815Sopenharmony_ci        ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived constructors may only return object or undefined."));
907425bb815Sopenharmony_ci      }
908425bb815Sopenharmony_ci      else
909425bb815Sopenharmony_ci      {
910425bb815Sopenharmony_ci        ret_value = ecma_op_get_this_binding (local_env_p);
911425bb815Sopenharmony_ci      }
912425bb815Sopenharmony_ci    }
913425bb815Sopenharmony_ci  }
914425bb815Sopenharmony_ci
915425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
916425bb815Sopenharmony_ci
917425bb815Sopenharmony_ci  if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
918425bb815Sopenharmony_ci  {
919425bb815Sopenharmony_ci    ecma_deref_object (local_env_p);
920425bb815Sopenharmony_ci  }
921425bb815Sopenharmony_ci
922425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (free_this_binding))
923425bb815Sopenharmony_ci  {
924425bb815Sopenharmony_ci    ecma_free_value (this_binding);
925425bb815Sopenharmony_ci  }
926425bb815Sopenharmony_ci
927425bb815Sopenharmony_ci  return ret_value;
928425bb815Sopenharmony_ci} /* ecma_op_function_call_simple */
929425bb815Sopenharmony_ci
930425bb815Sopenharmony_ci/**
931425bb815Sopenharmony_ci * Perform a native C method call which was registered via the API.
932425bb815Sopenharmony_ci *
933425bb815Sopenharmony_ci * @return the result of the function call.
934425bb815Sopenharmony_ci */
935425bb815Sopenharmony_cistatic ecma_value_t JERRY_ATTR_NOINLINE
936425bb815Sopenharmony_ciecma_op_function_call_external (ecma_object_t *func_obj_p, /**< Function object */
937425bb815Sopenharmony_ci                                ecma_value_t this_arg_value, /**< 'this' argument's value */
938425bb815Sopenharmony_ci                                const ecma_value_t *arguments_list_p, /**< arguments list */
939425bb815Sopenharmony_ci                                ecma_length_t arguments_list_len) /**< length of arguments list */
940425bb815Sopenharmony_ci
941425bb815Sopenharmony_ci{
942425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
943425bb815Sopenharmony_ci  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
944425bb815Sopenharmony_ci  JERRY_ASSERT (ext_func_obj_p->u.external_handler_cb != NULL);
945425bb815Sopenharmony_ci
946425bb815Sopenharmony_ci  ecma_value_t ret_value = ext_func_obj_p->u.external_handler_cb (ecma_make_object_value (func_obj_p),
947425bb815Sopenharmony_ci                                                                  this_arg_value,
948425bb815Sopenharmony_ci                                                                  arguments_list_p,
949425bb815Sopenharmony_ci                                                                  arguments_list_len);
950425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
951425bb815Sopenharmony_ci  {
952425bb815Sopenharmony_ci    ecma_raise_error_from_error_reference (ret_value);
953425bb815Sopenharmony_ci    return ECMA_VALUE_ERROR;
954425bb815Sopenharmony_ci  }
955425bb815Sopenharmony_ci
956425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER)
957425bb815Sopenharmony_ci  JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
958425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */
959425bb815Sopenharmony_ci  return ret_value;
960425bb815Sopenharmony_ci} /* ecma_op_function_call_external */
961425bb815Sopenharmony_ci
962425bb815Sopenharmony_ci/**
963425bb815Sopenharmony_ci * Append the bound arguments into the given collection
964425bb815Sopenharmony_ci *
965425bb815Sopenharmony_ci * Note:
966425bb815Sopenharmony_ci *       - The whole bound chain is resolved
967425bb815Sopenharmony_ci *       - The first element of the collection contains the bounded this value
968425bb815Sopenharmony_ci *
969425bb815Sopenharmony_ci * @return target function of the bound function
970425bb815Sopenharmony_ci */
971425bb815Sopenharmony_ciJERRY_ATTR_NOINLINE static ecma_object_t *
972425bb815Sopenharmony_ciecma_op_bound_function_get_argument_list (ecma_object_t *func_obj_p, /**< bound bunction object */
973425bb815Sopenharmony_ci                                          ecma_collection_t *list_p) /**< list of arguments */
974425bb815Sopenharmony_ci{
975425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
976425bb815Sopenharmony_ci
977425bb815Sopenharmony_ci  ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
978425bb815Sopenharmony_ci
979425bb815Sopenharmony_ci  func_obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
980425bb815Sopenharmony_ci                                                           bound_func_p->header.u.bound_function.target_function);
981425bb815Sopenharmony_ci
982425bb815Sopenharmony_ci  ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
983425bb815Sopenharmony_ci
984425bb815Sopenharmony_ci  ecma_length_t args_length = 1;
985425bb815Sopenharmony_ci
986425bb815Sopenharmony_ci  if (ecma_is_value_integer_number (args_len_or_this))
987425bb815Sopenharmony_ci  {
988425bb815Sopenharmony_ci    args_length = (ecma_length_t) ecma_get_integer_from_value (args_len_or_this);
989425bb815Sopenharmony_ci  }
990425bb815Sopenharmony_ci
991425bb815Sopenharmony_ci  /* 5. */
992425bb815Sopenharmony_ci  if (args_length != 1)
993425bb815Sopenharmony_ci  {
994425bb815Sopenharmony_ci    const ecma_value_t *args_p = (const ecma_value_t *) (bound_func_p + 1);
995425bb815Sopenharmony_ci    list_p->buffer_p[0] = *args_p;
996425bb815Sopenharmony_ci
997425bb815Sopenharmony_ci    if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
998425bb815Sopenharmony_ci    {
999425bb815Sopenharmony_ci      func_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, list_p);
1000425bb815Sopenharmony_ci    }
1001425bb815Sopenharmony_ci    ecma_collection_append (list_p, args_p + 1, args_length - 1);
1002425bb815Sopenharmony_ci  }
1003425bb815Sopenharmony_ci  else
1004425bb815Sopenharmony_ci  {
1005425bb815Sopenharmony_ci    list_p->buffer_p[0] = args_len_or_this;
1006425bb815Sopenharmony_ci  }
1007425bb815Sopenharmony_ci
1008425bb815Sopenharmony_ci  return func_obj_p;
1009425bb815Sopenharmony_ci} /* ecma_op_bound_function_get_argument_list */
1010425bb815Sopenharmony_ci
1011425bb815Sopenharmony_ci/**
1012425bb815Sopenharmony_ci * [[Call]] internal method for bound function objects
1013425bb815Sopenharmony_ci *
1014425bb815Sopenharmony_ci * @return ecma value
1015425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
1016425bb815Sopenharmony_ci */
1017425bb815Sopenharmony_cistatic ecma_value_t JERRY_ATTR_NOINLINE
1018425bb815Sopenharmony_ciecma_op_function_call_bound (ecma_object_t *func_obj_p, /**< Function object */
1019425bb815Sopenharmony_ci                             const ecma_value_t *arguments_list_p, /**< arguments list */
1020425bb815Sopenharmony_ci                             ecma_length_t arguments_list_len) /**< length of arguments list */
1021425bb815Sopenharmony_ci{
1022425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1023425bb815Sopenharmony_ci
1024425bb815Sopenharmony_ci  JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
1025425bb815Sopenharmony_ci
1026425bb815Sopenharmony_ci  ecma_collection_t *bound_arg_list_p = ecma_new_collection ();
1027425bb815Sopenharmony_ci  ecma_collection_push_back (bound_arg_list_p, ECMA_VALUE_EMPTY);
1028425bb815Sopenharmony_ci
1029425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, bound_arg_list_p);
1030425bb815Sopenharmony_ci
1031425bb815Sopenharmony_ci  ecma_collection_append (bound_arg_list_p, arguments_list_p, arguments_list_len);
1032425bb815Sopenharmony_ci
1033425bb815Sopenharmony_ci  JERRY_ASSERT (!ecma_is_value_empty (bound_arg_list_p->buffer_p[0]));
1034425bb815Sopenharmony_ci
1035425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_op_function_call (target_obj_p,
1036425bb815Sopenharmony_ci                                                  bound_arg_list_p->buffer_p[0],
1037425bb815Sopenharmony_ci                                                  bound_arg_list_p->buffer_p + 1,
1038425bb815Sopenharmony_ci                                                  (ecma_length_t) (bound_arg_list_p->item_count - 1));
1039425bb815Sopenharmony_ci
1040425bb815Sopenharmony_ci  ecma_collection_destroy (bound_arg_list_p);
1041425bb815Sopenharmony_ci
1042425bb815Sopenharmony_ci  return ret_value;
1043425bb815Sopenharmony_ci} /* ecma_op_function_call_bound */
1044425bb815Sopenharmony_ci
1045425bb815Sopenharmony_ci/**
1046425bb815Sopenharmony_ci * [[Call]] implementation for Function objects,
1047425bb815Sopenharmony_ci * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
1048425bb815Sopenharmony_ci * or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
1049425bb815Sopenharmony_ci * and for built-in Function objects
1050425bb815Sopenharmony_ci * from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
1051425bb815Sopenharmony_ci *
1052425bb815Sopenharmony_ci * @return ecma value
1053425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
1054425bb815Sopenharmony_ci */
1055425bb815Sopenharmony_ciecma_value_t
1056425bb815Sopenharmony_ciecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
1057425bb815Sopenharmony_ci                       ecma_value_t this_arg_value, /**< 'this' argument's value */
1058425bb815Sopenharmony_ci                       const ecma_value_t *arguments_list_p, /**< arguments list */
1059425bb815Sopenharmony_ci                       ecma_length_t arguments_list_len) /**< length of arguments list */
1060425bb815Sopenharmony_ci{
1061425bb815Sopenharmony_ci  JERRY_ASSERT (func_obj_p != NULL
1062425bb815Sopenharmony_ci                && !ecma_is_lexical_environment (func_obj_p));
1063425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_op_object_is_callable (func_obj_p));
1064425bb815Sopenharmony_ci
1065425bb815Sopenharmony_ci  ECMA_CHECK_STACK_USAGE ();
1066425bb815Sopenharmony_ci
1067425bb815Sopenharmony_ci  const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
1068425bb815Sopenharmony_ci
1069425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1070425bb815Sopenharmony_ci  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
1071425bb815Sopenharmony_ci  {
1072425bb815Sopenharmony_ci    return ecma_proxy_object_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1073425bb815Sopenharmony_ci  }
1074425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1075425bb815Sopenharmony_ci
1076425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1077425bb815Sopenharmony_ci  ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1078425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_DIRECT_EVAL)))
1079425bb815Sopenharmony_ci  {
1080425bb815Sopenharmony_ci    JERRY_CONTEXT (current_new_target) = NULL;
1081425bb815Sopenharmony_ci  }
1082425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1083425bb815Sopenharmony_ci
1084425bb815Sopenharmony_ci  ecma_value_t result;
1085425bb815Sopenharmony_ci
1086425bb815Sopenharmony_ci  if (JERRY_LIKELY (type == ECMA_OBJECT_TYPE_FUNCTION))
1087425bb815Sopenharmony_ci  {
1088425bb815Sopenharmony_ci    result = ecma_op_function_call_simple (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1089425bb815Sopenharmony_ci  }
1090425bb815Sopenharmony_ci  else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
1091425bb815Sopenharmony_ci  {
1092425bb815Sopenharmony_ci    result = ecma_op_function_call_external (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1093425bb815Sopenharmony_ci  }
1094425bb815Sopenharmony_ci  else
1095425bb815Sopenharmony_ci  {
1096425bb815Sopenharmony_ci    result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len);
1097425bb815Sopenharmony_ci  }
1098425bb815Sopenharmony_ci
1099425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1100425bb815Sopenharmony_ci  JERRY_CONTEXT (current_new_target) = old_new_target_p;
1101425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1102425bb815Sopenharmony_ci
1103425bb815Sopenharmony_ci  return result;
1104425bb815Sopenharmony_ci} /* ecma_op_function_call */
1105425bb815Sopenharmony_ci
1106425bb815Sopenharmony_ci/**
1107425bb815Sopenharmony_ci * [[Construct]] internal method for bound function objects
1108425bb815Sopenharmony_ci *
1109425bb815Sopenharmony_ci * @return ecma value
1110425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
1111425bb815Sopenharmony_ci */
1112425bb815Sopenharmony_cistatic ecma_value_t JERRY_ATTR_NOINLINE
1113425bb815Sopenharmony_ciecma_op_function_construct_bound (ecma_object_t *func_obj_p, /**< Function object */
1114425bb815Sopenharmony_ci                                  ecma_object_t *new_target_p, /**< new target */
1115425bb815Sopenharmony_ci                                  const ecma_value_t *arguments_list_p, /**< arguments list */
1116425bb815Sopenharmony_ci                                  ecma_length_t arguments_list_len) /**< length of arguments list */
1117425bb815Sopenharmony_ci{
1118425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1119425bb815Sopenharmony_ci
1120425bb815Sopenharmony_ci  ecma_collection_t *bound_arg_list_p = ecma_new_collection ();
1121425bb815Sopenharmony_ci  ecma_collection_push_back (bound_arg_list_p, ECMA_VALUE_EMPTY);
1122425bb815Sopenharmony_ci
1123425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, bound_arg_list_p);
1124425bb815Sopenharmony_ci
1125425bb815Sopenharmony_ci  ecma_collection_append (bound_arg_list_p, arguments_list_p, arguments_list_len);
1126425bb815Sopenharmony_ci
1127425bb815Sopenharmony_ci  if (func_obj_p == new_target_p)
1128425bb815Sopenharmony_ci  {
1129425bb815Sopenharmony_ci    new_target_p = target_obj_p;
1130425bb815Sopenharmony_ci  }
1131425bb815Sopenharmony_ci
1132425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_op_function_construct (target_obj_p,
1133425bb815Sopenharmony_ci                                                       new_target_p,
1134425bb815Sopenharmony_ci                                                       bound_arg_list_p->buffer_p + 1,
1135425bb815Sopenharmony_ci                                                       (ecma_length_t) (bound_arg_list_p->item_count - 1));
1136425bb815Sopenharmony_ci
1137425bb815Sopenharmony_ci  ecma_collection_destroy (bound_arg_list_p);
1138425bb815Sopenharmony_ci
1139425bb815Sopenharmony_ci  return ret_value;
1140425bb815Sopenharmony_ci} /* ecma_op_function_construct_bound */
1141425bb815Sopenharmony_ci
1142425bb815Sopenharmony_ci/**
1143425bb815Sopenharmony_ci * [[Construct]] internal method for external function objects
1144425bb815Sopenharmony_ci *
1145425bb815Sopenharmony_ci * @return ecma value
1146425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
1147425bb815Sopenharmony_ci */
1148425bb815Sopenharmony_cistatic ecma_value_t JERRY_ATTR_NOINLINE
1149425bb815Sopenharmony_ciecma_op_function_construct_external (ecma_object_t *func_obj_p, /**< Function object */
1150425bb815Sopenharmony_ci                                     ecma_object_t *new_target_p, /**< new target */
1151425bb815Sopenharmony_ci                                     const ecma_value_t *arguments_list_p, /**< arguments list */
1152425bb815Sopenharmony_ci                                     ecma_length_t arguments_list_len) /**< length of arguments list */
1153425bb815Sopenharmony_ci{
1154425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1155425bb815Sopenharmony_ci
1156425bb815Sopenharmony_ci  ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
1157425bb815Sopenharmony_ci
1158425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (proto_p == NULL))
1159425bb815Sopenharmony_ci  {
1160425bb815Sopenharmony_ci    return ECMA_VALUE_ERROR;
1161425bb815Sopenharmony_ci  }
1162425bb815Sopenharmony_ci
1163425bb815Sopenharmony_ci  ecma_object_t *new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
1164425bb815Sopenharmony_ci  ecma_value_t this_arg = ecma_make_object_value (new_this_obj_p);
1165425bb815Sopenharmony_ci  ecma_deref_object (proto_p);
1166425bb815Sopenharmony_ci
1167425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1168425bb815Sopenharmony_ci  ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1169425bb815Sopenharmony_ci  JERRY_CONTEXT (current_new_target) = new_target_p;
1170425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1171425bb815Sopenharmony_ci
1172425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_op_function_call_external (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
1173425bb815Sopenharmony_ci
1174425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1175425bb815Sopenharmony_ci  JERRY_CONTEXT (current_new_target) = old_new_target_p;
1176425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1177425bb815Sopenharmony_ci
1178425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
1179425bb815Sopenharmony_ci  {
1180425bb815Sopenharmony_ci    ecma_deref_object (new_this_obj_p);
1181425bb815Sopenharmony_ci    return ret_value;
1182425bb815Sopenharmony_ci  }
1183425bb815Sopenharmony_ci
1184425bb815Sopenharmony_ci  ecma_free_value (ret_value);
1185425bb815Sopenharmony_ci
1186425bb815Sopenharmony_ci  return this_arg;
1187425bb815Sopenharmony_ci} /* ecma_op_function_construct_external */
1188425bb815Sopenharmony_ci
1189425bb815Sopenharmony_ci/**
1190425bb815Sopenharmony_ci * General [[Construct]] implementation function objects
1191425bb815Sopenharmony_ci *
1192425bb815Sopenharmony_ci * See also: ECMAScript v6, 9.2.2
1193425bb815Sopenharmony_ci *
1194425bb815Sopenharmony_ci * @return ecma value
1195425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
1196425bb815Sopenharmony_ci */
1197425bb815Sopenharmony_ciecma_value_t
1198425bb815Sopenharmony_ciecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
1199425bb815Sopenharmony_ci                            ecma_object_t *new_target_p, /**< new target */
1200425bb815Sopenharmony_ci                            const ecma_value_t *arguments_list_p, /**< arguments list */
1201425bb815Sopenharmony_ci                            ecma_length_t arguments_list_len) /**< length of arguments list */
1202425bb815Sopenharmony_ci{
1203425bb815Sopenharmony_ci  JERRY_ASSERT (func_obj_p != NULL
1204425bb815Sopenharmony_ci                && !ecma_is_lexical_environment (func_obj_p));
1205425bb815Sopenharmony_ci
1206425bb815Sopenharmony_ci  const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
1207425bb815Sopenharmony_ci
1208425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1209425bb815Sopenharmony_ci  if (ECMA_OBJECT_TYPE_IS_PROXY (type))
1210425bb815Sopenharmony_ci  {
1211425bb815Sopenharmony_ci    return ecma_proxy_object_construct (func_obj_p,
1212425bb815Sopenharmony_ci                                        new_target_p,
1213425bb815Sopenharmony_ci                                        arguments_list_p,
1214425bb815Sopenharmony_ci                                        arguments_list_len);
1215425bb815Sopenharmony_ci  }
1216425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1217425bb815Sopenharmony_ci
1218425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION))
1219425bb815Sopenharmony_ci  {
1220425bb815Sopenharmony_ci    return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1221425bb815Sopenharmony_ci  }
1222425bb815Sopenharmony_ci
1223425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION))
1224425bb815Sopenharmony_ci  {
1225425bb815Sopenharmony_ci    return ecma_op_function_construct_external (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1226425bb815Sopenharmony_ci  }
1227425bb815Sopenharmony_ci
1228425bb815Sopenharmony_ci  JERRY_ASSERT (type == ECMA_OBJECT_TYPE_FUNCTION);
1229425bb815Sopenharmony_ci
1230425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
1231425bb815Sopenharmony_ci  {
1232425bb815Sopenharmony_ci    return ecma_builtin_dispatch_construct (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1233425bb815Sopenharmony_ci  }
1234425bb815Sopenharmony_ci
1235425bb815Sopenharmony_ci  ecma_object_t *new_this_obj_p = NULL;
1236425bb815Sopenharmony_ci  ecma_value_t this_arg;
1237425bb815Sopenharmony_ci  ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
1238425bb815Sopenharmony_ci  const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
1239425bb815Sopenharmony_ci
1240425bb815Sopenharmony_ci  if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1241425bb815Sopenharmony_ci  {
1242425bb815Sopenharmony_ci    if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
1243425bb815Sopenharmony_ci    {
1244425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor."));
1245425bb815Sopenharmony_ci    }
1246425bb815Sopenharmony_ci
1247425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
1248425bb815Sopenharmony_ci  }
1249425bb815Sopenharmony_ci
1250425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1251425bb815Sopenharmony_ci  /* 6. */
1252425bb815Sopenharmony_ci  ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1253425bb815Sopenharmony_ci  JERRY_CONTEXT (current_new_target) = new_target_p;
1254425bb815Sopenharmony_ci
1255425bb815Sopenharmony_ci  /* 5. */
1256425bb815Sopenharmony_ci  if (!ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_obj_p->u.function.scope_cp))
1257425bb815Sopenharmony_ci  {
1258425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1259425bb815Sopenharmony_ci    /* 5.a */
1260425bb815Sopenharmony_ci    ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
1261425bb815Sopenharmony_ci
1262425bb815Sopenharmony_ci    /* 5.b */
1263425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (proto_p == NULL))
1264425bb815Sopenharmony_ci    {
1265425bb815Sopenharmony_ci      return ECMA_VALUE_ERROR;
1266425bb815Sopenharmony_ci    }
1267425bb815Sopenharmony_ci
1268425bb815Sopenharmony_ci    new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
1269425bb815Sopenharmony_ci    ecma_deref_object (proto_p);
1270425bb815Sopenharmony_ci    this_arg = ecma_make_object_value (new_this_obj_p);
1271425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1272425bb815Sopenharmony_ci  }
1273425bb815Sopenharmony_ci  else
1274425bb815Sopenharmony_ci  {
1275425bb815Sopenharmony_ci    this_arg = ECMA_VALUE_UNDEFINED;
1276425bb815Sopenharmony_ci  }
1277425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1278425bb815Sopenharmony_ci
1279425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_op_function_call_simple (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
1280425bb815Sopenharmony_ci
1281425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1282425bb815Sopenharmony_ci  JERRY_CONTEXT (current_new_target) = old_new_target_p;
1283425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1284425bb815Sopenharmony_ci
1285425bb815Sopenharmony_ci  /* 13.a */
1286425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
1287425bb815Sopenharmony_ci  {
1288425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1289425bb815Sopenharmony_ci    if (new_this_obj_p != NULL)
1290425bb815Sopenharmony_ci    {
1291425bb815Sopenharmony_ci      ecma_deref_object (new_this_obj_p);
1292425bb815Sopenharmony_ci    }
1293425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1294425bb815Sopenharmony_ci    ecma_deref_object (new_this_obj_p);
1295425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1296425bb815Sopenharmony_ci    return ret_value;
1297425bb815Sopenharmony_ci  }
1298425bb815Sopenharmony_ci
1299425bb815Sopenharmony_ci  /* 13.b */
1300425bb815Sopenharmony_ci  ecma_free_value (ret_value);
1301425bb815Sopenharmony_ci  return this_arg;
1302425bb815Sopenharmony_ci} /* ecma_op_function_construct */
1303425bb815Sopenharmony_ci
1304425bb815Sopenharmony_ci/**
1305425bb815Sopenharmony_ci * Lazy instantiation of 'prototype' property for non-builtin and external functions
1306425bb815Sopenharmony_ci *
1307425bb815Sopenharmony_ci * @return pointer to newly instantiated property
1308425bb815Sopenharmony_ci */
1309425bb815Sopenharmony_cistatic ecma_property_t *
1310425bb815Sopenharmony_ciecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the function object */
1311425bb815Sopenharmony_ci{
1312425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
1313425bb815Sopenharmony_ci                || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1314425bb815Sopenharmony_ci
1315425bb815Sopenharmony_ci  /* ECMA-262 v5, 13.2, 16-18 */
1316425bb815Sopenharmony_ci
1317425bb815Sopenharmony_ci  ecma_object_t *proto_object_p = NULL;
1318425bb815Sopenharmony_ci  bool init_constructor = true;
1319425bb815Sopenharmony_ci
1320425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1321425bb815Sopenharmony_ci  if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
1322425bb815Sopenharmony_ci  {
1323425bb815Sopenharmony_ci    const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1324425bb815Sopenharmony_ci
1325425bb815Sopenharmony_ci    if (byte_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
1326425bb815Sopenharmony_ci    {
1327425bb815Sopenharmony_ci      proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
1328425bb815Sopenharmony_ci                                           0,
1329425bb815Sopenharmony_ci                                           ECMA_OBJECT_TYPE_GENERAL);
1330425bb815Sopenharmony_ci      init_constructor = false;
1331425bb815Sopenharmony_ci    }
1332425bb815Sopenharmony_ci    else if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1333425bb815Sopenharmony_ci    {
1334425bb815Sopenharmony_ci      return NULL;
1335425bb815Sopenharmony_ci    }
1336425bb815Sopenharmony_ci  }
1337425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1338425bb815Sopenharmony_ci
1339425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1340425bb815Sopenharmony_ci  if (proto_object_p == NULL)
1341425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1342425bb815Sopenharmony_ci  {
1343425bb815Sopenharmony_ci    proto_object_p = ecma_op_create_object_object_noarg ();
1344425bb815Sopenharmony_ci  }
1345425bb815Sopenharmony_ci
1346425bb815Sopenharmony_ci  /* 17. */
1347425bb815Sopenharmony_ci  if (init_constructor)
1348425bb815Sopenharmony_ci  {
1349425bb815Sopenharmony_ci    ecma_property_value_t *constructor_prop_value_p;
1350425bb815Sopenharmony_ci    constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
1351425bb815Sopenharmony_ci                                                                ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR),
1352425bb815Sopenharmony_ci                                                                ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
1353425bb815Sopenharmony_ci                                                                NULL);
1354425bb815Sopenharmony_ci
1355425bb815Sopenharmony_ci    constructor_prop_value_p->value = ecma_make_object_value (object_p);
1356425bb815Sopenharmony_ci  }
1357425bb815Sopenharmony_ci
1358425bb815Sopenharmony_ci  /* 18. */
1359425bb815Sopenharmony_ci  ecma_property_t *prototype_prop_p;
1360425bb815Sopenharmony_ci  ecma_property_value_t *prototype_prop_value_p;
1361425bb815Sopenharmony_ci  prototype_prop_value_p = ecma_create_named_data_property (object_p,
1362425bb815Sopenharmony_ci                                                            ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE),
1363425bb815Sopenharmony_ci                                                            ECMA_PROPERTY_FLAG_WRITABLE,
1364425bb815Sopenharmony_ci                                                            &prototype_prop_p);
1365425bb815Sopenharmony_ci
1366425bb815Sopenharmony_ci  prototype_prop_value_p->value = ecma_make_object_value (proto_object_p);
1367425bb815Sopenharmony_ci
1368425bb815Sopenharmony_ci  ecma_deref_object (proto_object_p);
1369425bb815Sopenharmony_ci
1370425bb815Sopenharmony_ci  return prototype_prop_p;
1371425bb815Sopenharmony_ci} /* ecma_op_lazy_instantiate_prototype_object */
1372425bb815Sopenharmony_ci
1373425bb815Sopenharmony_ci/**
1374425bb815Sopenharmony_ci * Lazy instantiation of non-builtin ecma function object's properties
1375425bb815Sopenharmony_ci *
1376425bb815Sopenharmony_ci * Warning:
1377425bb815Sopenharmony_ci *         Only non-configurable properties could be instantiated lazily in this function,
1378425bb815Sopenharmony_ci *         as configurable properties could be deleted and it would be incorrect
1379425bb815Sopenharmony_ci *         to reinstantiate them in the function in second time.
1380425bb815Sopenharmony_ci *
1381425bb815Sopenharmony_ci * @return pointer to newly instantiated property, if a property was instantiated,
1382425bb815Sopenharmony_ci *         NULL - otherwise
1383425bb815Sopenharmony_ci */
1384425bb815Sopenharmony_ciecma_property_t *
1385425bb815Sopenharmony_ciecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< the function object */
1386425bb815Sopenharmony_ci                                                   ecma_string_t *property_name_p) /**< property name */
1387425bb815Sopenharmony_ci{
1388425bb815Sopenharmony_ci  JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
1389425bb815Sopenharmony_ci
1390425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1391425bb815Sopenharmony_ci  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH))
1392425bb815Sopenharmony_ci  {
1393425bb815Sopenharmony_ci    ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1394425bb815Sopenharmony_ci    if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1395425bb815Sopenharmony_ci    {
1396425bb815Sopenharmony_ci      /* Initialize 'length' property */
1397425bb815Sopenharmony_ci      const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
1398425bb815Sopenharmony_ci      uint32_t len;
1399425bb815Sopenharmony_ci      if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
1400425bb815Sopenharmony_ci      {
1401425bb815Sopenharmony_ci        cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
1402425bb815Sopenharmony_ci        len = args_p->argument_end;
1403425bb815Sopenharmony_ci      }
1404425bb815Sopenharmony_ci      else
1405425bb815Sopenharmony_ci      {
1406425bb815Sopenharmony_ci        cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
1407425bb815Sopenharmony_ci        len = args_p->argument_end;
1408425bb815Sopenharmony_ci      }
1409425bb815Sopenharmony_ci
1410425bb815Sopenharmony_ci      /* Set tag bit to represent initialized 'length' property */
1411425bb815Sopenharmony_ci      ECMA_SET_FIRST_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
1412425bb815Sopenharmony_ci      ecma_property_t *value_prop_p;
1413425bb815Sopenharmony_ci      ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1414425bb815Sopenharmony_ci                                                                        property_name_p,
1415425bb815Sopenharmony_ci                                                                        ECMA_PROPERTY_FLAG_CONFIGURABLE,
1416425bb815Sopenharmony_ci                                                                        &value_prop_p);
1417425bb815Sopenharmony_ci      value_p->value = ecma_make_uint32_value (len);
1418425bb815Sopenharmony_ci      return value_prop_p;
1419425bb815Sopenharmony_ci    }
1420425bb815Sopenharmony_ci
1421425bb815Sopenharmony_ci    return NULL;
1422425bb815Sopenharmony_ci  }
1423425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1424425bb815Sopenharmony_ci
1425425bb815Sopenharmony_ci  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE)
1426425bb815Sopenharmony_ci      && ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
1427425bb815Sopenharmony_ci  {
1428425bb815Sopenharmony_ci    return ecma_op_lazy_instantiate_prototype_object (object_p);
1429425bb815Sopenharmony_ci  }
1430425bb815Sopenharmony_ci
1431425bb815Sopenharmony_ci  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_CALLER)
1432425bb815Sopenharmony_ci      || ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_ARGUMENTS))
1433425bb815Sopenharmony_ci  {
1434425bb815Sopenharmony_ci    const ecma_compiled_code_t *bytecode_data_p;
1435425bb815Sopenharmony_ci    bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1436425bb815Sopenharmony_ci
1437425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1438425bb815Sopenharmony_ci    if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
1439425bb815Sopenharmony_ci    {
1440425bb815Sopenharmony_ci      ecma_property_t *value_prop_p;
1441425bb815Sopenharmony_ci      /* The property_name_p argument contans the name. */
1442425bb815Sopenharmony_ci      ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1443425bb815Sopenharmony_ci                                                                        property_name_p,
1444425bb815Sopenharmony_ci                                                                        ECMA_PROPERTY_FIXED,
1445425bb815Sopenharmony_ci                                                                        &value_prop_p);
1446425bb815Sopenharmony_ci      value_p->value = ECMA_VALUE_NULL;
1447425bb815Sopenharmony_ci      return value_prop_p;
1448425bb815Sopenharmony_ci    }
1449425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1450425bb815Sopenharmony_ci    if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
1451425bb815Sopenharmony_ci    {
1452425bb815Sopenharmony_ci      ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
1453425bb815Sopenharmony_ci
1454425bb815Sopenharmony_ci      ecma_property_t *caller_prop_p;
1455425bb815Sopenharmony_ci      /* The property_name_p argument contans the name. */
1456425bb815Sopenharmony_ci      ecma_create_named_accessor_property (object_p,
1457425bb815Sopenharmony_ci                                           property_name_p,
1458425bb815Sopenharmony_ci                                           thrower_p,
1459425bb815Sopenharmony_ci                                           thrower_p,
1460425bb815Sopenharmony_ci                                           ECMA_PROPERTY_FIXED,
1461425bb815Sopenharmony_ci                                           &caller_prop_p);
1462425bb815Sopenharmony_ci      return caller_prop_p;
1463425bb815Sopenharmony_ci    }
1464425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1465425bb815Sopenharmony_ci
1466425bb815Sopenharmony_ci  }
1467425bb815Sopenharmony_ci
1468425bb815Sopenharmony_ci  return NULL;
1469425bb815Sopenharmony_ci} /* ecma_op_function_try_to_lazy_instantiate_property */
1470425bb815Sopenharmony_ci
1471425bb815Sopenharmony_ci/**
1472425bb815Sopenharmony_ci * Create specification defined non-configurable properties for external functions.
1473425bb815Sopenharmony_ci *
1474425bb815Sopenharmony_ci * See also:
1475425bb815Sopenharmony_ci *          ECMA-262 v5, 15.3.4.5
1476425bb815Sopenharmony_ci *
1477425bb815Sopenharmony_ci * @return pointer property, if one was instantiated,
1478425bb815Sopenharmony_ci *         NULL - otherwise.
1479425bb815Sopenharmony_ci */
1480425bb815Sopenharmony_ciecma_property_t *
1481425bb815Sopenharmony_ciecma_op_external_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
1482425bb815Sopenharmony_ci                                                            ecma_string_t *property_name_p) /**< property's name */
1483425bb815Sopenharmony_ci{
1484425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1485425bb815Sopenharmony_ci
1486425bb815Sopenharmony_ci  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE))
1487425bb815Sopenharmony_ci  {
1488425bb815Sopenharmony_ci    return ecma_op_lazy_instantiate_prototype_object (object_p);
1489425bb815Sopenharmony_ci  }
1490425bb815Sopenharmony_ci
1491425bb815Sopenharmony_ci  return NULL;
1492425bb815Sopenharmony_ci} /* ecma_op_external_function_try_to_lazy_instantiate_property */
1493425bb815Sopenharmony_ci
1494425bb815Sopenharmony_ci/**
1495425bb815Sopenharmony_ci * Create specification defined non-configurable properties for bound functions.
1496425bb815Sopenharmony_ci *
1497425bb815Sopenharmony_ci * See also:
1498425bb815Sopenharmony_ci *          ECMA-262 v5, 15.3.4.5
1499425bb815Sopenharmony_ci *
1500425bb815Sopenharmony_ci * @return pointer property, if one was instantiated,
1501425bb815Sopenharmony_ci *         NULL - otherwise.
1502425bb815Sopenharmony_ci */
1503425bb815Sopenharmony_ciecma_property_t *
1504425bb815Sopenharmony_ciecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
1505425bb815Sopenharmony_ci                                                         ecma_string_t *property_name_p) /**< property's name */
1506425bb815Sopenharmony_ci{
1507425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1508425bb815Sopenharmony_ci
1509425bb815Sopenharmony_ci  if (ecma_string_is_length (property_name_p))
1510425bb815Sopenharmony_ci  {
1511425bb815Sopenharmony_ci    ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
1512425bb815Sopenharmony_ci    ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
1513425bb815Sopenharmony_ci    ecma_integer_value_t length = 0;
1514425bb815Sopenharmony_ci    ecma_integer_value_t args_length = 1;
1515425bb815Sopenharmony_ci    uint8_t length_attributes;
1516425bb815Sopenharmony_ci
1517425bb815Sopenharmony_ci    if (ecma_is_value_integer_number (args_len_or_this))
1518425bb815Sopenharmony_ci    {
1519425bb815Sopenharmony_ci      args_length = ecma_get_integer_from_value (args_len_or_this);
1520425bb815Sopenharmony_ci    }
1521425bb815Sopenharmony_ci
1522425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1523425bb815Sopenharmony_ci    if (ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function))
1524425bb815Sopenharmony_ci    {
1525425bb815Sopenharmony_ci      return NULL;
1526425bb815Sopenharmony_ci    }
1527425bb815Sopenharmony_ci
1528425bb815Sopenharmony_ci    length_attributes = ECMA_PROPERTY_FLAG_CONFIGURABLE;
1529425bb815Sopenharmony_ci    length = bound_func_p->target_length - (args_length - 1);
1530425bb815Sopenharmony_ci
1531425bb815Sopenharmony_ci    /* Set tag bit to represent initialized 'length' property */
1532425bb815Sopenharmony_ci    ECMA_SET_FIRST_BIT_TO_POINTER_TAG (bound_func_p->header.u.bound_function.target_function);
1533425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1534425bb815Sopenharmony_ci    length_attributes = ECMA_PROPERTY_FIXED;
1535425bb815Sopenharmony_ci
1536425bb815Sopenharmony_ci    ecma_object_t *target_func_p;
1537425bb815Sopenharmony_ci    target_func_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
1538425bb815Sopenharmony_ci                                                                bound_func_p->header.u.bound_function.target_function);
1539425bb815Sopenharmony_ci
1540425bb815Sopenharmony_ci    if (ecma_object_get_class_name (target_func_p) == LIT_MAGIC_STRING_FUNCTION_UL)
1541425bb815Sopenharmony_ci    {
1542425bb815Sopenharmony_ci      /* The property_name_p argument contains the 'length' string. */
1543425bb815Sopenharmony_ci      ecma_value_t get_len_value = ecma_op_object_get (target_func_p, property_name_p);
1544425bb815Sopenharmony_ci
1545425bb815Sopenharmony_ci      JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (get_len_value));
1546425bb815Sopenharmony_ci      JERRY_ASSERT (ecma_is_value_integer_number (get_len_value));
1547425bb815Sopenharmony_ci
1548425bb815Sopenharmony_ci      length = ecma_get_integer_from_value (get_len_value) - (args_length - 1);
1549425bb815Sopenharmony_ci    }
1550425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1551425bb815Sopenharmony_ci
1552425bb815Sopenharmony_ci    if (length < 0)
1553425bb815Sopenharmony_ci    {
1554425bb815Sopenharmony_ci      length = 0;
1555425bb815Sopenharmony_ci    }
1556425bb815Sopenharmony_ci
1557425bb815Sopenharmony_ci    ecma_property_t *len_prop_p;
1558425bb815Sopenharmony_ci    ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p,
1559425bb815Sopenharmony_ci                                                                               property_name_p,
1560425bb815Sopenharmony_ci                                                                               length_attributes,
1561425bb815Sopenharmony_ci                                                                               &len_prop_p);
1562425bb815Sopenharmony_ci
1563425bb815Sopenharmony_ci    len_prop_value_p->value = ecma_make_integer_value (length);
1564425bb815Sopenharmony_ci    return len_prop_p;
1565425bb815Sopenharmony_ci  }
1566425bb815Sopenharmony_ci
1567425bb815Sopenharmony_ci  if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_CALLER)
1568425bb815Sopenharmony_ci      || ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_ARGUMENTS))
1569425bb815Sopenharmony_ci  {
1570425bb815Sopenharmony_ci    ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
1571425bb815Sopenharmony_ci
1572425bb815Sopenharmony_ci    ecma_property_t *caller_prop_p;
1573425bb815Sopenharmony_ci    /* The string_p argument contans the name. */
1574425bb815Sopenharmony_ci    ecma_create_named_accessor_property (object_p,
1575425bb815Sopenharmony_ci                                         property_name_p,
1576425bb815Sopenharmony_ci                                         thrower_p,
1577425bb815Sopenharmony_ci                                         thrower_p,
1578425bb815Sopenharmony_ci                                         ECMA_PROPERTY_FIXED,
1579425bb815Sopenharmony_ci                                         &caller_prop_p);
1580425bb815Sopenharmony_ci    return caller_prop_p;
1581425bb815Sopenharmony_ci  }
1582425bb815Sopenharmony_ci
1583425bb815Sopenharmony_ci  return NULL;
1584425bb815Sopenharmony_ci} /* ecma_op_bound_function_try_to_lazy_instantiate_property */
1585425bb815Sopenharmony_ci
1586425bb815Sopenharmony_ci/**
1587425bb815Sopenharmony_ci * List names of a Function object's lazy instantiated properties,
1588425bb815Sopenharmony_ci * adding them to corresponding string collections
1589425bb815Sopenharmony_ci *
1590425bb815Sopenharmony_ci * See also:
1591425bb815Sopenharmony_ci *          ecma_op_function_try_to_lazy_instantiate_property
1592425bb815Sopenharmony_ci */
1593425bb815Sopenharmony_civoid
1594425bb815Sopenharmony_ciecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functionobject */
1595425bb815Sopenharmony_ci                                           uint32_t opts, /**< listing options using flags
1596425bb815Sopenharmony_ci                                                           *   from ecma_list_properties_options_t */
1597425bb815Sopenharmony_ci                                           ecma_collection_t *main_collection_p, /**< 'main' collection */
1598425bb815Sopenharmony_ci                                           ecma_collection_t *non_enum_collection_p) /**< skipped
1599425bb815Sopenharmony_ci                                                                                      *   'non-enumerable'
1600425bb815Sopenharmony_ci                                                                                      *   collection */
1601425bb815Sopenharmony_ci{
1602425bb815Sopenharmony_ci  JERRY_UNUSED (main_collection_p);
1603425bb815Sopenharmony_ci
1604425bb815Sopenharmony_ci  ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1605425bb815Sopenharmony_ci
1606425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1607425bb815Sopenharmony_ci  ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1608425bb815Sopenharmony_ci  if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1609425bb815Sopenharmony_ci  {
1610425bb815Sopenharmony_ci    /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */
1611425bb815Sopenharmony_ci    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1612425bb815Sopenharmony_ci  }
1613425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1614425bb815Sopenharmony_ci  /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1615425bb815Sopenharmony_ci  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1616425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1617425bb815Sopenharmony_ci
1618425bb815Sopenharmony_ci  const ecma_compiled_code_t *bytecode_data_p;
1619425bb815Sopenharmony_ci  bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1620425bb815Sopenharmony_ci
1621425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1622425bb815Sopenharmony_ci  if (bytecode_data_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1623425bb815Sopenharmony_ci  {
1624425bb815Sopenharmony_ci    return;
1625425bb815Sopenharmony_ci  }
1626425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1627425bb815Sopenharmony_ci
1628425bb815Sopenharmony_ci  /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
1629425bb815Sopenharmony_ci  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
1630425bb815Sopenharmony_ci
1631425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1632425bb815Sopenharmony_ci  bool append_caller_and_arguments = !(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE);
1633425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1634425bb815Sopenharmony_ci  bool append_caller_and_arguments = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE);
1635425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1636425bb815Sopenharmony_ci
1637425bb815Sopenharmony_ci  if (append_caller_and_arguments)
1638425bb815Sopenharmony_ci  {
1639425bb815Sopenharmony_ci    /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1640425bb815Sopenharmony_ci    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
1641425bb815Sopenharmony_ci
1642425bb815Sopenharmony_ci    /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1643425bb815Sopenharmony_ci    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
1644425bb815Sopenharmony_ci  }
1645425bb815Sopenharmony_ci} /* ecma_op_function_list_lazy_property_names */
1646425bb815Sopenharmony_ci
1647425bb815Sopenharmony_ci/**
1648425bb815Sopenharmony_ci * List names of an External Function object's lazy instantiated properties,
1649425bb815Sopenharmony_ci * adding them to corresponding string collections
1650425bb815Sopenharmony_ci *
1651425bb815Sopenharmony_ci * See also:
1652425bb815Sopenharmony_ci *          ecma_op_external_function_try_to_lazy_instantiate_property
1653425bb815Sopenharmony_ci */
1654425bb815Sopenharmony_civoid
1655425bb815Sopenharmony_ciecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /**< function object */
1656425bb815Sopenharmony_ci                                                    uint32_t opts, /**< listing options using flags
1657425bb815Sopenharmony_ci                                                                    *   from ecma_list_properties_options_t */
1658425bb815Sopenharmony_ci                                                    ecma_collection_t *main_collection_p, /**< 'main' collection */
1659425bb815Sopenharmony_ci                                                    ecma_collection_t *non_enum_collection_p) /**< skipped
1660425bb815Sopenharmony_ci                                                                                               *   collection */
1661425bb815Sopenharmony_ci{
1662425bb815Sopenharmony_ci  JERRY_UNUSED (main_collection_p);
1663425bb815Sopenharmony_ci
1664425bb815Sopenharmony_ci  ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1665425bb815Sopenharmony_ci
1666425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015)
1667425bb815Sopenharmony_ci  JERRY_UNUSED (object_p);
1668425bb815Sopenharmony_ci#else /* ENABLED (JERRY_ES2015) */
1669425bb815Sopenharmony_ci  if (!ecma_op_ordinary_object_has_own_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE)))
1670425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */
1671425bb815Sopenharmony_ci  {
1672425bb815Sopenharmony_ci    /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
1673425bb815Sopenharmony_ci    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
1674425bb815Sopenharmony_ci  }
1675425bb815Sopenharmony_ci} /* ecma_op_external_function_list_lazy_property_names */
1676425bb815Sopenharmony_ci
1677425bb815Sopenharmony_ci/**
1678425bb815Sopenharmony_ci * List names of a Bound Function object's lazy instantiated properties,
1679425bb815Sopenharmony_ci * adding them to corresponding string collections
1680425bb815Sopenharmony_ci *
1681425bb815Sopenharmony_ci * See also:
1682425bb815Sopenharmony_ci *          ecma_op_bound_function_try_to_lazy_instantiate_property
1683425bb815Sopenharmony_ci */
1684425bb815Sopenharmony_civoid
1685425bb815Sopenharmony_ciecma_op_bound_function_list_lazy_property_names (ecma_object_t *object_p, /**< bound function object*/
1686425bb815Sopenharmony_ci                                                 uint32_t opts, /**< listing options using flags
1687425bb815Sopenharmony_ci                                                                 *   from ecma_list_properties_options_t */
1688425bb815Sopenharmony_ci                                                 ecma_collection_t *main_collection_p, /**< 'main' collection */
1689425bb815Sopenharmony_ci                                                 ecma_collection_t *non_enum_collection_p) /**< skipped
1690425bb815Sopenharmony_ci                                                                                            *   'non-enumerable'
1691425bb815Sopenharmony_ci                                                                                            *   collection */
1692425bb815Sopenharmony_ci{
1693425bb815Sopenharmony_ci  JERRY_UNUSED (main_collection_p);
1694425bb815Sopenharmony_ci
1695425bb815Sopenharmony_ci  ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1696425bb815Sopenharmony_ci
1697425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
1698425bb815Sopenharmony_ci  /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */
1699425bb815Sopenharmony_ci  ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
1700425bb815Sopenharmony_ci  if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function))
1701425bb815Sopenharmony_ci  {
1702425bb815Sopenharmony_ci    ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1703425bb815Sopenharmony_ci  }
1704425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
1705425bb815Sopenharmony_ci  JERRY_UNUSED (object_p);
1706425bb815Sopenharmony_ci  /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1707425bb815Sopenharmony_ci  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1708425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
1709425bb815Sopenharmony_ci
1710425bb815Sopenharmony_ci  /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1711425bb815Sopenharmony_ci  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
1712425bb815Sopenharmony_ci
1713425bb815Sopenharmony_ci  /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1714425bb815Sopenharmony_ci  ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
1715425bb815Sopenharmony_ci} /* ecma_op_bound_function_list_lazy_property_names */
1716425bb815Sopenharmony_ci
1717425bb815Sopenharmony_ci/**
1718425bb815Sopenharmony_ci * @}
1719425bb815Sopenharmony_ci * @}
1720425bb815Sopenharmony_ci */
1721