Chromium Code Reviews| 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 |