• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/inspector/inspected-context.h"
6 
7 #include "src/debug/debug-interface.h"
8 #include "src/inspector/injected-script.h"
9 #include "src/inspector/string-util.h"
10 #include "src/inspector/v8-console.h"
11 #include "src/inspector/v8-inspector-impl.h"
12 
13 #include "include/v8-inspector.h"
14 
15 namespace v8_inspector {
16 
17 class InspectedContext::WeakCallbackData {
18  public:
WeakCallbackData(InspectedContext * context,V8InspectorImpl * inspector,int groupId,int contextId)19   WeakCallbackData(InspectedContext* context, V8InspectorImpl* inspector,
20                    int groupId, int contextId)
21       : m_context(context),
22         m_inspector(inspector),
23         m_groupId(groupId),
24         m_contextId(contextId) {}
25 
resetContext(const v8::WeakCallbackInfo<WeakCallbackData> & data)26   static void resetContext(const v8::WeakCallbackInfo<WeakCallbackData>& data) {
27     // InspectedContext is alive here because weak handler is still alive.
28     data.GetParameter()->m_context->m_weakCallbackData = nullptr;
29     data.GetParameter()->m_context->m_context.Reset();
30     data.SetSecondPassCallback(&callContextCollected);
31   }
32 
callContextCollected(const v8::WeakCallbackInfo<WeakCallbackData> & data)33   static void callContextCollected(
34       const v8::WeakCallbackInfo<WeakCallbackData>& data) {
35     // InspectedContext can be dead here since anything can happen between first
36     // and second pass callback.
37     WeakCallbackData* callbackData = data.GetParameter();
38     callbackData->m_inspector->contextCollected(callbackData->m_groupId,
39                                                 callbackData->m_contextId);
40     delete callbackData;
41   }
42 
43  private:
44   InspectedContext* m_context;
45   V8InspectorImpl* m_inspector;
46   int m_groupId;
47   int m_contextId;
48 };
49 
InspectedContext(V8InspectorImpl * inspector,const V8ContextInfo & info,int contextId)50 InspectedContext::InspectedContext(V8InspectorImpl* inspector,
51                                    const V8ContextInfo& info, int contextId)
52     : m_inspector(inspector),
53       m_context(info.context->GetIsolate(), info.context),
54       m_contextId(contextId),
55       m_contextGroupId(info.contextGroupId),
56       m_origin(toString16(info.origin)),
57       m_humanReadableName(toString16(info.humanReadableName)),
58       m_auxData(toString16(info.auxData)) {
59   v8::debug::SetContextId(info.context, contextId);
60   m_weakCallbackData =
61       new WeakCallbackData(this, m_inspector, m_contextGroupId, m_contextId);
62   m_context.SetWeak(m_weakCallbackData,
63                     &InspectedContext::WeakCallbackData::resetContext,
64                     v8::WeakCallbackType::kParameter);
65   if (!info.hasMemoryOnConsole) return;
66   v8::Context::Scope contextScope(info.context);
67   v8::Local<v8::Object> global = info.context->Global();
68   v8::Local<v8::Value> console;
69   if (global->Get(info.context, toV8String(m_inspector->isolate(), "console"))
70           .ToLocal(&console) &&
71       console->IsObject()) {
72     m_inspector->console()->installMemoryGetter(
73         info.context, v8::Local<v8::Object>::Cast(console));
74   }
75 }
76 
~InspectedContext()77 InspectedContext::~InspectedContext() {
78   // If we destory InspectedContext before weak callback is invoked then we need
79   // to delete data here.
80   if (!m_context.IsEmpty()) delete m_weakCallbackData;
81 }
82 
83 // static
contextId(v8::Local<v8::Context> context)84 int InspectedContext::contextId(v8::Local<v8::Context> context) {
85   return v8::debug::GetContextId(context);
86 }
87 
context() const88 v8::Local<v8::Context> InspectedContext::context() const {
89   return m_context.Get(isolate());
90 }
91 
isolate() const92 v8::Isolate* InspectedContext::isolate() const {
93   return m_inspector->isolate();
94 }
95 
isReported(int sessionId) const96 bool InspectedContext::isReported(int sessionId) const {
97   return m_reportedSessionIds.find(sessionId) != m_reportedSessionIds.cend();
98 }
99 
setReported(int sessionId,bool reported)100 void InspectedContext::setReported(int sessionId, bool reported) {
101   if (reported)
102     m_reportedSessionIds.insert(sessionId);
103   else
104     m_reportedSessionIds.erase(sessionId);
105 }
106 
getInjectedScript(int sessionId)107 InjectedScript* InspectedContext::getInjectedScript(int sessionId) {
108   auto it = m_injectedScripts.find(sessionId);
109   return it == m_injectedScripts.end() ? nullptr : it->second.get();
110 }
111 
createInjectedScript(int sessionId)112 bool InspectedContext::createInjectedScript(int sessionId) {
113   std::unique_ptr<InjectedScript> injectedScript =
114       InjectedScript::create(this, sessionId);
115   // InjectedScript::create can destroy |this|.
116   if (!injectedScript) return false;
117   CHECK(m_injectedScripts.find(sessionId) == m_injectedScripts.end());
118   m_injectedScripts[sessionId] = std::move(injectedScript);
119   return true;
120 }
121 
discardInjectedScript(int sessionId)122 void InspectedContext::discardInjectedScript(int sessionId) {
123   m_injectedScripts.erase(sessionId);
124 }
125 
126 }  // namespace v8_inspector
127