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 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
833 setter = current.getSet(); | 833 setter = current.getSet(); |
834 } | 834 } |
835 %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag); | 835 %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag); |
836 } | 836 } |
837 return true; | 837 return true; |
838 } | 838 } |
839 | 839 |
840 | 840 |
841 // ES5 section 15.4.5.1. | 841 // ES5 section 15.4.5.1. |
842 function DefineArrayProperty(obj, p, desc, should_throw) { | 842 function DefineArrayProperty(obj, p, desc, should_throw) { |
843 // Note that the length of an array is not actually stored as part of the | 843 // Special handling for array index. |
844 // property, hence we use generated code throughout this function instead of | |
845 // DefineObjectProperty() to modify its value. | |
846 | |
847 // Step 3 - Special handling for length property. | |
Jakob Kummerow
2014/12/11 11:41:40
Some of this code was ~3 years old and seems unrel
adamk
2014/12/11 16:47:26
Arg, you're right, test262 not being in make check
| |
848 if (p === "length") { | |
849 var length = obj.length; | |
850 var old_length = length; | |
851 if (!desc.hasValue()) { | |
852 return DefineObjectProperty(obj, "length", desc, should_throw); | |
853 } | |
854 var new_length = ToUint32(desc.getValue()); | |
855 if (new_length != ToNumber(desc.getValue())) { | |
856 throw new $RangeError('defineProperty() array length out of range'); | |
857 } | |
858 var length_desc = GetOwnPropertyJS(obj, "length"); | |
859 if (new_length != length && !length_desc.isWritable()) { | |
860 if (should_throw) { | |
861 throw MakeTypeError("redefine_disallowed", [p]); | |
862 } else { | |
863 return false; | |
864 } | |
865 } | |
866 var threw = false; | |
867 | |
868 var emit_splice = %IsObserved(obj) && new_length !== old_length; | |
869 var removed; | |
870 if (emit_splice) { | |
871 BeginPerformSplice(obj); | |
872 removed = []; | |
873 if (new_length < old_length) | |
874 removed.length = old_length - new_length; | |
875 } | |
876 | |
877 while (new_length < length--) { | |
878 var index = ToString(length); | |
879 if (emit_splice) { | |
880 var deletedDesc = GetOwnPropertyJS(obj, index); | |
881 if (deletedDesc && deletedDesc.hasValue()) | |
882 removed[length - new_length] = deletedDesc.getValue(); | |
883 } | |
884 if (!Delete(obj, index, false)) { | |
885 new_length = length + 1; | |
886 threw = true; | |
887 break; | |
888 } | |
889 } | |
890 // Make sure the below call to DefineObjectProperty() doesn't overwrite | |
891 // any magic "length" property by removing the value. | |
892 // TODO(mstarzinger): This hack should be removed once we have addressed the | |
893 // respective TODO in Runtime_DefineDataPropertyUnchecked. | |
894 // For the time being, we need a hack to prevent Object.observe from | |
895 // generating two change records. | |
896 obj.length = new_length; | |
897 desc.value_ = UNDEFINED; | |
898 desc.hasValue_ = false; | |
899 threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw; | |
900 if (emit_splice) { | |
901 EndPerformSplice(obj); | |
902 EnqueueSpliceRecord(obj, | |
903 new_length < old_length ? new_length : old_length, | |
904 removed, | |
905 new_length > old_length ? new_length - old_length : 0); | |
906 } | |
907 if (threw) { | |
908 if (should_throw) { | |
909 throw MakeTypeError("redefine_disallowed", [p]); | |
910 } else { | |
911 return false; | |
912 } | |
913 } | |
914 return true; | |
915 } | |
916 | |
917 // Step 4 - Special handling for array index. | |
918 if (!IS_SYMBOL(p)) { | 844 if (!IS_SYMBOL(p)) { |
919 var index = ToUint32(p); | 845 var index = ToUint32(p); |
920 var emit_splice = false; | 846 var emit_splice = false; |
921 if (ToString(index) == p && index != 4294967295) { | 847 if (ToString(index) == p && index != 4294967295) { |
922 var length = obj.length; | 848 var length = obj.length; |
923 if (index >= length && %IsObserved(obj)) { | 849 if (index >= length && %IsObserved(obj)) { |
924 emit_splice = true; | 850 emit_splice = true; |
925 BeginPerformSplice(obj); | 851 BeginPerformSplice(obj); |
926 } | 852 } |
927 | 853 |
(...skipping 12 matching lines...) Expand all Loading... | |
940 obj.length = index + 1; | 866 obj.length = index + 1; |
941 } | 867 } |
942 if (emit_splice) { | 868 if (emit_splice) { |
943 EndPerformSplice(obj); | 869 EndPerformSplice(obj); |
944 EnqueueSpliceRecord(obj, length, [], index + 1 - length); | 870 EnqueueSpliceRecord(obj, length, [], index + 1 - length); |
945 } | 871 } |
946 return true; | 872 return true; |
947 } | 873 } |
948 } | 874 } |
949 | 875 |
950 // Step 5 - Fallback to default implementation. | 876 // Fallback to default implementation. |
951 return DefineObjectProperty(obj, p, desc, should_throw); | 877 return DefineObjectProperty(obj, p, desc, should_throw); |
952 } | 878 } |
953 | 879 |
954 | 880 |
955 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies. | 881 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies. |
956 function DefineOwnProperty(obj, p, desc, should_throw) { | 882 function DefineOwnProperty(obj, p, desc, should_throw) { |
957 if (%_IsJSProxy(obj)) { | 883 if (%_IsJSProxy(obj)) { |
958 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 884 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
959 if (IS_SYMBOL(p)) return false; | 885 if (IS_SYMBOL(p)) return false; |
960 | 886 |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1897 } | 1823 } |
1898 if (!IS_SPEC_FUNCTION(method)) { | 1824 if (!IS_SPEC_FUNCTION(method)) { |
1899 throw MakeTypeError('not_iterable', [obj]); | 1825 throw MakeTypeError('not_iterable', [obj]); |
1900 } | 1826 } |
1901 var iterator = %_CallFunction(obj, method); | 1827 var iterator = %_CallFunction(obj, method); |
1902 if (!IS_SPEC_OBJECT(iterator)) { | 1828 if (!IS_SPEC_OBJECT(iterator)) { |
1903 throw MakeTypeError('not_an_iterator', [iterator]); | 1829 throw MakeTypeError('not_an_iterator', [iterator]); |
1904 } | 1830 } |
1905 return iterator; | 1831 return iterator; |
1906 } | 1832 } |
OLD | NEW |