31 #include "src/inspector/v8-runtime-agent-impl.h" 35 #include "src/debug/debug-interface.h" 36 #include "src/inspector/injected-script.h" 37 #include "src/inspector/inspected-context.h" 38 #include "src/inspector/protocol/Protocol.h" 39 #include "src/inspector/remote-object-id.h" 40 #include "src/inspector/v8-console-message.h" 41 #include "src/inspector/v8-debugger-agent-impl.h" 42 #include "src/inspector/v8-debugger.h" 43 #include "src/inspector/v8-inspector-impl.h" 44 #include "src/inspector/v8-inspector-session-impl.h" 45 #include "src/inspector/v8-stack-trace-impl.h" 46 #include "src/inspector/v8-value-utils.h" 47 #include "src/tracing/trace-event.h" 49 #include "include/v8-inspector.h" 53 namespace V8RuntimeAgentImplState {
54 static const char customObjectFormatterEnabled[] =
55 "customObjectFormatterEnabled";
56 static const char runtimeEnabled[] =
"runtimeEnabled";
57 static const char bindings[] =
"bindings";
60 using protocol::Runtime::RemoteObject;
64 template <
typename ProtocolCallback>
65 class EvaluateCallbackWrapper :
public EvaluateCallback {
67 static std::unique_ptr<EvaluateCallback> wrap(
68 std::unique_ptr<ProtocolCallback> callback) {
69 return std::unique_ptr<EvaluateCallback>(
70 new EvaluateCallbackWrapper(std::move(callback)));
72 void sendSuccess(std::unique_ptr<protocol::Runtime::RemoteObject> result,
73 protocol::Maybe<protocol::Runtime::ExceptionDetails>
74 exceptionDetails)
override {
75 return m_callback->sendSuccess(std::move(result),
76 std::move(exceptionDetails));
78 void sendFailure(
const protocol::DispatchResponse& response)
override {
79 return m_callback->sendFailure(response);
83 explicit EvaluateCallbackWrapper(std::unique_ptr<ProtocolCallback> callback)
84 : m_callback(
std::move(callback)) {}
86 std::unique_ptr<ProtocolCallback> m_callback;
89 template <
typename ProtocolCallback>
90 bool wrapEvaluateResultAsync(InjectedScript* injectedScript,
92 const v8::TryCatch& tryCatch,
93 const String16& objectGroup, WrapMode wrapMode,
94 ProtocolCallback* callback) {
95 std::unique_ptr<RemoteObject> result;
96 Maybe<protocol::Runtime::ExceptionDetails> exceptionDetails;
98 Response response = injectedScript->wrapEvaluateResult(
99 maybeResultValue, tryCatch, objectGroup, wrapMode, &result,
101 if (response.isSuccess()) {
102 callback->sendSuccess(std::move(result), std::move(exceptionDetails));
105 callback->sendFailure(response);
109 void innerCallFunctionOn(
110 V8InspectorSessionImpl* session, InjectedScript::Scope& scope,
112 Maybe<protocol::Array<protocol::Runtime::CallArgument>> optionalArguments,
113 bool silent, WrapMode wrapMode,
bool userGesture,
bool awaitPromise,
114 const String16& objectGroup,
115 std::unique_ptr<V8RuntimeAgentImpl::CallFunctionOnCallback> callback) {
116 V8InspectorImpl* inspector = session->inspector();
118 std::unique_ptr<v8::Local<v8::Value>[]> argv =
nullptr;
120 if (optionalArguments.isJust()) {
121 protocol::Array<protocol::Runtime::CallArgument>* arguments =
122 optionalArguments.fromJust();
123 argc =
static_cast<int>(arguments->length());
125 for (
int i = 0;
i < argc; ++
i) {
127 Response response = scope.injectedScript()->resolveCallArgument(
128 arguments->get(
i), &argumentValue);
129 if (!response.isSuccess()) {
130 callback->sendFailure(response);
133 argv[
i] = argumentValue;
137 if (silent) scope.ignoreExceptionsAndMuteConsole();
138 if (userGesture) scope.pretendUserGesture();
141 scope.allowCodeGenerationFromStrings();
146 ->compileScript(scope.context(),
"(" + expression +
")", String16())
147 .ToLocal(&functionScript)) {
148 v8::MicrotasksScope microtasksScope(inspector->isolate(),
149 v8::MicrotasksScope::kRunMicrotasks);
150 maybeFunctionValue = functionScript->
Run(scope.context());
154 Response response = scope.initialize();
155 if (!response.isSuccess()) {
156 callback->sendFailure(response);
160 if (scope.tryCatch().HasCaught()) {
161 wrapEvaluateResultAsync(scope.injectedScript(), maybeFunctionValue,
162 scope.tryCatch(), objectGroup, WrapMode::kNoPreview,
168 if (!maybeFunctionValue.ToLocal(&functionValue) ||
170 callback->sendFailure(
171 Response::Error(
"Given expression does not evaluate to a function"));
177 v8::MicrotasksScope microtasksScope(inspector->isolate(),
178 v8::MicrotasksScope::kRunMicrotasks);
180 scope.context(), recv, argc, argv.get());
184 response = scope.initialize();
185 if (!response.isSuccess()) {
186 callback->sendFailure(response);
190 if (!awaitPromise || scope.tryCatch().HasCaught()) {
191 wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue,
192 scope.tryCatch(), objectGroup, wrapMode,
197 scope.injectedScript()->addPromiseCallback(
198 session, maybeResultValue, objectGroup, wrapMode,
199 EvaluateCallbackWrapper<V8RuntimeAgentImpl::CallFunctionOnCallback>::wrap(
200 std::move(callback)));
203 Response ensureContext(V8InspectorImpl* inspector,
int contextGroupId,
204 Maybe<int> executionContextId,
int* contextId) {
205 if (executionContextId.isJust()) {
206 *contextId = executionContextId.fromJust();
210 inspector->client()->ensureDefaultContextInGroup(contextGroupId);
211 if (defaultContext.IsEmpty())
212 return Response::Error(
"Cannot find default execution context");
213 *contextId = InspectedContext::contextId(defaultContext);
215 return Response::OK();
220 V8RuntimeAgentImpl::V8RuntimeAgentImpl(
221 V8InspectorSessionImpl* session, protocol::FrontendChannel* FrontendChannel,
222 protocol::DictionaryValue* state)
223 : m_session(session),
225 m_frontend(FrontendChannel),
226 m_inspector(session->inspector()),
229 V8RuntimeAgentImpl::~V8RuntimeAgentImpl() =
default;
231 void V8RuntimeAgentImpl::evaluate(
232 const String16& expression, Maybe<String16> objectGroup,
233 Maybe<bool> includeCommandLineAPI, Maybe<bool> silent,
234 Maybe<int> executionContextId, Maybe<bool> returnByValue,
235 Maybe<bool> generatePreview, Maybe<bool> userGesture,
236 Maybe<bool> awaitPromise, Maybe<bool> throwOnSideEffect,
237 Maybe<double> timeout, std::unique_ptr<EvaluateCallback> callback) {
238 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT(
"devtools.timeline"),
241 Response response = ensureContext(m_inspector, m_session->contextGroupId(),
242 std::move(executionContextId), &contextId);
243 if (!response.isSuccess()) {
244 callback->sendFailure(response);
248 InjectedScript::ContextScope scope(m_session, contextId);
249 response = scope.initialize();
250 if (!response.isSuccess()) {
251 callback->sendFailure(response);
255 if (silent.fromMaybe(
false)) scope.ignoreExceptionsAndMuteConsole();
256 if (userGesture.fromMaybe(
false)) scope.pretendUserGesture();
258 if (includeCommandLineAPI.fromMaybe(
false)) scope.installCommandLineAPI();
261 scope.allowCodeGenerationFromStrings();
264 V8InspectorImpl::EvaluateScope evaluateScope(m_inspector->isolate());
265 if (timeout.isJust()) {
266 response = evaluateScope.setTimeout(timeout.fromJust() / 1000.0);
267 if (!response.isSuccess()) {
268 callback->sendFailure(response);
272 v8::MicrotasksScope microtasksScope(m_inspector->isolate(),
273 v8::MicrotasksScope::kRunMicrotasks);
274 maybeResultValue = v8::debug::EvaluateGlobal(
275 m_inspector->isolate(), toV8String(m_inspector->isolate(), expression),
276 throwOnSideEffect.fromMaybe(
false));
281 response = scope.initialize();
282 if (!response.isSuccess()) {
283 callback->sendFailure(response);
287 WrapMode mode = generatePreview.fromMaybe(
false) ? WrapMode::kWithPreview
288 : WrapMode::kNoPreview;
289 if (returnByValue.fromMaybe(
false)) mode = WrapMode::kForceValue;
290 if (!awaitPromise.fromMaybe(
false) || scope.tryCatch().HasCaught()) {
291 wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue,
292 scope.tryCatch(), objectGroup.fromMaybe(
""), mode,
296 scope.injectedScript()->addPromiseCallback(
297 m_session, maybeResultValue, objectGroup.fromMaybe(
""), mode,
298 EvaluateCallbackWrapper<EvaluateCallback>::wrap(std::move(callback)));
301 void V8RuntimeAgentImpl::awaitPromise(
302 const String16& promiseObjectId, Maybe<bool> returnByValue,
303 Maybe<bool> generatePreview,
304 std::unique_ptr<AwaitPromiseCallback> callback) {
305 InjectedScript::ObjectScope scope(m_session, promiseObjectId);
306 Response response = scope.initialize();
307 if (!response.isSuccess()) {
308 callback->sendFailure(response);
311 if (!scope.object()->IsPromise()) {
312 callback->sendFailure(
313 Response::Error(
"Could not find promise with given id"));
316 WrapMode mode = generatePreview.fromMaybe(
false) ? WrapMode::kWithPreview
317 : WrapMode::kNoPreview;
318 if (returnByValue.fromMaybe(
false)) mode = WrapMode::kForceValue;
319 scope.injectedScript()->addPromiseCallback(
320 m_session, scope.object(), scope.objectGroupName(), mode,
321 EvaluateCallbackWrapper<AwaitPromiseCallback>::wrap(std::move(callback)));
324 void V8RuntimeAgentImpl::callFunctionOn(
325 const String16& expression, Maybe<String16> objectId,
326 Maybe<protocol::Array<protocol::Runtime::CallArgument>> optionalArguments,
327 Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
328 Maybe<bool> userGesture, Maybe<bool> awaitPromise,
329 Maybe<int> executionContextId, Maybe<String16> objectGroup,
330 std::unique_ptr<CallFunctionOnCallback> callback) {
331 if (objectId.isJust() && executionContextId.isJust()) {
332 callback->sendFailure(Response::Error(
333 "ObjectId must not be specified together with executionContextId"));
336 if (!objectId.isJust() && !executionContextId.isJust()) {
337 callback->sendFailure(Response::Error(
338 "Either ObjectId or executionContextId must be specified"));
341 WrapMode mode = generatePreview.fromMaybe(
false) ? WrapMode::kWithPreview
342 : WrapMode::kNoPreview;
343 if (returnByValue.fromMaybe(
false)) mode = WrapMode::kForceValue;
344 if (objectId.isJust()) {
345 InjectedScript::ObjectScope scope(m_session, objectId.fromJust());
346 Response response = scope.initialize();
347 if (!response.isSuccess()) {
348 callback->sendFailure(response);
351 innerCallFunctionOn(m_session, scope, scope.object(), expression,
352 std::move(optionalArguments), silent.fromMaybe(
false),
353 mode, userGesture.fromMaybe(
false),
354 awaitPromise.fromMaybe(
false),
355 objectGroup.isJust() ? objectGroup.fromMaybe(String16())
356 : scope.objectGroupName(),
357 std::move(callback));
361 ensureContext(m_inspector, m_session->contextGroupId(),
362 std::move(executionContextId.fromJust()), &contextId);
363 if (!response.isSuccess()) {
364 callback->sendFailure(response);
367 InjectedScript::ContextScope scope(m_session, contextId);
368 response = scope.initialize();
369 if (!response.isSuccess()) {
370 callback->sendFailure(response);
373 innerCallFunctionOn(m_session, scope, scope.context()->Global(), expression,
374 std::move(optionalArguments), silent.fromMaybe(
false),
375 mode, userGesture.fromMaybe(
false),
376 awaitPromise.fromMaybe(
false),
377 objectGroup.fromMaybe(
""), std::move(callback));
381 Response V8RuntimeAgentImpl::getProperties(
382 const String16& objectId, Maybe<bool> ownProperties,
383 Maybe<bool> accessorPropertiesOnly, Maybe<bool> generatePreview,
384 std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>*
386 Maybe<protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>*
388 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
389 using protocol::Runtime::InternalPropertyDescriptor;
391 InjectedScript::ObjectScope scope(m_session, objectId);
392 Response response = scope.initialize();
393 if (!response.isSuccess())
return response;
395 scope.ignoreExceptionsAndMuteConsole();
396 v8::MicrotasksScope microtasks_scope(m_inspector->isolate(),
397 v8::MicrotasksScope::kRunMicrotasks);
398 if (!scope.object()->IsObject())
399 return Response::Error(
"Value with given id is not an object");
402 response = scope.injectedScript()->getProperties(
403 object, scope.objectGroupName(), ownProperties.fromMaybe(
false),
404 accessorPropertiesOnly.fromMaybe(
false),
405 generatePreview.fromMaybe(
false) ? WrapMode::kWithPreview
406 : WrapMode::kNoPreview,
407 result, exceptionDetails);
408 if (!response.isSuccess())
return response;
409 if (exceptionDetails->isJust() || accessorPropertiesOnly.fromMaybe(
false))
410 return Response::OK();
411 std::unique_ptr<protocol::Array<InternalPropertyDescriptor>>
412 propertiesProtocolArray;
413 response = scope.injectedScript()->getInternalProperties(
414 object, scope.objectGroupName(), &propertiesProtocolArray);
415 if (!response.isSuccess())
return response;
416 if (propertiesProtocolArray->length())
417 *internalProperties = std::move(propertiesProtocolArray);
418 return Response::OK();
421 Response V8RuntimeAgentImpl::releaseObject(
const String16& objectId) {
422 InjectedScript::ObjectScope scope(m_session, objectId);
423 Response response = scope.initialize();
424 if (!response.isSuccess())
return response;
425 scope.injectedScript()->releaseObject(objectId);
426 return Response::OK();
429 Response V8RuntimeAgentImpl::releaseObjectGroup(
const String16& objectGroup) {
430 m_session->releaseObjectGroup(objectGroup);
431 return Response::OK();
434 Response V8RuntimeAgentImpl::runIfWaitingForDebugger() {
435 m_inspector->client()->runIfWaitingForDebugger(m_session->contextGroupId());
436 return Response::OK();
439 Response V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(
bool enabled) {
440 m_state->setBoolean(V8RuntimeAgentImplState::customObjectFormatterEnabled,
442 if (!m_enabled)
return Response::Error(
"Runtime agent is not enabled");
443 m_session->setCustomObjectFormatterEnabled(enabled);
444 return Response::OK();
447 Response V8RuntimeAgentImpl::setMaxCallStackSizeToCapture(
int size) {
449 return Response::Error(
"maxCallStackSizeToCapture should be non-negative");
451 V8StackTraceImpl::maxCallStackSizeToCapture = size;
452 return Response::OK();
455 Response V8RuntimeAgentImpl::discardConsoleEntries() {
456 V8ConsoleMessageStorage* storage =
457 m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId());
459 return Response::OK();
462 Response V8RuntimeAgentImpl::compileScript(
463 const String16& expression,
const String16& sourceURL,
bool persistScript,
464 Maybe<int> executionContextId, Maybe<String16>* scriptId,
465 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
466 if (!m_enabled)
return Response::Error(
"Runtime agent is not enabled");
469 Response response = ensureContext(m_inspector, m_session->contextGroupId(),
470 std::move(executionContextId), &contextId);
471 if (!response.isSuccess())
return response;
472 InjectedScript::ContextScope scope(m_session, contextId);
473 response = scope.initialize();
474 if (!response.isSuccess())
return response;
476 if (!persistScript) m_inspector->debugger()->muteScriptParsedEvents();
478 bool isOk = m_inspector->compileScript(scope.context(), expression, sourceURL)
480 if (!persistScript) m_inspector->debugger()->unmuteScriptParsedEvents();
482 if (scope.tryCatch().HasCaught()) {
483 response = scope.injectedScript()->createExceptionDetails(
484 scope.tryCatch(), String16(), WrapMode::kNoPreview, exceptionDetails);
485 if (!response.isSuccess())
return response;
486 return Response::OK();
488 return Response::Error(
"Script compilation failed");
492 if (!persistScript)
return Response::OK();
494 String16 scriptValueId =
496 std::unique_ptr<v8::Global<v8::Script>> global(
498 m_compiledScripts[scriptValueId] = std::move(global);
499 *scriptId = scriptValueId;
500 return Response::OK();
503 void V8RuntimeAgentImpl::runScript(
504 const String16& scriptId, Maybe<int> executionContextId,
505 Maybe<String16> objectGroup, Maybe<bool> silent,
506 Maybe<bool> includeCommandLineAPI, Maybe<bool> returnByValue,
507 Maybe<bool> generatePreview, Maybe<bool> awaitPromise,
508 std::unique_ptr<RunScriptCallback> callback) {
510 callback->sendFailure(Response::Error(
"Runtime agent is not enabled"));
514 auto it = m_compiledScripts.find(scriptId);
515 if (it == m_compiledScripts.end()) {
516 callback->sendFailure(Response::Error(
"No script with given id"));
521 Response response = ensureContext(m_inspector, m_session->contextGroupId(),
522 std::move(executionContextId), &contextId);
523 if (!response.isSuccess()) {
524 callback->sendFailure(response);
528 InjectedScript::ContextScope scope(m_session, contextId);
529 response = scope.initialize();
530 if (!response.isSuccess()) {
531 callback->sendFailure(response);
535 if (silent.fromMaybe(
false)) scope.ignoreExceptionsAndMuteConsole();
537 std::unique_ptr<v8::Global<v8::Script>> scriptWrapper = std::move(it->second);
538 m_compiledScripts.erase(it);
541 callback->sendFailure(Response::Error(
"Script execution failed"));
545 if (includeCommandLineAPI.fromMaybe(
false)) scope.installCommandLineAPI();
549 v8::MicrotasksScope microtasksScope(m_inspector->isolate(),
550 v8::MicrotasksScope::kRunMicrotasks);
551 maybeResultValue = script->
Run(scope.context());
556 response = scope.initialize();
557 if (!response.isSuccess()) {
558 callback->sendFailure(response);
562 WrapMode mode = generatePreview.fromMaybe(
false) ? WrapMode::kWithPreview
563 : WrapMode::kNoPreview;
564 if (returnByValue.fromMaybe(
false)) mode = WrapMode::kForceValue;
565 if (!awaitPromise.fromMaybe(
false) || scope.tryCatch().HasCaught()) {
566 wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue,
567 scope.tryCatch(), objectGroup.fromMaybe(
""), mode,
571 scope.injectedScript()->addPromiseCallback(
572 m_session, maybeResultValue.ToLocalChecked(), objectGroup.fromMaybe(
""),
574 EvaluateCallbackWrapper<RunScriptCallback>::wrap(std::move(callback)));
577 Response V8RuntimeAgentImpl::queryObjects(
578 const String16& prototypeObjectId, Maybe<String16> objectGroup,
579 std::unique_ptr<protocol::Runtime::RemoteObject>* objects) {
580 InjectedScript::ObjectScope scope(m_session, prototypeObjectId);
581 Response response = scope.initialize();
582 if (!response.isSuccess())
return response;
583 if (!scope.object()->IsObject()) {
584 return Response::Error(
"Prototype should be instance of Object");
588 return scope.injectedScript()->wrapObject(
589 resultArray, objectGroup.fromMaybe(scope.objectGroupName()),
590 WrapMode::kNoPreview, objects);
593 Response V8RuntimeAgentImpl::globalLexicalScopeNames(
594 Maybe<int> executionContextId,
595 std::unique_ptr<protocol::Array<String16>>* outNames) {
597 Response response = ensureContext(m_inspector, m_session->contextGroupId(),
598 std::move(executionContextId), &contextId);
599 if (!response.isSuccess())
return response;
601 InjectedScript::ContextScope scope(m_session, contextId);
602 response = scope.initialize();
603 if (!response.isSuccess())
return response;
606 v8::debug::GlobalLexicalScopeNames(scope.context(), &names);
607 *outNames = protocol::Array<String16>::create();
608 for (
size_t i = 0;
i < names.Size(); ++
i) {
609 (*outNames)->addItem(
610 toProtocolString(m_inspector->isolate(), names.Get(
i)));
612 return Response::OK();
615 Response V8RuntimeAgentImpl::getIsolateId(String16* outIsolateId) {
617 std::snprintf(buf,
sizeof(buf),
"%" PRIx64, m_inspector->isolateId());
619 return Response::OK();
622 Response V8RuntimeAgentImpl::getHeapUsage(
double* out_usedSize,
623 double* out_totalSize) {
624 v8::HeapStatistics stats;
625 m_inspector->isolate()->GetHeapStatistics(&stats);
626 *out_usedSize = stats.used_heap_size();
627 *out_totalSize = stats.total_heap_size();
628 return Response::OK();
631 void V8RuntimeAgentImpl::terminateExecution(
632 std::unique_ptr<TerminateExecutionCallback> callback) {
633 m_inspector->debugger()->terminateExecution(std::move(callback));
636 Response V8RuntimeAgentImpl::addBinding(
const String16& name,
637 Maybe<int> executionContextId) {
638 if (!m_state->getObject(V8RuntimeAgentImplState::bindings)) {
639 m_state->setObject(V8RuntimeAgentImplState::bindings,
640 protocol::DictionaryValue::create());
642 protocol::DictionaryValue* bindings =
643 m_state->getObject(V8RuntimeAgentImplState::bindings);
644 if (bindings->booleanProperty(name,
false))
return Response::OK();
645 if (executionContextId.isJust()) {
646 int contextId = executionContextId.fromJust();
647 InspectedContext* context =
648 m_inspector->getContext(m_session->contextGroupId(), contextId);
650 return Response::Error(
651 "Cannot find execution context with given executionContextId");
653 addBinding(context, name);
655 bindings->setBoolean(name,
false);
656 return Response::OK();
658 bindings->setBoolean(name,
true);
659 m_inspector->forEachContext(
660 m_session->contextGroupId(),
661 [&name,
this](InspectedContext* context) { addBinding(context, name); });
662 return Response::OK();
665 void V8RuntimeAgentImpl::bindingCallback(
668 if (info.
Length() != 1 || !info[0]->IsString()) {
670 isolate,
"Invalid arguments: should be exactly one string."));
673 V8InspectorImpl* inspector =
674 static_cast<V8InspectorImpl*
>(v8::debug::GetInspector(isolate));
675 int contextId = InspectedContext::contextId(isolate->GetCurrentContext());
676 int contextGroupId = inspector->contextGroupId(contextId);
683 inspector->forEachSession(
685 [&name, &payload, &contextId](V8InspectorSessionImpl* session) {
686 session->runtimeAgent()->bindingCalled(name, payload, contextId);
690 void V8RuntimeAgentImpl::addBinding(InspectedContext* context,
691 const String16& name) {
697 v8::MicrotasksScope microtasks(m_inspector->isolate(),
698 v8::MicrotasksScope::kDoNotRunMicrotasks);
700 .ToLocal(&functionValue)) {
701 v8::Maybe<bool> success = global->Set(localContext, v8Name, functionValue);
706 Response V8RuntimeAgentImpl::removeBinding(
const String16& name) {
707 protocol::DictionaryValue* bindings =
708 m_state->getObject(V8RuntimeAgentImplState::bindings);
709 if (!bindings)
return Response::OK();
710 bindings->remove(name);
711 return Response::OK();
714 void V8RuntimeAgentImpl::bindingCalled(
const String16& name,
715 const String16& payload,
716 int executionContextId) {
717 protocol::DictionaryValue* bindings =
718 m_state->getObject(V8RuntimeAgentImplState::bindings);
719 if (!bindings || !bindings->get(name))
return;
720 m_frontend.bindingCalled(name, payload, executionContextId);
723 void V8RuntimeAgentImpl::addBindings(InspectedContext* context) {
724 if (!m_enabled)
return;
725 protocol::DictionaryValue* bindings =
726 m_state->getObject(V8RuntimeAgentImplState::bindings);
727 if (!bindings)
return;
728 for (
size_t i = 0;
i < bindings->size(); ++
i) {
729 if (!bindings->at(
i).second)
continue;
730 addBinding(context, bindings->at(
i).first);
734 void V8RuntimeAgentImpl::restore() {
735 if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled,
false))
737 m_frontend.executionContextsCleared();
739 if (m_state->booleanProperty(
740 V8RuntimeAgentImplState::customObjectFormatterEnabled,
false))
741 m_session->setCustomObjectFormatterEnabled(
true);
743 m_inspector->forEachContext(
744 m_session->contextGroupId(),
745 [
this](InspectedContext* context) { addBindings(context); });
748 Response V8RuntimeAgentImpl::enable() {
749 if (m_enabled)
return Response::OK();
750 m_inspector->client()->beginEnsureAllContextsInGroup(
751 m_session->contextGroupId());
753 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled,
true);
754 m_inspector->enableStackCapturingIfNeeded();
755 m_session->reportAllContexts(
this);
756 V8ConsoleMessageStorage* storage =
757 m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId());
758 for (
const auto& message : storage->messages()) {
759 if (!reportMessage(message.get(),
false))
break;
761 return Response::OK();
764 Response V8RuntimeAgentImpl::disable() {
765 if (!m_enabled)
return Response::OK();
767 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled,
false);
768 m_state->remove(V8RuntimeAgentImplState::bindings);
769 m_inspector->disableStackCapturingIfNeeded();
770 m_session->setCustomObjectFormatterEnabled(
false);
772 m_inspector->client()->endEnsureAllContextsInGroup(
773 m_session->contextGroupId());
774 if (m_session->debuggerAgent() && !m_session->debuggerAgent()->enabled()) {
775 m_session->debuggerAgent()->setAsyncCallStackDepth(0);
777 return Response::OK();
780 void V8RuntimeAgentImpl::reset() {
781 m_compiledScripts.clear();
783 int sessionId = m_session->sessionId();
784 m_inspector->forEachContext(m_session->contextGroupId(),
785 [&sessionId](InspectedContext* context) {
786 context->setReported(sessionId,
false);
788 m_frontend.executionContextsCleared();
792 void V8RuntimeAgentImpl::reportExecutionContextCreated(
793 InspectedContext* context) {
794 if (!m_enabled)
return;
795 context->setReported(m_session->sessionId(),
true);
796 std::unique_ptr<protocol::Runtime::ExecutionContextDescription> description =
797 protocol::Runtime::ExecutionContextDescription::create()
798 .setId(context->contextId())
799 .setName(context->humanReadableName())
800 .setOrigin(context->origin())
802 if (!context->auxData().isEmpty())
803 description->setAuxData(protocol::DictionaryValue::cast(
804 protocol::StringUtil::parseJSON(context->auxData())));
805 m_frontend.executionContextCreated(std::move(description));
808 void V8RuntimeAgentImpl::reportExecutionContextDestroyed(
809 InspectedContext* context) {
810 if (m_enabled && context->isReported(m_session->sessionId())) {
811 context->setReported(m_session->sessionId(),
false);
812 m_frontend.executionContextDestroyed(context->contextId());
816 void V8RuntimeAgentImpl::inspect(
817 std::unique_ptr<protocol::Runtime::RemoteObject> objectToInspect,
818 std::unique_ptr<protocol::DictionaryValue> hints) {
820 m_frontend.inspectRequested(std::move(objectToInspect), std::move(hints));
823 void V8RuntimeAgentImpl::messageAdded(V8ConsoleMessage* message) {
824 if (m_enabled) reportMessage(message,
true);
827 bool V8RuntimeAgentImpl::reportMessage(V8ConsoleMessage* message,
828 bool generatePreview) {
829 message->reportToFrontend(&m_frontend, m_session, generatePreview);
831 return m_inspector->hasConsoleMessageStorage(m_session->contextGroupId());
V8_INLINE int Length() const
static V8_INLINE Local< T > Cast(Local< S > that)
V8_WARN_UNUSED_RESULT MaybeLocal< Value > Run(Local< Context > context)
V8_INLINE bool IsEmpty() const
static MaybeLocal< Function > New(Local< Context > context, FunctionCallback callback, Local< Value > data=Local< Value >(), int length=0, ConstructorBehavior behavior=ConstructorBehavior::kAllow, SideEffectType side_effect_type=SideEffectType::kHasSideEffect)
V8_INLINE Local< S > As() const
V8_INLINE Local< Value > Data() const
Local< UnboundScript > GetUnboundScript()
V8_INLINE Isolate * GetIsolate() const