Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
Roy Tam 2019-07-22 20:08:59 +08:00
commit 5fda7c378f
282 changed files with 8990 additions and 3961 deletions

View file

@ -1183,14 +1183,6 @@ GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
}
}
bool
UnforgeableValueOf(JSContext* cx, unsigned argc, JS::Value* vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().set(args.thisv());
return true;
}
bool
ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
{

View file

@ -2044,9 +2044,6 @@ GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID,
GetInterfaceImpl(aCx, aThis, aThis, aIID, aRetval, aError);
}
bool
UnforgeableValueOf(JSContext* cx, unsigned argc, JS::Value* vp);
bool
ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);

View file

@ -2390,11 +2390,10 @@ class MethodDefiner(PropertyDefiner):
# Synthesize our valueOf method
self.regular.append({
"name": 'valueOf',
"nativeName": "UnforgeableValueOf",
"selfHostedName": "Object_valueOf",
"methodInfo": False,
"length": 0,
"flags": "JSPROP_ENUMERATE", # readonly/permanent added
# automatically.
"flags": "0", # readonly/permanent added automatically.
"condition": MemberCondition()
})
@ -3456,19 +3455,15 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties, failureCode,
"nsContentUtils::ThreadsafeIsCallerChrome()"))
if descriptor.interface.getExtendedAttribute("Unforgeable"):
# We do our undefined toJSON and toPrimitive here, not as a regular
# property because we don't have a concept of value props anywhere in
# IDL.
# We do our undefined toPrimitive here, not as a regular property
# because we don't have a concept of value props anywhere in IDL.
unforgeables.append(CGGeneric(fill(
"""
JS::RootedId toPrimitive(aCx,
SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::toPrimitive)));
if (!JS_DefinePropertyById(aCx, ${holderName}, toPrimitive,
JS::UndefinedHandleValue,
JSPROP_READONLY | JSPROP_PERMANENT) ||
!JS_DefineProperty(aCx, ${holderName}, "toJSON",
JS::UndefinedHandleValue,
JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
JSPROP_READONLY | JSPROP_PERMANENT)) {
$*{failureCode}
}
""",

View file

@ -6,6 +6,12 @@
TEST_DIRS += ['test']
XPIDL_SOURCES += [
'nsIScriptError.idl'
]
XPIDL_MODULE = 'dom_bindings'
EXPORTS.ipc += [
'ErrorIPCUtils.h',
]
@ -91,6 +97,8 @@ UNIFIED_SOURCES += [
'DOMJSProxyHandler.cpp',
'Exceptions.cpp',
'IterableIterator.cpp',
'nsScriptError.cpp',
'nsScriptErrorWithStack.cpp',
'SimpleGlobalObject.cpp',
'ToJSValue.cpp',
'WebIDLGlobalNameHash.cpp',

View file

@ -0,0 +1,135 @@
/* -*- 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 "nsIArray.idl"
#include "nsIConsoleMessage.idl"
%{C++
#include "nsStringGlue.h" // for nsDependentCString
%}
[scriptable, uuid(e8933fc9-c302-4e12-a55b-4f88611d9c6c)]
interface nsIScriptErrorNote : nsISupports
{
readonly attribute AString errorMessage;
readonly attribute AString sourceName;
readonly attribute uint32_t lineNumber;
readonly attribute uint32_t columnNumber;
AUTF8String toString();
};
[scriptable, uuid(63eb4d3e-7d99-4150-b4f3-11314f9d82a9)]
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;
readonly attribute nsIArray notes;
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"
%}

View file

@ -0,0 +1,438 @@
/* -*- 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.
*/
#include "nsScriptError.h"
#include "jsprf.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "nsGlobalWindow.h"
#include "nsNetUtil.h"
#include "nsPIDOMWindow.h"
#include "nsILoadContext.h"
#include "nsIDocShell.h"
#include "nsIMutableArray.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::AddNote(nsIScriptErrorNote* note)
{
mNotes.AppendObject(note);
}
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);
}
static void
AssignSourceNameHelper(nsString& aSourceNameDest, const nsAString& aSourceNameSrc)
{
if (aSourceNameSrc.IsEmpty())
return;
aSourceNameDest.Assign(aSourceNameSrc);
nsCOMPtr<nsIURI> uri;
nsAutoCString pass;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), aSourceNameSrc)) &&
NS_SUCCEEDED(uri->GetPassword(pass)) &&
!pass.IsEmpty())
{
nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri = do_QueryInterface(uri);
nsAutoCString loc;
if (safeUri && NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc)))
aSourceNameDest.Assign(NS_ConvertUTF8toUTF16(loc));
}
}
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);
AssignSourceNameHelper(mSourceName, sourceName);
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;
}
static nsresult
ToStringHelper(const char* aSeverity, const nsString& aMessage,
const nsString& aSourceName, const nsString* aSourceLine,
uint32_t aLineNumber, uint32_t aColumnNumber,
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\"]";
char* temp;
char* tempMessage = nullptr;
char* tempSourceName = nullptr;
char* tempSourceLine = nullptr;
if (!aMessage.IsEmpty())
tempMessage = ToNewUTF8String(aMessage);
if (!aSourceName.IsEmpty())
// Use at most 512 characters from mSourceName.
tempSourceName = ToNewUTF8String(StringHead(aSourceName, 512));
if (aSourceLine && !aSourceLine->IsEmpty())
// Use at most 512 characters from mSourceLine.
tempSourceLine = ToNewUTF8String(StringHead(*aSourceLine, 512));
if (nullptr != tempSourceName && nullptr != tempSourceLine) {
temp = JS_smprintf(format0,
aSeverity,
tempMessage,
tempSourceName,
aLineNumber,
aColumnNumber,
tempSourceLine);
} else if (!aSourceName.IsEmpty()) {
temp = JS_smprintf(format1,
aSeverity,
tempMessage,
tempSourceName,
aLineNumber);
} else {
temp = JS_smprintf(format2,
aSeverity,
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::ToString(nsACString& /*UTF8*/ aResult)
{
static const char error[] = "JavaScript Error";
static const char warning[] = "JavaScript Warning";
const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning;
return ToStringHelper(severity, mMessage, mSourceName, &mSourceLine,
mLineNumber, mColumnNumber, aResult);
}
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_IMETHODIMP
nsScriptErrorBase::GetNotes(nsIArray** aNotes)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> array =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t len = mNotes.Length();
for (uint32_t i = 0; i < len; i++)
array->AppendElement(mNotes[i], false);
array.forget(aNotes);
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError)
nsScriptErrorNote::nsScriptErrorNote()
: mMessage(),
mSourceName(),
mLineNumber(0),
mColumnNumber(0)
{
}
nsScriptErrorNote::~nsScriptErrorNote() {}
void
nsScriptErrorNote::Init(const nsAString& message,
const nsAString& sourceName,
uint32_t lineNumber,
uint32_t columnNumber)
{
mMessage.Assign(message);
AssignSourceNameHelper(mSourceName, sourceName);
mLineNumber = lineNumber;
mColumnNumber = columnNumber;
}
// nsIScriptErrorNote methods
NS_IMETHODIMP
nsScriptErrorNote::GetErrorMessage(nsAString& aResult) {
aResult.Assign(mMessage);
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::GetSourceName(nsAString& aResult) {
aResult.Assign(mSourceName);
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::GetLineNumber(uint32_t* result) {
*result = mLineNumber;
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::GetColumnNumber(uint32_t* result) {
*result = mColumnNumber;
return NS_OK;
}
NS_IMETHODIMP
nsScriptErrorNote::ToString(nsACString& /*UTF8*/ aResult)
{
return ToStringHelper("JavaScript Note", mMessage, mSourceName, nullptr,
mLineNumber, mColumnNumber, aResult);
}
NS_IMPL_ISUPPORTS(nsScriptErrorNote, nsIScriptErrorNote)

View file

@ -0,0 +1,109 @@
/* -*- 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/. */
#ifndef mozilla_dom_nsScriptError_h
#define mozilla_dom_nsScriptError_h
#include "mozilla/Atomics.h"
#include <stdint.h>
#include "jsapi.h"
#include "js/RootingAPI.h"
#include "nsIScriptError.h"
#include "nsString.h"
class nsScriptErrorNote final : public nsIScriptErrorNote {
public:
nsScriptErrorNote();
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISCRIPTERRORNOTE
void Init(const nsAString& message, const nsAString& sourceName,
uint32_t lineNumber, uint32_t columnNumber);
private:
virtual ~nsScriptErrorNote();
nsString mMessage;
nsString mSourceName;
nsString mSourceLine;
uint32_t mLineNumber;
uint32_t mColumnNumber;
};
// Definition of nsScriptError..
class nsScriptErrorBase : public nsIScriptError {
public:
nsScriptErrorBase();
NS_DECL_NSICONSOLEMESSAGE
NS_DECL_NSISCRIPTERROR
void AddNote(nsIScriptErrorNote* note);
protected:
virtual ~nsScriptErrorBase();
void
InitializeOnMainThread();
nsCOMArray<nsIScriptErrorNote> mNotes;
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;
};
#endif /* mozilla_dom_nsScriptError_h */

View file

@ -0,0 +1,120 @@
/* -*- 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 "nsScriptError.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsGlobalWindow.h"
#include "nsCycleCollectionParticipant.h"
using namespace mozilla::dom;
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;
}

View file

@ -29,7 +29,9 @@ WebGLExtensionDebugShaders::GetTranslatedShaderSource(const WebGLShader& shader,
{
retval.SetIsVoid(true);
if (mIsLost || !mContext) return;
if (mIsLost || !mContext) {
return;
}
if (!mContext->ValidateObject("getShaderTranslatedSource: shader", shader))
return;

View file

@ -40,8 +40,10 @@ void
WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLQuery* query) const
{
const char funcName[] = "deleteQueryEXT";
if (mIsLost || !mContext)
return;
if (mIsLost || !mContext) {
return;
}
mContext->DeleteQuery(query, funcName);
}
@ -50,8 +52,10 @@ bool
WebGLExtensionDisjointTimerQuery::IsQueryEXT(const WebGLQuery* query) const
{
const char funcName[] = "isQueryEXT";
if (mIsLost || !mContext)
return false;
if (mIsLost || !mContext) {
return false;
}
return mContext->IsQuery(query, funcName);
}
@ -60,8 +64,10 @@ void
WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target, WebGLQuery& query) const
{
const char funcName[] = "beginQueryEXT";
if (mIsLost || !mContext)
return;
if (mIsLost || !mContext) {
return;
}
mContext->BeginQuery(target, query, funcName);
}
@ -70,8 +76,10 @@ void
WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target) const
{
const char funcName[] = "endQueryEXT";
if (mIsLost || !mContext)
return;
if (mIsLost || !mContext) {
return;
}
mContext->EndQuery(target, funcName);
}
@ -80,8 +88,10 @@ void
WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLQuery& query, GLenum target) const
{
const char funcName[] = "queryCounterEXT";
if (mIsLost || !mContext)
return;
if (mIsLost || !mContext) {
return;
}
if (!mContext->ValidateObject(funcName, query))
return;
@ -95,8 +105,10 @@ WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target, GLen
{
const char funcName[] = "getQueryEXT";
retval.setNull();
if (mIsLost || !mContext)
return;
if (mIsLost || !mContext) {
return;
}
mContext->GetQuery(cx, target, pname, retval, funcName);
}
@ -108,8 +120,10 @@ WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
{
const char funcName[] = "getQueryObjectEXT";
retval.setNull();
if (mIsLost || !mContext)
return;
if (mIsLost || !mContext) {
return;
}
mContext->GetQueryParameter(cx, query, pname, retval, funcName);
}

View file

@ -31,8 +31,8 @@ WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(GLenum mode,
if (mContext) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"drawArraysInstancedANGLE");
return;
}
return;
}
mContext->DrawArraysInstanced(mode, first, count, primcount);
@ -49,8 +49,8 @@ WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(GLenum mode,
if (mContext) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"drawElementsInstancedANGLE");
return;
}
return;
}
mContext->DrawElementsInstanced(mode, count, type, offset, primcount);
@ -64,8 +64,8 @@ WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(GLuint index,
if (mContext) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"vertexAttribDivisorANGLE");
return;
}
return;
}
mContext->VertexAttribDivisor(index, divisor);

View file

@ -8,7 +8,6 @@
#include "mozilla/WeakPtr.h"
#include "nsCycleCollectionNoteChild.h"
#include "WebGLTypes.h"
namespace mozilla {

View file

@ -1381,7 +1381,7 @@ nsPluginStreamListenerPeer::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsICh
return NS_ERROR_FAILURE;
}
// Don't allow cross-origin 307 POST redirects.
// Don't allow cross-origin 307/308 POST redirects.
nsCOMPtr<nsIHttpChannel> oldHttpChannel(do_QueryInterface(oldChannel));
if (oldHttpChannel) {
uint32_t responseStatus;
@ -1389,7 +1389,7 @@ nsPluginStreamListenerPeer::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsICh
if (NS_FAILED(rv)) {
return rv;
}
if (responseStatus == 307) {
if (responseStatus == 307 || responseStatus == 308) {
nsAutoCString method;
rv = oldHttpChannel->GetRequestMethod(method);
if (NS_FAILED(rv)) {

View file

@ -988,7 +988,7 @@ Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj)
}
if (existing) {
js::Wrapper::Renew(cx, existing, obj, wrapper);
js::Wrapper::Renew(existing, obj, wrapper);
}
return js::Wrapper::New(cx, obj, wrapper);
}

View file

@ -87,6 +87,7 @@
#include "nsProxyRelease.h"
#include "nsQueryObject.h"
#include "nsSandboxFlags.h"
#include "nsScriptError.h"
#include "nsUTF8Utils.h"
#include "prthread.h"
#include "xpcpublic.h"
@ -281,27 +282,34 @@ struct WindowAction
};
void
LogErrorToConsole(const nsAString& aMessage,
const nsAString& aFilename,
const nsAString& aLine,
uint32_t aLineNumber,
uint32_t aColumnNumber,
uint32_t aFlags,
uint64_t aInnerWindowId)
LogErrorToConsole(const WorkerErrorReport& aReport, uint64_t aInnerWindowId)
{
AssertIsOnMainThread();
nsCOMPtr<nsIScriptError> scriptError =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
RefPtr<nsScriptErrorBase> scriptError = new nsScriptError();
NS_WARNING_ASSERTION(scriptError, "Failed to create script error!");
if (scriptError) {
if (NS_FAILED(scriptError->InitWithWindowID(aMessage, aFilename, aLine,
aLineNumber, aColumnNumber,
aFlags, "Web Worker",
nsAutoCString category("Web Worker");
if (NS_FAILED(scriptError->InitWithWindowID(aReport.mMessage,
aReport.mFilename,
aReport.mLine,
aReport.mLineNumber,
aReport.mColumnNumber,
aReport.mFlags,
category,
aInnerWindowId))) {
NS_WARNING("Failed to init script error!");
scriptError = nullptr;
for (size_t i = 0, len = aReport.mNotes.Length(); i < len; i++) {
const WorkerErrorNote& note = aReport.mNotes.ElementAt(i);
nsScriptErrorNote* noteObject = new nsScriptErrorNote();
noteObject->Init(note.mMessage, note.mFilename,
note.mLineNumber, note.mColumnNumber);
scriptError->AddNote(noteObject);
}
}
}
@ -316,23 +324,23 @@ LogErrorToConsole(const nsAString& aMessage,
}
NS_WARNING("LogMessage failed!");
} else if (NS_SUCCEEDED(consoleService->LogStringMessage(
aMessage.BeginReading()))) {
aReport.mMessage.BeginReading()))) {
return;
}
NS_WARNING("LogStringMessage failed!");
}
NS_ConvertUTF16toUTF8 msg(aMessage);
NS_ConvertUTF16toUTF8 filename(aFilename);
NS_ConvertUTF16toUTF8 msg(aReport.mMessage);
NS_ConvertUTF16toUTF8 filename(aReport.mFilename);
static const char kErrorString[] = "JS error in Web Worker: %s [%s:%u]";
#ifdef ANDROID
__android_log_print(ANDROID_LOG_INFO, "Gecko", kErrorString, msg.get(),
filename.get(), aLineNumber);
filename.get(), aReport.mLineNumber);
#endif
fprintf(stderr, kErrorString, msg.get(), filename.get(), aLineNumber);
fprintf(stderr, kErrorString, msg.get(), filename.get(), aReport.mLineNumber);
fflush(stderr);
}
@ -536,10 +544,7 @@ private:
}
if (aWorkerPrivate->IsSharedWorker()) {
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, EmptyString(),
EmptyString(),
EmptyString(), 0, 0,
JSREPORT_ERROR,
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, nullptr,
/* isErrorEvent */ false);
return true;
}
@ -1060,15 +1065,7 @@ private:
class ReportErrorRunnable final : public WorkerRunnable
{
nsString mMessage;
nsString mFilename;
nsString mLine;
uint32_t mLineNumber;
uint32_t mColumnNumber;
uint32_t mFlags;
uint32_t mErrorNumber;
JSExnType mExnType;
bool mMutedError;
WorkerErrorReport mReport;
public:
// aWorkerPrivate is the worker thread we're on (or the main thread, if null)
@ -1077,11 +1074,7 @@ public:
static void
ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aFireAtScope, WorkerPrivate* aTarget,
const nsString& aMessage, const nsString& aFilename,
const nsString& aLine, uint32_t aLineNumber,
uint32_t aColumnNumber, uint32_t aFlags,
uint32_t aErrorNumber, JSExnType aExnType,
bool aMutedError, uint64_t aInnerWindowId,
const WorkerErrorReport& aReport, uint64_t aInnerWindowId,
JS::Handle<JS::Value> aException = JS::NullHandleValue)
{
if (aWorkerPrivate) {
@ -1092,16 +1085,16 @@ public:
// We should not fire error events for warnings but instead make sure that
// they show up in the error console.
if (!JSREPORT_IS_WARNING(aFlags)) {
if (!JSREPORT_IS_WARNING(aReport.mFlags)) {
// First fire an ErrorEvent at the worker.
RootedDictionary<ErrorEventInit> init(aCx);
if (aMutedError) {
if (aReport.mMutedError) {
init.mMessage.AssignLiteral("Script error.");
} else {
init.mMessage = aMessage;
init.mFilename = aFilename;
init.mLineno = aLineNumber;
init.mMessage = aReport.mMessage;
init.mFilename = aReport.mFilename;
init.mLineno = aReport.mLineNumber;
init.mError = aException;
}
@ -1128,7 +1121,8 @@ public:
// into an error event on our parent worker!
// https://bugzilla.mozilla.org/show_bug.cgi?id=1271441 tracks making this
// better.
if (aFireAtScope && (aTarget || aErrorNumber != JSMSG_OVER_RECURSED)) {
if (aFireAtScope &&
(aTarget || aReport.mErrorNumber != JSMSG_OVER_RECURSED)) {
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
NS_ASSERTION(global, "This should never be null!");
@ -1145,8 +1139,8 @@ public:
MOZ_ASSERT_IF(globalScope, globalScope->GetWrapperPreserveColor() == global);
if (globalScope || IsDebuggerSandbox(global)) {
aWorkerPrivate->ReportErrorToDebugger(aFilename, aLineNumber,
aMessage);
aWorkerPrivate->ReportErrorToDebugger(aReport.mFilename, aReport.mLineNumber,
aReport.mMessage);
return;
}
@ -1193,28 +1187,20 @@ public:
// Now fire a runnable to do the same on the parent's thread if we can.
if (aWorkerPrivate) {
RefPtr<ReportErrorRunnable> runnable =
new ReportErrorRunnable(aWorkerPrivate, aMessage, aFilename, aLine,
aLineNumber, aColumnNumber, aFlags,
aErrorNumber, aExnType, aMutedError);
new ReportErrorRunnable(aWorkerPrivate, aReport);
runnable->Dispatch();
return;
}
// Otherwise log an error to the error console.
LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber,
aFlags, aInnerWindowId);
LogErrorToConsole(aReport, aInnerWindowId);
}
private:
ReportErrorRunnable(WorkerPrivate* aWorkerPrivate, const nsString& aMessage,
const nsString& aFilename, const nsString& aLine,
uint32_t aLineNumber, uint32_t aColumnNumber,
uint32_t aFlags, uint32_t aErrorNumber,
JSExnType aExnType, bool aMutedError)
ReportErrorRunnable(WorkerPrivate* aWorkerPrivate,
const WorkerErrorReport& aReport)
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount),
mMessage(aMessage), mFilename(aFilename), mLine(aLine),
mLineNumber(aLineNumber), mColumnNumber(aColumnNumber), mFlags(aFlags),
mErrorNumber(aErrorNumber), mExnType(aExnType), mMutedError(aMutedError)
mReport(aReport)
{ }
virtual void
@ -1251,9 +1237,7 @@ private:
}
if (aWorkerPrivate->IsSharedWorker()) {
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename,
mLine, mLineNumber,
mColumnNumber, mFlags,
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, &mReport,
/* isErrorEvent */ true);
return true;
}
@ -1267,9 +1251,10 @@ private:
swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
aWorkerPrivate->WorkerName(),
aWorkerPrivate->ScriptURL(),
mMessage,
mFilename, mLine, mLineNumber,
mColumnNumber, mFlags, mExnType);
mReport.mMessage,
mReport.mFilename, mReport.mLine, mReport.mLineNumber,
mReport.mColumnNumber, mReport.mFlags,
mReport.mExnType);
}
return true;
}
@ -1289,9 +1274,8 @@ private:
return true;
}
ReportError(aCx, parent, fireAtScope, aWorkerPrivate, mMessage,
mFilename, mLine, mLineNumber, mColumnNumber, mFlags,
mErrorNumber, mExnType, mMutedError, innerWindowId);
ReportError(aCx, parent, fireAtScope, aWorkerPrivate, mReport,
innerWindowId);
return true;
}
};
@ -3314,21 +3298,16 @@ template <class Derived>
void
WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
JSContext* aCx,
const nsAString& aMessage,
const nsAString& aFilename,
const nsAString& aLine,
uint32_t aLineNumber,
uint32_t aColumnNumber,
uint32_t aFlags,
const WorkerErrorReport* aReport,
bool aIsErrorEvent)
{
AssertIsOnMainThread();
if (JSREPORT_IS_WARNING(aFlags)) {
if (aIsErrorEvent && JSREPORT_IS_WARNING(aReport->mFlags)) {
// Don't fire any events anywhere. Just log to console.
// XXXbz should we log to all the consoles of all the relevant windows?
LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber,
aFlags, 0);
MOZ_ASSERT(aReport);
LogErrorToConsole(*aReport, 0);
return;
}
@ -3357,10 +3336,10 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
RootedDictionary<ErrorEventInit> errorInit(aCx);
errorInit.mBubbles = false;
errorInit.mCancelable = true;
errorInit.mMessage = aMessage;
errorInit.mFilename = aFilename;
errorInit.mLineno = aLineNumber;
errorInit.mColno = aColumnNumber;
errorInit.mMessage = aReport->mMessage;
errorInit.mFilename = aReport->mFilename;
errorInit.mLineno = aReport->mLineNumber;
errorInit.mColno = aReport->mColumnNumber;
event = ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"),
errorInit);
@ -3426,9 +3405,9 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
MOZ_ASSERT(NS_IsMainThread());
RootedDictionary<ErrorEventInit> init(aCx);
init.mLineno = aLineNumber;
init.mFilename = aFilename;
init.mMessage = aMessage;
init.mLineno = aReport->mLineNumber;
init.mFilename = aReport->mFilename;
init.mMessage = aReport->mMessage;
init.mCancelable = true;
init.mBubbles = true;
@ -3446,8 +3425,8 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers(
// Finally log a warning in the console if no window tried to prevent it.
if (shouldLogErrorToConsole) {
LogErrorToConsole(aMessage, aFilename, aLine, aLineNumber, aColumnNumber,
aFlags, 0);
MOZ_ASSERT(aReport);
LogErrorToConsole(*aReport, 0);
}
}
@ -4120,7 +4099,10 @@ WorkerDebugger::ReportErrorToDebuggerOnMainThread(const nsAString& aFilename,
listeners[index]->OnError(aFilename, aLineno, aMessage);
}
LogErrorToConsole(aMessage, aFilename, nsString(), aLineno, 0, 0, 0);
WorkerErrorReport report;
report.mMessage = aMessage;
report.mFilename = aFilename;
LogErrorToConsole(report, 0);
}
WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
@ -5925,6 +5907,47 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
return false;
}
void
WorkerErrorBase::AssignErrorBase(JSErrorBase* aReport)
{
mFilename = NS_ConvertUTF8toUTF16(aReport->filename);
mLineNumber = aReport->lineno;
mColumnNumber = aReport->column;
mErrorNumber = aReport->errorNumber;
}
void
WorkerErrorNote::AssignErrorNote(JSErrorNotes::Note* aNote)
{
WorkerErrorBase::AssignErrorBase(aNote);
xpc::ErrorNote::ErrorNoteToMessageString(aNote, mMessage);
}
void
WorkerErrorReport::AssignErrorReport(JSErrorReport* aReport)
{
WorkerErrorBase::AssignErrorBase(aReport);
xpc::ErrorReport::ErrorReportToMessageString(aReport, mMessage);
mLine.Assign(aReport->linebuf(), aReport->linebufLength());
mFlags = aReport->flags;
MOZ_ASSERT(aReport->exnType >= JSEXN_FIRST && aReport->exnType < JSEXN_LIMIT);
mExnType = JSExnType(aReport->exnType);
mMutedError = aReport->isMuted;
if (aReport->notes) {
if (!mNotes.SetLength(aReport->notes->length(), fallible)) {
return;
}
size_t i = 0;
for (auto&& note : *aReport->notes) {
mNotes.ElementAt(i).AssignErrorNote(note.get());
i++;
}
}
}
void
WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
JSErrorReport* aReport)
@ -5947,32 +5970,17 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
}
JS_ClearPendingException(aCx);
nsString message, filename, line;
uint32_t lineNumber, columnNumber, flags, errorNumber;
JSExnType exnType = JSEXN_ERR;
bool mutedError = aReport && aReport->isMuted;
WorkerErrorReport report;
if (aReport) {
// We want the same behavior here as xpc::ErrorReport::init here.
xpc::ErrorReport::ErrorReportToMessageString(aReport, message);
filename = NS_ConvertUTF8toUTF16(aReport->filename);
line.Assign(aReport->linebuf(), aReport->linebufLength());
lineNumber = aReport->lineno;
columnNumber = aReport->tokenOffset();
flags = aReport->flags;
errorNumber = aReport->errorNumber;
MOZ_ASSERT(aReport->exnType >= JSEXN_FIRST && aReport->exnType < JSEXN_LIMIT);
exnType = JSExnType(aReport->exnType);
report.AssignErrorReport(aReport);
}
else {
lineNumber = columnNumber = errorNumber = 0;
flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
report.mFlags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
}
if (message.IsEmpty() && aToStringResult) {
if (report.mMessage.IsEmpty() && aToStringResult) {
nsDependentCString toStringResult(aToStringResult.c_str());
if (!AppendUTF8toUTF16(toStringResult, message, mozilla::fallible)) {
if (!AppendUTF8toUTF16(toStringResult, report.mMessage, mozilla::fallible)) {
// Try again, with only a 1 KB string. Do this infallibly this time.
// If the user doesn't have 1 KB to spare we're done anyways.
uint32_t index = std::min(uint32_t(1024), toStringResult.Length());
@ -5982,7 +5990,7 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
nsDependentCString truncatedToStringResult(aToStringResult.c_str(),
index);
AppendUTF8toUTF16(truncatedToStringResult, message);
AppendUTF8toUTF16(truncatedToStringResult, report.mMessage);
}
}
@ -5991,13 +5999,11 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
// Don't want to run the scope's error handler if this is a recursive error or
// if we ran out of memory.
bool fireAtScope = mErrorHandlerRecursionCount == 1 &&
errorNumber != JSMSG_OUT_OF_MEMORY &&
report.mErrorNumber != JSMSG_OUT_OF_MEMORY &&
JS::CurrentGlobalOrNull(aCx);
ReportErrorRunnable::ReportError(aCx, this, fireAtScope, nullptr, message,
filename, line, lineNumber,
columnNumber, flags, errorNumber, exnType,
mutedError, 0, exn);
ReportErrorRunnable::ReportError(aCx, this, fireAtScope, nullptr, report, 0,
exn);
mErrorHandlerRecursionCount--;
}

View file

@ -140,6 +140,45 @@ public:
}
};
class WorkerErrorBase {
public:
nsString mMessage;
nsString mFilename;
uint32_t mLineNumber;
uint32_t mColumnNumber;
uint32_t mErrorNumber;
WorkerErrorBase()
: mLineNumber(0),
mColumnNumber(0),
mErrorNumber(0)
{ }
void AssignErrorBase(JSErrorBase* aReport);
};
class WorkerErrorNote : public WorkerErrorBase {
public:
void AssignErrorNote(JSErrorNotes::Note* aNote);
};
class WorkerErrorReport : public WorkerErrorBase {
public:
nsString mLine;
uint32_t mFlags;
JSExnType mExnType;
bool mMutedError;
nsTArray<WorkerErrorNote> mNotes;
WorkerErrorReport()
: mFlags(0),
mExnType(JSEXN_ERR),
mMutedError(false)
{ }
void AssignErrorReport(JSErrorReport* aReport);
};
template <class Derived>
class WorkerPrivateParent : public DOMEventTargetHelper
{
@ -401,12 +440,7 @@ public:
void
BroadcastErrorToSharedWorkers(JSContext* aCx,
const nsAString& aMessage,
const nsAString& aFilename,
const nsAString& aLine,
uint32_t aLineNumber,
uint32_t aColumnNumber,
uint32_t aFlags,
const WorkerErrorReport* aReport,
bool aIsErrorEvent);
void

View file

@ -94,6 +94,7 @@ LOCAL_INCLUDES += [
'../base',
'../system',
'/dom/base',
'/dom/bindings',
'/xpcom/build',
'/xpcom/threads',
]

View file

@ -23,7 +23,7 @@
const errorFilename = href.substring(0, href.lastIndexOf("/") + 1) +
filename;
const errorLine = 91;
const errorColumn = 0;
const errorColumn = 11;
var worker = new SharedWorker(filename);