Bug 1132045 - Add handles to various equality operations. r=jandem

This commit is contained in:
Tom Schuster 2015-02-17 15:03:23 +01:00
parent d2f5f496e0
commit 65eaab2a37
8 changed files with 38 additions and 37 deletions

View File

@ -823,7 +823,10 @@ HashableValue::operator==(const HashableValue &other) const
#ifdef DEBUG
bool same;
MOZ_ASSERT(SameValue(nullptr, value, other.value, &same));
PerThreadData *data = TlsPerThreadData.get();
RootedValue valueRoot(data, value);
RootedValue otherRoot(data, other.value);
MOZ_ASSERT(SameValue(nullptr, valueRoot, otherRoot, &same));
MOZ_ASSERT(same == b);
#endif
return b;

View File

@ -17,8 +17,8 @@ BEGIN_TEST(testSameValue)
* double, and this is believed to be the only way to make such a
* comparison possible.
*/
jsval v1 = DOUBLE_TO_JSVAL(0.0);
jsval v2 = DOUBLE_TO_JSVAL(-0.0);
JS::RootedValue v1(cx, JS::DoubleValue(0.0));
JS::RootedValue v2(cx, JS::DoubleValue(-0.0));
bool same;
CHECK(JS_SameValue(cx, v1, v2, &same));
CHECK(!same);

View File

@ -30,11 +30,12 @@ C_jsvalAlignmentTest();
BEGIN_TEST(testValueABI_retparam)
{
JS::RootedObject obj(cx, JS::CurrentGlobalOrNull(cx));
jsval v = OBJECT_TO_JSVAL(obj);
RootedValue v(cx, ObjectValue(*obj));
obj = nullptr;
CHECK(C_ValueToObject(cx, v, obj.address()));
bool equal;
CHECK(JS_StrictlyEqual(cx, v, OBJECT_TO_JSVAL(obj), &equal));
RootedValue v2(cx, ObjectValue(*obj));
CHECK(JS_StrictlyEqual(cx, v, v2, &equal));
CHECK(equal);
v = C_GetEmptyStringValue(cx);

View File

@ -285,16 +285,13 @@ JS_TypeOfValue(JSContext *cx, HandleValue value)
}
JS_PUBLIC_API(bool)
JS_StrictlyEqual(JSContext *cx, jsval value1, jsval value2, bool *equal)
JS_StrictlyEqual(JSContext *cx, HandleValue value1, HandleValue value2, bool *equal)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, value1, value2);
bool eq;
if (!StrictlyEqual(cx, value1, value2, &eq))
return false;
*equal = eq;
return true;
MOZ_ASSERT(equal);
return StrictlyEqual(cx, value1, value2, equal);
}
JS_PUBLIC_API(bool)
@ -308,16 +305,13 @@ JS_LooselyEqual(JSContext *cx, HandleValue value1, HandleValue value2, bool *equ
}
JS_PUBLIC_API(bool)
JS_SameValue(JSContext *cx, jsval value1, jsval value2, bool *same)
JS_SameValue(JSContext *cx, HandleValue value1, HandleValue value2, bool *same)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, value1, value2);
bool s;
if (!SameValue(cx, value1, value2, &s))
return false;
*same = s;
return true;
MOZ_ASSERT(same);
return SameValue(cx, value1, value2, same);
}
JS_PUBLIC_API(bool)

View File

@ -1057,13 +1057,13 @@ extern JS_PUBLIC_API(JSType)
JS_TypeOfValue(JSContext *cx, JS::Handle<JS::Value> v);
extern JS_PUBLIC_API(bool)
JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, bool *equal);
JS_StrictlyEqual(JSContext *cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool *equal);
extern JS_PUBLIC_API(bool)
JS_LooselyEqual(JSContext *cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool *equal);
extern JS_PUBLIC_API(bool)
JS_SameValue(JSContext *cx, jsval v1, jsval v2, bool *same);
JS_SameValue(JSContext *cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool *same);
/* True iff fun is the global eval function. */
extern JS_PUBLIC_API(bool)

View File

