Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: src/runtime.js

Issue 1306993003: Call JS functions via native context instead of js builtins object. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This files contains runtime support implemented in JavaScript. 5 // This files contains runtime support implemented in JavaScript.
6 6
7 // CAUTION: Some of the functions specified in this file are called 7 // CAUTION: Some of the functions specified in this file are called
8 // directly from compiled code. These are the functions with names in 8 // directly from compiled code. These are the functions with names in
9 // ALL CAPS. The compiled code passes the first argument in 'this'. 9 // ALL CAPS. The compiled code passes the first argument in 'this'.
10 10
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 var x = this; 48 var x = this;
49 49
50 while (true) { 50 while (true) {
51 if (IS_NUMBER(x)) { 51 if (IS_NUMBER(x)) {
52 while (true) { 52 while (true) {
53 if (IS_NUMBER(y)) return %NumberEquals(x, y); 53 if (IS_NUMBER(y)) return %NumberEquals(x, y);
54 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal 54 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
55 if (!IS_SPEC_OBJECT(y)) { 55 if (!IS_SPEC_OBJECT(y)) {
56 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal 56 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal
57 // String or boolean. 57 // String or boolean.
58 return %NumberEquals(x, %$toNumber(y)); 58 return %NumberEquals(x, %to_number_fun(y));
59 } 59 }
60 y = %$toPrimitive(y, NO_HINT); 60 y = %to_primitive(y, NO_HINT);
61 } 61 }
62 } else if (IS_STRING(x)) { 62 } else if (IS_STRING(x)) {
63 while (true) { 63 while (true) {
64 if (IS_STRING(y)) return %StringEquals(x, y); 64 if (IS_STRING(y)) return %StringEquals(x, y);
65 if (IS_NUMBER(y)) return %NumberEquals(%$toNumber(x), y); 65 if (IS_NUMBER(y)) return %NumberEquals(%to_number_fun(x), y);
66 if (IS_BOOLEAN(y)) return %NumberEquals(%$toNumber(x), %$toNumber(y)); 66 if (IS_BOOLEAN(y)) return %NumberEquals(%to_number_fun(x), %to_number_fu n(y));
67 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal 67 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
68 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal 68 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal
69 y = %$toPrimitive(y, NO_HINT); 69 y = %to_primitive(y, NO_HINT);
70 } 70 }
71 } else if (IS_SYMBOL(x)) { 71 } else if (IS_SYMBOL(x)) {
72 if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1; 72 if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1;
73 return 1; // not equal 73 return 1; // not equal
74 } else if (IS_BOOLEAN(x)) { 74 } else if (IS_BOOLEAN(x)) {
75 if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1; 75 if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1;
76 if (IS_NULL_OR_UNDEFINED(y)) return 1; 76 if (IS_NULL_OR_UNDEFINED(y)) return 1;
77 if (IS_NUMBER(y)) return %NumberEquals(%$toNumber(x), y); 77 if (IS_NUMBER(y)) return %NumberEquals(%to_number_fun(x), y);
78 if (IS_STRING(y)) return %NumberEquals(%$toNumber(x), %$toNumber(y)); 78 if (IS_STRING(y)) return %NumberEquals(%to_number_fun(x), %to_number_fun(y ));
79 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal 79 if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal
80 // y is object. 80 // y is object.
81 x = %$toNumber(x); 81 x = %to_number_fun(x);
82 y = %$toPrimitive(y, NO_HINT); 82 y = %to_primitive(y, NO_HINT);
83 } else if (IS_NULL_OR_UNDEFINED(x)) { 83 } else if (IS_NULL_OR_UNDEFINED(x)) {
84 return IS_NULL_OR_UNDEFINED(y) ? 0 : 1; 84 return IS_NULL_OR_UNDEFINED(y) ? 0 : 1;
85 } else if (IS_SIMD_VALUE(x)) { 85 } else if (IS_SIMD_VALUE(x)) {
86 if (!IS_SIMD_VALUE(y)) return 1; // not equal 86 if (!IS_SIMD_VALUE(y)) return 1; // not equal
87 return %SimdEquals(x, y); 87 return %SimdEquals(x, y);
88 } else { 88 } else {
89 // x is an object. 89 // x is an object.
90 if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1; 90 if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1;
91 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal 91 if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
92 if (IS_BOOLEAN(y)) { 92 if (IS_BOOLEAN(y)) {
93 y = %$toNumber(y); 93 y = %to_number_fun(y);
94 } else if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) { 94 } else if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) {
95 return 1; // not equal 95 return 1; // not equal
96 } 96 }
97 x = %$toPrimitive(x, NO_HINT); 97 x = %to_primitive(x, NO_HINT);
98 } 98 }
99 } 99 }
100 } 100 }
101 101
102 102
103 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as 103 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as
104 // the result when either (or both) the operands are NaN. 104 // the result when either (or both) the operands are NaN.
105 function COMPARE(x, ncr) { 105 function COMPARE(x, ncr) {
106 var left; 106 var left;
107 var right; 107 var right;
108 // Fast cases for string, numbers and undefined compares. 108 // Fast cases for string, numbers and undefined compares.
109 if (IS_STRING(this)) { 109 if (IS_STRING(this)) {
110 if (IS_STRING(x)) return %_StringCompare(this, x); 110 if (IS_STRING(x)) return %_StringCompare(this, x);
111 if (IS_UNDEFINED(x)) return ncr; 111 if (IS_UNDEFINED(x)) return ncr;
112 left = this; 112 left = this;
113 } else if (IS_NUMBER(this)) { 113 } else if (IS_NUMBER(this)) {
114 if (IS_NUMBER(x)) return %NumberCompare(this, x, ncr); 114 if (IS_NUMBER(x)) return %NumberCompare(this, x, ncr);
115 if (IS_UNDEFINED(x)) return ncr; 115 if (IS_UNDEFINED(x)) return ncr;
116 left = this; 116 left = this;
117 } else if (IS_UNDEFINED(this)) { 117 } else if (IS_UNDEFINED(this)) {
118 if (!IS_UNDEFINED(x)) { 118 if (!IS_UNDEFINED(x)) {
119 %$toPrimitive(x, NUMBER_HINT); 119 %to_primitive(x, NUMBER_HINT);
120 } 120 }
121 return ncr; 121 return ncr;
122 } else if (IS_UNDEFINED(x)) { 122 } else if (IS_UNDEFINED(x)) {
123 %$toPrimitive(this, NUMBER_HINT); 123 %to_primitive(this, NUMBER_HINT);
124 return ncr; 124 return ncr;
125 } else { 125 } else {
126 left = %$toPrimitive(this, NUMBER_HINT); 126 left = %to_primitive(this, NUMBER_HINT);
127 } 127 }
128 128
129 right = %$toPrimitive(x, NUMBER_HINT); 129 right = %to_primitive(x, NUMBER_HINT);
130 if (IS_STRING(left) && IS_STRING(right)) { 130 if (IS_STRING(left) && IS_STRING(right)) {
131 return %_StringCompare(left, right); 131 return %_StringCompare(left, right);
132 } else { 132 } else {
133 var left_number = %$toNumber(left); 133 var left_number = %to_number_fun(left);
134 var right_number = %$toNumber(right); 134 var right_number = %to_number_fun(right);
135 if (NUMBER_IS_NAN(left_number) || NUMBER_IS_NAN(right_number)) return ncr; 135 if (NUMBER_IS_NAN(left_number) || NUMBER_IS_NAN(right_number)) return ncr;
136 return %NumberCompare(left_number, right_number, ncr); 136 return %NumberCompare(left_number, right_number, ncr);
137 } 137 }
138 } 138 }
139 139
140 // Strong mode COMPARE throws if an implicit conversion would be performed 140 // Strong mode COMPARE throws if an implicit conversion would be performed
141 function COMPARE_STRONG(x, ncr) { 141 function COMPARE_STRONG(x, ncr) {
142 if (IS_STRING(this) && IS_STRING(x)) return %_StringCompare(this, x); 142 if (IS_STRING(this) && IS_STRING(x)) return %_StringCompare(this, x);
143 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberCompare(this, x, ncr); 143 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberCompare(this, x, ncr);
144 144
145 throw %MakeTypeError(kStrongImplicitConversion); 145 throw %make_type_error(kStrongImplicitConversion);
146 } 146 }
147 147
148 148
149 149
150 /* ----------------------------------- 150 /* -----------------------------------
151 - - - A r i t h m e t i c - - - 151 - - - A r i t h m e t i c - - -
152 ----------------------------------- 152 -----------------------------------
153 */ 153 */
154 154
155 // ECMA-262, section 11.6.1, page 50. 155 // ECMA-262, section 11.6.1, page 50.
156 function ADD(x) { 156 function ADD(x) {
157 // Fast case: Check for number operands and do the addition. 157 // Fast case: Check for number operands and do the addition.
158 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); 158 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
159 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); 159 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
160 160
161 // Default implementation. 161 // Default implementation.
162 var a = %$toPrimitive(this, NO_HINT); 162 var a = %to_primitive(this, NO_HINT);
163 var b = %$toPrimitive(x, NO_HINT); 163 var b = %to_primitive(x, NO_HINT);
164 164
165 if (IS_STRING(a)) { 165 if (IS_STRING(a)) {
166 return %_StringAdd(a, %$toString(b)); 166 return %_StringAdd(a, %to_string_fun(b));
167 } else if (IS_STRING(b)) { 167 } else if (IS_STRING(b)) {
168 return %_StringAdd(%$nonStringToString(a), b); 168 return %_StringAdd(%non_string_to_string(a), b);
169 } else { 169 } else {
170 return %NumberAdd(%$toNumber(a), %$toNumber(b)); 170 return %NumberAdd(%to_number_fun(a), %to_number_fun(b));
171 } 171 }
172 } 172 }
173 173
174 174
175 // Strong mode ADD throws if an implicit conversion would be performed 175 // Strong mode ADD throws if an implicit conversion would be performed
176 function ADD_STRONG(x) { 176 function ADD_STRONG(x) {
177 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); 177 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
178 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); 178 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x);
179 179
180 throw %MakeTypeError(kStrongImplicitConversion); 180 throw %make_type_error(kStrongImplicitConversion);
181 } 181 }
182 182
183 183
184 // Left operand (this) is already a string. 184 // Left operand (this) is already a string.
185 function STRING_ADD_LEFT(y) { 185 function STRING_ADD_LEFT(y) {
186 if (!IS_STRING(y)) { 186 if (!IS_STRING(y)) {
187 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { 187 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) {
188 y = %_ValueOf(y); 188 y = %_ValueOf(y);
189 } else { 189 } else {
190 y = IS_NUMBER(y) 190 y = IS_NUMBER(y)
191 ? %_NumberToString(y) 191 ? %_NumberToString(y)
192 : %$toString(%$toPrimitive(y, NO_HINT)); 192 : %to_string_fun(%to_primitive(y, NO_HINT));
193 } 193 }
194 } 194 }
195 return %_StringAdd(this, y); 195 return %_StringAdd(this, y);
196 } 196 }
197 197
198 198
199 // Right operand (y) is already a string. 199 // Right operand (y) is already a string.
200 function STRING_ADD_RIGHT(y) { 200 function STRING_ADD_RIGHT(y) {
201 var x = this; 201 var x = this;
202 if (!IS_STRING(x)) { 202 if (!IS_STRING(x)) {
203 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) { 203 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) {
204 x = %_ValueOf(x); 204 x = %_ValueOf(x);
205 } else { 205 } else {
206 x = IS_NUMBER(x) 206 x = IS_NUMBER(x)
207 ? %_NumberToString(x) 207 ? %_NumberToString(x)
208 : %$toString(%$toPrimitive(x, NO_HINT)); 208 : %to_string_fun(%to_primitive(x, NO_HINT));
209 } 209 }
210 } 210 }
211 return %_StringAdd(x, y); 211 return %_StringAdd(x, y);
212 } 212 }
213 213
214 214
215 // ECMA-262, section 11.6.2, page 50. 215 // ECMA-262, section 11.6.2, page 50.
216 function SUB(y) { 216 function SUB(y) {
217 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 217 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
218 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 218 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
219 return %NumberSub(x, y); 219 return %NumberSub(x, y);
220 } 220 }
221 221
222 222
223 // Strong mode SUB throws if an implicit conversion would be performed 223 // Strong mode SUB throws if an implicit conversion would be performed
224 function SUB_STRONG(y) { 224 function SUB_STRONG(y) {
225 if (IS_NUMBER(this) && IS_NUMBER(y)) { 225 if (IS_NUMBER(this) && IS_NUMBER(y)) {
226 return %NumberSub(this, y); 226 return %NumberSub(this, y);
227 } 227 }
228 throw %MakeTypeError(kStrongImplicitConversion); 228 throw %make_type_error(kStrongImplicitConversion);
229 } 229 }
230 230
231 231
232 // ECMA-262, section 11.5.1, page 48. 232 // ECMA-262, section 11.5.1, page 48.
233 function MUL(y) { 233 function MUL(y) {
234 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 234 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
235 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 235 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
236 return %NumberMul(x, y); 236 return %NumberMul(x, y);
237 } 237 }
238 238
239 239
240 // Strong mode MUL throws if an implicit conversion would be performed 240 // Strong mode MUL throws if an implicit conversion would be performed
241 function MUL_STRONG(y) { 241 function MUL_STRONG(y) {
242 if (IS_NUMBER(this) && IS_NUMBER(y)) { 242 if (IS_NUMBER(this) && IS_NUMBER(y)) {
243 return %NumberMul(this, y); 243 return %NumberMul(this, y);
244 } 244 }
245 throw %MakeTypeError(kStrongImplicitConversion); 245 throw %make_type_error(kStrongImplicitConversion);
246 } 246 }
247 247
248 248
249 // ECMA-262, section 11.5.2, page 49. 249 // ECMA-262, section 11.5.2, page 49.
250 function DIV(y) { 250 function DIV(y) {
251 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 251 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
252 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 252 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
253 return %NumberDiv(x, y); 253 return %NumberDiv(x, y);
254 } 254 }
255 255
256 256
257 // Strong mode DIV throws if an implicit conversion would be performed 257 // Strong mode DIV throws if an implicit conversion would be performed
258 function DIV_STRONG(y) { 258 function DIV_STRONG(y) {
259 if (IS_NUMBER(this) && IS_NUMBER(y)) { 259 if (IS_NUMBER(this) && IS_NUMBER(y)) {
260 return %NumberDiv(this, y); 260 return %NumberDiv(this, y);
261 } 261 }
262 throw %MakeTypeError(kStrongImplicitConversion); 262 throw %make_type_error(kStrongImplicitConversion);
263 } 263 }
264 264
265 265
266 // ECMA-262, section 11.5.3, page 49. 266 // ECMA-262, section 11.5.3, page 49.
267 function MOD(y) { 267 function MOD(y) {
268 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 268 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
269 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 269 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
270 return %NumberMod(x, y); 270 return %NumberMod(x, y);
271 } 271 }
272 272
273 273
274 // Strong mode MOD throws if an implicit conversion would be performed 274 // Strong mode MOD throws if an implicit conversion would be performed
275 function MOD_STRONG(y) { 275 function MOD_STRONG(y) {
276 if (IS_NUMBER(this) && IS_NUMBER(y)) { 276 if (IS_NUMBER(this) && IS_NUMBER(y)) {
277 return %NumberMod(this, y); 277 return %NumberMod(this, y);
278 } 278 }
279 throw %MakeTypeError(kStrongImplicitConversion); 279 throw %make_type_error(kStrongImplicitConversion);
280 } 280 }
281 281
282 282
283 /* ------------------------------------------- 283 /* -------------------------------------------
284 - - - B i t o p e r a t i o n s - - - 284 - - - B i t o p e r a t i o n s - - -
285 ------------------------------------------- 285 -------------------------------------------
286 */ 286 */
287 287
288 // ECMA-262, section 11.10, page 57. 288 // ECMA-262, section 11.10, page 57.
289 function BIT_OR(y) { 289 function BIT_OR(y) {
290 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 290 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
291 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 291 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
292 return %NumberOr(x, y); 292 return %NumberOr(x, y);
293 } 293 }
294 294
295 295
296 // Strong mode BIT_OR throws if an implicit conversion would be performed 296 // Strong mode BIT_OR throws if an implicit conversion would be performed
297 function BIT_OR_STRONG(y) { 297 function BIT_OR_STRONG(y) {
298 if (IS_NUMBER(this) && IS_NUMBER(y)) { 298 if (IS_NUMBER(this) && IS_NUMBER(y)) {
299 return %NumberOr(this, y); 299 return %NumberOr(this, y);
300 } 300 }
301 throw %MakeTypeError(kStrongImplicitConversion); 301 throw %make_type_error(kStrongImplicitConversion);
302 } 302 }
303 303
304 304
305 // ECMA-262, section 11.10, page 57. 305 // ECMA-262, section 11.10, page 57.
306 function BIT_AND(y) { 306 function BIT_AND(y) {
307 var x; 307 var x;
308 if (IS_NUMBER(this)) { 308 if (IS_NUMBER(this)) {
309 x = this; 309 x = this;
310 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 310 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
311 } else { 311 } else {
312 x = %$nonNumberToNumber(this); 312 x = %non_number_to_number(this);
313 // Make sure to convert the right operand to a number before 313 // Make sure to convert the right operand to a number before
314 // bailing out in the fast case, but after converting the 314 // bailing out in the fast case, but after converting the
315 // left operand. This ensures that valueOf methods on the right 315 // left operand. This ensures that valueOf methods on the right
316 // operand are always executed. 316 // operand are always executed.
317 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 317 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
318 // Optimize for the case where we end up AND'ing a value 318 // Optimize for the case where we end up AND'ing a value
319 // that doesn't convert to a number. This is common in 319 // that doesn't convert to a number. This is common in
320 // certain benchmarks. 320 // certain benchmarks.
321 if (NUMBER_IS_NAN(x)) return 0; 321 if (NUMBER_IS_NAN(x)) return 0;
322 } 322 }
323 return %NumberAnd(x, y); 323 return %NumberAnd(x, y);
324 } 324 }
325 325
326 326
327 // Strong mode BIT_AND throws if an implicit conversion would be performed 327 // Strong mode BIT_AND throws if an implicit conversion would be performed
328 function BIT_AND_STRONG(y) { 328 function BIT_AND_STRONG(y) {
329 if (IS_NUMBER(this) && IS_NUMBER(y)) { 329 if (IS_NUMBER(this) && IS_NUMBER(y)) {
330 return %NumberAnd(this, y); 330 return %NumberAnd(this, y);
331 } 331 }
332 throw %MakeTypeError(kStrongImplicitConversion); 332 throw %make_type_error(kStrongImplicitConversion);
333 } 333 }
334 334
335 335
336 // ECMA-262, section 11.10, page 57. 336 // ECMA-262, section 11.10, page 57.
337 function BIT_XOR(y) { 337 function BIT_XOR(y) {
338 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 338 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
339 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 339 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
340 return %NumberXor(x, y); 340 return %NumberXor(x, y);
341 } 341 }
342 342
343 343
344 // Strong mode BIT_XOR throws if an implicit conversion would be performed 344 // Strong mode BIT_XOR throws if an implicit conversion would be performed
345 function BIT_XOR_STRONG(y) { 345 function BIT_XOR_STRONG(y) {
346 if (IS_NUMBER(this) && IS_NUMBER(y)) { 346 if (IS_NUMBER(this) && IS_NUMBER(y)) {
347 return %NumberXor(this, y); 347 return %NumberXor(this, y);
348 } 348 }
349 throw %MakeTypeError(kStrongImplicitConversion); 349 throw %make_type_error(kStrongImplicitConversion);
350 } 350 }
351 351
352 352
353 // ECMA-262, section 11.7.1, page 51. 353 // ECMA-262, section 11.7.1, page 51.
354 function SHL(y) { 354 function SHL(y) {
355 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 355 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
356 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 356 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
357 return %NumberShl(x, y); 357 return %NumberShl(x, y);
358 } 358 }
359 359
360 360
361 // Strong mode SHL throws if an implicit conversion would be performed 361 // Strong mode SHL throws if an implicit conversion would be performed
362 function SHL_STRONG(y) { 362 function SHL_STRONG(y) {
363 if (IS_NUMBER(this) && IS_NUMBER(y)) { 363 if (IS_NUMBER(this) && IS_NUMBER(y)) {
364 return %NumberShl(this, y); 364 return %NumberShl(this, y);
365 } 365 }
366 throw %MakeTypeError(kStrongImplicitConversion); 366 throw %make_type_error(kStrongImplicitConversion);
367 } 367 }
368 368
369 369
370 // ECMA-262, section 11.7.2, page 51. 370 // ECMA-262, section 11.7.2, page 51.
371 function SAR(y) { 371 function SAR(y) {
372 var x; 372 var x;
373 if (IS_NUMBER(this)) { 373 if (IS_NUMBER(this)) {
374 x = this; 374 x = this;
375 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 375 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
376 } else { 376 } else {
377 x = %$nonNumberToNumber(this); 377 x = %non_number_to_number(this);
378 // Make sure to convert the right operand to a number before 378 // Make sure to convert the right operand to a number before
379 // bailing out in the fast case, but after converting the 379 // bailing out in the fast case, but after converting the
380 // left operand. This ensures that valueOf methods on the right 380 // left operand. This ensures that valueOf methods on the right
381 // operand are always executed. 381 // operand are always executed.
382 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 382 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
383 // Optimize for the case where we end up shifting a value 383 // Optimize for the case where we end up shifting a value
384 // that doesn't convert to a number. This is common in 384 // that doesn't convert to a number. This is common in
385 // certain benchmarks. 385 // certain benchmarks.
386 if (NUMBER_IS_NAN(x)) return 0; 386 if (NUMBER_IS_NAN(x)) return 0;
387 } 387 }
388 return %NumberSar(x, y); 388 return %NumberSar(x, y);
389 } 389 }
390 390
391 391
392 // Strong mode SAR throws if an implicit conversion would be performed 392 // Strong mode SAR throws if an implicit conversion would be performed
393 function SAR_STRONG(y) { 393 function SAR_STRONG(y) {
394 if (IS_NUMBER(this) && IS_NUMBER(y)) { 394 if (IS_NUMBER(this) && IS_NUMBER(y)) {
395 return %NumberSar(this, y); 395 return %NumberSar(this, y);
396 } 396 }
397 throw %MakeTypeError(kStrongImplicitConversion); 397 throw %make_type_error(kStrongImplicitConversion);
398 } 398 }
399 399
400 400
401 // ECMA-262, section 11.7.3, page 52. 401 // ECMA-262, section 11.7.3, page 52.
402 function SHR(y) { 402 function SHR(y) {
403 var x = IS_NUMBER(this) ? this : %$nonNumberToNumber(this); 403 var x = IS_NUMBER(this) ? this : %non_number_to_number(this);
404 if (!IS_NUMBER(y)) y = %$nonNumberToNumber(y); 404 if (!IS_NUMBER(y)) y = %non_number_to_number(y);
405 return %NumberShr(x, y); 405 return %NumberShr(x, y);
406 } 406 }
407 407
408 408
409 // Strong mode SHR throws if an implicit conversion would be performed 409 // Strong mode SHR throws if an implicit conversion would be performed
410 function SHR_STRONG(y) { 410 function SHR_STRONG(y) {
411 if (IS_NUMBER(this) && IS_NUMBER(y)) { 411 if (IS_NUMBER(this) && IS_NUMBER(y)) {
412 return %NumberShr(this, y); 412 return %NumberShr(this, y);
413 } 413 }
414 throw %MakeTypeError(kStrongImplicitConversion); 414 throw %make_type_error(kStrongImplicitConversion);
415 } 415 }
416 416
417 417
418 /* ----------------------------- 418 /* -----------------------------
419 - - - H e l p e r s - - - 419 - - - H e l p e r s - - -
420 ----------------------------- 420 -----------------------------
421 */ 421 */
422 422
423 // ECMA-262, section 11.8.7, page 54. 423 // ECMA-262, section 11.8.7, page 54.
424 function IN(x) { 424 function IN(x) {
425 if (!IS_SPEC_OBJECT(x)) { 425 if (!IS_SPEC_OBJECT(x)) {
426 throw %MakeTypeError(kInvalidInOperatorUse, this, x); 426 throw %make_type_error(kInvalidInOperatorUse, this, x);
427 } 427 }
428 if (%_IsNonNegativeSmi(this)) { 428 if (%_IsNonNegativeSmi(this)) {
429 if (IS_ARRAY(x) && %_HasFastPackedElements(x)) { 429 if (IS_ARRAY(x) && %_HasFastPackedElements(x)) {
430 return this < x.length; 430 return this < x.length;
431 } 431 }
432 return %HasElement(x, this); 432 return %HasElement(x, this);
433 } 433 }
434 return %HasProperty(x, %$toName(this)); 434 return %HasProperty(x, %to_name(this));
435 } 435 }
436 436
437 437
438 // ECMA-262, section 11.8.6, page 54. To make the implementation more 438 // ECMA-262, section 11.8.6, page 54. To make the implementation more
439 // efficient, the return value should be zero if the 'this' is an 439 // efficient, the return value should be zero if the 'this' is an
440 // instance of F, and non-zero if not. This makes it possible to avoid 440 // instance of F, and non-zero if not. This makes it possible to avoid
441 // an expensive ToBoolean conversion in the generated code. 441 // an expensive ToBoolean conversion in the generated code.
442 function INSTANCE_OF(F) { 442 function INSTANCE_OF(F) {
443 var V = this; 443 var V = this;
444 if (!IS_SPEC_FUNCTION(F)) { 444 if (!IS_SPEC_FUNCTION(F)) {
445 throw %MakeTypeError(kInstanceofFunctionExpected, F); 445 throw %make_type_error(kInstanceofFunctionExpected, F);
446 } 446 }
447 447
448 // If V is not an object, return false. 448 // If V is not an object, return false.
449 if (!IS_SPEC_OBJECT(V)) { 449 if (!IS_SPEC_OBJECT(V)) {
450 return 1; 450 return 1;
451 } 451 }
452 452
453 // Check if function is bound, if so, get [[BoundFunction]] from it 453 // Check if function is bound, if so, get [[BoundFunction]] from it
454 // and use that instead of F. 454 // and use that instead of F.
455 var bindings = %BoundFunctionGetBindings(F); 455 var bindings = %BoundFunctionGetBindings(F);
456 if (bindings) { 456 if (bindings) {
457 F = bindings[kBoundFunctionIndex]; // Always a non-bound function. 457 F = bindings[kBoundFunctionIndex]; // Always a non-bound function.
458 } 458 }
459 // Get the prototype of F; if it is not an object, throw an error. 459 // Get the prototype of F; if it is not an object, throw an error.
460 var O = F.prototype; 460 var O = F.prototype;
461 if (!IS_SPEC_OBJECT(O)) { 461 if (!IS_SPEC_OBJECT(O)) {
462 throw %MakeTypeError(kInstanceofNonobjectProto, O); 462 throw %make_type_error(kInstanceofNonobjectProto, O);
463 } 463 }
464 464
465 // Return whether or not O is in the prototype chain of V. 465 // Return whether or not O is in the prototype chain of V.
466 return %IsInPrototypeChain(O, V) ? 0 : 1; 466 return %IsInPrototypeChain(O, V) ? 0 : 1;
467 } 467 }
468 468
469 469
470 function CALL_NON_FUNCTION() { 470 function CALL_NON_FUNCTION() {
471 var delegate = %GetFunctionDelegate(this); 471 var delegate = %GetFunctionDelegate(this);
472 if (!IS_FUNCTION(delegate)) { 472 if (!IS_FUNCTION(delegate)) {
473 var callsite = %RenderCallSite(); 473 var callsite = %RenderCallSite();
474 if (callsite == "") callsite = typeof this; 474 if (callsite == "") callsite = typeof this;
475 throw %MakeTypeError(kCalledNonCallable, callsite); 475 throw %make_type_error(kCalledNonCallable, callsite);
476 } 476 }
477 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); 477 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
478 } 478 }
479 479
480 480
481 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { 481 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
482 var delegate = %GetConstructorDelegate(this); 482 var delegate = %GetConstructorDelegate(this);
483 if (!IS_FUNCTION(delegate)) { 483 if (!IS_FUNCTION(delegate)) {
484 var callsite = %RenderCallSite(); 484 var callsite = %RenderCallSite();
485 if (callsite == "") callsite = typeof this; 485 if (callsite == "") callsite = typeof this;
486 throw %MakeTypeError(kCalledNonCallable, callsite); 486 throw %make_type_error(kCalledNonCallable, callsite);
487 } 487 }
488 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); 488 return %Apply(delegate, this, arguments, 0, %_ArgumentsLength());
489 } 489 }
490 490
491 491
492 function CALL_FUNCTION_PROXY() { 492 function CALL_FUNCTION_PROXY() {
493 var arity = %_ArgumentsLength() - 1; 493 var arity = %_ArgumentsLength() - 1;
494 var proxy = %_Arguments(arity); // The proxy comes in as an additional arg. 494 var proxy = %_Arguments(arity); // The proxy comes in as an additional arg.
495 var trap = %GetCallTrap(proxy); 495 var trap = %GetCallTrap(proxy);
496 return %Apply(trap, this, arguments, 0, arity); 496 return %Apply(trap, this, arguments, 0, arity);
(...skipping 18 matching lines...) Expand all
515 IS_SPEC_FUNCTION(this)) { 515 IS_SPEC_FUNCTION(this)) {
516 return length; 516 return length;
517 } 517 }
518 } 518 }
519 519
520 length = (args == null) ? 0 : TO_UINT32(args.length); 520 length = (args == null) ? 0 : TO_UINT32(args.length);
521 521
522 // We can handle any number of apply arguments if the stack is 522 // We can handle any number of apply arguments if the stack is
523 // big enough, but sanity check the value to avoid overflow when 523 // big enough, but sanity check the value to avoid overflow when
524 // multiplying with pointer size. 524 // multiplying with pointer size.
525 if (length > kSafeArgumentsLength) throw %MakeRangeError(kStackOverflow); 525 if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
526 526
527 if (!IS_SPEC_FUNCTION(this)) { 527 if (!IS_SPEC_FUNCTION(this)) {
528 throw %MakeTypeError(kApplyNonFunction, %$toString(this), typeof this); 528 throw %make_type_error(kApplyNonFunction, %to_string_fun(this), typeof this) ;
529 } 529 }
530 530
531 // Make sure the arguments list has the right type. 531 // Make sure the arguments list has the right type.
532 if (args != null && !IS_SPEC_OBJECT(args)) { 532 if (args != null && !IS_SPEC_OBJECT(args)) {
533 throw %MakeTypeError(kWrongArgs, "Function.prototype.apply"); 533 throw %make_type_error(kWrongArgs, "Function.prototype.apply");
534 } 534 }
535 535
536 // Return the length which is the number of arguments to copy to the 536 // Return the length which is the number of arguments to copy to the
537 // stack. It is guaranteed to be a small integer at this point. 537 // stack. It is guaranteed to be a small integer at this point.
538 return length; 538 return length;
539 } 539 }
540 540
541 541
542 function REFLECT_APPLY_PREPARE(args) { 542 function REFLECT_APPLY_PREPARE(args) {
543 var length; 543 var length;
544 // First check whether length is a positive Smi and args is an 544 // First check whether length is a positive Smi and args is an
545 // array. This is the fast case. If this fails, we do the slow case 545 // array. This is the fast case. If this fails, we do the slow case
546 // that takes care of more eventualities. 546 // that takes care of more eventualities.
547 if (IS_ARRAY(args)) { 547 if (IS_ARRAY(args)) {
548 length = args.length; 548 length = args.length;
549 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength && 549 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength &&
550 IS_SPEC_FUNCTION(this)) { 550 IS_SPEC_FUNCTION(this)) {
551 return length; 551 return length;
552 } 552 }
553 } 553 }
554 554
555 if (!IS_SPEC_FUNCTION(this)) { 555 if (!IS_SPEC_FUNCTION(this)) {
556 throw %MakeTypeError(kCalledNonCallable, %$toString(this)); 556 throw %make_type_error(kCalledNonCallable, %to_string_fun(this));
557 } 557 }
558 558
559 if (!IS_SPEC_OBJECT(args)) { 559 if (!IS_SPEC_OBJECT(args)) {
560 throw %MakeTypeError(kWrongArgs, "Reflect.apply"); 560 throw %make_type_error(kWrongArgs, "Reflect.apply");
561 } 561 }
562 562
563 length = %$toLength(args.length); 563 length = %to_length_fun(args.length);
564 564
565 // We can handle any number of apply arguments if the stack is 565 // We can handle any number of apply arguments if the stack is
566 // big enough, but sanity check the value to avoid overflow when 566 // big enough, but sanity check the value to avoid overflow when
567 // multiplying with pointer size. 567 // multiplying with pointer size.
568 if (length > kSafeArgumentsLength) throw %MakeRangeError(kStackOverflow); 568 if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
569 569
570 // Return the length which is the number of arguments to copy to the 570 // Return the length which is the number of arguments to copy to the
571 // stack. It is guaranteed to be a small integer at this point. 571 // stack. It is guaranteed to be a small integer at this point.
572 return length; 572 return length;
573 } 573 }
574 574
575 575
576 function REFLECT_CONSTRUCT_PREPARE( 576 function REFLECT_CONSTRUCT_PREPARE(
577 args, newTarget) { 577 args, newTarget) {
578 var length; 578 var length;
579 var ctorOk = IS_SPEC_FUNCTION(this) && %IsConstructor(this); 579 var ctorOk = IS_SPEC_FUNCTION(this) && %IsConstructor(this);
580 var newTargetOk = IS_SPEC_FUNCTION(newTarget) && %IsConstructor(newTarget); 580 var newTargetOk = IS_SPEC_FUNCTION(newTarget) && %IsConstructor(newTarget);
581 581
582 // First check whether length is a positive Smi and args is an 582 // First check whether length is a positive Smi and args is an
583 // array. This is the fast case. If this fails, we do the slow case 583 // array. This is the fast case. If this fails, we do the slow case
584 // that takes care of more eventualities. 584 // that takes care of more eventualities.
585 if (IS_ARRAY(args)) { 585 if (IS_ARRAY(args)) {
586 length = args.length; 586 length = args.length;
587 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength && 587 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength &&
588 ctorOk && newTargetOk) { 588 ctorOk && newTargetOk) {
589 return length; 589 return length;
590 } 590 }
591 } 591 }
592 592
593 if (!ctorOk) { 593 if (!ctorOk) {
594 if (!IS_SPEC_FUNCTION(this)) { 594 if (!IS_SPEC_FUNCTION(this)) {
595 throw %MakeTypeError(kCalledNonCallable, %$toString(this)); 595 throw %make_type_error(kCalledNonCallable, %to_string_fun(this));
596 } else { 596 } else {
597 throw %MakeTypeError(kNotConstructor, %$toString(this)); 597 throw %make_type_error(kNotConstructor, %to_string_fun(this));
598 } 598 }
599 } 599 }
600 600
601 if (!newTargetOk) { 601 if (!newTargetOk) {
602 if (!IS_SPEC_FUNCTION(newTarget)) { 602 if (!IS_SPEC_FUNCTION(newTarget)) {
603 throw %MakeTypeError(kCalledNonCallable, %$toString(newTarget)); 603 throw %make_type_error(kCalledNonCallable, %to_string_fun(newTarget));
604 } else { 604 } else {
605 throw %MakeTypeError(kNotConstructor, %$toString(newTarget)); 605 throw %make_type_error(kNotConstructor, %to_string_fun(newTarget));
606 } 606 }
607 } 607 }
608 608
609 if (!IS_SPEC_OBJECT(args)) { 609 if (!IS_SPEC_OBJECT(args)) {
610 throw %MakeTypeError(kWrongArgs, "Reflect.construct"); 610 throw %make_type_error(kWrongArgs, "Reflect.construct");
611 } 611 }
612 612
613 length = %$toLength(args.length); 613 length = %to_length_fun(args.length);
614 614
615 // We can handle any number of apply arguments if the stack is 615 // We can handle any number of apply arguments if the stack is
616 // big enough, but sanity check the value to avoid overflow when 616 // big enough, but sanity check the value to avoid overflow when
617 // multiplying with pointer size. 617 // multiplying with pointer size.
618 if (length > kSafeArgumentsLength) throw %MakeRangeError(kStackOverflow); 618 if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
619 619
620 // Return the length which is the number of arguments to copy to the 620 // Return the length which is the number of arguments to copy to the
621 // stack. It is guaranteed to be a small integer at this point. 621 // stack. It is guaranteed to be a small integer at this point.
622 return length; 622 return length;
623 } 623 }
624 624
625 625
626 function CONCAT_ITERABLE_TO_ARRAY(iterable) { 626 function CONCAT_ITERABLE_TO_ARRAY(iterable) {
627 return %$concatIterableToArray(this, iterable); 627 return %concat_iterable_to_array(this, iterable);
628 }; 628 };
629 629
630 630
631 function STACK_OVERFLOW(length) { 631 function STACK_OVERFLOW(length) {
632 throw %MakeRangeError(kStackOverflow); 632 throw %make_range_error(kStackOverflow);
633 } 633 }
634 634
635 635
636 // Convert the receiver to a number - forward to ToNumber. 636 // Convert the receiver to a number - forward to ToNumber.
637 function TO_NUMBER() { 637 function TO_NUMBER() {
638 return %$toNumber(this); 638 return %to_number_fun(this);
639 } 639 }
640 640
641 641
642 // Convert the receiver to a string - forward to ToString. 642 // Convert the receiver to a string - forward to ToString.
643 function TO_STRING() { 643 function TO_STRING() {
644 return %$toString(this); 644 return %to_string_fun(this);
645 } 645 }
646 646
647 647
648 // Convert the receiver to a string or symbol - forward to ToName. 648 // Convert the receiver to a string or symbol - forward to ToName.
649 function TO_NAME() { 649 function TO_NAME() {
650 return %$toName(this); 650 return %to_name(this);
651 } 651 }
652 652
653 653
654 /* ------------------------------------- 654 /* -------------------------------------
655 - - - C o n v e r s i o n s - - - 655 - - - C o n v e r s i o n s - - -
656 ------------------------------------- 656 -------------------------------------
657 */ 657 */
658 658
659 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint, 659 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint,
660 // (1) for number hint, and (2) for string hint. 660 // (1) for number hint, and (2) for string hint.
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 // NOTE: Setting the prototype for Array must take place as early as 847 // NOTE: Setting the prototype for Array must take place as early as
848 // possible due to code generation for array literals. When 848 // possible due to code generation for array literals. When
849 // generating code for a array literal a boilerplate array is created 849 // generating code for a array literal a boilerplate array is created
850 // that is cloned when running the code. It is essential that the 850 // that is cloned when running the code. It is essential that the
851 // boilerplate gets the right prototype. 851 // boilerplate gets the right prototype.
852 %FunctionSetPrototype(GlobalArray, new GlobalArray(0)); 852 %FunctionSetPrototype(GlobalArray, new GlobalArray(0));
853 853
854 // ---------------------------------------------------------------------------- 854 // ----------------------------------------------------------------------------
855 // Exports 855 // Exports
856 856
857 $concatIterableToArray = ConcatIterableToArray;
858 $defaultNumber = DefaultNumber; 857 $defaultNumber = DefaultNumber;
859 $defaultString = DefaultString; 858 $defaultString = DefaultString;
860 $NaN = %GetRootNaN(); 859 $NaN = %GetRootNaN();
861 $nonNumberToNumber = NonNumberToNumber; 860 $nonNumberToNumber = NonNumberToNumber;
862 $nonStringToString = NonStringToString; 861 $nonStringToString = NonStringToString;
863 $sameValue = SameValue; 862 $sameValue = SameValue;
864 $sameValueZero = SameValueZero; 863 $sameValueZero = SameValueZero;
865 $toInteger = ToInteger; 864 $toInteger = ToInteger;
866 $toLength = ToLength; 865 $toLength = ToLength;
867 $toName = ToName; 866 $toName = ToName;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 CONCAT_ITERABLE_TO_ARRAY, 906 CONCAT_ITERABLE_TO_ARRAY,
908 APPLY_PREPARE, 907 APPLY_PREPARE,
909 REFLECT_APPLY_PREPARE, 908 REFLECT_APPLY_PREPARE,
910 REFLECT_CONSTRUCT_PREPARE, 909 REFLECT_CONSTRUCT_PREPARE,
911 STACK_OVERFLOW, 910 STACK_OVERFLOW,
912 TO_NUMBER, 911 TO_NUMBER,
913 TO_STRING, 912 TO_STRING,
914 TO_NAME, 913 TO_NAME,
915 }); 914 });
916 915
917 utils.ExportToRuntime(function(to) { 916 %ExportToRuntime([
918 to["to_integer_fun"] = ToInteger; 917 "concat_iterable_to_array", ConcatIterableToArray,
919 to["to_length_fun"] = ToLength; 918 "non_number_to_number", NonNumberToNumber,
920 to["to_number_fun"] = ToNumber; 919 "non_string_to_string", NonStringToString,
921 to["to_string_fun"] = ToString; 920 "to_integer_fun", ToInteger,
922 }); 921 "to_length_fun", ToLength,
922 "to_name", ToName,
923 "to_number_fun", ToNumber,
924 "to_primitive", ToPrimitive,
925 "to_string_fun", ToString,
926 ]);
923 927
924 utils.Export(function(to) { 928 utils.Export(function(to) {
925 to.ToBoolean = ToBoolean; 929 to.ToBoolean = ToBoolean;
930 to.ToLength = ToLength;
931 to.ToName = ToName;
926 to.ToNumber = ToNumber; 932 to.ToNumber = ToNumber;
933 to.ToPrimitive = ToPrimitive;
927 to.ToString = ToString; 934 to.ToString = ToString;
928 }) 935 });
929 936
930 }) 937 })
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698