mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-05 09:29:07 +08:00
Add Page, Runtime, Debugger agents
Summary: Runtime and Debugger agents are shipped with JSC so we reuse them. Messages are routed to them through the `LegacyDispatcher` which also handles translating their events. The Page agent emits the `Page.getResourceTree` method that the Chrome inspector expects. Reviewed By: michalgr Differential Revision: D4021499 fbshipit-source-id: a93d0add01cee732401f8e8db1d43205bfbd4cd4
This commit is contained in:
committed by
Facebook Github Bot
parent
156e5d9837
commit
0ac7bf29af
@@ -4,7 +4,10 @@
|
||||
|
||||
#include "Error.h"
|
||||
#include "Agent.h"
|
||||
#include "LegacyInspectorEnvironment.h"
|
||||
#include "InspectorAgent.h"
|
||||
#include "PageAgent.h"
|
||||
#include "LegacyAgents.h"
|
||||
|
||||
#include <folly/Memory.h>
|
||||
#include <folly/Conv.h>
|
||||
@@ -132,10 +135,16 @@ private:
|
||||
|
||||
InspectorController::InspectorController(JSC::JSGlobalObject& globalObject)
|
||||
: globalObject_(globalObject) {
|
||||
auto environment = folly::make_unique<LegacyInspectorEnvironment>();
|
||||
auto inspectorAgent = folly::make_unique<InspectorAgent>();
|
||||
inspectorAgent_ = inspectorAgent.get();
|
||||
dispatchers_.push_back(std::move(inspectorAgent));
|
||||
dispatchers_.push_back(folly::make_unique<SchemaAgent>());
|
||||
dispatchers_.push_back(folly::make_unique<PageAgent>());
|
||||
|
||||
auto legacyAgents = folly::make_unique<LegacyAgents>(globalObject, std::move(environment), nullptr);
|
||||
|
||||
dispatchers_.push_back(std::move(legacyAgents));
|
||||
}
|
||||
|
||||
InspectorController::~InspectorController() {
|
||||
|
||||
35
ReactCommon/inspector/LegacyAgents.cpp
Normal file
35
ReactCommon/inspector/LegacyAgents.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "LegacyAgents.h"
|
||||
|
||||
#include "LegacyInspectorEnvironment.h"
|
||||
#include "LegacyRuntimeAgent.h"
|
||||
#include "LegacyDebuggerAgent.h"
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
#include <folly/Memory.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace Inspector;
|
||||
|
||||
LegacyAgents::LegacyAgents(
|
||||
JSC::JSGlobalObject& globalObject,
|
||||
std::unique_ptr<LegacyInspectorEnvironment> environment,
|
||||
ConsoleAgent* consoleAgent)
|
||||
: LegacyDispatcher(globalObject)
|
||||
, environment_(std::move(environment)) {
|
||||
auto injectedScriptManager = environment_->injectedScriptManager();
|
||||
auto runtimeAgent = folly::make_unique<LegacyRuntimeAgent>(injectedScriptManager, globalObject);
|
||||
auto debuggerAgent = folly::make_unique<LegacyDebuggerAgent>(injectedScriptManager, globalObject, consoleAgent);
|
||||
|
||||
runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer());
|
||||
|
||||
addAgent("Runtime", std::move(runtimeAgent));
|
||||
addAgent("Debugger", std::move(debuggerAgent));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
29
ReactCommon/inspector/LegacyAgents.h
Normal file
29
ReactCommon/inspector/LegacyAgents.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LegacyDispatcher.h"
|
||||
|
||||
namespace JSC {
|
||||
class JSGlobalObject;
|
||||
}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class LegacyInspectorEnvironment;
|
||||
class ConsoleAgent;
|
||||
|
||||
class LegacyAgents : public LegacyDispatcher {
|
||||
public:
|
||||
LegacyAgents(
|
||||
JSC::JSGlobalObject& globalObject,
|
||||
std::unique_ptr<LegacyInspectorEnvironment> environment,
|
||||
ConsoleAgent* consoleAgent);
|
||||
private:
|
||||
std::unique_ptr<LegacyInspectorEnvironment> environment_;
|
||||
ConsoleAgent* consoleAgent_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
45
ReactCommon/inspector/LegacyDebuggerAgent.cpp
Normal file
45
ReactCommon/inspector/LegacyDebuggerAgent.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "LegacyDebuggerAgent.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
#include <JavaScriptCore/InjectedScript.h>
|
||||
#include <JavaScriptCore/InjectedScriptManager.h>
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace Inspector;
|
||||
|
||||
LegacyDebuggerAgent::LegacyDebuggerAgent(InjectedScriptManager* injectedScriptManager, JSC::JSGlobalObject& globalObject, ConsoleAgent* consoleAgent)
|
||||
: InspectorDebuggerAgent(injectedScriptManager)
|
||||
, scriptDebugServer_(globalObject)
|
||||
, consoleAgent_(consoleAgent) {}
|
||||
|
||||
void LegacyDebuggerAgent::startListeningScriptDebugServer() {
|
||||
scriptDebugServer().addListener(this);
|
||||
}
|
||||
|
||||
void LegacyDebuggerAgent::stopListeningScriptDebugServer(bool isBeingDestroyed) {
|
||||
scriptDebugServer().removeListener(this, isBeingDestroyed);
|
||||
}
|
||||
|
||||
InjectedScript LegacyDebuggerAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId) {
|
||||
if (executionContextId) {
|
||||
*error = ASCIILiteral("Execution context id is not supported for JSContext inspection as there is only one execution context.");
|
||||
return InjectedScript();
|
||||
}
|
||||
|
||||
JSC::ExecState* exec = scriptDebugServer_.globalObject().globalExec();
|
||||
return injectedScriptManager()->injectedScriptFor(exec);
|
||||
}
|
||||
|
||||
void LegacyDebuggerAgent::breakpointActionLog(JSC::ExecState* exec, const String& message) {
|
||||
// TODO: Hook up
|
||||
// consoleAgent_->log(exec, toStdString(message));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
41
ReactCommon/inspector/LegacyDebuggerAgent.h
Normal file
41
ReactCommon/inspector/LegacyDebuggerAgent.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LegacyScriptDebugServer.h"
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/InspectorDebuggerAgent.h>
|
||||
#include <JavaScriptCore/InspectorConsoleAgent.h>
|
||||
|
||||
namespace JSC {
|
||||
class JSGlobalObject;
|
||||
}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ConsoleAgent;
|
||||
|
||||
class LegacyDebuggerAgent : public Inspector::InspectorDebuggerAgent {
|
||||
public:
|
||||
LegacyDebuggerAgent(Inspector::InjectedScriptManager*, JSC::JSGlobalObject&, ConsoleAgent*);
|
||||
|
||||
virtual LegacyScriptDebugServer& scriptDebugServer() override { return scriptDebugServer_; }
|
||||
|
||||
virtual void startListeningScriptDebugServer() override;
|
||||
virtual void stopListeningScriptDebugServer(bool isBeingDestroyed) override;
|
||||
virtual Inspector::InjectedScript injectedScriptForEval(Inspector::ErrorString*, const int* executionContextId) override;
|
||||
|
||||
virtual void breakpointActionLog(JSC::ExecState*, const String&) override;
|
||||
|
||||
virtual void muteConsole() override { }
|
||||
virtual void unmuteConsole() override { }
|
||||
|
||||
private:
|
||||
LegacyScriptDebugServer scriptDebugServer_;
|
||||
ConsoleAgent* consoleAgent_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
54
ReactCommon/inspector/LegacyDispatcher.cpp
Normal file
54
ReactCommon/inspector/LegacyDispatcher.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "LegacyDispatcher.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
#include <wtf/text/CString.h>
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
#include <JavaScriptCore/JSLock.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace Inspector;
|
||||
|
||||
LegacyDispatcher::FrontendChannel::FrontendChannel(std::shared_ptr<Channel> channel)
|
||||
: channel_(channel) {}
|
||||
|
||||
bool LegacyDispatcher::FrontendChannel::sendMessageToFrontend(const WTF::String& message) {
|
||||
channel_->sendMessage(toStdString(message));
|
||||
return true;
|
||||
}
|
||||
|
||||
LegacyDispatcher::LegacyDispatcher(JSC::JSGlobalObject& globalObject)
|
||||
: globalObject_(globalObject) {}
|
||||
|
||||
void LegacyDispatcher::addAgent(std::string domain, std::unique_ptr<InspectorAgentBase> agent) {
|
||||
domains_.emplace_back(std::move(domain));
|
||||
agents_.append(std::move(agent));
|
||||
}
|
||||
|
||||
void LegacyDispatcher::onConnect(std::shared_ptr<Channel> channel) {
|
||||
// TODO: Should perhaps only create this once and then connect each time instead
|
||||
frontendChannel_ = std::make_unique<FrontendChannel>(channel);
|
||||
dispatcher_.reset(InspectorBackendDispatcher::create(frontendChannel_.get()).leakRef());
|
||||
|
||||
auto messageHandler = [this](std::string message, int, const std::string&, folly::dynamic) {
|
||||
JSC::JSLockHolder lock(globalObject_.globalExec());
|
||||
dispatcher_->dispatch(message.c_str());
|
||||
};
|
||||
for (auto& domain : domains_) {
|
||||
channel->registerDomain(domain, messageHandler);
|
||||
}
|
||||
|
||||
agents_.didCreateFrontendAndBackend(frontendChannel_.get(), dispatcher_.get());
|
||||
}
|
||||
|
||||
void LegacyDispatcher::onDisconnect() {
|
||||
// TODO: Perhaps support InspectedTargetDestroyed
|
||||
agents_.willDestroyFrontendAndBackend(InspectorDisconnectReason::InspectorDestroyed);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
48
ReactCommon/inspector/LegacyDispatcher.h
Normal file
48
ReactCommon/inspector/LegacyDispatcher.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Dispatcher.h"
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/InspectorAgentRegistry.h>
|
||||
#include <JavaScriptCore/InspectorAgentBase.h>
|
||||
#include <JavaScriptCore/InspectorFrontendChannel.h>
|
||||
#include <JavaScriptCore/InspectorBackendDispatcher.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace JSC {
|
||||
class JSGlobalObject;
|
||||
}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class LegacyDispatcher : public Dispatcher {
|
||||
public:
|
||||
LegacyDispatcher(JSC::JSGlobalObject& globalObject);
|
||||
void addAgent(std::string domain, std::unique_ptr<Inspector::InspectorAgentBase> agent);
|
||||
|
||||
void onConnect(std::shared_ptr<Channel> channel) override;
|
||||
void onDisconnect() override;
|
||||
private:
|
||||
class FrontendChannel : public Inspector::InspectorFrontendChannel {
|
||||
public:
|
||||
FrontendChannel(std::shared_ptr<Channel> channel);
|
||||
bool sendMessageToFrontend(const WTF::String& message) override;
|
||||
private:
|
||||
std::shared_ptr<Channel> channel_;
|
||||
};
|
||||
|
||||
JSC::JSGlobalObject& globalObject_;
|
||||
std::vector<std::string> domains_;
|
||||
Inspector::InspectorAgentRegistry agents_;
|
||||
|
||||
std::unique_ptr<FrontendChannel> frontendChannel_;
|
||||
std::unique_ptr<Inspector::InspectorBackendDispatcher> dispatcher_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
34
ReactCommon/inspector/LegacyInspectorEnvironment.cpp
Normal file
34
ReactCommon/inspector/LegacyInspectorEnvironment.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "LegacyInspectorEnvironment.h"
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/Completion.h>
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
#include <JavaScriptCore/InjectedScriptManager.h>
|
||||
#include <JavaScriptCore/InjectedScriptHost.h>
|
||||
|
||||
#include <folly/Memory.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace Inspector;
|
||||
|
||||
LegacyInspectorEnvironment::LegacyInspectorEnvironment()
|
||||
: injectedScriptManager_(folly::make_unique<InjectedScriptManager>(*this, InjectedScriptHost::create())) {}
|
||||
|
||||
LegacyInspectorEnvironment::~LegacyInspectorEnvironment() {
|
||||
injectedScriptManager_->disconnect();
|
||||
}
|
||||
|
||||
InspectorFunctionCallHandler LegacyInspectorEnvironment::functionCallHandler() const {
|
||||
return JSC::call;
|
||||
}
|
||||
|
||||
InspectorEvaluateHandler LegacyInspectorEnvironment::evaluateHandler() const {
|
||||
return JSC::evaluate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
35
ReactCommon/inspector/LegacyInspectorEnvironment.h
Normal file
35
ReactCommon/inspector/LegacyInspectorEnvironment.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/InspectorEnvironment.h>
|
||||
|
||||
namespace Inspector {
|
||||
class InjectedScriptManager;
|
||||
}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class LegacyInspectorEnvironment : public Inspector::InspectorEnvironment {
|
||||
public:
|
||||
LegacyInspectorEnvironment();
|
||||
~LegacyInspectorEnvironment();
|
||||
|
||||
Inspector::InjectedScriptManager* injectedScriptManager() const {
|
||||
return injectedScriptManager_.get();
|
||||
}
|
||||
private:
|
||||
std::unique_ptr<Inspector::InjectedScriptManager> injectedScriptManager_;
|
||||
|
||||
bool developerExtrasEnabled() const override { return true; }
|
||||
bool canAccessInspectedScriptState(JSC::ExecState*) const override { return true; }
|
||||
Inspector::InspectorFunctionCallHandler functionCallHandler() const override;
|
||||
Inspector::InspectorEvaluateHandler evaluateHandler() const override;
|
||||
void willCallInjectedScriptFunction(JSC::ExecState*, const WTF::String& scriptName, int scriptLine) override {};
|
||||
void didCallInjectedScriptFunction(JSC::ExecState*) override {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
63
ReactCommon/inspector/LegacyRuntimeAgent.cpp
Normal file
63
ReactCommon/inspector/LegacyRuntimeAgent.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "LegacyRuntimeAgent.h"
|
||||
|
||||
#include <JavaScriptCore/InjectedScript.h>
|
||||
#include <JavaScriptCore/InjectedScriptManager.h>
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace Inspector;
|
||||
|
||||
LegacyRuntimeAgent::LegacyRuntimeAgent(InjectedScriptManager* injectedScriptManager, JSC::JSGlobalObject& globalObject)
|
||||
: InspectorRuntimeAgent(injectedScriptManager)
|
||||
, m_globalObject(globalObject) {}
|
||||
|
||||
void LegacyRuntimeAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) {
|
||||
// m_frontendDispatcher = folly::make_unique<InspectorRuntimeFrontendDispatcher>(frontendChannel);
|
||||
frontendChannel_ = frontendChannel;
|
||||
m_backendDispatcher.reset(InspectorRuntimeBackendDispatcher::create(backendDispatcher, this).leakRef());
|
||||
}
|
||||
|
||||
void LegacyRuntimeAgent::enable(ErrorString* error) {
|
||||
InspectorRuntimeAgent::enable(error);
|
||||
|
||||
auto contextObject = InspectorObject::create();
|
||||
contextObject->setNumber(ASCIILiteral("id"), 1);
|
||||
contextObject->setBoolean(ASCIILiteral("isDefault"), true);
|
||||
contextObject->setBoolean(ASCIILiteral("isPageContext"), true);
|
||||
contextObject->setString(ASCIILiteral("origin"), ASCIILiteral(""));
|
||||
contextObject->setString(ASCIILiteral("name"), ASCIILiteral("React Native"));
|
||||
|
||||
auto jsonMessage = InspectorObject::create();
|
||||
jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("Runtime.executionContextCreated"));
|
||||
auto paramsObject = InspectorObject::create();
|
||||
paramsObject->setValue(ASCIILiteral("context"), contextObject);
|
||||
jsonMessage->setObject(ASCIILiteral("params"), paramsObject);
|
||||
|
||||
frontendChannel_->sendMessageToFrontend(jsonMessage->toJSONString());
|
||||
}
|
||||
|
||||
void LegacyRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) {
|
||||
frontendChannel_ = nullptr;
|
||||
m_backendDispatcher = nullptr;
|
||||
}
|
||||
|
||||
JSC::VM& LegacyRuntimeAgent::globalVM() {
|
||||
return m_globalObject.vm();
|
||||
}
|
||||
|
||||
InjectedScript LegacyRuntimeAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId) {
|
||||
JSC::ExecState* scriptState = m_globalObject.globalExec();
|
||||
InjectedScript injectedScript = injectedScriptManager()->injectedScriptFor(scriptState);
|
||||
if (injectedScript.hasNoValue()) {
|
||||
*error = ASCIILiteral("Internal error: main world execution context not found.");
|
||||
}
|
||||
|
||||
return injectedScript;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
39
ReactCommon/inspector/LegacyRuntimeAgent.h
Normal file
39
ReactCommon/inspector/LegacyRuntimeAgent.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/InspectorRuntimeAgent.h>
|
||||
|
||||
namespace JSC {
|
||||
class JSGlobalObject;
|
||||
}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class LegacyRuntimeAgent : public Inspector::InspectorRuntimeAgent {
|
||||
public:
|
||||
LegacyRuntimeAgent(Inspector::InjectedScriptManager*, JSC::JSGlobalObject&);
|
||||
|
||||
void enable(Inspector::ErrorString* error) override;
|
||||
|
||||
void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override;
|
||||
void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override;
|
||||
|
||||
JSC::VM& globalVM() override;
|
||||
Inspector::InjectedScript injectedScriptForEval(Inspector::ErrorString* error, const int* executionContextId) override;
|
||||
|
||||
void muteConsole() override { }
|
||||
void unmuteConsole() override { }
|
||||
private:
|
||||
Inspector::InspectorFrontendChannel* frontendChannel_;
|
||||
// std::unique_ptr<Inspector::InspectorRuntimeFrontendDispatcher> m_frontendDispatcher;
|
||||
std::unique_ptr<Inspector::InspectorRuntimeBackendDispatcher> m_backendDispatcher;
|
||||
JSC::JSGlobalObject& m_globalObject;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
64
ReactCommon/inspector/LegacyScriptDebugServer.cpp
Normal file
64
ReactCommon/inspector/LegacyScriptDebugServer.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "LegacyScriptDebugServer.h"
|
||||
|
||||
#include <JavaScriptCore/JSGlobalObject.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using namespace Inspector;
|
||||
|
||||
LegacyScriptDebugServer::LegacyScriptDebugServer(JSC::JSGlobalObject& globalObject)
|
||||
: Inspector::ScriptDebugServer(false)
|
||||
, globalObject_(globalObject) {}
|
||||
|
||||
void LegacyScriptDebugServer::addListener(ScriptDebugListener* listener)
|
||||
{
|
||||
if (!listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasEmpty = listeners_.isEmpty();
|
||||
listeners_.add(listener);
|
||||
|
||||
// First listener. Attach the debugger to the JSGlobalObject.
|
||||
if (wasEmpty) {
|
||||
attach(&globalObject_);
|
||||
recompileAllJSFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
void LegacyScriptDebugServer::removeListener(ScriptDebugListener* listener, bool isBeingDestroyed) {
|
||||
if (!listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
listeners_.remove(listener);
|
||||
|
||||
// Last listener. Detach the debugger from the JSGlobalObject.
|
||||
if (listeners_.isEmpty()) {
|
||||
detach(&globalObject_, isBeingDestroyed ? Debugger::GlobalObjectIsDestructing : Debugger::TerminatingDebuggingSession);
|
||||
if (!isBeingDestroyed) {
|
||||
recompileAllJSFunctions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LegacyScriptDebugServer::recompileAllJSFunctions() {
|
||||
JSC::Debugger::recompileAllJSFunctions(&globalObject_.vm());
|
||||
}
|
||||
|
||||
void LegacyScriptDebugServer::runEventLoopWhilePaused() {
|
||||
// Drop all locks so another thread can work in the VM while we are nested.
|
||||
JSC::JSLock::DropAllLocks dropAllLocks(&globalObject_.vm());
|
||||
|
||||
// Spinning here is our best option, we could override the method
|
||||
// notifyDoneProcessingDebuggerEvents but it's marked as final :(
|
||||
while (!m_doneProcessingDebuggerEvents) {
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
45
ReactCommon/inspector/LegacyScriptDebugServer.h
Normal file
45
ReactCommon/inspector/LegacyScriptDebugServer.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <JavaScriptCore/config.h>
|
||||
#include <JavaScriptCore/ScriptDebugServer.h>
|
||||
|
||||
namespace JSC {
|
||||
class JSGlobalObject;
|
||||
}
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class LegacyScriptDebugServer : public Inspector::ScriptDebugServer {
|
||||
public:
|
||||
LegacyScriptDebugServer(JSC::JSGlobalObject& object);
|
||||
|
||||
void addListener(Inspector::ScriptDebugListener* listener);
|
||||
void removeListener(Inspector::ScriptDebugListener* listener, bool isBeingDestroyed);
|
||||
|
||||
JSC::JSGlobalObject& globalObject() const { return globalObject_; }
|
||||
|
||||
void recompileAllJSFunctions() override;
|
||||
|
||||
private:
|
||||
ListenerSet* getListenersForGlobalObject(JSC::JSGlobalObject*) override { return &listeners_; }
|
||||
void didPause(JSC::JSGlobalObject*) override { }
|
||||
void didContinue(JSC::JSGlobalObject*) override { }
|
||||
void runEventLoopWhilePaused() override;
|
||||
bool isContentScript(JSC::ExecState*) const override { return false; }
|
||||
|
||||
// NOTE: Currently all exceptions are reported at the API boundary through reportAPIException.
|
||||
// Until a time comes where an exception can be caused outside of the API (e.g. setTimeout
|
||||
// or some other async operation in a pure JSContext) we can ignore exceptions reported here.
|
||||
// TODO: Should we actually ignore them?
|
||||
void reportException(JSC::ExecState*, JSC::JSValue) const override { }
|
||||
|
||||
ListenerSet listeners_;
|
||||
JSC::JSGlobalObject& globalObject_;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
31
ReactCommon/inspector/PageAgent.cpp
Normal file
31
ReactCommon/inspector/PageAgent.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "PageAgent.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
PageAgent::PageAgent() {
|
||||
auto emptyMethod = [](folly::dynamic args) -> folly::dynamic {
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
registerMethod("enable", emptyMethod);
|
||||
registerMethod("disable", emptyMethod);
|
||||
registerMethod("getResourceTree", [](folly::dynamic args) -> folly::dynamic {
|
||||
return folly::dynamic::object
|
||||
("frameTree", folly::dynamic::object
|
||||
("childFrames", folly::dynamic::array)
|
||||
("resources", folly::dynamic::array)
|
||||
("frame", folly::dynamic::object
|
||||
("id", "1")
|
||||
("loaderId", "1")
|
||||
("name", "main")
|
||||
("url", "")
|
||||
("securityOrigin", "")
|
||||
("mimeType", "application/octet-stream")));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
20
ReactCommon/inspector/PageAgent.h
Normal file
20
ReactCommon/inspector/PageAgent.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class PageAgent : public Agent {
|
||||
public:
|
||||
PageAgent();
|
||||
private:
|
||||
std::string getDomain() override {
|
||||
return "Page";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user