зеркало из https://github.com/mozilla/gecko-dev.git
Bug 695438 - Allow all integers in StringIsTypedArrayIndex, r=luke.
This commit is contained in:
Родитель
605cb7f12d
Коммит
0888f9f9a1
|
@ -14,11 +14,18 @@ function f() {
|
|||
}
|
||||
f();
|
||||
|
||||
// Integers which don't fit in a double value's mantissa aren't really integers.
|
||||
// Really big integers not representable with a double or uint64 are still integers.
|
||||
|
||||
var bigint = "" + Math.pow(2, 53);
|
||||
x[bigint] = "twelve";
|
||||
assertEq(x[bigint], "twelve");
|
||||
assertEq(x[bigint], undefined);
|
||||
|
||||
x["9999999999999999999999"] = "twelve";
|
||||
assertEq(x["9999999999999999999999"], undefined);
|
||||
|
||||
// Except when their toString() makes them not look like integers!
|
||||
x[9999999999999999999999] = "twelve";
|
||||
assertEq(x[9999999999999999999999], "twelve");
|
||||
|
||||
// Infinity and -Infinity maybe are supposed to be integers, but they aren't currently.
|
||||
|
||||
|
|
|
@ -66,9 +66,9 @@ for (constructor of constructors) {
|
|||
a[-10 >>> 0] = "twelve";
|
||||
assertEq(a[-10 >>> 0], undefined);
|
||||
|
||||
// Watch for overly large indexed properties.
|
||||
// Watch for really large indexed properties too.
|
||||
a[Math.pow(2, 53)] = "twelve";
|
||||
assertEq(a[Math.pow(2, 53)], "twelve");
|
||||
assertEq(a[Math.pow(2, 53)], undefined);
|
||||
|
||||
// Don't define old properties.
|
||||
Object.defineProperty(a, 5, {value: 3});
|
||||
|
|
|
@ -3760,7 +3760,7 @@ DefinePropertyOrElement(typename ExecutionModeTraits<mode>::ExclusiveContextType
|
|||
|
||||
// Don't define new indexed properties on typed arrays.
|
||||
if (obj->is<TypedArrayObject>()) {
|
||||
double index;
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index))
|
||||
return true;
|
||||
}
|
||||
|
@ -4002,9 +4002,9 @@ LookupOwnPropertyWithFlagsInline(ExclusiveContext *cx,
|
|||
// so that integer properties on the prototype are ignored even for out
|
||||
// of bounds accesses.
|
||||
if (obj->template is<TypedArrayObject>()) {
|
||||
double index;
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index)) {
|
||||
if (index >= 0 && index < obj->template as<TypedArrayObject>().length()) {
|
||||
if (index < obj->template as<TypedArrayObject>().length()) {
|
||||
objp.set(obj);
|
||||
MarkDenseOrTypedArrayElementFound<allowGC>(propp);
|
||||
}
|
||||
|
@ -4595,9 +4595,9 @@ LookupPropertyPureInline(JSObject *obj, jsid id, JSObject **objp, Shape **propp)
|
|||
}
|
||||
|
||||
if (current->is<TypedArrayObject>()) {
|
||||
double index;
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index)) {
|
||||
if (index >= 0 && index < obj->as<TypedArrayObject>().length()) {
|
||||
if (index < obj->as<TypedArrayObject>().length()) {
|
||||
*objp = current;
|
||||
MarkDenseOrTypedArrayElementFound<NoGC>(propp);
|
||||
} else {
|
||||
|
|
|
@ -2500,12 +2500,8 @@ js::AsTypedArrayBuffer(HandleValue v)
|
|||
}
|
||||
|
||||
bool
|
||||
js::StringIsTypedArrayIndex(JSLinearString *str, double *indexp)
|
||||
js::StringIsTypedArrayIndex(JSLinearString *str, uint64_t *indexp)
|
||||
{
|
||||
// Largest double (2^53 - 1) which can be exactly represented in the
|
||||
// mantissa of a double.
|
||||
static const double MAX_INTEGER = 9007199254740991;
|
||||
|
||||
const jschar *s = str->chars();
|
||||
const jschar *end = s + str->length();
|
||||
|
||||
|
@ -2522,7 +2518,7 @@ js::StringIsTypedArrayIndex(JSLinearString *str, double *indexp)
|
|||
if (!JS7_ISDEC(*s))
|
||||
return false;
|
||||
|
||||
double index = 0;
|
||||
uint64_t index = 0;
|
||||
uint32_t digit = JS7_UNDEC(*s++);
|
||||
|
||||
/* Don't allow leading zeros. */
|
||||
|
@ -2537,17 +2533,17 @@ js::StringIsTypedArrayIndex(JSLinearString *str, double *indexp)
|
|||
|
||||
digit = JS7_UNDEC(*s);
|
||||
|
||||
/* Watch for mantissa overflows. */
|
||||
if ((MAX_INTEGER - digit) / 10 < index)
|
||||
return false;
|
||||
|
||||
index = 10 * index + digit;
|
||||
/* Watch for overflows. */
|
||||
if ((UINT64_MAX - digit) / 10 < index)
|
||||
index = UINT64_MAX;
|
||||
else
|
||||
index = 10 * index + digit;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
index = -index;
|
||||
|
||||
*indexp = index;
|
||||
*indexp = UINT64_MAX;
|
||||
else
|
||||
*indexp = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,11 +140,14 @@ IsTypedArrayBuffer(HandleValue v);
|
|||
ArrayBufferObject &
|
||||
AsTypedArrayBuffer(HandleValue v);
|
||||
|
||||
// Return value is whether the string is some integer. If the string is an
|
||||
// integer which is not representable as a uint64_t, the return value is true
|
||||
// and the resulting index is UINT64_MAX.
|
||||
bool
|
||||
StringIsTypedArrayIndex(JSLinearString *str, double *indexp);
|
||||
StringIsTypedArrayIndex(JSLinearString *str, uint64_t *indexp);
|
||||
|
||||
inline bool
|
||||
IsTypedArrayIndex(jsid id, double *indexp)
|
||||
IsTypedArrayIndex(jsid id, uint64_t *indexp)
|
||||
{
|
||||
if (JSID_IS_INT(id)) {
|
||||
int32_t i = JSID_TO_INT(id);
|
||||
|
@ -156,7 +159,13 @@ IsTypedArrayIndex(jsid id, double *indexp)
|
|||
if (MOZ_UNLIKELY(!JSID_IS_STRING(id)))
|
||||
return false;
|
||||
|
||||
return StringIsTypedArrayIndex(JSID_TO_ATOM(id), indexp);
|
||||
JSAtom *atom = JSID_TO_ATOM(id);
|
||||
|
||||
jschar c = atom->chars()[0];
|
||||
if (!JS7_ISDEC(c) && c != '-')
|
||||
return false;
|
||||
|
||||
return StringIsTypedArrayIndex(atom, indexp);
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
|
|
Загрузка…
Ссылка в новой задаче