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