OLD | NEW |
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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 if (IS_STRING(a)) { | 153 if (IS_STRING(a)) { |
154 return %_StringAdd(a, %ToString(b)); | 154 return %_StringAdd(a, %ToString(b)); |
155 } else if (IS_STRING(b)) { | 155 } else if (IS_STRING(b)) { |
156 return %_StringAdd(%NonStringToString(a), b); | 156 return %_StringAdd(%NonStringToString(a), b); |
157 } else { | 157 } else { |
158 return %NumberAdd(%ToNumber(a), %ToNumber(b)); | 158 return %NumberAdd(%ToNumber(a), %ToNumber(b)); |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 | 162 |
| 163 // Strong mode ADD throws if an implicit conversion would be performed |
| 164 function ADD_STRONG(x) { |
| 165 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); |
| 166 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); |
| 167 |
| 168 throw %MakeTypeError('strong_implicit_cast'); |
| 169 } |
| 170 |
| 171 |
163 // Left operand (this) is already a string. | 172 // Left operand (this) is already a string. |
164 function STRING_ADD_LEFT(y) { | 173 function STRING_ADD_LEFT(y) { |
165 if (!IS_STRING(y)) { | 174 if (!IS_STRING(y)) { |
166 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { | 175 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { |
167 y = %_ValueOf(y); | 176 y = %_ValueOf(y); |
168 } else { | 177 } else { |
169 y = IS_NUMBER(y) | 178 y = IS_NUMBER(y) |
170 ? %_NumberToString(y) | 179 ? %_NumberToString(y) |
171 : %ToString(%ToPrimitive(y, NO_HINT)); | 180 : %ToString(%ToPrimitive(y, NO_HINT)); |
172 } | 181 } |
173 } | 182 } |
174 return %_StringAdd(this, y); | 183 return %_StringAdd(this, y); |
175 } | 184 } |
176 | 185 |
177 | 186 |
| 187 // Left operand (this) is already a string. |
| 188 function STRING_ADD_LEFT_STRONG(y) { |
| 189 if (IS_STRING(y)) { |
| 190 return %_StringAdd(this, y); |
| 191 } |
| 192 throw %MakeTypeError('strong_implicit_cast'); |
| 193 } |
| 194 |
| 195 |
178 // Right operand (y) is already a string. | 196 // Right operand (y) is already a string. |
179 function STRING_ADD_RIGHT(y) { | 197 function STRING_ADD_RIGHT(y) { |
180 var x = this; | 198 var x = this; |
181 if (!IS_STRING(x)) { | 199 if (!IS_STRING(x)) { |
182 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) { | 200 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) { |
183 x = %_ValueOf(x); | 201 x = %_ValueOf(x); |
184 } else { | 202 } else { |
185 x = IS_NUMBER(x) | 203 x = IS_NUMBER(x) |
186 ? %_NumberToString(x) | 204 ? %_NumberToString(x) |
187 : %ToString(%ToPrimitive(x, NO_HINT)); | 205 : %ToString(%ToPrimitive(x, NO_HINT)); |
188 } | 206 } |
189 } | 207 } |
190 return %_StringAdd(x, y); | 208 return %_StringAdd(x, y); |
191 } | 209 } |
192 | 210 |
193 | 211 |
| 212 // Right operand (y) is already a string. |
| 213 function STRING_ADD_RIGHT_STRONG(y) { |
| 214 if (IS_STRING(this)) { |
| 215 return %_StringAdd(this, y); |
| 216 } |
| 217 throw %MakeTypeError('strong_implicit_cast'); |
| 218 } |
| 219 |
| 220 |
194 // ECMA-262, section 11.6.2, page 50. | 221 // ECMA-262, section 11.6.2, page 50. |
195 function SUB(y) { | 222 function SUB(y) { |
196 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 223 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
197 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 224 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
198 return %NumberSub(x, y); | 225 return %NumberSub(x, y); |
199 } | 226 } |
200 | 227 |
201 | 228 |
202 // ECMA-262, section 11.6.2, page 50. | 229 // Strong mode SUB throws if an implicit conversion would be performed |
203 function SUB_STRONG(y) { | 230 function SUB_STRONG(y) { |
204 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 231 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
205 return %NumberSub(this, y); | 232 return %NumberSub(this, y); |
206 } | 233 } |
207 throw %MakeTypeError('strong_implicit_cast'); | 234 throw %MakeTypeError('strong_implicit_cast'); |
208 } | 235 } |
209 | 236 |
210 | 237 |
211 // ECMA-262, section 11.5.1, page 48. | 238 // ECMA-262, section 11.5.1, page 48. |
212 function MUL(y) { | 239 function MUL(y) { |
213 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 240 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
214 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 241 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
215 return %NumberMul(x, y); | 242 return %NumberMul(x, y); |
216 } | 243 } |
217 | 244 |
218 | 245 |
219 // ECMA-262, section 11.5.1, page 48. | 246 // Strong mode MUL throws if an implicit conversion would be performed |
220 function MUL_STRONG(y) { | 247 function MUL_STRONG(y) { |
221 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 248 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
222 return %NumberMul(this, y); | 249 return %NumberMul(this, y); |
223 } | 250 } |
224 throw %MakeTypeError('strong_implicit_cast'); | 251 throw %MakeTypeError('strong_implicit_cast'); |
225 } | 252 } |
226 | 253 |
227 | 254 |
228 // ECMA-262, section 11.5.2, page 49. | 255 // ECMA-262, section 11.5.2, page 49. |
229 function DIV(y) { | 256 function DIV(y) { |
230 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 257 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
231 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 258 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
232 return %NumberDiv(x, y); | 259 return %NumberDiv(x, y); |
233 } | 260 } |
234 | 261 |
235 | 262 |
236 // ECMA-262, section 11.5.2, page 49. | 263 // Strong mode DIV throws if an implicit conversion would be performed |
237 function DIV_STRONG(y) { | 264 function DIV_STRONG(y) { |
238 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 265 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
239 return %NumberDiv(this, y); | 266 return %NumberDiv(this, y); |
240 } | 267 } |
241 throw %MakeTypeError('strong_implicit_cast'); | 268 throw %MakeTypeError('strong_implicit_cast'); |
242 } | 269 } |
243 | 270 |
244 | 271 |
245 // ECMA-262, section 11.5.3, page 49. | 272 // ECMA-262, section 11.5.3, page 49. |
246 function MOD(y) { | 273 function MOD(y) { |
247 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 274 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
248 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 275 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
249 return %NumberMod(x, y); | 276 return %NumberMod(x, y); |
250 } | 277 } |
251 | 278 |
252 | 279 |
253 // ECMA-262, section 11.5.3, page 49. | 280 // Strong mode MOD throws if an implicit conversion would be performed |
254 function MOD_STRONG(y) { | 281 function MOD_STRONG(y) { |
255 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 282 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
256 return %NumberMod(this, y); | 283 return %NumberMod(this, y); |
257 } | 284 } |
258 throw %MakeTypeError('strong_implicit_cast'); | 285 throw %MakeTypeError('strong_implicit_cast'); |
259 } | 286 } |
260 | 287 |
261 | 288 |
262 /* ------------------------------------------- | 289 /* ------------------------------------------- |
263 - - - B i t o p e r a t i o n s - - - | 290 - - - B i t o p e r a t i o n s - - - |
264 ------------------------------------------- | 291 ------------------------------------------- |
265 */ | 292 */ |
266 | 293 |
267 // ECMA-262, section 11.10, page 57. | 294 // ECMA-262, section 11.10, page 57. |
268 function BIT_OR(y) { | 295 function BIT_OR(y) { |
269 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 296 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
270 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 297 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
271 return %NumberOr(x, y); | 298 return %NumberOr(x, y); |
272 } | 299 } |
273 | 300 |
274 | 301 |
275 //ECMA-262, section 11.10, page 57. | 302 // Strong mode BIT_OR throws if an implicit conversion would be performed |
276 function BIT_OR_STRONG(y) { | 303 function BIT_OR_STRONG(y) { |
277 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 304 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
278 return %NumberOr(this, y); | 305 return %NumberOr(this, y); |
279 } | 306 } |
280 throw %MakeTypeError('strong_implicit_cast'); | 307 throw %MakeTypeError('strong_implicit_cast'); |
281 } | 308 } |
282 | 309 |
283 | 310 |
284 // ECMA-262, section 11.10, page 57. | 311 // ECMA-262, section 11.10, page 57. |
285 function BIT_AND(y) { | 312 function BIT_AND(y) { |
(...skipping 10 matching lines...) Expand all Loading... |
296 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 323 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
297 // Optimize for the case where we end up AND'ing a value | 324 // Optimize for the case where we end up AND'ing a value |
298 // that doesn't convert to a number. This is common in | 325 // that doesn't convert to a number. This is common in |
299 // certain benchmarks. | 326 // certain benchmarks. |
300 if (NUMBER_IS_NAN(x)) return 0; | 327 if (NUMBER_IS_NAN(x)) return 0; |
301 } | 328 } |
302 return %NumberAnd(x, y); | 329 return %NumberAnd(x, y); |
303 } | 330 } |
304 | 331 |
305 | 332 |
306 //ECMA-262, section 11.10, page 57. | 333 // Strong mode BIT_AND throws if an implicit conversion would be performed |
307 function BIT_AND_STRONG(y) { | 334 function BIT_AND_STRONG(y) { |
308 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 335 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
309 return %NumberAnd(this, y); | 336 return %NumberAnd(this, y); |
310 } | 337 } |
311 throw %MakeTypeError('strong_implicit_cast'); | 338 throw %MakeTypeError('strong_implicit_cast'); |
312 } | 339 } |
313 | 340 |
314 | 341 |
315 // ECMA-262, section 11.10, page 57. | 342 // ECMA-262, section 11.10, page 57. |
316 function BIT_XOR(y) { | 343 function BIT_XOR(y) { |
317 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 344 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
318 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 345 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
319 return %NumberXor(x, y); | 346 return %NumberXor(x, y); |
320 } | 347 } |
321 | 348 |
322 | 349 |
323 //ECMA-262, section 11.10, page 57. | 350 // Strong mode BIT_XOR throws if an implicit conversion would be performed |
324 function BIT_XOR_STRONG(y) { | 351 function BIT_XOR_STRONG(y) { |
325 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 352 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
326 return %NumberXor(this, y); | 353 return %NumberXor(this, y); |
327 } | 354 } |
328 throw %MakeTypeError('strong_implicit_cast'); | 355 throw %MakeTypeError('strong_implicit_cast'); |
329 } | 356 } |
330 | 357 |
331 | 358 |
332 // ECMA-262, section 11.7.1, page 51. | 359 // ECMA-262, section 11.7.1, page 51. |
333 function SHL(y) { | 360 function SHL(y) { |
334 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 361 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
335 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 362 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
336 return %NumberShl(x, y); | 363 return %NumberShl(x, y); |
337 } | 364 } |
338 | 365 |
339 | 366 |
340 //ECMA-262, section 11.7.1, page 51. | 367 // Strong mode SHL throws if an implicit conversion would be performed |
341 function SHL_STRONG(y) { | 368 function SHL_STRONG(y) { |
342 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 369 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
343 return %NumberShl(this, y); | 370 return %NumberShl(this, y); |
344 } | 371 } |
345 throw %MakeTypeError('strong_implicit_cast'); | 372 throw %MakeTypeError('strong_implicit_cast'); |
346 } | 373 } |
347 | 374 |
348 | 375 |
349 // ECMA-262, section 11.7.2, page 51. | 376 // ECMA-262, section 11.7.2, page 51. |
350 function SAR(y) { | 377 function SAR(y) { |
(...skipping 10 matching lines...) Expand all Loading... |
361 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 388 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
362 // Optimize for the case where we end up shifting a value | 389 // Optimize for the case where we end up shifting a value |
363 // that doesn't convert to a number. This is common in | 390 // that doesn't convert to a number. This is common in |
364 // certain benchmarks. | 391 // certain benchmarks. |
365 if (NUMBER_IS_NAN(x)) return 0; | 392 if (NUMBER_IS_NAN(x)) return 0; |
366 } | 393 } |
367 return %NumberSar(x, y); | 394 return %NumberSar(x, y); |
368 } | 395 } |
369 | 396 |
370 | 397 |
371 //ECMA-262, section 11.7.2, page 51. | 398 // Strong mode SAR throws if an implicit conversion would be performed |
372 function SAR_STRONG(y) { | 399 function SAR_STRONG(y) { |
373 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 400 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
374 return %NumberSar(this, y); | 401 return %NumberSar(this, y); |
375 } | 402 } |
376 throw %MakeTypeError('strong_implicit_cast'); | 403 throw %MakeTypeError('strong_implicit_cast'); |
377 } | 404 } |
378 | 405 |
379 | 406 |
380 // ECMA-262, section 11.7.3, page 52. | 407 // ECMA-262, section 11.7.3, page 52. |
381 function SHR(y) { | 408 function SHR(y) { |
382 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 409 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
383 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 410 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
384 return %NumberShr(x, y); | 411 return %NumberShr(x, y); |
385 } | 412 } |
386 | 413 |
387 | 414 |
388 //ECMA-262, section 11.7.3, page 52. | 415 // Strong mode SHR throws if an implicit conversion would be performed |
389 function SHR_STRONG(y) { | 416 function SHR_STRONG(y) { |
390 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 417 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
391 return %NumberShr(this, y); | 418 return %NumberShr(this, y); |
392 } | 419 } |
393 throw %MakeTypeError('strong_implicit_cast'); | 420 throw %MakeTypeError('strong_implicit_cast'); |
394 } | 421 } |
395 | 422 |
396 | 423 |
397 /* ----------------------------- | 424 /* ----------------------------- |
398 - - - H e l p e r s - - - | 425 - - - H e l p e r s - - - |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 | 893 |
867 /* ----------------------------------------------- | 894 /* ----------------------------------------------- |
868 - - - J a v a S c r i p t S t u b s - - - | 895 - - - J a v a S c r i p t S t u b s - - - |
869 ----------------------------------------------- | 896 ----------------------------------------------- |
870 */ | 897 */ |
871 | 898 |
872 function STRING_LENGTH_STUB(name) { | 899 function STRING_LENGTH_STUB(name) { |
873 var receiver = this; // implicit first parameter | 900 var receiver = this; // implicit first parameter |
874 return %_StringGetLength(%_JSValueGetValue(receiver)); | 901 return %_StringGetLength(%_JSValueGetValue(receiver)); |
875 } | 902 } |
OLD | NEW |