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
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The following declarations are shared with other native JS files.
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// They are all declared at this one spot to avoid redeclaration errors.
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $Object = global.Object;
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $Array = global.Array;
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $String = global.String;
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $Number = global.Number;
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $Function = global.Function;
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $Boolean = global.Boolean;
50db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdochvar $NaN = %GetRootNaN();
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar builtins = this;
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// ECMA-262 Section 11.9.3.
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  while (true) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (IS_NUMBER(x)) {
60257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      while (true) {
61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (IS_NUMBER(y)) return %NumberEquals(x, y);
62257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
63257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (!IS_SPEC_OBJECT(y)) {
64257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          // String or boolean.
65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          return %NumberEquals(x, %ToNumber(y));
66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        y = %ToPrimitive(y, NO_HINT);
68257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (IS_STRING(x)) {
70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      while (true) {
71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (IS_STRING(y)) return %StringEquals(x, y);
72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
74257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
75257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        y = %ToPrimitive(y, NO_HINT);
76257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
77257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else if (IS_BOOLEAN(x)) {
78257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1;
79257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (IS_NULL_OR_UNDEFINED(y)) return 1;
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
81257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (IS_STRING(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
82257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // y is object.
83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      x = %ToNumber(x);
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      y = %ToPrimitive(y, NO_HINT);
85257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else if (IS_NULL_OR_UNDEFINED(x)) {
86257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return IS_NULL_OR_UNDEFINED(y) ? 0 : 1;
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // x is an object.
893bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      if (IS_SPEC_OBJECT(y)) {
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return %_ObjectEquals(x, y) ? 0 : 1;
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (IS_NULL_OR_UNDEFINED(y)) return 1;  // not equal
93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (IS_BOOLEAN(y)) y = %ToNumber(y);
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      x = %ToPrimitive(x, NO_HINT);
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.9.4, page 56.
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction STRICT_EQUALS(x) {
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_STRING(this)) {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!IS_STRING(x)) return 1;  // not equal
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return %StringEquals(this, x);
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_NUMBER(this)) {
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!IS_NUMBER(x)) return 1;  // not equal
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return %NumberEquals(this, x);
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If anything else gets here, we just do simple identity check.
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Objects (including functions), null, undefined and booleans were
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // checked in the CompareStub, so there should be nothing left.
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %_ObjectEquals(this, x) ? 0 : 1;
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the result when either (or both) the operands are NaN.
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction COMPARE(x, ncr) {
121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  var left;
1228defd9ff6930b4e24729971a61cf7469daf119beSteve Block  var right;
123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Fast cases for string, numbers and undefined compares.
124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IS_STRING(this)) {
125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    if (IS_STRING(x)) return %_StringCompare(this, x);
126e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    if (IS_UNDEFINED(x)) return ncr;
127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    left = this;
128e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else if (IS_NUMBER(this)) {
129e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    if (IS_NUMBER(x)) return %NumberCompare(this, x, ncr);
130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    if (IS_UNDEFINED(x)) return ncr;
131e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    left = this;
132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else if (IS_UNDEFINED(this)) {
1338defd9ff6930b4e24729971a61cf7469daf119beSteve Block    if (!IS_UNDEFINED(x)) {
1348defd9ff6930b4e24729971a61cf7469daf119beSteve Block      %ToPrimitive(x, NUMBER_HINT);
1358defd9ff6930b4e24729971a61cf7469daf119beSteve Block    }
1368defd9ff6930b4e24729971a61cf7469daf119beSteve Block    return ncr;
1378defd9ff6930b4e24729971a61cf7469daf119beSteve Block  } else if (IS_UNDEFINED(x)) {
1388defd9ff6930b4e24729971a61cf7469daf119beSteve Block    %ToPrimitive(this, NUMBER_HINT);
139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return ncr;
140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    left = %ToPrimitive(this, NUMBER_HINT);
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1448defd9ff6930b4e24729971a61cf7469daf119beSteve Block  right = %ToPrimitive(x, NUMBER_HINT);
145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IS_STRING(left) && IS_STRING(right)) {
146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return %_StringCompare(left, right);
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    var left_number = %ToNumber(left);
149e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    var right_number = %ToNumber(right);
150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    if (NUMBER_IS_NAN(left_number) || NUMBER_IS_NAN(right_number)) return ncr;
151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return %NumberCompare(left_number, right_number, ncr);
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* -----------------------------------
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   - - -   A r i t h m e t i c   - - -
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   -----------------------------------
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.6.1, page 50.
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ADD(x) {
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fast case: Check for number operands and do the addition.
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Default implementation.
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var a = %ToPrimitive(this, NO_HINT);
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var b = %ToPrimitive(x, NO_HINT);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_STRING(a)) {
173d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return %_StringAdd(a, %ToString(b));
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (IS_STRING(b)) {
175086aeeaae12517475c22695a200be45495516549Ben Murdoch    return %_StringAdd(%NonStringToString(a), b);
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return %NumberAdd(%ToNumber(a), %ToNumber(b));
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Left operand (this) is already a string.
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction STRING_ADD_LEFT(y) {
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_STRING(y)) {
185756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) {
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      y = %_ValueOf(y);
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      y = IS_NUMBER(y)
189402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu          ? %_NumberToString(y)
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          : %ToString(%ToPrimitive(y, NO_HINT));
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return %_StringAdd(this, y);
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Right operand (y) is already a string.
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction STRING_ADD_RIGHT(y) {
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var x = this;
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_STRING(x)) {
201756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) {
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      x = %_ValueOf(x);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      x = IS_NUMBER(x)
205402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu          ? %_NumberToString(x)
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          : %ToString(%ToPrimitive(x, NO_HINT));
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return %_StringAdd(x, y);
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.6.2, page 50.
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SUB(y) {
215086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
216086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberSub(x, y);
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.5.1, page 48.
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MUL(y) {
223086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
224086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberMul(x, y);
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.5.2, page 49.
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DIV(y) {
231086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
232086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberDiv(x, y);
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.5.3, page 49.
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MOD(y) {
239086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
240086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberMod(x, y);
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* -------------------------------------------
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   - - -   B i t   o p e r a t i o n s   - - -
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   -------------------------------------------
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.10, page 57.
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_OR(y) {
253086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
254086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberOr(x, y);
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.10, page 57.
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_AND(y) {
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var x;
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_NUMBER(this)) {
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    x = this;
264086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
266086aeeaae12517475c22695a200be45495516549Ben Murdoch    x = %NonNumberToNumber(this);
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Make sure to convert the right operand to a number before
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // bailing out in the fast case, but after converting the
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // left operand. This ensures that valueOf methods on the right
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // operand are always executed.
271086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Optimize for the case where we end up AND'ing a value
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // that doesn't convert to a number. This is common in
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // certain benchmarks.
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (NUMBER_IS_NAN(x)) return 0;
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberAnd(x, y);
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.10, page 57.
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_XOR(y) {
283086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
284086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberXor(x, y);
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.4.7, page 47.
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction UNARY_MINUS() {
291086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberUnaryMinus(x);
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.4.8, page 48.
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BIT_NOT() {
298086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberNot(x);
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.7.1, page 51.
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SHL(y) {
305086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
306086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberShl(x, y);
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.7.2, page 51.
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SAR(y) {
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var x;
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_NUMBER(this)) {
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    x = this;
316086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
318086aeeaae12517475c22695a200be45495516549Ben Murdoch    x = %NonNumberToNumber(this);
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Make sure to convert the right operand to a number before
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // bailing out in the fast case, but after converting the
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // left operand. This ensures that valueOf methods on the right
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // operand are always executed.
323086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Optimize for the case where we end up shifting a value
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // that doesn't convert to a number. This is common in
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // certain benchmarks.
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (NUMBER_IS_NAN(x)) return 0;
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberSar(x, y);
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.7.3, page 52.
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SHR(y) {
335086aeeaae12517475c22695a200be45495516549Ben Murdoch  var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this);
336086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(y)) y = %NonNumberToNumber(y);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberShr(x, y);
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* -----------------------------
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   - - -   H e l p e r s   - - -
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   -----------------------------
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.4.1, page 46.
348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochfunction DELETE(key, strict) {
349e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return %DeleteProperty(%ToObject(this), %ToString(key), strict);
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.8.7, page 54.
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction IN(x) {
3553bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(x)) {
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw %MakeTypeError('invalid_in_operator_use', [this, x]);
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return %_IsNonNegativeSmi(this) ?
3593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %HasElement(x, this) : %HasProperty(x, %ToString(this));
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 11.8.6, page 54. To make the implementation more
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// efficient, the return value should be zero if the 'this' is an
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instance of F, and non-zero if not. This makes it possible to avoid
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an expensive ToBoolean conversion in the generated code.
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction INSTANCE_OF(F) {
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var V = this;
369589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!IS_SPEC_FUNCTION(F)) {
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw %MakeTypeError('instanceof_function_expected', [V]);
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If V is not an object, return false.
3743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(V)) {
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return 1;
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if function is bound, if so, get [[BoundFunction]] from it
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // and use that instead of F.
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var bindings = %BoundFunctionGetBindings(F);
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (bindings) {
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    F = bindings[kBoundFunctionIndex];  // Always a non-bound function.
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the prototype of F; if it is not an object, throw an error.
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var O = F.prototype;
3863bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(O)) {
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw %MakeTypeError('instanceof_nonobject_proto', [O]);
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return whether or not O is in the prototype chain of V.
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %IsInPrototypeChain(O, V) ? 0 : 1;
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Filter a given key against an object by checking if the object
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// has a property with the given key; return the key as a string if
397756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// it has. Otherwise returns 0 (smi). Used in for-in statements.
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FILTER_KEY(key) {
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var string = %ToString(key);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%HasProperty(this, string)) return string;
401756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return 0;
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CALL_NON_FUNCTION() {
406402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  var delegate = %GetFunctionDelegate(this);
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_FUNCTION(delegate)) {
408402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    throw %MakeTypeError('called_non_callable', [typeof this]);
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
410589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
415402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  var delegate = %GetConstructorDelegate(this);
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_FUNCTION(delegate)) {
417402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    throw %MakeTypeError('called_non_callable', [typeof this]);
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
419589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
420589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
421589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
422589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
423589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CALL_FUNCTION_PROXY() {
424589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  var arity = %_ArgumentsLength() - 1;
425589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  var proxy = %_Arguments(arity);  // The proxy comes in as an additional arg.
426589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  var trap = %GetCallTrap(proxy);
427589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return %Apply(trap, this, arguments, 0, arity);
428589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
429589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
430589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction CALL_FUNCTION_PROXY_AS_CONSTRUCTOR() {
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var proxy = this;
433589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  var trap = %GetConstructTrap(proxy);
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return %Apply(trap, this, arguments, 0, %_ArgumentsLength());
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction APPLY_PREPARE(args) {
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var length;
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // First check whether length is a positive Smi and args is an
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // array. This is the fast case. If this fails, we do the slow case
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that takes care of more eventualities.
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_ARRAY(args)) {
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    length = args.length;
445589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (%_IsSmi(length) && length >= 0 && length < 0x800000 &&
446589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        IS_SPEC_FUNCTION(this)) {
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return length;
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  length = (args == null) ? 0 : %ToUint32(args.length);
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We can handle any number of apply arguments if the stack is
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // big enough, but sanity check the value to avoid overflow when
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // multiplying with pointer size.
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (length > 0x800000) {
4573bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    throw %MakeRangeError('stack_overflow', []);
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
460589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!IS_SPEC_FUNCTION(this)) {
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw %MakeTypeError('apply_non_function',
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         [ %ToString(this), typeof this ]);
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure the arguments list has the right type.
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (args != null && !IS_SPEC_OBJECT(args)) {
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw %MakeTypeError('apply_wrong_args', []);
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the length which is the number of arguments to copy to the
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // stack. It is guaranteed to be a small integer at this point.
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return length;
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction APPLY_OVERFLOW(length) {
4773bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  throw %MakeRangeError('stack_overflow', []);
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert the receiver to an object - forward to ToObject.
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction TO_OBJECT() {
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %ToObject(this);
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert the receiver to a number - forward to ToNumber.
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction TO_NUMBER() {
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %ToNumber(this);
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert the receiver to a string - forward to ToString.
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction TO_STRING() {
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %ToString(this);
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* -------------------------------------
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   - - -   C o n v e r s i o n s   - - -
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   -------------------------------------
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.1, page 30. Use null/undefined for no hint,
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (1) for number hint, and (2) for string hint.
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToPrimitive(x, hint) {
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fast case check.
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_STRING(x)) return x;
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Normal behavior.
5103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(x)) return x;
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x);
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ECMA-262, section 9.2, page 30
5173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescufunction ToBoolean(x) {
5183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (IS_BOOLEAN(x)) return x;
5193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (IS_STRING(x)) return x.length != 0;
5203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (x == null) return false;
5213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x));
5223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return true;
5233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
5243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.3, page 31.
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToNumber(x) {
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_NUMBER(x)) return x;
52980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (IS_STRING(x)) {
53080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
53180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                    : %StringToNumber(x);
53280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_BOOLEAN(x)) return x ? 1 : 0;
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_UNDEFINED(x)) return $NaN;
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
538086aeeaae12517475c22695a200be45495516549Ben Murdochfunction NonNumberToNumber(x) {
539086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (IS_STRING(x)) {
540086aeeaae12517475c22695a200be45495516549Ben Murdoch    return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
541086aeeaae12517475c22695a200be45495516549Ben Murdoch                                    : %StringToNumber(x);
542086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
543086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (IS_BOOLEAN(x)) return x ? 1 : 0;
544086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (IS_UNDEFINED(x)) return $NaN;
545086aeeaae12517475c22695a200be45495516549Ben Murdoch  return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
546086aeeaae12517475c22695a200be45495516549Ben Murdoch}
547086aeeaae12517475c22695a200be45495516549Ben Murdoch
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.8, page 35.
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToString(x) {
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_STRING(x)) return x;
552402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (IS_NUMBER(x)) return %_NumberToString(x);
553402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
554402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (IS_UNDEFINED(x)) return 'undefined';
555402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x));
556402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
557402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
558402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescufunction NonStringToString(x) {
5596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (IS_NUMBER(x)) return %_NumberToString(x);
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_UNDEFINED(x)) return 'undefined';
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x));
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.9, page 36.
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToObject(x) {
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_STRING(x)) return new $String(x);
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_NUMBER(x)) return new $Number(x);
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_BOOLEAN(x)) return new $Boolean(x);
571d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (IS_NULL_OR_UNDEFINED(x) && !IS_UNDETECTABLE(x)) {
572d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    throw %MakeTypeError('null_to_object', []);
573d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return x;
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.4, page 34.
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToInteger(x) {
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%_IsSmi(x)) return x;
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToInteger(ToNumber(x));
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.6, page 34.
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToUint32(x) {
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%_IsSmi(x) && x >= 0) return x;
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToJSUint32(ToNumber(x));
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 9.5, page 34
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToInt32(x) {
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%_IsSmi(x)) return x;
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToJSInt32(ToNumber(x));
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ES5, section 9.12
6003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescufunction SameValue(x, y) {
6013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (typeof x != typeof y) return false;
6023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (IS_NUMBER(x)) {
6033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
604f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // x is +0 and y is -0 or vice versa.
605086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (x === 0 && y === 0 && (1 / x) != (1 / y)) return false;
6063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
607086aeeaae12517475c22695a200be45495516549Ben Murdoch  return x === y;
6083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
6093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* ---------------------------------
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   - - -   U t i l i t i e s   - - -
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   ---------------------------------
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block*/
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns if the given x is a primitive value - not an object or a
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function.
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction IsPrimitive(x) {
6193bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Even though the type of null is "object", null is still
6203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // considered a primitive value. IS_SPEC_OBJECT handles this correctly
6213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // (i.e., it will return false if x is null).
6223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  return !IS_SPEC_OBJECT(x);
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 8.6.2.6, page 28.
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DefaultNumber(x) {
628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  var valueOf = x.valueOf;
629589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IS_SPEC_FUNCTION(valueOf)) {
630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var v = %_CallFunction(x, valueOf);
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (%IsPrimitive(v)) return v;
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  var toString = x.toString;
635589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IS_SPEC_FUNCTION(toString)) {
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var s = %_CallFunction(x, toString);
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (%IsPrimitive(s)) return s;
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  throw %MakeTypeError('cannot_convert_to_primitive', []);
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262, section 8.6.2.6, page 28.
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DefaultString(x) {
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  var toString = x.toString;
647589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IS_SPEC_FUNCTION(toString)) {
648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var s = %_CallFunction(x, toString);
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (%IsPrimitive(s)) return s;
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  var valueOf = x.valueOf;
653589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IS_SPEC_FUNCTION(valueOf)) {
654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var v = %_CallFunction(x, valueOf);
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (%IsPrimitive(v)) return v;
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  throw %MakeTypeError('cannot_convert_to_primitive', []);
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NOTE: Setting the prototype for Array must take place as early as
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// possible due to code generation for array literals.  When
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// generating code for a array literal a boilerplate array is created
665257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// that is cloned when running the code.  It is essential that the
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// boilerplate gets the right prototype.
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetPrototype($Array, new $Array(0));
668