31 #include "src/inspector/injected-script.h" 34 #include <unordered_set> 36 #include "src/inspector/custom-preview.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/string-util.h" 41 #include "src/inspector/v8-console.h" 42 #include "src/inspector/v8-inspector-impl.h" 43 #include "src/inspector/v8-inspector-session-impl.h" 44 #include "src/inspector/v8-stack-trace-impl.h" 45 #include "src/inspector/v8-value-utils.h" 46 #include "src/inspector/value-mirror.h" 48 #include "include/v8-inspector.h" 53 static const char kGlobalHandleLabel[] =
"DevTools console";
54 static bool isResolvableNumberLike(String16 query) {
55 return query ==
"Infinity" || query ==
"-Infinity" || query ==
"NaN";
59 using protocol::Array;
60 using protocol::Runtime::PropertyDescriptor;
61 using protocol::Runtime::InternalPropertyDescriptor;
62 using protocol::Runtime::RemoteObject;
63 using protocol::Maybe;
69 int executionContextId,
const String16& objectGroup,
73 callback->sendFailure(Response::InternalError());
76 if (!resolver->
Resolve(context, value).FromMaybe(
false)) {
77 callback->sendFailure(Response::InternalError());
84 session, executionContextId, objectGroup, wrapMode, callback);
88 v8::ConstructorBehavior::kThrow)
90 if (promise->Then(context, thenCallbackFunction).IsEmpty()) {
91 callback->sendFailure(Response::InternalError());
96 v8::ConstructorBehavior::kThrow)
98 if (promise->
Catch(context, catchCallbackFunction).IsEmpty()) {
99 callback->sendFailure(Response::InternalError());
114 handler->thenCallback(value);
126 handler->catchCallback(value);
131 int executionContextId,
const String16& objectGroup,
133 : m_inspector(session->inspector()),
134 m_sessionId(session->sessionId()),
135 m_contextGroupId(session->contextGroupId()),
136 m_executionContextId(executionContextId),
137 m_objectGroup(objectGroup),
138 m_wrapMode(wrapMode),
139 m_callback(std::move(callback)),
140 m_wrapper(m_inspector->isolate(),
141 v8::External::New(m_inspector->isolate(),
this)) {
142 m_wrapper.
SetWeak(
this, cleanup, v8::WeakCallbackType::kParameter);
147 if (!data.GetParameter()->m_wrapper.IsEmpty()) {
148 data.GetParameter()->m_wrapper.Reset();
149 data.SetSecondPassCallback(cleanup);
151 data.GetParameter()->sendPromiseCollected();
152 delete data.GetParameter();
158 m_inspector->sessionById(m_contextGroupId, m_sessionId);
159 if (!session)
return;
161 Response response = scope.initialize();
162 if (!response.isSuccess())
return;
163 if (m_objectGroup ==
"console") {
164 scope.injectedScript()->setLastEvaluationResult(result);
166 std::unique_ptr<EvaluateCallback> callback =
167 scope.injectedScript()->takeEvaluateCallback(m_callback);
168 if (!callback)
return;
169 std::unique_ptr<protocol::Runtime::RemoteObject> wrappedValue;
170 response = scope.injectedScript()->wrapObject(result, m_objectGroup,
171 m_wrapMode, &wrappedValue);
172 if (!response.isSuccess()) {
173 callback->sendFailure(response);
176 callback->sendSuccess(std::move(wrappedValue),
177 Maybe<protocol::Runtime::ExceptionDetails>());
182 m_inspector->sessionById(m_contextGroupId, m_sessionId);
183 if (!session)
return;
185 Response response = scope.initialize();
186 if (!response.isSuccess())
return;
187 std::unique_ptr<EvaluateCallback> callback =
188 scope.injectedScript()->takeEvaluateCallback(m_callback);
189 if (!callback)
return;
190 std::unique_ptr<protocol::Runtime::RemoteObject> wrappedValue;
191 response = scope.injectedScript()->wrapObject(result, m_objectGroup,
192 m_wrapMode, &wrappedValue);
193 if (!response.isSuccess()) {
194 callback->sendFailure(response);
198 std::unique_ptr<V8StackTraceImpl> stack;
199 v8::Isolate* isolate = session->inspector()->isolate();
200 if (result->IsNativeError()) {
201 message =
" " + toProtocolString(
203 result->ToDetailString(isolate->GetCurrentContext())
207 if (!stackTrace.IsEmpty()) {
208 stack = m_inspector->debugger()->createStackTrace(stackTrace);
212 stack = m_inspector->debugger()->captureStackTrace(
true);
214 std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails =
215 protocol::Runtime::ExceptionDetails::create()
216 .setExceptionId(m_inspector->nextExceptionId())
217 .setText(
"Uncaught (in promise)" + message)
218 .setLineNumber(stack && !stack->isEmpty() ? stack->topLineNumber()
221 stack && !stack->isEmpty() ? stack->topColumnNumber() : 0)
222 .setException(wrappedValue->clone())
225 exceptionDetails->setStackTrace(
226 stack->buildInspectorObjectImpl(m_inspector->debugger()));
227 if (stack && !stack->isEmpty())
228 exceptionDetails->setScriptId(toString16(stack->topScriptId()));
229 callback->sendSuccess(std::move(wrappedValue), std::move(exceptionDetails));
232 void sendPromiseCollected() {
234 m_inspector->sessionById(m_contextGroupId, m_sessionId);
235 if (!session)
return;
237 Response response = scope.initialize();
238 if (!response.isSuccess())
return;
239 std::unique_ptr<EvaluateCallback> callback =
240 scope.injectedScript()->takeEvaluateCallback(m_callback);
241 if (!callback)
return;
242 callback->sendFailure(Response::Error(
"Promise was collected"));
247 int m_contextGroupId;
248 int m_executionContextId;
256 : m_context(context), m_sessionId(sessionId) {}
258 InjectedScript::~InjectedScript() { discardEvaluateCallbacks(); }
261 class PropertyAccumulator :
public ValueMirror::PropertyAccumulator {
263 explicit PropertyAccumulator(std::vector<PropertyMirror>* mirrors)
264 : m_mirrors(mirrors) {}
265 bool Add(PropertyMirror mirror)
override {
266 m_mirrors->push_back(std::move(mirror));
271 std::vector<PropertyMirror>* m_mirrors;
275 Response InjectedScript::getProperties(
277 bool accessorPropertiesOnly, WrapMode wrapMode,
278 std::unique_ptr<Array<PropertyDescriptor>>* properties,
279 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
282 v8::Isolate* isolate = m_context->isolate();
283 int sessionId = m_sessionId;
284 v8::TryCatch tryCatch(isolate);
286 *properties = Array<PropertyDescriptor>::create();
287 std::vector<PropertyMirror> mirrors;
288 PropertyAccumulator accumulator(&mirrors);
289 if (!ValueMirror::getProperties(context,
object, ownProperties,
290 accessorPropertiesOnly, &accumulator)) {
291 return createExceptionDetails(tryCatch, groupName, wrapMode,
294 for (
const PropertyMirror& mirror : mirrors) {
295 std::unique_ptr<PropertyDescriptor> descriptor =
296 PropertyDescriptor::create()
297 .setName(mirror.name)
298 .setConfigurable(mirror.configurable)
299 .setEnumerable(mirror.enumerable)
300 .setIsOwn(mirror.isOwn)
303 std::unique_ptr<RemoteObject> remoteObject;
306 mirror.value->buildRemoteObject(context, wrapMode, &remoteObject);
307 if (!response.isSuccess())
return response;
309 bindRemoteObjectIfNeeded(sessionId, context, mirror.value->v8Value(),
310 groupName, remoteObject.get());
311 if (!response.isSuccess())
return response;
312 descriptor->setValue(std::move(remoteObject));
313 descriptor->setWritable(mirror.writable);
317 mirror.getter->buildRemoteObject(context, wrapMode, &remoteObject);
318 if (!response.isSuccess())
return response;
320 bindRemoteObjectIfNeeded(sessionId, context, mirror.getter->v8Value(),
321 groupName, remoteObject.get());
322 if (!response.isSuccess())
return response;
323 descriptor->setGet(std::move(remoteObject));
327 mirror.setter->buildRemoteObject(context, wrapMode, &remoteObject);
328 if (!response.isSuccess())
return response;
330 bindRemoteObjectIfNeeded(sessionId, context, mirror.setter->v8Value(),
331 groupName, remoteObject.get());
332 if (!response.isSuccess())
return response;
333 descriptor->setSet(std::move(remoteObject));
337 mirror.symbol->buildRemoteObject(context, wrapMode, &remoteObject);
338 if (!response.isSuccess())
return response;
340 bindRemoteObjectIfNeeded(sessionId, context, mirror.symbol->v8Value(),
341 groupName, remoteObject.get());
342 if (!response.isSuccess())
return response;
343 descriptor->setSymbol(std::move(remoteObject));
345 if (mirror.exception) {
347 mirror.exception->buildRemoteObject(context, wrapMode, &remoteObject);
348 if (!response.isSuccess())
return response;
349 response = bindRemoteObjectIfNeeded(sessionId, context,
350 mirror.exception->v8Value(),
351 groupName, remoteObject.get());
352 if (!response.isSuccess())
return response;
353 descriptor->setValue(std::move(remoteObject));
354 descriptor->setWasThrown(
true);
356 (*properties)->addItem(std::move(descriptor));
358 return Response::OK();
361 Response InjectedScript::getInternalProperties(
363 std::unique_ptr<protocol::Array<InternalPropertyDescriptor>>* result) {
364 *result = protocol::Array<InternalPropertyDescriptor>::create();
366 int sessionId = m_sessionId;
367 std::vector<InternalPropertyMirror> wrappers;
368 if (value->IsObject()) {
369 ValueMirror::getInternalProperties(m_context->context(),
372 for (
size_t i = 0;
i < wrappers.size(); ++
i) {
373 std::unique_ptr<RemoteObject> remoteObject;
374 Response response = wrappers[
i].value->buildRemoteObject(
375 m_context->context(), WrapMode::kNoPreview, &remoteObject);
376 if (!response.isSuccess())
return response;
377 response = bindRemoteObjectIfNeeded(sessionId, context,
378 wrappers[
i].value->v8Value(), groupName,
380 if (!response.isSuccess())
return response;
381 (*result)->addItem(InternalPropertyDescriptor::create()
382 .setName(wrappers[
i].name)
383 .setValue(std::move(remoteObject))
386 return Response::OK();
389 void InjectedScript::releaseObject(
const String16& objectId) {
390 std::unique_ptr<protocol::Value> parsedObjectId =
391 protocol::StringUtil::parseJSON(objectId);
392 if (!parsedObjectId)
return;
393 protocol::DictionaryValue*
object =
394 protocol::DictionaryValue::cast(parsedObjectId.get());
397 if (!object->getInteger(
"id", &boundId))
return;
398 unbindObject(boundId);
401 Response InjectedScript::wrapObject(
403 std::unique_ptr<protocol::Runtime::RemoteObject>* result) {
405 kMaxCustomPreviewDepth, result);
408 Response InjectedScript::wrapObject(
411 std::unique_ptr<protocol::Runtime::RemoteObject>* result) {
414 int customPreviewEnabled = m_customPreviewEnabled;
415 int sessionId = m_sessionId;
416 auto obj = ValueMirror::create(m_context->context(), value);
417 if (!obj)
return Response::InternalError();
418 Response response = obj->buildRemoteObject(context, wrapMode, result);
419 if (!response.isSuccess())
return response;
420 response = bindRemoteObjectIfNeeded(sessionId, context, value, groupName,
422 if (!response.isSuccess())
return response;
423 if (customPreviewEnabled && value->IsObject()) {
424 std::unique_ptr<protocol::Runtime::CustomPreview> customPreview;
425 generateCustomPreview(sessionId, groupName, context, value.As<
v8::Object>(),
426 customPreviewConfig, maxCustomPreviewDepth,
428 if (customPreview) (*result)->setCustomPreview(std::move(customPreview));
430 return Response::OK();
433 std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable(
435 using protocol::Runtime::RemoteObject;
436 using protocol::Runtime::ObjectPreview;
437 using protocol::Runtime::PropertyPreview;
438 using protocol::Array;
440 v8::Isolate* isolate = m_context->isolate();
444 std::unique_ptr<RemoteObject> remoteObject;
446 wrapObject(table,
"console", WrapMode::kNoPreview, &remoteObject);
447 if (!remoteObject || !response.isSuccess())
return nullptr;
449 auto mirror = ValueMirror::create(context, table);
450 std::unique_ptr<ObjectPreview> preview;
452 mirror->buildObjectPreview(context,
true ,
453 &limit, &limit, &preview);
454 if (!preview)
return nullptr;
456 Array<PropertyPreview>* columns = preview->getProperties();
457 std::unordered_set<String16> selectedColumns;
459 if (maybeColumns.
ToLocal(&v8Columns)) {
460 for (
uint32_t i = 0;
i < v8Columns->Length(); ++
i) {
463 selectedColumns.insert(
468 if (!selectedColumns.empty()) {
469 for (
size_t i = 0;
i < columns->length(); ++
i) {
470 ObjectPreview* columnPreview = columns->get(
i)->getValuePreview(
nullptr);
471 if (!columnPreview)
continue;
473 std::unique_ptr<Array<PropertyPreview>> filtered =
474 Array<PropertyPreview>::create();
475 Array<PropertyPreview>* columns = columnPreview->getProperties();
476 for (
size_t j = 0; j < columns->length(); ++j) {
477 PropertyPreview*
property = columns->get(j);
478 if (selectedColumns.find(property->getName()) !=
479 selectedColumns.end()) {
480 filtered->addItem(property->clone());
483 columnPreview->setProperties(std::move(filtered));
486 remoteObject->setPreview(std::move(preview));
490 void InjectedScript::addPromiseCallback(
492 const String16& objectGroup, WrapMode wrapMode,
493 std::unique_ptr<EvaluateCallback> callback) {
494 if (value.IsEmpty()) {
495 callback->sendFailure(Response::InternalError());
498 v8::MicrotasksScope microtasksScope(m_context->isolate(),
499 v8::MicrotasksScope::kRunMicrotasks);
500 if (ProtocolPromiseHandler::add(
501 session, m_context->context(), value.ToLocalChecked(),
502 m_context->contextId(), objectGroup, wrapMode, callback.get())) {
503 m_evaluateCallbacks.insert(callback.release());
507 void InjectedScript::discardEvaluateCallbacks() {
508 for (
auto& callback : m_evaluateCallbacks) {
509 callback->sendFailure(Response::Error(
"Execution context was destroyed."));
512 m_evaluateCallbacks.clear();
515 std::unique_ptr<EvaluateCallback> InjectedScript::takeEvaluateCallback(
516 EvaluateCallback* callback) {
517 auto it = m_evaluateCallbacks.find(callback);
518 if (it == m_evaluateCallbacks.end())
return nullptr;
519 std::unique_ptr<EvaluateCallback> value(*it);
520 m_evaluateCallbacks.erase(it);
524 Response InjectedScript::findObject(
const RemoteObjectId& objectId,
526 auto it = m_idToWrappedObject.find(objectId.id());
527 if (it == m_idToWrappedObject.end())
528 return Response::Error(
"Could not find object with given id");
529 *outObject = it->second.Get(m_context->isolate());
530 return Response::OK();
533 String16 InjectedScript::objectGroupName(
const RemoteObjectId& objectId)
const {
534 if (objectId.id() <= 0)
return String16();
535 auto it = m_idToObjectGroupName.find(objectId.id());
536 return it != m_idToObjectGroupName.end() ? it->second : String16();
539 void InjectedScript::releaseObjectGroup(
const String16& objectGroup) {
540 if (objectGroup ==
"console") m_lastEvaluationResult.
Reset();
541 if (objectGroup.isEmpty())
return;
542 auto it = m_nameToObjectGroup.find(objectGroup);
543 if (it == m_nameToObjectGroup.end())
return;
544 for (
int id : it->second) unbindObject(
id);
545 m_nameToObjectGroup.erase(it);
548 void InjectedScript::setCustomObjectFormatterEnabled(
bool enabled) {
549 m_customPreviewEnabled = enabled;
553 if (m_lastEvaluationResult.IsEmpty())
554 return v8::Undefined(m_context->isolate());
555 return m_lastEvaluationResult.Get(m_context->isolate());
559 m_lastEvaluationResult.
Reset(m_context->isolate(), result);
563 Response InjectedScript::resolveCallArgument(
564 protocol::Runtime::CallArgument* callArgument,
566 if (callArgument->hasObjectId()) {
567 std::unique_ptr<RemoteObjectId> remoteObjectId;
569 RemoteObjectId::parse(callArgument->getObjectId(
""), &remoteObjectId);
570 if (!response.isSuccess())
return response;
571 if (remoteObjectId->contextId() != m_context->contextId())
572 return Response::Error(
573 "Argument should belong to the same JavaScript world as target " 575 return findObject(*remoteObjectId, result);
577 if (callArgument->hasValue() || callArgument->hasUnserializableValue()) {
579 if (callArgument->hasValue()) {
580 value =
"(" + callArgument->getValue(
nullptr)->serialize() +
")";
582 String16 unserializableValue = callArgument->getUnserializableValue(
"");
584 if (isResolvableNumberLike(unserializableValue))
585 value =
"Number(\"" + unserializableValue +
"\")";
587 value = unserializableValue;
589 if (!m_context->inspector()
590 ->compileAndRunInternalScript(
591 m_context->context(), toV8String(m_context->isolate(), value))
593 return Response::Error(
"Couldn't parse value object in call argument");
595 return Response::OK();
597 *result = v8::Undefined(m_context->isolate());
598 return Response::OK();
601 Response InjectedScript::createExceptionDetails(
602 const v8::TryCatch& tryCatch,
const String16& objectGroup,
603 WrapMode wrapMode, Maybe<protocol::Runtime::ExceptionDetails>* result) {
604 if (!tryCatch.HasCaught())
return Response::InternalError();
607 String16 messageText =
610 : toProtocolString(m_context->isolate(), message->Get());
611 std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails =
612 protocol::Runtime::ExceptionDetails::create()
613 .setExceptionId(m_context->inspector()->nextExceptionId())
614 .setText(exception.
IsEmpty() ? messageText : String16(
"Uncaught"))
618 : message->
GetLineNumber(m_context->context()).FromMaybe(1) -
626 exceptionDetails->setScriptId(String16::fromInteger(
630 exceptionDetails->setStackTrace(
631 m_context->inspector()
633 ->createStackTrace(stackTrace)
634 ->buildInspectorObjectImpl(m_context->inspector()->debugger()));
637 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped;
639 wrapObject(exception, objectGroup,
641 : WrapMode::kWithPreview,
643 if (!response.isSuccess())
return response;
644 exceptionDetails->setException(std::move(wrapped));
646 *result = std::move(exceptionDetails);
647 return Response::OK();
650 Response InjectedScript::wrapEvaluateResult(
652 const String16& objectGroup, WrapMode wrapMode,
653 std::unique_ptr<protocol::Runtime::RemoteObject>* result,
654 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
656 if (!tryCatch.HasCaught()) {
657 if (!maybeResultValue.
ToLocal(&resultValue))
658 return Response::InternalError();
659 Response response = wrapObject(resultValue, objectGroup, wrapMode, result);
660 if (!response.isSuccess())
return response;
661 if (objectGroup ==
"console") {
662 m_lastEvaluationResult.
Reset(m_context->isolate(), resultValue);
666 if (tryCatch.HasTerminated() || !tryCatch.CanContinue()) {
667 return Response::Error(
"Execution was terminated");
671 wrapObject(exception, objectGroup,
673 : WrapMode::kWithPreview,
675 if (!response.isSuccess())
return response;
678 response = createExceptionDetails(tryCatch, objectGroup, wrapMode,
680 if (!response.isSuccess())
return response;
682 return Response::OK();
686 if (m_commandLineAPI.IsEmpty()) {
687 m_commandLineAPI.
Reset(
688 m_context->isolate(),
689 m_context->inspector()->console()->createCommandLineAPI(
690 m_context->context(), m_sessionId));
693 return m_commandLineAPI.Get(m_context->isolate());
696 InjectedScript::Scope::Scope(V8InspectorSessionImpl* session)
697 : m_inspector(session->inspector()),
698 m_injectedScript(nullptr),
699 m_handleScope(m_inspector->isolate()),
700 m_tryCatch(m_inspector->isolate()),
701 m_ignoreExceptionsAndMuteConsole(false),
702 m_previousPauseOnExceptionsState(
v8::debug::NoBreakOnException),
703 m_userGesture(false),
705 m_contextGroupId(session->contextGroupId()),
706 m_sessionId(session->sessionId()) {}
708 Response InjectedScript::Scope::initialize() {
710 V8InspectorSessionImpl* session =
711 m_inspector->sessionById(m_contextGroupId, m_sessionId);
712 if (!session)
return Response::InternalError();
713 Response response = findInjectedScript(session);
714 if (!response.isSuccess())
return response;
715 m_context = m_injectedScript->context()->context();
717 if (m_allowEval) m_context->AllowCodeGenerationFromStrings(
true);
718 return Response::OK();
721 void InjectedScript::Scope::installCommandLineAPI() {
722 DCHECK(m_injectedScript && !m_context.IsEmpty() &&
723 !m_commandLineAPIScope.get());
724 m_commandLineAPIScope.reset(
new V8Console::CommandLineAPIScope(
725 m_context, m_injectedScript->commandLineAPI(), m_context->Global()));
728 void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() {
729 DCHECK(!m_ignoreExceptionsAndMuteConsole);
730 m_ignoreExceptionsAndMuteConsole =
true;
731 m_inspector->client()->muteMetrics(m_contextGroupId);
732 m_inspector->muteExceptions(m_contextGroupId);
733 m_previousPauseOnExceptionsState =
734 setPauseOnExceptionsState(v8::debug::NoBreakOnException);
737 v8::debug::ExceptionBreakState InjectedScript::Scope::setPauseOnExceptionsState(
738 v8::debug::ExceptionBreakState newState) {
739 if (!m_inspector->debugger()->enabled())
return newState;
740 v8::debug::ExceptionBreakState presentState =
741 m_inspector->debugger()->getPauseOnExceptionsState();
742 if (presentState != newState)
743 m_inspector->debugger()->setPauseOnExceptionsState(newState);
747 void InjectedScript::Scope::pretendUserGesture() {
748 DCHECK(!m_userGesture);
749 m_userGesture =
true;
750 m_inspector->client()->beginUserGesture();
753 void InjectedScript::Scope::allowCodeGenerationFromStrings() {
754 DCHECK(!m_allowEval);
755 if (m_context->IsCodeGenerationFromStringsAllowed())
return;
757 m_context->AllowCodeGenerationFromStrings(
true);
760 void InjectedScript::Scope::cleanup() {
761 m_commandLineAPIScope.reset();
762 if (!m_context.IsEmpty()) {
763 if (m_allowEval) m_context->AllowCodeGenerationFromStrings(
false);
769 InjectedScript::Scope::~Scope() {
770 if (m_ignoreExceptionsAndMuteConsole) {
771 setPauseOnExceptionsState(m_previousPauseOnExceptionsState);
772 m_inspector->client()->unmuteMetrics(m_contextGroupId);
773 m_inspector->unmuteExceptions(m_contextGroupId);
775 if (m_userGesture) m_inspector->client()->endUserGesture();
779 InjectedScript::ContextScope::ContextScope(V8InspectorSessionImpl* session,
780 int executionContextId)
781 : InjectedScript::Scope(session),
782 m_executionContextId(executionContextId) {}
784 InjectedScript::ContextScope::~ContextScope() =
default;
786 Response InjectedScript::ContextScope::findInjectedScript(
787 V8InspectorSessionImpl* session) {
788 return session->findInjectedScript(m_executionContextId, m_injectedScript);
791 InjectedScript::ObjectScope::ObjectScope(V8InspectorSessionImpl* session,
792 const String16& remoteObjectId)
793 : InjectedScript::Scope(session), m_remoteObjectId(remoteObjectId) {}
795 InjectedScript::ObjectScope::~ObjectScope() =
default;
797 Response InjectedScript::ObjectScope::findInjectedScript(
798 V8InspectorSessionImpl* session) {
799 std::unique_ptr<RemoteObjectId> remoteId;
800 Response response = RemoteObjectId::parse(m_remoteObjectId, &remoteId);
801 if (!response.isSuccess())
return response;
802 InjectedScript* injectedScript =
nullptr;
803 response = session->findInjectedScript(remoteId.get(), injectedScript);
804 if (!response.isSuccess())
return response;
805 m_objectGroupName = injectedScript->objectGroupName(*remoteId);
806 response = injectedScript->findObject(*remoteId, &m_object);
807 if (!response.isSuccess())
return response;
808 m_injectedScript = injectedScript;
809 return Response::OK();
812 InjectedScript::CallFrameScope::CallFrameScope(V8InspectorSessionImpl* session,
813 const String16& remoteObjectId)
814 : InjectedScript::Scope(session), m_remoteCallFrameId(remoteObjectId) {}
816 InjectedScript::CallFrameScope::~CallFrameScope() =
default;
818 Response InjectedScript::CallFrameScope::findInjectedScript(
819 V8InspectorSessionImpl* session) {
820 std::unique_ptr<RemoteCallFrameId> remoteId;
821 Response response = RemoteCallFrameId::parse(m_remoteCallFrameId, &remoteId);
822 if (!response.isSuccess())
return response;
823 m_frameOrdinal =
static_cast<size_t>(remoteId->frameOrdinal());
824 return session->findInjectedScript(remoteId.get(), m_injectedScript);
828 const String16& groupName) {
829 if (m_lastBoundObjectId <= 0) m_lastBoundObjectId = 1;
830 int id = m_lastBoundObjectId++;
831 m_idToWrappedObject[id].Reset(m_context->isolate(), value);
832 m_idToWrappedObject[id].AnnotateStrongRetainer(kGlobalHandleLabel);
833 if (!groupName.isEmpty() &&
id > 0) {
834 m_idToObjectGroupName[id] = groupName;
835 m_nameToObjectGroup[groupName].push_back(
id);
838 return String16::concat(
839 "{\"injectedScriptId\":", String16::fromInteger(m_context->contextId()),
840 ",\"id\":", String16::fromInteger(
id),
"}");
844 Response InjectedScript::bindRemoteObjectIfNeeded(
846 const String16& groupName, protocol::Runtime::RemoteObject* remoteObject) {
847 if (!remoteObject)
return Response::OK();
848 if (remoteObject->hasValue())
return Response::OK();
849 if (remoteObject->hasUnserializableValue())
return Response::OK();
850 if (remoteObject->getType() != RemoteObject::TypeEnum::Undefined) {
851 v8::Isolate* isolate = context->GetIsolate();
852 V8InspectorImpl* inspector =
853 static_cast<V8InspectorImpl*
>(v8::debug::GetInspector(isolate));
854 InspectedContext* inspectedContext =
855 inspector->getContext(InspectedContext::contextId(context));
856 InjectedScript* injectedScript =
857 inspectedContext ? inspectedContext->getInjectedScript(sessionId)
859 if (!injectedScript) {
860 return Response::Error(
"Cannot find context with specified id");
862 remoteObject->setObjectId(injectedScript->bindObject(value, groupName));
864 return Response::OK();
867 void InjectedScript::unbindObject(
int id) {
868 m_idToWrappedObject.erase(
id);
869 m_idToObjectGroupName.erase(
id);
static V8_WARN_UNUSED_RESULT MaybeLocal< Resolver > New(Local< Context > context)
V8_WARN_UNUSED_RESULT Maybe< bool > Resolve(Local< Context > context, Local< Value > value)
bool IsNativeError() const
V8_WARN_UNUSED_RESULT Maybe< int > GetLineNumber(Local< Context > context) const
V8_INLINE bool IsString() const
V8_INLINE int Length() const
static V8_INLINE Local< T > Cast(Local< S > that)
Local< StackTrace > GetStackTrace() const
V8_WARN_UNUSED_RESULT MaybeLocal< Promise > Catch(Local< Context > context, Local< Function > handler)
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_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local< S > *out) const
int GetFrameCount() const
int GetStartColumn() const
V8_INLINE Local< Value > Data() const
Local< Promise > GetPromise()
ScriptOrigin GetScriptOrigin() const
V8_INLINE void SetWeak(P *parameter, typename WeakCallbackInfo< P >::Callback callback, WeakCallbackType type)
V8_INLINE void AnnotateStrongRetainer(const char *label)
V8_INLINE Isolate * GetIsolate() const