| Index: src/runtime.js
|
| diff --git a/src/runtime.js b/src/runtime.js
|
| index 66d839bec083ded693b03e7f642c1d241ee9fdab..4f53efe0b064c1c6e508ae6c455566276f8fd794 100644
|
| --- a/src/runtime.js
|
| +++ b/src/runtime.js
|
| @@ -49,41 +49,47 @@ const $Function = global.Function;
|
| const $Boolean = global.Boolean;
|
| const $NaN = 0/0;
|
|
|
| -
|
| -// ECMA-262, section 11.9.1, page 55.
|
| +// ECMA-262 Section 11.9.3.
|
| 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));
|
| + while (true) {
|
| + if (IS_NUMBER(y)) return %NumberEquals(x, y);
|
| + if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
|
| + if (!IS_SPEC_OBJECT(y)) {
|
| + // String or boolean.
|
| + return %NumberEquals(x, %ToNumber(y));
|
| + }
|
| + y = %ToPrimitive(y, NO_HINT);
|
| + }
|
| } else if (IS_STRING(x)) {
|
| - if (IS_STRING(y)) return %StringEquals(x, y);
|
| + while (true) {
|
| + 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 (IS_NULL_OR_UNDEFINED(y)) 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 (IS_NULL_OR_UNDEFINED(y)) return 1;
|
| 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
|
| + if (IS_STRING(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
|
| + // y is object.
|
| + x = %ToNumber(x);
|
| 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_NULL_OR_UNDEFINED(x)) {
|
| + return IS_NULL_OR_UNDEFINED(y) ? 0 : 1;
|
| } else {
|
| - // x is not a number, boolean, null or undefined.
|
| - if (y == null) return 1; // not equal
|
| + // x is an object.
|
| if (IS_SPEC_OBJECT(y)) {
|
| return %_ObjectEquals(x, y) ? 0 : 1;
|
| }
|
| -
|
| + if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
|
| + if (IS_BOOLEAN(y)) y = %ToNumber(y);
|
| x = %ToPrimitive(x, NO_HINT);
|
| }
|
| }
|
|
|