mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
Issue #2241 - Part 1: Move {js::,JS_}{{Strictly,Loosely}Equal,SameValue} into their own header and implementation files
Backported from Mozilla bug 1516742. The .from* methods are going to depend on SameValueZero, which needs to be visible to /dom. This patch provides the foundation for that.
This commit is contained in:
parent
1ae0d6ff7f
commit
ec2fb72568
17 changed files with 338 additions and 223 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue