diff options
Diffstat (limited to 'js/src/vm/Interpreter.cpp')
-rw-r--r-- | js/src/vm/Interpreter.cpp | 165 |
1 files changed, 1 insertions, 164 deletions
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index b17c762eae..d7c1b8e84a 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -41,6 +41,7 @@ #include "vm/AsyncFunction.h" #include "vm/AsyncIteration.h" #include "vm/Debugger.h" +#include "vm/EqualityOperations.h" // js::StrictlyEqual #include "vm/GeneratorObject.h" #include "vm/Opcodes.h" #include "vm/Scope.h" @@ -786,170 +787,6 @@ js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp) return JS::InstanceofOperator(cx, obj, local, bp); } -static inline bool -EqualGivenSameType(JSContext* cx, HandleValue lval, HandleValue rval, bool* equal) -{ - MOZ_ASSERT(SameType(lval, rval)); - - if (lval.isString()) - return EqualStrings(cx, lval.toString(), rval.toString(), equal); - if (lval.isDouble()) { - *equal = (lval.toDouble() == rval.toDouble()); - return true; - } - if (lval.isGCThing()) { // objects or symbols - *equal = (lval.toGCThing() == rval.toGCThing()); - return true; - } - *equal = lval.get().payloadAsRawUint32() == rval.get().payloadAsRawUint32(); - MOZ_ASSERT_IF(lval.isUndefined() || lval.isNull(), *equal); - return true; -} - -static inline bool -LooselyEqualBooleanAndOther(JSContext* cx, HandleValue lval, HandleValue rval, bool* result) -{ - MOZ_ASSERT(!rval.isBoolean()); - RootedValue lvalue(cx, Int32Value(lval.toBoolean() ? 1 : 0)); - - // The tail-call would end up in Step 3. - if (rval.isNumber()) { - *result = (lvalue.toNumber() == rval.toNumber()); - return true; - } - // The tail-call would end up in Step 6. - if (rval.isString()) { - double num; - if (!StringToNumber(cx, rval.toString(), &num)) - return false; - *result = (lvalue.toNumber() == num); - return true; - } - - return LooselyEqual(cx, lvalue, rval, result); -} - -// ES6 draft rev32 7.2.12 Abstract Equality Comparison -bool -js::LooselyEqual(JSContext* cx, HandleValue lval, HandleValue rval, bool* result) -{ - // Step 3. - if (SameType(lval, rval)) - return EqualGivenSameType(cx, lval, rval, result); - - // Handle int32 x double. - if (lval.isNumber() && rval.isNumber()) { - *result = (lval.toNumber() == rval.toNumber()); - return true; - } - - // Step 4. This a bit more complex, because of the undefined emulating object. - if (lval.isNullOrUndefined()) { - // We can return early here, because null | undefined is only equal to the same set. - *result = rval.isNullOrUndefined() || - (rval.isObject() && EmulatesUndefined(&rval.toObject())); - return true; - } - - // Step 5. - if (rval.isNullOrUndefined()) { - MOZ_ASSERT(!lval.isNullOrUndefined()); - *result = lval.isObject() && EmulatesUndefined(&lval.toObject()); - return true; - } - - // Step 6. - if (lval.isNumber() && rval.isString()) { - double num; - if (!StringToNumber(cx, rval.toString(), &num)) - return false; - *result = (lval.toNumber() == num); - return true; - } - - // Step 7. - if (lval.isString() && rval.isNumber()) { - double num; - if (!StringToNumber(cx, lval.toString(), &num)) - return false; - *result = (num == rval.toNumber()); - return true; - } - - // Step 8. - if (lval.isBoolean()) - return LooselyEqualBooleanAndOther(cx, lval, rval, result); - - // Step 9. - if (rval.isBoolean()) - return LooselyEqualBooleanAndOther(cx, rval, lval, result); - - // Step 10. - if ((lval.isString() || lval.isNumber() || lval.isSymbol()) && rval.isObject()) { - RootedValue rvalue(cx, rval); - if (!ToPrimitive(cx, &rvalue)) - return false; - return LooselyEqual(cx, lval, rvalue, result); - } - - // Step 11. - if (lval.isObject() && (rval.isString() || rval.isNumber() || rval.isSymbol())) { - RootedValue lvalue(cx, lval); - if (!ToPrimitive(cx, &lvalue)) - return false; - return LooselyEqual(cx, lvalue, rval, result); - } - - // Step 12. - *result = false; - return true; -} - -bool -js::StrictlyEqual(JSContext* cx, HandleValue lval, HandleValue rval, bool* equal) -{ - if (SameType(lval, rval)) - return EqualGivenSameType(cx, lval, rval, equal); - - if (lval.isNumber() && rval.isNumber()) { - *equal = (lval.toNumber() == rval.toNumber()); - return true; - } - - *equal = false; - return true; -} - -static inline bool -IsNegativeZero(const Value& v) -{ - return v.isDouble() && mozilla::IsNegativeZero(v.toDouble()); -} - -static inline bool -IsNaN(const Value& v) -{ - return v.isDouble() && mozilla::IsNaN(v.toDouble()); -} - -bool -js::SameValue(JSContext* cx, HandleValue v1, HandleValue v2, bool* same) -{ - if (IsNegativeZero(v1)) { - *same = IsNegativeZero(v2); - return true; - } - if (IsNegativeZero(v2)) { - *same = false; - return true; - } - if (IsNaN(v1) && IsNaN(v2)) { - *same = true; - return true; - } - return StrictlyEqual(cx, v1, v2, same); -} - JSType js::TypeOfObject(JSObject* obj) { |