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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 256 } |
257 | 257 |
258 | 258 |
259 // ECMA-262 - 15.2.4.6 | 259 // ECMA-262 - 15.2.4.6 |
260 function ObjectPropertyIsEnumerable(V) { | 260 function ObjectPropertyIsEnumerable(V) { |
261 var P = ToName(V); | 261 var P = ToName(V); |
262 if (%IsJSProxy(this)) { | 262 if (%IsJSProxy(this)) { |
263 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 263 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
264 if (IS_SYMBOL(V)) return false; | 264 if (IS_SYMBOL(V)) return false; |
265 | 265 |
266 var desc = GetOwnProperty(this, P); | 266 var desc = GetOwnPropertyJS(this, P); |
267 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); | 267 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); |
268 } | 268 } |
269 return %IsPropertyEnumerable(ToObject(this), P); | 269 return %IsPropertyEnumerable(ToObject(this), P); |
270 } | 270 } |
271 | 271 |
272 | 272 |
273 // Extensions for providing property getters and setters. | 273 // Extensions for providing property getters and setters. |
274 function ObjectDefineGetter(name, fun) { | 274 function ObjectDefineGetter(name, fun) { |
275 var receiver = this; | 275 var receiver = this; |
276 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 276 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap)); | 620 return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap)); |
621 } | 621 } |
622 | 622 |
623 | 623 |
624 function CallTrap2(handler, name, defaultTrap, x, y) { | 624 function CallTrap2(handler, name, defaultTrap, x, y) { |
625 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); | 625 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); |
626 } | 626 } |
627 | 627 |
628 | 628 |
629 // ES5 section 8.12.1. | 629 // ES5 section 8.12.1. |
630 function GetOwnProperty(obj, v) { | 630 function GetOwnPropertyJS(obj, v) { |
631 var p = ToName(v); | 631 var p = ToName(v); |
632 if (%IsJSProxy(obj)) { | 632 if (%IsJSProxy(obj)) { |
633 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 633 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
634 if (IS_SYMBOL(v)) return UNDEFINED; | 634 if (IS_SYMBOL(v)) return UNDEFINED; |
635 | 635 |
636 var handler = %GetHandler(obj); | 636 var handler = %GetHandler(obj); |
637 var descriptor = CallTrap1( | 637 var descriptor = CallTrap1( |
638 handler, "getOwnPropertyDescriptor", UNDEFINED, p); | 638 handler, "getOwnPropertyDescriptor", UNDEFINED, p); |
639 if (IS_UNDEFINED(descriptor)) return descriptor; | 639 if (IS_UNDEFINED(descriptor)) return descriptor; |
640 var desc = ToCompletePropertyDescriptor(descriptor); | 640 var desc = ToCompletePropertyDescriptor(descriptor); |
(...skipping 11 matching lines...) Expand all Loading... |
652 | 652 |
653 // A false value here means that access checks failed. | 653 // A false value here means that access checks failed. |
654 if (props === false) return UNDEFINED; | 654 if (props === false) return UNDEFINED; |
655 | 655 |
656 return ConvertDescriptorArrayToDescriptor(props); | 656 return ConvertDescriptorArrayToDescriptor(props); |
657 } | 657 } |
658 | 658 |
659 | 659 |
660 // ES5 section 8.12.7. | 660 // ES5 section 8.12.7. |
661 function Delete(obj, p, should_throw) { | 661 function Delete(obj, p, should_throw) { |
662 var desc = GetOwnProperty(obj, p); | 662 var desc = GetOwnPropertyJS(obj, p); |
663 if (IS_UNDEFINED(desc)) return true; | 663 if (IS_UNDEFINED(desc)) return true; |
664 if (desc.isConfigurable()) { | 664 if (desc.isConfigurable()) { |
665 %DeleteProperty(obj, p, 0); | 665 %DeleteProperty(obj, p, 0); |
666 return true; | 666 return true; |
667 } else if (should_throw) { | 667 } else if (should_throw) { |
668 throw MakeTypeError("define_disallowed", [p]); | 668 throw MakeTypeError("define_disallowed", [p]); |
669 } else { | 669 } else { |
670 return; | 670 return; |
671 } | 671 } |
672 } | 672 } |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 if (p === "length") { | 859 if (p === "length") { |
860 var length = obj.length; | 860 var length = obj.length; |
861 var old_length = length; | 861 var old_length = length; |
862 if (!desc.hasValue()) { | 862 if (!desc.hasValue()) { |
863 return DefineObjectProperty(obj, "length", desc, should_throw); | 863 return DefineObjectProperty(obj, "length", desc, should_throw); |
864 } | 864 } |
865 var new_length = ToUint32(desc.getValue()); | 865 var new_length = ToUint32(desc.getValue()); |
866 if (new_length != ToNumber(desc.getValue())) { | 866 if (new_length != ToNumber(desc.getValue())) { |
867 throw new $RangeError('defineProperty() array length out of range'); | 867 throw new $RangeError('defineProperty() array length out of range'); |
868 } | 868 } |
869 var length_desc = GetOwnProperty(obj, "length"); | 869 var length_desc = GetOwnPropertyJS(obj, "length"); |
870 if (new_length != length && !length_desc.isWritable()) { | 870 if (new_length != length && !length_desc.isWritable()) { |
871 if (should_throw) { | 871 if (should_throw) { |
872 throw MakeTypeError("redefine_disallowed", [p]); | 872 throw MakeTypeError("redefine_disallowed", [p]); |
873 } else { | 873 } else { |
874 return false; | 874 return false; |
875 } | 875 } |
876 } | 876 } |
877 var threw = false; | 877 var threw = false; |
878 | 878 |
879 var emit_splice = %IsObserved(obj) && new_length !== old_length; | 879 var emit_splice = %IsObserved(obj) && new_length !== old_length; |
880 var removed; | 880 var removed; |
881 if (emit_splice) { | 881 if (emit_splice) { |
882 BeginPerformSplice(obj); | 882 BeginPerformSplice(obj); |
883 removed = []; | 883 removed = []; |
884 if (new_length < old_length) | 884 if (new_length < old_length) |
885 removed.length = old_length - new_length; | 885 removed.length = old_length - new_length; |
886 } | 886 } |
887 | 887 |
888 while (new_length < length--) { | 888 while (new_length < length--) { |
889 var index = ToString(length); | 889 var index = ToString(length); |
890 if (emit_splice) { | 890 if (emit_splice) { |
891 var deletedDesc = GetOwnProperty(obj, index); | 891 var deletedDesc = GetOwnPropertyJS(obj, index); |
892 if (deletedDesc && deletedDesc.hasValue()) | 892 if (deletedDesc && deletedDesc.hasValue()) |
893 removed[length - new_length] = deletedDesc.getValue(); | 893 removed[length - new_length] = deletedDesc.getValue(); |
894 } | 894 } |
895 if (!Delete(obj, index, false)) { | 895 if (!Delete(obj, index, false)) { |
896 new_length = length + 1; | 896 new_length = length + 1; |
897 threw = true; | 897 threw = true; |
898 break; | 898 break; |
899 } | 899 } |
900 } | 900 } |
901 // Make sure the below call to DefineObjectProperty() doesn't overwrite | 901 // Make sure the below call to DefineObjectProperty() doesn't overwrite |
(...skipping 26 matching lines...) Expand all Loading... |
928 // Step 4 - Special handling for array index. | 928 // Step 4 - Special handling for array index. |
929 var index = ToUint32(p); | 929 var index = ToUint32(p); |
930 var emit_splice = false; | 930 var emit_splice = false; |
931 if (ToString(index) == p && index != 4294967295) { | 931 if (ToString(index) == p && index != 4294967295) { |
932 var length = obj.length; | 932 var length = obj.length; |
933 if (index >= length && %IsObserved(obj)) { | 933 if (index >= length && %IsObserved(obj)) { |
934 emit_splice = true; | 934 emit_splice = true; |
935 BeginPerformSplice(obj); | 935 BeginPerformSplice(obj); |
936 } | 936 } |
937 | 937 |
938 var length_desc = GetOwnProperty(obj, "length"); | 938 var length_desc = GetOwnPropertyJS(obj, "length"); |
939 if ((index >= length && !length_desc.isWritable()) || | 939 if ((index >= length && !length_desc.isWritable()) || |
940 !DefineObjectProperty(obj, p, desc, true)) { | 940 !DefineObjectProperty(obj, p, desc, true)) { |
941 if (emit_splice) | 941 if (emit_splice) |
942 EndPerformSplice(obj); | 942 EndPerformSplice(obj); |
943 if (should_throw) { | 943 if (should_throw) { |
944 throw MakeTypeError("define_disallowed", [p]); | 944 throw MakeTypeError("define_disallowed", [p]); |
945 } else { | 945 } else { |
946 return false; | 946 return false; |
947 } | 947 } |
948 } | 948 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 return obj; | 1000 return obj; |
1001 } | 1001 } |
1002 | 1002 |
1003 | 1003 |
1004 // ES5 section 15.2.3.3 | 1004 // ES5 section 15.2.3.3 |
1005 function ObjectGetOwnPropertyDescriptor(obj, p) { | 1005 function ObjectGetOwnPropertyDescriptor(obj, p) { |
1006 if (!IS_SPEC_OBJECT(obj)) { | 1006 if (!IS_SPEC_OBJECT(obj)) { |
1007 throw MakeTypeError("called_on_non_object", | 1007 throw MakeTypeError("called_on_non_object", |
1008 ["Object.getOwnPropertyDescriptor"]); | 1008 ["Object.getOwnPropertyDescriptor"]); |
1009 } | 1009 } |
1010 var desc = GetOwnProperty(obj, p); | 1010 var desc = GetOwnPropertyJS(obj, p); |
1011 return FromPropertyDescriptor(desc); | 1011 return FromPropertyDescriptor(desc); |
1012 } | 1012 } |
1013 | 1013 |
1014 | 1014 |
1015 // For Harmony proxies | 1015 // For Harmony proxies |
1016 function ToNameArray(obj, trap, includeSymbols) { | 1016 function ToNameArray(obj, trap, includeSymbols) { |
1017 if (!IS_SPEC_OBJECT(obj)) { | 1017 if (!IS_SPEC_OBJECT(obj)) { |
1018 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); | 1018 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); |
1019 } | 1019 } |
1020 var n = ToUint32(obj.length); | 1020 var n = ToUint32(obj.length); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 // The following would implement the spec as in the current proposal, | 1150 // The following would implement the spec as in the current proposal, |
1151 // but after recent comments on es-discuss, is most likely obsolete. | 1151 // but after recent comments on es-discuss, is most likely obsolete. |
1152 /* | 1152 /* |
1153 var defineObj = FromGenericPropertyDescriptor(desc); | 1153 var defineObj = FromGenericPropertyDescriptor(desc); |
1154 var names = ObjectGetOwnPropertyNames(attributes); | 1154 var names = ObjectGetOwnPropertyNames(attributes); |
1155 var standardNames = | 1155 var standardNames = |
1156 {value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0}; | 1156 {value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0}; |
1157 for (var i = 0; i < names.length; i++) { | 1157 for (var i = 0; i < names.length; i++) { |
1158 var N = names[i]; | 1158 var N = names[i]; |
1159 if (!(%HasLocalProperty(standardNames, N))) { | 1159 if (!(%HasLocalProperty(standardNames, N))) { |
1160 var attr = GetOwnProperty(attributes, N); | 1160 var attr = GetOwnPropertyJS(attributes, N); |
1161 DefineOwnProperty(descObj, N, attr, true); | 1161 DefineOwnProperty(descObj, N, attr, true); |
1162 } | 1162 } |
1163 } | 1163 } |
1164 // This is really confusing the types, but it is what the proxies spec | 1164 // This is really confusing the types, but it is what the proxies spec |
1165 // currently requires: | 1165 // currently requires: |
1166 desc = descObj; | 1166 desc = descObj; |
1167 */ | 1167 */ |
1168 } else { | 1168 } else { |
1169 var desc = ToPropertyDescriptor(attributes); | 1169 var desc = ToPropertyDescriptor(attributes); |
1170 DefineOwnProperty(obj, name, desc, true); | 1170 DefineOwnProperty(obj, name, desc, true); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 function ObjectSeal(obj) { | 1235 function ObjectSeal(obj) { |
1236 if (!IS_SPEC_OBJECT(obj)) { | 1236 if (!IS_SPEC_OBJECT(obj)) { |
1237 throw MakeTypeError("called_on_non_object", ["Object.seal"]); | 1237 throw MakeTypeError("called_on_non_object", ["Object.seal"]); |
1238 } | 1238 } |
1239 if (%IsJSProxy(obj)) { | 1239 if (%IsJSProxy(obj)) { |
1240 ProxyFix(obj); | 1240 ProxyFix(obj); |
1241 } | 1241 } |
1242 var names = ObjectGetOwnPropertyNames(obj); | 1242 var names = ObjectGetOwnPropertyNames(obj); |
1243 for (var i = 0; i < names.length; i++) { | 1243 for (var i = 0; i < names.length; i++) { |
1244 var name = names[i]; | 1244 var name = names[i]; |
1245 var desc = GetOwnProperty(obj, name); | 1245 var desc = GetOwnPropertyJS(obj, name); |
1246 if (desc.isConfigurable()) { | 1246 if (desc.isConfigurable()) { |
1247 desc.setConfigurable(false); | 1247 desc.setConfigurable(false); |
1248 DefineOwnProperty(obj, name, desc, true); | 1248 DefineOwnProperty(obj, name, desc, true); |
1249 } | 1249 } |
1250 } | 1250 } |
1251 %PreventExtensions(obj); | 1251 %PreventExtensions(obj); |
1252 return obj; | 1252 return obj; |
1253 } | 1253 } |
1254 | 1254 |
1255 | 1255 |
1256 // ES5 section 15.2.3.9. | 1256 // ES5 section 15.2.3.9. |
1257 function ObjectFreeze(obj) { | 1257 function ObjectFreezeJS(obj) { |
1258 if (!IS_SPEC_OBJECT(obj)) { | 1258 if (!IS_SPEC_OBJECT(obj)) { |
1259 throw MakeTypeError("called_on_non_object", ["Object.freeze"]); | 1259 throw MakeTypeError("called_on_non_object", ["Object.freeze"]); |
1260 } | 1260 } |
1261 var isProxy = %IsJSProxy(obj); | 1261 var isProxy = %IsJSProxy(obj); |
1262 if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { | 1262 if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { |
1263 if (isProxy) { | 1263 if (isProxy) { |
1264 ProxyFix(obj); | 1264 ProxyFix(obj); |
1265 } | 1265 } |
1266 var names = ObjectGetOwnPropertyNames(obj); | 1266 var names = ObjectGetOwnPropertyNames(obj); |
1267 for (var i = 0; i < names.length; i++) { | 1267 for (var i = 0; i < names.length; i++) { |
1268 var name = names[i]; | 1268 var name = names[i]; |
1269 var desc = GetOwnProperty(obj, name); | 1269 var desc = GetOwnPropertyJS(obj, name); |
1270 if (desc.isWritable() || desc.isConfigurable()) { | 1270 if (desc.isWritable() || desc.isConfigurable()) { |
1271 if (IsDataDescriptor(desc)) desc.setWritable(false); | 1271 if (IsDataDescriptor(desc)) desc.setWritable(false); |
1272 desc.setConfigurable(false); | 1272 desc.setConfigurable(false); |
1273 DefineOwnProperty(obj, name, desc, true); | 1273 DefineOwnProperty(obj, name, desc, true); |
1274 } | 1274 } |
1275 } | 1275 } |
1276 %PreventExtensions(obj); | 1276 %PreventExtensions(obj); |
1277 } else { | 1277 } else { |
1278 // TODO(adamk): Is it worth going to this fast path if the | 1278 // TODO(adamk): Is it worth going to this fast path if the |
1279 // object's properties are already in dictionary mode? | 1279 // object's properties are already in dictionary mode? |
(...skipping 23 matching lines...) Expand all Loading... |
1303 } | 1303 } |
1304 if (%IsJSProxy(obj)) { | 1304 if (%IsJSProxy(obj)) { |
1305 return false; | 1305 return false; |
1306 } | 1306 } |
1307 if (%IsExtensible(obj)) { | 1307 if (%IsExtensible(obj)) { |
1308 return false; | 1308 return false; |
1309 } | 1309 } |
1310 var names = ObjectGetOwnPropertyNames(obj); | 1310 var names = ObjectGetOwnPropertyNames(obj); |
1311 for (var i = 0; i < names.length; i++) { | 1311 for (var i = 0; i < names.length; i++) { |
1312 var name = names[i]; | 1312 var name = names[i]; |
1313 var desc = GetOwnProperty(obj, name); | 1313 var desc = GetOwnPropertyJS(obj, name); |
1314 if (desc.isConfigurable()) return false; | 1314 if (desc.isConfigurable()) return false; |
1315 } | 1315 } |
1316 return true; | 1316 return true; |
1317 } | 1317 } |
1318 | 1318 |
1319 | 1319 |
1320 // ES5 section 15.2.3.12 | 1320 // ES5 section 15.2.3.12 |
1321 function ObjectIsFrozen(obj) { | 1321 function ObjectIsFrozen(obj) { |
1322 if (!IS_SPEC_OBJECT(obj)) { | 1322 if (!IS_SPEC_OBJECT(obj)) { |
1323 throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]); | 1323 throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]); |
1324 } | 1324 } |
1325 if (%IsJSProxy(obj)) { | 1325 if (%IsJSProxy(obj)) { |
1326 return false; | 1326 return false; |
1327 } | 1327 } |
1328 if (%IsExtensible(obj)) { | 1328 if (%IsExtensible(obj)) { |
1329 return false; | 1329 return false; |
1330 } | 1330 } |
1331 var names = ObjectGetOwnPropertyNames(obj); | 1331 var names = ObjectGetOwnPropertyNames(obj); |
1332 for (var i = 0; i < names.length; i++) { | 1332 for (var i = 0; i < names.length; i++) { |
1333 var name = names[i]; | 1333 var name = names[i]; |
1334 var desc = GetOwnProperty(obj, name); | 1334 var desc = GetOwnPropertyJS(obj, name); |
1335 if (IsDataDescriptor(desc) && desc.isWritable()) return false; | 1335 if (IsDataDescriptor(desc) && desc.isWritable()) return false; |
1336 if (desc.isConfigurable()) return false; | 1336 if (desc.isConfigurable()) return false; |
1337 } | 1337 } |
1338 return true; | 1338 return true; |
1339 } | 1339 } |
1340 | 1340 |
1341 | 1341 |
1342 // ES5 section 15.2.3.13 | 1342 // ES5 section 15.2.3.13 |
1343 function ObjectIsExtensible(obj) { | 1343 function ObjectIsExtensible(obj) { |
1344 if (!IS_SPEC_OBJECT(obj)) { | 1344 if (!IS_SPEC_OBJECT(obj)) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 )); | 1415 )); |
1416 InstallGetterSetter($Object.prototype, "__proto__", | 1416 InstallGetterSetter($Object.prototype, "__proto__", |
1417 ObjectGetProto, ObjectSetProto); | 1417 ObjectGetProto, ObjectSetProto); |
1418 | 1418 |
1419 // Set up non-enumerable functions in the Object object. | 1419 // Set up non-enumerable functions in the Object object. |
1420 InstallFunctions($Object, DONT_ENUM, $Array( | 1420 InstallFunctions($Object, DONT_ENUM, $Array( |
1421 "keys", ObjectKeys, | 1421 "keys", ObjectKeys, |
1422 "create", ObjectCreate, | 1422 "create", ObjectCreate, |
1423 "defineProperty", ObjectDefineProperty, | 1423 "defineProperty", ObjectDefineProperty, |
1424 "defineProperties", ObjectDefineProperties, | 1424 "defineProperties", ObjectDefineProperties, |
1425 "freeze", ObjectFreeze, | 1425 "freeze", ObjectFreezeJS, |
1426 "getPrototypeOf", ObjectGetPrototypeOf, | 1426 "getPrototypeOf", ObjectGetPrototypeOf, |
1427 "setPrototypeOf", ObjectSetPrototypeOf, | 1427 "setPrototypeOf", ObjectSetPrototypeOf, |
1428 "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor, | 1428 "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor, |
1429 "getOwnPropertyNames", ObjectGetOwnPropertyNames, | 1429 "getOwnPropertyNames", ObjectGetOwnPropertyNames, |
1430 // getOwnPropertySymbols is added in symbol.js. | 1430 // getOwnPropertySymbols is added in symbol.js. |
1431 "is", ObjectIs, | 1431 "is", ObjectIs, |
1432 "isExtensible", ObjectIsExtensible, | 1432 "isExtensible", ObjectIsExtensible, |
1433 "isFrozen", ObjectIsFrozen, | 1433 "isFrozen", ObjectIsFrozen, |
1434 "isSealed", ObjectIsSealed, | 1434 "isSealed", ObjectIsSealed, |
1435 "preventExtensions", ObjectPreventExtension, | 1435 "preventExtensions", ObjectPreventExtension, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 // NOTE: Both Number objects and values can enter here as | 1547 // NOTE: Both Number objects and values can enter here as |
1548 // 'this'. This is not as dictated by ECMA-262. | 1548 // 'this'. This is not as dictated by ECMA-262. |
1549 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) { | 1549 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) { |
1550 throw new $TypeError('Number.prototype.valueOf is not generic'); | 1550 throw new $TypeError('Number.prototype.valueOf is not generic'); |
1551 } | 1551 } |
1552 return %_ValueOf(this); | 1552 return %_ValueOf(this); |
1553 } | 1553 } |
1554 | 1554 |
1555 | 1555 |
1556 // ECMA-262 section 15.7.4.5 | 1556 // ECMA-262 section 15.7.4.5 |
1557 function NumberToFixed(fractionDigits) { | 1557 function NumberToFixedJS(fractionDigits) { |
1558 var x = this; | 1558 var x = this; |
1559 if (!IS_NUMBER(this)) { | 1559 if (!IS_NUMBER(this)) { |
1560 if (!IS_NUMBER_WRAPPER(this)) { | 1560 if (!IS_NUMBER_WRAPPER(this)) { |
1561 throw MakeTypeError("incompatible_method_receiver", | 1561 throw MakeTypeError("incompatible_method_receiver", |
1562 ["Number.prototype.toFixed", this]); | 1562 ["Number.prototype.toFixed", this]); |
1563 } | 1563 } |
1564 // Get the value of this number in case it's an object. | 1564 // Get the value of this number in case it's an object. |
1565 x = %_ValueOf(this); | 1565 x = %_ValueOf(this); |
1566 } | 1566 } |
1567 var f = TO_INTEGER(fractionDigits); | 1567 var f = TO_INTEGER(fractionDigits); |
1568 | 1568 |
1569 if (f < 0 || f > 20) { | 1569 if (f < 0 || f > 20) { |
1570 throw new $RangeError("toFixed() digits argument must be between 0 and 20"); | 1570 throw new $RangeError("toFixed() digits argument must be between 0 and 20"); |
1571 } | 1571 } |
1572 | 1572 |
1573 if (NUMBER_IS_NAN(x)) return "NaN"; | 1573 if (NUMBER_IS_NAN(x)) return "NaN"; |
1574 if (x == INFINITY) return "Infinity"; | 1574 if (x == INFINITY) return "Infinity"; |
1575 if (x == -INFINITY) return "-Infinity"; | 1575 if (x == -INFINITY) return "-Infinity"; |
1576 | 1576 |
1577 return %NumberToFixed(x, f); | 1577 return %NumberToFixed(x, f); |
1578 } | 1578 } |
1579 | 1579 |
1580 | 1580 |
1581 // ECMA-262 section 15.7.4.6 | 1581 // ECMA-262 section 15.7.4.6 |
1582 function NumberToExponential(fractionDigits) { | 1582 function NumberToExponentialJS(fractionDigits) { |
1583 var x = this; | 1583 var x = this; |
1584 if (!IS_NUMBER(this)) { | 1584 if (!IS_NUMBER(this)) { |
1585 if (!IS_NUMBER_WRAPPER(this)) { | 1585 if (!IS_NUMBER_WRAPPER(this)) { |
1586 throw MakeTypeError("incompatible_method_receiver", | 1586 throw MakeTypeError("incompatible_method_receiver", |
1587 ["Number.prototype.toExponential", this]); | 1587 ["Number.prototype.toExponential", this]); |
1588 } | 1588 } |
1589 // Get the value of this number in case it's an object. | 1589 // Get the value of this number in case it's an object. |
1590 x = %_ValueOf(this); | 1590 x = %_ValueOf(this); |
1591 } | 1591 } |
1592 var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits); | 1592 var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits); |
1593 | 1593 |
1594 if (NUMBER_IS_NAN(x)) return "NaN"; | 1594 if (NUMBER_IS_NAN(x)) return "NaN"; |
1595 if (x == INFINITY) return "Infinity"; | 1595 if (x == INFINITY) return "Infinity"; |
1596 if (x == -INFINITY) return "-Infinity"; | 1596 if (x == -INFINITY) return "-Infinity"; |
1597 | 1597 |
1598 if (IS_UNDEFINED(f)) { | 1598 if (IS_UNDEFINED(f)) { |
1599 f = -1; // Signal for runtime function that f is not defined. | 1599 f = -1; // Signal for runtime function that f is not defined. |
1600 } else if (f < 0 || f > 20) { | 1600 } else if (f < 0 || f > 20) { |
1601 throw new $RangeError("toExponential() argument must be between 0 and 20"); | 1601 throw new $RangeError("toExponential() argument must be between 0 and 20"); |
1602 } | 1602 } |
1603 return %NumberToExponential(x, f); | 1603 return %NumberToExponential(x, f); |
1604 } | 1604 } |
1605 | 1605 |
1606 | 1606 |
1607 // ECMA-262 section 15.7.4.7 | 1607 // ECMA-262 section 15.7.4.7 |
1608 function NumberToPrecision(precision) { | 1608 function NumberToPrecisionJS(precision) { |
1609 var x = this; | 1609 var x = this; |
1610 if (!IS_NUMBER(this)) { | 1610 if (!IS_NUMBER(this)) { |
1611 if (!IS_NUMBER_WRAPPER(this)) { | 1611 if (!IS_NUMBER_WRAPPER(this)) { |
1612 throw MakeTypeError("incompatible_method_receiver", | 1612 throw MakeTypeError("incompatible_method_receiver", |
1613 ["Number.prototype.toPrecision", this]); | 1613 ["Number.prototype.toPrecision", this]); |
1614 } | 1614 } |
1615 // Get the value of this number in case it's an object. | 1615 // Get the value of this number in case it's an object. |
1616 x = %_ValueOf(this); | 1616 x = %_ValueOf(this); |
1617 } | 1617 } |
1618 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); | 1618 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 "MAX_SAFE_INTEGER", %_MathPow(2, 53) - 1, | 1687 "MAX_SAFE_INTEGER", %_MathPow(2, 53) - 1, |
1688 "MIN_SAFE_INTEGER", -%_MathPow(2, 53) + 1, | 1688 "MIN_SAFE_INTEGER", -%_MathPow(2, 53) + 1, |
1689 "EPSILON", %_MathPow(2, -52) | 1689 "EPSILON", %_MathPow(2, -52) |
1690 )); | 1690 )); |
1691 | 1691 |
1692 // Set up non-enumerable functions on the Number prototype object. | 1692 // Set up non-enumerable functions on the Number prototype object. |
1693 InstallFunctions($Number.prototype, DONT_ENUM, $Array( | 1693 InstallFunctions($Number.prototype, DONT_ENUM, $Array( |
1694 "toString", NumberToString, | 1694 "toString", NumberToString, |
1695 "toLocaleString", NumberToLocaleString, | 1695 "toLocaleString", NumberToLocaleString, |
1696 "valueOf", NumberValueOf, | 1696 "valueOf", NumberValueOf, |
1697 "toFixed", NumberToFixed, | 1697 "toFixed", NumberToFixedJS, |
1698 "toExponential", NumberToExponential, | 1698 "toExponential", NumberToExponentialJS, |
1699 "toPrecision", NumberToPrecision | 1699 "toPrecision", NumberToPrecisionJS |
1700 )); | 1700 )); |
1701 | 1701 |
1702 // Harmony Number constructor additions | 1702 // Harmony Number constructor additions |
1703 InstallFunctions($Number, DONT_ENUM, $Array( | 1703 InstallFunctions($Number, DONT_ENUM, $Array( |
1704 "isFinite", NumberIsFinite, | 1704 "isFinite", NumberIsFinite, |
1705 "isInteger", NumberIsInteger, | 1705 "isInteger", NumberIsInteger, |
1706 "isNaN", NumberIsNaN, | 1706 "isNaN", NumberIsNaN, |
1707 "isSafeInteger", NumberIsSafeInteger, | 1707 "isSafeInteger", NumberIsSafeInteger, |
1708 "parseInt", GlobalParseInt, | 1708 "parseInt", GlobalParseInt, |
1709 "parseFloat", GlobalParseFloat | 1709 "parseFloat", GlobalParseFloat |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 var n = arguments.length; | 1816 var n = arguments.length; |
1817 var p = ''; | 1817 var p = ''; |
1818 if (n > 1) { | 1818 if (n > 1) { |
1819 p = ToString(arguments[0]); | 1819 p = ToString(arguments[0]); |
1820 for (var i = 1; i < n - 1; i++) { | 1820 for (var i = 1; i < n - 1; i++) { |
1821 p += ',' + ToString(arguments[i]); | 1821 p += ',' + ToString(arguments[i]); |
1822 } | 1822 } |
1823 // If the formal parameters string include ) - an illegal | 1823 // If the formal parameters string include ) - an illegal |
1824 // character - it may make the combined function expression | 1824 // character - it may make the combined function expression |
1825 // compile. We avoid this problem by checking for this early on. | 1825 // compile. We avoid this problem by checking for this early on. |
1826 if (%_CallFunction(p, ')', StringIndexOf) != -1) { | 1826 if (%_CallFunction(p, ')', StringIndexOfJS) != -1) { |
1827 throw MakeSyntaxError('paren_in_arg_string', []); | 1827 throw MakeSyntaxError('paren_in_arg_string', []); |
1828 } | 1828 } |
1829 // If the formal parameters include an unbalanced block comment, the | 1829 // If the formal parameters include an unbalanced block comment, the |
1830 // function must be rejected. Since JavaScript does not allow nested | 1830 // function must be rejected. Since JavaScript does not allow nested |
1831 // comments we can include a trailing block comment to catch this. | 1831 // comments we can include a trailing block comment to catch this. |
1832 p += '\n/' + '**/'; | 1832 p += '\n/' + '**/'; |
1833 } | 1833 } |
1834 var body = (n > 0) ? ToString(arguments[n - 1]) : ''; | 1834 var body = (n > 0) ? ToString(arguments[n - 1]) : ''; |
1835 return '(' + function_token + '(' + p + ') {\n' + body + '\n})'; | 1835 return '(' + function_token + '(' + p + ') {\n' + body + '\n})'; |
1836 } | 1836 } |
(...skipping 26 matching lines...) Expand all Loading... |
1863 | 1863 |
1864 SetUpFunction(); | 1864 SetUpFunction(); |
1865 | 1865 |
1866 | 1866 |
1867 //---------------------------------------------------------------------------- | 1867 //---------------------------------------------------------------------------- |
1868 | 1868 |
1869 // TODO(rossberg): very simple abstraction for generic microtask queue. | 1869 // TODO(rossberg): very simple abstraction for generic microtask queue. |
1870 // Eventually, we should move to a real event queue that allows to maintain | 1870 // Eventually, we should move to a real event queue that allows to maintain |
1871 // relative ordering of different kinds of tasks. | 1871 // relative ordering of different kinds of tasks. |
1872 | 1872 |
1873 function RunMicrotasks() { | 1873 function RunMicrotasksJS() { |
1874 while (%SetMicrotaskPending(false)) { | 1874 while (%SetMicrotaskPending(false)) { |
1875 var microtaskState = %GetMicrotaskState(); | 1875 var microtaskState = %GetMicrotaskState(); |
1876 if (IS_UNDEFINED(microtaskState.queue)) | 1876 if (IS_UNDEFINED(microtaskState.queue)) |
1877 return; | 1877 return; |
1878 | 1878 |
1879 var microtasks = microtaskState.queue; | 1879 var microtasks = microtaskState.queue; |
1880 microtaskState.queue = null; | 1880 microtaskState.queue = null; |
1881 | 1881 |
1882 for (var i = 0; i < microtasks.length; i++) { | 1882 for (var i = 0; i < microtasks.length; i++) { |
1883 microtasks[i](); | 1883 microtasks[i](); |
1884 } | 1884 } |
1885 } | 1885 } |
1886 } | 1886 } |
1887 | 1887 |
1888 function EnqueueMicrotask(fn) { | 1888 function EnqueueMicrotask(fn) { |
1889 var microtaskState = %GetMicrotaskState(); | 1889 var microtaskState = %GetMicrotaskState(); |
1890 if (IS_UNDEFINED(microtaskState.queue) || IS_NULL(microtaskState.queue)) { | 1890 if (IS_UNDEFINED(microtaskState.queue) || IS_NULL(microtaskState.queue)) { |
1891 microtaskState.queue = new InternalArray; | 1891 microtaskState.queue = new InternalArray; |
1892 } | 1892 } |
1893 microtaskState.queue.push(fn); | 1893 microtaskState.queue.push(fn); |
1894 %SetMicrotaskPending(true); | 1894 %SetMicrotaskPending(true); |
1895 } | 1895 } |
OLD | NEW |