diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/ipc/JavaScriptParent.cpp | 1 | ||||
-rw-r--r-- | js/src/vm/ErrorReporting.cpp | 124 | ||||
-rw-r--r-- | js/src/vm/ErrorReporting.h | 91 | ||||
-rw-r--r-- | js/xpconnect/idl/moz.build | 1 | ||||
-rw-r--r-- | js/xpconnect/idl/nsIScriptError.idl | 122 | ||||
-rw-r--r-- | js/xpconnect/src/XPCComponents.cpp | 2 | ||||
-rw-r--r-- | js/xpconnect/src/XPCConvert.cpp | 2 | ||||
-rw-r--r-- | js/xpconnect/src/XPCModule.h | 4 | ||||
-rw-r--r-- | js/xpconnect/src/XPCWrappedJSClass.cpp | 1 | ||||
-rw-r--r-- | js/xpconnect/src/XPCWrappedNativeInfo.cpp | 1 | ||||
-rw-r--r-- | js/xpconnect/src/moz.build | 3 | ||||
-rw-r--r-- | js/xpconnect/src/nsScriptError.cpp | 345 | ||||
-rw-r--r-- | js/xpconnect/src/nsScriptErrorWithStack.cpp | 118 | ||||
-rw-r--r-- | js/xpconnect/src/nsXPConnect.cpp | 2 | ||||
-rw-r--r-- | js/xpconnect/src/xpcprivate.h | 72 |
15 files changed, 225 insertions, 664 deletions
diff --git a/js/ipc/JavaScriptParent.cpp b/js/ipc/JavaScriptParent.cpp index 6cf9e05911..aafd7f565f 100644 --- a/js/ipc/JavaScriptParent.cpp +++ b/js/ipc/JavaScriptParent.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ScriptSettings.h" #include "nsJSUtils.h" +#include "nsIScriptError.h" #include "jsfriendapi.h" #include "jswrapper.h" #include "js/Proxy.h" diff --git a/js/src/vm/ErrorReporting.cpp b/js/src/vm/ErrorReporting.cpp new file mode 100644 index 0000000000..5877f3a4b4 --- /dev/null +++ b/js/src/vm/ErrorReporting.cpp @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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 "vm/ErrorReporting.h" + +#include "mozilla/Move.h" + +#include <stdarg.h> + +#include "jscntxt.h" +#include "jsexn.h" + +using mozilla::Move; + +using JS::UniqueTwoByteChars; + +void +CallWarningReporter(JSContext* cx, JSErrorReport* reportp) +{ + MOZ_ASSERT(reportp); + MOZ_ASSERT(JSREPORT_IS_WARNING(reportp->flags)); + + if (JS::WarningReporter warningReporter = cx->runtime()->warningReporter) + warningReporter(cx, reportp); +} + +void +CompileError::throwError(JSContext* cx) +{ + if (JSREPORT_IS_WARNING(flags)) { + CallWarningReporter(cx, this); + return; + } + + // If there's a runtime exception type associated with this error + // number, set that as the pending exception. For errors occuring at + // compile time, this is very likely to be a JSEXN_SYNTAXERR. + // + // If an exception is thrown but not caught, the JSREPORT_EXCEPTION + // flag will be set in report.flags. Proper behavior for an error + // reporter is to ignore a report with this flag for all but top-level + // compilation errors. The exception will remain pending, and so long + // as the non-top-level "load", "eval", or "compile" native function + // returns false, the top-level reporter will eventually receive the + // uncaught exception report. + ErrorToException(cx, this, nullptr, nullptr); +} + +bool +ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes, + unsigned flags, unsigned errorNumber, va_list args) +{ + // On the main thread, report the error immediately. When compiling off + // thread, save the error so that the thread finishing the parse can report + // it later. + CompileError tempErr; + CompileError* err = &tempErr; + if (!cx->isJSContext() && !cx->addPendingCompileError(&err)) { + return false; + } + + err->notes = Move(notes); + err->flags = flags; + err->errorNumber = errorNumber; + + err->filename = metadata.filename; + err->lineno = metadata.lineNumber; + err->column = metadata.columnNumber; + err->isMuted = metadata.isMuted; + + if (UniqueTwoByteChars lineOfContext = Move(metadata.lineOfContext)) + err->initOwnedLinebuf(lineOfContext.release(), metadata.lineLength, metadata.tokenOffset); + + if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber, + nullptr, ArgumentsAreLatin1, err, args)) + { + return false; + } + + if (cx->isJSContext()) { + err->throwError(cx->asJSContext()); + } + + return true; +} + +void +ReportCompileError(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes, + unsigned flags, unsigned errorNumber, va_list args) +{ + // On the main thread, report the error immediately. When compiling off + // thread, save the error so that the thread finishing the parse can report + // it later. + CompileError tempErr; + CompileError* err = &tempErr; + if (!cx->isJSContext() && !cx->addPendingCompileError(&err)) { + return; + } + + err->notes = Move(notes); + err->flags = flags; + err->errorNumber = errorNumber; + + err->filename = metadata.filename; + err->lineno = metadata.lineNumber; + err->column = metadata.columnNumber; + err->isMuted = metadata.isMuted; + + if (UniqueTwoByteChars lineOfContext = Move(metadata.lineOfContext)) + err->initOwnedLinebuf(lineOfContext.release(), metadata.lineLength, metadata.tokenOffset); + + if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber, + nullptr, ArgumentsAreLatin1, err, args)) + { + return; + } + + if (cx->isJSContext()) { + err->throwError(cx->asJSContext()); + } +} diff --git a/js/src/vm/ErrorReporting.h b/js/src/vm/ErrorReporting.h new file mode 100644 index 0000000000..02bbe2c636 --- /dev/null +++ b/js/src/vm/ErrorReporting.h @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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/. */ + +#ifndef vm_ErrorReporting_h +#define vm_ErrorReporting_h + +#include "mozilla/Move.h" + +#include <stdarg.h> + +#include "jsapi.h" // for JSErrorNotes, JSErrorReport + +#include "js/UniquePtr.h" // for UniquePtr +#include "js/Utility.h" // for UniqueTwoByteChars + +struct JSContext; + +namespace js { + +/** + * Metadata for a compilation error (or warning) at a particular offset, or at + * no offset (i.e. with respect to a script overall). + */ +struct ErrorMetadata +{ + // The file/URL where the error occurred. + const char* filename; + + // The line and column numbers where the error occurred. If the error + // is with respect to the entire script and not with respect to a + // particular location, these will both be zero. + uint32_t lineNumber; + uint32_t columnNumber; + + // If the error occurs at a particular location, context surrounding the + // location of the error: the line that contained the error, or a small + // portion of it if the line is long. + // + // This information is provided on a best-effort basis: code populating + // ErrorMetadata instances isn't obligated to supply this. + JS::UniqueTwoByteChars lineOfContext; + + // If |lineOfContext| is non-null, its length. + size_t lineLength; + + // If |lineOfContext| is non-null, the offset within it of the token that + // triggered the error. + size_t tokenOffset; + + // Whether the error is "muted" because it derives from a cross-origin + // load. See the comment in TransitiveCompileOptions in jsapi.h for + // details. + bool isMuted; +}; + +class CompileError : public JSErrorReport +{ + public: + void throwError(JSContext* cx); +}; + +/** Send a JSErrorReport to the warningReporter callback. */ +extern void +CallWarningReporter(JSContext* cx, JSErrorReport* report); + +/** + * Report a compile error during script processing prior to execution of the + * script. + */ +extern void +ReportCompileError(ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes, + unsigned flags, unsigned errorNumber, va_list args); + +/** + * Report a compile warning during script processing prior to execution of the + * script. Returns true if the warning was successfully reported, false if an + * error occurred. + * + * This function DOES NOT respect an existing werror option. If the caller + * wishes such option to be respected, it must do so itself. + */ +extern MOZ_MUST_USE bool +ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes, + unsigned flags, unsigned errorNumber, va_list args); + +} // namespace js + +#endif /* vm_ErrorReporting_h */ diff --git a/js/xpconnect/idl/moz.build b/js/xpconnect/idl/moz.build index 2438b1a5a8..0808d34506 100644 --- a/js/xpconnect/idl/moz.build +++ b/js/xpconnect/idl/moz.build @@ -7,7 +7,6 @@ XPIDL_SOURCES += [ 'mozIJSSubScriptLoader.idl', 'nsIAddonInterposition.idl', - 'nsIScriptError.idl', 'nsIXPConnect.idl', 'nsIXPCScriptable.idl', 'xpccomponents.idl', diff --git a/js/xpconnect/idl/nsIScriptError.idl b/js/xpconnect/idl/nsIScriptError.idl deleted file mode 100644 index 468ca682fa..0000000000 --- a/js/xpconnect/idl/nsIScriptError.idl +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* - * nsIConsoleMessage subclass for representing JavaScript errors and warnings. - */ - - -#include "nsISupports.idl" -#include "nsIConsoleMessage.idl" - -%{C++ -#include "nsStringGlue.h" // for nsDependentCString -%} - -[scriptable, uuid(361be358-76f0-47aa-b37b-6ad833599e8d)] -interface nsIScriptError : nsIConsoleMessage -{ - /** pseudo-flag for default case */ - const unsigned long errorFlag = 0x0; - - /** message is warning */ - const unsigned long warningFlag = 0x1; - - /** exception was thrown for this case - exception-aware hosts can ignore */ - const unsigned long exceptionFlag = 0x2; - - // XXX check how strict is implemented these days. - /** error or warning is due to strict option */ - const unsigned long strictFlag = 0x4; - - /** just a log message */ - const unsigned long infoFlag = 0x8; - - /** - * The error message without any context/line number information. - * - * @note nsIConsoleMessage.message will return the error formatted - * with file/line information. - */ - readonly attribute AString errorMessage; - - readonly attribute AString sourceName; - readonly attribute AString sourceLine; - readonly attribute uint32_t lineNumber; - readonly attribute uint32_t columnNumber; - readonly attribute uint32_t flags; - - /** - * Categories I know about - - * XUL javascript - * content javascript (both of these from nsDocShell, currently) - * system javascript (errors in JS components and other system JS) - */ - readonly attribute string category; - - /* Get the window id this was initialized with. Zero will be - returned if init() was used instead of initWithWindowID(). */ - readonly attribute unsigned long long outerWindowID; - - /* Get the inner window id this was initialized with. Zero will be - returned if init() was used instead of initWithWindowID(). */ - readonly attribute unsigned long long innerWindowID; - - readonly attribute boolean isFromPrivateWindow; - - attribute jsval stack; - - /** - * The name of a template string, as found in js.msg, associated with the - * error message. - */ - attribute AString errorMessageName; - - - void init(in AString message, - in AString sourceName, - in AString sourceLine, - in uint32_t lineNumber, - in uint32_t columnNumber, - in uint32_t flags, - in string category); - - /* This should be called instead of nsIScriptError.init to - initialize with a window id. The window id should be for the - inner window associated with this error. */ - void initWithWindowID(in AString message, - in AString sourceName, - in AString sourceLine, - in uint32_t lineNumber, - in uint32_t columnNumber, - in uint32_t flags, - in ACString category, - in unsigned long long innerWindowID); -%{C++ - // This overload allows passing a literal string for category. - template<uint32_t N> - nsresult InitWithWindowID(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char (&c)[N], - uint64_t aInnerWindowID) - { - nsDependentCString category(c, N - 1); - return InitWithWindowID(message, sourceName, sourceLine, lineNumber, - columnNumber, flags, category, aInnerWindowID); - } -%} - -}; - -%{ C++ -#define NS_SCRIPTERROR_CID \ -{ 0x1950539a, 0x90f0, 0x4d22, { 0xb5, 0xaf, 0x71, 0x32, 0x9c, 0x68, 0xfa, 0x35 }} - -#define NS_SCRIPTERROR_CONTRACTID "@mozilla.org/scripterror;1" -%} diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index dbb63092ed..07ce7460b9 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -34,9 +34,11 @@ #include "nsDOMClassInfo.h" #include "ShimInterfaceInfo.h" #include "nsIAddonInterposition.h" +#include "nsIScriptError.h" #include "nsISimpleEnumerator.h" #include "nsPIDOMWindow.h" #include "nsGlobalWindow.h" +#include "nsScriptError.h" using namespace mozilla; using namespace JS; diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index 37932b452c..77f09f4a54 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -11,9 +11,11 @@ #include "xpcprivate.h" #include "nsIAtom.h" +#include "nsIScriptError.h" #include "nsWrapperCache.h" #include "nsJSUtils.h" #include "nsQueryObject.h" +#include "nsScriptError.h" #include "WrapperFactory.h" #include "nsWrapperCacheInlines.h" diff --git a/js/xpconnect/src/XPCModule.h b/js/xpconnect/src/XPCModule.h index d627646254..506e8945a4 100644 --- a/js/xpconnect/src/XPCModule.h +++ b/js/xpconnect/src/XPCModule.h @@ -23,7 +23,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSID) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect, nsXPConnect::GetSingleton) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError) NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSComponentLoader) NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSSubScriptLoader) @@ -31,14 +30,12 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSSubScriptLoader) NS_DEFINE_NAMED_CID(NS_JS_ID_CID); NS_DEFINE_NAMED_CID(NS_XPCONNECT_CID); NS_DEFINE_NAMED_CID(NS_XPCEXCEPTION_CID); -NS_DEFINE_NAMED_CID(NS_SCRIPTERROR_CID); NS_DEFINE_NAMED_CID(MOZJSCOMPONENTLOADER_CID); NS_DEFINE_NAMED_CID(MOZ_JSSUBSCRIPTLOADER_CID); #define XPCONNECT_CIDENTRIES \ { &kNS_JS_ID_CID, false, nullptr, nsJSIDConstructor }, \ { &kNS_XPCONNECT_CID, false, nullptr, nsIXPConnectConstructor }, \ - { &kNS_SCRIPTERROR_CID, false, nullptr, nsScriptErrorConstructor }, \ { &kMOZJSCOMPONENTLOADER_CID, false, nullptr, mozJSComponentLoaderConstructor },\ { &kMOZ_JSSUBSCRIPTLOADER_CID, false, nullptr, mozJSSubScriptLoaderConstructor }, @@ -46,7 +43,6 @@ NS_DEFINE_NAMED_CID(MOZ_JSSUBSCRIPTLOADER_CID); { XPC_ID_CONTRACTID, &kNS_JS_ID_CID }, \ { XPC_XPCONNECT_CONTRACTID, &kNS_XPCONNECT_CID }, \ { XPC_CONTEXT_STACK_CONTRACTID, &kNS_XPCONNECT_CID }, \ - { NS_SCRIPTERROR_CONTRACTID, &kNS_SCRIPTERROR_CID }, \ { MOZJSCOMPONENTLOADER_CONTRACTID, &kMOZJSCOMPONENTLOADER_CID }, \ { MOZJSSUBSCRIPTLOADER_CONTRACTID, &kMOZ_JSSUBSCRIPTLOADER_CID }, diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 2c9fd66bc1..e90373e3d1 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -10,6 +10,7 @@ #include "jsprf.h" #include "nsArrayEnumerator.h" #include "nsContentUtils.h" +#include "nsIScriptError.h" #include "nsWrapperCache.h" #include "AccessCheck.h" #include "nsJSUtils.h" diff --git a/js/xpconnect/src/XPCWrappedNativeInfo.cpp b/js/xpconnect/src/XPCWrappedNativeInfo.cpp index 302454fb53..4b0330af62 100644 --- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp +++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp @@ -11,6 +11,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/XPTInterfaceInfoManager.h" +#include "nsIScriptError.h" #include "nsPrintfCString.h" using namespace JS; diff --git a/js/xpconnect/src/moz.build b/js/xpconnect/src/moz.build index 7e787bb566..7d9cd5b37f 100644 --- a/js/xpconnect/src/moz.build +++ b/js/xpconnect/src/moz.build @@ -14,8 +14,6 @@ EXPORTS += [ UNIFIED_SOURCES += [ 'ExportHelpers.cpp', - 'nsScriptError.cpp', - 'nsScriptErrorWithStack.cpp', 'nsXPConnect.cpp', 'Sandbox.cpp', 'XPCCallContext.cpp', @@ -58,6 +56,7 @@ LOCAL_INCLUDES += [ '../wrappers', '/caps', '/dom/base', + '/dom/bindings', '/dom/html', '/dom/svg', '/dom/workers', diff --git a/js/xpconnect/src/nsScriptError.cpp b/js/xpconnect/src/nsScriptError.cpp deleted file mode 100644 index ff687bc441..0000000000 --- a/js/xpconnect/src/nsScriptError.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=99: */ -/* 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/. */ - -/* - * nsIScriptError implementation. Defined here, lacking a JS-specific - * place to put XPCOM things. - */ - -#include "xpcprivate.h" -#include "jsprf.h" -#include "MainThreadUtils.h" -#include "mozilla/Assertions.h" -#include "nsGlobalWindow.h" -#include "nsPIDOMWindow.h" -#include "nsILoadContext.h" -#include "nsIDocShell.h" -#include "nsIScriptError.h" -#include "nsISensitiveInfoHiddenURI.h" - -static_assert(nsIScriptError::errorFlag == JSREPORT_ERROR && - nsIScriptError::warningFlag == JSREPORT_WARNING && - nsIScriptError::exceptionFlag == JSREPORT_EXCEPTION && - nsIScriptError::strictFlag == JSREPORT_STRICT && - nsIScriptError::infoFlag == JSREPORT_USER_1, - "flags should be consistent"); - -nsScriptErrorBase::nsScriptErrorBase() - : mMessage(), - mMessageName(), - mSourceName(), - mLineNumber(0), - mSourceLine(), - mColumnNumber(0), - mFlags(0), - mCategory(), - mOuterWindowID(0), - mInnerWindowID(0), - mTimeStamp(0), - mInitializedOnMainThread(false), - mIsFromPrivateWindow(false) -{ -} - -nsScriptErrorBase::~nsScriptErrorBase() {} - -void -nsScriptErrorBase::InitializeOnMainThread() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!mInitializedOnMainThread); - - if (mInnerWindowID) { - nsGlobalWindow* window = - nsGlobalWindow::GetInnerWindowWithId(mInnerWindowID); - if (window) { - nsPIDOMWindowOuter* outer = window->GetOuterWindow(); - if (outer) - mOuterWindowID = outer->WindowID(); - - nsIDocShell* docShell = window->GetDocShell(); - nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell); - - if (loadContext) { - // Never mark exceptions from chrome windows as having come from - // private windows, since we always want them to be reported. - nsIPrincipal* winPrincipal = window->GetPrincipal(); - mIsFromPrivateWindow = loadContext->UsePrivateBrowsing() && - !nsContentUtils::IsSystemPrincipal(winPrincipal); - } - } - } - - mInitializedOnMainThread = true; -} - -// nsIConsoleMessage methods -NS_IMETHODIMP -nsScriptErrorBase::GetMessageMoz(char16_t** result) { - nsresult rv; - - nsAutoCString message; - rv = ToString(message); - if (NS_FAILED(rv)) - return rv; - - *result = UTF8ToNewUnicode(message); - if (!*result) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; -} - - -NS_IMETHODIMP -nsScriptErrorBase::GetLogLevel(uint32_t* aLogLevel) -{ - if (mFlags & (uint32_t)nsIScriptError::infoFlag) { - *aLogLevel = nsIConsoleMessage::info; - } else if (mFlags & (uint32_t)nsIScriptError::warningFlag) { - *aLogLevel = nsIConsoleMessage::warn; - } else { - *aLogLevel = nsIConsoleMessage::error; - } - return NS_OK; -} - -// nsIScriptError methods -NS_IMETHODIMP -nsScriptErrorBase::GetErrorMessage(nsAString& aResult) { - aResult.Assign(mMessage); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetSourceName(nsAString& aResult) { - aResult.Assign(mSourceName); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetSourceLine(nsAString& aResult) { - aResult.Assign(mSourceLine); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetLineNumber(uint32_t* result) { - *result = mLineNumber; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetColumnNumber(uint32_t* result) { - *result = mColumnNumber; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetFlags(uint32_t* result) { - *result = mFlags; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetCategory(char** result) { - *result = ToNewCString(mCategory); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetStack(JS::MutableHandleValue aStack) { - aStack.setUndefined(); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::SetStack(JS::HandleValue aStack) { - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetErrorMessageName(nsAString& aErrorMessageName) { - aErrorMessageName = mMessageName; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::SetErrorMessageName(const nsAString& aErrorMessageName) { - mMessageName = aErrorMessageName; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::Init(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char* category) -{ - return InitWithWindowID(message, sourceName, sourceLine, lineNumber, - columnNumber, flags, - category ? nsDependentCString(category) - : EmptyCString(), - 0); -} - -NS_IMETHODIMP -nsScriptErrorBase::InitWithWindowID(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const nsACString& category, - uint64_t aInnerWindowID) -{ - mMessage.Assign(message); - - if (!sourceName.IsEmpty()) { - mSourceName.Assign(sourceName); - - nsCOMPtr<nsIURI> uri; - nsAutoCString pass; - if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), sourceName)) && - NS_SUCCEEDED(uri->GetPassword(pass)) && - !pass.IsEmpty()) { - nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri = - do_QueryInterface(uri); - - nsAutoCString loc; - if (safeUri && - NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc))) { - mSourceName.Assign(NS_ConvertUTF8toUTF16(loc)); - } - } - } - - mLineNumber = lineNumber; - mSourceLine.Assign(sourceLine); - mColumnNumber = columnNumber; - mFlags = flags; - mCategory = category; - mTimeStamp = JS_Now() / 1000; - mInnerWindowID = aInnerWindowID; - - if (aInnerWindowID && NS_IsMainThread()) { - InitializeOnMainThread(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult) -{ - static const char format0[] = - "[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]"; - static const char format1[] = - "[%s: \"%s\" {file: \"%s\" line: %d}]"; - static const char format2[] = - "[%s: \"%s\"]"; - - static const char error[] = "JavaScript Error"; - static const char warning[] = "JavaScript Warning"; - - const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning; - - char* temp; - char* tempMessage = nullptr; - char* tempSourceName = nullptr; - char* tempSourceLine = nullptr; - - if (!mMessage.IsEmpty()) - tempMessage = ToNewUTF8String(mMessage); - if (!mSourceName.IsEmpty()) - // Use at most 512 characters from mSourceName. - tempSourceName = ToNewUTF8String(StringHead(mSourceName, 512)); - if (!mSourceLine.IsEmpty()) - // Use at most 512 characters from mSourceLine. - tempSourceLine = ToNewUTF8String(StringHead(mSourceLine, 512)); - - if (nullptr != tempSourceName && nullptr != tempSourceLine) - temp = JS_smprintf(format0, - severity, - tempMessage, - tempSourceName, - mLineNumber, - mColumnNumber, - tempSourceLine); - else if (!mSourceName.IsEmpty()) - temp = JS_smprintf(format1, - severity, - tempMessage, - tempSourceName, - mLineNumber); - else - temp = JS_smprintf(format2, - severity, - tempMessage); - - if (nullptr != tempMessage) - free(tempMessage); - if (nullptr != tempSourceName) - free(tempSourceName); - if (nullptr != tempSourceLine) - free(tempSourceLine); - - if (!temp) - return NS_ERROR_OUT_OF_MEMORY; - - aResult.Assign(temp); - JS_smprintf_free(temp); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetOuterWindowID(uint64_t* aOuterWindowID) -{ - NS_WARNING_ASSERTION(NS_IsMainThread() || mInitializedOnMainThread, - "This can't be safely determined off the main thread, " - "returning an inaccurate value!"); - - if (!mInitializedOnMainThread && NS_IsMainThread()) { - InitializeOnMainThread(); - } - - *aOuterWindowID = mOuterWindowID; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetInnerWindowID(uint64_t* aInnerWindowID) -{ - *aInnerWindowID = mInnerWindowID; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetTimeStamp(int64_t* aTimeStamp) -{ - *aTimeStamp = mTimeStamp; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetIsFromPrivateWindow(bool* aIsFromPrivateWindow) -{ - NS_WARNING_ASSERTION(NS_IsMainThread() || mInitializedOnMainThread, - "This can't be safely determined off the main thread, " - "returning an inaccurate value!"); - - if (!mInitializedOnMainThread && NS_IsMainThread()) { - InitializeOnMainThread(); - } - - *aIsFromPrivateWindow = mIsFromPrivateWindow; - return NS_OK; -} - -NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError) diff --git a/js/xpconnect/src/nsScriptErrorWithStack.cpp b/js/xpconnect/src/nsScriptErrorWithStack.cpp deleted file mode 100644 index 50407da23c..0000000000 --- a/js/xpconnect/src/nsScriptErrorWithStack.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=99: */ -/* 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/. */ - -/* - * nsScriptErrorWithStack implementation. - * a main-thread-only, cycle-collected subclass of nsScriptErrorBase - * that can store a SavedFrame stack trace object. - */ - -#include "xpcprivate.h" -#include "MainThreadUtils.h" -#include "mozilla/Assertions.h" -#include "nsGlobalWindow.h" -#include "nsCycleCollectionParticipant.h" - - -namespace { - -static nsCString -FormatStackString(JSContext* cx, HandleObject aStack) { - JS::RootedString formattedStack(cx); - - if (!JS::BuildStackString(cx, aStack, &formattedStack)) { - return nsCString(); - } - - nsAutoJSString stackJSString; - if (!stackJSString.init(cx, formattedStack)) { - return nsCString(); - } - - return NS_ConvertUTF16toUTF8(stackJSString.get()); -} - -} - - -NS_IMPL_CYCLE_COLLECTION_CLASS(nsScriptErrorWithStack) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptErrorWithStack) - tmp->mStack = nullptr; -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptErrorWithStack) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsScriptErrorWithStack) - NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mStack) -NS_IMPL_CYCLE_COLLECTION_TRACE_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptErrorWithStack) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptErrorWithStack) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScriptErrorWithStack) - NS_INTERFACE_MAP_ENTRY(nsISupports) - NS_INTERFACE_MAP_ENTRY(nsIConsoleMessage) - NS_INTERFACE_MAP_ENTRY(nsIScriptError) -NS_INTERFACE_MAP_END - -nsScriptErrorWithStack::nsScriptErrorWithStack(JS::HandleObject aStack) - : mStack(aStack) -{ - MOZ_ASSERT(NS_IsMainThread(), "You can't use this class on workers."); - mozilla::HoldJSObjects(this); -} - -nsScriptErrorWithStack::~nsScriptErrorWithStack() { - mozilla::DropJSObjects(this); -} - -NS_IMETHODIMP -nsScriptErrorWithStack::Init(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char* category) -{ - MOZ_CRASH("nsScriptErrorWithStack requires to be initialized with a document, by using InitWithWindowID"); -} - -NS_IMETHODIMP -nsScriptErrorWithStack::GetStack(JS::MutableHandleValue aStack) { - aStack.setObjectOrNull(mStack); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorWithStack::ToString(nsACString& /*UTF8*/ aResult) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsCString message; - nsresult rv = nsScriptErrorBase::ToString(message); - NS_ENSURE_SUCCESS(rv, rv); - - if (!mStack) { - aResult.Assign(message); - return NS_OK; - } - - AutoJSAPI jsapi; - if (!jsapi.Init(mStack)) { - return NS_ERROR_FAILURE; - } - - JSContext* cx = jsapi.cx(); - RootedObject stack(cx, mStack); - nsCString stackString = FormatStackString(cx, stack); - nsCString combined = message + NS_LITERAL_CSTRING("\n") + stackString; - aResult.Assign(combined); - - return NS_OK; -} diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 4a403874b4..8102d4a4a9 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -33,7 +33,9 @@ #include "nsIObjectOutputStream.h" #include "nsScriptSecurityManager.h" #include "nsIPermissionManager.h" +#include "nsIScriptError.h" #include "nsContentUtils.h" +#include "nsScriptError.h" #include "jsfriendapi.h" using namespace mozilla; diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 347b406eb5..e55cc06e0d 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -128,7 +128,6 @@ #include "MainThreadUtils.h" #include "nsIConsoleService.h" -#include "nsIScriptError.h" #include "nsIException.h" #include "nsVariant.h" @@ -2552,77 +2551,6 @@ extern char* xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps); -/***************************************************************************/ - -// Definition of nsScriptError, defined here because we lack a place to put -// XPCOM objects associated with the JavaScript engine. -class nsScriptErrorBase : public nsIScriptError { -public: - nsScriptErrorBase(); - - // TODO - do something reasonable on getting null from these babies. - - NS_DECL_NSICONSOLEMESSAGE - NS_DECL_NSISCRIPTERROR - -protected: - virtual ~nsScriptErrorBase(); - - void - InitializeOnMainThread(); - - nsString mMessage; - nsString mMessageName; - nsString mSourceName; - uint32_t mLineNumber; - nsString mSourceLine; - uint32_t mColumnNumber; - uint32_t mFlags; - nsCString mCategory; - // mOuterWindowID is set on the main thread from InitializeOnMainThread(). - uint64_t mOuterWindowID; - uint64_t mInnerWindowID; - int64_t mTimeStamp; - // mInitializedOnMainThread and mIsFromPrivateWindow are set on the main - // thread from InitializeOnMainThread(). - mozilla::Atomic<bool> mInitializedOnMainThread; - bool mIsFromPrivateWindow; -}; - -class nsScriptError final : public nsScriptErrorBase { -public: - nsScriptError() {} - NS_DECL_THREADSAFE_ISUPPORTS - -private: - virtual ~nsScriptError() {} -}; - -class nsScriptErrorWithStack : public nsScriptErrorBase { -public: - explicit nsScriptErrorWithStack(JS::HandleObject); - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsScriptErrorWithStack) - - NS_IMETHOD Init(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char* category) override; - - NS_IMETHOD GetStack(JS::MutableHandleValue) override; - NS_IMETHOD ToString(nsACString& aResult) override; - -private: - virtual ~nsScriptErrorWithStack(); - // Complete stackframe where the error happened. - // Must be SavedFrame object. - JS::Heap<JSObject*> mStack; -}; - /****************************************************************************** * Handles pre/post script processing. */ |