Skip to content

Commit

Permalink
Use RuntimeAdapter to disable debugging
Browse files Browse the repository at this point in the history
Summary:
Make the interface to enable/disable debugging symmetrical; both enabling and disabling are done by passing in a reference to the RuntimeAdapter.

Doing so requires moving ownership of the RuntimeAdapter, so each caller (java2js, arfx engine, React Native, react-native-github, and venice) has been updated to own their adapter.

Additionally, the two implementations of the Inspector connection (react-native-github and arfx engine) have been updated to expect and use the new argument.

`Connection::getRuntime` could be removed and replaced with calls to `Connection::getRuntimeAdapter::getRuntime`. I've left that choice to a followup diff, as this one is getting messy enough as it is.

Changelog: [Internal]

Reviewed By: jpporto

Differential Revision: D38242964

fbshipit-source-id: f2a3354f9d424b203a76d2c15122a6515a0926f2
  • Loading branch information
mattbfb authored and pull[bot] committed Feb 12, 2024
1 parent fcad655 commit 1049078
Show file tree
Hide file tree
Showing 14 changed files with 69 additions and 69 deletions.
23 changes: 13 additions & 10 deletions ReactCommon/hermes/executor/HermesExecutorFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,35 +149,38 @@ class DecoratedRuntime : public jsi::WithRuntimeDecorator<ReentrancyCheck> {
HermesRuntime &hermesRuntime,
std::shared_ptr<MessageQueueThread> jsQueue)
: jsi::WithRuntimeDecorator<ReentrancyCheck>(*runtime, reentrancyCheck_),
runtime_(std::move(runtime)),
hermesRuntime_(hermesRuntime) {
runtime_(std::move(runtime))
#ifdef HERMES_ENABLE_DEBUGGER
,
adapter_(
std::shared_ptr<HermesRuntime>(runtime_, &hermesRuntime),
jsQueue)
#endif
{
#ifdef HERMES_ENABLE_DEBUGGER
std::shared_ptr<HermesRuntime> rt(runtime_, &hermesRuntime);
auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(rt, jsQueue);
facebook::hermes::inspector::chrome::enableDebugging(
std::move(adapter), "Hermes React Native");
#else
(void)hermesRuntime_;
adapter_, "Hermes React Native");
#endif
}

~DecoratedRuntime() {
#ifdef HERMES_ENABLE_DEBUGGER
facebook::hermes::inspector::chrome::disableDebugging(hermesRuntime_);
facebook::hermes::inspector::chrome::disableDebugging(adapter_);
#endif
}

private:
// runtime_ is a potentially decorated Runtime.
// hermesRuntime is a reference to a HermesRuntime managed by runtime_.
//
// HermesExecutorRuntimeAdapter requirements are kept, because the
// dtor will disable debugging on the HermesRuntime before the
// member managing it is destroyed.

std::shared_ptr<Runtime> runtime_;
#ifdef HERMES_ENABLE_DEBUGGER
HermesExecutorRuntimeAdapter adapter_;
#endif
ReentrancyCheck reentrancyCheck_;
HermesRuntime &hermesRuntime_;
};

} // namespace
Expand Down
19 changes: 9 additions & 10 deletions ReactCommon/hermes/inspector/Inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,16 @@ static constexpr bool kShouldLog = false;
} while (0)

