summaryrefslogtreecommitdiff
path: root/js/src/vm/Interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/Interpreter.cpp')
-rw-r--r--js/src/vm/Interpreter.cpp165
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)
{