зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changesets fbc3bb6c002f and 3da2b2a2899b (bug 620935) for debug B2G mochitest-13 crashes.
This commit is contained in:
Родитель
681cf0665c
Коммит
49c724dc8b
|
@ -34710,8 +34710,41 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
|
||||||
|
|
||||||
var consoleTimer = {};
|
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?
|
// Worker thread?
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
|
globalScope.console = workerConsole;
|
||||||
|
|
||||||
// Add a logger so we can pass warnings on to the main thread, errors will
|
// Add a logger so we can pass warnings on to the main thread, errors will
|
||||||
// throw an exception which will be forwarded on automatically.
|
// throw an exception which will be forwarded on automatically.
|
||||||
PDFJS.LogManager.addLogger({
|
PDFJS.LogManager.addLogger({
|
||||||
|
|
|
@ -214,22 +214,19 @@ ConsoleAPI.prototype = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue a call to a console method. See the CALL_DELAY constant.
|
* 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
|
* @param string aMethod
|
||||||
* The console method the code has invoked.
|
* The console method the code has invoked.
|
||||||
* @param object aArguments
|
* @param object aArguments
|
||||||
* The arguments passed to the console method.
|
* 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 window = this._window.get();
|
||||||
let metaForCall = {
|
let metaForCall = {
|
||||||
private: PrivateBrowsingUtils.isWindowPrivate(window),
|
private: PrivateBrowsingUtils.isWindowPrivate(window),
|
||||||
timeStamp: Date.now(),
|
timeStamp: Date.now(),
|
||||||
stack: (aStack ? aStack : this.getStackTrace(aMethod != "trace" ? 1 : null)),
|
stack: this.getStackTrace(aMethod != "trace" ? 1 : null),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (aMethod == "time" || aMethod == "timeEnd") {
|
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': {
|
'WorkerLocation': {
|
||||||
'headerFile': 'mozilla/dom/workers/bindings/Location.h',
|
'headerFile': 'mozilla/dom/workers/bindings/Location.h',
|
||||||
'workers': True,
|
'workers': True,
|
||||||
|
|
|
@ -281,7 +281,7 @@ public:
|
||||||
virtual ~JSStackFrame();
|
virtual ~JSStackFrame();
|
||||||
|
|
||||||
static already_AddRefed<nsIStackFrame>
|
static already_AddRefed<nsIStackFrame>
|
||||||
CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
|
CreateStack(JSContext* cx);
|
||||||
static already_AddRefed<nsIStackFrame>
|
static already_AddRefed<nsIStackFrame>
|
||||||
CreateStackFrameLocation(uint32_t aLanguage,
|
CreateStackFrameLocation(uint32_t aLanguage,
|
||||||
const char* aFilename,
|
const char* aFilename,
|
||||||
|
@ -495,14 +495,11 @@ NS_IMETHODIMP JSStackFrame::ToString(nsACString& _retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ already_AddRefed<nsIStackFrame>
|
/* static */ already_AddRefed<nsIStackFrame>
|
||||||
JSStackFrame::CreateStack(JSContext* aCx, int32_t aMaxDepth)
|
JSStackFrame::CreateStack(JSContext* cx)
|
||||||
{
|
{
|
||||||
static const unsigned MAX_FRAMES = 100;
|
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) {
|
if (!desc) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -533,9 +530,9 @@ JSStackFrame::CreateStackFrameLocation(uint32_t aLanguage,
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIStackFrame>
|
already_AddRefed<nsIStackFrame>
|
||||||
CreateStack(JSContext* aCx, int32_t aMaxDepth)
|
CreateStack(JSContext* cx)
|
||||||
{
|
{
|
||||||
return JSStackFrame::CreateStack(aCx, aMaxDepth);
|
return JSStackFrame::CreateStack(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIStackFrame>
|
already_AddRefed<nsIStackFrame>
|
||||||
|
|
|
@ -36,10 +36,8 @@ GetCurrentJSStack();
|
||||||
// Internal stuff not intended to be widely used.
|
// Internal stuff not intended to be widely used.
|
||||||
namespace exceptions {
|
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>
|
already_AddRefed<nsIStackFrame>
|
||||||
CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
|
CreateStack(JSContext* cx);
|
||||||
|
|
||||||
already_AddRefed<nsIStackFrame>
|
already_AddRefed<nsIStackFrame>
|
||||||
CreateStackFrameLocation(uint32_t aLanguage,
|
CreateStackFrameLocation(uint32_t aLanguage,
|
||||||
|
|
|
@ -315,7 +315,7 @@ class IDLUnresolvedIdentifier(IDLObject):
|
||||||
|
|
||||||
assert len(name) > 0
|
assert len(name) > 0
|
||||||
|
|
||||||
if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore:
|
if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore:
|
||||||
raise WebIDLError("Identifiers beginning with __ are reserved",
|
raise WebIDLError("Identifiers beginning with __ are reserved",
|
||||||
[location])
|
[location])
|
||||||
if name[0] == '_' and not allowDoubleUnderscore:
|
if name[0] == '_' and not allowDoubleUnderscore:
|
||||||
|
@ -3155,7 +3155,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
return self._hasOverloads
|
return self._hasOverloads
|
||||||
|
|
||||||
def isIdentifierLess(self):
|
def isIdentifierLess(self):
|
||||||
return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__"
|
return self.identifier.name[:2] == "__"
|
||||||
|
|
||||||
def resolve(self, parentScope):
|
def resolve(self, parentScope):
|
||||||
assert isinstance(parentScope, IDLScope)
|
assert isinstance(parentScope, IDLScope)
|
||||||
|
|
|
@ -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 {
|
interface WorkerGlobalScope : EventTarget {
|
||||||
readonly attribute WorkerGlobalScope self;
|
readonly attribute WorkerGlobalScope self;
|
||||||
readonly attribute WorkerConsole console;
|
|
||||||
readonly attribute WorkerLocation location;
|
readonly attribute WorkerLocation location;
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
|
@ -428,7 +428,6 @@ WEBIDL_FILES = [
|
||||||
'WheelEvent.webidl',
|
'WheelEvent.webidl',
|
||||||
'WifiOptions.webidl',
|
'WifiOptions.webidl',
|
||||||
'Worker.webidl',
|
'Worker.webidl',
|
||||||
'WorkerConsole.webidl',
|
|
||||||
'WorkerGlobalScope.webidl',
|
'WorkerGlobalScope.webidl',
|
||||||
'WorkerLocation.webidl',
|
'WorkerLocation.webidl',
|
||||||
'WorkerNavigator.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>
|
#include <android/log.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Console.h"
|
|
||||||
#include "Location.h"
|
#include "Location.h"
|
||||||
#include "Navigator.h"
|
#include "Navigator.h"
|
||||||
#include "Principal.h"
|
#include "Principal.h"
|
||||||
|
@ -78,19 +77,6 @@ WorkerGlobalScope::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||||
MOZ_CRASH("We should never get here!");
|
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>
|
already_AddRefed<WorkerLocation>
|
||||||
WorkerGlobalScope::Location()
|
WorkerGlobalScope::Location()
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,14 +20,12 @@ class Function;
|
||||||
BEGIN_WORKERS_NAMESPACE
|
BEGIN_WORKERS_NAMESPACE
|
||||||
|
|
||||||
class WorkerPrivate;
|
class WorkerPrivate;
|
||||||
class WorkerConsole;
|
|
||||||
class WorkerLocation;
|
class WorkerLocation;
|
||||||
class WorkerNavigator;
|
class WorkerNavigator;
|
||||||
|
|
||||||
class WorkerGlobalScope : public nsDOMEventTargetHelper,
|
class WorkerGlobalScope : public nsDOMEventTargetHelper,
|
||||||
public nsIGlobalObject
|
public nsIGlobalObject
|
||||||
{
|
{
|
||||||
nsRefPtr<WorkerConsole> mConsole;
|
|
||||||
nsRefPtr<WorkerLocation> mLocation;
|
nsRefPtr<WorkerLocation> mLocation;
|
||||||
nsRefPtr<WorkerNavigator> mNavigator;
|
nsRefPtr<WorkerNavigator> mNavigator;
|
||||||
|
|
||||||
|
@ -60,9 +58,6 @@ public:
|
||||||
return nsRefPtr<WorkerGlobalScope>(this).forget();
|
return nsRefPtr<WorkerGlobalScope>(this).forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerConsole*
|
|
||||||
Console();
|
|
||||||
|
|
||||||
already_AddRefed<WorkerLocation>
|
already_AddRefed<WorkerLocation>
|
||||||
Location();
|
Location();
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ EXPORTS.mozilla.dom.workers += [
|
||||||
|
|
||||||
# Stuff needed for the bindings, not really public though.
|
# Stuff needed for the bindings, not really public though.
|
||||||
EXPORTS.mozilla.dom.workers.bindings += [
|
EXPORTS.mozilla.dom.workers.bindings += [
|
||||||
'Console.h',
|
|
||||||
'FileReaderSync.h',
|
'FileReaderSync.h',
|
||||||
'Location.h',
|
'Location.h',
|
||||||
'MessagePort.h',
|
'MessagePort.h',
|
||||||
|
@ -33,7 +32,6 @@ EXPORTS.mozilla.dom.workers.bindings += [
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'ChromeWorkerScope.cpp',
|
'ChromeWorkerScope.cpp',
|
||||||
'Console.cpp',
|
|
||||||
'File.cpp',
|
'File.cpp',
|
||||||
'FileReaderSync.cpp',
|
'FileReaderSync.cpp',
|
||||||
'Location.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
|
closeOnGC_worker.js
|
||||||
close_worker.js
|
close_worker.js
|
||||||
content_worker.js
|
content_worker.js
|
||||||
console_worker.js
|
|
||||||
csp_worker.js
|
csp_worker.js
|
||||||
errorPropagation_iframe.html
|
errorPropagation_iframe.html
|
||||||
errorPropagation_worker.js
|
errorPropagation_worker.js
|
||||||
|
@ -21,7 +20,6 @@ support-files =
|
||||||
importScripts_worker_imported4.js
|
importScripts_worker_imported4.js
|
||||||
instanceof_worker.js
|
instanceof_worker.js
|
||||||
json_worker.js
|
json_worker.js
|
||||||
jsversion_worker.js
|
|
||||||
loadEncoding_worker.js
|
loadEncoding_worker.js
|
||||||
location_worker.js
|
location_worker.js
|
||||||
longThread_worker.js
|
longThread_worker.js
|
||||||
|
@ -61,6 +59,7 @@ support-files =
|
||||||
xhr_implicit_cancel_worker.js
|
xhr_implicit_cancel_worker.js
|
||||||
xhr_worker.js
|
xhr_worker.js
|
||||||
url_exceptions_worker.js
|
url_exceptions_worker.js
|
||||||
|
jsversion_worker.js
|
||||||
urlSearchParams_worker.js
|
urlSearchParams_worker.js
|
||||||
subdir/relativeLoad_sub_worker.js
|
subdir/relativeLoad_sub_worker.js
|
||||||
subdir/relativeLoad_sub_worker2.js
|
subdir/relativeLoad_sub_worker2.js
|
||||||
|
@ -74,7 +73,6 @@ support-files =
|
||||||
[test_clearTimeouts.html]
|
[test_clearTimeouts.html]
|
||||||
[test_close.html]
|
[test_close.html]
|
||||||
[test_closeOnGC.html]
|
[test_closeOnGC.html]
|
||||||
[test_console.html]
|
|
||||||
[test_contentWorker.html]
|
[test_contentWorker.html]
|
||||||
[test_csp.html]
|
[test_csp.html]
|
||||||
[test_csp.html^headers^]
|
[test_csp.html^headers^]
|
||||||
|
@ -87,7 +85,6 @@ support-files =
|
||||||
[test_importScripts.html]
|
[test_importScripts.html]
|
||||||
[test_instanceof.html]
|
[test_instanceof.html]
|
||||||
[test_json.html]
|
[test_json.html]
|
||||||
[test_jsversion.html]
|
|
||||||
[test_loadEncoding.html]
|
[test_loadEncoding.html]
|
||||||
[test_loadError.html]
|
[test_loadError.html]
|
||||||
[test_location.html]
|
[test_location.html]
|
||||||
|
@ -128,3 +125,4 @@ support-files =
|
||||||
skip-if = (os == "win") || (os == "mac")
|
skip-if = (os == "win") || (os == "mac")
|
||||||
[test_url_exceptions.html]
|
[test_url_exceptions.html]
|
||||||
[test_urlSearchParams.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>
|
|
Загрузка…
Ссылка в новой задаче