| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file relies on the fact that the following declarations have been made | 5 // This file relies on the fact that the following declarations have been made |
| 6 // in runtime.js: | 6 // in runtime.js: |
| 7 // var $Object = global.Object; | 7 // var $Object = global.Object; |
| 8 // var $Boolean = global.Boolean; | 8 // var $Boolean = global.Boolean; |
| 9 // var $Number = global.Number; | 9 // var $Number = global.Number; |
| 10 // var $Function = global.Function; | 10 // var $Function = global.Function; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 } | 293 } |
| 294 | 294 |
| 295 | 295 |
| 296 // Extensions for providing property getters and setters. | 296 // Extensions for providing property getters and setters. |
| 297 function ObjectDefineGetter(name, fun) { | 297 function ObjectDefineGetter(name, fun) { |
| 298 var receiver = this; | 298 var receiver = this; |
| 299 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 299 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 300 receiver = %GlobalProxy(global); | 300 receiver = %GlobalProxy(global); |
| 301 } | 301 } |
| 302 if (!IS_SPEC_FUNCTION(fun)) { | 302 if (!IS_SPEC_FUNCTION(fun)) { |
| 303 throw new $TypeError( | 303 throw MakeTypeError(kObjectGetterExpectingFunction); |
| 304 'Object.prototype.__defineGetter__: Expecting function'); | |
| 305 } | 304 } |
| 306 var desc = new PropertyDescriptor(); | 305 var desc = new PropertyDescriptor(); |
| 307 desc.setGet(fun); | 306 desc.setGet(fun); |
| 308 desc.setEnumerable(true); | 307 desc.setEnumerable(true); |
| 309 desc.setConfigurable(true); | 308 desc.setConfigurable(true); |
| 310 DefineOwnProperty(TO_OBJECT_INLINE(receiver), ToName(name), desc, false); | 309 DefineOwnProperty(TO_OBJECT_INLINE(receiver), ToName(name), desc, false); |
| 311 } | 310 } |
| 312 | 311 |
| 313 | 312 |
| 314 function ObjectLookupGetter(name) { | 313 function ObjectLookupGetter(name) { |
| 315 var receiver = this; | 314 var receiver = this; |
| 316 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 315 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 317 receiver = %GlobalProxy(global); | 316 receiver = %GlobalProxy(global); |
| 318 } | 317 } |
| 319 return %LookupAccessor(TO_OBJECT_INLINE(receiver), ToName(name), GETTER); | 318 return %LookupAccessor(TO_OBJECT_INLINE(receiver), ToName(name), GETTER); |
| 320 } | 319 } |
| 321 | 320 |
| 322 | 321 |
| 323 function ObjectDefineSetter(name, fun) { | 322 function ObjectDefineSetter(name, fun) { |
| 324 var receiver = this; | 323 var receiver = this; |
| 325 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 324 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 326 receiver = %GlobalProxy(global); | 325 receiver = %GlobalProxy(global); |
| 327 } | 326 } |
| 328 if (!IS_SPEC_FUNCTION(fun)) { | 327 if (!IS_SPEC_FUNCTION(fun)) { |
| 329 throw new $TypeError( | 328 throw MakeTypeError(kObjectSetterExpectingFunction); |
| 330 'Object.prototype.__defineSetter__: Expecting function'); | |
| 331 } | 329 } |
| 332 var desc = new PropertyDescriptor(); | 330 var desc = new PropertyDescriptor(); |
| 333 desc.setSet(fun); | 331 desc.setSet(fun); |
| 334 desc.setEnumerable(true); | 332 desc.setEnumerable(true); |
| 335 desc.setConfigurable(true); | 333 desc.setConfigurable(true); |
| 336 DefineOwnProperty(TO_OBJECT_INLINE(receiver), ToName(name), desc, false); | 334 DefineOwnProperty(TO_OBJECT_INLINE(receiver), ToName(name), desc, false); |
| 337 } | 335 } |
| 338 | 336 |
| 339 | 337 |
| 340 function ObjectLookupSetter(name) { | 338 function ObjectLookupSetter(name) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 } | 421 } |
| 424 if (desc.hasConfigurable()) { | 422 if (desc.hasConfigurable()) { |
| 425 %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE); | 423 %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE); |
| 426 } | 424 } |
| 427 return obj; | 425 return obj; |
| 428 } | 426 } |
| 429 | 427 |
| 430 | 428 |
| 431 // ES5 8.10.5. | 429 // ES5 8.10.5. |
| 432 function ToPropertyDescriptor(obj) { | 430 function ToPropertyDescriptor(obj) { |
| 433 if (!IS_SPEC_OBJECT(obj)) { | 431 if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError(kPropertyDescObject, obj); |
| 434 throw MakeTypeError("property_desc_object", [obj]); | 432 |
| 435 } | |
| 436 var desc = new PropertyDescriptor(); | 433 var desc = new PropertyDescriptor(); |
| 437 | 434 |
| 438 if ("enumerable" in obj) { | 435 if ("enumerable" in obj) { |
| 439 desc.setEnumerable(ToBoolean(obj.enumerable)); | 436 desc.setEnumerable(ToBoolean(obj.enumerable)); |
| 440 } | 437 } |
| 441 | 438 |
| 442 if ("configurable" in obj) { | 439 if ("configurable" in obj) { |
| 443 desc.setConfigurable(ToBoolean(obj.configurable)); | 440 desc.setConfigurable(ToBoolean(obj.configurable)); |
| 444 } | 441 } |
| 445 | 442 |
| 446 if ("value" in obj) { | 443 if ("value" in obj) { |
| 447 desc.setValue(obj.value); | 444 desc.setValue(obj.value); |
| 448 } | 445 } |
| 449 | 446 |
| 450 if ("writable" in obj) { | 447 if ("writable" in obj) { |
| 451 desc.setWritable(ToBoolean(obj.writable)); | 448 desc.setWritable(ToBoolean(obj.writable)); |
| 452 } | 449 } |
| 453 | 450 |
| 454 if ("get" in obj) { | 451 if ("get" in obj) { |
| 455 var get = obj.get; | 452 var get = obj.get; |
| 456 if (!IS_UNDEFINED(get) && !IS_SPEC_FUNCTION(get)) { | 453 if (!IS_UNDEFINED(get) && !IS_SPEC_FUNCTION(get)) { |
| 457 throw MakeTypeError("getter_must_be_callable", [get]); | 454 throw MakeTypeError(kObjectGetterCallable, get); |
| 458 } | 455 } |
| 459 desc.setGet(get); | 456 desc.setGet(get); |
| 460 } | 457 } |
| 461 | 458 |
| 462 if ("set" in obj) { | 459 if ("set" in obj) { |
| 463 var set = obj.set; | 460 var set = obj.set; |
| 464 if (!IS_UNDEFINED(set) && !IS_SPEC_FUNCTION(set)) { | 461 if (!IS_UNDEFINED(set) && !IS_SPEC_FUNCTION(set)) { |
| 465 throw MakeTypeError("setter_must_be_callable", [set]); | 462 throw MakeTypeError(kObjectSetterCallable, set); |
| 466 } | 463 } |
| 467 desc.setSet(set); | 464 desc.setSet(set); |
| 468 } | 465 } |
| 469 | 466 |
| 470 if (IsInconsistentDescriptor(desc)) { | 467 if (IsInconsistentDescriptor(desc)) { |
| 471 throw MakeTypeError("value_and_accessor", [obj]); | 468 throw MakeTypeError(kValueAndAccessor, obj); |
| 472 } | 469 } |
| 473 return desc; | 470 return desc; |
| 474 } | 471 } |
| 475 | 472 |
| 476 | 473 |
| 477 // For Harmony proxies. | 474 // For Harmony proxies. |
| 478 function ToCompletePropertyDescriptor(obj) { | 475 function ToCompletePropertyDescriptor(obj) { |
| 479 var desc = ToPropertyDescriptor(obj); | 476 var desc = ToPropertyDescriptor(obj); |
| 480 if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) { | 477 if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) { |
| 481 if (!desc.hasValue()) desc.setValue(UNDEFINED); | 478 if (!desc.hasValue()) desc.setValue(UNDEFINED); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 | 608 |
| 612 return desc; | 609 return desc; |
| 613 } | 610 } |
| 614 | 611 |
| 615 | 612 |
| 616 // For Harmony proxies. | 613 // For Harmony proxies. |
| 617 function GetTrap(handler, name, defaultTrap) { | 614 function GetTrap(handler, name, defaultTrap) { |
| 618 var trap = handler[name]; | 615 var trap = handler[name]; |
| 619 if (IS_UNDEFINED(trap)) { | 616 if (IS_UNDEFINED(trap)) { |
| 620 if (IS_UNDEFINED(defaultTrap)) { | 617 if (IS_UNDEFINED(defaultTrap)) { |
| 621 throw MakeTypeError("handler_trap_missing", [handler, name]); | 618 throw MakeTypeError(kProxyHandlerTrapMissing, handler, name); |
| 622 } | 619 } |
| 623 trap = defaultTrap; | 620 trap = defaultTrap; |
| 624 } else if (!IS_SPEC_FUNCTION(trap)) { | 621 } else if (!IS_SPEC_FUNCTION(trap)) { |
| 625 throw MakeTypeError("handler_trap_must_be_callable", [handler, name]); | 622 throw MakeTypeError(kProxyHandlerTrapMustBeCallable, handler, name); |
| 626 } | 623 } |
| 627 return trap; | 624 return trap; |
| 628 } | 625 } |
| 629 | 626 |
| 630 | 627 |
| 631 function CallTrap0(handler, name, defaultTrap) { | 628 function CallTrap0(handler, name, defaultTrap) { |
| 632 return %_CallFunction(handler, GetTrap(handler, name, defaultTrap)); | 629 return %_CallFunction(handler, GetTrap(handler, name, defaultTrap)); |
| 633 } | 630 } |
| 634 | 631 |
| 635 | 632 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 649 if (%_IsJSProxy(obj)) { | 646 if (%_IsJSProxy(obj)) { |
| 650 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 647 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 651 if (IS_SYMBOL(v)) return UNDEFINED; | 648 if (IS_SYMBOL(v)) return UNDEFINED; |
| 652 | 649 |
| 653 var handler = %GetHandler(obj); | 650 var handler = %GetHandler(obj); |
| 654 var descriptor = CallTrap1( | 651 var descriptor = CallTrap1( |
| 655 handler, "getOwnPropertyDescriptor", UNDEFINED, p); | 652 handler, "getOwnPropertyDescriptor", UNDEFINED, p); |
| 656 if (IS_UNDEFINED(descriptor)) return descriptor; | 653 if (IS_UNDEFINED(descriptor)) return descriptor; |
| 657 var desc = ToCompletePropertyDescriptor(descriptor); | 654 var desc = ToCompletePropertyDescriptor(descriptor); |
| 658 if (!desc.isConfigurable()) { | 655 if (!desc.isConfigurable()) { |
| 659 throw MakeTypeError("proxy_prop_not_configurable", | 656 throw MakeTypeError(kProxyPropNotConfigurable, |
| 660 [handler, "getOwnPropertyDescriptor", p, descriptor]); | 657 handler, p, "getOwnPropertyDescriptor"); |
| 661 } | 658 } |
| 662 return desc; | 659 return desc; |
| 663 } | 660 } |
| 664 | 661 |
| 665 // GetOwnProperty returns an array indexed by the constants | 662 // GetOwnProperty returns an array indexed by the constants |
| 666 // defined in macros.py. | 663 // defined in macros.py. |
| 667 // If p is not a property on obj undefined is returned. | 664 // If p is not a property on obj undefined is returned. |
| 668 var props = %GetOwnProperty(TO_OBJECT_INLINE(obj), p); | 665 var props = %GetOwnProperty(TO_OBJECT_INLINE(obj), p); |
| 669 | 666 |
| 670 return ConvertDescriptorArrayToDescriptor(props); | 667 return ConvertDescriptorArrayToDescriptor(props); |
| 671 } | 668 } |
| 672 | 669 |
| 673 | 670 |
| 674 // ES5 section 8.12.7. | 671 // ES5 section 8.12.7. |
| 675 function Delete(obj, p, should_throw) { | 672 function Delete(obj, p, should_throw) { |
| 676 var desc = GetOwnPropertyJS(obj, p); | 673 var desc = GetOwnPropertyJS(obj, p); |
| 677 if (IS_UNDEFINED(desc)) return true; | 674 if (IS_UNDEFINED(desc)) return true; |
| 678 if (desc.isConfigurable()) { | 675 if (desc.isConfigurable()) { |
| 679 %DeleteProperty(obj, p, 0); | 676 %DeleteProperty(obj, p, 0); |
| 680 return true; | 677 return true; |
| 681 } else if (should_throw) { | 678 } else if (should_throw) { |
| 682 throw MakeTypeError("define_disallowed", [p]); | 679 throw MakeTypeError(kDefineDisallowed, p); |
| 683 } else { | 680 } else { |
| 684 return; | 681 return; |
| 685 } | 682 } |
| 686 } | 683 } |
| 687 | 684 |
| 688 | 685 |
| 689 // ES6, draft 12-24-14, section 7.3.8 | 686 // ES6, draft 12-24-14, section 7.3.8 |
| 690 function GetMethod(obj, p) { | 687 function GetMethod(obj, p) { |
| 691 var func = obj[p]; | 688 var func = obj[p]; |
| 692 if (IS_NULL_OR_UNDEFINED(func)) return UNDEFINED; | 689 if (IS_NULL_OR_UNDEFINED(func)) return UNDEFINED; |
| 693 if (IS_SPEC_FUNCTION(func)) return func; | 690 if (IS_SPEC_FUNCTION(func)) return func; |
| 694 throw MakeTypeError(kCalledNonCallable, typeof func); | 691 throw MakeTypeError(kCalledNonCallable, typeof func); |
| 695 } | 692 } |
| 696 | 693 |
| 697 | 694 |
| 698 // Harmony proxies. | 695 // Harmony proxies. |
| 699 function DefineProxyProperty(obj, p, attributes, should_throw) { | 696 function DefineProxyProperty(obj, p, attributes, should_throw) { |
| 700 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 697 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 701 if (IS_SYMBOL(p)) return false; | 698 if (IS_SYMBOL(p)) return false; |
| 702 | 699 |
| 703 var handler = %GetHandler(obj); | 700 var handler = %GetHandler(obj); |
| 704 var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes); | 701 var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes); |
| 705 if (!ToBoolean(result)) { | 702 if (!ToBoolean(result)) { |
| 706 if (should_throw) { | 703 if (should_throw) { |
| 707 throw MakeTypeError("handler_returned_false", | 704 throw MakeTypeError(kProxyHandlerReturned, |
| 708 [handler, "defineProperty"]); | 705 handler, "false", "defineProperty"); |
| 709 } else { | 706 } else { |
| 710 return false; | 707 return false; |
| 711 } | 708 } |
| 712 } | 709 } |
| 713 return true; | 710 return true; |
| 714 } | 711 } |
| 715 | 712 |
| 716 | 713 |
| 717 // ES5 8.12.9. | 714 // ES5 8.12.9. |
| 718 function DefineObjectProperty(obj, p, desc, should_throw) { | 715 function DefineObjectProperty(obj, p, desc, should_throw) { |
| 719 var current_array = %GetOwnProperty(obj, ToName(p)); | 716 var current_array = %GetOwnProperty(obj, ToName(p)); |
| 720 var current = ConvertDescriptorArrayToDescriptor(current_array); | 717 var current = ConvertDescriptorArrayToDescriptor(current_array); |
| 721 var extensible = %IsExtensible(obj); | 718 var extensible = %IsExtensible(obj); |
| 722 | 719 |
| 723 // Error handling according to spec. | 720 // Error handling according to spec. |
| 724 // Step 3 | 721 // Step 3 |
| 725 if (IS_UNDEFINED(current) && !extensible) { | 722 if (IS_UNDEFINED(current) && !extensible) { |
| 726 if (should_throw) { | 723 if (should_throw) { |
| 727 throw MakeTypeError("define_disallowed", [p]); | 724 throw MakeTypeError(kDefineDisallowed, p); |
| 728 } else { | 725 } else { |
| 729 return false; | 726 return false; |
| 730 } | 727 } |
| 731 } | 728 } |
| 732 | 729 |
| 733 if (!IS_UNDEFINED(current)) { | 730 if (!IS_UNDEFINED(current)) { |
| 734 // Step 5 and 6 | 731 // Step 5 and 6 |
| 735 if ((IsGenericDescriptor(desc) || | 732 if ((IsGenericDescriptor(desc) || |
| 736 IsDataDescriptor(desc) == IsDataDescriptor(current)) && | 733 IsDataDescriptor(desc) == IsDataDescriptor(current)) && |
| 737 (!desc.hasEnumerable() || | 734 (!desc.hasEnumerable() || |
| 738 SameValue(desc.isEnumerable(), current.isEnumerable())) && | 735 SameValue(desc.isEnumerable(), current.isEnumerable())) && |
| 739 (!desc.hasConfigurable() || | 736 (!desc.hasConfigurable() || |
| 740 SameValue(desc.isConfigurable(), current.isConfigurable())) && | 737 SameValue(desc.isConfigurable(), current.isConfigurable())) && |
| 741 (!desc.hasWritable() || | 738 (!desc.hasWritable() || |
| 742 SameValue(desc.isWritable(), current.isWritable())) && | 739 SameValue(desc.isWritable(), current.isWritable())) && |
| 743 (!desc.hasValue() || | 740 (!desc.hasValue() || |
| 744 SameValue(desc.getValue(), current.getValue())) && | 741 SameValue(desc.getValue(), current.getValue())) && |
| 745 (!desc.hasGetter() || | 742 (!desc.hasGetter() || |
| 746 SameValue(desc.getGet(), current.getGet())) && | 743 SameValue(desc.getGet(), current.getGet())) && |
| 747 (!desc.hasSetter() || | 744 (!desc.hasSetter() || |
| 748 SameValue(desc.getSet(), current.getSet()))) { | 745 SameValue(desc.getSet(), current.getSet()))) { |
| 749 return true; | 746 return true; |
| 750 } | 747 } |
| 751 if (!current.isConfigurable()) { | 748 if (!current.isConfigurable()) { |
| 752 // Step 7 | 749 // Step 7 |
| 753 if (desc.isConfigurable() || | 750 if (desc.isConfigurable() || |
| 754 (desc.hasEnumerable() && | 751 (desc.hasEnumerable() && |
| 755 desc.isEnumerable() != current.isEnumerable())) { | 752 desc.isEnumerable() != current.isEnumerable())) { |
| 756 if (should_throw) { | 753 if (should_throw) { |
| 757 throw MakeTypeError("redefine_disallowed", [p]); | 754 throw MakeTypeError(kRedefineDisallowed, p); |
| 758 } else { | 755 } else { |
| 759 return false; | 756 return false; |
| 760 } | 757 } |
| 761 } | 758 } |
| 762 // Step 8 | 759 // Step 8 |
| 763 if (!IsGenericDescriptor(desc)) { | 760 if (!IsGenericDescriptor(desc)) { |
| 764 // Step 9a | 761 // Step 9a |
| 765 if (IsDataDescriptor(current) != IsDataDescriptor(desc)) { | 762 if (IsDataDescriptor(current) != IsDataDescriptor(desc)) { |
| 766 if (should_throw) { | 763 if (should_throw) { |
| 767 throw MakeTypeError("redefine_disallowed", [p]); | 764 throw MakeTypeError(kRedefineDisallowed, p); |
| 768 } else { | 765 } else { |
| 769 return false; | 766 return false; |
| 770 } | 767 } |
| 771 } | 768 } |
| 772 // Step 10a | 769 // Step 10a |
| 773 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { | 770 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { |
| 774 if (!current.isWritable() && desc.isWritable()) { | 771 if (!current.isWritable() && desc.isWritable()) { |
| 775 if (should_throw) { | 772 if (should_throw) { |
| 776 throw MakeTypeError("redefine_disallowed", [p]); | 773 throw MakeTypeError(kRedefineDisallowed, p); |
| 777 } else { | 774 } else { |
| 778 return false; | 775 return false; |
| 779 } | 776 } |
| 780 } | 777 } |
| 781 if (!current.isWritable() && desc.hasValue() && | 778 if (!current.isWritable() && desc.hasValue() && |
| 782 !SameValue(desc.getValue(), current.getValue())) { | 779 !SameValue(desc.getValue(), current.getValue())) { |
| 783 if (should_throw) { | 780 if (should_throw) { |
| 784 throw MakeTypeError("redefine_disallowed", [p]); | 781 throw MakeTypeError(kRedefineDisallowed, p); |
| 785 } else { | 782 } else { |
| 786 return false; | 783 return false; |
| 787 } | 784 } |
| 788 } | 785 } |
| 789 } | 786 } |
| 790 // Step 11 | 787 // Step 11 |
| 791 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { | 788 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { |
| 792 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) { | 789 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) { |
| 793 if (should_throw) { | 790 if (should_throw) { |
| 794 throw MakeTypeError("redefine_disallowed", [p]); | 791 throw MakeTypeError(kRedefineDisallowed, p); |
| 795 } else { | 792 } else { |
| 796 return false; | 793 return false; |
| 797 } | 794 } |
| 798 } | 795 } |
| 799 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) { | 796 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) { |
| 800 if (should_throw) { | 797 if (should_throw) { |
| 801 throw MakeTypeError("redefine_disallowed", [p]); | 798 throw MakeTypeError(kRedefineDisallowed, p); |
| 802 } else { | 799 } else { |
| 803 return false; | 800 return false; |
| 804 } | 801 } |
| 805 } | 802 } |
| 806 } | 803 } |
| 807 } | 804 } |
| 808 } | 805 } |
| 809 } | 806 } |
| 810 | 807 |
| 811 // Send flags - enumerable and configurable are common - writable is | 808 // Send flags - enumerable and configurable are common - writable is |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 | 884 |
| 888 // Step 3 - Special handling for length property. | 885 // Step 3 - Special handling for length property. |
| 889 if (p === "length") { | 886 if (p === "length") { |
| 890 var length = obj.length; | 887 var length = obj.length; |
| 891 var old_length = length; | 888 var old_length = length; |
| 892 if (!desc.hasValue()) { | 889 if (!desc.hasValue()) { |
| 893 return DefineObjectProperty(obj, "length", desc, should_throw); | 890 return DefineObjectProperty(obj, "length", desc, should_throw); |
| 894 } | 891 } |
| 895 var new_length = ToUint32(desc.getValue()); | 892 var new_length = ToUint32(desc.getValue()); |
| 896 if (new_length != ToNumber(desc.getValue())) { | 893 if (new_length != ToNumber(desc.getValue())) { |
| 897 throw new $RangeError('defineProperty() array length out of range'); | 894 throw MakeRangeError(kArrayLengthOutOfRange); |
| 898 } | 895 } |
| 899 var length_desc = GetOwnPropertyJS(obj, "length"); | 896 var length_desc = GetOwnPropertyJS(obj, "length"); |
| 900 if (new_length != length && !length_desc.isWritable()) { | 897 if (new_length != length && !length_desc.isWritable()) { |
| 901 if (should_throw) { | 898 if (should_throw) { |
| 902 throw MakeTypeError("redefine_disallowed", [p]); | 899 throw MakeTypeError(kRedefineDisallowed, p); |
| 903 } else { | 900 } else { |
| 904 return false; | 901 return false; |
| 905 } | 902 } |
| 906 } | 903 } |
| 907 var threw = false; | 904 var threw = false; |
| 908 | 905 |
| 909 var emit_splice = %IsObserved(obj) && new_length !== old_length; | 906 var emit_splice = %IsObserved(obj) && new_length !== old_length; |
| 910 var removed; | 907 var removed; |
| 911 if (emit_splice) { | 908 if (emit_splice) { |
| 912 $observeBeginPerformSplice(obj); | 909 $observeBeginPerformSplice(obj); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 931 threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw; | 928 threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw; |
| 932 if (emit_splice) { | 929 if (emit_splice) { |
| 933 $observeEndPerformSplice(obj); | 930 $observeEndPerformSplice(obj); |
| 934 $observeEnqueueSpliceRecord(obj, | 931 $observeEnqueueSpliceRecord(obj, |
| 935 new_length < old_length ? new_length : old_length, | 932 new_length < old_length ? new_length : old_length, |
| 936 removed, | 933 removed, |
| 937 new_length > old_length ? new_length - old_length : 0); | 934 new_length > old_length ? new_length - old_length : 0); |
| 938 } | 935 } |
| 939 if (threw) { | 936 if (threw) { |
| 940 if (should_throw) { | 937 if (should_throw) { |
| 941 throw MakeTypeError("redefine_disallowed", [p]); | 938 throw MakeTypeError(kRedefineDisallowed, p); |
| 942 } else { | 939 } else { |
| 943 return false; | 940 return false; |
| 944 } | 941 } |
| 945 } | 942 } |
| 946 return true; | 943 return true; |
| 947 } | 944 } |
| 948 | 945 |
| 949 // Step 4 - Special handling for array index. | 946 // Step 4 - Special handling for array index. |
| 950 if (!IS_SYMBOL(p)) { | 947 if (!IS_SYMBOL(p)) { |
| 951 var index = ToUint32(p); | 948 var index = ToUint32(p); |
| 952 var emit_splice = false; | 949 var emit_splice = false; |
| 953 if (ToString(index) == p && index != 4294967295) { | 950 if (ToString(index) == p && index != 4294967295) { |
| 954 var length = obj.length; | 951 var length = obj.length; |
| 955 if (index >= length && %IsObserved(obj)) { | 952 if (index >= length && %IsObserved(obj)) { |
| 956 emit_splice = true; | 953 emit_splice = true; |
| 957 $observeBeginPerformSplice(obj); | 954 $observeBeginPerformSplice(obj); |
| 958 } | 955 } |
| 959 | 956 |
| 960 var length_desc = GetOwnPropertyJS(obj, "length"); | 957 var length_desc = GetOwnPropertyJS(obj, "length"); |
| 961 if ((index >= length && !length_desc.isWritable()) || | 958 if ((index >= length && !length_desc.isWritable()) || |
| 962 !DefineObjectProperty(obj, p, desc, true)) { | 959 !DefineObjectProperty(obj, p, desc, true)) { |
| 963 if (emit_splice) | 960 if (emit_splice) |
| 964 $observeEndPerformSplice(obj); | 961 $observeEndPerformSplice(obj); |
| 965 if (should_throw) { | 962 if (should_throw) { |
| 966 throw MakeTypeError("define_disallowed", [p]); | 963 throw MakeTypeError(kDefineDisallowed, p); |
| 967 } else { | 964 } else { |
| 968 return false; | 965 return false; |
| 969 } | 966 } |
| 970 } | 967 } |
| 971 if (index >= length) { | 968 if (index >= length) { |
| 972 obj.length = index + 1; | 969 obj.length = index + 1; |
| 973 } | 970 } |
| 974 if (emit_splice) { | 971 if (emit_splice) { |
| 975 $observeEndPerformSplice(obj); | 972 $observeEndPerformSplice(obj); |
| 976 $observeEnqueueSpliceRecord(obj, length, [], index + 1 - length); | 973 $observeEnqueueSpliceRecord(obj, length, [], index + 1 - length); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1003 // ES6 section 19.1.2.9 | 1000 // ES6 section 19.1.2.9 |
| 1004 function ObjectGetPrototypeOf(obj) { | 1001 function ObjectGetPrototypeOf(obj) { |
| 1005 return %_GetPrototype(TO_OBJECT_INLINE(obj)); | 1002 return %_GetPrototype(TO_OBJECT_INLINE(obj)); |
| 1006 } | 1003 } |
| 1007 | 1004 |
| 1008 // ES6 section 19.1.2.19. | 1005 // ES6 section 19.1.2.19. |
| 1009 function ObjectSetPrototypeOf(obj, proto) { | 1006 function ObjectSetPrototypeOf(obj, proto) { |
| 1010 CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf"); | 1007 CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf"); |
| 1011 | 1008 |
| 1012 if (proto !== null && !IS_SPEC_OBJECT(proto)) { | 1009 if (proto !== null && !IS_SPEC_OBJECT(proto)) { |
| 1013 throw MakeTypeError("proto_object_or_null", [proto]); | 1010 throw MakeTypeError(kProtoObjectOrNull, proto); |
| 1014 } | 1011 } |
| 1015 | 1012 |
| 1016 if (IS_SPEC_OBJECT(obj)) { | 1013 if (IS_SPEC_OBJECT(obj)) { |
| 1017 %SetPrototype(obj, proto); | 1014 %SetPrototype(obj, proto); |
| 1018 } | 1015 } |
| 1019 | 1016 |
| 1020 return obj; | 1017 return obj; |
| 1021 } | 1018 } |
| 1022 | 1019 |
| 1023 | 1020 |
| 1024 // ES6 section 19.1.2.6 | 1021 // ES6 section 19.1.2.6 |
| 1025 function ObjectGetOwnPropertyDescriptor(obj, p) { | 1022 function ObjectGetOwnPropertyDescriptor(obj, p) { |
| 1026 var desc = GetOwnPropertyJS(TO_OBJECT_INLINE(obj), p); | 1023 var desc = GetOwnPropertyJS(TO_OBJECT_INLINE(obj), p); |
| 1027 return FromPropertyDescriptor(desc); | 1024 return FromPropertyDescriptor(desc); |
| 1028 } | 1025 } |
| 1029 | 1026 |
| 1030 | 1027 |
| 1031 // For Harmony proxies | 1028 // For Harmony proxies |
| 1032 function ToNameArray(obj, trap, includeSymbols) { | 1029 function ToNameArray(obj, trap, includeSymbols) { |
| 1033 if (!IS_SPEC_OBJECT(obj)) { | 1030 if (!IS_SPEC_OBJECT(obj)) { |
| 1034 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); | 1031 throw MakeTypeError(kProxyNonObjectPropNames, trap, obj); |
| 1035 } | 1032 } |
| 1036 var n = ToUint32(obj.length); | 1033 var n = ToUint32(obj.length); |
| 1037 var array = new $Array(n); | 1034 var array = new $Array(n); |
| 1038 var realLength = 0; | 1035 var realLength = 0; |
| 1039 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. | 1036 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. |
| 1040 for (var index = 0; index < n; index++) { | 1037 for (var index = 0; index < n; index++) { |
| 1041 var s = ToName(obj[index]); | 1038 var s = ToName(obj[index]); |
| 1042 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 1039 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 1043 if (IS_SYMBOL(s) && !includeSymbols) continue; | 1040 if (IS_SYMBOL(s) && !includeSymbols) continue; |
| 1044 if (%HasOwnProperty(names, s)) { | 1041 if (%HasOwnProperty(names, s)) { |
| 1045 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]); | 1042 throw MakeTypeError(kProxyRepeatedPropName, trap, s); |
| 1046 } | 1043 } |
| 1047 array[index] = s; | 1044 array[index] = s; |
| 1048 ++realLength; | 1045 ++realLength; |
| 1049 names[s] = 0; | 1046 names[s] = 0; |
| 1050 } | 1047 } |
| 1051 array.length = realLength; | 1048 array.length = realLength; |
| 1052 return array; | 1049 return array; |
| 1053 } | 1050 } |
| 1054 | 1051 |
| 1055 | 1052 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 return ToNameArray(names, "getOwnPropertyNames", false); | 1127 return ToNameArray(names, "getOwnPropertyNames", false); |
| 1131 } | 1128 } |
| 1132 | 1129 |
| 1133 return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_SYMBOLIC); | 1130 return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_SYMBOLIC); |
| 1134 } | 1131 } |
| 1135 | 1132 |
| 1136 | 1133 |
| 1137 // ES5 section 15.2.3.5. | 1134 // ES5 section 15.2.3.5. |
| 1138 function ObjectCreate(proto, properties) { | 1135 function ObjectCreate(proto, properties) { |
| 1139 if (!IS_SPEC_OBJECT(proto) && proto !== null) { | 1136 if (!IS_SPEC_OBJECT(proto) && proto !== null) { |
| 1140 throw MakeTypeError("proto_object_or_null", [proto]); | 1137 throw MakeTypeError(kProtoObjectOrNull, proto); |
| 1141 } | 1138 } |
| 1142 var obj = {}; | 1139 var obj = {}; |
| 1143 %InternalSetPrototype(obj, proto); | 1140 %InternalSetPrototype(obj, proto); |
| 1144 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); | 1141 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); |
| 1145 return obj; | 1142 return obj; |
| 1146 } | 1143 } |
| 1147 | 1144 |
| 1148 | 1145 |
| 1149 // ES5 section 15.2.3.6. | 1146 // ES5 section 15.2.3.6. |
| 1150 function ObjectDefineProperty(obj, p, attributes) { | 1147 function ObjectDefineProperty(obj, p, attributes) { |
| 1151 if (!IS_SPEC_OBJECT(obj)) { | 1148 if (!IS_SPEC_OBJECT(obj)) { |
| 1152 throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]); | 1149 throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty"); |
| 1153 } | 1150 } |
| 1154 var name = ToName(p); | 1151 var name = ToName(p); |
| 1155 if (%_IsJSProxy(obj)) { | 1152 if (%_IsJSProxy(obj)) { |
| 1156 // Clone the attributes object for protection. | 1153 // Clone the attributes object for protection. |
| 1157 // TODO(rossberg): not spec'ed yet, so not sure if this should involve | 1154 // TODO(rossberg): not spec'ed yet, so not sure if this should involve |
| 1158 // non-own properties as it does (or non-enumerable ones, as it doesn't?). | 1155 // non-own properties as it does (or non-enumerable ones, as it doesn't?). |
| 1159 var attributesClone = { __proto__: null }; | 1156 var attributesClone = { __proto__: null }; |
| 1160 for (var a in attributes) { | 1157 for (var a in attributes) { |
| 1161 attributesClone[a] = attributes[a]; | 1158 attributesClone[a] = attributes[a]; |
| 1162 } | 1159 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 } | 1202 } |
| 1206 } | 1203 } |
| 1207 | 1204 |
| 1208 return names; | 1205 return names; |
| 1209 } | 1206 } |
| 1210 | 1207 |
| 1211 | 1208 |
| 1212 // ES5 section 15.2.3.7. | 1209 // ES5 section 15.2.3.7. |
| 1213 function ObjectDefineProperties(obj, properties) { | 1210 function ObjectDefineProperties(obj, properties) { |
| 1214 if (!IS_SPEC_OBJECT(obj)) { | 1211 if (!IS_SPEC_OBJECT(obj)) { |
| 1215 throw MakeTypeError("called_on_non_object", ["Object.defineProperties"]); | 1212 throw MakeTypeError(kCalledOnNonObject, "Object.defineProperties"); |
| 1216 } | 1213 } |
| 1217 var props = TO_OBJECT_INLINE(properties); | 1214 var props = TO_OBJECT_INLINE(properties); |
| 1218 var names = GetOwnEnumerablePropertyNames(props); | 1215 var names = GetOwnEnumerablePropertyNames(props); |
| 1219 var descriptors = new InternalArray(); | 1216 var descriptors = new InternalArray(); |
| 1220 for (var i = 0; i < names.length; i++) { | 1217 for (var i = 0; i < names.length; i++) { |
| 1221 descriptors.push(ToPropertyDescriptor(props[names[i]])); | 1218 descriptors.push(ToPropertyDescriptor(props[names[i]])); |
| 1222 } | 1219 } |
| 1223 for (var i = 0; i < names.length; i++) { | 1220 for (var i = 0; i < names.length; i++) { |
| 1224 DefineOwnProperty(obj, names[i], descriptors[i], true); | 1221 DefineOwnProperty(obj, names[i], descriptors[i], true); |
| 1225 } | 1222 } |
| 1226 return obj; | 1223 return obj; |
| 1227 } | 1224 } |
| 1228 | 1225 |
| 1229 | 1226 |
| 1230 // Harmony proxies. | 1227 // Harmony proxies. |
| 1231 function ProxyFix(obj) { | 1228 function ProxyFix(obj) { |
| 1232 var handler = %GetHandler(obj); | 1229 var handler = %GetHandler(obj); |
| 1233 var props = CallTrap0(handler, "fix", UNDEFINED); | 1230 var props = CallTrap0(handler, "fix", UNDEFINED); |
| 1234 if (IS_UNDEFINED(props)) { | 1231 if (IS_UNDEFINED(props)) { |
| 1235 throw MakeTypeError("handler_returned_undefined", [handler, "fix"]); | 1232 throw MakeTypeError(kProxyHandlerReturned, handler, "undefined", "fix"); |
| 1236 } | 1233 } |
| 1237 | 1234 |
| 1238 if (%IsJSFunctionProxy(obj)) { | 1235 if (%IsJSFunctionProxy(obj)) { |
| 1239 var callTrap = %GetCallTrap(obj); | 1236 var callTrap = %GetCallTrap(obj); |
| 1240 var constructTrap = %GetConstructTrap(obj); | 1237 var constructTrap = %GetConstructTrap(obj); |
| 1241 var code = $proxyDelegateCallAndConstruct(callTrap, constructTrap); | 1238 var code = $proxyDelegateCallAndConstruct(callTrap, constructTrap); |
| 1242 %Fix(obj); // becomes a regular function | 1239 %Fix(obj); // becomes a regular function |
| 1243 %SetCode(obj, code); | 1240 %SetCode(obj, code); |
| 1244 // TODO(rossberg): What about length and other properties? Not specified. | 1241 // TODO(rossberg): What about length and other properties? Not specified. |
| 1245 // We just put in some half-reasonable defaults for now. | 1242 // We just put in some half-reasonable defaults for now. |
| 1246 var prototype = new $Object(); | 1243 var prototype = new $Object(); |
| 1247 $Object.defineProperty(prototype, "constructor", | 1244 $Object.defineProperty(prototype, "constructor", |
| 1248 {value: obj, writable: true, enumerable: false, configurable: true}); | 1245 {value: obj, writable: true, enumerable: false, configurable: true}); |
| 1249 // TODO(v8:1530): defineProperty does not handle prototype and length. | 1246 // TODO(v8:1530): defineProperty does not handle prototype and length. |
| 1250 %FunctionSetPrototype(obj, prototype); | 1247 %FunctionSetPrototype(obj, prototype); |
| 1251 obj.length = 0; | 1248 obj.length = 0; |
| 1252 } else { | 1249 } else { |
| 1253 %Fix(obj); | 1250 %Fix(obj); |
| 1254 } | 1251 } |
| 1255 ObjectDefineProperties(obj, props); | 1252 ObjectDefineProperties(obj, props); |
| 1256 } | 1253 } |
| 1257 | 1254 |
| 1258 | 1255 |
| 1259 // ES5 section 15.2.3.8. | 1256 // ES5 section 15.2.3.8. |
| 1260 function ObjectSealJS(obj) { | 1257 function ObjectSealJS(obj) { |
| 1261 if (!IS_SPEC_OBJECT(obj)) { | 1258 if (!IS_SPEC_OBJECT(obj)) { |
| 1262 throw MakeTypeError("called_on_non_object", ["Object.seal"]); | 1259 throw MakeTypeError(kCalledOnNonObject, "Object.seal"); |
| 1263 } | 1260 } |
| 1264 var isProxy = %_IsJSProxy(obj); | 1261 var isProxy = %_IsJSProxy(obj); |
| 1265 if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { | 1262 if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { |
| 1266 if (isProxy) { | 1263 if (isProxy) { |
| 1267 ProxyFix(obj); | 1264 ProxyFix(obj); |
| 1268 } | 1265 } |
| 1269 var names = ObjectGetOwnPropertyNames(obj); | 1266 var names = ObjectGetOwnPropertyNames(obj); |
| 1270 for (var i = 0; i < names.length; i++) { | 1267 for (var i = 0; i < names.length; i++) { |
| 1271 var name = names[i]; | 1268 var name = names[i]; |
| 1272 var desc = GetOwnPropertyJS(obj, name); | 1269 var desc = GetOwnPropertyJS(obj, name); |
| 1273 if (desc.isConfigurable()) { | 1270 if (desc.isConfigurable()) { |
| 1274 desc.setConfigurable(false); | 1271 desc.setConfigurable(false); |
| 1275 DefineOwnProperty(obj, name, desc, true); | 1272 DefineOwnProperty(obj, name, desc, true); |
| 1276 } | 1273 } |
| 1277 } | 1274 } |
| 1278 %PreventExtensions(obj); | 1275 %PreventExtensions(obj); |
| 1279 } else { | 1276 } else { |
| 1280 // TODO(adamk): Is it worth going to this fast path if the | 1277 // TODO(adamk): Is it worth going to this fast path if the |
| 1281 // object's properties are already in dictionary mode? | 1278 // object's properties are already in dictionary mode? |
| 1282 %ObjectSeal(obj); | 1279 %ObjectSeal(obj); |
| 1283 } | 1280 } |
| 1284 return obj; | 1281 return obj; |
| 1285 } | 1282 } |
| 1286 | 1283 |
| 1287 | 1284 |
| 1288 // ES5 section 15.2.3.9. | 1285 // ES5 section 15.2.3.9. |
| 1289 function ObjectFreezeJS(obj) { | 1286 function ObjectFreezeJS(obj) { |
| 1290 if (!IS_SPEC_OBJECT(obj)) { | 1287 if (!IS_SPEC_OBJECT(obj)) { |
| 1291 throw MakeTypeError("called_on_non_object", ["Object.freeze"]); | 1288 throw MakeTypeError(kCalledOnNonObject, "Object.freeze"); |
| 1292 } | 1289 } |
| 1293 var isProxy = %_IsJSProxy(obj); | 1290 var isProxy = %_IsJSProxy(obj); |
| 1294 if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { | 1291 if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { |
| 1295 if (isProxy) { | 1292 if (isProxy) { |
| 1296 ProxyFix(obj); | 1293 ProxyFix(obj); |
| 1297 } | 1294 } |
| 1298 var names = ObjectGetOwnPropertyNames(obj); | 1295 var names = ObjectGetOwnPropertyNames(obj); |
| 1299 for (var i = 0; i < names.length; i++) { | 1296 for (var i = 0; i < names.length; i++) { |
| 1300 var name = names[i]; | 1297 var name = names[i]; |
| 1301 var desc = GetOwnPropertyJS(obj, name); | 1298 var desc = GetOwnPropertyJS(obj, name); |
| 1302 if (desc.isWritable() || desc.isConfigurable()) { | 1299 if (desc.isWritable() || desc.isConfigurable()) { |
| 1303 if (IsDataDescriptor(desc)) desc.setWritable(false); | 1300 if (IsDataDescriptor(desc)) desc.setWritable(false); |
| 1304 desc.setConfigurable(false); | 1301 desc.setConfigurable(false); |
| 1305 DefineOwnProperty(obj, name, desc, true); | 1302 DefineOwnProperty(obj, name, desc, true); |
| 1306 } | 1303 } |
| 1307 } | 1304 } |
| 1308 %PreventExtensions(obj); | 1305 %PreventExtensions(obj); |
| 1309 } else { | 1306 } else { |
| 1310 // TODO(adamk): Is it worth going to this fast path if the | 1307 // TODO(adamk): Is it worth going to this fast path if the |
| 1311 // object's properties are already in dictionary mode? | 1308 // object's properties are already in dictionary mode? |
| 1312 %ObjectFreeze(obj); | 1309 %ObjectFreeze(obj); |
| 1313 } | 1310 } |
| 1314 return obj; | 1311 return obj; |
| 1315 } | 1312 } |
| 1316 | 1313 |
| 1317 | 1314 |
| 1318 // ES5 section 15.2.3.10 | 1315 // ES5 section 15.2.3.10 |
| 1319 function ObjectPreventExtension(obj) { | 1316 function ObjectPreventExtension(obj) { |
| 1320 if (!IS_SPEC_OBJECT(obj)) { | 1317 if (!IS_SPEC_OBJECT(obj)) { |
| 1321 throw MakeTypeError("called_on_non_object", ["Object.preventExtension"]); | 1318 throw MakeTypeError(kCalledOnNonObject, "Object.preventExtension"); |
| 1322 } | 1319 } |
| 1323 if (%_IsJSProxy(obj)) { | 1320 if (%_IsJSProxy(obj)) { |
| 1324 ProxyFix(obj); | 1321 ProxyFix(obj); |
| 1325 } | 1322 } |
| 1326 %PreventExtensions(obj); | 1323 %PreventExtensions(obj); |
| 1327 return obj; | 1324 return obj; |
| 1328 } | 1325 } |
| 1329 | 1326 |
| 1330 | 1327 |
| 1331 // ES5 section 15.2.3.11 | 1328 // ES5 section 15.2.3.11 |
| 1332 function ObjectIsSealed(obj) { | 1329 function ObjectIsSealed(obj) { |
| 1333 if (!IS_SPEC_OBJECT(obj)) { | 1330 if (!IS_SPEC_OBJECT(obj)) { |
| 1334 throw MakeTypeError("called_on_non_object", ["Object.isSealed"]); | 1331 throw MakeTypeError(kCalledOnNonObject, "Object.isSealed"); |
| 1335 } | 1332 } |
| 1336 if (%_IsJSProxy(obj)) { | 1333 if (%_IsJSProxy(obj)) { |
| 1337 return false; | 1334 return false; |
| 1338 } | 1335 } |
| 1339 if (%IsExtensible(obj)) { | 1336 if (%IsExtensible(obj)) { |
| 1340 return false; | 1337 return false; |
| 1341 } | 1338 } |
| 1342 var names = ObjectGetOwnPropertyNames(obj); | 1339 var names = ObjectGetOwnPropertyNames(obj); |
| 1343 for (var i = 0; i < names.length; i++) { | 1340 for (var i = 0; i < names.length; i++) { |
| 1344 var name = names[i]; | 1341 var name = names[i]; |
| 1345 var desc = GetOwnPropertyJS(obj, name); | 1342 var desc = GetOwnPropertyJS(obj, name); |
| 1346 if (desc.isConfigurable()) { | 1343 if (desc.isConfigurable()) { |
| 1347 return false; | 1344 return false; |
| 1348 } | 1345 } |
| 1349 } | 1346 } |
| 1350 return true; | 1347 return true; |
| 1351 } | 1348 } |
| 1352 | 1349 |
| 1353 | 1350 |
| 1354 // ES5 section 15.2.3.12 | 1351 // ES5 section 15.2.3.12 |
| 1355 function ObjectIsFrozen(obj) { | 1352 function ObjectIsFrozen(obj) { |
| 1356 if (!IS_SPEC_OBJECT(obj)) { | 1353 if (!IS_SPEC_OBJECT(obj)) { |
| 1357 throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]); | 1354 throw MakeTypeError(kCalledOnNonObject, "Object.isFrozen"); |
| 1358 } | 1355 } |
| 1359 if (%_IsJSProxy(obj)) { | 1356 if (%_IsJSProxy(obj)) { |
| 1360 return false; | 1357 return false; |
| 1361 } | 1358 } |
| 1362 if (%IsExtensible(obj)) { | 1359 if (%IsExtensible(obj)) { |
| 1363 return false; | 1360 return false; |
| 1364 } | 1361 } |
| 1365 var names = ObjectGetOwnPropertyNames(obj); | 1362 var names = ObjectGetOwnPropertyNames(obj); |
| 1366 for (var i = 0; i < names.length; i++) { | 1363 for (var i = 0; i < names.length; i++) { |
| 1367 var name = names[i]; | 1364 var name = names[i]; |
| 1368 var desc = GetOwnPropertyJS(obj, name); | 1365 var desc = GetOwnPropertyJS(obj, name); |
| 1369 if (IsDataDescriptor(desc) && desc.isWritable()) return false; | 1366 if (IsDataDescriptor(desc) && desc.isWritable()) return false; |
| 1370 if (desc.isConfigurable()) return false; | 1367 if (desc.isConfigurable()) return false; |
| 1371 } | 1368 } |
| 1372 return true; | 1369 return true; |
| 1373 } | 1370 } |
| 1374 | 1371 |
| 1375 | 1372 |
| 1376 // ES5 section 15.2.3.13 | 1373 // ES5 section 15.2.3.13 |
| 1377 function ObjectIsExtensible(obj) { | 1374 function ObjectIsExtensible(obj) { |
| 1378 if (!IS_SPEC_OBJECT(obj)) { | 1375 if (!IS_SPEC_OBJECT(obj)) { |
| 1379 throw MakeTypeError("called_on_non_object", ["Object.isExtensible"]); | 1376 throw MakeTypeError(kCalledOnNonObject, "Object.isExtensible"); |
| 1380 } | 1377 } |
| 1381 if (%_IsJSProxy(obj)) { | 1378 if (%_IsJSProxy(obj)) { |
| 1382 return true; | 1379 return true; |
| 1383 } | 1380 } |
| 1384 return %IsExtensible(obj); | 1381 return %IsExtensible(obj); |
| 1385 } | 1382 } |
| 1386 | 1383 |
| 1387 | 1384 |
| 1388 // ECMA-262, Edition 6, section 19.1.2.10 | 1385 // ECMA-262, Edition 6, section 19.1.2.10 |
| 1389 function ObjectIs(obj1, obj2) { | 1386 function ObjectIs(obj1, obj2) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 } | 1479 } |
| 1483 } | 1480 } |
| 1484 | 1481 |
| 1485 | 1482 |
| 1486 function BooleanToString() { | 1483 function BooleanToString() { |
| 1487 // NOTE: Both Boolean objects and values can enter here as | 1484 // NOTE: Both Boolean objects and values can enter here as |
| 1488 // 'this'. This is not as dictated by ECMA-262. | 1485 // 'this'. This is not as dictated by ECMA-262. |
| 1489 var b = this; | 1486 var b = this; |
| 1490 if (!IS_BOOLEAN(b)) { | 1487 if (!IS_BOOLEAN(b)) { |
| 1491 if (!IS_BOOLEAN_WRAPPER(b)) { | 1488 if (!IS_BOOLEAN_WRAPPER(b)) { |
| 1492 throw new $TypeError('Boolean.prototype.toString is not generic'); | 1489 throw MakeTypeError(kNotGeneric, 'Boolean.prototype.toString'); |
| 1493 } | 1490 } |
| 1494 b = %_ValueOf(b); | 1491 b = %_ValueOf(b); |
| 1495 } | 1492 } |
| 1496 return b ? 'true' : 'false'; | 1493 return b ? 'true' : 'false'; |
| 1497 } | 1494 } |
| 1498 | 1495 |
| 1499 | 1496 |
| 1500 function BooleanValueOf() { | 1497 function BooleanValueOf() { |
| 1501 // NOTE: Both Boolean objects and values can enter here as | 1498 // NOTE: Both Boolean objects and values can enter here as |
| 1502 // 'this'. This is not as dictated by ECMA-262. | 1499 // 'this'. This is not as dictated by ECMA-262. |
| 1503 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) { | 1500 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) { |
| 1504 throw new $TypeError('Boolean.prototype.valueOf is not generic'); | 1501 throw MakeTypeError(kNotGeneric, 'Boolean.prototype.valueOf'); |
| 1505 } | 1502 } |
| 1506 return %_ValueOf(this); | 1503 return %_ValueOf(this); |
| 1507 } | 1504 } |
| 1508 | 1505 |
| 1509 | 1506 |
| 1510 // ---------------------------------------------------------------------------- | 1507 // ---------------------------------------------------------------------------- |
| 1511 | 1508 |
| 1512 function SetUpBoolean () { | 1509 function SetUpBoolean () { |
| 1513 %CheckIsBootstrapping(); | 1510 %CheckIsBootstrapping(); |
| 1514 | 1511 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1538 } | 1535 } |
| 1539 | 1536 |
| 1540 | 1537 |
| 1541 // ECMA-262 section 15.7.4.2. | 1538 // ECMA-262 section 15.7.4.2. |
| 1542 function NumberToStringJS(radix) { | 1539 function NumberToStringJS(radix) { |
| 1543 // NOTE: Both Number objects and values can enter here as | 1540 // NOTE: Both Number objects and values can enter here as |
| 1544 // 'this'. This is not as dictated by ECMA-262. | 1541 // 'this'. This is not as dictated by ECMA-262. |
| 1545 var number = this; | 1542 var number = this; |
| 1546 if (!IS_NUMBER(this)) { | 1543 if (!IS_NUMBER(this)) { |
| 1547 if (!IS_NUMBER_WRAPPER(this)) { | 1544 if (!IS_NUMBER_WRAPPER(this)) { |
| 1548 throw new $TypeError('Number.prototype.toString is not generic'); | 1545 throw MakeTypeError(kNotGeneric, 'Number.prototype.toString'); |
| 1549 } | 1546 } |
| 1550 // Get the value of this number in case it's an object. | 1547 // Get the value of this number in case it's an object. |
| 1551 number = %_ValueOf(this); | 1548 number = %_ValueOf(this); |
| 1552 } | 1549 } |
| 1553 // Fast case: Convert number in radix 10. | 1550 // Fast case: Convert number in radix 10. |
| 1554 if (IS_UNDEFINED(radix) || radix === 10) { | 1551 if (IS_UNDEFINED(radix) || radix === 10) { |
| 1555 return %_NumberToString(number); | 1552 return %_NumberToString(number); |
| 1556 } | 1553 } |
| 1557 | 1554 |
| 1558 // Convert the radix to an integer and check the range. | 1555 // Convert the radix to an integer and check the range. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1569 function NumberToLocaleString() { | 1566 function NumberToLocaleString() { |
| 1570 return %_CallFunction(this, NumberToStringJS); | 1567 return %_CallFunction(this, NumberToStringJS); |
| 1571 } | 1568 } |
| 1572 | 1569 |
| 1573 | 1570 |
| 1574 // ECMA-262 section 15.7.4.4 | 1571 // ECMA-262 section 15.7.4.4 |
| 1575 function NumberValueOf() { | 1572 function NumberValueOf() { |
| 1576 // NOTE: Both Number objects and values can enter here as | 1573 // NOTE: Both Number objects and values can enter here as |
| 1577 // 'this'. This is not as dictated by ECMA-262. | 1574 // 'this'. This is not as dictated by ECMA-262. |
| 1578 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) { | 1575 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) { |
| 1579 throw new $TypeError('Number.prototype.valueOf is not generic'); | 1576 throw MakeTypeError(kNotGeneric, 'Number.prototype.valueOf'); |
| 1580 } | 1577 } |
| 1581 return %_ValueOf(this); | 1578 return %_ValueOf(this); |
| 1582 } | 1579 } |
| 1583 | 1580 |
| 1584 | 1581 |
| 1585 // ECMA-262 section 15.7.4.5 | 1582 // ECMA-262 section 15.7.4.5 |
| 1586 function NumberToFixedJS(fractionDigits) { | 1583 function NumberToFixedJS(fractionDigits) { |
| 1587 var x = this; | 1584 var x = this; |
| 1588 if (!IS_NUMBER(this)) { | 1585 if (!IS_NUMBER(this)) { |
| 1589 if (!IS_NUMBER_WRAPPER(this)) { | 1586 if (!IS_NUMBER_WRAPPER(this)) { |
| 1590 throw MakeTypeError(kIncompatibleMethodReceiver, | 1587 throw MakeTypeError(kIncompatibleMethodReceiver, |
| 1591 "Number.prototype.toFixed", this); | 1588 "Number.prototype.toFixed", this); |
| 1592 } | 1589 } |
| 1593 // Get the value of this number in case it's an object. | 1590 // Get the value of this number in case it's an object. |
| 1594 x = %_ValueOf(this); | 1591 x = %_ValueOf(this); |
| 1595 } | 1592 } |
| 1596 var f = TO_INTEGER(fractionDigits); | 1593 var f = TO_INTEGER(fractionDigits); |
| 1597 | 1594 |
| 1598 if (f < 0 || f > 20) { | 1595 if (f < 0 || f > 20) { |
| 1599 throw new $RangeError("toFixed() digits argument must be between 0 and 20"); | 1596 throw MakeRangeError(kNumberFormatRange, "toFixed() digits"); |
| 1600 } | 1597 } |
| 1601 | 1598 |
| 1602 if (NUMBER_IS_NAN(x)) return "NaN"; | 1599 if (NUMBER_IS_NAN(x)) return "NaN"; |
| 1603 if (x == INFINITY) return "Infinity"; | 1600 if (x == INFINITY) return "Infinity"; |
| 1604 if (x == -INFINITY) return "-Infinity"; | 1601 if (x == -INFINITY) return "-Infinity"; |
| 1605 | 1602 |
| 1606 return %NumberToFixed(x, f); | 1603 return %NumberToFixed(x, f); |
| 1607 } | 1604 } |
| 1608 | 1605 |
| 1609 | 1606 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1620 } | 1617 } |
| 1621 var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits); | 1618 var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits); |
| 1622 | 1619 |
| 1623 if (NUMBER_IS_NAN(x)) return "NaN"; | 1620 if (NUMBER_IS_NAN(x)) return "NaN"; |
| 1624 if (x == INFINITY) return "Infinity"; | 1621 if (x == INFINITY) return "Infinity"; |
| 1625 if (x == -INFINITY) return "-Infinity"; | 1622 if (x == -INFINITY) return "-Infinity"; |
| 1626 | 1623 |
| 1627 if (IS_UNDEFINED(f)) { | 1624 if (IS_UNDEFINED(f)) { |
| 1628 f = -1; // Signal for runtime function that f is not defined. | 1625 f = -1; // Signal for runtime function that f is not defined. |
| 1629 } else if (f < 0 || f > 20) { | 1626 } else if (f < 0 || f > 20) { |
| 1630 throw new $RangeError("toExponential() argument must be between 0 and 20"); | 1627 throw MakeRangeError(kNumberFormatRange, "toExponential()"); |
| 1631 } | 1628 } |
| 1632 return %NumberToExponential(x, f); | 1629 return %NumberToExponential(x, f); |
| 1633 } | 1630 } |
| 1634 | 1631 |
| 1635 | 1632 |
| 1636 // ECMA-262 section 15.7.4.7 | 1633 // ECMA-262 section 15.7.4.7 |
| 1637 function NumberToPrecisionJS(precision) { | 1634 function NumberToPrecisionJS(precision) { |
| 1638 var x = this; | 1635 var x = this; |
| 1639 if (!IS_NUMBER(this)) { | 1636 if (!IS_NUMBER(this)) { |
| 1640 if (!IS_NUMBER_WRAPPER(this)) { | 1637 if (!IS_NUMBER_WRAPPER(this)) { |
| 1641 throw MakeTypeError(kIncompatibleMethodReceiver, | 1638 throw MakeTypeError(kIncompatibleMethodReceiver, |
| 1642 "Number.prototype.toPrecision", this); | 1639 "Number.prototype.toPrecision", this); |
| 1643 } | 1640 } |
| 1644 // Get the value of this number in case it's an object. | 1641 // Get the value of this number in case it's an object. |
| 1645 x = %_ValueOf(this); | 1642 x = %_ValueOf(this); |
| 1646 } | 1643 } |
| 1647 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); | 1644 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); |
| 1648 var p = TO_INTEGER(precision); | 1645 var p = TO_INTEGER(precision); |
| 1649 | 1646 |
| 1650 if (NUMBER_IS_NAN(x)) return "NaN"; | 1647 if (NUMBER_IS_NAN(x)) return "NaN"; |
| 1651 if (x == INFINITY) return "Infinity"; | 1648 if (x == INFINITY) return "Infinity"; |
| 1652 if (x == -INFINITY) return "-Infinity"; | 1649 if (x == -INFINITY) return "-Infinity"; |
| 1653 | 1650 |
| 1654 if (p < 1 || p > 21) { | 1651 if (p < 1 || p > 21) { |
| 1655 throw new $RangeError("toPrecision() argument must be between 1 and 21"); | 1652 throw MakeRangeError(kToPrecisionFormatRange); |
| 1656 } | 1653 } |
| 1657 return %NumberToPrecision(x, p); | 1654 return %NumberToPrecision(x, p); |
| 1658 } | 1655 } |
| 1659 | 1656 |
| 1660 | 1657 |
| 1661 // Harmony isFinite. | 1658 // Harmony isFinite. |
| 1662 function NumberIsFinite(number) { | 1659 function NumberIsFinite(number) { |
| 1663 return IS_NUMBER(number) && NUMBER_IS_FINITE(number); | 1660 return IS_NUMBER(number) && NUMBER_IS_FINITE(number); |
| 1664 } | 1661 } |
| 1665 | 1662 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1745 | 1742 |
| 1746 // ---------------------------------------------------------------------------- | 1743 // ---------------------------------------------------------------------------- |
| 1747 // Function | 1744 // Function |
| 1748 | 1745 |
| 1749 function FunctionSourceString(func) { | 1746 function FunctionSourceString(func) { |
| 1750 while (%IsJSFunctionProxy(func)) { | 1747 while (%IsJSFunctionProxy(func)) { |
| 1751 func = %GetCallTrap(func); | 1748 func = %GetCallTrap(func); |
| 1752 } | 1749 } |
| 1753 | 1750 |
| 1754 if (!IS_FUNCTION(func)) { | 1751 if (!IS_FUNCTION(func)) { |
| 1755 throw new $TypeError('Function.prototype.toString is not generic'); | 1752 throw MakeTypeError(kNotGeneric, 'Function.prototype.toString'); |
| 1756 } | 1753 } |
| 1757 | 1754 |
| 1758 var classSource = %ClassGetSourceCode(func); | 1755 var classSource = %ClassGetSourceCode(func); |
| 1759 if (IS_STRING(classSource)) { | 1756 if (IS_STRING(classSource)) { |
| 1760 return classSource; | 1757 return classSource; |
| 1761 } | 1758 } |
| 1762 | 1759 |
| 1763 var source = %FunctionGetSourceCode(func); | 1760 var source = %FunctionGetSourceCode(func); |
| 1764 if (!IS_STRING(source) || %FunctionIsBuiltin(func)) { | 1761 if (!IS_STRING(source) || %FunctionIsBuiltin(func)) { |
| 1765 var name = %FunctionGetName(func); | 1762 var name = %FunctionGetName(func); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1787 } | 1784 } |
| 1788 | 1785 |
| 1789 | 1786 |
| 1790 function FunctionToString() { | 1787 function FunctionToString() { |
| 1791 return FunctionSourceString(this); | 1788 return FunctionSourceString(this); |
| 1792 } | 1789 } |
| 1793 | 1790 |
| 1794 | 1791 |
| 1795 // ES5 15.3.4.5 | 1792 // ES5 15.3.4.5 |
| 1796 function FunctionBind(this_arg) { // Length is 1. | 1793 function FunctionBind(this_arg) { // Length is 1. |
| 1797 if (!IS_SPEC_FUNCTION(this)) { | 1794 if (!IS_SPEC_FUNCTION(this)) throw MakeTypeError(kFunctionBind); |
| 1798 throw new $TypeError('Bind must be called on a function'); | 1795 |
| 1799 } | |
| 1800 var boundFunction = function () { | 1796 var boundFunction = function () { |
| 1801 // Poison .arguments and .caller, but is otherwise not detectable. | 1797 // Poison .arguments and .caller, but is otherwise not detectable. |
| 1802 "use strict"; | 1798 "use strict"; |
| 1803 // This function must not use any object literals (Object, Array, RegExp), | 1799 // This function must not use any object literals (Object, Array, RegExp), |
| 1804 // since the literals-array is being used to store the bound data. | 1800 // since the literals-array is being used to store the bound data. |
| 1805 if (%_IsConstructCall()) { | 1801 if (%_IsConstructCall()) { |
| 1806 return %NewObjectFromBound(boundFunction); | 1802 return %NewObjectFromBound(boundFunction); |
| 1807 } | 1803 } |
| 1808 var bindings = %BoundFunctionGetBindings(boundFunction); | 1804 var bindings = %BoundFunctionGetBindings(boundFunction); |
| 1809 | 1805 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 var p = ''; | 1852 var p = ''; |
| 1857 if (n > 1) { | 1853 if (n > 1) { |
| 1858 p = ToString(arguments[0]); | 1854 p = ToString(arguments[0]); |
| 1859 for (var i = 1; i < n - 1; i++) { | 1855 for (var i = 1; i < n - 1; i++) { |
| 1860 p += ',' + ToString(arguments[i]); | 1856 p += ',' + ToString(arguments[i]); |
| 1861 } | 1857 } |
| 1862 // If the formal parameters string include ) - an illegal | 1858 // If the formal parameters string include ) - an illegal |
| 1863 // character - it may make the combined function expression | 1859 // character - it may make the combined function expression |
| 1864 // compile. We avoid this problem by checking for this early on. | 1860 // compile. We avoid this problem by checking for this early on. |
| 1865 if (%_CallFunction(p, ')', $stringIndexOf) != -1) { | 1861 if (%_CallFunction(p, ')', $stringIndexOf) != -1) { |
| 1866 throw MakeSyntaxError('paren_in_arg_string', []); | 1862 throw MakeSyntaxError(kParenthesisInArgString); |
| 1867 } | 1863 } |
| 1868 // If the formal parameters include an unbalanced block comment, the | 1864 // If the formal parameters include an unbalanced block comment, the |
| 1869 // function must be rejected. Since JavaScript does not allow nested | 1865 // function must be rejected. Since JavaScript does not allow nested |
| 1870 // comments we can include a trailing block comment to catch this. | 1866 // comments we can include a trailing block comment to catch this. |
| 1871 p += '\n/' + '**/'; | 1867 p += '\n/' + '**/'; |
| 1872 } | 1868 } |
| 1873 var body = (n > 0) ? ToString(arguments[n - 1]) : ''; | 1869 var body = (n > 0) ? ToString(arguments[n - 1]) : ''; |
| 1874 return '(' + function_token + '(' + p + ') {\n' + body + '\n})'; | 1870 return '(' + function_token + '(' + p + ') {\n' + body + '\n})'; |
| 1875 } | 1871 } |
| 1876 | 1872 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1906 // ---------------------------------------------------------------------------- | 1902 // ---------------------------------------------------------------------------- |
| 1907 // Iterator related spec functions. | 1903 // Iterator related spec functions. |
| 1908 | 1904 |
| 1909 // ES6 rev 33, 2015-02-12 | 1905 // ES6 rev 33, 2015-02-12 |
| 1910 // 7.4.1 GetIterator ( obj, method ) | 1906 // 7.4.1 GetIterator ( obj, method ) |
| 1911 function GetIterator(obj, method) { | 1907 function GetIterator(obj, method) { |
| 1912 if (IS_UNDEFINED(method)) { | 1908 if (IS_UNDEFINED(method)) { |
| 1913 method = obj[symbolIterator]; | 1909 method = obj[symbolIterator]; |
| 1914 } | 1910 } |
| 1915 if (!IS_SPEC_FUNCTION(method)) { | 1911 if (!IS_SPEC_FUNCTION(method)) { |
| 1916 throw MakeTypeError('not_iterable', [obj]); | 1912 throw MakeTypeError(kNotIterable, obj); |
| 1917 } | 1913 } |
| 1918 var iterator = %_CallFunction(obj, method); | 1914 var iterator = %_CallFunction(obj, method); |
| 1919 if (!IS_SPEC_OBJECT(iterator)) { | 1915 if (!IS_SPEC_OBJECT(iterator)) { |
| 1920 throw MakeTypeError('not_an_iterator', [iterator]); | 1916 throw MakeTypeError(kNotAnIterator, iterator); |
| 1921 } | 1917 } |
| 1922 return iterator; | 1918 return iterator; |
| 1923 } | 1919 } |
| OLD | NEW |