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-builtins.h" 19#include "ecma-conversion.h" 20#include "ecma-exceptions.h" 21#include "ecma-gc.h" 22#include "ecma-globals.h" 23#include "ecma-helpers.h" 24#include "ecma-objects.h" 25#include "ecma-proxy-object.h" 26#include "ecma-objects-general.h" 27#include "jrt.h" 28#include "ecma-builtin-object.h" 29 30#define ECMA_BUILTINS_INTERNAL 31#include "ecma-builtins-internal.h" 32 33/** 34 * This object has a custom dispatch function. 35 */ 36#define BUILTIN_CUSTOM_DISPATCH 37 38/** 39 * List of built-in routine identifiers. 40 */ 41enum 42{ 43 ECMA_OBJECT_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1, 44 45 ECMA_OBJECT_ROUTINE_CREATE, 46 ECMA_OBJECT_ROUTINE_IS, 47 ECMA_OBJECT_ROUTINE_SET_PROTOTYPE_OF, 48 49 /* These should be in this order. */ 50 ECMA_OBJECT_ROUTINE_DEFINE_PROPERTY, 51 ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES, 52 53 /* These should be in this order. */ 54 ECMA_OBJECT_ROUTINE_ASSIGN, 55 ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR, 56 ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES, 57 ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS, 58 ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF, 59 ECMA_OBJECT_ROUTINE_KEYS, 60 61 /* These should be in this order. */ 62 ECMA_OBJECT_ROUTINE_FREEZE, 63 ECMA_OBJECT_ROUTINE_PREVENT_EXTENSIONS, 64 ECMA_OBJECT_ROUTINE_SEAL, 65 66 /* These should be in this order. */ 67 ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE, 68 ECMA_OBJECT_ROUTINE_IS_FROZEN, 69 ECMA_OBJECT_ROUTINE_IS_SEALED, 70}; 71 72#define BUILTIN_INC_HEADER_NAME "ecma-builtin-object.inc.h" 73#define BUILTIN_UNDERSCORED_ID object 74#include "ecma-builtin-internal-routines-template.inc.h" 75 76/** \addtogroup ecma ECMA 77 * @{ 78 * 79 * \addtogroup ecmabuiltins 80 * @{ 81 * 82 * \addtogroup object ECMA Object object built-in 83 * @{ 84 */ 85 86/** 87 * Handle calling [[Call]] of built-in Object object 88 * 89 * @return ecma value 90 */ 91ecma_value_t 92ecma_builtin_object_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ 93 ecma_length_t arguments_list_len) /**< number of arguments */ 94{ 95 JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); 96 97 if (arguments_list_len == 0 98 || ecma_is_value_undefined (arguments_list_p[0]) 99 || ecma_is_value_null (arguments_list_p[0])) 100 { 101 return ecma_builtin_object_dispatch_construct (arguments_list_p, arguments_list_len); 102 } 103 104 return ecma_op_to_object (arguments_list_p[0]); 105} /* ecma_builtin_object_dispatch_call */ 106 107/** 108 * Handle calling [[Construct]] of built-in Object object 109 * 110 * @return ecma value 111 */ 112ecma_value_t 113ecma_builtin_object_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ 114 ecma_length_t arguments_list_len) /**< number of arguments */ 115{ 116 JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); 117 118 if (arguments_list_len == 0) 119 { 120 ecma_object_t *obj_p = ecma_op_create_object_object_noarg (); 121 122 return ecma_make_object_value (obj_p); 123 } 124 125 return ecma_op_create_object_object_arg (arguments_list_p[0]); 126} /* ecma_builtin_object_dispatch_construct */ 127 128/** 129 * The Object object's 'getPrototypeOf' routine 130 * 131 * See also: 132 * ECMA-262 v5, 15.2.3.2 133 * 134 * @return ecma value 135 * Returned value must be freed with ecma_free_value. 136 */ 137ecma_value_t 138ecma_builtin_object_object_get_prototype_of (ecma_object_t *obj_p) /**< routine's argument */ 139{ 140#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 141 if (ECMA_OBJECT_IS_PROXY (obj_p)) 142 { 143 return ecma_proxy_object_get_prototype_of (obj_p); 144 } 145#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 146 147 jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (obj_p); 148 149 if (proto_cp != JMEM_CP_NULL) 150 { 151 ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp); 152 ecma_ref_object (prototype_p); 153 return ecma_make_object_value (prototype_p); 154 } 155 156 return ECMA_VALUE_NULL; 157} /* ecma_builtin_object_object_get_prototype_of */ 158 159#if ENABLED (JERRY_ES2015) 160/** 161 * The Object object's 'setPrototypeOf' routine 162 * 163 * See also: 164 * ES2015 19.1.2.18 165 * 166 * @return ecma value 167 * Returned value must be freed with ecma_free_value. 168 */ 169ecma_value_t 170ecma_builtin_object_object_set_prototype_of (ecma_value_t arg1, /**< routine's first argument */ 171 ecma_value_t arg2) /**< routine's second argument */ 172{ 173 /* 1., 2. */ 174 if (ECMA_IS_VALUE_ERROR (ecma_op_check_object_coercible (arg1))) 175 { 176 return ECMA_VALUE_ERROR; 177 } 178 179 /* 3. */ 180 if (!ecma_is_value_object (arg2) && !ecma_is_value_null (arg2)) 181 { 182 return ecma_raise_type_error (ECMA_ERR_MSG ("proto is neither Object nor Null.")); 183 } 184 185 /* 4. */ 186 if (!ecma_is_value_object (arg1)) 187 { 188 return ecma_copy_value (arg1); 189 } 190 191 ecma_object_t *obj_p = ecma_get_object_from_value (arg1); 192 ecma_value_t status; 193 194 /* 5. */ 195#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 196 if (ECMA_OBJECT_IS_PROXY (obj_p)) 197 { 198 status = ecma_proxy_object_set_prototype_of (obj_p, arg2); 199 200 if (ECMA_IS_VALUE_ERROR (status)) 201 { 202 return status; 203 } 204 } 205 else 206 { 207#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 208 status = ecma_op_ordinary_object_set_prototype_of (obj_p, arg2); 209#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 210 } 211#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 212 213 if (ecma_is_value_false (status)) 214 { 215 return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot set [[Prototype]].")); 216 } 217 218 JERRY_ASSERT (ecma_is_value_true (status)); 219 ecma_ref_object (obj_p); 220 221 return arg1; 222} /* ecma_builtin_object_object_set_prototype_of */ 223 224/** 225 * The Object object's set __proto__ routine 226 * 227 * See also: 228 * ECMA-262 v6, B.2.2.1.2 229 * 230 * @return ecma value 231 * Returned value must be freed with ecma_free_value. 232 */ 233ecma_value_t 234ecma_builtin_object_object_set_proto (ecma_value_t arg1, /**< routine's first argument */ 235 ecma_value_t arg2) /**< routine's second argument */ 236{ 237 /* 1., 2. */ 238 if (ECMA_IS_VALUE_ERROR (ecma_op_check_object_coercible (arg1))) 239 { 240 return ECMA_VALUE_ERROR; 241 } 242 243 /* 3. */ 244 if (!ecma_is_value_object (arg2) && !ecma_is_value_null (arg2)) 245 { 246 return ECMA_VALUE_UNDEFINED; 247 } 248 249 /* 4. */ 250 if (!ecma_is_value_object (arg1)) 251 { 252 return ECMA_VALUE_UNDEFINED; 253 } 254 255 ecma_object_t *obj_p = ecma_get_object_from_value (arg1); 256 ecma_value_t status; 257 258 /* 5. */ 259#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 260 if (ECMA_OBJECT_IS_PROXY (obj_p)) 261 { 262 status = ecma_proxy_object_set_prototype_of (obj_p, arg2); 263 264 if (ECMA_IS_VALUE_ERROR (status)) 265 { 266 return status; 267 } 268 } 269 else 270 { 271#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 272 status = ecma_op_ordinary_object_set_prototype_of (obj_p, arg2); 273#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 274 } 275#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 276 277 if (ecma_is_value_false (status)) 278 { 279 return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot set [[Prototype]].")); 280 } 281 282 JERRY_ASSERT (ecma_is_value_true (status)); 283 284 return ECMA_VALUE_UNDEFINED; 285} /* ecma_builtin_object_object_set_proto */ 286#endif /* ENABLED (JERRY_ES2015) */ 287 288/** 289 * The Object object's 'getOwnPropertyNames' routine 290 * 291 * See also: 292 * ECMA-262 v5, 15.2.3.4 293 * 294 * @return ecma value 295 * Returned value must be freed with ecma_free_value. 296 */ 297static ecma_value_t 298ecma_builtin_object_object_get_own_property_names (ecma_object_t *obj_p) /**< routine's argument */ 299{ 300 return ecma_builtin_helper_object_get_properties (obj_p, ECMA_LIST_NO_OPTS); 301} /* ecma_builtin_object_object_get_own_property_names */ 302 303#if ENABLED (JERRY_ES2015) 304 305/** 306 * The Object object's 'getOwnPropertySymbols' routine 307 * 308 * See also: 309 * ECMA-262 v6, 19.1.2.7 310 * 311 * @return ecma value 312 * Returned value must be freed with ecma_free_value. 313 */ 314static ecma_value_t 315ecma_builtin_object_object_get_own_property_symbols (ecma_object_t *obj_p) /**< routine's argument */ 316{ 317 return ecma_builtin_helper_object_get_properties (obj_p, ECMA_LIST_SYMBOLS_ONLY); 318} /* ecma_builtin_object_object_get_own_property_symbols */ 319 320#endif /* ENABLED (JERRY_ES2015) */ 321 322/** 323 * SetIntegrityLevel operation 324 * 325 * See also: 326 * ECMA-262 v6, 7.3.14 327 * 328 * @return ECMA_VALUE_ERROR - if the operation raised an error 329 * ECMA_VALUE_{TRUE/FALSE} - depends on whether the integrity level has been set sucessfully 330 */ 331static ecma_value_t 332ecma_builtin_object_set_integrity_level (ecma_object_t *obj_p, /**< object */ 333 bool is_seal) /**< true - set "sealed" 334 * false - set "frozen" */ 335{ 336 /* 3. */ 337#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 338 if (ECMA_OBJECT_IS_PROXY (obj_p)) 339 { 340 ecma_value_t status = ecma_proxy_object_prevent_extensions (obj_p); 341 342 if (!ecma_is_value_true (status)) 343 { 344 return status; 345 } 346 } 347 else 348 { 349#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 350 ecma_op_ordinary_object_prevent_extensions (obj_p); 351#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 352 } 353#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 354 355 /* 6. */ 356 uint32_t opts = ECMA_LIST_CONVERT_FAST_ARRAYS; 357#if ENABLED (JERRY_ES2015) 358 opts |= ECMA_LIST_SYMBOLS; 359#endif /* ENABLED (JERRY_ES2015) */ 360 361 ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, opts); 362 363#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 364 if (props_p == NULL) 365 { 366 return ECMA_VALUE_ERROR; 367 } 368#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 369 370 ecma_value_t *buffer_p = props_p->buffer_p; 371 372 if (is_seal) 373 { 374 /* 8.a */ 375 for (uint32_t i = 0; i < props_p->item_count; i++) 376 { 377 ecma_string_t *property_name_p = ecma_get_prop_name_from_value (buffer_p[i]); 378 379 ecma_property_descriptor_t prop_desc; 380 ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc); 381 382#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 383 if (ECMA_IS_VALUE_ERROR (status)) 384 { 385 break; 386 } 387#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 388 389 if (ecma_is_value_false (status)) 390 { 391 continue; 392 } 393 394 prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE; 395 prop_desc.flags |= ECMA_PROP_IS_THROW; 396 397 /* 8.a.i */ 398 ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, 399 property_name_p, 400 &prop_desc); 401 402 ecma_free_property_descriptor (&prop_desc); 403 404 /* 8.a.ii */ 405 if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) 406 { 407 ecma_collection_free (props_p); 408 return define_own_prop_ret; 409 } 410 411 ecma_free_value (define_own_prop_ret); 412 } 413 } 414 else 415 { 416 /* 9.a */ 417 for (uint32_t i = 0; i < props_p->item_count; i++) 418 { 419 ecma_string_t *property_name_p = ecma_get_prop_name_from_value (buffer_p[i]); 420 421 /* 9.1 */ 422 ecma_property_descriptor_t prop_desc; 423 ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc); 424 425#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 426 if (ECMA_IS_VALUE_ERROR (status)) 427 { 428 break; 429 } 430#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 431 432 if (ecma_is_value_false (status)) 433 { 434 continue; 435 } 436 437 /* 9.2 */ 438 if ((prop_desc.flags & (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE)) 439 == (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE)) 440 { 441 prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_WRITABLE; 442 } 443 444 prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE; 445 prop_desc.flags |= ECMA_PROP_IS_THROW; 446 447 /* 9.3 */ 448 ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, 449 property_name_p, 450 &prop_desc); 451 452 ecma_free_property_descriptor (&prop_desc); 453 454 /* 9.4 */ 455 if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) 456 { 457 ecma_collection_free (props_p); 458 return define_own_prop_ret; 459 } 460 461 ecma_free_value (define_own_prop_ret); 462 } 463 464 } 465 466 ecma_collection_free (props_p); 467 468 return ECMA_VALUE_TRUE; 469} /* ecma_builtin_object_set_integrity_level */ 470 471/** 472 * The Object object's 'seal' routine 473 * 474 * See also: 475 * ECMA-262 v5, 15.2.3.8 476 * 477 * @return ecma value 478 * Returned value must be freed with ecma_free_value. 479 */ 480static ecma_value_t 481ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument */ 482{ 483 ecma_value_t status = ecma_builtin_object_set_integrity_level (obj_p, true); 484 485 if (ECMA_IS_VALUE_ERROR (status)) 486 { 487 return status; 488 } 489 490#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 491 if (ecma_is_value_false (status)) 492 { 493 return ecma_raise_type_error (ECMA_ERR_MSG ("Object cannot be sealed.")); 494 } 495#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 496 497 /* 4. */ 498 ecma_ref_object (obj_p); 499 return ecma_make_object_value (obj_p); 500} /* ecma_builtin_object_object_seal */ 501 502/** 503 * The Object object's 'freeze' routine 504 * 505 * See also: 506 * ECMA-262 v5, 15.2.3.9 507 * 508 * @return ecma value 509 * Returned value must be freed with ecma_free_value. 510 */ 511static ecma_value_t 512ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument */ 513{ 514 ecma_value_t status = ecma_builtin_object_set_integrity_level (obj_p, false); 515 516 if (ECMA_IS_VALUE_ERROR (status)) 517 { 518 return status; 519 } 520 521#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 522 if (ecma_is_value_false (status)) 523 { 524 return ecma_raise_type_error (ECMA_ERR_MSG ("Object cannot be frozen.")); 525 } 526#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 527 528 /* 4. */ 529 ecma_ref_object (obj_p); 530 return ecma_make_object_value (obj_p); 531} /* ecma_builtin_object_object_freeze */ 532 533/** 534 * The Object object's 'preventExtensions' routine 535 * 536 * See also: 537 * ECMA-262 v5, 15.2.3.10 538 * 539 * @return ecma value 540 * Returned value must be freed with ecma_free_value. 541 */ 542ecma_value_t 543ecma_builtin_object_object_prevent_extensions (ecma_object_t *obj_p) /**< routine's argument */ 544{ 545#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 546 if (ECMA_OBJECT_IS_PROXY (obj_p)) 547 { 548 ecma_value_t status = ecma_proxy_object_prevent_extensions (obj_p); 549 550 if (ECMA_IS_VALUE_ERROR (status)) 551 { 552 return status; 553 } 554 555 if (ecma_is_value_false (status)) 556 { 557 return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot set [[Extensible]] property of the object.")); 558 } 559 560 JERRY_ASSERT (ecma_is_value_true (status)); 561 } 562 else 563 { 564#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 565 ecma_op_ordinary_object_prevent_extensions (obj_p); 566#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 567 } 568#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 569 ecma_ref_object (obj_p); 570 571 return ecma_make_object_value (obj_p); 572} /* ecma_builtin_object_object_prevent_extensions */ 573 574/** 575 * The Object object's 'isSealed' and 'isFrozen' routines 576 * 577 * See also: 578 * ECMA-262 v5, 15.2.3.11 579 * ECMA-262 v5, 15.2.3.12 580 * 581 * @return ecma value 582 * Returned value must be freed with ecma_free_value. 583 */ 584static ecma_value_t 585ecma_builtin_object_test_integrity_level (ecma_object_t *obj_p, /**< routine's argument */ 586 int mode) /**< routine mode */ 587{ 588 JERRY_ASSERT (mode == ECMA_OBJECT_ROUTINE_IS_FROZEN || mode == ECMA_OBJECT_ROUTINE_IS_SEALED); 589 590 /* 3. */ 591 bool is_extensible; 592#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 593 if (ECMA_OBJECT_IS_PROXY (obj_p)) 594 { 595 ecma_value_t status = ecma_proxy_object_is_extensible (obj_p); 596 597 if (ECMA_IS_VALUE_ERROR (status)) 598 { 599 return status; 600 } 601 602 is_extensible = ecma_is_value_true (status); 603 } 604 else 605 { 606#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 607 is_extensible = ecma_op_ordinary_object_is_extensible (obj_p); 608#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 609 } 610#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 611 612 if (is_extensible) 613 { 614 return ECMA_VALUE_FALSE; 615 } 616 617 /* the value can be updated in the loop below */ 618 ecma_value_t ret_value = ECMA_VALUE_TRUE; 619 620 /* 2. */ 621 ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS); 622 623#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 624 if (props_p == NULL) 625 { 626 return ECMA_VALUE_ERROR; 627 } 628#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 629 630 ecma_value_t *buffer_p = props_p->buffer_p; 631 632 for (uint32_t i = 0; i < props_p->item_count; i++) 633 { 634 ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); 635 636 /* 2.a */ 637 ecma_property_descriptor_t prop_desc; 638 ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc); 639 640#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 641 if (ECMA_IS_VALUE_ERROR (status)) 642 { 643 ret_value = status; 644 break; 645 } 646#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 647 648 if (ecma_is_value_false (status)) 649 { 650 continue; 651 } 652 653 bool is_writable_data = ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE)) 654 == (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE)); 655 bool is_configurable = (prop_desc.flags & ECMA_PROP_IS_CONFIGURABLE); 656 657 ecma_free_property_descriptor (&prop_desc); 658 659 /* 2.b for isFrozen */ 660 /* 2.b for isSealed, 2.c for isFrozen */ 661 if ((mode == ECMA_OBJECT_ROUTINE_IS_FROZEN && is_writable_data) 662 || is_configurable) 663 { 664 ret_value = ECMA_VALUE_FALSE; 665 break; 666 } 667 } 668 669 ecma_collection_free (props_p); 670 671 return ret_value; 672} /* ecma_builtin_object_test_integrity_level */ 673 674/** 675 * The Object object's 'isExtensible' routine 676 * 677 * See also: 678 * ECMA-262 v5, 15.2.3.13 679 * 680 * @return ecma value 681 * Returned value must be freed with ecma_free_value. 682 */ 683ecma_value_t 684ecma_builtin_object_object_is_extensible (ecma_object_t *obj_p) /**< routine's argument */ 685{ 686#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 687 if (ECMA_OBJECT_IS_PROXY (obj_p)) 688 { 689 return ecma_proxy_object_is_extensible (obj_p); 690 } 691#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 692 693 return ecma_make_boolean_value (ecma_op_ordinary_object_is_extensible (obj_p)); 694} /* ecma_builtin_object_object_is_extensible */ 695 696/** 697 * The Object object's 'keys' routine 698 * 699 * See also: 700 * ECMA-262 v5, 15.2.3.14 701 * 702 * @return ecma value 703 * Returned value must be freed with ecma_free_value. 704 */ 705static ecma_value_t 706ecma_builtin_object_object_keys (ecma_object_t *obj_p) /**< routine's argument */ 707{ 708 return ecma_builtin_helper_object_get_properties (obj_p, ECMA_LIST_ENUMERABLE); 709} /* ecma_builtin_object_object_keys */ 710 711/** 712 * The Object object's 'getOwnPropertyDescriptor' routine 713 * 714 * See also: 715 * ECMA-262 v5, 15.2.3.3 716 * 717 * @return ecma value 718 * Returned value must be freed with ecma_free_value. 719 */ 720ecma_value_t 721ecma_builtin_object_object_get_own_property_descriptor (ecma_object_t *obj_p, /**< routine's first argument */ 722 ecma_string_t *name_str_p) /**< routine's second argument */ 723{ 724 /* 3. */ 725 ecma_property_descriptor_t prop_desc; 726 727 ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, name_str_p, &prop_desc); 728 729#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 730 if (ECMA_IS_VALUE_ERROR (status)) 731 { 732 return status; 733 } 734#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 735 736 if (ecma_is_value_true (status)) 737 { 738 /* 4. */ 739 ecma_object_t *desc_obj_p = ecma_op_from_property_descriptor (&prop_desc); 740 741 ecma_free_property_descriptor (&prop_desc); 742 743 return ecma_make_object_value (desc_obj_p); 744 } 745 746 return ECMA_VALUE_UNDEFINED; 747} /* ecma_builtin_object_object_get_own_property_descriptor */ 748 749/** 750 * The Object object's 'defineProperties' routine 751 * 752 * See also: 753 * ECMA-262 v5, 15.2.3.7 754 * 755 * @return ecma value 756 * Returned value must be freed with ecma_free_value. 757 */ 758static ecma_value_t 759ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine's first argument */ 760 ecma_value_t arg2) /**< routine's second argument */ 761{ 762 /* 2. */ 763 ecma_value_t props = ecma_op_to_object (arg2); 764 765 if (ECMA_IS_VALUE_ERROR (props)) 766 { 767 return props; 768 } 769 770 ecma_object_t *props_p = ecma_get_object_from_value (props); 771 /* 3. */ 772 ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_CONVERT_FAST_ARRAYS 773 | ECMA_LIST_ENUMERABLE); 774 ecma_value_t ret_value = ECMA_VALUE_ERROR; 775 776#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 777 if (prop_names_p == NULL) 778 { 779 ecma_deref_object (props_p); 780 return ret_value; 781 } 782#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 783 784 ecma_value_t *buffer_p = prop_names_p->buffer_p; 785 786 /* 4. */ 787 JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, prop_names_p->item_count, ecma_property_descriptor_t); 788 uint32_t property_descriptor_number = 0; 789 790 for (uint32_t i = 0; i < prop_names_p->item_count; i++) 791 { 792 /* 5.a */ 793 ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (buffer_p[i])); 794 795 if (ECMA_IS_VALUE_ERROR (desc_obj)) 796 { 797 goto cleanup; 798 } 799 800 /* 5.b */ 801 ecma_value_t conv_result = ecma_op_to_property_descriptor (desc_obj, 802 &property_descriptors[property_descriptor_number]); 803 804 property_descriptors[property_descriptor_number].flags |= ECMA_PROP_IS_THROW; 805 806 ecma_free_value (desc_obj); 807 808 if (ECMA_IS_VALUE_ERROR (conv_result)) 809 { 810 goto cleanup; 811 } 812 813 property_descriptor_number++; 814 815 ecma_free_value (conv_result); 816 } 817 818 /* 6. */ 819 buffer_p = prop_names_p->buffer_p; 820 821 for (uint32_t i = 0; i < prop_names_p->item_count; i++) 822 { 823 ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, 824 ecma_get_string_from_value (buffer_p[i]), 825 &property_descriptors[i]); 826 if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) 827 { 828 goto cleanup; 829 } 830 831 ecma_free_value (define_own_prop_ret); 832 } 833 834 ecma_ref_object (obj_p); 835 ret_value = ecma_make_object_value (obj_p); 836 837cleanup: 838 /* Clean up. */ 839 for (uint32_t index = 0; 840 index < property_descriptor_number; 841 index++) 842 { 843 ecma_free_property_descriptor (&property_descriptors[index]); 844 } 845 846 JMEM_FINALIZE_LOCAL_ARRAY (property_descriptors); 847 848 ecma_collection_free (prop_names_p); 849 850 ecma_deref_object (props_p); 851 852 return ret_value; 853} /* ecma_builtin_object_object_define_properties */ 854 855/** 856 * The Object object's 'create' routine 857 * 858 * See also: 859 * ECMA-262 v5, 15.2.3.5 860 * 861 * @return ecma value 862 * Returned value must be freed with ecma_free_value. 863 */ 864static ecma_value_t 865ecma_builtin_object_object_create (ecma_value_t arg1, /**< routine's first argument */ 866 ecma_value_t arg2) /**< routine's second argument */ 867{ 868 /* 1. */ 869 if (!ecma_is_value_object (arg1) && !ecma_is_value_null (arg1)) 870 { 871 return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object.")); 872 } 873 874 ecma_object_t *obj_p = NULL; 875 876 if (!ecma_is_value_null (arg1)) 877 { 878 obj_p = ecma_get_object_from_value (arg1); 879 } 880 /* 2-3. */ 881 ecma_object_t *result_obj_p = ecma_op_create_object_object_noarg_and_set_prototype (obj_p); 882 883 /* 4. */ 884 if (!ecma_is_value_undefined (arg2)) 885 { 886 ecma_value_t obj = ecma_builtin_object_object_define_properties (result_obj_p, arg2); 887 888 if (ECMA_IS_VALUE_ERROR (obj)) 889 { 890 ecma_deref_object (result_obj_p); 891 return obj; 892 } 893 894 ecma_free_value (obj); 895 } 896 897 /* 5. */ 898 return ecma_make_object_value (result_obj_p); 899} /* ecma_builtin_object_object_create */ 900 901/** 902 * The Object object's 'defineProperty' routine 903 * 904 * See also: 905 * ECMA-262 v5, 15.2.3.6 906 * 907 * @return ecma value 908 * Returned value must be freed with ecma_free_value. 909 */ 910ecma_value_t 911ecma_builtin_object_object_define_property (ecma_object_t *obj_p, /**< routine's first argument */ 912 ecma_string_t *name_str_p, /**< routine's second argument */ 913 ecma_value_t arg3) /**< routine's third argument */ 914{ 915 ecma_property_descriptor_t prop_desc; 916 917 ecma_value_t conv_result = ecma_op_to_property_descriptor (arg3, &prop_desc); 918 919 if (ECMA_IS_VALUE_ERROR (conv_result)) 920 { 921 return conv_result; 922 } 923 924 prop_desc.flags |= ECMA_PROP_IS_THROW; 925 926 ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, 927 name_str_p, 928 &prop_desc); 929 930 ecma_free_property_descriptor (&prop_desc); 931 ecma_free_value (conv_result); 932 933 if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) 934 { 935 return define_own_prop_ret; 936 } 937 938 ecma_ref_object (obj_p); 939 ecma_free_value (define_own_prop_ret); 940 941 return ecma_make_object_value (obj_p); 942} /* ecma_builtin_object_object_define_property */ 943 944#if ENABLED (JERRY_ES2015) 945 946/** 947 * The Object object's 'assign' routine 948 * 949 * See also: 950 * ECMA-262 v6, 19.1.2.1 951 * 952 * @return ecma value 953 * Returned value must be freed with ecma_free_value. 954 */ 955static ecma_value_t 956ecma_builtin_object_object_assign (ecma_object_t *target_p, /**< target object */ 957 const ecma_value_t arguments_list_p[], /**< arguments list */ 958 ecma_length_t arguments_list_len) /**< number of arguments */ 959{ 960 ecma_value_t ret_value = ECMA_VALUE_EMPTY; 961 962 /* 4-5. */ 963 for (uint32_t i = 0; i < arguments_list_len && ecma_is_value_empty (ret_value); i++) 964 { 965 ecma_value_t next_source = arguments_list_p[i]; 966 967 /* 5.a */ 968 if (ecma_is_value_undefined (next_source) || ecma_is_value_null (next_source)) 969 { 970 continue; 971 } 972 973 /* 5.b.i */ 974 ecma_value_t from_value = ecma_op_to_object (next_source); 975 /* null and undefied cases are handled above, so this must be a valid object */ 976 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (from_value)); 977 978 ecma_object_t *from_obj_p = ecma_get_object_from_value (from_value); 979 980 /* 5.b.iii */ 981 ecma_collection_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS 982 | ECMA_LIST_ENUMERABLE 983 | ECMA_LIST_SYMBOLS); 984#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 985 if (props_p == NULL) 986 { 987 ecma_deref_object (from_obj_p); 988 return ECMA_VALUE_ERROR; 989 } 990#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 991 992 ecma_value_t *buffer_p = props_p->buffer_p; 993 994 for (uint32_t j = 0; (j < props_p->item_count) && ecma_is_value_empty (ret_value); j++) 995 { 996 ecma_string_t *property_name_p = ecma_get_prop_name_from_value (buffer_p[j]); 997 998 /* 5.c.i-ii */ 999 ecma_property_descriptor_t prop_desc; 1000 ecma_value_t desc_status = ecma_op_object_get_own_property_descriptor (from_obj_p, property_name_p, &prop_desc); 1001 1002#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1003 if (ECMA_IS_VALUE_ERROR (desc_status)) 1004 { 1005 ret_value = desc_status; 1006 break; 1007 } 1008#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1009 1010 if (ecma_is_value_false (desc_status)) 1011 { 1012 continue; 1013 } 1014 1015 /* 5.c.iii */ 1016 if ((prop_desc.flags & ECMA_PROP_IS_ENUMERABLE) 1017 && (((prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED) && !ecma_is_value_undefined (prop_desc.value)) 1018 || (prop_desc.flags & ECMA_PROP_IS_GET_DEFINED))) 1019 { 1020 /* 5.c.iii.1 */ 1021 ecma_value_t prop_value = ecma_op_object_get (from_obj_p, property_name_p); 1022 1023 /* 5.c.iii.2 */ 1024 if (ECMA_IS_VALUE_ERROR (prop_value)) 1025 { 1026 ret_value = prop_value; 1027 } 1028 else 1029 { 1030 /* 5.c.iii.3 */ 1031 ecma_value_t status = ecma_op_object_put (target_p, property_name_p, prop_value, true); 1032 1033 /* 5.c.iii.4 */ 1034 if (ECMA_IS_VALUE_ERROR (status)) 1035 { 1036 ret_value = status; 1037 } 1038 } 1039 1040 ecma_free_value (prop_value); 1041 ecma_free_property_descriptor (&prop_desc); 1042 } 1043 } 1044 1045 ecma_deref_object (from_obj_p); 1046 ecma_collection_free (props_p); 1047 } 1048 1049 /* 6. */ 1050 if (ecma_is_value_empty (ret_value)) 1051 { 1052 ecma_ref_object (target_p); 1053 return ecma_make_object_value (target_p); 1054 } 1055 1056 return ret_value; 1057} /* ecma_builtin_object_object_assign */ 1058 1059/** 1060 * The Object object's 'is' routine 1061 * 1062 * See also: 1063 * ECMA-262 v6, 19.1.2.10 1064 * 1065 * @return ecma value 1066 * Returned value must be freed with ecma_free_value. 1067 */ 1068static ecma_value_t 1069ecma_builtin_object_object_is (ecma_value_t arg1, /**< routine's first argument */ 1070 ecma_value_t arg2) /**< routine's second argument */ 1071{ 1072 return ecma_op_same_value (arg1, arg2) ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE; 1073} /* ecma_builtin_object_object_is */ 1074 1075#endif /* ENABLED (JERRY_ES2015) */ 1076 1077/** 1078 * Dispatcher of the built-in's routines 1079 * 1080 * @return ecma value 1081 * Returned value must be freed with ecma_free_value. 1082 */ 1083ecma_value_t 1084ecma_builtin_object_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine 1085 * identifier */ 1086 ecma_value_t this_arg, /**< 'this' argument value */ 1087 const ecma_value_t arguments_list_p[], /**< list of arguments 1088 * passed to routine */ 1089 ecma_length_t arguments_number) /**< length of arguments' list */ 1090{ 1091 JERRY_UNUSED (this_arg); 1092 JERRY_UNUSED (arguments_list_p); 1093 JERRY_UNUSED (arguments_number); 1094 1095 ecma_value_t arg1 = arguments_list_p[0]; 1096 ecma_value_t arg2 = arguments_list_p[1]; 1097 1098 /* No specialization for the arguments */ 1099 switch (builtin_routine_id) 1100 { 1101 case ECMA_OBJECT_ROUTINE_CREATE: 1102 { 1103 return ecma_builtin_object_object_create (arg1, arg2); 1104 } 1105#if ENABLED (JERRY_ES2015) 1106 case ECMA_OBJECT_ROUTINE_SET_PROTOTYPE_OF: 1107 { 1108 return ecma_builtin_object_object_set_prototype_of (arg1, arg2); 1109 } 1110 case ECMA_OBJECT_ROUTINE_IS: 1111 { 1112 return ecma_builtin_object_object_is (arg1, arg2); 1113 } 1114#endif /* ENABLED (JERRY_ES2015) */ 1115 default: 1116 { 1117 break; 1118 } 1119 } 1120 1121 ecma_object_t *obj_p; 1122#if !ENABLED (JERRY_ES2015) 1123 if (!ecma_is_value_object (arg1)) 1124 { 1125 return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object.")); 1126 } 1127#endif /* !ENABLED (JERRY_ES2015) */ 1128 1129 if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES) 1130 { 1131#if ENABLED (JERRY_ES2015) 1132 if (!ecma_is_value_object (arg1)) 1133 { 1134 return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object.")); 1135 } 1136#endif /* ENABLED (JERRY_ES2015) */ 1137 1138 obj_p = ecma_get_object_from_value (arg1); 1139 1140 if (builtin_routine_id == ECMA_OBJECT_ROUTINE_DEFINE_PROPERTY) 1141 { 1142 ecma_string_t *prop_name_p = ecma_op_to_prop_name (arg2); 1143 1144 if (prop_name_p == NULL) 1145 { 1146 return ECMA_VALUE_ERROR; 1147 } 1148 1149 ecma_value_t result = ecma_builtin_object_object_define_property (obj_p, prop_name_p, arguments_list_p[2]); 1150 1151 ecma_deref_ecma_string (prop_name_p); 1152 return result; 1153 } 1154 1155 JERRY_ASSERT (builtin_routine_id == ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES); 1156 return ecma_builtin_object_object_define_properties (obj_p, arg2); 1157 } 1158 else if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_KEYS) 1159 { 1160#if ENABLED (JERRY_ES2015) 1161 ecma_value_t object = ecma_op_to_object (arg1); 1162 if (ECMA_IS_VALUE_ERROR (object)) 1163 { 1164 return object; 1165 } 1166 1167 obj_p = ecma_get_object_from_value (object); 1168#else /* !ENABLED (JERRY_ES2015) */ 1169 obj_p = ecma_get_object_from_value (arg1); 1170#endif /* ENABLED (JERRY_ES2015) */ 1171 1172 ecma_value_t result; 1173 switch (builtin_routine_id) 1174 { 1175 case ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF: 1176 { 1177 result = ecma_builtin_object_object_get_prototype_of (obj_p); 1178 break; 1179 } 1180 case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES: 1181 { 1182 result = ecma_builtin_object_object_get_own_property_names (obj_p); 1183 break; 1184 } 1185#if ENABLED (JERRY_ES2015) 1186 case ECMA_OBJECT_ROUTINE_ASSIGN: 1187 { 1188 result = ecma_builtin_object_object_assign (obj_p, arguments_list_p + 1, arguments_number - 1); 1189 break; 1190 } 1191 case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS: 1192 { 1193 result = ecma_builtin_object_object_get_own_property_symbols (obj_p); 1194 break; 1195 } 1196#endif /* ENABLED (JERRY_ES2015) */ 1197 case ECMA_OBJECT_ROUTINE_KEYS: 1198 { 1199 result = ecma_builtin_object_object_keys (obj_p); 1200 break; 1201 } 1202 case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR: 1203 { 1204 ecma_string_t *prop_name_p = ecma_op_to_prop_name (arg2); 1205 1206 if (prop_name_p == NULL) 1207 { 1208 result = ECMA_VALUE_ERROR; 1209 break; 1210 } 1211 1212 result = ecma_builtin_object_object_get_own_property_descriptor (obj_p, prop_name_p); 1213 ecma_deref_ecma_string (prop_name_p); 1214 break; 1215 } 1216 default: 1217 { 1218 JERRY_UNREACHABLE (); 1219 } 1220 } 1221 1222#if ENABLED (JERRY_ES2015) 1223 ecma_deref_object (obj_p); 1224#endif /* ENABLED (JERRY_ES2015) */ 1225 return result; 1226 } 1227 else if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_SEAL) 1228 { 1229#if ENABLED (JERRY_ES2015) 1230 if (!ecma_is_value_object (arg1)) 1231 { 1232 return ecma_copy_value (arg1); 1233 } 1234#endif /* ENABLED (JERRY_ES2015) */ 1235 1236 obj_p = ecma_get_object_from_value (arg1); 1237 switch (builtin_routine_id) 1238 { 1239 case ECMA_OBJECT_ROUTINE_SEAL: 1240 { 1241 return ecma_builtin_object_object_seal (obj_p); 1242 } 1243 case ECMA_OBJECT_ROUTINE_FREEZE: 1244 { 1245 return ecma_builtin_object_object_freeze (obj_p); 1246 } 1247 case ECMA_OBJECT_ROUTINE_PREVENT_EXTENSIONS: 1248 { 1249 return ecma_builtin_object_object_prevent_extensions (obj_p); 1250 } 1251 default: 1252 { 1253 JERRY_UNREACHABLE (); 1254 } 1255 } 1256 } 1257 else 1258 { 1259 JERRY_ASSERT (builtin_routine_id <= ECMA_OBJECT_ROUTINE_IS_SEALED); 1260#if ENABLED (JERRY_ES2015) 1261 if (!ecma_is_value_object (arg1)) 1262 { 1263 return ecma_make_boolean_value (builtin_routine_id != ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE); 1264 } 1265#endif /* ENABLED (JERRY_ES2015) */ 1266 1267 obj_p = ecma_get_object_from_value (arg1); 1268 switch (builtin_routine_id) 1269 { 1270 case ECMA_OBJECT_ROUTINE_IS_SEALED: 1271 case ECMA_OBJECT_ROUTINE_IS_FROZEN: 1272 { 1273 return ecma_builtin_object_test_integrity_level (obj_p, builtin_routine_id); 1274 } 1275 case ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE: 1276 { 1277 return ecma_builtin_object_object_is_extensible (obj_p); 1278 } 1279 default: 1280 { 1281 JERRY_UNREACHABLE (); 1282 } 1283 } 1284 } 1285} /* ecma_builtin_object_dispatch_routine */ 1286 1287/** 1288 * @} 1289 * @} 1290 * @} 1291 */ 1292