Bug 1246091 - patch 4/7 - Expose ConsoleCallData to WorkerDebuggerGlobalScope, r=ejpbruel

This commit is contained in:
Andrea Marchesini 2016-03-23 22:55:07 +01:00
Родитель a41a9b217f
Коммит 931f576f19
6 изменённых файлов: 160 добавлений и 2 удалений

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/Maybe.h"
@ -146,6 +147,21 @@ public:
mIDType = eString;
}
bool
PopulateArgumentsSequence(Sequence<JS::Value>& aSequence) const
{
AssertIsOnOwningThread();
for (uint32_t i = 0; i < mCopiedArguments.Length(); ++i) {
if (NS_WARN_IF(!aSequence.AppendElement(mCopiedArguments[i],
fallible))) {
return false;
}
}
return true;
}
void
Trace(const TraceCallbacks& aCallbacks, void* aClosure)
{
@ -800,12 +816,14 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Console)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Console)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsoleEventNotifier)
tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Console)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsoleEventNotifier)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -1352,6 +1370,9 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
return;
}
// We do this only in workers for now.
NotifyHandler(aCx, global, aData, callData);
RefPtr<ConsoleCallDataRunnable> runnable =
new ConsoleCallDataRunnable(this, callData);
NS_WARN_IF(!runnable->Dispatch(global));
@ -1477,7 +1498,7 @@ Console::PopulateEvent(JSContext* aCx,
event.mInnerID.Value().SetAsUnsignedLongLong() = aData->mInnerIDNumber;
} else {
// aData->mIDType can be eUnknown when we dispatch notifications via
// mConsoleEventHandler.
// mConsoleEventNotifier.
event.mID.Value().SetAsUnsignedLongLong() = 0;
event.mInnerID.Value().SetAsUnsignedLongLong() = 0;
}
@ -2224,6 +2245,74 @@ Console::ReleaseCallData(ConsoleCallData* aCallData)
mCallDataStoragePending.RemoveElement(aCallData);
}
void
Console::NotifyHandler(JSContext* aCx, JS::Handle<JSObject*> aGlobal,
const Sequence<JS::Value>& aArguments,
ConsoleCallData* aCallData) const
{
AssertIsOnOwningThread();
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aCallData);
if (!mConsoleEventNotifier) {
return;
}
JSAutoCompartment ac(aCx, mConsoleEventNotifier->Callable());
JS::Rooted<JS::Value> value(aCx);
if (NS_WARN_IF(!PopulateEvent(aCx, mConsoleEventNotifier->Callable(),
aArguments, &value, aCallData))) {
return;
}
JS::Rooted<JS::Value> ignored(aCx);
mConsoleEventNotifier->Call(value, &ignored);
}
void
Console::RetrieveConsoleEvents(JSContext* aCx, nsTArray<JS::Value>& aEvents,
ErrorResult& aRv)
{
AssertIsOnOwningThread();
// We don't want to expose this functionality to main-thread yet.
MOZ_ASSERT(!NS_IsMainThread());
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
for (uint32_t i = 0; i < mCallDataStorage.Length(); ++i) {
JS::Rooted<JS::Value> value(aCx);
Sequence<JS::Value> sequence;
SequenceRooter<JS::Value> arguments(aCx, &sequence);
if (!mCallDataStorage[i]->PopulateArgumentsSequence(sequence)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
if (NS_WARN_IF(!PopulateEvent(aCx, global, sequence, &value,
mCallDataStorage[i]))) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
aEvents.AppendElement(value);
}
}
void
Console::SetConsoleEventHandler(AnyCallback& aHandler)
{
AssertIsOnOwningThread();
// We don't want to expose this functionality to main-thread yet.
MOZ_ASSERT(!NS_IsMainThread());
mConsoleEventNotifier = &aHandler;
}
void
Console::AssertIsOnOwningThread() const
{

Просмотреть файл

@ -25,6 +25,7 @@ class nsIPrincipal;
namespace mozilla {
namespace dom {
class AnyCallback;
class ConsoleCallData;
class ConsoleRunnable;
class ConsoleCallDataRunnable;
@ -117,6 +118,13 @@ public:
void
NoopMethod();
void
RetrieveConsoleEvents(JSContext* aCx, nsTArray<JS::Value>& aEvents,
ErrorResult& aRv);
void
SetConsoleEventHandler(AnyCallback& aHandler);
private:
explicit Console(nsPIDOMWindowInner* aWindow);
@ -167,6 +175,12 @@ private:
void
ReleaseCallData(ConsoleCallData* aCallData);
void
NotifyHandler(JSContext* aCx,
JS::Handle<JSObject*> aGlobal,
const Sequence<JS::Value>& aArguments,
ConsoleCallData* aData) const;
bool
PopulateEvent(JSContext* aCx,
JS::Handle<JSObject*> aGlobal,
@ -332,6 +346,8 @@ private:
// the storage.
nsTArray<RefPtr<ConsoleCallData>> mCallDataStoragePending;
RefPtr<AnyCallback> mConsoleEventNotifier;
#ifdef DEBUG
PRThread* mOwningThread;
#endif

Просмотреть файл

@ -1605,7 +1605,7 @@ DOMInterfaces = {
'headerFile': 'mozilla/dom/WorkerScope.h',
'nativeType': 'mozilla::dom::workers::WorkerDebuggerGlobalScope',
'implicitJSContext': [
'dump', 'global', 'reportError',
'dump', 'global', 'reportError', 'setConsoleEventHandler',
],
},

Просмотреть файл

@ -25,6 +25,12 @@ interface WorkerDebuggerGlobalScope : EventTarget {
void setImmediate(Function handler);
void reportError(DOMString message);
[Throws]
sequence<any> retrieveConsoleEvents();
[Throws]
void setConsoleEventHandler(AnyCallback handler);
};
// So you can debug while you debug

Просмотреть файл

@ -923,6 +923,44 @@ WorkerDebuggerGlobalScope::ReportError(JSContext* aCx,
mWorkerPrivate->ReportErrorToDebugger(filename, lineno, aMessage);
}
void
WorkerDebuggerGlobalScope::RetrieveConsoleEvents(JSContext* aCx,
nsTArray<JS::Value>& aEvents,
ErrorResult& aRv)
{
WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
if (!scope) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
RefPtr<Console> console = scope->GetConsole(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
console->RetrieveConsoleEvents(aCx, aEvents, aRv);
}
void
WorkerDebuggerGlobalScope::SetConsoleEventHandler(JSContext* aCx,
AnyCallback& aHandler,
ErrorResult& aRv)
{
WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
if (!scope) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
RefPtr<Console> console = scope->GetConsole(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
console->SetConsoleEventHandler(aHandler);
}
Console*
WorkerDebuggerGlobalScope::GetConsole(ErrorResult& aRv)
{

Просмотреть файл

@ -17,6 +17,7 @@
namespace mozilla {
namespace dom {
class AnyCallback;
class Console;
class Function;
class IDBFactory;
@ -327,6 +328,14 @@ public:
void
ReportError(JSContext* aCx, const nsAString& aMessage);
void
RetrieveConsoleEvents(JSContext* aCx, nsTArray<JS::Value>& aEvents,
ErrorResult& aRv);
void
SetConsoleEventHandler(JSContext* aCx, AnyCallback& aHandler,
ErrorResult& aRv);
Console*
GetConsole(ErrorResult& aRv);