1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This files contains runtime support implemented in JavaScript. 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CAUTION: Some of the functions specified in this file are called 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// directly from compiled code. These are the functions with names in 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ALL CAPS. The compiled code passes the first argument in 'this' and 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// it does not push the function onto the stack. This means that you 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// cannot use contexts in all these functions. 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ----------------------------------- 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block - - - C o m p a r i s o n - - - 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ----------------------------------- 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The following const declarations are shared with other native JS files. 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// They are all declared at this one spot to avoid const redeclaration errors. 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $Object = global.Object; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $Array = global.Array; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $String = global.String; 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $Number = global.Number; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $Function = global.Function; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $Boolean = global.Boolean; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst $NaN = 0/0; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.9.1, page 55. 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction EQUALS(y) { 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y); 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var x = this; 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE: We use iteration instead of recursion, because it is 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // difficult to call EQUALS with the correct setting of 'this' in 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // an efficient way. 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(x)) { 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (y == null) return 1; // not equal 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberEquals(x, %ToNumber(y)); 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (IS_STRING(x)) { 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(y)) return %StringEquals(x, y); 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y)); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (y == null) return 1; // not equal 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block y = %ToPrimitive(y, NO_HINT); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (IS_BOOLEAN(x)) { 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_BOOLEAN(y)) { 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %_ObjectEquals(x, y) ? 0 : 1; 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (y == null) return 1; // not equal 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberEquals(%ToNumber(x), %ToNumber(y)); 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (x == null) { 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE: This checks for both null and undefined. 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (y == null) ? 0 : 1; 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // x is not a number, boolean, null or undefined. 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (y == null) return 1; // not equal 833bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (IS_SPEC_OBJECT(y)) { 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %_ObjectEquals(x, y) ? 0 : 1; 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = %ToPrimitive(x, NO_HINT); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.9.4, page 56. 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction STRICT_EQUALS(x) { 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(this)) { 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_STRING(x)) return 1; // not equal 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %StringEquals(this, x); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(this)) { 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_NUMBER(x)) return 1; // not equal 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberEquals(this, x); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If anything else gets here, we just do simple identity check. 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects (including functions), null, undefined and booleans were 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // checked in the CompareStub, so there should be nothing left. 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %_ObjectEquals(this, x) ? 0 : 1; 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the result when either (or both) the operands are NaN. 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction COMPARE(x, ncr) { 114e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var left; 1158defd9ff6930b4e24729971a61cf7469daf119beSteve Block var right; 116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Fast cases for string, numbers and undefined compares. 117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_STRING(this)) { 118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_STRING(x)) return %_StringCompare(this, x); 119e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_UNDEFINED(x)) return ncr; 120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke left = this; 121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (IS_NUMBER(this)) { 122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_NUMBER(x)) return %NumberCompare(this, x, ncr); 123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_UNDEFINED(x)) return ncr; 124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke left = this; 125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else if (IS_UNDEFINED(this)) { 1268defd9ff6930b4e24729971a61cf7469daf119beSteve Block if (!IS_UNDEFINED(x)) { 1278defd9ff6930b4e24729971a61cf7469daf119beSteve Block %ToPrimitive(x, NUMBER_HINT); 1288defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 1298defd9ff6930b4e24729971a61cf7469daf119beSteve Block return ncr; 1308defd9ff6930b4e24729971a61cf7469daf119beSteve Block } else if (IS_UNDEFINED(x)) { 1318defd9ff6930b4e24729971a61cf7469daf119beSteve Block %ToPrimitive(this, NUMBER_HINT); 132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return ncr; 133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke left = %ToPrimitive(this, NUMBER_HINT); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1378defd9ff6930b4e24729971a61cf7469daf119beSteve Block right = %ToPrimitive(x, NUMBER_HINT); 138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (IS_STRING(left) && IS_STRING(right)) { 139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return %_StringCompare(left, right); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var left_number = %ToNumber(left); 142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke var right_number = %ToNumber(right); 143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (NUMBER_IS_NAN(left_number) || NUMBER_IS_NAN(right_number)) return ncr; 144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return %NumberCompare(left_number, right_number, ncr); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ----------------------------------- 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block - - - A r i t h m e t i c - - - 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ----------------------------------- 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.6.1, page 50. 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ADD(x) { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fast case: Check for number operands and do the addition. 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); 159d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default implementation. 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var a = %ToPrimitive(this, NO_HINT); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var b = %ToPrimitive(x, NO_HINT); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(a)) { 166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return %_StringAdd(a, %ToString(b)); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (IS_STRING(b)) { 168086aeeaae12517475c22695a200be45495516549Ben Murdoch return %_StringAdd(%NonStringToString(a), b); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberAdd(%ToNumber(a), %ToNumber(b)); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Left operand (this) is already a string. 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction STRING_ADD_LEFT(y) { 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_STRING(y)) { 178756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block y = %_ValueOf(y); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block y = IS_NUMBER(y) 182402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu ? %_NumberToString(y) 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : %ToString(%ToPrimitive(y, NO_HINT)); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return %_StringAdd(this, y); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Right operand (y) is already a string. 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction STRING_ADD_RIGHT(y) { 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var x = this; 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_STRING(x)) { 194756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) { 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = %_ValueOf(x); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = IS_NUMBER(x) 198402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu ? %_NumberToString(x) 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : %ToString(%ToPrimitive(x, NO_HINT)); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 202d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return %_StringAdd(x, y); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.6.2, page 50. 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SUB(y) { 208086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 209086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberSub(x, y); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.5.1, page 48. 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MUL(y) { 216086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 217086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberMul(x, y); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.5.2, page 49. 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DIV(y) { 224086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 225086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberDiv(x, y); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.5.3, page 49. 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MOD(y) { 232086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 233086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberMod(x, y); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------------- 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block - - - B i t o p e r a t i o n s - - - 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ------------------------------------------- 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.10, page 57. 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_OR(y) { 246086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 247086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberOr(x, y); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.10, page 57. 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_AND(y) { 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var x; 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(this)) { 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = this; 257086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 259086aeeaae12517475c22695a200be45495516549Ben Murdoch x = %NonNumberToNumber(this); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure to convert the right operand to a number before 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bailing out in the fast case, but after converting the 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // left operand. This ensures that valueOf methods on the right 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // operand are always executed. 264086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optimize for the case where we end up AND'ing a value 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that doesn't convert to a number. This is common in 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // certain benchmarks. 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (NUMBER_IS_NAN(x)) return 0; 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberAnd(x, y); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.10, page 57. 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_XOR(y) { 276086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 277086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberXor(x, y); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.4.7, page 47. 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction UNARY_MINUS() { 284086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberUnaryMinus(x); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.4.8, page 48. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_NOT() { 291086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberNot(x); 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.7.1, page 51. 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SHL(y) { 298086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 299086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberShl(x, y); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.7.2, page 51. 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SAR(y) { 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var x; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(this)) { 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = this; 309086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 311086aeeaae12517475c22695a200be45495516549Ben Murdoch x = %NonNumberToNumber(this); 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure to convert the right operand to a number before 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bailing out in the fast case, but after converting the 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // left operand. This ensures that valueOf methods on the right 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // operand are always executed. 316086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Optimize for the case where we end up shifting a value 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that doesn't convert to a number. This is common in 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // certain benchmarks. 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (NUMBER_IS_NAN(x)) return 0; 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberSar(x, y); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.7.3, page 52. 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SHR(y) { 328086aeeaae12517475c22695a200be45495516549Ben Murdoch var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); 329086aeeaae12517475c22695a200be45495516549Ben Murdoch if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberShr(x, y); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ----------------------------- 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block - - - H e l p e r s - - - 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ----------------------------- 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.4.1, page 46. 341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochfunction DELETE(key, strict) { 342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return %DeleteProperty(%ToObject(this), %ToString(key), strict); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.8.7, page 54. 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction IN(x) { 3483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!IS_SPEC_OBJECT(x)) { 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('invalid_in_operator_use', [this, x]); 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %_IsNonNegativeSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToString(this)); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.8.6, page 54. To make the implementation more 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// efficient, the return value should be zero if the 'this' is an 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instance of F, and non-zero if not. This makes it possible to avoid 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an expensive ToBoolean conversion in the generated code. 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction INSTANCE_OF(F) { 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var V = this; 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_FUNCTION(F)) { 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('instanceof_function_expected', [V]); 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If V is not an object, return false. 3663bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!IS_SPEC_OBJECT(V)) { 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1; 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype of F; if it is not an object, throw an error. 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var O = F.prototype; 3723bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!IS_SPEC_OBJECT(O)) { 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('instanceof_nonobject_proto', [O]); 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return whether or not O is in the prototype chain of V. 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %IsInPrototypeChain(O, V) ? 0 : 1; 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Get an array of property keys for the given object. Used in 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for-in statements. 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GET_KEYS() { 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %GetPropertyNames(this); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Filter a given key against an object by checking if the object 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// has a property with the given key; return the key as a string if 390756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// it has. Otherwise returns 0 (smi). Used in for-in statements. 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FILTER_KEY(key) { 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var string = %ToString(key); 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%HasProperty(this, string)) return string; 394756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return 0; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CALL_NON_FUNCTION() { 399402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var delegate = %GetFunctionDelegate(this); 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_FUNCTION(delegate)) { 401402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu throw %MakeTypeError('called_non_callable', [typeof this]); 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 403402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return delegate.apply(this, arguments); 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CALL_NON_FUNCTION_AS_CONSTRUCTOR() { 408402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu var delegate = %GetConstructorDelegate(this); 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_FUNCTION(delegate)) { 410402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu throw %MakeTypeError('called_non_callable', [typeof this]); 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 412402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return delegate.apply(this, arguments); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction APPLY_PREPARE(args) { 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block var length; 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // First check whether length is a positive Smi and args is an 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // array. This is the fast case. If this fails, we do the slow case 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that takes care of more eventualities. 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_ARRAY(args)) { 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block length = args.length; 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this)) { 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return length; 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block length = (args == null) ? 0 : %ToUint32(args.length); 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We can handle any number of apply arguments if the stack is 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // big enough, but sanity check the value to avoid overflow when 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // multiplying with pointer size. 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length > 0x800000) { 4343bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch throw %MakeRangeError('stack_overflow', []); 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!IS_FUNCTION(this)) { 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ]); 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the arguments list has the right type. 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (args != null && !IS_ARRAY(args) && !IS_ARGUMENTS(args)) { 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('apply_wrong_args', []); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return the length which is the number of arguments to copy to the 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // stack. It is guaranteed to be a small integer at this point. 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return length; 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction APPLY_OVERFLOW(length) { 4533bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch throw %MakeRangeError('stack_overflow', []); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert the receiver to an object - forward to ToObject. 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction TO_OBJECT() { 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %ToObject(this); 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert the receiver to a number - forward to ToNumber. 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction TO_NUMBER() { 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %ToNumber(this); 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert the receiver to a string - forward to ToString. 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction TO_STRING() { 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %ToString(this); 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ------------------------------------- 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block - - - C o n v e r s i o n s - - - 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ------------------------------------- 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.1, page 30. Use null/undefined for no hint, 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (1) for number hint, and (2) for string hint. 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToPrimitive(x, hint) { 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fast case check. 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(x)) return x; 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Normal behavior. 4863bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!IS_SPEC_OBJECT(x)) return x; 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT; 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x); 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ECMA-262, section 9.2, page 30 4933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescufunction ToBoolean(x) { 4943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (IS_BOOLEAN(x)) return x; 4953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (IS_STRING(x)) return x.length != 0; 4963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (x == null) return false; 4973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x)); 4983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return true; 4993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 5003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.3, page 31. 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToNumber(x) { 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(x)) return x; 50580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (IS_STRING(x)) { 50680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x) 50780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : %StringToNumber(x); 50880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_BOOLEAN(x)) return x ? 1 : 0; 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_UNDEFINED(x)) return $NaN; 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 514086aeeaae12517475c22695a200be45495516549Ben Murdochfunction NonNumberToNumber(x) { 515086aeeaae12517475c22695a200be45495516549Ben Murdoch if (IS_STRING(x)) { 516086aeeaae12517475c22695a200be45495516549Ben Murdoch return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x) 517086aeeaae12517475c22695a200be45495516549Ben Murdoch : %StringToNumber(x); 518086aeeaae12517475c22695a200be45495516549Ben Murdoch } 519086aeeaae12517475c22695a200be45495516549Ben Murdoch if (IS_BOOLEAN(x)) return x ? 1 : 0; 520086aeeaae12517475c22695a200be45495516549Ben Murdoch if (IS_UNDEFINED(x)) return $NaN; 521086aeeaae12517475c22695a200be45495516549Ben Murdoch return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); 522086aeeaae12517475c22695a200be45495516549Ben Murdoch} 523086aeeaae12517475c22695a200be45495516549Ben Murdoch 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.8, page 35. 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToString(x) { 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(x)) return x; 528402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (IS_NUMBER(x)) return %_NumberToString(x); 529402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; 530402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (IS_UNDEFINED(x)) return 'undefined'; 531402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); 532402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 533402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 534402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescufunction NonStringToString(x) { 5356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (IS_NUMBER(x)) return %_NumberToString(x); 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_UNDEFINED(x)) return 'undefined'; 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.9, page 36. 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToObject(x) { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_STRING(x)) return new $String(x); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_NUMBER(x)) return new $Number(x); 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IS_BOOLEAN(x)) return new $Boolean(x); 547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (IS_NULL_OR_UNDEFINED(x) && !IS_UNDETECTABLE(x)) { 548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke throw %MakeTypeError('null_to_object', []); 549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return x; 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.4, page 34. 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToInteger(x) { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_IsSmi(x)) return x; 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberToInteger(ToNumber(x)); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.6, page 34. 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToUint32(x) { 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_IsSmi(x) && x >= 0) return x; 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberToJSUint32(ToNumber(x)); 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.5, page 34 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToInt32(x) { 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%_IsSmi(x)) return x; 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return %NumberToJSInt32(ToNumber(x)); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ES5, section 9.12 5763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescufunction SameValue(x, y) { 5773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (typeof x != typeof y) return false; 5783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (IS_NUMBER(x)) { 5793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; 580f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // x is +0 and y is -0 or vice versa. 581086aeeaae12517475c22695a200be45495516549Ben Murdoch if (x === 0 && y === 0 && (1 / x) != (1 / y)) return false; 5823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 583086aeeaae12517475c22695a200be45495516549Ben Murdoch return x === y; 5843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 5853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* --------------------------------- 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block - - - U t i l i t i e s - - - 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block --------------------------------- 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/ 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns if the given x is a primitive value - not an object or a 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction IsPrimitive(x) { 5953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Even though the type of null is "object", null is still 5963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // considered a primitive value. IS_SPEC_OBJECT handles this correctly 5973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // (i.e., it will return false if x is null). 5983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch return !IS_SPEC_OBJECT(x); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 8.6.2.6, page 28. 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DefaultNumber(x) { 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var valueOf = x.valueOf; 605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IS_FUNCTION(valueOf)) { 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var v = %_CallFunction(x, valueOf); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%IsPrimitive(v)) return v; 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var toString = x.toString; 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IS_FUNCTION(toString)) { 612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var s = %_CallFunction(x, toString); 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%IsPrimitive(s)) return s; 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('cannot_convert_to_primitive', []); 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 8.6.2.6, page 28. 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DefaultString(x) { 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var toString = x.toString; 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IS_FUNCTION(toString)) { 624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var s = %_CallFunction(x, toString); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%IsPrimitive(s)) return s; 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var valueOf = x.valueOf; 629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (IS_FUNCTION(valueOf)) { 630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch var v = %_CallFunction(x, valueOf); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (%IsPrimitive(v)) return v; 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block throw %MakeTypeError('cannot_convert_to_primitive', []); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: Setting the prototype for Array must take place as early as 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// possible due to code generation for array literals. When 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// generating code for a array literal a boilerplate array is created 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// that is cloned when running the code. It is essiential that the 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// boilerplate gets the right prototype. 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetPrototype($Array, new $Array(0)); 644