OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 // If p is not a property on obj undefined is returned. | 653 // If p is not a property on obj undefined is returned. |
654 var props = %GetOwnProperty(ToObject(obj), ToString(v)); | 654 var props = %GetOwnProperty(ToObject(obj), ToString(v)); |
655 | 655 |
656 // A false value here means that access checks failed. | 656 // A false value here means that access checks failed. |
657 if (props === false) return void 0; | 657 if (props === false) return void 0; |
658 | 658 |
659 return ConvertDescriptorArrayToDescriptor(props); | 659 return ConvertDescriptorArrayToDescriptor(props); |
660 } | 660 } |
661 | 661 |
662 | 662 |
| 663 // ES5 section 8.12.7. |
| 664 function Delete(obj, p, should_throw) { |
| 665 var desc = GetOwnProperty(obj, p); |
| 666 if (IS_UNDEFINED(desc)) return true; |
| 667 if (desc.isConfigurable()) { |
| 668 %DeleteProperty(obj, p, 0); |
| 669 return true; |
| 670 } else if (should_throw) { |
| 671 throw MakeTypeError("define_disallowed", [p]); |
| 672 } else { |
| 673 return; |
| 674 } |
| 675 } |
| 676 |
| 677 |
663 // Harmony proxies. | 678 // Harmony proxies. |
664 function DefineProxyProperty(obj, p, attributes, should_throw) { | 679 function DefineProxyProperty(obj, p, attributes, should_throw) { |
665 var handler = %GetHandler(obj); | 680 var handler = %GetHandler(obj); |
666 var result = CallTrap2(handler, "defineProperty", void 0, p, attributes); | 681 var result = CallTrap2(handler, "defineProperty", void 0, p, attributes); |
667 if (!ToBoolean(result)) { | 682 if (!ToBoolean(result)) { |
668 if (should_throw) { | 683 if (should_throw) { |
669 throw MakeTypeError("handler_returned_false", | 684 throw MakeTypeError("handler_returned_false", |
670 [handler, "defineProperty"]); | 685 [handler, "defineProperty"]); |
671 } else { | 686 } else { |
672 return false; | 687 return false; |
673 } | 688 } |
674 } | 689 } |
675 return true; | 690 return true; |
676 } | 691 } |
677 | 692 |
678 | 693 |
679 // ES5 8.12.9. | 694 // ES5 8.12.9. |
680 function DefineOwnProperty(obj, p, desc, should_throw) { | 695 function DefineObjectProperty(obj, p, desc, should_throw) { |
681 if (%IsJSProxy(obj)) { | |
682 var attributes = FromGenericPropertyDescriptor(desc); | |
683 return DefineProxyProperty(obj, p, attributes, should_throw); | |
684 } | |
685 | |
686 var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p)); | 696 var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p)); |
687 // A false value here means that access checks failed. | 697 // A false value here means that access checks failed. |
688 if (current_or_access === false) return void 0; | 698 if (current_or_access === false) return void 0; |
689 | 699 |
690 var current = ConvertDescriptorArrayToDescriptor(current_or_access); | 700 var current = ConvertDescriptorArrayToDescriptor(current_or_access); |
691 var extensible = %IsExtensible(ToObject(obj)); | 701 var extensible = %IsExtensible(ToObject(obj)); |
692 | 702 |
693 // Error handling according to spec. | 703 // Error handling according to spec. |
694 // Step 3 | 704 // Step 3 |
695 if (IS_UNDEFINED(current) && !extensible) { | 705 if (IS_UNDEFINED(current) && !extensible) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag); | 849 %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag); |
840 } | 850 } |
841 if (desc.hasSetter()) { | 851 if (desc.hasSetter()) { |
842 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag); | 852 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag); |
843 } | 853 } |
844 } | 854 } |
845 return true; | 855 return true; |
846 } | 856 } |
847 | 857 |
848 | 858 |
| 859 // ES5 section 15.4.5.1. |
| 860 function DefineArrayProperty(obj, p, desc, should_throw) { |
| 861 // Note that the length of an array is not actually stored as part of the |
| 862 // property, hence we use generated code throughout this function instead of |
| 863 // DefineObjectProperty() to modify its value. |
| 864 |
| 865 // Step 3 - Special handling for length property. |
| 866 if (p == "length") { |
| 867 var length = obj.length; |
| 868 if (!desc.hasValue()) { |
| 869 return DefineObjectProperty(obj, "length", desc, should_throw); |
| 870 } |
| 871 var new_length = ToUint32(desc.getValue()); |
| 872 if (new_length != ToNumber(desc.getValue())) { |
| 873 throw new $RangeError('defineProperty() array length out of range'); |
| 874 } |
| 875 var length_desc = GetOwnProperty(obj, "length"); |
| 876 // Make sure the below call to DefineObjectProperty() doesn't overwrite |
| 877 // any magic "length" property. |
| 878 desc.value_ = void 0; |
| 879 desc.hasValue_ = false; |
| 880 if ((new_length != length && !length_desc.isWritable()) || |
| 881 !DefineObjectProperty(obj, "length", desc, should_throw)) { |
| 882 if (should_throw) { |
| 883 throw MakeTypeError("redefine_disallowed", [p]); |
| 884 } else { |
| 885 return false; |
| 886 } |
| 887 } |
| 888 obj.length = new_length; |
| 889 while (new_length < length--) { |
| 890 if (!Delete(obj, length, false)) { |
| 891 obj.length = length + 1; |
| 892 if (should_throw) { |
| 893 throw MakeTypeError("redefine_disallowed", [p]); |
| 894 } else { |
| 895 return false; |
| 896 } |
| 897 } |
| 898 } |
| 899 return true; |
| 900 } |
| 901 |
| 902 // Step 4 - Special handling for array index. |
| 903 var index = ToUint32(p); |
| 904 if (index == ToNumber(p) && index != 4294967295) { |
| 905 var length = obj.length; |
| 906 var length_desc = GetOwnProperty(obj, "length"); |
| 907 if ((index >= length && !length_desc.isWritable()) || |
| 908 !DefineObjectProperty(obj, p, desc, true)) { |
| 909 if (should_throw) { |
| 910 throw MakeTypeError("define_disallowed", [p]); |
| 911 } else { |
| 912 return false; |
| 913 } |
| 914 } |
| 915 if (index >= length) { |
| 916 obj.length = index + 1; |
| 917 } |
| 918 return true; |
| 919 } |
| 920 |
| 921 // Step 5 - Fallback to default implementation. |
| 922 return DefineObjectProperty(obj, p, desc, should_throw); |
| 923 } |
| 924 |
| 925 |
| 926 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies. |
| 927 function DefineOwnProperty(obj, p, desc, should_throw) { |
| 928 if (%IsJSProxy(obj)) { |
| 929 var attributes = FromGenericPropertyDescriptor(desc); |
| 930 return DefineProxyProperty(obj, p, attributes, should_throw); |
| 931 } else if (IS_ARRAY(obj)) { |
| 932 return DefineArrayProperty(obj, p, desc, should_throw); |
| 933 } else { |
| 934 return DefineObjectProperty(obj, p, desc, should_throw); |
| 935 } |
| 936 } |
| 937 |
| 938 |
849 // ES5 section 15.2.3.2. | 939 // ES5 section 15.2.3.2. |
850 function ObjectGetPrototypeOf(obj) { | 940 function ObjectGetPrototypeOf(obj) { |
851 if (!IS_SPEC_OBJECT(obj)) { | 941 if (!IS_SPEC_OBJECT(obj)) { |
852 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); | 942 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); |
853 } | 943 } |
854 return %GetPrototype(obj); | 944 return %GetPrototype(obj); |
855 } | 945 } |
856 | 946 |
857 | 947 |
858 // ES5 section 15.2.3.3 | 948 // ES5 section 15.2.3.3 |
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 | 1642 |
1553 function SetUpFunction() { | 1643 function SetUpFunction() { |
1554 %CheckIsBootstrapping(); | 1644 %CheckIsBootstrapping(); |
1555 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1645 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
1556 "bind", FunctionBind, | 1646 "bind", FunctionBind, |
1557 "toString", FunctionToString | 1647 "toString", FunctionToString |
1558 )); | 1648 )); |
1559 } | 1649 } |
1560 | 1650 |
1561 SetUpFunction(); | 1651 SetUpFunction(); |
OLD | NEW |