mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 691a1d12372a (bug 620935) for m13 perma orange on a CLOSED TREE
This commit is contained in:
parent
e04fe7ce7c
commit
f27222213d
@ -34710,8 +34710,41 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
|
||||
|
||||
var consoleTimer = {};
|
||||
|
||||
var workerConsole = {
|
||||
log: function log() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
globalScope.postMessage({
|
||||
action: 'console_log',
|
||||
data: args
|
||||
});
|
||||
},
|
||||
|
||||
error: function error() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
globalScope.postMessage({
|
||||
action: 'console_error',
|
||||
data: args
|
||||
});
|
||||
throw 'pdf.js execution error';
|
||||
},
|
||||
|
||||
time: function time(name) {
|
||||
consoleTimer[name] = Date.now();
|
||||
},
|
||||
|
||||
timeEnd: function timeEnd(name) {
|
||||
var time = consoleTimer[name];
|
||||
if (!time) {
|
||||
error('Unkown timer name ' + name);
|
||||
}
|
||||
this.log('Timer:', name, Date.now() - time);
|
||||
}
|
||||
};
|
||||
|
||||
// Worker thread?
|
||||
if (typeof window === 'undefined') {
|
||||
globalScope.console = workerConsole;
|
||||
|
||||
// Add a logger so we can pass warnings on to the main thread, errors will
|
||||
// throw an exception which will be forwarded on automatically.
|
||||
PDFJS.LogManager.addLogger({
|
||||
|
@ -214,22 +214,19 @@ ConsoleAPI.prototype = {
|
||||
|
||||
/**
|
||||
* Queue a call to a console method. See the CALL_DELAY constant.
|
||||
* This method is the entry point for the console.* for workers.
|
||||
*
|
||||
* @param string aMethod
|
||||
* The console method the code has invoked.
|
||||
* @param object aArguments
|
||||
* The arguments passed to the console method.
|
||||
* @param array aStack
|
||||
* The stack of the console method. Used by console.* for workers.
|
||||
*/
|
||||
queueCall: function CA_queueCall(aMethod, aArguments, aStack = null)
|
||||
queueCall: function CA_queueCall(aMethod, aArguments)
|
||||
{
|
||||
let window = this._window.get();
|
||||
let metaForCall = {
|
||||
private: PrivateBrowsingUtils.isWindowPrivate(window),
|
||||
timeStamp: Date.now(),
|
||||
stack: (aStack ? aStack : this.getStackTrace(aMethod != "trace" ? 1 : null)),
|
||||
stack: this.getStackTrace(aMethod != "trace" ? 1 : null),
|
||||
};
|
||||
|
||||
if (aMethod == "time" || aMethod == "timeEnd") {
|
||||
|
@ -1528,12 +1528,6 @@ DOMInterfaces = {
|
||||
],
|
||||
},
|
||||
|
||||
'WorkerConsole': {
|
||||
'headerFile': 'mozilla/dom/workers/bindings/Console.h',
|
||||
'workers': True,
|
||||
'implicitJSContext': [ 'trace', 'time', 'timeEnd' ],
|
||||
},
|
||||
|
||||
'WorkerLocation': {
|
||||
'headerFile': 'mozilla/dom/workers/bindings/Location.h',
|
||||
'workers': True,
|
||||
|
@ -281,7 +281,7 @@ public:
|
||||
virtual ~JSStackFrame();
|
||||
|
||||
static already_AddRefed<nsIStackFrame>
|
||||
CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
|
||||
CreateStack(JSContext* cx);
|
||||
static already_AddRefed<nsIStackFrame>
|
||||
CreateStackFrameLocation(uint32_t aLanguage,
|
||||
const char* aFilename,
|
||||
@ -495,14 +495,11 @@ NS_IMETHODIMP JSStackFrame::ToString(nsACString& _retval)
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIStackFrame>
|
||||
JSStackFrame::CreateStack(JSContext* aCx, int32_t aMaxDepth)
|
||||
JSStackFrame::CreateStack(JSContext* cx)
|
||||
{
|
||||
static const unsigned MAX_FRAMES = 100;
|
||||
if (aMaxDepth < 0) {
|
||||
aMaxDepth = MAX_FRAMES;
|
||||
}
|
||||
|
||||
JS::StackDescription* desc = JS::DescribeStack(aCx, aMaxDepth);
|
||||
JS::StackDescription* desc = JS::DescribeStack(cx, MAX_FRAMES);
|
||||
if (!desc) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -533,9 +530,9 @@ JSStackFrame::CreateStackFrameLocation(uint32_t aLanguage,
|
||||
}
|
||||
|
||||
already_AddRefed<nsIStackFrame>
|
||||
CreateStack(JSContext* aCx, int32_t aMaxDepth)
|
||||
CreateStack(JSContext* cx)
|
||||
{
|
||||
return JSStackFrame::CreateStack(aCx, aMaxDepth);
|
||||
return JSStackFrame::CreateStack(cx);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIStackFrame>
|
||||
|
@ -36,10 +36,8 @@ GetCurrentJSStack();
|
||||
// Internal stuff not intended to be widely used.
|
||||
namespace exceptions {
|
||||
|
||||
// aMaxDepth can be used to define a maximal depth for the stack trace. If the
|
||||
// value is -1, a default maximal depth will be selected.
|
||||
already_AddRefed<nsIStackFrame>
|
||||
CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
|
||||
CreateStack(JSContext* cx);
|
||||
|
||||
already_AddRefed<nsIStackFrame>
|
||||
CreateStackFrameLocation(uint32_t aLanguage,
|
||||
|
@ -1,35 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
|
||||
interface WorkerConsole {
|
||||
void log(any... data);
|
||||
void info(any... data);
|
||||
void warn(any... data);
|
||||
void error(any... data);
|
||||
void _exception(any... data);
|
||||
void debug(any... data);
|
||||
void trace();
|
||||
void dir(optional any data);
|
||||
void group(any... data);
|
||||
void groupCollapsed(any... data);
|
||||
void groupEnd(any... data);
|
||||
void time(optional any time);
|
||||
void timeEnd(optional any time);
|
||||
void profile(any... data);
|
||||
void profileEnd(any... data);
|
||||
void assert(boolean condition, any... data);
|
||||
void ___noSuchMethod__();
|
||||
};
|
||||
|
||||
// This dictionary is used internally to send the stack trace from the worker to
|
||||
// the main thread Console API implementation.
|
||||
dictionary WorkerConsoleStack {
|
||||
DOMString filename = "";
|
||||
unsigned long lineNumber = 0;
|
||||
DOMString functionName = "";
|
||||
unsigned long language = 0;
|
||||
};
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
interface WorkerGlobalScope : EventTarget {
|
||||
readonly attribute WorkerGlobalScope self;
|
||||
readonly attribute WorkerConsole console;
|
||||
readonly attribute WorkerLocation location;
|
||||
|
||||
void close();
|
||||
|
@ -428,7 +428,6 @@ WEBIDL_FILES = [
|
||||
'WheelEvent.webidl',
|
||||
'WifiOptions.webidl',
|
||||
'Worker.webidl',
|
||||
'WorkerConsole.webidl',
|
||||
'WorkerGlobalScope.webidl',
|
||||
'WorkerLocation.webidl',
|
||||
'WorkerNavigator.webidl',
|
||||
|
@ -1,561 +0,0 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* 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 "Console.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/OldDebugAPI.h"
|
||||
|
||||
#include "nsJSUtils.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIDOMGlobalPropertyInitializer.h"
|
||||
|
||||
#include "mozilla/dom/WorkerConsoleBinding.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
|
||||
#define CONSOLE_TAG JS_SCTAG_USER_MIN
|
||||
|
||||
// From dom/base/ConsoleAPI.js
|
||||
#define DEFAULT_MAX_STACKTRACE_DEPTH 200
|
||||
|
||||
using namespace mozilla::dom::exceptions;
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class ConsoleProxy
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy)
|
||||
|
||||
bool
|
||||
Init(JSContext* aCx, nsPIDOMWindow* aWindow)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// Console API:
|
||||
nsCOMPtr<nsISupports> cInstance =
|
||||
do_CreateInstance("@mozilla.org/console-api;1");
|
||||
|
||||
nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
|
||||
do_QueryInterface(cInstance);
|
||||
NS_ENSURE_TRUE(gpi, false);
|
||||
|
||||
// We don't do anything with the return value.
|
||||
JS::Rooted<JS::Value> prop_val(aCx);
|
||||
if (NS_FAILED(gpi->Init(aWindow, &prop_val))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mXpcwrappedjs = do_QueryInterface(cInstance);
|
||||
NS_ENSURE_TRUE(mXpcwrappedjs, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsIXPConnectWrappedJS*
|
||||
GetWrappedJS() const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return mXpcwrappedjs;
|
||||
}
|
||||
|
||||
void ReleaseWrappedJS()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mXpcwrappedjs = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIXPConnectWrappedJS> mXpcwrappedjs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Console API in workers uses the Structured Clone Algorithm to move any value
|
||||
* from the worker thread to the main-thread. Some object cannot be moved and,
|
||||
* in these cases, we convert them to strings.
|
||||
* It's not the best, but at least we are able to show something.
|
||||
*/
|
||||
|
||||
// This method is called by the Structured Clone Algorithm when some data has
|
||||
// to be read.
|
||||
static JSObject*
|
||||
ConsoleStructuredCloneCallbacksRead(JSContext* aCx,
|
||||
JSStructuredCloneReader* /* unused */,
|
||||
uint32_t aTag, uint32_t aData,
|
||||
void* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (aTag != CONSOLE_TAG) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<nsString>* strings = static_cast<nsTArray<nsString>*>(aClosure);
|
||||
if (strings->Length() <= aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!xpc::StringToJsval(aCx, strings->ElementAt(aData), &value)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx);
|
||||
if (!JS_ValueToObject(aCx, value, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// This method is called by the Structured Clone Algorithm when some data has
|
||||
// to be written.
|
||||
static bool
|
||||
ConsoleStructuredCloneCallbacksWrite(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
void* aClosure)
|
||||
{
|
||||
JS::Rooted<JS::Value> value(aCx, JS::ObjectOrNullValue(aObj));
|
||||
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, value));
|
||||
if (!jsString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsDependentJSString string;
|
||||
if (!string.init(aCx, jsString)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsTArray<nsString>* strings = static_cast<nsTArray<nsString>*>(aClosure);
|
||||
|
||||
if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG, strings->Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
strings->AppendElement(string);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ConsoleStructuredCloneCallbacksError(JSContext* /* aCx */,
|
||||
uint32_t /* aErrorId */)
|
||||
{
|
||||
NS_WARNING("Failed to clone data for the Console API in workers.");
|
||||
}
|
||||
|
||||
JSStructuredCloneCallbacks gConsoleCallbacks = {
|
||||
ConsoleStructuredCloneCallbacksRead,
|
||||
ConsoleStructuredCloneCallbacksWrite,
|
||||
ConsoleStructuredCloneCallbacksError
|
||||
};
|
||||
|
||||
class ConsoleStackData
|
||||
{
|
||||
public:
|
||||
ConsoleStackData()
|
||||
: mLineNumber(0)
|
||||
{}
|
||||
|
||||
nsCString mFilename;
|
||||
uint32_t mLineNumber;
|
||||
nsCString mFunctionName;
|
||||
};
|
||||
|
||||
class ConsoleRunnable MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit ConsoleRunnable(WorkerConsole* aConsole,
|
||||
WorkerPrivate* aWorkerPrivate)
|
||||
: mConsole(aConsole)
|
||||
, mWorkerPrivate(aWorkerPrivate)
|
||||
, mMethod(nullptr)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
bool
|
||||
Dispatch(JSContext* aCx,
|
||||
const char* aMethod,
|
||||
JS::Handle<JS::Value> aArguments,
|
||||
nsTArray<ConsoleStackData>& aStackData)
|
||||
{
|
||||
mMethod = aMethod;
|
||||
mStackData.SwapElements(aStackData);
|
||||
|
||||
if (!mArguments.write(aCx, aArguments, &gConsoleCallbacks, &mStrings)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
return false;
|
||||
}
|
||||
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
|
||||
|
||||
mSyncLoopTarget = syncLoop.EventTarget();
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
|
||||
JS_ReportError(aCx,
|
||||
"Failed to dispatch to main thread for the "
|
||||
"Console API (method %s)!", mMethod);
|
||||
return false;
|
||||
}
|
||||
|
||||
return syncLoop.Run();
|
||||
}
|
||||
|
||||
private:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RunConsole();
|
||||
|
||||
nsRefPtr<MainThreadStopSyncLoopRunnable> response =
|
||||
new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
|
||||
mSyncLoopTarget.forget(),
|
||||
true);
|
||||
if (!response->Dispatch(nullptr)) {
|
||||
NS_WARNING("Failed to dispatch response!");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
RunConsole()
|
||||
{
|
||||
// This class is used to clear any exception at the end of this method.
|
||||
class ClearException
|
||||
{
|
||||
public:
|
||||
ClearException(JSContext* aCx)
|
||||
: mCx(aCx)
|
||||
{
|
||||
}
|
||||
|
||||
~ClearException()
|
||||
{
|
||||
JS_ClearPendingException(mCx);
|
||||
}
|
||||
|
||||
private:
|
||||
JSContext* mCx;
|
||||
};
|
||||
|
||||
// Walk up to our containing page
|
||||
WorkerPrivate* wp = mWorkerPrivate;
|
||||
while (wp->GetParent()) {
|
||||
wp = wp->GetParent();
|
||||
}
|
||||
|
||||
AutoPushJSContext cx(wp->ParentJSContext());
|
||||
JSAutoRequest ar(cx);
|
||||
ClearException ce(cx);
|
||||
|
||||
nsRefPtr<ConsoleProxy> proxy = mConsole->GetProxy();
|
||||
if (!proxy) {
|
||||
nsPIDOMWindow* window = wp->GetWindow();
|
||||
NS_ENSURE_TRUE_VOID(window);
|
||||
|
||||
proxy = new ConsoleProxy();
|
||||
if (!proxy->Init(cx, window)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mConsole->SetProxy(proxy);
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> consoleObj(cx, proxy->GetWrappedJS()->GetJSObject());
|
||||
NS_ENSURE_TRUE_VOID(consoleObj);
|
||||
|
||||
JSAutoCompartment ac(cx, consoleObj);
|
||||
|
||||
// 3 args for the queueCall.
|
||||
nsDependentCString method(mMethod);
|
||||
|
||||
JS::Rooted<JS::Value> methodValue(cx);
|
||||
if (!ByteStringToJsval(cx, method, &methodValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> argumentsValue(cx);
|
||||
if (!mArguments.read(cx, &argumentsValue, &gConsoleCallbacks, &mStrings)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> stackValue(cx);
|
||||
{
|
||||
JS::Rooted<JSObject*> stackObj(cx,
|
||||
JS_NewArrayObject(cx, mStackData.Length(), nullptr));
|
||||
if (!stackObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mStackData.Length(); ++i) {
|
||||
WorkerConsoleStack stack;
|
||||
|
||||
CopyUTF8toUTF16(mStackData[i].mFilename, stack.mFilename);
|
||||
|
||||
CopyUTF8toUTF16(mStackData[i].mFunctionName, stack.mFunctionName);
|
||||
|
||||
stack.mLineNumber = mStackData[i].mLineNumber;
|
||||
|
||||
stack.mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
if (!stack.ToObject(cx, JS::NullPtr(), &value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!JS_DefineElement(cx, stackObj, i, value, nullptr, nullptr, 0)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stackValue = JS::ObjectValue(*stackObj);
|
||||
}
|
||||
|
||||
JS::AutoValueVector argv(cx);
|
||||
if (!argv.resize(3)) {
|
||||
return;
|
||||
}
|
||||
|
||||
argv[0] = methodValue;
|
||||
argv[1] = argumentsValue;
|
||||
argv[2] = stackValue;
|
||||
|
||||
JS::Rooted<JS::Value> ret(cx);
|
||||
JS_CallFunctionName(cx, consoleObj, "queueCall", argv.length(),
|
||||
argv.begin(), ret.address());
|
||||
}
|
||||
|
||||
WorkerConsole* mConsole;
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||
|
||||
const char* mMethod;
|
||||
JSAutoStructuredCloneBuffer mArguments;
|
||||
nsTArray<ConsoleStackData> mStackData;
|
||||
|
||||
nsTArray<nsString> mStrings;
|
||||
};
|
||||
|
||||
class TeardownRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
TeardownRunnable(ConsoleProxy* aProxy)
|
||||
: mProxy(aProxy)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mProxy->ReleaseWrappedJS();
|
||||
mProxy = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<ConsoleProxy> mProxy;
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WorkerConsole)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WorkerConsole, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WorkerConsole, Release)
|
||||
|
||||
/* static */ already_AddRefed<WorkerConsole>
|
||||
WorkerConsole::Create()
|
||||
{
|
||||
nsRefPtr<WorkerConsole> console = new WorkerConsole();
|
||||
return console.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
WorkerConsole::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||
{
|
||||
return WorkerConsoleBinding_workers::Wrap(aCx, aScope, this);
|
||||
}
|
||||
|
||||
WorkerConsole::WorkerConsole()
|
||||
{
|
||||
MOZ_COUNT_CTOR(WorkerConsole);
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
WorkerConsole::~WorkerConsole()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WorkerConsole);
|
||||
|
||||
if (mProxy) {
|
||||
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mProxy);
|
||||
mProxy = nullptr;
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
NS_ERROR("Failed to dispatch teardown runnable!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorkerConsole::SetProxy(ConsoleProxy* aProxy)
|
||||
{
|
||||
MOZ_ASSERT(!mProxy);
|
||||
mProxy = aProxy;
|
||||
}
|
||||
|
||||
void
|
||||
WorkerConsole::Method(JSContext* aCx, const char* aMethodName,
|
||||
const Sequence<JS::Value>& aData,
|
||||
uint32_t aStackLevel)
|
||||
{
|
||||
nsCOMPtr<nsIStackFrame> stack = CreateStack(aCx, aStackLevel);
|
||||
if (!stack) {
|
||||
return;
|
||||
}
|
||||
|
||||
// nsIStackFrame is not thread-safe so we take what we need and we store in
|
||||
// an array of ConsoleStackData objects.
|
||||
nsTArray<ConsoleStackData> stackData;
|
||||
while (stack) {
|
||||
ConsoleStackData& data = *stackData.AppendElement();
|
||||
|
||||
if (NS_FAILED(stack->GetFilename(data.mFilename))) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t lineNumber;
|
||||
if (NS_FAILED(stack->GetLineNumber(&lineNumber))) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.mLineNumber = lineNumber;
|
||||
|
||||
if (NS_FAILED(stack->GetName(data.mFunctionName))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStackFrame> caller;
|
||||
if (NS_FAILED(stack->GetCaller(getter_AddRefs(caller)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
stack.swap(caller);
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> arguments(aCx,
|
||||
JS_NewArrayObject(aCx, aData.Length(), nullptr));
|
||||
if (!arguments) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aData.Length(); ++i) {
|
||||
if (!JS_DefineElement(aCx, arguments, i, aData[i], nullptr, nullptr,
|
||||
JSPROP_ENUMERATE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
JS::Rooted<JS::Value> argumentsValue(aCx, JS::ObjectValue(*arguments));
|
||||
|
||||
WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
|
||||
MOZ_ASSERT(worker);
|
||||
|
||||
nsRefPtr<ConsoleRunnable> runnable = new ConsoleRunnable(this, worker);
|
||||
runnable->Dispatch(aCx, aMethodName, argumentsValue, stackData);
|
||||
}
|
||||
|
||||
#define METHOD(name, jsName) \
|
||||
void \
|
||||
WorkerConsole::name(JSContext* aCx, \
|
||||
const Sequence<JS::Value>& aData) \
|
||||
{ \
|
||||
Method(aCx, jsName, aData, 1); \
|
||||
}
|
||||
|
||||
METHOD(Log, "log")
|
||||
METHOD(Info, "info")
|
||||
METHOD(Warn, "warn")
|
||||
METHOD(Error, "error")
|
||||
METHOD(Exception, "exception")
|
||||
METHOD(Debug, "debug")
|
||||
|
||||
void
|
||||
WorkerConsole::Trace(JSContext* aCx)
|
||||
{
|
||||
Sequence<JS::Value> data;
|
||||
Method(aCx, "trace", data, DEFAULT_MAX_STACKTRACE_DEPTH);
|
||||
}
|
||||
|
||||
void
|
||||
WorkerConsole::Dir(JSContext* aCx,
|
||||
const Optional<JS::Handle<JS::Value>>& aValue)
|
||||
{
|
||||
Sequence<JS::Value> data;
|
||||
|
||||
if (aValue.WasPassed()) {
|
||||
data.AppendElement(aValue.Value());
|
||||
}
|
||||
|
||||
Method(aCx, "dir", data, 1);
|
||||
}
|
||||
|
||||
METHOD(Group, "group")
|
||||
METHOD(GroupCollapsed, "groupCollapsed")
|
||||
METHOD(GroupEnd, "groupEnd")
|
||||
|
||||
void
|
||||
WorkerConsole::Time(JSContext* aCx,
|
||||
const Optional<JS::Handle<JS::Value>>& aTimer)
|
||||
{
|
||||
Sequence<JS::Value> data;
|
||||
|
||||
if (aTimer.WasPassed()) {
|
||||
data.AppendElement(aTimer.Value());
|
||||
}
|
||||
|
||||
Method(aCx, "time", data, 1);
|
||||
}
|
||||
|
||||
void
|
||||
WorkerConsole::TimeEnd(JSContext* aCx,
|
||||
const Optional<JS::Handle<JS::Value>>& aTimer)
|
||||
{
|
||||
Sequence<JS::Value> data;
|
||||
|
||||
if (aTimer.WasPassed()) {
|
||||
data.AppendElement(aTimer.Value());
|
||||
}
|
||||
|
||||
Method(aCx, "timeEnd", data, 1);
|
||||
}
|
||||
|
||||
METHOD(Profile, "profile")
|
||||
METHOD(ProfileEnd, "profileEnd")
|
||||
|
||||
void
|
||||
WorkerConsole::Assert(JSContext* aCx, bool aCondition,
|
||||
const Sequence<JS::Value>& aData)
|
||||
{
|
||||
if (!aCondition) {
|
||||
Method(aCx, "assert", aData, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorkerConsole::__noSuchMethod__()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
#undef METHOD
|
||||
|
||||
END_WORKERS_NAMESPACE
|
@ -1,112 +0,0 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* 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_workers_Console_h
|
||||
#define mozilla_dom_workers_Console_h
|
||||
|
||||
#include "Workers.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class ConsoleProxy;
|
||||
class ConsoleStackData;
|
||||
|
||||
class WorkerConsole MOZ_FINAL : public nsWrapperCache
|
||||
{
|
||||
WorkerConsole();
|
||||
|
||||
public:
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WorkerConsole)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WorkerConsole)
|
||||
|
||||
static already_AddRefed<WorkerConsole>
|
||||
Create();
|
||||
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
~WorkerConsole();
|
||||
|
||||
ConsoleProxy*
|
||||
GetProxy() const
|
||||
{
|
||||
return mProxy;
|
||||
}
|
||||
|
||||
void
|
||||
SetProxy(ConsoleProxy* aProxy);
|
||||
|
||||
// WebIDL methods
|
||||
|
||||
void
|
||||
Log(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Info(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Warn(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Error(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Exception(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Debug(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Trace(JSContext* aCx);
|
||||
|
||||
void
|
||||
Dir(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aValue);
|
||||
|
||||
void
|
||||
Group(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
GroupCollapsed(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
GroupEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Time(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aTimer);
|
||||
|
||||
void
|
||||
TimeEnd(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aTimer);
|
||||
|
||||
void
|
||||
Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Assert(JSContext* aCx, bool aCondition, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
__noSuchMethod__();
|
||||
|
||||
private:
|
||||
void
|
||||
Method(JSContext* aCx, const char* aMethodName,
|
||||
const Sequence<JS::Value>& aData, uint32_t aMaxStackDepth);
|
||||
|
||||
nsRefPtr<ConsoleProxy> mProxy;
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
#endif // mozilla_dom_workers_Console_h
|
@ -15,7 +15,6 @@
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#include "Console.h"
|
||||
#include "Location.h"
|
||||
#include "Navigator.h"
|
||||
#include "Principal.h"
|
||||
@ -78,19 +77,6 @@ WorkerGlobalScope::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||
MOZ_CRASH("We should never get here!");
|
||||
}
|
||||
|
||||
WorkerConsole*
|
||||
WorkerGlobalScope::Console()
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (!mConsole) {
|
||||
mConsole = WorkerConsole::Create();
|
||||
MOZ_ASSERT(mConsole);
|
||||
}
|
||||
|
||||
return mConsole;
|
||||
}
|
||||
|
||||
already_AddRefed<WorkerLocation>
|
||||
WorkerGlobalScope::Location()
|
||||
{
|
||||
|
@ -20,14 +20,12 @@ class Function;
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class WorkerPrivate;
|
||||
class WorkerConsole;
|
||||
class WorkerLocation;
|
||||
class WorkerNavigator;
|
||||
|
||||
class WorkerGlobalScope : public nsDOMEventTargetHelper,
|
||||
public nsIGlobalObject
|
||||
{
|
||||
nsRefPtr<WorkerConsole> mConsole;
|
||||
nsRefPtr<WorkerLocation> mLocation;
|
||||
nsRefPtr<WorkerNavigator> mNavigator;
|
||||
|
||||
@ -60,9 +58,6 @@ public:
|
||||
return nsRefPtr<WorkerGlobalScope>(this).forget();
|
||||
}
|
||||
|
||||
WorkerConsole*
|
||||
Console();
|
||||
|
||||
already_AddRefed<WorkerLocation>
|
||||
Location();
|
||||
|
||||
|
@ -19,7 +19,6 @@ EXPORTS.mozilla.dom.workers += [
|
||||
|
||||
# Stuff needed for the bindings, not really public though.
|
||||
EXPORTS.mozilla.dom.workers.bindings += [
|
||||
'Console.h',
|
||||
'FileReaderSync.h',
|
||||
'Location.h',
|
||||
'MessagePort.h',
|
||||
@ -33,7 +32,6 @@ EXPORTS.mozilla.dom.workers.bindings += [
|
||||
|
||||
SOURCES += [
|
||||
'ChromeWorkerScope.cpp',
|
||||
'Console.cpp',
|
||||
'File.cpp',
|
||||
'FileReaderSync.cpp',
|
||||
'Location.cpp',
|
||||
|
@ -1,104 +0,0 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
onmessage = function(event) {
|
||||
// TEST: does console exist?
|
||||
postMessage({event: 'console exists', status: !!console, last : false});
|
||||
|
||||
postMessage({event: 'trace without function', status: true, last : false});
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
console.what('1', 123, 321);
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
console.log(i, i, i);
|
||||
}
|
||||
|
||||
function trace1() {
|
||||
function trace2() {
|
||||
function trace3() {
|
||||
console.trace("trace " + i);
|
||||
}
|
||||
trace3();
|
||||
}
|
||||
trace2();
|
||||
}
|
||||
trace1();
|
||||
|
||||
foobar585956c = function(a) {
|
||||
console.trace();
|
||||
return a+"c";
|
||||
};
|
||||
|
||||
function foobar585956b(a) {
|
||||
return foobar585956c(a+"b");
|
||||
}
|
||||
|
||||
function foobar585956a(omg) {
|
||||
return foobar585956b(omg + "a");
|
||||
}
|
||||
|
||||
function foobar646025(omg) {
|
||||
console.log(omg, "o", "d");
|
||||
}
|
||||
|
||||
function startTimer(timer) {
|
||||
console.time(timer);
|
||||
}
|
||||
|
||||
function stopTimer(timer) {
|
||||
console.timeEnd(timer);
|
||||
}
|
||||
|
||||
function testGroups() {
|
||||
console.groupCollapsed("a", "group");
|
||||
console.group("b", "group");
|
||||
console.groupEnd("b", "group");
|
||||
}
|
||||
|
||||
foobar585956a('omg');
|
||||
foobar646025('omg');
|
||||
testGroups();
|
||||
startTimer('foo');
|
||||
setTimeout(function() {
|
||||
stopTimer('foo');
|
||||
nextSteps(event);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function nextSteps(event) {
|
||||
|
||||
function namelessTimer() {
|
||||
console.time();
|
||||
console.timeEnd();
|
||||
}
|
||||
|
||||
namelessTimer();
|
||||
|
||||
var str = "Test Message."
|
||||
console.foobar(str); // if this throws, we don't execute following funcs
|
||||
console.log(str);
|
||||
console.info(str);
|
||||
console.warn(str);
|
||||
console.error(str);
|
||||
console.exception(str);
|
||||
console.assert(true, str);
|
||||
console.assert(false, str);
|
||||
console.profile(str);
|
||||
console.profileEnd(str);
|
||||
postMessage({event: '4 messages', status: true, last : false});
|
||||
|
||||
// Recursive:
|
||||
if (event.data == true) {
|
||||
var worker = new Worker('console_worker.js');
|
||||
worker.onmessage = function(event) {
|
||||
postMessage(event.data);
|
||||
}
|
||||
worker.postMessage(false);
|
||||
} else {
|
||||
postMessage({event: 'bye bye', status: true, last : true});
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ support-files =
|
||||
closeOnGC_worker.js
|
||||
close_worker.js
|
||||
content_worker.js
|
||||
console_worker.js
|
||||
csp_worker.js
|
||||
errorPropagation_iframe.html
|
||||
errorPropagation_worker.js
|
||||
@ -21,7 +20,6 @@ support-files =
|
||||
importScripts_worker_imported4.js
|
||||
instanceof_worker.js
|
||||
json_worker.js
|
||||
jsversion_worker.js
|
||||
loadEncoding_worker.js
|
||||
location_worker.js
|
||||
longThread_worker.js
|
||||
@ -61,6 +59,7 @@ support-files =
|
||||
xhr_implicit_cancel_worker.js
|
||||
xhr_worker.js
|
||||
url_exceptions_worker.js
|
||||
jsversion_worker.js
|
||||
urlSearchParams_worker.js
|
||||
subdir/relativeLoad_sub_worker.js
|
||||
subdir/relativeLoad_sub_worker2.js
|
||||
@ -74,7 +73,6 @@ support-files =
|
||||
[test_clearTimeouts.html]
|
||||
[test_close.html]
|
||||
[test_closeOnGC.html]
|
||||
[test_console.html]
|
||||
[test_contentWorker.html]
|
||||
[test_csp.html]
|
||||
[test_csp.html^headers^]
|
||||
@ -87,7 +85,6 @@ support-files =
|
||||
[test_importScripts.html]
|
||||
[test_instanceof.html]
|
||||
[test_json.html]
|
||||
[test_jsversion.html]
|
||||
[test_loadEncoding.html]
|
||||
[test_loadError.html]
|
||||
[test_location.html]
|
||||
@ -128,3 +125,4 @@ support-files =
|
||||
skip-if = (os == "win") || (os == "mac")
|
||||
[test_url_exceptions.html]
|
||||
[test_urlSearchParams.html]
|
||||
[test_jsversion.html]
|
||||
|
@ -1,44 +0,0 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Tests of DOM Worker Console
|
||||
-->
|
||||
<head>
|
||||
<title>Test for DOM Worker Console</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" language="javascript">
|
||||
var worker = new Worker("console_worker.js");
|
||||
|
||||
worker.onmessage = function(event) {
|
||||
is(event.target, worker, "Worker and target match!");
|
||||
ok(event.data.status, event.data.event);
|
||||
|
||||
if (!event.data.status || event.data.last)
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
worker.onerror = function(event) {
|
||||
ok(false, "Worker had an error: " + event.message);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
worker.postMessage(true);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user