7#include "../../third_party/inspector_protocol/crdtp/cbor.h"
8#include "../../third_party/inspector_protocol/crdtp/dispatch.h"
9#include "../../third_party/inspector_protocol/crdtp/json.h"
16#include "src/inspector/protocol/Protocol.h"
33using v8_crdtp::SpanFrom;
34using v8_crdtp::Status;
35using v8_crdtp::cbor::CheckCBORMessage;
36using v8_crdtp::json::ConvertCBORToJSON;
37using v8_crdtp::json::ConvertJSONToCBOR;
39bool IsCBORMessage(StringView msg) {
40 if (!msg.is8Bit() || msg.length() < 3)
return false;
41 const uint8_t* bytes = msg.characters8();
42 return bytes[0] == 0xd8 &&
43 (bytes[1] == 0x5a || (bytes[1] == 0x18 && bytes[2] == 0x5a));
46Status ConvertToCBOR(StringView state, std::vector<uint8_t>* cbor) {
49 span<uint8_t>(state.characters8(), state.length()), cbor)
51 span<
uint16_t>(state.characters16(), state.length()), cbor);
54std::unique_ptr<protocol::DictionaryValue> ParseState(StringView state) {
55 std::vector<uint8_t> converted;
57 if (IsCBORMessage(state))
58 cbor = span<uint8_t>(state.characters8(), state.length());
59 else if (ConvertToCBOR(state, &converted).ok())
60 cbor = SpanFrom(converted);
62 std::unique_ptr<protocol::Value> value =
63 protocol::Value::parseBinary(cbor.data(), cbor.size());
64 std::unique_ptr<protocol::DictionaryValue> dictionaryValue =
65 protocol::DictionaryValue::cast(std::move(value));
66 if (dictionaryValue)
return dictionaryValue;
68 return protocol::DictionaryValue::create();
75 protocol::Runtime::Metainfo::commandPrefix) ||
77 protocol::Debugger::Metainfo::commandPrefix) ||
79 protocol::Profiler::Metainfo::commandPrefix) ||
81 method, protocol::HeapProfiler::Metainfo::commandPrefix) ||
83 protocol::Console::Metainfo::commandPrefix) ||
85 protocol::Schema::Metainfo::commandPrefix);
97 std::shared_ptr<V8DebuggerBarrier> debuggerBarrier) {
100 std::move(debuggerBarrier)));
107 std::shared_ptr<V8DebuggerBarrier> debuggerBarrier)
108 : m_contextGroupId(contextGroupId),
109 m_sessionId(sessionId),
112 m_customObjectFormatterEnabled(false),
114 m_state(ParseState(savedState)),
115 m_runtimeAgent(nullptr),
116 m_debuggerAgent(nullptr),
117 m_heapProfilerAgent(nullptr),
118 m_profilerAgent(nullptr),
119 m_consoleAgent(nullptr),
120 m_schemaAgent(nullptr),
121 m_clientTrustLevel(clientTrustLevel) {
125 this,
this,
agentState(protocol::Runtime::Metainfo::domainName),
126 std::move(debuggerBarrier)));
130 this,
this,
agentState(protocol::Debugger::Metainfo::domainName)));
134 this,
this,
agentState(protocol::Console::Metainfo::domainName)));
138 this,
this,
agentState(protocol::Profiler::Metainfo::domainName)));
143 this,
this,
agentState(protocol::HeapProfiler::Metainfo::domainName)));
148 this,
this,
agentState(protocol::Schema::Metainfo::domainName)));
151 if (savedState.
length()) {
173 protocol::DictionaryValue* state =
m_state->getObject(name);
175 std::unique_ptr<protocol::DictionaryValue> newState =
176 protocol::DictionaryValue::create();
177 state = newState.get();
178 m_state->setObject(name, std::move(newState));
184 std::unique_ptr<protocol::Serializable> message) {
185 std::vector<uint8_t> cbor = message->Serialize();
186 DCHECK(CheckCBORMessage(SpanFrom(cbor)).ok());
188 std::vector<uint8_t> json;
189 Status status = ConvertCBORToJSON(SpanFrom(cbor), &json);
198 String16 string16(
reinterpret_cast<const char*
>(json.data()), json.size());
203 int callId, std::unique_ptr<protocol::Serializable> message) {
208 std::unique_ptr<protocol::Serializable> message) {
213 const v8_crdtp::span<uint8_t>
method,
214 v8_crdtp::span<uint8_t> message) {
234 context->discardInjectedScript(
sessionId);
240 injectedScript =
nullptr;
244 return Response::ServerError(
"Cannot find context with specified id");
245 injectedScript = context->getInjectedScript(
m_sessionId);
246 if (!injectedScript) {
247 injectedScript = context->createInjectedScript(
m_sessionId);
251 return Response::Success();
257 return Response::ServerError(
"Cannot find context with specified id");
275 std::unique_ptr<StringBuffer>* error,
StringView objectId,
277 std::unique_ptr<StringBuffer>* objectGroup) {
280 objectGroup ? &objectGroupString :
nullptr);
281 if (response.IsError()) {
283 const std::string& msg = response.Message();
297 std::unique_ptr<RemoteObjectId> remoteId;
299 if (!response.IsSuccess())
return response;
302 if (!response.IsSuccess())
return response;
303 response = injectedScript->
findObject(*remoteId,
object);
304 if (!response.IsSuccess())
return response;
306 if (objectGroup) *objectGroup = injectedScript->
objectGroupName(*remoteId);
307 return Response::Success();
310std::unique_ptr<protocol::Runtime::API::RemoteObject>
317std::unique_ptr<protocol::Runtime::RemoteObject>
321 bool generatePreview) {
324 if (!injectedScript)
return nullptr;
325 std::unique_ptr<protocol::Runtime::RemoteObject>
result;
333std::unique_ptr<protocol::Runtime::RemoteObject>
339 if (!injectedScript)
return nullptr;
340 return injectedScript->
wrapTable(table, columns);
362 using v8_crdtp::span;
363 using v8_crdtp::SpanFrom;
365 std::vector<uint8_t> converted_cbor;
366 if (IsCBORMessage(message)) {
368 m_state->setBoolean(
"use_binary_protocol",
true);
369 cbor = span<uint8_t>(message.characters8(), message.length());
373 auto status = ConvertToCBOR(message, &converted_cbor);
377 v8_crdtp::DispatchResponse::ParseError(status.ToASCIIString()))));
380 cbor = SpanFrom(converted_cbor);
382 v8_crdtp::Dispatchable dispatchable(cbor);
383 if (!dispatchable.ok()) {
384 if (!dispatchable.HasCallId()) {
386 v8_crdtp::CreateErrorNotification(dispatchable.DispatchError())));
389 dispatchable.CallId(),
391 dispatchable.CallId(), dispatchable.DispatchError())));
402std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
404 std::vector<std::unique_ptr<protocol::Schema::Domain>> domains =
406 std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
result;
407 for (
size_t i = 0;
i < domains.size(); ++
i)
408 result.push_back(std::move(domains[
i]));
412std::vector<std::unique_ptr<protocol::Schema::Domain>>
414 std::vector<std::unique_ptr<protocol::Schema::Domain>>
result;
415 result.push_back(protocol::Schema::Domain::create()
416 .setName(protocol::Runtime::Metainfo::domainName)
417 .setVersion(protocol::Runtime::Metainfo::version)
419 result.push_back(protocol::Schema::Domain::create()
420 .setName(protocol::Debugger::Metainfo::domainName)
421 .setVersion(protocol::Debugger::Metainfo::version)
423 result.push_back(protocol::Schema::Domain::create()
424 .setName(protocol::Profiler::Metainfo::domainName)
425 .setVersion(protocol::Profiler::Metainfo::version)
427 result.push_back(protocol::Schema::Domain::create()
428 .setName(protocol::HeapProfiler::Metainfo::domainName)
429 .setVersion(protocol::HeapProfiler::Metainfo::version)
431 result.push_back(protocol::Schema::Domain::create()
432 .setName(protocol::Schema::Metainfo::domainName)
433 .setVersion(protocol::Schema::Metainfo::version)
439 std::unique_ptr<V8InspectorSession::Inspectable> inspectable) {
453 std::vector<uint8_t> cbor;
454 ConvertToCBOR(breakDetails, &cbor);
457 protocol::DictionaryValue::cast(
458 protocol::Value::parseBinary(cbor.data(), cbor.size())));
467 std::vector<uint8_t> cbor;
468 ConvertToCBOR(breakDetails, &cbor);
471 protocol::DictionaryValue::cast(
472 protocol::Value::parseBinary(cbor.data(), cbor.size())));
485std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
487 bool caseSensitive,
bool isRegex) {
489 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches =
491 caseSensitive, isRegex);
492 std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
result;
493 for (
size_t i = 0;
i < matches.size(); ++
i)
494 result.push_back(std::move(matches[
i]));
505 bool includeCommandLineAPI) {
516 if (includeCommandLineAPI) {
531 return {EvaluateResult::ResultType::kException,
536 return {EvaluateResult::ResultType::kSuccess, handleScope.
Escape(
result)};
V8_INLINE Local< T > Escape(Local< T > value)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local< S > *out) const
v8::Local< v8::Context > context() const
const v8::TryCatch & tryCatch() const
void installCommandLineAPI()
void allowCodeGenerationFromStrings()
void setTryCatchVerbose()
Response wrapObject(v8::Local< v8::Value >, const String16 &groupName, const WrapOptions &wrapOptions, std::unique_ptr< protocol::Runtime::RemoteObject > *result)
void setCustomObjectFormatterEnabled(bool)
void releaseObjectGroup(const String16 &)
InspectedContext * context() const
Response findObject(const RemoteObjectId &, v8::Local< v8::Value > *) const
std::unique_ptr< protocol::Runtime::RemoteObject > wrapTable(v8::Local< v8::Object > table, v8::MaybeLocal< v8::Array > columns)
String16 objectGroupName(const RemoteObjectId &) const
v8::Local< v8::Context > context() const
uint64_t isolateId() const
static Response parse(const String16 &, std::unique_ptr< RemoteObjectId > *)
static V8_EXPORT String16 fromUTF8(const char *stringStart, size_t length)
static int executionContextId(v8::Local< v8::Context > context)
void disconnect(V8InspectorSessionImpl *)
v8::Isolate * isolate() const
InspectedContext * getContext(int groupId, int contextId) const
uint64_t isolateId() override
void forEachContext(int contextGroupId, const std::function< void(InspectedContext *)> &callback)
V8Inspector::Channel * m_channel
void FlushProtocolNotifications() override
protocol::DictionaryValue * agentState(const String16 &name)
V8Inspector::ClientTrustLevel clientTrustLevel()
std::vector< std::unique_ptr< protocol::Schema::Domain > > supportedDomainsImpl()
std::unique_ptr< V8ConsoleAgentImpl > m_consoleAgent
V8InspectorSession::Inspectable * inspectedObject(unsigned num)
Response findInjectedScript(int contextId, InjectedScript *&)
std::unique_ptr< protocol::DictionaryValue > m_state
std::unique_ptr< V8DebuggerAgentImpl > m_debuggerAgent
std::vector< std::unique_ptr< protocol::Schema::API::Domain > > supportedDomains() override
void addInspectedObject(std::unique_ptr< V8InspectorSession::Inspectable >) override
std::vector< std::unique_ptr< V8InspectorSession::Inspectable > > m_inspectedObjects
void schedulePauseOnNextStatement(StringView breakReason, StringView breakDetails) override
std::unique_ptr< StringBuffer > serializeForFrontend(std::unique_ptr< protocol::Serializable > message)
void FallThrough(int callId, v8_crdtp::span< uint8_t > method, v8_crdtp::span< uint8_t > message) override
void resume(bool terminateOnResume=false) override
std::unique_ptr< protocol::Runtime::RemoteObject > wrapObject(v8::Local< v8::Context >, v8::Local< v8::Value >, const String16 &groupName, bool generatePreview)
V8Inspector::ClientTrustLevel m_clientTrustLevel
std::vector< std::unique_ptr< protocol::Debugger::API::SearchMatch > > searchInTextByLines(StringView text, StringView query, bool caseSensitive, bool isRegex) override
void releaseObjectGroup(const String16 &objectGroup)
void SendProtocolResponse(int callId, std::unique_ptr< protocol::Serializable > message) override
V8InspectorImpl * inspector() const
void SendProtocolNotification(std::unique_ptr< protocol::Serializable > message) override
std::unique_ptr< V8ProfilerAgentImpl > m_profilerAgent
void breakProgram(StringView breakReason, StringView breakDetails) override
static std::unique_ptr< V8InspectorSessionImpl > create(V8InspectorImpl *, int contextGroupId, int sessionId, V8Inspector::Channel *, StringView state, v8_inspector::V8Inspector::ClientTrustLevel, std::shared_ptr< V8DebuggerBarrier >)
std::unique_ptr< V8HeapProfilerAgentImpl > m_heapProfilerAgent
void setCustomObjectFormatterEnabled(bool)
bool m_customObjectFormatterEnabled
std::vector< uint8_t > state() override
std::unique_ptr< V8SchemaAgentImpl > m_schemaAgent
protocol::UberDispatcher m_dispatcher
static const unsigned kInspectedObjectBufferSize
void discardInjectedScripts()
std::unique_ptr< protocol::Runtime::RemoteObject > wrapTable(v8::Local< v8::Context >, v8::Local< v8::Object > table, v8::MaybeLocal< v8::Array > columns)
bool use_binary_protocol_
void dispatchProtocolMessage(StringView message) override
~V8InspectorSessionImpl() override
Response unwrapObject(const String16 &objectId, v8::Local< v8::Value > *, v8::Local< v8::Context > *, String16 *objectGroup)
void triggerPreciseCoverageDeltaUpdate(StringView occasion) override
std::unique_ptr< V8RuntimeAgentImpl > m_runtimeAgent
void cancelPauseOnNextStatement() override
V8InspectorSessionImpl(const V8InspectorSessionImpl &)=delete
V8InspectorImpl * m_inspector
void reportAllContexts(V8RuntimeAgentImpl *)
EvaluateResult evaluate(v8::Local< v8::Context > context, StringView expression, bool includeCommandLineAPI=false) override
int contextGroupId() const
void setSkipAllPauses(bool) override
virtual v8::Local< v8::Value > get(v8::Local< v8::Context >)=0
static bool canDispatchMethod(StringView method)
virtual void sendNotification(std::unique_ptr< StringBuffer > message)=0
virtual void flushProtocolNotifications()=0
virtual void sendResponse(int callId, std::unique_ptr< StringBuffer > message)=0
void reportExecutionContextCreated(InspectedContext *)
ZoneVector< RpoNumber > & result
MaybeLocal< v8::Value > EvaluateGlobal(v8::Isolate *isolate, v8::Local< v8::String > source, EvaluateGlobalMode mode, bool repl)
bool stringViewStartsWith(const StringView &string, const char *prefix)
std::unique_ptr< StringBuffer > StringBufferFrom(String16 str)
v8::Local< v8::String > toV8String(v8::Isolate *isolate, const String16 &string)
std::vector< std::unique_ptr< protocol::Debugger::SearchMatch > > searchInTextByLinesImpl(V8InspectorSession *session, const String16 &text, const String16 &query, const bool caseSensitive, const bool isRegex)
String16 toString16(const StringView &string)
#define DCHECK(condition)
V8InspectorImpl * m_inspector