forked from mirrors/gecko-dev
Bug 1816776 - Support initializing SourceText with FrontendContext. r=bthrall
Differential Revision: https://phabricator.services.mozilla.com/D176510
This commit is contained in:
parent
3b979f198c
commit
4230b3e7e5
3 changed files with 108 additions and 22 deletions
|
|
@ -62,13 +62,19 @@ namespace mozilla {
|
|||
union Utf8Unit;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
class FrontendContext;
|
||||
} // namespace js
|
||||
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API AutoStableStringChars;
|
||||
using FrontendContext = js::FrontendContext;
|
||||
|
||||
namespace detail {
|
||||
|
||||
MOZ_COLD extern JS_PUBLIC_API void ReportSourceTooLong(JSContext* cx);
|
||||
MOZ_COLD extern JS_PUBLIC_API void ReportSourceTooLong(JS::FrontendContext* fc);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
|
@ -131,21 +137,12 @@ class SourceText final {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this with source unit data: |char16_t| for UTF-16 source
|
||||
* units, or |Utf8Unit| for UTF-8 source units.
|
||||
*
|
||||
* If |ownership == TakeOwnership|, *this function* takes ownership of
|
||||
* |units|, *even if* this function fails, and you MUST NOT free |units|
|
||||
* yourself. This single-owner-friendly approach reduces risk of leaks on
|
||||
* failure.
|
||||
*
|
||||
* |units| may be null if |unitsLength == 0|; if so, this will silently be
|
||||
* initialized using non-null, unowned units.
|
||||
*/
|
||||
[[nodiscard]] MOZ_IS_CLASS_INIT bool init(JSContext* cx, const Unit* units,
|
||||
size_t unitsLength,
|
||||
SourceOwnership ownership) {
|
||||
private:
|
||||
template <typename ContextT>
|
||||
[[nodiscard]] MOZ_IS_CLASS_INIT bool initImpl(ContextT* context,
|
||||
const Unit* units,
|
||||
size_t unitsLength,
|
||||
SourceOwnership ownership) {
|
||||
MOZ_ASSERT_IF(units == nullptr, unitsLength == 0);
|
||||
|
||||
// Ideally we'd use |Unit| and not cast below, but the risk of a static
|
||||
|
|
@ -169,13 +166,38 @@ class SourceText final {
|
|||
// store offsets in |JSScript|s as |uint32_t|. It could be lifted
|
||||
// fairly easily if desired, as the compiler uses |size_t| internally.
|
||||
if (MOZ_UNLIKELY(unitsLength > UINT32_MAX)) {
|
||||
detail::ReportSourceTooLong(cx);
|
||||
detail::ReportSourceTooLong(context);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initialize this with source unit data: |char16_t| for UTF-16 source
|
||||
* units, or |Utf8Unit| for UTF-8 source units.
|
||||
*
|
||||
* If |ownership == TakeOwnership|, *this function* takes ownership of
|
||||
* |units|, *even if* this function fails, and you MUST NOT free |units|
|
||||
* yourself. This single-owner-friendly approach reduces risk of leaks on
|
||||
* failure.
|
||||
*
|
||||
* |units| may be null if |unitsLength == 0|; if so, this will silently be
|
||||
* initialized using non-null, unowned units.
|
||||
*/
|
||||
[[nodiscard]] MOZ_IS_CLASS_INIT bool init(JSContext* cx, const Unit* units,
|
||||
size_t unitsLength,
|
||||
SourceOwnership ownership) {
|
||||
return initImpl(cx, units, unitsLength, ownership);
|
||||
}
|
||||
[[nodiscard]] MOZ_IS_CLASS_INIT bool init(JS::FrontendContext* fc,
|
||||
const Unit* units,
|
||||
size_t unitsLength,
|
||||
SourceOwnership ownership) {
|
||||
return initImpl(fc, units, unitsLength, ownership);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exactly identical to the |init()| overload above that accepts
|
||||
* |const Unit*|, but instead takes character data: |const CharT*|.
|
||||
|
|
@ -190,8 +212,18 @@ class SourceText final {
|
|||
[[nodiscard]] MOZ_IS_CLASS_INIT bool init(JSContext* cx, const Char* chars,
|
||||
size_t charsLength,
|
||||
SourceOwnership ownership) {
|
||||
return init(cx, reinterpret_cast<const Unit*>(chars), charsLength,
|
||||
ownership);
|
||||
return initImpl(cx, reinterpret_cast<const Unit*>(chars), charsLength,
|
||||
ownership);
|
||||
}
|
||||
template <typename Char,
|
||||
typename = std::enable_if_t<std::is_same_v<Char, CharT> &&
|
||||
!std::is_same_v<Char, Unit>>>
|
||||
[[nodiscard]] MOZ_IS_CLASS_INIT bool init(JS::FrontendContext* fc,
|
||||
const Char* chars,
|
||||
size_t charsLength,
|
||||
SourceOwnership ownership) {
|
||||
return initImpl(fc, reinterpret_cast<const Unit*>(chars), charsLength,
|
||||
ownership);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -200,7 +232,14 @@ class SourceText final {
|
|||
[[nodiscard]] bool init(JSContext* cx,
|
||||
js::UniquePtr<Unit[], JS::FreePolicy> data,
|
||||
size_t dataLength) {
|
||||
return init(cx, data.release(), dataLength, SourceOwnership::TakeOwnership);
|
||||
return initImpl(cx, data.release(), dataLength,
|
||||
SourceOwnership::TakeOwnership);
|
||||
}
|
||||
[[nodiscard]] bool init(JS::FrontendContext* fc,
|
||||
js::UniquePtr<Unit[], JS::FreePolicy> data,
|
||||
size_t dataLength) {
|
||||
return initImpl(fc, data.release(), dataLength,
|
||||
SourceOwnership::TakeOwnership);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -220,6 +259,14 @@ class SourceText final {
|
|||
size_t dataLength) {
|
||||
return init(cx, data.release(), dataLength, SourceOwnership::TakeOwnership);
|
||||
}
|
||||
template <typename Char,
|
||||
typename = std::enable_if_t<std::is_same_v<Char, CharT> &&
|
||||
!std::is_same_v<Char, Unit>>>
|
||||
[[nodiscard]] bool init(JS::FrontendContext* fc,
|
||||
js::UniquePtr<Char[], JS::FreePolicy> data,
|
||||
size_t dataLength) {
|
||||
return init(fc, data.release(), dataLength, SourceOwnership::TakeOwnership);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this using an AutoStableStringChars. Transfers the code units if
|
||||
|
|
@ -230,6 +277,8 @@ class SourceText final {
|
|||
*/
|
||||
[[nodiscard]] bool initMaybeBorrowed(JSContext* cx,
|
||||
AutoStableStringChars& linearChars);
|
||||
[[nodiscard]] bool initMaybeBorrowed(JS::FrontendContext* fc,
|
||||
AutoStableStringChars& linearChars);
|
||||
|
||||
/**
|
||||
* Access the encapsulated data using a code unit type.
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@
|
|||
#include "util/CompleteFile.h" // js::FileContents, js::ReadCompleteFile
|
||||
#include "util/StringBuffer.h" // js::StringBuffer
|
||||
#include "vm/EnvironmentObject.h" // js::CreateNonSyntacticEnvironmentChain
|
||||
#include "vm/Interpreter.h" // js::Execute
|
||||
#include "vm/JSContext.h" // JSContext
|
||||
#include "vm/ErrorReporting.h" // js::ErrorMetadata, js::ReportCompileErrorLatin1
|
||||
#include "vm/Interpreter.h" // js::Execute
|
||||
#include "vm/JSContext.h" // JSContext
|
||||
|
||||
#include "vm/JSContext-inl.h" // JSContext::check
|
||||
|
||||
|
|
@ -56,6 +57,28 @@ JS_PUBLIC_API void JS::detail::ReportSourceTooLong(JSContext* cx) {
|
|||
JSMSG_SOURCE_TOO_LONG);
|
||||
}
|
||||
|
||||
static void ReportSourceTooLongImpl(JS::FrontendContext* fc, ...) {
|
||||
va_list args;
|
||||
va_start(args, fc);
|
||||
|
||||
js::ErrorMetadata metadata;
|
||||
metadata.filename = "<unknown>";
|
||||
metadata.lineNumber = 0;
|
||||
metadata.columnNumber = 0;
|
||||
metadata.lineLength = 0;
|
||||
metadata.tokenOffset = 0;
|
||||
metadata.isMuted = false;
|
||||
|
||||
js::ReportCompileErrorLatin1(fc, std::move(metadata), nullptr,
|
||||
JSMSG_SOURCE_TOO_LONG, &args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void JS::detail::ReportSourceTooLong(JS::FrontendContext* fc) {
|
||||
ReportSourceTooLongImpl(fc);
|
||||
}
|
||||
|
||||
template <typename Unit>
|
||||
static JSScript* CompileSourceBuffer(JSContext* cx,
|
||||
const ReadOnlyCompileOptions& options,
|
||||
|
|
|
|||
|
|
@ -1457,7 +1457,21 @@ bool JS::SourceText<char16_t>::initMaybeBorrowed(
|
|||
JS::SourceOwnership ownership = linearChars.maybeGiveOwnershipToCaller()
|
||||
? JS::SourceOwnership::TakeOwnership
|
||||
: JS::SourceOwnership::Borrowed;
|
||||
return init(cx, chars, length, ownership);
|
||||
return initImpl(cx, chars, length, ownership);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool JS::SourceText<char16_t>::initMaybeBorrowed(
|
||||
JS::FrontendContext* fc, JS::AutoStableStringChars& linearChars) {
|
||||
MOZ_ASSERT(linearChars.isTwoByte(),
|
||||
"AutoStableStringChars must be initialized with char16_t");
|
||||
|
||||
const char16_t* chars = linearChars.twoByteChars();
|
||||
size_t length = linearChars.length();
|
||||
JS::SourceOwnership ownership = linearChars.maybeGiveOwnershipToCaller()
|
||||
? JS::SourceOwnership::TakeOwnership
|
||||
: JS::SourceOwnership::Borrowed;
|
||||
return initImpl(fc, chars, length, ownership);
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_CACHEIR_SPEW)
|
||||
|
|
|
|||
Loading…
Reference in a new issue