tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 6c8aca084c9078fe3f1f260e3d4fdcbaefa1e9a4
parent 5c1c817d7d025ae8796c1ccdc195f0109ae1a6ea
Author: André Bargull <andre.bargull@gmail.com>
Date:   Mon, 13 Oct 2025 12:55:23 +0000

Bug 1990248 - Part 1: Add IndexToId with uint64_t argument. r=spidermonkey-reviewers,jandem

Also used in part 2.

Differential Revision: https://phabricator.services.mozilla.com/D265823

Diffstat:
Mjs/src/builtin/Array.cpp | 36+++++++-----------------------------
Mjs/src/vm/JSAtomUtils-inl.h | 13+++++++++++++
Mjs/src/vm/JSAtomUtils.cpp | 22++++++++++++++++++++++
Mjs/src/vm/NativeObject.cpp | 2+-
Mjs/src/vm/ObjectOperations-inl.h | 14++++----------
5 files changed, 47 insertions(+), 40 deletions(-)

diff --git a/js/src/builtin/Array.cpp b/js/src/builtin/Array.cpp @@ -259,27 +259,6 @@ JS_PUBLIC_API bool js::StringIsArrayIndex(const char16_t* str, uint32_t length, return true; } -template <typename T> -static bool ToId(JSContext* cx, T index, MutableHandleId id); - -template <> -bool ToId(JSContext* cx, uint32_t index, MutableHandleId id) { - return IndexToId(cx, index, id); -} - -template <> -bool ToId(JSContext* cx, uint64_t index, MutableHandleId id) { - MOZ_ASSERT(index < uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)); - - if (index == uint32_t(index)) { - return IndexToId(cx, uint32_t(index), id); - } - - Value tmp = DoubleValue(index); - return PrimitiveValueToId<CanGC>(cx, HandleValue::fromMarkedLocation(&tmp), - id); -} - /* * If the property at the given index exists, get its value into |vp| and set * |*hole| to false. Otherwise set |*hole| to true and |vp| to Undefined. @@ -306,7 +285,7 @@ static bool HasAndGetElement(JSContext* cx, HandleObject obj, } RootedId id(cx); - if (!ToId(cx, index, &id)) { + if (!IndexToId(cx, index, &id)) { return false; } @@ -475,7 +454,7 @@ static inline bool GetArrayElement(JSContext* cx, HandleObject obj, } RootedId id(cx); - if (!ToId(cx, index, &id)) { + if (!IndexToId(cx, index, &id)) { return false; } return GetProperty(cx, obj, obj, id, vp); @@ -484,7 +463,7 @@ static inline bool GetArrayElement(JSContext* cx, HandleObject obj, static inline bool DefineArrayElement(JSContext* cx, HandleObject obj, uint64_t index, HandleValue value) { RootedId id(cx); - if (!ToId(cx, index, &id)) { + if (!IndexToId(cx, index, &id)) { return false; } return DefineDataProperty(cx, obj, id, value); @@ -494,10 +473,9 @@ static inline bool DefineArrayElement(JSContext* cx, HandleObject obj, static inline bool SetArrayElement(JSContext* cx, HandleObject obj, uint64_t index, HandleValue v) { RootedId id(cx); - if (!ToId(cx, index, &id)) { + if (!IndexToId(cx, index, &id)) { return false; } - return SetProperty(cx, obj, id, v); } @@ -536,7 +514,7 @@ static bool DeleteArrayElement(JSContext* cx, HandleObject obj, uint64_t index, } RootedId id(cx); - if (!ToId(cx, index, &id)) { + if (!IndexToId(cx, index, &id)) { return false; } return DeleteProperty(cx, obj, id, result); @@ -551,7 +529,7 @@ static bool DeletePropertyOrThrow(JSContext* cx, HandleObject obj, } if (!success) { RootedId id(cx); - if (!ToId(cx, index, &id)) { + if (!IndexToId(cx, index, &id)) { return false; } return success.reportError(cx, obj, id); @@ -1586,7 +1564,7 @@ static bool SetArrayElements(JSContext* cx, HandleObject obj, uint64_t start, return false; } - if (!ToId(cx, start++, &id)) { + if (!IndexToId(cx, start++, &id)) { return false; } diff --git a/js/src/vm/JSAtomUtils-inl.h b/js/src/vm/JSAtomUtils-inl.h @@ -82,6 +82,19 @@ inline bool IndexToId(JSContext* cx, uint32_t index, MutableHandleId idp) { return IndexToIdSlow(cx, index, idp); } +bool IndexToIdSlow(JSContext* cx, uint64_t index, MutableHandleId idp); + +inline bool IndexToId(JSContext* cx, uint64_t index, MutableHandleId idp) { + MOZ_ASSERT(index < uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)); + + if (index <= PropertyKey::IntMax) { + idp.set(PropertyKey::Int(index)); + return true; + } + + return IndexToIdSlow(cx, index, idp); +} + static MOZ_ALWAYS_INLINE JSLinearString* IdToString( JSContext* cx, jsid id, gc::Heap heap = gc::Heap::Default) { if (id.isString()) { diff --git a/js/src/vm/JSAtomUtils.cpp b/js/src/vm/JSAtomUtils.cpp @@ -916,6 +916,28 @@ bool js::IndexToIdSlow(JSContext* cx, uint32_t index, MutableHandleId idp) { return true; } +bool js::IndexToIdSlow(JSContext* cx, uint64_t index, MutableHandleId idp) { + MOZ_ASSERT(index > JS::PropertyKey::IntMax); + + // Plus one to include the largest number. + constexpr size_t UINT64_CHAR_BUFFER_LENGTH = + std::numeric_limits<uint64_t>::digits10 + 1; + + char buf[UINT64_CHAR_BUFFER_LENGTH]; + + auto result = std::to_chars(buf, buf + std::size(buf), index, 10); + MOZ_ASSERT(result.ec == std::errc()); + + size_t length = result.ptr - buf; + JSAtom* atom = Atomize(cx, buf, length); + if (!atom) { + return false; + } + + idp.set(JS::PropertyKey::NonIntAtom(atom)); + return true; +} + template <AllowGC allowGC> static MOZ_ALWAYS_INLINE JSAtom* PrimitiveToAtom(JSContext* cx, const Value& v) { diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp @@ -2356,7 +2356,7 @@ bool js::NativeGetElement(JSContext* cx, Handle<NativeObject*> obj, RootedId id(cx); if (MOZ_LIKELY(index >= 0)) { - if (!IndexToId(cx, index, &id)) { + if (!IndexToId(cx, uint32_t(index), &id)) { return false; } } else { diff --git a/js/src/vm/ObjectOperations-inl.h b/js/src/vm/ObjectOperations-inl.h @@ -155,19 +155,13 @@ inline bool GetElement(JSContext* cx, JS::Handle<JSObject*> obj, inline bool GetElementLargeIndex(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JSObject*> receiver, uint64_t index, JS::MutableHandle<JS::Value> vp) { - MOZ_ASSERT(index < uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)); - - if (MOZ_LIKELY(index <= UINT32_MAX)) { - return GetElement(cx, obj, receiver, uint32_t(index), vp); - } - - RootedValue tmp(cx, DoubleValue(index)); - RootedId id(cx); - if (!PrimitiveValueToId<CanGC>(cx, tmp, &id)) { + JS::Rooted<jsid> id(cx); + if (!IndexToId(cx, index, &id)) { return false; } - return GetProperty(cx, obj, obj, id, vp); + JS::Rooted<JS::Value> receiverValue(cx, JS::ObjectValue(*receiver)); + return GetProperty(cx, obj, receiverValue, id, vp); } inline bool GetPropertyNoGC(JSContext* cx, JSObject* obj,