зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1459611 - Use NumberEqualsInt32 when negative and positive zero are treated the same. r=jandem
This commit is contained in:
Родитель
b8d8d911f6
Коммит
5dfcfcd243
|
@ -661,38 +661,20 @@ js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, const V
|
|||
if (!GetElement(cx, replacer, k, &item))
|
||||
return false;
|
||||
|
||||
RootedId id(cx);
|
||||
/* Step 4b(iii)(5)(c-g). */
|
||||
if (!item.isNumber() && !item.isString()) {
|
||||
ESClass cls;
|
||||
if (!GetClassOfValue(cx, item, &cls))
|
||||
return false;
|
||||
|
||||
/* Step 4b(iii)(5)(c-f). */
|
||||
if (item.isNumber()) {
|
||||
/* Step 4b(iii)(5)(e). */
|
||||
int32_t n;
|
||||
if (ValueFitsInInt32(item, &n) && INT_FITS_IN_JSID(n)) {
|
||||
id = INT_TO_JSID(n);
|
||||
} else {
|
||||
if (!ValueToId<CanGC>(cx, item, &id))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
bool shouldAdd = item.isString();
|
||||
if (!shouldAdd) {
|
||||
ESClass cls;
|
||||
if (!GetClassOfValue(cx, item, &cls))
|
||||
return false;
|
||||
|
||||
shouldAdd = cls == ESClass::String || cls == ESClass::Number;
|
||||
}
|
||||
|
||||
if (shouldAdd) {
|
||||
/* Step 4b(iii)(5)(f). */
|
||||
if (!ValueToId<CanGC>(cx, item, &id))
|
||||
return false;
|
||||
} else {
|
||||
/* Step 4b(iii)(5)(g). */
|
||||
if (cls != ESClass::String && cls != ESClass::Number)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
RootedId id(cx);
|
||||
if (!ValueToId<CanGC>(cx, item, &id))
|
||||
return false;
|
||||
|
||||
/* Step 4b(iii)(5)(g). */
|
||||
auto p = idSet.lookupForAdd(id);
|
||||
if (!p) {
|
||||
|
|
|
@ -49,6 +49,7 @@ using mozilla::AssertedCast;
|
|||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::NumberEqualsInt32;
|
||||
using mozilla::NumberIsInt32;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::Some;
|
||||
|
@ -4669,7 +4670,7 @@ BytecodeEmitter::emitSwitch(ParseNode* pn)
|
|||
}
|
||||
|
||||
int32_t i;
|
||||
if (!NumberIsInt32(caseValue->pn_dval, &i)) {
|
||||
if (!NumberEqualsInt32(caseValue->pn_dval, &i)) {
|
||||
switchOp = JSOP_CONDSWITCH;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -845,7 +845,7 @@ js::math_round_impl(double x)
|
|||
AutoUnsafeCallWithABI unsafe;
|
||||
|
||||
int32_t ignored;
|
||||
if (NumberIsInt32(x, &ignored))
|
||||
if (NumberEqualsInt32(x, &ignored))
|
||||
return x;
|
||||
|
||||
/* Some numbers are so big that adding 0.5 would give the wrong number. */
|
||||
|
@ -862,7 +862,7 @@ js::math_roundf_impl(float x)
|
|||
AutoUnsafeCallWithABI unsafe;
|
||||
|
||||
int32_t ignored;
|
||||
if (NumberIsInt32(x, &ignored))
|
||||
if (NumberEqualsInt32(x, &ignored))
|
||||
return x;
|
||||
|
||||
/* Some numbers are so big that adding 0.5 would give the wrong number. */
|
||||
|
|
|
@ -1282,7 +1282,7 @@ FracNumberToCString(JSContext* cx, ToCStringBuf* cbuf, double d, int base = 10)
|
|||
#ifdef DEBUG
|
||||
{
|
||||
int32_t _;
|
||||
MOZ_ASSERT(!mozilla::NumberIsInt32(d, &_));
|
||||
MOZ_ASSERT(!mozilla::NumberEqualsInt32(d, &_));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1313,7 +1313,7 @@ js::NumberToCString(JSContext* cx, ToCStringBuf* cbuf, double d, int base/* = 10
|
|||
{
|
||||
int32_t i;
|
||||
size_t len;
|
||||
return mozilla::NumberIsInt32(d, &i)
|
||||
return mozilla::NumberEqualsInt32(d, &i)
|
||||
? Int32ToCString(cbuf, i, &len, base)
|
||||
: FracNumberToCString(cx, cbuf, d, base);
|
||||
}
|
||||
|
@ -1322,22 +1322,16 @@ template <AllowGC allowGC>
|
|||
static JSString*
|
||||
NumberToStringWithBase(JSContext* cx, double d, int base)
|
||||
{
|
||||
MOZ_ASSERT(2 <= base && base <= 36);
|
||||
|
||||
ToCStringBuf cbuf;
|
||||
char* numStr;
|
||||
|
||||
/*
|
||||
* Caller is responsible for error reporting. When called from trace,
|
||||
* returning nullptr here will cause us to fall of trace and then retry
|
||||
* from the interpreter (which will report the error).
|
||||
*/
|
||||
if (base < 2 || base > 36)
|
||||
return nullptr;
|
||||
|
||||
JSCompartment* comp = cx->compartment();
|
||||
|
||||
int32_t i;
|
||||
bool isBase10Int = false;
|
||||
if (mozilla::NumberIsInt32(d, &i)) {
|
||||
if (mozilla::NumberEqualsInt32(d, &i)) {
|
||||
isBase10Int = (base == 10);
|
||||
if (isBase10Int && StaticStrings::hasInt(i))
|
||||
return cx->staticStrings().getInt(i);
|
||||
|
@ -1398,7 +1392,7 @@ JSAtom*
|
|||
js::NumberToAtom(JSContext* cx, double d)
|
||||
{
|
||||
int32_t si;
|
||||
if (mozilla::NumberIsInt32(d, &si))
|
||||
if (mozilla::NumberEqualsInt32(d, &si))
|
||||
return Int32ToAtom(cx, si);
|
||||
|
||||
if (JSFlatString* str = LookupDtoaCache(cx, d))
|
||||
|
|
|
@ -201,16 +201,6 @@ num_toString(JSContext* cx, unsigned argc, Value* vp);
|
|||
extern MOZ_MUST_USE bool
|
||||
num_valueOf(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ValueFitsInInt32(const Value& v, int32_t* pi)
|
||||
{
|
||||
if (v.isInt32()) {
|
||||
*pi = v.toInt32();
|
||||
return true;
|
||||
}
|
||||
return v.isDouble() && mozilla::NumberIsInt32(v.toDouble(), pi);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the given value is definitely an index: that is, the value
|
||||
* is a number that's an unsigned 32-bit integer.
|
||||
|
@ -229,7 +219,7 @@ IsDefinitelyIndex(const Value& v, uint32_t* indexp)
|
|||
}
|
||||
|
||||
int32_t i;
|
||||
if (v.isDouble() && mozilla::NumberIsInt32(v.toDouble(), &i) && i >= 0) {
|
||||
if (v.isDouble() && mozilla::NumberEqualsInt32(v.toDouble(), &i) && i >= 0) {
|
||||
*indexp = uint32_t(i);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "vm/JSAtom.h"
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "jsnum.h"
|
||||
|
@ -34,6 +35,22 @@ AtomToId(JSAtom* atom)
|
|||
inline jsid
|
||||
AtomToId(PropertyName* name) = delete;
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
ValueToIntId(const Value& v, jsid* id)
|
||||
{
|
||||
int32_t i;
|
||||
if (v.isInt32())
|
||||
i = v.toInt32();
|
||||
else if (!v.isDouble() || !mozilla::NumberEqualsInt32(v.toDouble(), &i))
|
||||
return false;
|
||||
|
||||
if (!INT_FITS_IN_JSID(i))
|
||||
return false;
|
||||
|
||||
*id = INT_TO_JSID(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ValueToIdPure(const Value& v, jsid* id)
|
||||
{
|
||||
|
@ -45,11 +62,8 @@ ValueToIdPure(const Value& v, jsid* id)
|
|||
return false;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
|
||||
*id = INT_TO_JSID(i);
|
||||
if (ValueToIntId(v, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (v.isSymbol()) {
|
||||
*id = SYMBOL_TO_JSID(v.toSymbol());
|
||||
|
@ -70,11 +84,8 @@ ValueToId(JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType v,
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
int32_t i;
|
||||
if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
|
||||
idp.set(INT_TO_JSID(i));
|
||||
if (ValueToIntId(v, idp.address()))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (v.isSymbol()) {
|
||||
idp.set(SYMBOL_TO_JSID(v.toSymbol()));
|
||||
|
|
Загрузка…
Ссылка в новой задаче