| Index: src/runtime.js
|
| ===================================================================
|
| --- src/runtime.js (revision 457)
|
| +++ src/runtime.js (working copy)
|
| @@ -52,36 +52,31 @@
|
|
|
| // ECMA-262, section 11.9.1, page 55.
|
| function EQUALS(y) {
|
| + if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y);
|
| var x = this;
|
|
|
| // NOTE: We use iteration instead of recursion, because it is
|
| // difficult to call EQUALS with the correct setting of 'this' in
|
| // an efficient way.
|
| -
|
| while (true) {
|
| -
|
| if (IS_NUMBER(x)) {
|
| if (y == null) return 1; // not equal
|
| return %NumberEquals(x, %ToNumber(y));
|
| -
|
| } else if (IS_STRING(x)) {
|
| if (IS_STRING(y)) return %StringEquals(x, y);
|
| if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
|
| if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
|
| if (y == null) return 1; // not equal
|
| y = %ToPrimitive(y, NO_HINT);
|
| -
|
| } else if (IS_BOOLEAN(x)) {
|
| if (IS_BOOLEAN(y)) {
|
| return %_ObjectEquals(x, y) ? 0 : 1;
|
| }
|
| if (y == null) return 1; // not equal
|
| return %NumberEquals(%ToNumber(x), %ToNumber(y));
|
| -
|
| } else if (x == null) {
|
| // NOTE: This checks for both null and undefined.
|
| return (y == null) ? 0 : 1;
|
| -
|
| } else {
|
| if (IS_OBJECT(y)) {
|
| return %_ObjectEquals(x, y) ? 0 : 1;
|
| @@ -90,12 +85,10 @@
|
| return %_ObjectEquals(x, y) ? 0 : 1;
|
| }
|
| x = %ToPrimitive(x, NO_HINT);
|
| -
|
| }
|
| }
|
| }
|
|
|
| -
|
| // ECMA-262, section 11.9.4, page 56.
|
| function STRICT_EQUALS(x) {
|
| if (IS_NUMBER(this)) {
|
| @@ -125,11 +118,15 @@
|
| // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as
|
| // the result when either (or both) the operands are NaN.
|
| function COMPARE(x, ncr) {
|
| - // Improve performance for floating point compares
|
| + // Fast case for numbers and strings.
|
| if (IS_NUMBER(this) && IS_NUMBER(x)) {
|
| return %NumberCompare(this, x, ncr);
|
| }
|
| + if (IS_STRING(this) && IS_STRING(x)) {
|
| + return %StringCompare(this, x);
|
| + }
|
|
|
| + // Default implementation.
|
| var a = %ToPrimitive(this, NUMBER_HINT);
|
| var b = %ToPrimitive(x, NUMBER_HINT);
|
| if (IS_STRING(a) && IS_STRING(b)) {
|
| @@ -149,10 +146,10 @@
|
| // ECMA-262, section 11.6.1, page 50.
|
| function ADD(x) {
|
| // Fast case: Check for number operands and do the addition.
|
| - if (IS_NUMBER(this) && IS_NUMBER(x)) {
|
| - return %NumberAdd(this, x);
|
| - }
|
| + if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x);
|
| + if (IS_STRING(this) && IS_STRING(x)) return %StringAdd(this, x);
|
|
|
| + // Default implementation.
|
| var a = %ToPrimitive(this, NO_HINT);
|
| var b = %ToPrimitive(x, NO_HINT);
|
|
|
| @@ -397,6 +394,10 @@
|
| // ECMA-262, section 9.1, page 30. Use null/undefined for no hint,
|
| // (1) for number hint, and (2) for string hint.
|
| function ToPrimitive(x, hint) {
|
| + // Fast case check.
|
| + if (IS_STRING(x)) return x;
|
| + if ((hint != NUMBER_HINT) && %IsStringClass(x)) return %_ValueOf(x);
|
| + // Normal behaior.
|
| if (!IS_OBJECT(x) && !IS_FUNCTION(x)) return x;
|
| if (x == null) return x; // check for null, undefined
|
| if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;
|
|
|