mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-07 11:56:51 +00:00
Bug 1773324 - Replace ErrorReporting allocator with ErrorAllocator r=arai
ErrorAllocator is an adapter that allows MallocProvider to delegate to polymorphic Contexts. MallocProvider provides a well-known interface, but doesn't support polymorphism, so we resort to templating and adapters like this. JS::CharsToNewUTF8CharsZ() needs a definition in CharacterEncoding.cpp, so for now I explicitly instantiate it for ErrorAllocator<JSContext>. A better solution would be to move the definition to a header, but that's a bigger task. Differential Revision: https://phabricator.services.mozilla.com/D151179
This commit is contained in:
parent
29bcf1e310
commit
43ad49bda4
@ -235,8 +235,8 @@ inline Latin1CharsZ LossyTwoByteCharsToNewLatin1CharsZ(JSContext* cx,
|
||||
return JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
extern UTF8CharsZ CharsToNewUTF8CharsZ(JSContext* cx,
|
||||
template <typename CharT, typename Allocator>
|
||||
extern UTF8CharsZ CharsToNewUTF8CharsZ(Allocator* alloc,
|
||||
const mozilla::Range<CharT> chars);
|
||||
|
||||
JS_PUBLIC_API uint32_t Utf8ToOneUcs4Char(const uint8_t* utf8Buffer,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
|
||||
#include "util/StringBuffer.h"
|
||||
#include "util/Unicode.h" // unicode::REPLACEMENT_CHARACTER
|
||||
#include "vm/ErrorContext.h"
|
||||
#include "vm/JSContext.h"
|
||||
|
||||
using mozilla::AsChars;
|
||||
@ -133,15 +134,15 @@ void ConvertToUTF8<const Latin1Char>(mozilla::Span<const Latin1Char> src,
|
||||
(void)ConvertLatin1toUtf8Partial(AsChars(src), dst);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
UTF8CharsZ JS::CharsToNewUTF8CharsZ(JSContext* cx,
|
||||
template <typename CharT, typename Allocator>
|
||||
UTF8CharsZ JS::CharsToNewUTF8CharsZ(Allocator* alloc,
|
||||
const mozilla::Range<CharT> chars) {
|
||||
/* Get required buffer size. */
|
||||
const CharT* str = chars.begin().get();
|
||||
size_t len = ::GetDeflatedUTF8StringLength(str, chars.length());
|
||||
|
||||
/* Allocate buffer. */
|
||||
char* utf8 = cx->pod_malloc<char>(len + 1);
|
||||
char* utf8 = alloc->template pod_malloc<char>(len + 1);
|
||||
if (!utf8) {
|
||||
return UTF8CharsZ();
|
||||
}
|
||||
@ -165,6 +166,19 @@ template UTF8CharsZ JS::CharsToNewUTF8CharsZ(
|
||||
template UTF8CharsZ JS::CharsToNewUTF8CharsZ(
|
||||
JSContext* cx, const mozilla::Range<const char16_t> chars);
|
||||
|
||||
template UTF8CharsZ JS::CharsToNewUTF8CharsZ(
|
||||
ErrorAllocator<JSContext>* cx, const mozilla::Range<Latin1Char> chars);
|
||||
|
||||
template UTF8CharsZ JS::CharsToNewUTF8CharsZ(
|
||||
ErrorAllocator<JSContext>* cx, const mozilla::Range<char16_t> chars);
|
||||
|
||||
template UTF8CharsZ JS::CharsToNewUTF8CharsZ(
|
||||
ErrorAllocator<JSContext>* cx,
|
||||
const mozilla::Range<const Latin1Char> chars);
|
||||
|
||||
template UTF8CharsZ JS::CharsToNewUTF8CharsZ(
|
||||
ErrorAllocator<JSContext>* cx, const mozilla::Range<const char16_t> chars);
|
||||
|
||||
static const uint32_t INVALID_UTF8 = UINT32_MAX;
|
||||
|
||||
/*
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define vm_ErrorContext_h
|
||||
|
||||
#include "vm/ErrorReporting.h"
|
||||
#include "vm/MallocProvider.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -24,6 +25,9 @@ class ErrorContext {
|
||||
public:
|
||||
virtual ~ErrorContext() = default;
|
||||
virtual bool addPendingError(js::CompileError** error) = 0;
|
||||
virtual void* onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
|
||||
size_t nbytes, void* reallocPtr = nullptr) = 0;
|
||||
virtual void reportAllocationOverflow() = 0;
|
||||
|
||||
virtual void reportError(js::CompileError* err) = 0;
|
||||
virtual void reportWarning(js::CompileError* err) = 0;
|
||||
@ -42,6 +46,10 @@ class GeneralErrorContext : public ErrorContext {
|
||||
explicit GeneralErrorContext(JSContext* cx);
|
||||
|
||||
bool addPendingError(js::CompileError** error) override;
|
||||
virtual void* onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
|
||||
size_t nbytes,
|
||||
void* reallocPtr = nullptr) override;
|
||||
virtual void reportAllocationOverflow() override;
|
||||
|
||||
virtual void reportError(js::CompileError* err) override;
|
||||
virtual void reportWarning(js::CompileError* err) override;
|
||||
@ -61,6 +69,9 @@ class OffThreadErrorContext : public ErrorContext {
|
||||
public:
|
||||
OffThreadErrorContext() : alloc_(nullptr) {}
|
||||
bool addPendingError(js::CompileError** error) override;
|
||||
void* onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
|
||||
size_t nbytes, void* reallocPtr = nullptr) override;
|
||||
void reportAllocationOverflow() override;
|
||||
|
||||
virtual void reportError(js::CompileError* err) override;
|
||||
virtual void reportWarning(js::CompileError* err) override;
|
||||
@ -78,6 +89,21 @@ class OffThreadErrorContext : public ErrorContext {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
class ErrorAllocator : public MallocProvider<ErrorAllocator<Context>> {
|
||||
private:
|
||||
Context* context_;
|
||||
|
||||
public:
|
||||
explicit ErrorAllocator(Context* ec) : context_(ec) {}
|
||||
|
||||
void* onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
|
||||
size_t nbytes, void* reallocPtr = nullptr) {
|
||||
return context_->onOutOfMemory(allocFunc, arena, nbytes, reallocPtr);
|
||||
}
|
||||
void reportAllocationOverflow() { context_->reportAllocationOverflow(); }
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif /* vm_ErrorContext_h */
|
||||
|
@ -31,6 +31,15 @@ using JS::UniqueTwoByteChars;
|
||||
GeneralErrorContext::GeneralErrorContext(JSContext* cx) : cx_(cx) {}
|
||||
|
||||
bool GeneralErrorContext::addPendingError(CompileError** error) { return true; }
|
||||
void* GeneralErrorContext::onOutOfMemory(js::AllocFunction allocFunc,
|
||||
arena_id_t arena, size_t nbytes,
|
||||
void* reallocPtr) {
|
||||
return cx_->onOutOfMemory(allocFunc, arena, nbytes, reallocPtr);
|
||||
}
|
||||
|
||||
void GeneralErrorContext::reportAllocationOverflow() {
|
||||
return cx_->reportAllocationOverflow();
|
||||
}
|
||||
|
||||
void GeneralErrorContext::reportError(CompileError* err) {
|
||||
// On the main thread, report the error immediately.
|
||||
@ -76,6 +85,17 @@ bool OffThreadErrorContext::addPendingError(CompileError** error) {
|
||||
*error = errors_.errors.back().get();
|
||||
return true;
|
||||
}
|
||||
void* OffThreadErrorContext::onOutOfMemory(js::AllocFunction allocFunc,
|
||||
arena_id_t arena, size_t nbytes,
|
||||
void* reallocPtr) {
|
||||
addPendingOutOfMemory();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OffThreadErrorContext::reportAllocationOverflow() {
|
||||
// TODO Bug 1780599 - Currently allocation overflows are not reported for
|
||||
// helper threads; see js::reportAllocationOverflow()
|
||||
}
|
||||
|
||||
void OffThreadErrorContext::reportError(CompileError* err) {
|
||||
// TODO Bug 1773324 - restore selfHosting_ErrorReporter if needed
|
||||
@ -321,7 +341,8 @@ class MOZ_RAII AutoMessageArgs {
|
||||
* if argsArg were strongly typed we'd still need casting below for this to
|
||||
* compile, because typeArg is not known at compile-time here.
|
||||
*/
|
||||
bool init(JSAllocator* alloc, void* argsArg, uint16_t countArg,
|
||||
template <typename Allocator>
|
||||
bool init(Allocator* alloc, void* argsArg, uint16_t countArg,
|
||||
ErrorArgumentsType typeArg, va_list ap) {
|
||||
MOZ_ASSERT(countArg > 0);
|
||||
|
||||
@ -392,9 +413,9 @@ class MOZ_RAII AutoMessageArgs {
|
||||
* that is not worth it here because AutoMessageArgs takes a void* anyway, and
|
||||
* using void* here simplifies our callers a bit.
|
||||
*/
|
||||
template <typename T>
|
||||
static bool ExpandErrorArgumentsHelper(JSContext* cx, JSErrorCallback callback,
|
||||
void* userRef,
|
||||
template <typename T, typename Allocator>
|
||||
static bool ExpandErrorArgumentsHelper(JSContext* cx, Allocator* alloc,
|
||||
JSErrorCallback callback, void* userRef,
|
||||
const unsigned errorNumber,
|
||||
void* messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
@ -438,7 +459,7 @@ static bool ExpandErrorArgumentsHelper(JSContext* cx, JSErrorCallback callback,
|
||||
size_t len = strlen(efs->format);
|
||||
|
||||
AutoMessageArgs args;
|
||||
if (!args.init(cx, messageArgs, argCount, argumentsType, ap)) {
|
||||
if (!args.init(alloc, messageArgs, argCount, argumentsType, ap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -449,7 +470,7 @@ static bool ExpandErrorArgumentsHelper(JSContext* cx, JSErrorCallback callback,
|
||||
* Note - the above calculation assumes that each argument
|
||||
* is used once and only once in the expansion !!!
|
||||
*/
|
||||
char* utf8 = out = cx->pod_malloc<char>(expandedLength + 1);
|
||||
char* utf8 = out = alloc->template pod_malloc<char>(expandedLength + 1);
|
||||
if (!out) {
|
||||
return false;
|
||||
}
|
||||
@ -493,7 +514,7 @@ static bool ExpandErrorArgumentsHelper(JSContext* cx, JSErrorCallback callback,
|
||||
const char* defaultErrorMessage =
|
||||
"No error message available for error number %d";
|
||||
size_t nbytes = strlen(defaultErrorMessage) + 16;
|
||||
char* message = cx->pod_malloc<char>(nbytes);
|
||||
char* message = alloc->template pod_malloc<char>(nbytes);
|
||||
if (!message) {
|
||||
return false;
|
||||
}
|
||||
@ -509,7 +530,8 @@ bool js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap) {
|
||||
MOZ_ASSERT(argumentsType == ArgumentsAreUnicode);
|
||||
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
|
||||
ErrorAllocator<JSContext> alloc(cx);
|
||||
return ExpandErrorArgumentsHelper(cx, &alloc, callback, userRef, errorNumber,
|
||||
messageArgs, argumentsType, reportp, ap);
|
||||
}
|
||||
|
||||
@ -519,7 +541,8 @@ bool js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap) {
|
||||
MOZ_ASSERT(argumentsType != ArgumentsAreUnicode);
|
||||
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
|
||||
ErrorAllocator<JSContext> alloc(cx);
|
||||
return ExpandErrorArgumentsHelper(cx, &alloc, callback, userRef, errorNumber,
|
||||
messageArgs, argumentsType, reportp, ap);
|
||||
}
|
||||
|
||||
@ -527,8 +550,9 @@ bool js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap) {
|
||||
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber, nullptr,
|
||||
argumentsType, reportp, ap);
|
||||
ErrorAllocator<JSContext> alloc(cx);
|
||||
return ExpandErrorArgumentsHelper(cx, &alloc, callback, userRef, errorNumber,
|
||||
nullptr, argumentsType, reportp, ap);
|
||||
}
|
||||
|
||||
bool js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
@ -536,7 +560,8 @@ bool js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorNotes::Note* notep, va_list ap) {
|
||||
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
|
||||
ErrorAllocator<JSContext> alloc(cx);
|
||||
return ExpandErrorArgumentsHelper(cx, &alloc, callback, userRef, errorNumber,
|
||||
messageArgs, argumentsType, notep, ap);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user