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