зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1506323 - Add JS::PrintError to public API. r=evilpie
Differential Revision: https://phabricator.services.mozilla.com/D73519
This commit is contained in:
Родитель
5a987970c4
Коммит
9209aaccd1
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче