зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1771874 part 3 - Make ToTypedArrayIndex infallible, remove unused cx argument. r=anba
Differential Revision: https://phabricator.services.mozilla.com/D147736
This commit is contained in:
Родитель
ec2cbc67fd
Коммит
937265d1ac
|
@ -704,15 +704,7 @@ static MOZ_ALWAYS_INLINE bool NativeLookupOwnPropertyInline(
|
|||
// so that integer properties on the prototype are ignored even for out
|
||||
// of bounds accesses.
|
||||
if (obj->template is<TypedArrayObject>()) {
|
||||
mozilla::Maybe<uint64_t> index;
|
||||
if (!ToTypedArrayIndex(cx, id, &index)) {
|
||||
if (!allowGC) {
|
||||
cx->recoverFromOutOfMemory();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index.isSome()) {
|
||||
if (mozilla::Maybe<uint64_t> index = ToTypedArrayIndex(id)) {
|
||||
uint64_t idx = index.value();
|
||||
if (idx < obj->template as<TypedArrayObject>().length()) {
|
||||
propp->setTypedArrayElement(idx);
|
||||
|
|
|
@ -1443,14 +1443,9 @@ bool js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj,
|
|||
}
|
||||
} else if (obj->is<TypedArrayObject>()) {
|
||||
// 9.4.5.3 step 3. Indexed properties of typed arrays are special.
|
||||
Rooted<TypedArrayObject*> tobj(cx, &obj->as<TypedArrayObject>());
|
||||
mozilla::Maybe<uint64_t> index;
|
||||
if (!ToTypedArrayIndex(cx, id, &index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index) {
|
||||
if (mozilla::Maybe<uint64_t> index = ToTypedArrayIndex(id)) {
|
||||
MOZ_ASSERT(!cx->isHelperThreadContext());
|
||||
Rooted<TypedArrayObject*> tobj(cx, &obj->as<TypedArrayObject>());
|
||||
return DefineTypedArrayElement(cx, tobj, index.value(), desc_, result);
|
||||
}
|
||||
} else if (obj->is<ArgumentsObject>()) {
|
||||
|
@ -1741,12 +1736,7 @@ static bool DefineNonexistentProperty(JSContext* cx, HandleNativeObject obj,
|
|||
}
|
||||
} else if (obj->is<TypedArrayObject>()) {
|
||||
// 9.4.5.5 step 2. Indexed properties of typed arrays are special.
|
||||
mozilla::Maybe<uint64_t> index;
|
||||
if (!ToTypedArrayIndex(cx, id, &index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index) {
|
||||
if (mozilla::Maybe<uint64_t> index = ToTypedArrayIndex(id)) {
|
||||
// This method is only called for non-existent properties, which
|
||||
// means any absent indexed property must be out of range.
|
||||
MOZ_ASSERT(index.value() >= obj->as<TypedArrayObject>().length());
|
||||
|
|
|
@ -2468,9 +2468,8 @@ static inline bool StringIsNaN(mozilla::Range<const CharT> s) {
|
|||
}
|
||||
|
||||
template <typename CharT>
|
||||
static bool StringToTypedArrayIndexSlow(JSContext* cx,
|
||||
mozilla::Range<const CharT> s,
|
||||
mozilla::Maybe<uint64_t>* indexp) {
|
||||
static mozilla::Maybe<uint64_t> StringToTypedArrayIndexSlow(
|
||||
mozilla::Range<const CharT> s) {
|
||||
const mozilla::RangedPtr<const CharT> start = s.begin();
|
||||
const mozilla::RangedPtr<const CharT> end = s.end();
|
||||
|
||||
|
@ -2479,8 +2478,7 @@ static bool StringToTypedArrayIndexSlow(JSContext* cx,
|
|||
|
||||
// The complete string must have been parsed.
|
||||
if (actualEnd != end.get()) {
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
// Now convert it back to a string.
|
||||
|
@ -2491,8 +2489,7 @@ static bool StringToTypedArrayIndexSlow(JSContext* cx,
|
|||
// Both strings must be equal for a canonical numeric index string.
|
||||
if (s.length() != strlen(cstr) ||
|
||||
!EqualChars(start.get(), cstr, s.length())) {
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
// Directly perform IsInteger() check and encode negative and non-integer
|
||||
|
@ -2502,25 +2499,22 @@ static bool StringToTypedArrayIndexSlow(JSContext* cx,
|
|||
// See 9.4.5.8 IntegerIndexedElementGet, steps 5 and 8.
|
||||
// See 9.4.5.9 IntegerIndexedElementSet, steps 6 and 9.
|
||||
if (result < 0 || !IsInteger(result)) {
|
||||
indexp->emplace(UINT64_MAX);
|
||||
return true;
|
||||
return mozilla::Some(UINT64_MAX);
|
||||
}
|
||||
|
||||
// Anything equals-or-larger than 2^53 is definitely OOB, encode it
|
||||
// accordingly so that the cast to uint64_t is well defined.
|
||||
if (result >= DOUBLE_INTEGRAL_PRECISION_LIMIT) {
|
||||
indexp->emplace(UINT64_MAX);
|
||||
return true;
|
||||
return mozilla::Some(UINT64_MAX);
|
||||
}
|
||||
|
||||
// The string is an actual canonical numeric index.
|
||||
indexp->emplace(result);
|
||||
return true;
|
||||
return mozilla::Some(result);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
|
||||
mozilla::Maybe<uint64_t>* indexp) {
|
||||
mozilla::Maybe<uint64_t> js::StringToTypedArrayIndex(
|
||||
mozilla::Range<const CharT> s) {
|
||||
mozilla::RangedPtr<const CharT> cp = s.begin();
|
||||
const mozilla::RangedPtr<const CharT> end = s.end();
|
||||
|
||||
|
@ -2530,8 +2524,7 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
|
|||
if (*cp == '-') {
|
||||
negative = true;
|
||||
if (++cp == end) {
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2539,11 +2532,9 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
|
|||
// Check for "NaN", "Infinity", or "-Infinity".
|
||||
if ((!negative && StringIsNaN<CharT>({cp, end})) ||
|
||||
StringIsInfinity<CharT>({cp, end})) {
|
||||
indexp->emplace(UINT64_MAX);
|
||||
} else {
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return mozilla::Some(UINT64_MAX);
|
||||
}
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
uint32_t digit = AsciiDigitToNumber(*cp++);
|
||||
|
@ -2553,10 +2544,9 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
|
|||
// The string may be of the form "0.xyz". The exponent form isn't possible
|
||||
// when the string starts with "0".
|
||||
if (*cp == '.') {
|
||||
return StringToTypedArrayIndexSlow(cx, s, indexp);
|
||||
return StringToTypedArrayIndexSlow(s);
|
||||
}
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
uint64_t index = digit;
|
||||
|
@ -2565,10 +2555,9 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
|
|||
if (!IsAsciiDigit(*cp)) {
|
||||
// Take the slow path when the string has fractional parts or an exponent.
|
||||
if (*cp == '.' || *cp == 'e') {
|
||||
return StringToTypedArrayIndexSlow(cx, s, indexp);
|
||||
return StringToTypedArrayIndexSlow(s);
|
||||
}
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
digit = AsciiDigitToNumber(*cp);
|
||||
|
@ -2581,25 +2570,21 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
|
|||
|
||||
// Also take the slow path when the string is larger-or-equals 2^53.
|
||||
if (index >= uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)) {
|
||||
return StringToTypedArrayIndexSlow(cx, s, indexp);
|
||||
return StringToTypedArrayIndexSlow(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
indexp->emplace(UINT64_MAX);
|
||||
} else {
|
||||
indexp->emplace(index);
|
||||
return mozilla::Some(UINT64_MAX);
|
||||
}
|
||||
return true;
|
||||
return mozilla::Some(index);
|
||||
}
|
||||
|
||||
template bool js::StringToTypedArrayIndex(JSContext* cx,
|
||||
mozilla::Range<const char16_t> s,
|
||||
mozilla::Maybe<uint64_t>* indexOut);
|
||||
template mozilla::Maybe<uint64_t> js::StringToTypedArrayIndex(
|
||||
mozilla::Range<const char16_t> s);
|
||||
|
||||
template bool js::StringToTypedArrayIndex(JSContext* cx,
|
||||
mozilla::Range<const Latin1Char> s,
|
||||
mozilla::Maybe<uint64_t>* indexOut);
|
||||
template mozilla::Maybe<uint64_t> js::StringToTypedArrayIndex(
|
||||
mozilla::Range<const Latin1Char> s);
|
||||
|
||||
bool js::SetTypedArrayElement(JSContext* cx, Handle<TypedArrayObject*> obj,
|
||||
uint64_t index, HandleValue v,
|
||||
|
|
|
@ -220,9 +220,7 @@ inline size_t TypedArrayObject::bytesPerElement() const {
|
|||
// string is a canonical numeric index which is not representable as a uint64_t,
|
||||
// the returned index is UINT64_MAX.
|
||||
template <typename CharT>
|
||||
[[nodiscard]] bool StringToTypedArrayIndex(JSContext* cx,
|
||||
mozilla::Range<const CharT> s,
|
||||
mozilla::Maybe<uint64_t>* indexp);
|
||||
mozilla::Maybe<uint64_t> StringToTypedArrayIndex(mozilla::Range<const CharT> s);
|
||||
|
||||
// A string |s| is a TypedArray index (or: canonical numeric index string) iff
|
||||
// |s| is "-0" or |SameValue(ToString(ToNumber(s)), s)| is true. So check for
|
||||
|
@ -233,35 +231,31 @@ inline bool CanStartTypedArrayIndex(CharT ch) {
|
|||
return mozilla::IsAsciiDigit(ch) || ch == '-' || ch == 'N' || ch == 'I';
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool ToTypedArrayIndex(JSContext* cx, jsid id,
|
||||
mozilla::Maybe<uint64_t>* indexp) {
|
||||
[[nodiscard]] inline mozilla::Maybe<uint64_t> ToTypedArrayIndex(jsid id) {
|
||||
if (id.isInt()) {
|
||||
int32_t i = id.toInt();
|
||||
MOZ_ASSERT(i >= 0);
|
||||
indexp->emplace(i);
|
||||
return true;
|
||||
return mozilla::Some(i);
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(!id.isString())) {
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
JSAtom* atom = id.toAtom();
|
||||
|
||||
if (atom->empty() || !CanStartTypedArrayIndex(atom->latin1OrTwoByteChar(0))) {
|
||||
MOZ_ASSERT(indexp->isNothing());
|
||||
return true;
|
||||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
if (atom->hasLatin1Chars()) {
|
||||
mozilla::Range<const Latin1Char> chars = atom->latin1Range(nogc);
|
||||
return StringToTypedArrayIndex(cx, chars, indexp);
|
||||
return StringToTypedArrayIndex(chars);
|
||||
}
|
||||
|
||||
mozilla::Range<const char16_t> chars = atom->twoByteRange(nogc);
|
||||
return StringToTypedArrayIndex(cx, chars, indexp);
|
||||
return StringToTypedArrayIndex(chars);
|
||||
}
|
||||
|
||||
bool SetTypedArrayElement(JSContext* cx, Handle<TypedArrayObject*> obj,
|
||||
|
|
Загрузка…
Ссылка в новой задаче