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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 (-1e9 < string && string < -0.01))) { | 120 (-1e9 < string && string < -0.01))) { |
121 // Truncate number. | 121 // Truncate number. |
122 return string | 0; | 122 return string | 0; |
123 } | 123 } |
124 string = TO_STRING_INLINE(string); | 124 string = TO_STRING_INLINE(string); |
125 radix = radix | 0; | 125 radix = radix | 0; |
126 } else { | 126 } else { |
127 // The spec says ToString should be evaluated before ToInt32. | 127 // The spec says ToString should be evaluated before ToInt32. |
128 string = TO_STRING_INLINE(string); | 128 string = TO_STRING_INLINE(string); |
129 radix = TO_INT32(radix); | 129 radix = TO_INT32(radix); |
130 if (!(radix == 0 || (2 <= radix && radix <= 36))) | 130 if (!(radix == 0 || (2 <= radix && radix <= 36))) { |
131 return $NaN; | 131 return $NaN; |
132 } | |
132 } | 133 } |
133 | 134 |
134 if (%_HasCachedArrayIndex(string) && | 135 if (%_HasCachedArrayIndex(string) && |
135 (radix == 0 || radix == 10)) { | 136 (radix == 0 || radix == 10)) { |
136 return %_GetCachedArrayIndex(string); | 137 return %_GetCachedArrayIndex(string); |
137 } | 138 } |
138 return %StringParseInt(string, radix); | 139 return %StringParseInt(string, radix); |
139 } | 140 } |
140 | 141 |
141 | 142 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 function ObjectLookupSetter(name) { | 323 function ObjectLookupSetter(name) { |
323 var receiver = this; | 324 var receiver = this; |
324 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 325 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
325 receiver = %GlobalReceiver(global); | 326 receiver = %GlobalReceiver(global); |
326 } | 327 } |
327 return %LookupAccessor(ToObject(receiver), ToString(name), SETTER); | 328 return %LookupAccessor(ToObject(receiver), ToString(name), SETTER); |
328 } | 329 } |
329 | 330 |
330 | 331 |
331 function ObjectKeys(obj) { | 332 function ObjectKeys(obj) { |
332 if (!IS_SPEC_OBJECT(obj)) | 333 if (!IS_SPEC_OBJECT(obj)) { |
333 throw MakeTypeError("obj_ctor_property_non_object", ["keys"]); | 334 throw MakeTypeError("obj_ctor_property_non_object", ["keys"]); |
335 } | |
334 if (%IsJSProxy(obj)) { | 336 if (%IsJSProxy(obj)) { |
335 var handler = %GetHandler(obj); | 337 var handler = %GetHandler(obj); |
336 var names = CallTrap0(handler, "keys", DerivedKeysTrap); | 338 var names = CallTrap0(handler, "keys", DerivedKeysTrap); |
337 return ToStringArray(names); | 339 return ToStringArray(names); |
338 } | 340 } |
339 return %LocalKeys(obj); | 341 return %LocalKeys(obj); |
340 } | 342 } |
341 | 343 |
342 | 344 |
343 // ES5 8.10.1. | 345 // ES5 8.10.1. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 | 456 |
455 if (IsInconsistentDescriptor(desc)) { | 457 if (IsInconsistentDescriptor(desc)) { |
456 throw MakeTypeError("value_and_accessor", [obj]); | 458 throw MakeTypeError("value_and_accessor", [obj]); |
457 } | 459 } |
458 return desc; | 460 return desc; |
459 } | 461 } |
460 | 462 |
461 | 463 |
462 // For Harmony proxies. | 464 // For Harmony proxies. |
463 function ToCompletePropertyDescriptor(obj) { | 465 function ToCompletePropertyDescriptor(obj) { |
464 var desc = ToPropertyDescriptor(obj) | 466 var desc = ToPropertyDescriptor(obj); |
465 if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) { | 467 if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) { |
466 if (!desc.hasValue()) desc.setValue(void 0); | 468 if (!desc.hasValue()) desc.setValue(void 0); |
467 if (!desc.hasWritable()) desc.setWritable(false); | 469 if (!desc.hasWritable()) desc.setWritable(false); |
468 } else { | 470 } else { |
469 // Is accessor descriptor. | 471 // Is accessor descriptor. |
470 if (!desc.hasGetter()) desc.setGet(void 0); | 472 if (!desc.hasGetter()) desc.setGet(void 0); |
471 if (!desc.hasSetter()) desc.setSet(void 0); | 473 if (!desc.hasSetter()) desc.setSet(void 0); |
472 } | 474 } |
473 if (!desc.hasEnumerable()) desc.setEnumerable(false); | 475 if (!desc.hasEnumerable()) desc.setEnumerable(false); |
474 if (!desc.hasConfigurable()) desc.setConfigurable(false); | 476 if (!desc.hasConfigurable()) desc.setConfigurable(false); |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 if (desc.hasSetter()) { | 840 if (desc.hasSetter()) { |
839 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag); | 841 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag); |
840 } | 842 } |
841 } | 843 } |
842 return true; | 844 return true; |
843 } | 845 } |
844 | 846 |
845 | 847 |
846 // ES5 section 15.2.3.2. | 848 // ES5 section 15.2.3.2. |
847 function ObjectGetPrototypeOf(obj) { | 849 function ObjectGetPrototypeOf(obj) { |
848 if (!IS_SPEC_OBJECT(obj)) | 850 if (!IS_SPEC_OBJECT(obj)) { |
849 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); | 851 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); |
852 } | |
850 return %GetPrototype(obj); | 853 return %GetPrototype(obj); |
851 } | 854 } |
852 | 855 |
853 | 856 |
854 // ES5 section 15.2.3.3 | 857 // ES5 section 15.2.3.3 |
855 function ObjectGetOwnPropertyDescriptor(obj, p) { | 858 function ObjectGetOwnPropertyDescriptor(obj, p) { |
856 if (!IS_SPEC_OBJECT(obj)) | 859 if (!IS_SPEC_OBJECT(obj)) { |
857 throw MakeTypeError("obj_ctor_property_non_object", | 860 throw MakeTypeError("obj_ctor_property_non_object", |
858 ["getOwnPropertyDescriptor"]); | 861 ["getOwnPropertyDescriptor"]); |
862 } | |
859 var desc = GetOwnProperty(obj, p); | 863 var desc = GetOwnProperty(obj, p); |
860 return FromPropertyDescriptor(desc); | 864 return FromPropertyDescriptor(desc); |
861 } | 865 } |
862 | 866 |
863 | 867 |
864 // For Harmony proxies | 868 // For Harmony proxies |
865 function ToStringArray(obj, trap) { | 869 function ToStringArray(obj, trap) { |
866 if (!IS_SPEC_OBJECT(obj)) { | 870 if (!IS_SPEC_OBJECT(obj)) { |
867 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); | 871 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); |
868 } | 872 } |
869 var n = ToUint32(obj.length); | 873 var n = ToUint32(obj.length); |
870 var array = new $Array(n); | 874 var array = new $Array(n); |
871 var names = {} // TODO(rossberg): use sets once they are ready. | 875 var names = {} // TODO(rossberg): use sets once they are ready. |
872 for (var index = 0; index < n; index++) { | 876 for (var index = 0; index < n; index++) { |
873 var s = ToString(obj[index]); | 877 var s = ToString(obj[index]); |
874 if (s in names) { | 878 if (s in names) { |
875 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]) | 879 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]); |
876 } | 880 } |
877 array[index] = s; | 881 array[index] = s; |
878 names[s] = 0; | 882 names[s] = 0; |
879 } | 883 } |
880 return array; | 884 return array; |
881 } | 885 } |
882 | 886 |
883 | 887 |
884 // ES5 section 15.2.3.4. | 888 // ES5 section 15.2.3.4. |
885 function ObjectGetOwnPropertyNames(obj) { | 889 function ObjectGetOwnPropertyNames(obj) { |
886 if (!IS_SPEC_OBJECT(obj)) | 890 if (!IS_SPEC_OBJECT(obj)) { |
887 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]) ; | 891 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]) ; |
Yang
2011/11/25 15:56:02
Might as well insert a line break in here to keep
| |
888 | 892 } |
889 // Special handling for proxies. | 893 // Special handling for proxies. |
890 if (%IsJSProxy(obj)) { | 894 if (%IsJSProxy(obj)) { |
891 var handler = %GetHandler(obj); | 895 var handler = %GetHandler(obj); |
892 var names = CallTrap0(handler, "getOwnPropertyNames", void 0); | 896 var names = CallTrap0(handler, "getOwnPropertyNames", void 0); |
893 return ToStringArray(names, "getOwnPropertyNames"); | 897 return ToStringArray(names, "getOwnPropertyNames"); |
894 } | 898 } |
895 | 899 |
896 // Find all the indexed properties. | 900 // Find all the indexed properties. |
897 | 901 |
898 // Get the local element names. | 902 // Get the local element names. |
899 var propertyNames = %GetLocalElementNames(obj); | 903 var propertyNames = %GetLocalElementNames(obj); |
900 | 904 |
901 // Get names for indexed interceptor properties. | 905 // Get names for indexed interceptor properties. |
902 if (%GetInterceptorInfo(obj) & 1) { | 906 if (%GetInterceptorInfo(obj) & 1) { |
903 var indexedInterceptorNames = | 907 var indexedInterceptorNames = |
904 %GetIndexedInterceptorElementNames(obj); | 908 %GetIndexedInterceptorElementNames(obj); |
905 if (indexedInterceptorNames) | 909 if (indexedInterceptorNames) { |
906 propertyNames = propertyNames.concat(indexedInterceptorNames); | 910 propertyNames = propertyNames.concat(indexedInterceptorNames); |
911 } | |
907 } | 912 } |
908 | 913 |
909 // Find all the named properties. | 914 // Find all the named properties. |
910 | 915 |
911 // Get the local property names. | 916 // Get the local property names. |
912 propertyNames = propertyNames.concat(%GetLocalPropertyNames(obj)); | 917 propertyNames = propertyNames.concat(%GetLocalPropertyNames(obj)); |
913 | 918 |
914 // Get names for named interceptor properties if any. | 919 // Get names for named interceptor properties if any. |
915 | 920 |
916 if (%GetInterceptorInfo(obj) & 2) { | 921 if (%GetInterceptorInfo(obj) & 2) { |
917 var namedInterceptorNames = | 922 var namedInterceptorNames = |
918 %GetNamedInterceptorPropertyNames(obj); | 923 %GetNamedInterceptorPropertyNames(obj); |
919 if (namedInterceptorNames) { | 924 if (namedInterceptorNames) { |
920 propertyNames = propertyNames.concat(namedInterceptorNames); | 925 propertyNames = propertyNames.concat(namedInterceptorNames); |
921 } | 926 } |
922 } | 927 } |
923 | 928 |
924 // Property names are expected to be unique strings. | 929 // Property names are expected to be unique strings. |
925 var propertySet = {}; | 930 var propertySet = {}; |
926 var j = 0; | 931 var j = 0; |
927 for (var i = 0; i < propertyNames.length; ++i) { | 932 for (var i = 0; i < propertyNames.length; ++i) { |
928 var name = ToString(propertyNames[i]); | 933 var name = ToString(propertyNames[i]); |
929 // We need to check for the exact property value since for intrinsic | 934 // We need to check for the exact property value since for intrinsic |
930 // properties like toString if(propertySet["toString"]) will always | 935 // properties like toString if(propertySet["toString"]) will always |
931 // succeed. | 936 // succeed. |
932 if (propertySet[name] === true) | 937 if (propertySet[name] === true) { |
933 continue; | 938 continue; |
939 } | |
934 propertySet[name] = true; | 940 propertySet[name] = true; |
935 propertyNames[j++] = name; | 941 propertyNames[j++] = name; |
936 } | 942 } |
937 propertyNames.length = j; | 943 propertyNames.length = j; |
938 | 944 |
939 return propertyNames; | 945 return propertyNames; |
940 } | 946 } |
941 | 947 |
942 | 948 |
943 // ES5 section 15.2.3.5. | 949 // ES5 section 15.2.3.5. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
999 if (%HasLocalProperty(properties, key)) { | 1005 if (%HasLocalProperty(properties, key)) { |
1000 names.push(key); | 1006 names.push(key); |
1001 } | 1007 } |
1002 } | 1008 } |
1003 return names; | 1009 return names; |
1004 } | 1010 } |
1005 | 1011 |
1006 | 1012 |
1007 // ES5 section 15.2.3.7. | 1013 // ES5 section 15.2.3.7. |
1008 function ObjectDefineProperties(obj, properties) { | 1014 function ObjectDefineProperties(obj, properties) { |
1009 if (!IS_SPEC_OBJECT(obj)) | 1015 if (!IS_SPEC_OBJECT(obj)) { |
1010 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]); | 1016 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]); |
1017 } | |
1011 var props = ToObject(properties); | 1018 var props = ToObject(properties); |
1012 var names = GetOwnEnumerablePropertyNames(props); | 1019 var names = GetOwnEnumerablePropertyNames(props); |
1013 var descriptors = new InternalArray(); | 1020 var descriptors = new InternalArray(); |
1014 for (var i = 0; i < names.length; i++) { | 1021 for (var i = 0; i < names.length; i++) { |
1015 descriptors.push(ToPropertyDescriptor(props[names[i]])); | 1022 descriptors.push(ToPropertyDescriptor(props[names[i]])); |
1016 } | 1023 } |
1017 for (var i = 0; i < names.length; i++) { | 1024 for (var i = 0; i < names.length; i++) { |
1018 DefineOwnProperty(obj, names[i], descriptors[i], true); | 1025 DefineOwnProperty(obj, names[i], descriptors[i], true); |
1019 } | 1026 } |
1020 return obj; | 1027 return obj; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1225 } | 1232 } |
1226 b = %_ValueOf(b); | 1233 b = %_ValueOf(b); |
1227 } | 1234 } |
1228 return b ? 'true' : 'false'; | 1235 return b ? 'true' : 'false'; |
1229 } | 1236 } |
1230 | 1237 |
1231 | 1238 |
1232 function BooleanValueOf() { | 1239 function BooleanValueOf() { |
1233 // NOTE: Both Boolean objects and values can enter here as | 1240 // NOTE: Both Boolean objects and values can enter here as |
1234 // 'this'. This is not as dictated by ECMA-262. | 1241 // 'this'. This is not as dictated by ECMA-262. |
1235 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) | 1242 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) { |
1236 throw new $TypeError('Boolean.prototype.valueOf is not generic'); | 1243 throw new $TypeError('Boolean.prototype.valueOf is not generic'); |
1244 } | |
1237 return %_ValueOf(this); | 1245 return %_ValueOf(this); |
1238 } | 1246 } |
1239 | 1247 |
1240 | 1248 |
1241 // ---------------------------------------------------------------------------- | 1249 // ---------------------------------------------------------------------------- |
1242 | 1250 |
1243 | 1251 |
1244 function SetUpBoolean () { | 1252 function SetUpBoolean () { |
1245 %CheckIsBootstrapping(); | 1253 %CheckIsBootstrapping(); |
1246 InstallFunctions($Boolean.prototype, DONT_ENUM, $Array( | 1254 InstallFunctions($Boolean.prototype, DONT_ENUM, $Array( |
(...skipping 19 matching lines...) Expand all Loading... | |
1266 }); | 1274 }); |
1267 | 1275 |
1268 %FunctionSetPrototype($Number, new $Number(0)); | 1276 %FunctionSetPrototype($Number, new $Number(0)); |
1269 | 1277 |
1270 // ECMA-262 section 15.7.4.2. | 1278 // ECMA-262 section 15.7.4.2. |
1271 function NumberToString(radix) { | 1279 function NumberToString(radix) { |
1272 // NOTE: Both Number objects and values can enter here as | 1280 // NOTE: Both Number objects and values can enter here as |
1273 // 'this'. This is not as dictated by ECMA-262. | 1281 // 'this'. This is not as dictated by ECMA-262. |
1274 var number = this; | 1282 var number = this; |
1275 if (!IS_NUMBER(this)) { | 1283 if (!IS_NUMBER(this)) { |
1276 if (!IS_NUMBER_WRAPPER(this)) | 1284 if (!IS_NUMBER_WRAPPER(this)) { |
1277 throw new $TypeError('Number.prototype.toString is not generic'); | 1285 throw new $TypeError('Number.prototype.toString is not generic'); |
1286 } | |
1278 // Get the value of this number in case it's an object. | 1287 // Get the value of this number in case it's an object. |
1279 number = %_ValueOf(this); | 1288 number = %_ValueOf(this); |
1280 } | 1289 } |
1281 // Fast case: Convert number in radix 10. | 1290 // Fast case: Convert number in radix 10. |
1282 if (IS_UNDEFINED(radix) || radix === 10) { | 1291 if (IS_UNDEFINED(radix) || radix === 10) { |
1283 return %_NumberToString(number); | 1292 return %_NumberToString(number); |
1284 } | 1293 } |
1285 | 1294 |
1286 // Convert the radix to an integer and check the range. | 1295 // Convert the radix to an integer and check the range. |
1287 radix = TO_INTEGER(radix); | 1296 radix = TO_INTEGER(radix); |
(...skipping 12 matching lines...) Expand all Loading... | |
1300 ["Number.prototype.toLocaleString"]); | 1309 ["Number.prototype.toLocaleString"]); |
1301 } | 1310 } |
1302 return this.toString(); | 1311 return this.toString(); |
1303 } | 1312 } |
1304 | 1313 |
1305 | 1314 |
1306 // ECMA-262 section 15.7.4.4 | 1315 // ECMA-262 section 15.7.4.4 |
1307 function NumberValueOf() { | 1316 function NumberValueOf() { |
1308 // NOTE: Both Number objects and values can enter here as | 1317 // NOTE: Both Number objects and values can enter here as |
1309 // 'this'. This is not as dictated by ECMA-262. | 1318 // 'this'. This is not as dictated by ECMA-262. |
1310 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) | 1319 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) { |
1311 throw new $TypeError('Number.prototype.valueOf is not generic'); | 1320 throw new $TypeError('Number.prototype.valueOf is not generic'); |
1321 } | |
1312 return %_ValueOf(this); | 1322 return %_ValueOf(this); |
1313 } | 1323 } |
1314 | 1324 |
1315 | 1325 |
1316 // ECMA-262 section 15.7.4.5 | 1326 // ECMA-262 section 15.7.4.5 |
1317 function NumberToFixed(fractionDigits) { | 1327 function NumberToFixed(fractionDigits) { |
1318 var f = TO_INTEGER(fractionDigits); | 1328 var f = TO_INTEGER(fractionDigits); |
1319 if (f < 0 || f > 20) { | 1329 if (f < 0 || f > 20) { |
1320 throw new $RangeError("toFixed() digits argument must be between 0 and 20"); | 1330 throw new $RangeError("toFixed() digits argument must be between 0 and 20"); |
1321 } | 1331 } |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1537 | 1547 |
1538 function SetUpFunction() { | 1548 function SetUpFunction() { |
1539 %CheckIsBootstrapping(); | 1549 %CheckIsBootstrapping(); |
1540 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1550 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
1541 "bind", FunctionBind, | 1551 "bind", FunctionBind, |
1542 "toString", FunctionToString | 1552 "toString", FunctionToString |
1543 )); | 1553 )); |
1544 } | 1554 } |
1545 | 1555 |
1546 SetUpFunction(); | 1556 SetUpFunction(); |
OLD | NEW |