| Index: src/runtime.js
|
| ===================================================================
|
| --- src/runtime.js (revision 6174)
|
| +++ src/runtime.js (working copy)
|
| @@ -165,7 +165,7 @@
|
| if (IS_STRING(a)) {
|
| return %_StringAdd(a, %ToString(b));
|
| } else if (IS_STRING(b)) {
|
| - return %_StringAdd(%ToString(a), b);
|
| + return %_StringAdd(%NonStringToString(a), b);
|
| } else {
|
| return %NumberAdd(%ToNumber(a), %ToNumber(b));
|
| }
|
| @@ -205,32 +205,32 @@
|
|
|
| // ECMA-262, section 11.6.2, page 50.
|
| function SUB(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberSub(x, y);
|
| }
|
|
|
|
|
| // ECMA-262, section 11.5.1, page 48.
|
| function MUL(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberMul(x, y);
|
| }
|
|
|
|
|
| // ECMA-262, section 11.5.2, page 49.
|
| function DIV(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberDiv(x, y);
|
| }
|
|
|
|
|
| // ECMA-262, section 11.5.3, page 49.
|
| function MOD(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberMod(x, y);
|
| }
|
|
|
| @@ -243,8 +243,8 @@
|
|
|
| // ECMA-262, section 11.10, page 57.
|
| function BIT_OR(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberOr(x, y);
|
| }
|
|
|
| @@ -254,14 +254,14 @@
|
| var x;
|
| if (IS_NUMBER(this)) {
|
| x = this;
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| } else {
|
| - x = %ToNumber(this);
|
| + x = %NonNumToNum(this);
|
| // Make sure to convert the right operand to a number before
|
| // bailing out in the fast case, but after converting the
|
| // left operand. This ensures that valueOf methods on the right
|
| // operand are always executed.
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| // Optimize for the case where we end up AND'ing a value
|
| // that doesn't convert to a number. This is common in
|
| // certain benchmarks.
|
| @@ -273,30 +273,30 @@
|
|
|
| // ECMA-262, section 11.10, page 57.
|
| function BIT_XOR(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberXor(x, y);
|
| }
|
|
|
|
|
| // ECMA-262, section 11.4.7, page 47.
|
| function UNARY_MINUS() {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| return %NumberUnaryMinus(x);
|
| }
|
|
|
|
|
| // ECMA-262, section 11.4.8, page 48.
|
| function BIT_NOT() {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| return %NumberNot(x);
|
| }
|
|
|
|
|
| // ECMA-262, section 11.7.1, page 51.
|
| function SHL(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberShl(x, y);
|
| }
|
|
|
| @@ -306,14 +306,14 @@
|
| var x;
|
| if (IS_NUMBER(this)) {
|
| x = this;
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| } else {
|
| - x = %ToNumber(this);
|
| + x = %NonNumToNum(this);
|
| // Make sure to convert the right operand to a number before
|
| // bailing out in the fast case, but after converting the
|
| // left operand. This ensures that valueOf methods on the right
|
| // operand are always executed.
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| // Optimize for the case where we end up shifting a value
|
| // that doesn't convert to a number. This is common in
|
| // certain benchmarks.
|
| @@ -325,8 +325,8 @@
|
|
|
| // ECMA-262, section 11.7.3, page 52.
|
| function SHR(y) {
|
| - var x = IS_NUMBER(this) ? this : %ToNumber(this);
|
| - if (!IS_NUMBER(y)) y = %ToNumber(y);
|
| + var x = IS_NUMBER(this) ? this : %NonNumToNum(this);
|
| + if (!IS_NUMBER(y)) y = %NonNumToNum(y);
|
| return %NumberShr(x, y);
|
| }
|
|
|
| @@ -511,7 +511,17 @@
|
| return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
|
| }
|
|
|
| +function NonNumToNum(x) {
|
| + if (IS_STRING(x)) {
|
| + return %_HasCachedArrayIndex(x) ? %_GetCachedArrayIndex(x)
|
| + : %StringToNumber(x);
|
| + }
|
| + if (IS_BOOLEAN(x)) return x ? 1 : 0;
|
| + if (IS_UNDEFINED(x)) return $NaN;
|
| + return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
|
| +}
|
|
|
| +
|
| // ECMA-262, section 9.8, page 35.
|
| function ToString(x) {
|
| if (IS_STRING(x)) return x;
|
| @@ -568,12 +578,9 @@
|
| if (IS_NUMBER(x)) {
|
| if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
|
| // x is +0 and y is -0 or vice versa.
|
| - if (x === 0 && y === 0 && (1 / x) != (1 / y)) {
|
| - return false;
|
| - }
|
| - return x === y;
|
| + if (x === 0 && y === 0 && (1 / x) != (1 / y)) return false;
|
| }
|
| - return x === y
|
| + return x === y;
|
| }
|
|
|
|
|
|
|