public bool AreEqual(GlobalContext c) { if (ReferenceEquals(X, Y)) { return(X != JSEvalNumber.NaN); } if (ReferenceEquals(X.Type, Y.Type)) { Debug.Assert(X != RuntimeObj.Undefined && X != RuntimeObj.Null, "This has been handled by the normalization and the above reference test."); if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber)) { Debug.Assert(!(((JSEvalNumber)X).IsNaN && ((JSEvalNumber)Y).IsNaN)); return(X.ToDouble() == Y.ToDouble()); } else if (ReferenceEquals(X.Type, RuntimeObj.TypeString)) { return(X.ToString() == Y.ToString()); } else if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean)) { return(X.ToBoolean() == Y.ToBoolean()); } else { IComparable cmp; if (X.GetType() == Y.GetType() && (cmp = X as IComparable) != null) { Debug.Assert((cmp.CompareTo(Y) == 0) == X.Equals(Y), "When IComparable is implemented, it must match Equals behavior."); return(cmp.Equals(Y)); } } return(false); } if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber) && ReferenceEquals(Y.Type, RuntimeObj.TypeString)) { return(X.ToDouble() == Y.ToDouble()); } if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean) || ReferenceEquals(Y.Type, RuntimeObj.TypeBoolean)) { return(X.ToBoolean() == Y.ToBoolean()); } return(false); }