Inspector::Inspector(
std::shared_ptr<RuntimeAdapter> adapter,
RuntimeAdapter &adapter,
InspectorObserver &observer,
bool pauseOnFirstStatement)
: adapter_(adapter),
debugger_(adapter->getRuntime().getDebugger()),
debugger_(adapter.getRuntime().getDebugger()),
observer_(observer),
executor_(std::make_unique<detail::SerialExecutor>("hermes-inspector")) {
// TODO (t26491391): make tickleJs a real Hermes runtime API
std::string src = "function __tickleJs() { return Math.random(); }";
adapter->getRuntime().evaluateJavaScript(
adapter.getRuntime().evaluateJavaScript(
std::make_shared<jsi::StringBuffer>(src), "__tickleJsHackUrl");

{
Expand Down Expand Up @@ -163,7 +163,7 @@ void Inspector::installConsoleFunction(
std::shared_ptr<jsi::Object> &originalConsole,
const std::string &name,
const std::string &chromeTypeDefault = "") {
jsi::Runtime &rt = adapter_->getRuntime();
jsi::Runtime &rt = adapter_.getRuntime();
auto chromeType = chromeTypeDefault == "" ? name : chromeTypeDefault;
auto nameID = jsi::PropNameID::forUtf8(rt, name);
auto weakInspector = std::weak_ptr<Inspector>(shared_from_this());
Expand Down Expand Up @@ -222,7 +222,7 @@ void Inspector::installConsoleFunction(
}

void Inspector::installLogHandler() {
jsi::Runtime &rt = adapter_->getRuntime();
jsi::Runtime &rt = adapter_.getRuntime();
auto console = jsi::Object(rt);
auto val = rt.global().getProperty(rt, "console");
std::shared_ptr<jsi::Object> originalConsole;
Expand Down Expand Up @@ -261,9 +261,8 @@ void Inspector::triggerAsyncPause(bool andTickle) {
if (andTickle) {
// We run the dummy JS on a background thread to avoid any reentrancy issues
// in case this thread is called with the inspector mutex held.
std::shared_ptr<RuntimeAdapter> adapter = adapter_;
detail::Thread tickleJsLater(
"inspectorTickleJs", [adapter]() { adapter->tickleJs(); });
"inspectorTickleJs", [&adapter = adapter_]() { adapter.tickleJs(); });
tickleJsLater.detach();
}
}
Expand Down Expand Up @@ -706,16 +705,16 @@ void Inspector::alertIfPausedInSupersededFile() {
"=true to "
"suppress this warning. Filename: " +
info.fileName + ").";
jsi::Array jsiArray(adapter_->getRuntime(), 1);
jsiArray.setValueAtIndex(adapter_->getRuntime(), 0, warning);
jsi::Array jsiArray(adapter_.getRuntime(), 1);
jsiArray.setValueAtIndex(adapter_.getRuntime(), 0, warning);

ConsoleMessageInfo logMessage("warning", std::move(jsiArray));
observer_.onMessageAdded(*this, logMessage);
}
}

bool Inspector::shouldSuppressAlertAboutSupersededFiles() {
jsi::Runtime &rt = adapter_->getRuntime();
jsi::Runtime &rt = adapter_.getRuntime();
jsi::Value setting = rt.global().getProperty(rt, kSuppressionVariable);

if (setting.isUndefined() || !setting.isBool())
Expand Down
4 changes: 2 additions & 2 deletions ReactCommon/hermes/inspector/Inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class Inspector : public facebook::hermes::debugger::EventObserver,
* provided runtime before any JS executes in the runtime.
*/
Inspector(
std::shared_ptr<RuntimeAdapter> adapter,
RuntimeAdapter &adapter,
InspectorObserver &observer,
bool pauseOnFirstStatement);
~Inspector();
Expand Down Expand Up @@ -317,7 +317,7 @@ class Inspector : public facebook::hermes::debugger::EventObserver,
const std::string &name,
const std::string &chromeType);

std::shared_ptr<RuntimeAdapter> adapter_;
RuntimeAdapter &adapter_;
facebook::hermes::debugger::Debugger &debugger_;
InspectorObserver &observer_;

Expand Down
27 changes: 16 additions & 11 deletions ReactCommon/hermes/inspector/chrome/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,11 @@ static const char *const kBeforeScriptWithSourceMapExecution =
class Connection::Impl : public inspector::InspectorObserver,
public message::RequestHandler {
public:
Impl(
std::unique_ptr<RuntimeAdapter> adapter,
const std::string &title,
bool waitForDebugger);
Impl(RuntimeAdapter &adapter, const std::string &title, bool waitForDebugger);
~Impl();

jsi::Runtime &getRuntime();
RuntimeAdapter &getRuntimeAdapter();
std::string getTitle() const;

bool connect(std::unique_ptr<IRemoteConnection> remoteConn);
Expand Down Expand Up @@ -143,7 +141,7 @@ class Connection::Impl : public inspector::InspectorObserver,
folly::via(executor_.get(), [cb = std::move(callback)]() { cb(); });
}

std::shared_ptr<RuntimeAdapter> runtimeAdapter_;
RuntimeAdapter &runtimeAdapter_;
std::string title_;

// connected_ is protected by connectionMutex_.
Expand Down Expand Up @@ -185,10 +183,10 @@ class Connection::Impl : public inspector::InspectorObserver,
};

Connection::Impl::Impl(
std::unique_ptr<RuntimeAdapter> adapter,
RuntimeAdapter &adapter,
const std::string &title,
bool waitForDebugger)
: runtimeAdapter_(std::move(adapter)),
: runtimeAdapter_(adapter),
title_(title),
connected_(false),
executor_(std::make_unique<inspector::detail::SerialExecutor>(
Expand All @@ -204,7 +202,11 @@ Connection::Impl::Impl(
Connection::Impl::~Impl() = default;

jsi::Runtime &Connection::Impl::getRuntime() {
return runtimeAdapter_->getRuntime();
return runtimeAdapter_.getRuntime();
}

RuntimeAdapter &Connection::Impl::getRuntimeAdapter() {
return runtimeAdapter_;
}

std::string Connection::Impl::getTitle() const {
Expand Down Expand Up @@ -1571,18 +1573,21 @@ void Connection::Impl::sendNotificationToClientViaExecutor(
* Connection
*/
Connection::Connection(
std::unique_ptr<RuntimeAdapter> adapter,
RuntimeAdapter &adapter,
const std::string &title,
bool waitForDebugger)
: impl_(
std::make_unique<Impl>(std::move(adapter), title, waitForDebugger)) {}
: impl_(std::make_unique<Impl>(adapter, title, waitForDebugger)) {}

Connection::~Connection() = default;

jsi::Runtime &Connection::getRuntime() {
return impl_->getRuntime();
}

RuntimeAdapter &Connection::getRuntimeAdapter() {
return impl_->getRuntimeAdapter();
}

std::string Connection::getTitle() const {
return impl_->getTitle();
}
Expand Down
5 changes: 4 additions & 1 deletion ReactCommon/hermes/inspector/chrome/Connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ class INSPECTOR_EXPORT Connection {
/// Connection constructor enables the debugger on the provided runtime. This
/// should generally called before you start running any JS in the runtime.
Connection(
std::unique_ptr<RuntimeAdapter> adapter,
RuntimeAdapter &adapter,
const std::string &title,
bool waitForDebugger = false);
~Connection();

/// getRuntime returns the underlying runtime being debugged.
jsi::Runtime &getRuntime();

/// getRuntimeAdapter returns the runtime adapter being debugged.
RuntimeAdapter &getRuntimeAdapter();

/// getTitle returns the name of the friendly name of the runtime that's shown
/// to users in Nuclide.
std::string getTitle() const;
Expand Down
9 changes: 4 additions & 5 deletions ReactCommon/hermes/inspector/chrome/ConnectionDemux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ ConnectionDemux::ConnectionDemux(facebook::react::IInspector &inspector)
ConnectionDemux::~ConnectionDemux() = default;

int ConnectionDemux::enableDebugging(
std::unique_ptr<RuntimeAdapter> adapter,
RuntimeAdapter &adapter,
const std::string &title) {
std::lock_guard<std::mutex> lock(mutex_);

Expand All @@ -90,18 +90,17 @@ int ConnectionDemux::enableDebugging(
(inspectedContexts_->find(title) != inspectedContexts_->end()) ||
isNetworkInspected(title, "app_name", "device_name");

return addPage(
std::make_shared<Connection>(std::move(adapter), title, waitForDebugger));
return addPage(std::make_shared<Connection>(adapter, title, waitForDebugger));
}

void ConnectionDemux::disableDebugging(HermesRuntime &runtime) {
void ConnectionDemux::disableDebugging(RuntimeAdapter &adapter) {
std::lock_guard<std::mutex> lock(mutex_);

for (auto &it : conns_) {
int pageId = it.first;
auto &conn = it.second;

if (&(conn->getRuntime()) == &runtime) {
if (&(conn->getRuntimeAdapter()) == &adapter) {
removePage(pageId);

// must break here. removePage mutates conns_, so range-for iterator is
Expand Down
6 changes: 2 additions & 4 deletions ReactCommon/hermes/inspector/chrome/ConnectionDemux.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ class ConnectionDemux {
ConnectionDemux(const ConnectionDemux &) = delete;
ConnectionDemux &operator=(const ConnectionDemux &) = delete;

int enableDebugging(
std::unique_ptr<RuntimeAdapter> adapter,
const std::string &title);
void disableDebugging(HermesRuntime &runtime);
int enableDebugging(RuntimeAdapter &adapter, const std::string &title);
void disableDebugging(RuntimeAdapter &adapter);

private:
int addPage(std::shared_ptr<Connection> conn);
Expand Down
10 changes: 4 additions & 6 deletions ReactCommon/hermes/inspector/chrome/Registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ ConnectionDemux &demux() {

} // namespace

void enableDebugging(
std::unique_ptr<RuntimeAdapter> adapter,
const std::string &title) {
demux().enableDebugging(std::move(adapter), title);
void enableDebugging(RuntimeAdapter &adapter, const std::string &title) {
demux().enableDebugging(adapter, title);
}

void disableDebugging(HermesRuntime &runtime) {
demux().disableDebugging(runtime);
void disableDebugging(RuntimeAdapter &adapter) {
demux().disableDebugging(adapter);
}

} // namespace chrome
Expand Down
6 changes: 2 additions & 4 deletions ReactCommon/hermes/inspector/chrome/Registration.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ namespace chrome {
* (called "pages" in the higher-leavel React Native API) in this process. It
* should be called before any JS runs in the runtime.
*/
extern void enableDebugging(
std::unique_ptr<RuntimeAdapter> adapter,
const std::string &title);
extern void enableDebugging(RuntimeAdapter &adapter, const std::string &title);

/*
* disableDebugging removes this runtime from the list of debuggable JS targets
* in this process.
*/
extern void disableDebugging(HermesRuntime &runtime);
extern void disableDebugging(RuntimeAdapter &adapter);

} // namespace chrome
} // namespace inspector
Expand Down
5 changes: 2 additions & 3 deletions ReactCommon/hermes/inspector/chrome/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,9 @@ static void runDebuggerLoop(
static void runScript(const std::string &scriptSource, const std::string &url) {
std::shared_ptr<fbhermes::HermesRuntime> runtime(
fbhermes::makeHermesRuntime());
auto adapter =
std::make_unique<fbhermes::inspector::SharedRuntimeAdapter>(runtime);
fbhermes::inspector::SharedRuntimeAdapter adapter(runtime);
fbhermes::inspector::chrome::Connection conn(
std::move(adapter), "hermes-chrome-debug-server");
adapter, "hermes-chrome-debug-server");
std::thread debuggerLoop(runDebuggerLoop, std::ref(conn), scriptSource);

fbhermes::HermesRuntime::DebugFlags flags{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ TEST(ConnectionDemuxTests, TestEnableDisable) {

ConnectionDemux demux{*inspector};

int id1 = demux.enableDebugging(
std::make_unique<SharedRuntimeAdapter>(runtime1), "page1");
int id2 = demux.enableDebugging(
std::make_unique<SharedRuntimeAdapter>(runtime2), "page2");
SharedRuntimeAdapter adapter1(runtime1);
int id1 = demux.enableDebugging(adapter1, "page1");
SharedRuntimeAdapter adapter2(runtime2);
int id2 = demux.enableDebugging(adapter2, "page2");

expectPages(*inspector, {{id1, "page1"}, {id2, "page2"}});

Expand All @@ -124,7 +124,7 @@ TEST(ConnectionDemuxTests, TestEnableDisable) {

// Disable debugging on runtime2. This should remove its page from the list
// and call onDisconnect on its remoteConn
demux.disableDebugging(*runtime2);
demux.disableDebugging(adapter2);
expectPages(*inspector, {{id1, "page1"}});
remoteData2->expectDisconnected();

Expand Down
6 changes: 2 additions & 4 deletions ReactCommon/hermes/inspector/chrome/tests/SyncConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,8 @@ class SyncConnection::RemoteConnnection : public IRemoteConnection {
SyncConnection::SyncConnection(
std::shared_ptr<HermesRuntime> runtime,
bool waitForDebugger)
: connection_(
std::make_unique<SharedRuntimeAdapter>(runtime),
"testConn",
waitForDebugger) {
: runtimeAdapter_(runtime),
connection_(runtimeAdapter_, "testConn", waitForDebugger) {
connection_.connect(std::make_unique<RemoteConnnection>(*this));
}

Expand Down
1 change: 1 addition & 0 deletions ReactCommon/hermes/inspector/chrome/tests/SyncConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class SyncConnection {

void onReply(const std::string &message);

SharedRuntimeAdapter runtimeAdapter_;
Connection connection_;

std::mutex mutex_;
Expand Down
7 changes: 3 additions & 4 deletions ReactCommon/hermes/inspector/tests/InspectorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,8 @@ struct HermesDebugContext {
InspectorObserver &observer,
folly::Future<Unit> &&finished)
: runtime(makeHermesRuntime()),
inspector(
std::make_shared<SharedRuntimeAdapter>(runtime),
observer,
false),
adapter(runtime),
inspector(adapter, observer, false),
stopFlag(false),
finished(std::move(finished)) {
runtime->global().setProperty(
Expand Down Expand Up @@ -124,6 +122,7 @@ struct HermesDebugContext {
}

std::shared_ptr<HermesRuntime> runtime;
SharedRuntimeAdapter adapter;
Inspector inspector;
std::atomic<bool> stopFlag{};
folly::Future<Unit> finished;
Expand Down

0 comments on commit 1049078

Please sign in to comment.