Bug 1506323 - Add JS::PrintError to public API. r=evilpie

Differential Revision: https://phabricator.services.mozilla.com/D73519
This commit is contained in:
Philip Chimento 2020-05-13 16:10:25 +00:00
Родитель 5a987970c4
Коммит 9209aaccd1
9 изменённых файлов: 132 добавлений и 18 удалений

Просмотреть файл

@ -265,4 +265,15 @@ class JSErrorReport : public JSErrorBase {
void freeLinebuf();
};
namespace JS {
// Writes a full report to a file descriptor. Does nothing for JSErrorReports
// which are warnings, unless reportWarnings is set.
extern JS_PUBLIC_API void PrintError(JSContext* cx, FILE* file,
ConstUTF8CharsZ toStringResult,
JSErrorReport* report,
bool reportWarnings);
} // namespace JS
#endif /* js_ErrorReport_h */

Просмотреть файл

@ -163,6 +163,12 @@ if CONFIG['JS_BUILD_BINAST'] and CONFIG['JS_STANDALONE'] and not CONFIG['FUZZING
'testBinASTReader.cpp',
]
if CONFIG['OS_ARCH'] != 'WINNT':
# open_memstream() not available on Windows
UNIFIED_SOURCES += [
'testPrintError.cpp',
]
DEFINES['EXPORT_JS_API'] = True

Просмотреть файл

@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <cstdio> // fclose, fflush, open_memstream
#include "jsapi.h" // JS_{Clear,Get}PendingException
#include "jsfriendapi.h" // js::ErrorReport
#include "js/ErrorReport.h" // JS::PrintError
#include "js/Warnings.h" // JS::SetWarningReporter, JS::WarnUTF8
#include "jsapi-tests/tests.h"
class AutoStreamBuffer {
char* buffer;
size_t size;
FILE* fp;
public:
AutoStreamBuffer() { fp = open_memstream(&buffer, &size); }
~AutoStreamBuffer() {
fclose(fp);
free(buffer);
}
FILE* stream() { return fp; }
bool contains(const char* str) {
if (fflush(fp) != 0) {
fprintf(stderr, "Error flushing stream\n");
return false;
}
if (strcmp(buffer, str) != 0) {
fprintf(stderr, "Expected |%s|, got |%s|\n", str, buffer);
return false;
}
return true;
}
};
BEGIN_TEST(testPrintError_Works) {
AutoStreamBuffer buf;
CHECK(!execDontReport("throw null;", "testPrintError_Works.js", 3));
JS::RootedValue exception(cx);
CHECK(JS_GetPendingException(cx, &exception));
JS_ClearPendingException(cx);
js::ErrorReport report(cx);
CHECK(report.init(cx, exception,
js::ErrorReport::SniffingBehavior::NoSideEffects));
JS::PrintError(cx, buf.stream(), report.toStringResult(), report.report(),
false);
CHECK(buf.contains("testPrintError_Works.js:3:1 uncaught exception: null\n"));
return true;
}
END_TEST(testPrintError_Works)
BEGIN_TEST(testPrintError_SkipWarning) {
JS::SetWarningReporter(cx, warningReporter);
CHECK(JS::WarnUTF8(cx, "warning message"));
CHECK(warningSuccess);
return true;
}
static bool warningSuccess;
static void warningReporter(JSContext* cx, JSErrorReport* report) {
AutoStreamBuffer buf;
JS::PrintError(cx, buf.stream(), JS::ConstUTF8CharsZ(), report, false);
warningSuccess = buf.contains("");
}
END_TEST(testPrintError_SkipWarning)
bool cls_testPrintError_SkipWarning::warningSuccess = false;
BEGIN_TEST(testPrintError_PrintWarning) {
JS::SetWarningReporter(cx, warningReporter);
CHECK(JS::WarnUTF8(cx, "warning message"));
CHECK(warningSuccess);
return true;
}
static bool warningSuccess;
static void warningReporter(JSContext* cx, JSErrorReport* report) {
AutoStreamBuffer buf;
JS::PrintError(cx, buf.stream(), JS::ConstUTF8CharsZ(), report, true);
warningSuccess = buf.contains("warning: warning message\n");
}
END_TEST(testPrintError_PrintWarning)
bool cls_testPrintError_PrintWarning::warningSuccess = false;

Просмотреть файл

@ -28,7 +28,8 @@
#include "js/CharacterEncoding.h"
#include "js/Class.h"
#include "js/Conversions.h"
#include "js/Exception.h" // JS::ExceptionStack
#include "js/ErrorReport.h" // JS::PrintError
#include "js/Exception.h" // JS::ExceptionStack
#include "js/SavedFrameAPI.h"
#include "js/UniquePtr.h"
#include "js/Value.h"
@ -287,7 +288,7 @@ void js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
// cannot construct the Error constructor without self-hosted code. Just
// print the error to stderr to help debugging.
if (cx->realm()->isSelfHostingRealm()) {
PrintError(cx, stderr, JS::ConstUTF8CharsZ(), reportp, true);
JS::PrintError(cx, stderr, JS::ConstUTF8CharsZ(), reportp, true);
return;
}