@ -534,16 +534,18 @@ DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const
break;
if (desc.hasGet()) {
RootedValue getter(cx, shape->getterOrUndefined());
bool same;
if (!SameValue(cx, desc.getterValue(), shape->getterOrUndefined(), &same))
if (!SameValue(cx, desc.getterValue(), getter, &same))
return false;
if (!same)
break;
}
if (desc.hasSet()) {
RootedValue setter(cx, shape->setterOrUndefined());
bool same;
if (!SameValue(cx, desc.setterValue(), shape->setterOrUndefined(), &same))
if (!SameValue(cx, desc.setterValue(), setter, &same))
return false;
if (!same)
break;
@ -669,16 +671,18 @@ DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const
MOZ_ASSERT(desc.isAccessorDescriptor() && shape->isAccessorDescriptor());
if (!shape->configurable()) {
if (desc.hasSet()) {
RootedValue setter(cx, shape->setterOrUndefined());
bool same;
if (!SameValue(cx, desc.setterValue(), shape->setterOrUndefined(), &same))
if (!SameValue(cx, desc.setterValue(), setter, &same))
return false;
if (!same)
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
}
if (desc.hasGet()) {
RootedValue getter(cx, shape->getterOrUndefined());
bool same;
if (!SameValue(cx, desc.getterValue(), shape->getterOrUndefined(), &same))
if (!SameValue(cx, desc.getterValue(), getter, &same))
return false;
if (!same)
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);

View File

@ -702,7 +702,7 @@ js::HasInstance(JSContext *cx, HandleObject obj, HandleValue v, bool *bp)
}
static inline bool
EqualGivenSameType(JSContext *cx, const Value &lval, const Value &rval, bool *equal)
EqualGivenSameType(JSContext *cx, HandleValue lval, HandleValue rval, bool *equal)
{
MOZ_ASSERT(SameType(lval, rval));
@ -716,13 +716,13 @@ EqualGivenSameType(JSContext *cx, const Value &lval, const Value &rval, bool *eq
*equal = (lval.toGCThing() == rval.toGCThing());
return true;
}
*equal = lval.payloadAsRawUint32() == rval.payloadAsRawUint32();
MOZ_ASSERT_IF(lval.isUndefined(), *equal);
*equal = lval.get().payloadAsRawUint32() == rval.get().payloadAsRawUint32();
MOZ_ASSERT_IF(lval.isUndefined() || lval.isNull(), *equal);
return true;
}
static inline bool
LooselyEqualBooleanAndOther(JSContext *cx, const Value &lval, const Value &rval, bool *result)
LooselyEqualBooleanAndOther(JSContext *cx, HandleValue lval, HandleValue rval, bool *result)
{
MOZ_ASSERT(!rval.isBoolean());
RootedValue lvalue(cx, Int32Value(lval.toBoolean() ? 1 : 0));
@ -746,7 +746,7 @@ LooselyEqualBooleanAndOther(JSContext *cx, const Value &lval, const Value &rval,
// ES6 draft rev32 7.2.12 Abstract Equality Comparison
bool
js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *result)
js::LooselyEqual(JSContext *cx, HandleValue lval, HandleValue rval, bool *result)
{
// Step 3.
if (SameType(lval, rval))
@ -821,9 +821,8 @@ js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *resu
}
bool
js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equal)
js::StrictlyEqual(JSContext *cx, HandleValue lval, HandleValue rval, bool *equal)
{
Value lval = lref, rval = rref;
if (SameType(lval, rval))
return EqualGivenSameType(cx, lval, rval, equal);
@ -849,7 +848,7 @@ IsNaN(const Value &v)
}
bool
js::SameValue(JSContext *cx, const Value &v1, const Value &v2, bool *same)
js::SameValue(JSContext *cx, HandleValue v1, HandleValue v2, bool *same)
{
if (IsNegativeZero(v1)) {
*same = IsNegativeZero(v2);
@ -2091,10 +2090,10 @@ END_CASE(JSOP_NE)
#define STRICT_EQUALITY_OP(OP, COND) \
JS_BEGIN_MACRO \
const Value &rref = REGS.sp[-1]; \
const Value &lref = REGS.sp[-2]; \
HandleValue lval = REGS.stackHandleAt(-2); \
HandleValue rval = REGS.stackHandleAt(-1); \
bool equal; \
if (!StrictlyEqual(cx, lref, rref, &equal)) \
if (!StrictlyEqual(cx, lval, rval, &equal)) \
goto error; \
(COND) = equal OP true; \
REGS.sp--; \

View File

@ -221,14 +221,14 @@ extern bool
RunScript(JSContext *cx, RunState &state);
extern bool
StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *equal);
StrictlyEqual(JSContext *cx, HandleValue lval, HandleValue rval, bool *equal);
extern bool
LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *equal);
LooselyEqual(JSContext *cx, HandleValue lval, HandleValue rval, bool *equal);
/* === except that NaN is the same as NaN and -0 is not the same as +0. */
extern bool
SameValue(JSContext *cx, const Value &v1, const Value &v2, bool *same);
SameValue(JSContext *cx, HandleValue v1, HandleValue v2, bool *same);
extern JSType
TypeOfObject(JSObject *obj);