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); |
} |
} |