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 |