| 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 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 = %ToPrimitive(this, NO_HINT); |
| 163 var b = %ToPrimitive(x, NO_HINT); | 163 var b = %ToPrimitive(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, %ToString(b)); |
| 167 } else if (IS_STRING(b)) { | 167 } else if (IS_STRING(b)) { |
| 168 return %_StringAdd(%ToString(a), b); | 168 return %_StringAdd(%NonStringToString(a), b); |
| 169 } else { | 169 } else { |
| 170 return %NumberAdd(%ToNumber(a), %ToNumber(b)); | 170 return %NumberAdd(%ToNumber(a), %ToNumber(b)); |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| 175 // Left operand (this) is already a string. | 175 // Left operand (this) is already a string. |
| 176 function STRING_ADD_LEFT(y) { | 176 function STRING_ADD_LEFT(y) { |
| 177 if (!IS_STRING(y)) { | 177 if (!IS_STRING(y)) { |
| 178 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { | 178 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 198 ? %_NumberToString(x) | 198 ? %_NumberToString(x) |
| 199 : %ToString(%ToPrimitive(x, NO_HINT)); | 199 : %ToString(%ToPrimitive(x, NO_HINT)); |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 return %_StringAdd(x, y); | 202 return %_StringAdd(x, y); |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 // ECMA-262, section 11.6.2, page 50. | 206 // ECMA-262, section 11.6.2, page 50. |
| 207 function SUB(y) { | 207 function SUB(y) { |
| 208 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 208 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 209 if (!IS_NUMBER(y)) y = %ToNumber(y); | 209 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 210 return %NumberSub(x, y); | 210 return %NumberSub(x, y); |
| 211 } | 211 } |
| 212 | 212 |
| 213 | 213 |
| 214 // ECMA-262, section 11.5.1, page 48. | 214 // ECMA-262, section 11.5.1, page 48. |
| 215 function MUL(y) { | 215 function MUL(y) { |
| 216 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 216 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 217 if (!IS_NUMBER(y)) y = %ToNumber(y); | 217 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 218 return %NumberMul(x, y); | 218 return %NumberMul(x, y); |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 // ECMA-262, section 11.5.2, page 49. | 222 // ECMA-262, section 11.5.2, page 49. |
| 223 function DIV(y) { | 223 function DIV(y) { |
| 224 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 224 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 225 if (!IS_NUMBER(y)) y = %ToNumber(y); | 225 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 226 return %NumberDiv(x, y); | 226 return %NumberDiv(x, y); |
| 227 } | 227 } |
| 228 | 228 |
| 229 | 229 |
| 230 // ECMA-262, section 11.5.3, page 49. | 230 // ECMA-262, section 11.5.3, page 49. |
| 231 function MOD(y) { | 231 function MOD(y) { |
| 232 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 232 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 233 if (!IS_NUMBER(y)) y = %ToNumber(y); | 233 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 234 return %NumberMod(x, y); | 234 return %NumberMod(x, y); |
| 235 } | 235 } |
| 236 | 236 |
| 237 | 237 |
| 238 | 238 |
| 239 /* ------------------------------------------- | 239 /* ------------------------------------------- |
| 240 - - - B i t o p e r a t i o n s - - - | 240 - - - B i t o p e r a t i o n s - - - |
| 241 ------------------------------------------- | 241 ------------------------------------------- |
| 242 */ | 242 */ |
| 243 | 243 |
| 244 // ECMA-262, section 11.10, page 57. | 244 // ECMA-262, section 11.10, page 57. |
| 245 function BIT_OR(y) { | 245 function BIT_OR(y) { |
| 246 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 246 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 247 if (!IS_NUMBER(y)) y = %ToNumber(y); | 247 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 248 return %NumberOr(x, y); | 248 return %NumberOr(x, y); |
| 249 } | 249 } |
| 250 | 250 |
| 251 | 251 |
| 252 // ECMA-262, section 11.10, page 57. | 252 // ECMA-262, section 11.10, page 57. |
| 253 function BIT_AND(y) { | 253 function BIT_AND(y) { |
| 254 var x; | 254 var x; |
| 255 if (IS_NUMBER(this)) { | 255 if (IS_NUMBER(this)) { |
| 256 x = this; | 256 x = this; |
| 257 if (!IS_NUMBER(y)) y = %ToNumber(y); | 257 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 258 } else { | 258 } else { |
| 259 x = %ToNumber(this); | 259 x = %NonNumberToNumber(this); |
| 260 // Make sure to convert the right operand to a number before | 260 // Make sure to convert the right operand to a number before |
| 261 // bailing out in the fast case, but after converting the | 261 // bailing out in the fast case, but after converting the |
| 262 // left operand. This ensures that valueOf methods on the right | 262 // left operand. This ensures that valueOf methods on the right |
| 263 // operand are always executed. | 263 // operand are always executed. |
| 264 if (!IS_NUMBER(y)) y = %ToNumber(y); | 264 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 265 // Optimize for the case where we end up AND'ing a value | 265 // Optimize for the case where we end up AND'ing a value |
| 266 // that doesn't convert to a number. This is common in | 266 // that doesn't convert to a number. This is common in |
| 267 // certain benchmarks. | 267 // certain benchmarks. |
| 268 if (NUMBER_IS_NAN(x)) return 0; | 268 if (NUMBER_IS_NAN(x)) return 0; |
| 269 } | 269 } |
| 270 return %NumberAnd(x, y); | 270 return %NumberAnd(x, y); |
| 271 } | 271 } |
| 272 | 272 |
| 273 | 273 |
| 274 // ECMA-262, section 11.10, page 57. | 274 // ECMA-262, section 11.10, page 57. |
| 275 function BIT_XOR(y) { | 275 function BIT_XOR(y) { |
| 276 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 276 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 277 if (!IS_NUMBER(y)) y = %ToNumber(y); | 277 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 278 return %NumberXor(x, y); | 278 return %NumberXor(x, y); |
| 279 } | 279 } |
| 280 | 280 |
| 281 | 281 |
| 282 // ECMA-262, section 11.4.7, page 47. | 282 // ECMA-262, section 11.4.7, page 47. |
| 283 function UNARY_MINUS() { | 283 function UNARY_MINUS() { |
| 284 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 284 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 285 return %NumberUnaryMinus(x); | 285 return %NumberUnaryMinus(x); |
| 286 } | 286 } |
| 287 | 287 |
| 288 | 288 |
| 289 // ECMA-262, section 11.4.8, page 48. | 289 // ECMA-262, section 11.4.8, page 48. |
| 290 function BIT_NOT() { | 290 function BIT_NOT() { |
| 291 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 291 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 292 return %NumberNot(x); | 292 return %NumberNot(x); |
| 293 } | 293 } |
| 294 | 294 |
| 295 | 295 |
| 296 // ECMA-262, section 11.7.1, page 51. | 296 // ECMA-262, section 11.7.1, page 51. |
| 297 function SHL(y) { | 297 function SHL(y) { |
| 298 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 298 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 299 if (!IS_NUMBER(y)) y = %ToNumber(y); | 299 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 300 return %NumberShl(x, y); | 300 return %NumberShl(x, y); |
| 301 } | 301 } |
| 302 | 302 |
| 303 | 303 |
| 304 // ECMA-262, section 11.7.2, page 51. | 304 // ECMA-262, section 11.7.2, page 51. |
| 305 function SAR(y) { | 305 function SAR(y) { |
| 306 var x; | 306 var x; |
| 307 if (IS_NUMBER(this)) { | 307 if (IS_NUMBER(this)) { |
| 308 x = this; | 308 x = this; |
| 309 if (!IS_NUMBER(y)) y = %ToNumber(y); | 309 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 310 } else { | 310 } else { |
| 311 x = %ToNumber(this); | 311 x = %NonNumberToNumber(this); |
| 312 // Make sure to convert the right operand to a number before | 312 // Make sure to convert the right operand to a number before |
| 313 // bailing out in the fast case, but after converting the | 313 // bailing out in the fast case, but after converting the |
| 314 // left operand. This ensures that valueOf methods on the right | 314 // left operand. This ensures that valueOf methods on the right |
| 315 // operand are always executed. | 315 // operand are always executed. |
| 316 if (!IS_NUMBER(y)) y = %ToNumber(y); | 316 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 317 // Optimize for the case where we end up shifting a value | 317 // Optimize for the case where we end up shifting a value |
| 318 // that doesn't convert to a number. This is common in | 318 // that doesn't convert to a number. This is common in |
| 319 // certain benchmarks. | 319 // certain benchmarks. |
| 320 if (NUMBER_IS_NAN(x)) return 0; | 320 if (NUMBER_IS_NAN(x)) return 0; |
| 321 } | 321 } |
| 322 return %NumberSar(x, y); | 322 return %NumberSar(x, y); |
| 323 } | 323 } |
| 324 | 324 |
| 325 | 325 |
| 326 // ECMA-262, section 11.7.3, page 52. | 326 // ECMA-262, section 11.7.3, page 52. |
| 327 function SHR(y) { | 327 function SHR(y) { |
| 328 var x = IS_NUMBER(this) ? this : %ToNumber(this); | 328 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 329 if (!IS_NUMBER(y)) y = %ToNumber(y); | 329 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 330 return %NumberShr(x, y); | 330 return %NumberShr(x, y); |
| 331 } | 331 } |
| 332 | 332 |
| 333 | 333 |
| 334 | 334 |
| 335 /* ----------------------------- | 335 /* ----------------------------- |
| 336 - - - H e l p e r s - - - | 336 - - - H e l p e r s - - - |
| 337 ----------------------------- | 337 ----------------------------- |
| 338 */ | 338 */ |
| 339 | 339 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 if (IS_NUMBER(x)) return x; | 504 if (IS_NUMBER(x)) return x; |
| 505 if (IS_STRING(x)) { | 505 if (IS_STRING(x)) { |
| 506 return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x) | 506 return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x) |
| 507 : %StringToNumber(x); | 507 : %StringToNumber(x); |
| 508 } | 508 } |
| 509 if (IS_BOOLEAN(x)) return x ? 1 : 0; | 509 if (IS_BOOLEAN(x)) return x ? 1 : 0; |
| 510 if (IS_UNDEFINED(x)) return $NaN; | 510 if (IS_UNDEFINED(x)) return $NaN; |
| 511 return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); | 511 return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); |
| 512 } | 512 } |
| 513 | 513 |
| 514 function NonNumberToNumber(x) { |
| 515 if (IS_STRING(x)) { |
| 516 return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x) |
| 517 : %StringToNumber(x); |
| 518 } |
| 519 if (IS_BOOLEAN(x)) return x ? 1 : 0; |
| 520 if (IS_UNDEFINED(x)) return $NaN; |
| 521 return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); |
| 522 } |
| 523 |
| 514 | 524 |
| 515 // ECMA-262, section 9.8, page 35. | 525 // ECMA-262, section 9.8, page 35. |
| 516 function ToString(x) { | 526 function ToString(x) { |
| 517 if (IS_STRING(x)) return x; | 527 if (IS_STRING(x)) return x; |
| 518 if (IS_NUMBER(x)) return %_NumberToString(x); | 528 if (IS_NUMBER(x)) return %_NumberToString(x); |
| 519 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; | 529 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; |
| 520 if (IS_UNDEFINED(x)) return 'undefined'; | 530 if (IS_UNDEFINED(x)) return 'undefined'; |
| 521 return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); | 531 return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); |
| 522 } | 532 } |
| 523 | 533 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 return %NumberToJSInt32(ToNumber(x)); | 571 return %NumberToJSInt32(ToNumber(x)); |
| 562 } | 572 } |
| 563 | 573 |
| 564 | 574 |
| 565 // ES5, section 9.12 | 575 // ES5, section 9.12 |
| 566 function SameValue(x, y) { | 576 function SameValue(x, y) { |
| 567 if (typeof x != typeof y) return false; | 577 if (typeof x != typeof y) return false; |
| 568 if (IS_NUMBER(x)) { | 578 if (IS_NUMBER(x)) { |
| 569 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; | 579 if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true; |
| 570 // x is +0 and y is -0 or vice versa. | 580 // x is +0 and y is -0 or vice versa. |
| 571 if (x === 0 && y === 0 && (1 / x) != (1 / y)) { | 581 if (x === 0 && y === 0 && (1 / x) != (1 / y)) return false; |
| 572 return false; | |
| 573 } | |
| 574 return x === y; | |
| 575 } | 582 } |
| 576 return x === y | 583 return x === y; |
| 577 } | 584 } |
| 578 | 585 |
| 579 | 586 |
| 580 /* --------------------------------- | 587 /* --------------------------------- |
| 581 - - - U t i l i t i e s - - - | 588 - - - U t i l i t i e s - - - |
| 582 --------------------------------- | 589 --------------------------------- |
| 583 */ | 590 */ |
| 584 | 591 |
| 585 // Returns if the given x is a primitive value - not an object or a | 592 // Returns if the given x is a primitive value - not an object or a |
| 586 // function. | 593 // function. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 throw %MakeTypeError('cannot_convert_to_primitive', []); | 634 throw %MakeTypeError('cannot_convert_to_primitive', []); |
| 628 } | 635 } |
| 629 | 636 |
| 630 | 637 |
| 631 // NOTE: Setting the prototype for Array must take place as early as | 638 // NOTE: Setting the prototype for Array must take place as early as |
| 632 // possible due to code generation for array literals. When | 639 // possible due to code generation for array literals. When |
| 633 // generating code for a array literal a boilerplate array is created | 640 // generating code for a array literal a boilerplate array is created |
| 634 // that is cloned when running the code. It is essiential that the | 641 // that is cloned when running the code. It is essiential that the |
| 635 // boilerplate gets the right prototype. | 642 // boilerplate gets the right prototype. |
| 636 %FunctionSetPrototype($Array, new $Array(0)); | 643 %FunctionSetPrototype($Array, new $Array(0)); |
| OLD | NEW |