| 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 var $delete; | 5 var $delete; |
| 6 var $functionSourceString; | 6 var $functionSourceString; |
| 7 var $getIterator; | 7 var $getIterator; |
| 8 var $getMethod; | 8 var $getMethod; |
| 9 var $globalEval; | 9 var $globalEval; |
| 10 var $installConstants; | 10 var $installConstants; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 %InternalSetPrototype(prototype, null); | 147 %InternalSetPrototype(prototype, null); |
| 148 %ToFastProperties(prototype); | 148 %ToFastProperties(prototype); |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 // ---------------------------------------------------------------------------- | 152 // ---------------------------------------------------------------------------- |
| 153 | 153 |
| 154 | 154 |
| 155 // ECMA 262 - 15.1.4 | 155 // ECMA 262 - 15.1.4 |
| 156 function GlobalIsNaN(number) { | 156 function GlobalIsNaN(number) { |
| 157 if (!IS_NUMBER(number)) number = NonNumberToNumber(number); | 157 number = TO_NUMBER_INLINE(number); |
| 158 return NUMBER_IS_NAN(number); | 158 return NUMBER_IS_NAN(number); |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 // ECMA 262 - 15.1.5 | 162 // ECMA 262 - 15.1.5 |
| 163 function GlobalIsFinite(number) { | 163 function GlobalIsFinite(number) { |
| 164 if (!IS_NUMBER(number)) number = NonNumberToNumber(number); | 164 number = TO_NUMBER_INLINE(number); |
| 165 return NUMBER_IS_FINITE(number); | 165 return NUMBER_IS_FINITE(number); |
| 166 } | 166 } |
| 167 | 167 |
| 168 | 168 |
| 169 // ECMA-262 - 15.1.2.2 | 169 // ECMA-262 - 15.1.2.2 |
| 170 function GlobalParseInt(string, radix) { | 170 function GlobalParseInt(string, radix) { |
| 171 if (IS_UNDEFINED(radix) || radix === 10 || radix === 0) { | 171 if (IS_UNDEFINED(radix) || radix === 10 || radix === 0) { |
| 172 // Some people use parseInt instead of Math.floor. This | 172 // Some people use parseInt instead of Math.floor. This |
| 173 // optimization makes parseInt on a Smi 12 times faster (60ns | 173 // optimization makes parseInt on a Smi 12 times faster (60ns |
| 174 // vs 800ns). The following optimization makes parseInt on a | 174 // vs 800ns). The following optimization makes parseInt on a |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 } | 282 } |
| 283 | 283 |
| 284 | 284 |
| 285 // ECMA-262 - 15.2.4.5 | 285 // ECMA-262 - 15.2.4.5 |
| 286 function ObjectHasOwnProperty(V) { | 286 function ObjectHasOwnProperty(V) { |
| 287 if (%_IsJSProxy(this)) { | 287 if (%_IsJSProxy(this)) { |
| 288 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 288 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 289 if (IS_SYMBOL(V)) return false; | 289 if (IS_SYMBOL(V)) return false; |
| 290 | 290 |
| 291 var handler = %GetHandler(this); | 291 var handler = %GetHandler(this); |
| 292 return CallTrap1(handler, "hasOwn", $proxyDerivedHasOwnTrap, ToName(V)); | 292 return CallTrap1(handler, "hasOwn", $proxyDerivedHasOwnTrap, $toName(V)); |
| 293 } | 293 } |
| 294 return %HasOwnProperty(TO_OBJECT_INLINE(this), ToName(V)); | 294 return %HasOwnProperty(TO_OBJECT_INLINE(this), $toName(V)); |
| 295 } | 295 } |
| 296 | 296 |
| 297 | 297 |
| 298 // ECMA-262 - 15.2.4.6 | 298 // ECMA-262 - 15.2.4.6 |
| 299 function ObjectIsPrototypeOf(V) { | 299 function ObjectIsPrototypeOf(V) { |
| 300 if (!IS_SPEC_OBJECT(V)) return false; | 300 if (!IS_SPEC_OBJECT(V)) return false; |
| 301 CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf"); | 301 CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf"); |
| 302 return %IsInPrototypeChain(this, V); | 302 return %IsInPrototypeChain(this, V); |
| 303 } | 303 } |
| 304 | 304 |
| 305 | 305 |
| 306 // ECMA-262 - 15.2.4.6 | 306 // ECMA-262 - 15.2.4.6 |
| 307 function ObjectPropertyIsEnumerable(V) { | 307 function ObjectPropertyIsEnumerable(V) { |
| 308 var P = ToName(V); | 308 var P = $toName(V); |
| 309 if (%_IsJSProxy(this)) { | 309 if (%_IsJSProxy(this)) { |
| 310 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 310 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 311 if (IS_SYMBOL(V)) return false; | 311 if (IS_SYMBOL(V)) return false; |
| 312 | 312 |
| 313 var desc = GetOwnPropertyJS(this, P); | 313 var desc = GetOwnPropertyJS(this, P); |
| 314 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); | 314 return IS_UNDEFINED(desc) ? false : desc.isEnumerable(); |
| 315 } | 315 } |
| 316 return %IsPropertyEnumerable(TO_OBJECT_INLINE(this), P); | 316 return %IsPropertyEnumerable(TO_OBJECT_INLINE(this), P); |
| 317 } | 317 } |
| 318 | 318 |
| 319 | 319 |
| 320 // Extensions for providing property getters and setters. | 320 // Extensions for providing property getters and setters. |
| 321 function ObjectDefineGetter(name, fun) { | 321 function ObjectDefineGetter(name, fun) { |
| 322 var receiver = this; | 322 var receiver = this; |
| 323 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 323 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 324 receiver = %GlobalProxy(global); | 324 receiver = %GlobalProxy(global); |
| 325 } | 325 } |
| 326 if (!IS_SPEC_FUNCTION(fun)) { | 326 if (!IS_SPEC_FUNCTION(fun)) { |
| 327 throw MakeTypeError(kObjectGetterExpectingFunction); | 327 throw MakeTypeError(kObjectGetterExpectingFunction); |
| 328 } | 328 } |
| 329 var desc = new PropertyDescriptor(); | 329 var desc = new PropertyDescriptor(); |
| 330 desc.setGet(fun); | 330 desc.setGet(fun); |
| 331 desc.setEnumerable(true); | 331 desc.setEnumerable(true); |
| 332 desc.setConfigurable(true); | 332 desc.setConfigurable(true); |
| 333 DefineOwnProperty(TO_OBJECT_INLINE(receiver), ToName(name), desc, false); | 333 DefineOwnProperty(TO_OBJECT_INLINE(receiver), $toName(name), desc, false); |
| 334 } | 334 } |
| 335 | 335 |
| 336 | 336 |
| 337 function ObjectLookupGetter(name) { | 337 function ObjectLookupGetter(name) { |
| 338 var receiver = this; | 338 var receiver = this; |
| 339 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 339 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 340 receiver = %GlobalProxy(global); | 340 receiver = %GlobalProxy(global); |
| 341 } | 341 } |
| 342 return %LookupAccessor(TO_OBJECT_INLINE(receiver), ToName(name), GETTER); | 342 return %LookupAccessor(TO_OBJECT_INLINE(receiver), $toName(name), GETTER); |
| 343 } | 343 } |
| 344 | 344 |
| 345 | 345 |
| 346 function ObjectDefineSetter(name, fun) { | 346 function ObjectDefineSetter(name, fun) { |
| 347 var receiver = this; | 347 var receiver = this; |
| 348 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 348 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 349 receiver = %GlobalProxy(global); | 349 receiver = %GlobalProxy(global); |
| 350 } | 350 } |
| 351 if (!IS_SPEC_FUNCTION(fun)) { | 351 if (!IS_SPEC_FUNCTION(fun)) { |
| 352 throw MakeTypeError(kObjectSetterExpectingFunction); | 352 throw MakeTypeError(kObjectSetterExpectingFunction); |
| 353 } | 353 } |
| 354 var desc = new PropertyDescriptor(); | 354 var desc = new PropertyDescriptor(); |
| 355 desc.setSet(fun); | 355 desc.setSet(fun); |
| 356 desc.setEnumerable(true); | 356 desc.setEnumerable(true); |
| 357 desc.setConfigurable(true); | 357 desc.setConfigurable(true); |
| 358 DefineOwnProperty(TO_OBJECT_INLINE(receiver), ToName(name), desc, false); | 358 DefineOwnProperty(TO_OBJECT_INLINE(receiver), $toName(name), desc, false); |
| 359 } | 359 } |
| 360 | 360 |
| 361 | 361 |
| 362 function ObjectLookupSetter(name) { | 362 function ObjectLookupSetter(name) { |
| 363 var receiver = this; | 363 var receiver = this; |
| 364 if (receiver == null && !IS_UNDETECTABLE(receiver)) { | 364 if (receiver == null && !IS_UNDETECTABLE(receiver)) { |
| 365 receiver = %GlobalProxy(global); | 365 receiver = %GlobalProxy(global); |
| 366 } | 366 } |
| 367 return %LookupAccessor(TO_OBJECT_INLINE(receiver), ToName(name), SETTER); | 367 return %LookupAccessor(TO_OBJECT_INLINE(receiver), $toName(name), SETTER); |
| 368 } | 368 } |
| 369 | 369 |
| 370 | 370 |
| 371 function ObjectKeys(obj) { | 371 function ObjectKeys(obj) { |
| 372 obj = TO_OBJECT_INLINE(obj); | 372 obj = TO_OBJECT_INLINE(obj); |
| 373 if (%_IsJSProxy(obj)) { | 373 if (%_IsJSProxy(obj)) { |
| 374 var handler = %GetHandler(obj); | 374 var handler = %GetHandler(obj); |
| 375 var names = CallTrap0(handler, "keys", $proxyDerivedKeysTrap); | 375 var names = CallTrap0(handler, "keys", $proxyDerivedKeysTrap); |
| 376 return ToNameArray(names, "keys", false); | 376 return ToNameArray(names, "keys", false); |
| 377 } | 377 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 } | 450 } |
| 451 | 451 |
| 452 | 452 |
| 453 // ES5 8.10.5. | 453 // ES5 8.10.5. |
| 454 function ToPropertyDescriptor(obj) { | 454 function ToPropertyDescriptor(obj) { |
| 455 if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError(kPropertyDescObject, obj); | 455 if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError(kPropertyDescObject, obj); |
| 456 | 456 |
| 457 var desc = new PropertyDescriptor(); | 457 var desc = new PropertyDescriptor(); |
| 458 | 458 |
| 459 if ("enumerable" in obj) { | 459 if ("enumerable" in obj) { |
| 460 desc.setEnumerable(ToBoolean(obj.enumerable)); | 460 desc.setEnumerable($toBoolean(obj.enumerable)); |
| 461 } | 461 } |
| 462 | 462 |
| 463 if ("configurable" in obj) { | 463 if ("configurable" in obj) { |
| 464 desc.setConfigurable(ToBoolean(obj.configurable)); | 464 desc.setConfigurable($toBoolean(obj.configurable)); |
| 465 } | 465 } |
| 466 | 466 |
| 467 if ("value" in obj) { | 467 if ("value" in obj) { |
| 468 desc.setValue(obj.value); | 468 desc.setValue(obj.value); |
| 469 } | 469 } |
| 470 | 470 |
| 471 if ("writable" in obj) { | 471 if ("writable" in obj) { |
| 472 desc.setWritable(ToBoolean(obj.writable)); | 472 desc.setWritable($toBoolean(obj.writable)); |
| 473 } | 473 } |
| 474 | 474 |
| 475 if ("get" in obj) { | 475 if ("get" in obj) { |
| 476 var get = obj.get; | 476 var get = obj.get; |
| 477 if (!IS_UNDEFINED(get) && !IS_SPEC_FUNCTION(get)) { | 477 if (!IS_UNDEFINED(get) && !IS_SPEC_FUNCTION(get)) { |
| 478 throw MakeTypeError(kObjectGetterCallable, get); | 478 throw MakeTypeError(kObjectGetterCallable, get); |
| 479 } | 479 } |
| 480 desc.setGet(get); | 480 desc.setGet(get); |
| 481 } | 481 } |
| 482 | 482 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 } | 659 } |
| 660 | 660 |
| 661 | 661 |
| 662 function CallTrap2(handler, name, defaultTrap, x, y) { | 662 function CallTrap2(handler, name, defaultTrap, x, y) { |
| 663 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); | 663 return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap)); |
| 664 } | 664 } |
| 665 | 665 |
| 666 | 666 |
| 667 // ES5 section 8.12.1. | 667 // ES5 section 8.12.1. |
| 668 function GetOwnPropertyJS(obj, v) { | 668 function GetOwnPropertyJS(obj, v) { |
| 669 var p = ToName(v); | 669 var p = $toName(v); |
| 670 if (%_IsJSProxy(obj)) { | 670 if (%_IsJSProxy(obj)) { |
| 671 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 671 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 672 if (IS_SYMBOL(v)) return UNDEFINED; | 672 if (IS_SYMBOL(v)) return UNDEFINED; |
| 673 | 673 |
| 674 var handler = %GetHandler(obj); | 674 var handler = %GetHandler(obj); |
| 675 var descriptor = CallTrap1( | 675 var descriptor = CallTrap1( |
| 676 handler, "getOwnPropertyDescriptor", UNDEFINED, p); | 676 handler, "getOwnPropertyDescriptor", UNDEFINED, p); |
| 677 if (IS_UNDEFINED(descriptor)) return descriptor; | 677 if (IS_UNDEFINED(descriptor)) return descriptor; |
| 678 var desc = ToCompletePropertyDescriptor(descriptor); | 678 var desc = ToCompletePropertyDescriptor(descriptor); |
| 679 if (!desc.isConfigurable()) { | 679 if (!desc.isConfigurable()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 } | 716 } |
| 717 | 717 |
| 718 | 718 |
| 719 // Harmony proxies. | 719 // Harmony proxies. |
| 720 function DefineProxyProperty(obj, p, attributes, should_throw) { | 720 function DefineProxyProperty(obj, p, attributes, should_throw) { |
| 721 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 721 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 722 if (IS_SYMBOL(p)) return false; | 722 if (IS_SYMBOL(p)) return false; |
| 723 | 723 |
| 724 var handler = %GetHandler(obj); | 724 var handler = %GetHandler(obj); |
| 725 var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes); | 725 var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes); |
| 726 if (!ToBoolean(result)) { | 726 if (!$toBoolean(result)) { |
| 727 if (should_throw) { | 727 if (should_throw) { |
| 728 throw MakeTypeError(kProxyHandlerReturned, | 728 throw MakeTypeError(kProxyHandlerReturned, |
| 729 handler, "false", "defineProperty"); | 729 handler, "false", "defineProperty"); |
| 730 } else { | 730 } else { |
| 731 return false; | 731 return false; |
| 732 } | 732 } |
| 733 } | 733 } |
| 734 return true; | 734 return true; |
| 735 } | 735 } |
| 736 | 736 |
| 737 | 737 |
| 738 // ES5 8.12.9. | 738 // ES5 8.12.9. |
| 739 function DefineObjectProperty(obj, p, desc, should_throw) { | 739 function DefineObjectProperty(obj, p, desc, should_throw) { |
| 740 var current_array = %GetOwnProperty(obj, ToName(p)); | 740 var current_array = %GetOwnProperty(obj, $toName(p)); |
| 741 var current = ConvertDescriptorArrayToDescriptor(current_array); | 741 var current = ConvertDescriptorArrayToDescriptor(current_array); |
| 742 var extensible = %IsExtensible(obj); | 742 var extensible = %IsExtensible(obj); |
| 743 | 743 |
| 744 // Error handling according to spec. | 744 // Error handling according to spec. |
| 745 // Step 3 | 745 // Step 3 |
| 746 if (IS_UNDEFINED(current) && !extensible) { | 746 if (IS_UNDEFINED(current) && !extensible) { |
| 747 if (should_throw) { | 747 if (should_throw) { |
| 748 throw MakeTypeError(kDefineDisallowed, p); | 748 throw MakeTypeError(kDefineDisallowed, p); |
| 749 } else { | 749 } else { |
| 750 return false; | 750 return false; |
| 751 } | 751 } |
| 752 } | 752 } |
| 753 | 753 |
| 754 if (!IS_UNDEFINED(current)) { | 754 if (!IS_UNDEFINED(current)) { |
| 755 // Step 5 and 6 | 755 // Step 5 and 6 |
| 756 if ((IsGenericDescriptor(desc) || | 756 if ((IsGenericDescriptor(desc) || |
| 757 IsDataDescriptor(desc) == IsDataDescriptor(current)) && | 757 IsDataDescriptor(desc) == IsDataDescriptor(current)) && |
| 758 (!desc.hasEnumerable() || | 758 (!desc.hasEnumerable() || |
| 759 SameValue(desc.isEnumerable(), current.isEnumerable())) && | 759 $sameValue(desc.isEnumerable(), current.isEnumerable())) && |
| 760 (!desc.hasConfigurable() || | 760 (!desc.hasConfigurable() || |
| 761 SameValue(desc.isConfigurable(), current.isConfigurable())) && | 761 $sameValue(desc.isConfigurable(), current.isConfigurable())) && |
| 762 (!desc.hasWritable() || | 762 (!desc.hasWritable() || |
| 763 SameValue(desc.isWritable(), current.isWritable())) && | 763 $sameValue(desc.isWritable(), current.isWritable())) && |
| 764 (!desc.hasValue() || | 764 (!desc.hasValue() || |
| 765 SameValue(desc.getValue(), current.getValue())) && | 765 $sameValue(desc.getValue(), current.getValue())) && |
| 766 (!desc.hasGetter() || | 766 (!desc.hasGetter() || |
| 767 SameValue(desc.getGet(), current.getGet())) && | 767 $sameValue(desc.getGet(), current.getGet())) && |
| 768 (!desc.hasSetter() || | 768 (!desc.hasSetter() || |
| 769 SameValue(desc.getSet(), current.getSet()))) { | 769 $sameValue(desc.getSet(), current.getSet()))) { |
| 770 return true; | 770 return true; |
| 771 } | 771 } |
| 772 if (!current.isConfigurable()) { | 772 if (!current.isConfigurable()) { |
| 773 // Step 7 | 773 // Step 7 |
| 774 if (desc.isConfigurable() || | 774 if (desc.isConfigurable() || |
| 775 (desc.hasEnumerable() && | 775 (desc.hasEnumerable() && |
| 776 desc.isEnumerable() != current.isEnumerable())) { | 776 desc.isEnumerable() != current.isEnumerable())) { |
| 777 if (should_throw) { | 777 if (should_throw) { |
| 778 throw MakeTypeError(kRedefineDisallowed, p); | 778 throw MakeTypeError(kRedefineDisallowed, p); |
| 779 } else { | 779 } else { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 793 // Step 10a | 793 // Step 10a |
| 794 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { | 794 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { |
| 795 if (!current.isWritable() && desc.isWritable()) { | 795 if (!current.isWritable() && desc.isWritable()) { |
| 796 if (should_throw) { | 796 if (should_throw) { |
| 797 throw MakeTypeError(kRedefineDisallowed, p); | 797 throw MakeTypeError(kRedefineDisallowed, p); |
| 798 } else { | 798 } else { |
| 799 return false; | 799 return false; |
| 800 } | 800 } |
| 801 } | 801 } |
| 802 if (!current.isWritable() && desc.hasValue() && | 802 if (!current.isWritable() && desc.hasValue() && |
| 803 !SameValue(desc.getValue(), current.getValue())) { | 803 !$sameValue(desc.getValue(), current.getValue())) { |
| 804 if (should_throw) { | 804 if (should_throw) { |
| 805 throw MakeTypeError(kRedefineDisallowed, p); | 805 throw MakeTypeError(kRedefineDisallowed, p); |
| 806 } else { | 806 } else { |
| 807 return false; | 807 return false; |
| 808 } | 808 } |
| 809 } | 809 } |
| 810 } | 810 } |
| 811 // Step 11 | 811 // Step 11 |
| 812 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { | 812 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { |
| 813 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) { | 813 if (desc.hasSetter() && |
| 814 !$sameValue(desc.getSet(), current.getSet())) { |
| 814 if (should_throw) { | 815 if (should_throw) { |
| 815 throw MakeTypeError(kRedefineDisallowed, p); | 816 throw MakeTypeError(kRedefineDisallowed, p); |
| 816 } else { | 817 } else { |
| 817 return false; | 818 return false; |
| 818 } | 819 } |
| 819 } | 820 } |
| 820 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) { | 821 if (desc.hasGetter() && !$sameValue(desc.getGet(),current.getGet())) { |
| 821 if (should_throw) { | 822 if (should_throw) { |
| 822 throw MakeTypeError(kRedefineDisallowed, p); | 823 throw MakeTypeError(kRedefineDisallowed, p); |
| 823 } else { | 824 } else { |
| 824 return false; | 825 return false; |
| 825 } | 826 } |
| 826 } | 827 } |
| 827 } | 828 } |
| 828 } | 829 } |
| 829 } | 830 } |
| 830 } | 831 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 // property, hence we use generated code throughout this function instead of | 907 // property, hence we use generated code throughout this function instead of |
| 907 // DefineObjectProperty() to modify its value. | 908 // DefineObjectProperty() to modify its value. |
| 908 | 909 |
| 909 // Step 3 - Special handling for length property. | 910 // Step 3 - Special handling for length property. |
| 910 if (p === "length") { | 911 if (p === "length") { |
| 911 var length = obj.length; | 912 var length = obj.length; |
| 912 var old_length = length; | 913 var old_length = length; |
| 913 if (!desc.hasValue()) { | 914 if (!desc.hasValue()) { |
| 914 return DefineObjectProperty(obj, "length", desc, should_throw); | 915 return DefineObjectProperty(obj, "length", desc, should_throw); |
| 915 } | 916 } |
| 916 var new_length = ToUint32(desc.getValue()); | 917 var new_length = $toUint32(desc.getValue()); |
| 917 if (new_length != ToNumber(desc.getValue())) { | 918 if (new_length != $toNumber(desc.getValue())) { |
| 918 throw MakeRangeError(kArrayLengthOutOfRange); | 919 throw MakeRangeError(kArrayLengthOutOfRange); |
| 919 } | 920 } |
| 920 var length_desc = GetOwnPropertyJS(obj, "length"); | 921 var length_desc = GetOwnPropertyJS(obj, "length"); |
| 921 if (new_length != length && !length_desc.isWritable()) { | 922 if (new_length != length && !length_desc.isWritable()) { |
| 922 if (should_throw) { | 923 if (should_throw) { |
| 923 throw MakeTypeError(kRedefineDisallowed, p); | 924 throw MakeTypeError(kRedefineDisallowed, p); |
| 924 } else { | 925 } else { |
| 925 return false; | 926 return false; |
| 926 } | 927 } |
| 927 } | 928 } |
| 928 var threw = false; | 929 var threw = false; |
| 929 | 930 |
| 930 var emit_splice = %IsObserved(obj) && new_length !== old_length; | 931 var emit_splice = %IsObserved(obj) && new_length !== old_length; |
| 931 var removed; | 932 var removed; |
| 932 if (emit_splice) { | 933 if (emit_splice) { |
| 933 $observeBeginPerformSplice(obj); | 934 $observeBeginPerformSplice(obj); |
| 934 removed = []; | 935 removed = []; |
| 935 if (new_length < old_length) | 936 if (new_length < old_length) |
| 936 removed.length = old_length - new_length; | 937 removed.length = old_length - new_length; |
| 937 } | 938 } |
| 938 | 939 |
| 939 while (new_length < length--) { | 940 while (new_length < length--) { |
| 940 var index = ToString(length); | 941 var index = $toString(length); |
| 941 if (emit_splice) { | 942 if (emit_splice) { |
| 942 var deletedDesc = GetOwnPropertyJS(obj, index); | 943 var deletedDesc = GetOwnPropertyJS(obj, index); |
| 943 if (deletedDesc && deletedDesc.hasValue()) | 944 if (deletedDesc && deletedDesc.hasValue()) |
| 944 removed[length - new_length] = deletedDesc.getValue(); | 945 removed[length - new_length] = deletedDesc.getValue(); |
| 945 } | 946 } |
| 946 if (!Delete(obj, index, false)) { | 947 if (!Delete(obj, index, false)) { |
| 947 new_length = length + 1; | 948 new_length = length + 1; |
| 948 threw = true; | 949 threw = true; |
| 949 break; | 950 break; |
| 950 } | 951 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 962 throw MakeTypeError(kRedefineDisallowed, p); | 963 throw MakeTypeError(kRedefineDisallowed, p); |
| 963 } else { | 964 } else { |
| 964 return false; | 965 return false; |
| 965 } | 966 } |
| 966 } | 967 } |
| 967 return true; | 968 return true; |
| 968 } | 969 } |
| 969 | 970 |
| 970 // Step 4 - Special handling for array index. | 971 // Step 4 - Special handling for array index. |
| 971 if (!IS_SYMBOL(p)) { | 972 if (!IS_SYMBOL(p)) { |
| 972 var index = ToUint32(p); | 973 var index = $toUint32(p); |
| 973 var emit_splice = false; | 974 var emit_splice = false; |
| 974 if (ToString(index) == p && index != 4294967295) { | 975 if ($toString(index) == p && index != 4294967295) { |
| 975 var length = obj.length; | 976 var length = obj.length; |
| 976 if (index >= length && %IsObserved(obj)) { | 977 if (index >= length && %IsObserved(obj)) { |
| 977 emit_splice = true; | 978 emit_splice = true; |
| 978 $observeBeginPerformSplice(obj); | 979 $observeBeginPerformSplice(obj); |
| 979 } | 980 } |
| 980 | 981 |
| 981 var length_desc = GetOwnPropertyJS(obj, "length"); | 982 var length_desc = GetOwnPropertyJS(obj, "length"); |
| 982 if ((index >= length && !length_desc.isWritable()) || | 983 if ((index >= length && !length_desc.isWritable()) || |
| 983 !DefineObjectProperty(obj, p, desc, true)) { | 984 !DefineObjectProperty(obj, p, desc, true)) { |
| 984 if (emit_splice) | 985 if (emit_splice) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 var desc = GetOwnPropertyJS(TO_OBJECT_INLINE(obj), p); | 1048 var desc = GetOwnPropertyJS(TO_OBJECT_INLINE(obj), p); |
| 1048 return FromPropertyDescriptor(desc); | 1049 return FromPropertyDescriptor(desc); |
| 1049 } | 1050 } |
| 1050 | 1051 |
| 1051 | 1052 |
| 1052 // For Harmony proxies | 1053 // For Harmony proxies |
| 1053 function ToNameArray(obj, trap, includeSymbols) { | 1054 function ToNameArray(obj, trap, includeSymbols) { |
| 1054 if (!IS_SPEC_OBJECT(obj)) { | 1055 if (!IS_SPEC_OBJECT(obj)) { |
| 1055 throw MakeTypeError(kProxyNonObjectPropNames, trap, obj); | 1056 throw MakeTypeError(kProxyNonObjectPropNames, trap, obj); |
| 1056 } | 1057 } |
| 1057 var n = ToUint32(obj.length); | 1058 var n = $toUint32(obj.length); |
| 1058 var array = new GlobalArray(n); | 1059 var array = new GlobalArray(n); |
| 1059 var realLength = 0; | 1060 var realLength = 0; |
| 1060 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. | 1061 var names = { __proto__: null }; // TODO(rossberg): use sets once ready. |
| 1061 for (var index = 0; index < n; index++) { | 1062 for (var index = 0; index < n; index++) { |
| 1062 var s = ToName(obj[index]); | 1063 var s = $toName(obj[index]); |
| 1063 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 1064 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 1064 if (IS_SYMBOL(s) && !includeSymbols) continue; | 1065 if (IS_SYMBOL(s) && !includeSymbols) continue; |
| 1065 if (%HasOwnProperty(names, s)) { | 1066 if (%HasOwnProperty(names, s)) { |
| 1066 throw MakeTypeError(kProxyRepeatedPropName, trap, s); | 1067 throw MakeTypeError(kProxyRepeatedPropName, trap, s); |
| 1067 } | 1068 } |
| 1068 array[index] = s; | 1069 array[index] = s; |
| 1069 ++realLength; | 1070 ++realLength; |
| 1070 names[s] = 0; | 1071 names[s] = 0; |
| 1071 } | 1072 } |
| 1072 array.length = realLength; | 1073 array.length = realLength; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 var seenKeys = { __proto__: null }; | 1122 var seenKeys = { __proto__: null }; |
| 1122 var j = 0; | 1123 var j = 0; |
| 1123 for (var i = 0; i < propertyNames.length; ++i) { | 1124 for (var i = 0; i < propertyNames.length; ++i) { |
| 1124 var name = propertyNames[i]; | 1125 var name = propertyNames[i]; |
| 1125 if (IS_SYMBOL(name)) { | 1126 if (IS_SYMBOL(name)) { |
| 1126 if ((filter & PROPERTY_ATTRIBUTES_SYMBOLIC) || IS_PRIVATE(name)) { | 1127 if ((filter & PROPERTY_ATTRIBUTES_SYMBOLIC) || IS_PRIVATE(name)) { |
| 1127 continue; | 1128 continue; |
| 1128 } | 1129 } |
| 1129 } else { | 1130 } else { |
| 1130 if (filter & PROPERTY_ATTRIBUTES_STRING) continue; | 1131 if (filter & PROPERTY_ATTRIBUTES_STRING) continue; |
| 1131 name = ToString(name); | 1132 name = $toString(name); |
| 1132 } | 1133 } |
| 1133 if (seenKeys[name]) continue; | 1134 if (seenKeys[name]) continue; |
| 1134 seenKeys[name] = true; | 1135 seenKeys[name] = true; |
| 1135 propertyNames[j++] = name; | 1136 propertyNames[j++] = name; |
| 1136 } | 1137 } |
| 1137 propertyNames.length = j; | 1138 propertyNames.length = j; |
| 1138 } | 1139 } |
| 1139 | 1140 |
| 1140 return propertyNames; | 1141 return propertyNames; |
| 1141 } | 1142 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1165 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); | 1166 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); |
| 1166 return obj; | 1167 return obj; |
| 1167 } | 1168 } |
| 1168 | 1169 |
| 1169 | 1170 |
| 1170 // ES5 section 15.2.3.6. | 1171 // ES5 section 15.2.3.6. |
| 1171 function ObjectDefineProperty(obj, p, attributes) { | 1172 function ObjectDefineProperty(obj, p, attributes) { |
| 1172 if (!IS_SPEC_OBJECT(obj)) { | 1173 if (!IS_SPEC_OBJECT(obj)) { |
| 1173 throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty"); | 1174 throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty"); |
| 1174 } | 1175 } |
| 1175 var name = ToName(p); | 1176 var name = $toName(p); |
| 1176 if (%_IsJSProxy(obj)) { | 1177 if (%_IsJSProxy(obj)) { |
| 1177 // Clone the attributes object for protection. | 1178 // Clone the attributes object for protection. |
| 1178 // TODO(rossberg): not spec'ed yet, so not sure if this should involve | 1179 // TODO(rossberg): not spec'ed yet, so not sure if this should involve |
| 1179 // non-own properties as it does (or non-enumerable ones, as it doesn't?). | 1180 // non-own properties as it does (or non-enumerable ones, as it doesn't?). |
| 1180 var attributesClone = { __proto__: null }; | 1181 var attributesClone = { __proto__: null }; |
| 1181 for (var a in attributes) { | 1182 for (var a in attributes) { |
| 1182 attributesClone[a] = attributes[a]; | 1183 attributesClone[a] = attributes[a]; |
| 1183 } | 1184 } |
| 1184 DefineProxyProperty(obj, name, attributesClone, true); | 1185 DefineProxyProperty(obj, name, attributesClone, true); |
| 1185 // The following would implement the spec as in the current proposal, | 1186 // The following would implement the spec as in the current proposal, |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 if (!IS_SPEC_OBJECT(obj)) return false; | 1390 if (!IS_SPEC_OBJECT(obj)) return false; |
| 1390 if (%_IsJSProxy(obj)) { | 1391 if (%_IsJSProxy(obj)) { |
| 1391 return true; | 1392 return true; |
| 1392 } | 1393 } |
| 1393 return %IsExtensible(obj); | 1394 return %IsExtensible(obj); |
| 1394 } | 1395 } |
| 1395 | 1396 |
| 1396 | 1397 |
| 1397 // ECMA-262, Edition 6, section 19.1.2.10 | 1398 // ECMA-262, Edition 6, section 19.1.2.10 |
| 1398 function ObjectIs(obj1, obj2) { | 1399 function ObjectIs(obj1, obj2) { |
| 1399 return SameValue(obj1, obj2); | 1400 return $sameValue(obj1, obj2); |
| 1400 } | 1401 } |
| 1401 | 1402 |
| 1402 | 1403 |
| 1403 // ECMA-262, Edition 6, section B.2.2.1.1 | 1404 // ECMA-262, Edition 6, section B.2.2.1.1 |
| 1404 function ObjectGetProto() { | 1405 function ObjectGetProto() { |
| 1405 return %_GetPrototype(TO_OBJECT_INLINE(this)); | 1406 return %_GetPrototype(TO_OBJECT_INLINE(this)); |
| 1406 } | 1407 } |
| 1407 | 1408 |
| 1408 | 1409 |
| 1409 // ECMA-262, Edition 6, section B.2.2.1.2 | 1410 // ECMA-262, Edition 6, section B.2.2.1.2 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 // deliverChangeRecords, getNotifier, observe and unobserve are added | 1474 // deliverChangeRecords, getNotifier, observe and unobserve are added |
| 1474 // in object-observe.js. | 1475 // in object-observe.js. |
| 1475 ]); | 1476 ]); |
| 1476 | 1477 |
| 1477 | 1478 |
| 1478 // ---------------------------------------------------------------------------- | 1479 // ---------------------------------------------------------------------------- |
| 1479 // Boolean | 1480 // Boolean |
| 1480 | 1481 |
| 1481 function BooleanConstructor(x) { | 1482 function BooleanConstructor(x) { |
| 1482 if (%_IsConstructCall()) { | 1483 if (%_IsConstructCall()) { |
| 1483 %_SetValueOf(this, ToBoolean(x)); | 1484 %_SetValueOf(this, $toBoolean(x)); |
| 1484 } else { | 1485 } else { |
| 1485 return ToBoolean(x); | 1486 return $toBoolean(x); |
| 1486 } | 1487 } |
| 1487 } | 1488 } |
| 1488 | 1489 |
| 1489 | 1490 |
| 1490 function BooleanToString() { | 1491 function BooleanToString() { |
| 1491 // NOTE: Both Boolean objects and values can enter here as | 1492 // NOTE: Both Boolean objects and values can enter here as |
| 1492 // 'this'. This is not as dictated by ECMA-262. | 1493 // 'this'. This is not as dictated by ECMA-262. |
| 1493 var b = this; | 1494 var b = this; |
| 1494 if (!IS_BOOLEAN(b)) { | 1495 if (!IS_BOOLEAN(b)) { |
| 1495 if (!IS_BOOLEAN_WRAPPER(b)) { | 1496 if (!IS_BOOLEAN_WRAPPER(b)) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1521 InstallFunctions(GlobalBoolean.prototype, DONT_ENUM, [ | 1522 InstallFunctions(GlobalBoolean.prototype, DONT_ENUM, [ |
| 1522 "toString", BooleanToString, | 1523 "toString", BooleanToString, |
| 1523 "valueOf", BooleanValueOf | 1524 "valueOf", BooleanValueOf |
| 1524 ]); | 1525 ]); |
| 1525 | 1526 |
| 1526 | 1527 |
| 1527 // ---------------------------------------------------------------------------- | 1528 // ---------------------------------------------------------------------------- |
| 1528 // Number | 1529 // Number |
| 1529 | 1530 |
| 1530 function NumberConstructor(x) { | 1531 function NumberConstructor(x) { |
| 1531 var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x); | 1532 var value = %_ArgumentsLength() == 0 ? 0 : $toNumber(x); |
| 1532 if (%_IsConstructCall()) { | 1533 if (%_IsConstructCall()) { |
| 1533 %_SetValueOf(this, value); | 1534 %_SetValueOf(this, value); |
| 1534 } else { | 1535 } else { |
| 1535 return value; | 1536 return value; |
| 1536 } | 1537 } |
| 1537 } | 1538 } |
| 1538 | 1539 |
| 1539 | 1540 |
| 1540 // ECMA-262 section 15.7.4.2. | 1541 // ECMA-262 section 15.7.4.2. |
| 1541 function NumberToStringJS(radix) { | 1542 function NumberToStringJS(radix) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 function NumberToPrecisionJS(precision) { | 1635 function NumberToPrecisionJS(precision) { |
| 1635 var x = this; | 1636 var x = this; |
| 1636 if (!IS_NUMBER(this)) { | 1637 if (!IS_NUMBER(this)) { |
| 1637 if (!IS_NUMBER_WRAPPER(this)) { | 1638 if (!IS_NUMBER_WRAPPER(this)) { |
| 1638 throw MakeTypeError(kIncompatibleMethodReceiver, | 1639 throw MakeTypeError(kIncompatibleMethodReceiver, |
| 1639 "Number.prototype.toPrecision", this); | 1640 "Number.prototype.toPrecision", this); |
| 1640 } | 1641 } |
| 1641 // Get the value of this number in case it's an object. | 1642 // Get the value of this number in case it's an object. |
| 1642 x = %_ValueOf(this); | 1643 x = %_ValueOf(this); |
| 1643 } | 1644 } |
| 1644 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); | 1645 if (IS_UNDEFINED(precision)) return $toString(%_ValueOf(this)); |
| 1645 var p = TO_INTEGER(precision); | 1646 var p = TO_INTEGER(precision); |
| 1646 | 1647 |
| 1647 if (NUMBER_IS_NAN(x)) return "NaN"; | 1648 if (NUMBER_IS_NAN(x)) return "NaN"; |
| 1648 if (x == INFINITY) return "Infinity"; | 1649 if (x == INFINITY) return "Infinity"; |
| 1649 if (x == -INFINITY) return "-Infinity"; | 1650 if (x == -INFINITY) return "-Infinity"; |
| 1650 | 1651 |
| 1651 if (p < 1 || p > 21) { | 1652 if (p < 1 || p > 21) { |
| 1652 throw MakeRangeError(kToPrecisionFormatRange); | 1653 throw MakeRangeError(kToPrecisionFormatRange); |
| 1653 } | 1654 } |
| 1654 return %NumberToPrecision(x, p); | 1655 return %NumberToPrecision(x, p); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 // To be consistent with our normal functions we leave this as it is. | 1850 // To be consistent with our normal functions we leave this as it is. |
| 1850 // TODO(lrn): Do set these to be thrower. | 1851 // TODO(lrn): Do set these to be thrower. |
| 1851 return result; | 1852 return result; |
| 1852 } | 1853 } |
| 1853 | 1854 |
| 1854 | 1855 |
| 1855 function NewFunctionString(args, function_token) { | 1856 function NewFunctionString(args, function_token) { |
| 1856 var n = args.length; | 1857 var n = args.length; |
| 1857 var p = ''; | 1858 var p = ''; |
| 1858 if (n > 1) { | 1859 if (n > 1) { |
| 1859 p = ToString(args[0]); | 1860 p = $toString(args[0]); |
| 1860 for (var i = 1; i < n - 1; i++) { | 1861 for (var i = 1; i < n - 1; i++) { |
| 1861 p += ',' + ToString(args[i]); | 1862 p += ',' + $toString(args[i]); |
| 1862 } | 1863 } |
| 1863 // If the formal parameters string include ) - an illegal | 1864 // If the formal parameters string include ) - an illegal |
| 1864 // character - it may make the combined function expression | 1865 // character - it may make the combined function expression |
| 1865 // compile. We avoid this problem by checking for this early on. | 1866 // compile. We avoid this problem by checking for this early on. |
| 1866 if (%_CallFunction(p, ')', $stringIndexOf) != -1) { | 1867 if (%_CallFunction(p, ')', $stringIndexOf) != -1) { |
| 1867 throw MakeSyntaxError(kParenthesisInArgString); | 1868 throw MakeSyntaxError(kParenthesisInArgString); |
| 1868 } | 1869 } |
| 1869 // If the formal parameters include an unbalanced block comment, the | 1870 // If the formal parameters include an unbalanced block comment, the |
| 1870 // function must be rejected. Since JavaScript does not allow nested | 1871 // function must be rejected. Since JavaScript does not allow nested |
| 1871 // comments we can include a trailing block comment to catch this. | 1872 // comments we can include a trailing block comment to catch this. |
| 1872 p += '\n/' + '**/'; | 1873 p += '\n/' + '**/'; |
| 1873 } | 1874 } |
| 1874 var body = (n > 0) ? ToString(args[n - 1]) : ''; | 1875 var body = (n > 0) ? $toString(args[n - 1]) : ''; |
| 1875 return '(' + function_token + '(' + p + ') {\n' + body + '\n})'; | 1876 return '(' + function_token + '(' + p + ') {\n' + body + '\n})'; |
| 1876 } | 1877 } |
| 1877 | 1878 |
| 1878 | 1879 |
| 1879 function FunctionConstructor(arg1) { // length == 1 | 1880 function FunctionConstructor(arg1) { // length == 1 |
| 1880 var source = NewFunctionString(arguments, 'function'); | 1881 var source = NewFunctionString(arguments, 'function'); |
| 1881 var global_proxy = %GlobalProxy(global); | 1882 var global_proxy = %GlobalProxy(global); |
| 1882 // Compile the string in the constructor and not a helper so that errors | 1883 // Compile the string in the constructor and not a helper so that errors |
| 1883 // appear to come from here. | 1884 // appear to come from here. |
| 1884 var f = %_CallFunction(global_proxy, %CompileString(source, true)); | 1885 var f = %_CallFunction(global_proxy, %CompileString(source, true)); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1942 $objectLookupGetter = ObjectLookupGetter; | 1943 $objectLookupGetter = ObjectLookupGetter; |
| 1943 $objectLookupSetter = ObjectLookupSetter; | 1944 $objectLookupSetter = ObjectLookupSetter; |
| 1944 $objectToString = ObjectToString; | 1945 $objectToString = ObjectToString; |
| 1945 $overrideFunction = OverrideFunction; | 1946 $overrideFunction = OverrideFunction; |
| 1946 $setFunctionName = SetFunctionName; | 1947 $setFunctionName = SetFunctionName; |
| 1947 $setUpLockedPrototype = SetUpLockedPrototype; | 1948 $setUpLockedPrototype = SetUpLockedPrototype; |
| 1948 $toCompletePropertyDescriptor = ToCompletePropertyDescriptor; | 1949 $toCompletePropertyDescriptor = ToCompletePropertyDescriptor; |
| 1949 $toNameArray = ToNameArray; | 1950 $toNameArray = ToNameArray; |
| 1950 | 1951 |
| 1951 })(); | 1952 })(); |
| OLD | NEW |