• 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::HandleScope handleScope(info.context->GetIsolate());
68   v8::Local<v8::Object> global = info.context->Global();
69   v8::Local<v8::Value> console;
70   if (global->Get(info.context, toV8String(m_inspector->isolate(), "console"))
71           .ToLocal(&console) &&
72       console->IsObject()) {
73     m_inspector->console()->installMemoryGetter(
74         info.context, v8::Local<v8::Object>::Cast(console));
75   }
76 }
77 
~InspectedContext()78 InspectedContext::~InspectedContext() {
79   // If we destory InspectedContext before weak callback is invoked then we need
80   // to delete data here.
81   if (!m_context.IsEmpty()) delete m_weakCallbackData;
82 }
83 
84 // static
contextId(v8::Local<v8::Context> context)85 int InspectedContext::contextId(v8::Local<v8::Context> context) {
86   return v8::debug::GetContextId(context);
87 }
88 
context() const89 v8::Local<v8::Context> InspectedContext::context() const {
90   return m_context.Get(isolate());
91 }
92 
isolate() const93 v8::Isolate* InspectedContext::isolate() const {
94   return m_inspector->isolate();
95 }
96 
isReported(int sessionId) const97 bool InspectedContext::isReported(int sessionId) const {
98   return m_reportedSessionIds.find(sessionId) != m_reportedSessionIds.cend();
99 }
100 
setReported(int sessionId,bool reported)101 void InspectedContext::setReported(int sessionId, bool reported) {
102   if (reported)
103     m_reportedSessionIds.insert(sessionId);
104   else
105     m_reportedSessionIds.erase(sessionId);
106 }
107 
getInjectedScript(int sessionId)108 InjectedScript* InspectedContext::getInjectedScript(int sessionId) {
109   auto it = m_injectedScripts.find(sessionId);
110   return it == m_injectedScripts.end() ? nullptr : it->second.get();
111 }
112 
createInjectedScript(int sessionId)113 InjectedScript* InspectedContext::createInjectedScript(int sessionId) {
114   std::unique_ptr<InjectedScript> injectedScript =
115       std::make_unique<InjectedScript>(this, sessionId);
116   CHECK(m_injectedScripts.find(sessionId) == m_injectedScripts.end());
117   m_injectedScripts[sessionId] = std::move(injectedScript);
118   return getInjectedScript(sessionId);
119 }
120 
discardInjectedScript(int sessionId)121 void InspectedContext::discardInjectedScript(int sessionId) {
122   m_injectedScripts.erase(sessionId);
123 }
124 
addInternalObject(v8::Local<v8::Object> object,V8InternalValueType type)125 bool InspectedContext::addInternalObject(v8::Local<v8::Object> object,
126                                          V8InternalValueType type) {
127   if (m_internalObjects.IsEmpty()) {
128     m_internalObjects.Reset(isolate(), v8::debug::WeakMap::New(isolate()));
129   }
130   return !m_internalObjects.Get(isolate())
131               ->Set(m_context.Get(isolate()), object,
132                     v8::Integer::New(isolate(), static_cast<int>(type)))
133               .IsEmpty();
134 }
135 
getInternalType(v8::Local<v8::Object> object)136 V8InternalValueType InspectedContext::getInternalType(
137     v8::Local<v8::Object> object) {
138   if (m_internalObjects.IsEmpty()) return V8InternalValueType::kNone;
139   v8::Local<v8::Value> typeValue;
140   if (!m_internalObjects.Get(isolate())
141            ->Get(m_context.Get(isolate()), object)
142            .ToLocal(&typeValue) ||
143       !typeValue->IsUint32()) {
144     return V8InternalValueType::kNone;
145   }
146   return static_cast<V8InternalValueType>(typeValue.As<v8::Int32>()->Value());
147 }
148 
149 }  // namespace v8_inspector
150