mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement Runtime.compileScript
Summary: Implement Runtime.compileScript, which is a dev tools request to compile a given script, optionally persisting the compiled result. There are 3 main cases: - Unsuccessful compilation, populates the exception details output. (We could retrieve the line and column number from the exception message, but it felt a bit too hacky.) - Successful unpersisted output, returns an empty result, indicating success - Successful persisted output, returns a result with a unique scriptID that identifies the prepared script. The script IDs end with an index that can be used to infer the location in the vector storing persisted scripts. Changelog: [Internal] Reviewed By: jpporto Differential Revision: D38761119 fbshipit-source-id: 504faad0149d1637682fa11d285f71736c3133e5
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a45eeea17a
commit
2b4390e15d
@@ -40,6 +40,7 @@ namespace m = ::facebook::hermes::inspector::chrome::message;
|
||||
static const char *const kVirtualBreakpointPrefix = "virtualbreakpoint-";
|
||||
static const char *const kBeforeScriptWithSourceMapExecution =
|
||||
"beforeScriptWithSourceMapExecution";
|
||||
static const char *const kUserEnteredScriptPrefix = "userScript";
|
||||
|
||||
/*
|
||||
* Connection::Impl
|
||||
@@ -104,6 +105,7 @@ class Connection::Impl : public inspector::InspectorObserver,
|
||||
void handle(const m::profiler::StartRequest &req) override;
|
||||
void handle(const m::profiler::StopRequest &req) override;
|
||||
void handle(const m::runtime::CallFunctionOnRequest &req) override;
|
||||
void handle(const m::runtime::CompileScriptRequest &req) override;
|
||||
void handle(const m::runtime::EvaluateRequest &req) override;
|
||||
void handle(const m::runtime::GetHeapUsageRequest &req) override;
|
||||
void handle(const m::runtime::GetPropertiesRequest &req) override;
|
||||
@@ -160,6 +162,10 @@ class Connection::Impl : public inspector::InspectorObserver,
|
||||
std::mutex parsedScriptsMutex_;
|
||||
std::vector<std::string> parsedScripts_;
|
||||
|
||||
// preparedScripts_ stores user-entered scripts that have been prepared for
|
||||
// execution, and may be invoked by a later command.
|
||||
std::vector<std::shared_ptr<const jsi::PreparedJavaScript>> preparedScripts_;
|
||||
|
||||
// Some events are represented as a mode in Hermes but a breakpoint in CDP,
|
||||
// e.g. "beforeScriptExecution" and "beforeScriptWithSourceMapExecution".
|
||||
// Keep track of these separately. The caller should lock the
|
||||
@@ -1092,6 +1098,42 @@ void Connection::Impl::handle(const m::runtime::CallFunctionOnRequest &req) {
|
||||
.thenError<std::exception>(sendErrorToClient(req.id));
|
||||
}
|
||||
|
||||
void Connection::Impl::handle(const m::runtime::CompileScriptRequest &req) {
|
||||
auto resp = std::make_shared<m::runtime::CompileScriptResponse>();
|
||||
resp->id = req.id;
|
||||
|
||||
inspector_
|
||||
->executeIfEnabled(
|
||||
"Runtime.compileScriptRequest",
|
||||
[this, req, resp](const debugger::ProgramState &state) {
|
||||
if (req.executionContextId.hasValue() &&
|
||||
req.executionContextId.value() != kHermesExecutionContextId) {
|
||||
throw std::invalid_argument("Invalid execution context");
|
||||
}
|
||||
|
||||
auto source = std::make_shared<jsi::StringBuffer>(req.expression);
|
||||
std::shared_ptr<const jsi::PreparedJavaScript> preparedScript;
|
||||
try {
|
||||
preparedScript =
|
||||
getRuntime().prepareJavaScript(source, req.sourceURL);
|
||||
} catch (const facebook::jsi::JSIException &err) {
|
||||
resp->exceptionDetails = m::runtime::ExceptionDetails();
|
||||
resp->exceptionDetails->text = err.what();
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.persistScript) {
|
||||
auto scriptId = folly::to<std::string>(
|
||||
kUserEnteredScriptPrefix, preparedScripts_.size());
|
||||
preparedScripts_.push_back(std::move(preparedScript));
|
||||
resp->scriptId = scriptId;
|
||||
}
|
||||
})
|
||||
.via(executor_.get())
|
||||
.thenValue([this, resp](auto &&) { sendResponseToClient(*resp); })
|
||||
.thenError<std::exception>(sendErrorToClient(req.id));
|
||||
}
|
||||
|
||||
void Connection::Impl::handle(const m::runtime::EvaluateRequest &req) {
|
||||
auto remoteObjPtr = std::make_shared<m::runtime::RemoteObject>();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
|
||||
// @generated SignedSource<<d10e11c5f88b40149af7ace19008d0fc>>
|
||||
// @generated SignedSource<<8397f2428e68a26e014f91fdb77c1eb3>>
|
||||
|
||||
#include "MessageTypes.h"
|
||||
|
||||
@@ -63,6 +63,7 @@ std::unique_ptr<Request> Request::fromJsonThrowOnError(const std::string &str) {
|
||||
{"Profiler.start", makeUnique<profiler::StartRequest>},
|
||||
{"Profiler.stop", makeUnique<profiler::StopRequest>},
|
||||
{"Runtime.callFunctionOn", makeUnique<runtime::CallFunctionOnRequest>},
|
||||
{"Runtime.compileScript", makeUnique<runtime::CompileScriptRequest>},
|
||||
{"Runtime.evaluate", makeUnique<runtime::EvaluateRequest>},
|
||||
{"Runtime.getHeapUsage", makeUnique<runtime::GetHeapUsageRequest>},
|
||||
{"Runtime.getProperties", makeUnique<runtime::GetPropertiesRequest>},
|
||||
@@ -1112,6 +1113,39 @@ void runtime::CallFunctionOnRequest::accept(RequestHandler &handler) const {
|
||||
handler.handle(*this);
|
||||
}
|
||||
|
||||
runtime::CompileScriptRequest::CompileScriptRequest()
|
||||
: Request("Runtime.compileScript") {}
|
||||
|
||||
runtime::CompileScriptRequest::CompileScriptRequest(const dynamic &obj)
|
||||
: Request("Runtime.compileScript") {
|
||||
assign(id, obj, "id");
|
||||
assign(method, obj, "method");
|
||||
|
||||
dynamic params = obj.at("params");
|
||||
assign(expression, params, "expression");
|
||||
assign(sourceURL, params, "sourceURL");
|
||||
assign(persistScript, params, "persistScript");
|
||||
assign(executionContextId, params, "executionContextId");
|
||||
}
|
||||
|
||||
dynamic runtime::CompileScriptRequest::toDynamic() const {
|
||||
dynamic params = dynamic::object;
|
||||
put(params, "expression", expression);
|
||||
put(params, "sourceURL", sourceURL);
|
||||
put(params, "persistScript", persistScript);
|
||||
put(params, "executionContextId", executionContextId);
|
||||
|
||||
dynamic obj = dynamic::object;
|
||||
put(obj, "id", id);
|
||||
put(obj, "method", method);
|
||||
put(obj, "params", std::move(params));
|
||||
return obj;
|
||||
}
|
||||
|
||||
void runtime::CompileScriptRequest::accept(RequestHandler &handler) const {
|
||||
handler.handle(*this);
|
||||
}
|
||||
|
||||
runtime::EvaluateRequest::EvaluateRequest() : Request("Runtime.evaluate") {}
|
||||
|
||||
runtime::EvaluateRequest::EvaluateRequest(const dynamic &obj)
|
||||
@@ -1456,6 +1490,25 @@ dynamic runtime::CallFunctionOnResponse::toDynamic() const {
|
||||
return obj;
|
||||
}
|
||||
|
||||
runtime::CompileScriptResponse::CompileScriptResponse(const dynamic &obj) {
|
||||
assign(id, obj, "id");
|
||||
|
||||
dynamic res = obj.at("result");
|
||||
assign(scriptId, res, "scriptId");
|
||||
assign(exceptionDetails, res, "exceptionDetails");
|
||||
}
|
||||
|
||||
dynamic runtime::CompileScriptResponse::toDynamic() const {
|
||||
dynamic res = dynamic::object;
|
||||
put(res, "scriptId", scriptId);
|
||||
put(res, "exceptionDetails", exceptionDetails);
|
||||
|
||||
dynamic obj = dynamic::object;
|
||||
put(obj, "id", id);
|
||||
put(obj, "result", std::move(res));
|
||||
return obj;
|
||||
}
|
||||
|
||||
runtime::EvaluateResponse::EvaluateResponse(const dynamic &obj) {
|
||||
assign(id, obj, "id");
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates. All Rights Reserved.
|
||||
// @generated SignedSource<<dafd583635231e17c0264beb38610499>>
|
||||
// @generated SignedSource<<2bada3d9c303c840ddcc292c7ba52604>>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -52,6 +52,8 @@ struct CallArgument;
|
||||
struct CallFrame;
|
||||
struct CallFunctionOnRequest;
|
||||
struct CallFunctionOnResponse;
|
||||
struct CompileScriptRequest;
|
||||
struct CompileScriptResponse;
|
||||
struct ConsoleAPICalledNotification;
|
||||
struct EvaluateRequest;
|
||||
struct EvaluateResponse;
|
||||
@@ -141,6 +143,7 @@ struct RequestHandler {
|
||||
virtual void handle(const profiler::StartRequest &req) = 0;
|
||||
virtual void handle(const profiler::StopRequest &req) = 0;
|
||||
virtual void handle(const runtime::CallFunctionOnRequest &req) = 0;
|
||||
virtual void handle(const runtime::CompileScriptRequest &req) = 0;
|
||||
virtual void handle(const runtime::EvaluateRequest &req) = 0;
|
||||
virtual void handle(const runtime::GetHeapUsageRequest &req) = 0;
|
||||
virtual void handle(const runtime::GetPropertiesRequest &req) = 0;
|
||||
@@ -180,6 +183,7 @@ struct NoopRequestHandler : public RequestHandler {
|
||||
void handle(const profiler::StartRequest &req) override {}
|
||||
void handle(const profiler::StopRequest &req) override {}
|
||||
void handle(const runtime::CallFunctionOnRequest &req) override {}
|
||||
void handle(const runtime::CompileScriptRequest &req) override {}
|
||||
void handle(const runtime::EvaluateRequest &req) override {}
|
||||
void handle(const runtime::GetHeapUsageRequest &req) override {}
|
||||
void handle(const runtime::GetPropertiesRequest &req) override {}
|
||||
@@ -654,6 +658,19 @@ struct runtime::CallFunctionOnRequest : public Request {
|
||||
folly::Optional<std::string> objectGroup;
|
||||
};
|
||||
|
||||
struct runtime::CompileScriptRequest : public Request {
|
||||
CompileScriptRequest();
|
||||
explicit CompileScriptRequest(const folly::dynamic &obj);
|
||||
|
||||
folly::dynamic toDynamic() const override;
|
||||
void accept(RequestHandler &handler) const override;
|
||||
|
||||
std::string expression;
|
||||
std::string sourceURL;
|
||||
bool persistScript{};
|
||||
folly::Optional<runtime::ExecutionContextId> executionContextId;
|
||||
};
|
||||
|
||||
struct runtime::EvaluateRequest : public Request {
|
||||
EvaluateRequest();
|
||||
explicit EvaluateRequest(const folly::dynamic &obj);
|
||||
@@ -801,6 +818,15 @@ struct runtime::CallFunctionOnResponse : public Response {
|
||||
folly::Optional<runtime::ExceptionDetails> exceptionDetails;
|
||||
};
|
||||
|
||||
struct runtime::CompileScriptResponse : public Response {
|
||||
CompileScriptResponse() = default;
|
||||
explicit CompileScriptResponse(const folly::dynamic &obj);
|
||||
folly::dynamic toDynamic() const override;
|
||||
|
||||
folly::Optional<runtime::ScriptId> scriptId;
|
||||
folly::Optional<runtime::ExceptionDetails> exceptionDetails;
|
||||
};
|
||||
|
||||
struct runtime::EvaluateResponse : public Response {
|
||||
EvaluateResponse() = default;
|
||||
explicit EvaluateResponse(const folly::dynamic &obj);
|
||||
|
||||
@@ -38,3 +38,4 @@ Runtime.getHeapUsage
|
||||
Runtime.getProperties
|
||||
Runtime.runIfWaitingForDebugger
|
||||
Runtime.globalLexicalScopeNames
|
||||
Runtime.compileScript
|
||||
|
||||
Reference in New Issue
Block a user