Просмотреть файл

@ -106,6 +106,7 @@
#include "js/ContextOptions.h" // JS::ContextOptions{,Ref}
#include "js/Debug.h"
#include "js/Equality.h" // JS::SameValue
#include "js/ErrorReport.h" // JS::PrintError
#include "js/Exception.h" // JS::StealPendingExceptionStack
#include "js/experimental/SourceHook.h" // js::{Set,Forget,}SourceHook
#include "js/GCVector.h"
@ -9741,7 +9742,8 @@ js::shell::AutoReportException::~AutoReportException() {
MOZ_ASSERT(!report.report()->isWarning());
FILE* fp = ErrorFilePointer();
PrintError(cx, fp, report.toStringResult(), report.report(), reportWarnings);
JS::PrintError(cx, fp, report.toStringResult(), report.report(),
reportWarnings);
JS_ClearPendingException(cx);
if (!PrintStackTrace(cx, exnStack.stack())) {
@ -9781,7 +9783,7 @@ void js::shell::WarningReporter(JSContext* cx, JSErrorReport* report) {
}
// Print the warning.
PrintError(cx, fp, JS::ConstUTF8CharsZ(), report, reportWarnings);
JS::PrintError(cx, fp, JS::ConstUTF8CharsZ(), report, reportWarnings);
}
static bool global_enumerate(JSContext* cx, JS::HandleObject obj,

Просмотреть файл

@ -18,13 +18,13 @@
#include "js/CompilationAndEvaluation.h" // JS::Evaluate
#include "js/CompileOptions.h" // JS::CompileOptions
#include "js/ErrorReport.h" // JS::PrintError
#include "js/Exception.h" // JS::StealPendingExceptionStack
#include "js/RootingAPI.h" // JS::Rooted
#include "js/SourceText.h" // JS::Source{Ownership,Text}
#include "js/Value.h" // JS::Value
#include "shell/jsshell.h" // js::shell::{reportWarnings,PrintStackTrace,sArg{c,v}}
#include "vm/Interpreter.h"
#include "vm/JSContext.h" // js::PrintError
#include "vm/TypedArrayObject.h"
#include "vm/ArrayBufferObject-inl.h"
@ -43,7 +43,7 @@ static void CrashOnPendingException() {
fprintf(stderr, "out of memory initializing ErrorReport\n");
fflush(stderr);
} else {
js::PrintError(gCx, stderr, report.toStringResult(), report.report(),
JS::PrintError(gCx, stderr, report.toStringResult(), report.report(),
js::shell::reportWarnings);
if (!js::shell::PrintStackTrace(gCx, exnStack.stack())) {
fputs("(Unable to print stack trace)\n", stderr);

Просмотреть файл

@ -448,9 +448,9 @@ static void PrintSingleError(JSContext* cx, FILE* file,
fflush(file);
}
void js::PrintError(JSContext* cx, FILE* file,
JS::ConstUTF8CharsZ toStringResult, JSErrorReport* report,
bool reportWarnings) {
JS_PUBLIC_API void JS::PrintError(JSContext* cx, FILE* file,
JS::ConstUTF8CharsZ toStringResult,
JSErrorReport* report, bool reportWarnings) {
MOZ_ASSERT(report);
/* Conditionally ignore reported warnings. */

Просмотреть файл

@ -1036,13 +1036,6 @@ extern void DestroyContext(JSContext* cx);
extern void ReportUsageErrorASCII(JSContext* cx, HandleObject callee,
const char* msg);
// Writes a full report to a file descriptor.
// Does nothing for JSErrorReport which are warnings, unless
// reportWarnings is set.
extern void PrintError(JSContext* cx, FILE* file,
JS::ConstUTF8CharsZ toStringResult,
JSErrorReport* report, bool reportWarnings);
extern void ReportIsNotDefined(JSContext* cx, HandlePropertyName name);
extern void ReportIsNotDefined(JSContext* cx, HandleId id);

Просмотреть файл

@ -49,6 +49,7 @@
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
#include "js/Date.h"
#include "js/ErrorReport.h" // JS::PrintError
#include "js/Exception.h"
#include "js/Modules.h" // JS::GetModulePrivate
#include "js/PropertySpec.h"
@ -108,7 +109,7 @@ using mozilla::Maybe;
static void selfHosting_WarningReporter(JSContext* cx, JSErrorReport* report) {
MOZ_ASSERT(report->isWarning());
PrintError(cx, stderr, JS::ConstUTF8CharsZ(), report, true);
JS::PrintError(cx, stderr, JS::ConstUTF8CharsZ(), report, true);
}
static bool intrinsic_ToObject(JSContext* cx, unsigned argc, Value* vp) {
@ -2601,7 +2602,7 @@ static void MaybePrintAndClearPendingException(JSContext* cx, FILE* file) {
}
MOZ_ASSERT(!report.report()->isWarning());
PrintError(cx, file, report.toStringResult(), report.report(), true);
JS::PrintError(cx, file, report.toStringResult(), report.report(), true);
}
class MOZ_STACK_CLASS AutoSelfHostingErrorReporter {