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