Commit 3655dc52 authored by dgozman's avatar dgozman Committed by Commit Bot

[inspector] Prepare some methods in V8InspectorImpl to multiple sessions

- introduced session id, which fixes an issue of reconnect while evaluating;
- forEachContext provides a safe way to iterate over contexts in a group.

BUG=chromium:590878

Review-Url: https://codereview.chromium.org/2905543004
Cr-Commit-Position: refs/heads/master@{#45613}
parent d41fe9f5
......@@ -415,22 +415,20 @@ v8::Local<v8::Object> InjectedScript::commandLineAPI() {
return m_commandLineAPI.Get(m_context->isolate());
}
InjectedScript::Scope::Scope(V8InspectorImpl* inspector, int contextGroupId)
: m_inspector(inspector),
m_contextGroupId(contextGroupId),
InjectedScript::Scope::Scope(V8InspectorSessionImpl* session)
: m_inspector(session->inspector()),
m_injectedScript(nullptr),
m_handleScope(inspector->isolate()),
m_tryCatch(inspector->isolate()),
m_handleScope(m_inspector->isolate()),
m_tryCatch(m_inspector->isolate()),
m_ignoreExceptionsAndMuteConsole(false),
m_previousPauseOnExceptionsState(v8::debug::NoBreakOnException),
m_userGesture(false) {}
m_userGesture(false),
m_contextGroupId(session->contextGroupId()),
m_sessionId(session->sessionId()) {}
Response InjectedScript::Scope::initialize() {
cleanup();
// TODO(dgozman): what if we reattach to the same context group during
// evaluate? Introduce a session id?
V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(m_contextGroupId);
V8InspectorSessionImpl* session = m_inspector->sessionById(m_sessionId);
if (!session) return Response::InternalError();
Response response = findInjectedScript(session);
if (!response.isSuccess()) return response;
......@@ -489,10 +487,9 @@ InjectedScript::Scope::~Scope() {
cleanup();
}
InjectedScript::ContextScope::ContextScope(V8InspectorImpl* inspector,
int contextGroupId,
InjectedScript::ContextScope::ContextScope(V8InspectorSessionImpl* session,
int executionContextId)
: InjectedScript::Scope(inspector, contextGroupId),
: InjectedScript::Scope(session),
m_executionContextId(executionContextId) {}
InjectedScript::ContextScope::~ContextScope() {}
......@@ -502,11 +499,9 @@ Response InjectedScript::ContextScope::findInjectedScript(
return session->findInjectedScript(m_executionContextId, m_injectedScript);
}
InjectedScript::ObjectScope::ObjectScope(V8InspectorImpl* inspector,
int contextGroupId,
InjectedScript::ObjectScope::ObjectScope(V8InspectorSessionImpl* session,
const String16& remoteObjectId)
: InjectedScript::Scope(inspector, contextGroupId),
m_remoteObjectId(remoteObjectId) {}
: InjectedScript::Scope(session), m_remoteObjectId(remoteObjectId) {}
InjectedScript::ObjectScope::~ObjectScope() {}
......@@ -525,11 +520,9 @@ Response InjectedScript::ObjectScope::findInjectedScript(
return Response::OK();
}
InjectedScript::CallFrameScope::CallFrameScope(V8InspectorImpl* inspector,
int contextGroupId,
InjectedScript::CallFrameScope::CallFrameScope(V8InspectorSessionImpl* session,
const String16& remoteObjectId)
: InjectedScript::Scope(inspector, contextGroupId),
m_remoteCallFrameId(remoteObjectId) {}
: InjectedScript::Scope(session), m_remoteCallFrameId(remoteObjectId) {}
InjectedScript::CallFrameScope::~CallFrameScope() {}
......
......@@ -110,12 +110,11 @@ class InjectedScript final {
const v8::TryCatch& tryCatch() const { return m_tryCatch; }
protected:
Scope(V8InspectorImpl*, int contextGroupId);
explicit Scope(V8InspectorSessionImpl*);
virtual ~Scope();
virtual Response findInjectedScript(V8InspectorSessionImpl*) = 0;
V8InspectorImpl* m_inspector;
int m_contextGroupId;
InjectedScript* m_injectedScript;
private:
......@@ -130,11 +129,13 @@ class InjectedScript final {
bool m_ignoreExceptionsAndMuteConsole;
v8::debug::ExceptionBreakState m_previousPauseOnExceptionsState;
bool m_userGesture;
int m_contextGroupId;
int m_sessionId;
};
class ContextScope : public Scope {
public:
ContextScope(V8InspectorImpl*, int contextGroupId, int executionContextId);
ContextScope(V8InspectorSessionImpl*, int executionContextId);
~ContextScope();
private:
......@@ -146,8 +147,7 @@ class InjectedScript final {
class ObjectScope : public Scope {
public:
ObjectScope(V8InspectorImpl*, int contextGroupId,
const String16& remoteObjectId);
ObjectScope(V8InspectorSessionImpl*, const String16& remoteObjectId);
~ObjectScope();
const String16& objectGroupName() const { return m_objectGroupName; }
v8::Local<v8::Value> object() const { return m_object; }
......@@ -163,8 +163,7 @@ class InjectedScript final {
class CallFrameScope : public Scope {
public:
CallFrameScope(V8InspectorImpl*, int contextGroupId,
const String16& remoteCallFrameId);
CallFrameScope(V8InspectorSessionImpl*, const String16& remoteCallFrameId);
~CallFrameScope();
size_t frameOrdinal() const { return m_frameOrdinal; }
......
......@@ -629,8 +629,7 @@ Response V8DebuggerAgentImpl::restartFrame(
std::unique_ptr<Array<CallFrame>>* newCallFrames,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace) {
if (!isPaused()) return Response::Error(kDebuggerNotPaused);
InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
callFrameId);
InjectedScript::CallFrameScope scope(m_session, callFrameId);
Response response = scope.initialize();
if (!response.isSuccess()) return response;
if (scope.frameOrdinal() >= m_pausedCallFrames.size())
......@@ -777,8 +776,7 @@ Response V8DebuggerAgentImpl::evaluateOnCallFrame(
Maybe<bool> throwOnSideEffect, std::unique_ptr<RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
if (!isPaused()) return Response::Error(kDebuggerNotPaused);
InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
callFrameId);
InjectedScript::CallFrameScope scope(m_session, callFrameId);
Response response = scope.initialize();
if (!response.isSuccess()) return response;
if (scope.frameOrdinal() >= m_pausedCallFrames.size())
......@@ -808,8 +806,7 @@ Response V8DebuggerAgentImpl::setVariableValue(
const String16& callFrameId) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled);
if (!isPaused()) return Response::Error(kDebuggerNotPaused);
InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
callFrameId);
InjectedScript::CallFrameScope scope(m_session, callFrameId);
Response response = scope.initialize();
if (!response.isSuccess()) return response;
v8::Local<v8::Value> newValue;
......
......@@ -11,7 +11,9 @@
#include "src/inspector/string-util.h"
#include "src/inspector/v8-debugger-agent-impl.h"
#include "src/inspector/v8-inspector-impl.h"
#include "src/inspector/v8-inspector-session-impl.h"
#include "src/inspector/v8-internal-value-type.h"
#include "src/inspector/v8-runtime-agent-impl.h"
#include "src/inspector/v8-stack-trace-impl.h"
#include "src/inspector/v8-value-copier.h"
......@@ -27,15 +29,6 @@ inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
return value ? v8::True(isolate) : v8::False(isolate);
}
V8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector,
v8::Local<v8::debug::Script> script) {
int contextId;
if (!script->ContextId().To(&contextId)) return nullptr;
int contextGroupId = inspector->contextGroupId(contextId);
if (!contextGroupId) return nullptr;
return inspector->enabledDebuggerAgentForGroup(contextGroupId);
}
v8::MaybeLocal<v8::Array> collectionsEntries(v8::Local<v8::Context> context,
v8::Local<v8::Value> value) {
v8::Isolate* isolate = context->GetIsolate();
......@@ -361,7 +354,9 @@ bool V8Debugger::breakProgram(int targetContextGroupId) {
DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId;
v8::debug::BreakRightNow(m_isolate);
return m_inspector->enabledDebuggerAgentForGroup(targetContextGroupId);
V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(targetContextGroupId);
return session && session->debuggerAgent()->enabled();
}
void V8Debugger::continueProgram(int targetContextGroupId) {
......@@ -605,9 +600,10 @@ void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext,
m_stepIntoAsyncCallback.reset();
}
m_breakRequested = false;
V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(
m_inspector->contextGroupId(pausedContext));
if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return;
V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(contextGroupId);
if (!session || !session->debuggerAgent()->enabled()) return;
if (!m_scheduledOOMBreak && session->debuggerAgent()->skipAllPauses()) return;
std::vector<String16> breakpointIds;
if (!hitBreakpointNumbers.IsEmpty()) {
......@@ -627,25 +623,25 @@ void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext,
}
clearContinueToLocation();
DCHECK(contextGroupId);
m_pausedContext = pausedContext;
m_executionState = executionState;
m_pausedContextGroupId = contextGroupId;
agent->didPause(InspectedContext::contextId(pausedContext), exception,
breakpointIds, isPromiseRejection, isUncaught,
m_scheduledOOMBreak);
int groupId = m_inspector->contextGroupId(pausedContext);
DCHECK(groupId);
session->debuggerAgent()->didPause(
InspectedContext::contextId(pausedContext), exception, breakpointIds,
isPromiseRejection, isUncaught, m_scheduledOOMBreak);
{
v8::Context::Scope scope(pausedContext);
v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
CHECK(!context.IsEmpty() &&
context != v8::debug::GetDebugContext(m_isolate));
m_inspector->client()->runMessageLoopOnPause(groupId);
m_inspector->client()->runMessageLoopOnPause(contextGroupId);
m_pausedContextGroupId = 0;
}
// The agent may have been removed in the nested loop.
agent = m_inspector->enabledDebuggerAgentForGroup(groupId);
if (agent) agent->didContinue();
session = m_inspector->sessionForContextGroup(contextGroupId);
if (session && session->debuggerAgent()->enabled())
session->debuggerAgent()->didContinue();
if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit();
m_scheduledOOMBreak = false;
m_pausedContext.Clear();
......@@ -664,12 +660,16 @@ void V8Debugger::v8OOMCallback(void* data) {
void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
bool has_compile_error) {
V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
if (!agent) return;
int contextId;
if (!script->ContextId().To(&contextId)) return;
V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup(
m_inspector->contextGroupId(contextId));
if (!session || !session->debuggerAgent()->enabled()) return;
if (script->IsWasm()) {
m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent);
m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(),
session->debuggerAgent());
} else if (m_ignoreScriptParsedEventsCounter == 0) {
agent->didParseSource(
session->debuggerAgent()->didParseSource(
V8DebuggerScript::Create(m_isolate, script, inLiveEditScope),
!has_compile_error);
}
......@@ -702,10 +702,13 @@ void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext,
bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
const v8::debug::Location& start,
const v8::debug::Location& end) {
V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
if (!agent) return false;
return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start,
end);
int contextId;
if (!script->ContextId().To(&contextId)) return false;
V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup(
m_inspector->contextGroupId(contextId));
if (!session || !session->debuggerAgent()->enabled()) return false;
return session->debuggerAgent()->isFunctionBlackboxed(
String16::fromInteger(script->Id()), start, end);
}
void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type,
......@@ -1081,7 +1084,9 @@ std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
if (!contextGroupId) return nullptr;
int stackSize = 1;
if (fullStack || m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) {
V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(contextGroupId);
if (fullStack || (session && session->runtimeAgent()->enabled())) {
stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
}
return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
......
......@@ -30,6 +30,8 @@
#include "src/inspector/v8-inspector-impl.h"
#include <vector>
#include "src/inspector/inspected-context.h"
#include "src/inspector/string-util.h"
#include "src/inspector/v8-console-agent-impl.h"
......@@ -74,27 +76,6 @@ int V8InspectorImpl::contextGroupId(int contextId) {
return it != m_contextIdToGroupIdMap.end() ? it->second : 0;
}
V8DebuggerAgentImpl* V8InspectorImpl::enabledDebuggerAgentForGroup(
int contextGroupId) {
V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId);
V8DebuggerAgentImpl* agent = session ? session->debuggerAgent() : nullptr;
return agent && agent->enabled() ? agent : nullptr;
}
V8RuntimeAgentImpl* V8InspectorImpl::enabledRuntimeAgentForGroup(
int contextGroupId) {
V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId);
V8RuntimeAgentImpl* agent = session ? session->runtimeAgent() : nullptr;
return agent && agent->enabled() ? agent : nullptr;
}
V8ProfilerAgentImpl* V8InspectorImpl::enabledProfilerAgentForGroup(
int contextGroupId) {
V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId);
V8ProfilerAgentImpl* agent = session ? session->profilerAgent() : nullptr;
return agent && agent->enabled() ? agent : nullptr;
}
v8::MaybeLocal<v8::Value> V8InspectorImpl::compileAndRunInternalScript(
v8::Local<v8::Context> context, v8::Local<v8::String> source) {
v8::Local<v8::UnboundScript> unboundScript;
......@@ -171,15 +152,19 @@ std::unique_ptr<V8InspectorSession> V8InspectorImpl::connect(
int contextGroupId, V8Inspector::Channel* channel,
const StringView& state) {
DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend());
int sessionId = ++m_lastSessionId;
std::unique_ptr<V8InspectorSessionImpl> session =
V8InspectorSessionImpl::create(this, contextGroupId, channel, state);
V8InspectorSessionImpl::create(this, contextGroupId, sessionId, channel,
state);
m_sessions[contextGroupId] = session.get();
m_sessionById[sessionId] = session.get();
return std::move(session);
}
void V8InspectorImpl::disconnect(V8InspectorSessionImpl* session) {
DCHECK(m_sessions.find(session->contextGroupId()) != m_sessions.end());
m_sessions.erase(session->contextGroupId());
m_sessionById.erase(session->sessionId());
}
InspectedContext* V8InspectorImpl::getContext(int groupId,
......@@ -327,12 +312,6 @@ void V8InspectorImpl::discardInspectedContext(int contextGroupId,
if (m_contexts[contextGroupId]->empty()) m_contexts.erase(contextGroupId);
}
const V8InspectorImpl::ContextByIdMap* V8InspectorImpl::contextGroup(
int contextGroupId) {
ContextsByGroupMap::iterator iter = m_contexts.find(contextGroupId);
return iter == m_contexts.end() ? nullptr : iter->second.get();
}
V8InspectorSessionImpl* V8InspectorImpl::sessionForContextGroup(
int contextGroupId) {
if (!contextGroupId) return nullptr;
......@@ -340,9 +319,31 @@ V8InspectorSessionImpl* V8InspectorImpl::sessionForContextGroup(
return iter == m_sessions.end() ? nullptr : iter->second;
}
V8InspectorSessionImpl* V8InspectorImpl::sessionById(int sessionId) {
auto it = m_sessionById.find(sessionId);
return it == m_sessionById.end() ? nullptr : it->second;
}
V8Console* V8InspectorImpl::console() {
if (!m_console) m_console.reset(new V8Console(this));
return m_console.get();
}
void V8InspectorImpl::forEachContext(
int contextGroupId, std::function<void(InspectedContext*)> callback) {
auto it = m_contexts.find(contextGroupId);
if (it == m_contexts.end()) return;
std::vector<int> ids;
ids.reserve(it->second->size());
for (auto& contextIt : *(it->second)) ids.push_back(contextIt.first);
// Retrieve by ids each time since |callback| may destroy some contexts.
for (auto& contextId : ids) {
it = m_contexts.find(contextGroupId);
if (it == m_contexts.end()) continue;
auto contextIt = it->second->find(contextId);
if (contextIt != it->second->end()) callback(contextIt->second.get());
}
}
} // namespace v8_inspector
......@@ -31,7 +31,7 @@
#ifndef V8_INSPECTOR_V8INSPECTORIMPL_H_
#define V8_INSPECTOR_V8INSPECTORIMPL_H_
#include <vector>
#include <functional>
#include "src/base/macros.h"
#include "src/inspector/protocol/Protocol.h"
......@@ -102,17 +102,14 @@ class V8InspectorImpl : public V8Inspector {
void unmuteExceptions(int contextGroupId);
V8ConsoleMessageStorage* ensureConsoleMessageStorage(int contextGroupId);
bool hasConsoleMessageStorage(int contextGroupId);
using ContextByIdMap =
protocol::HashMap<int, std::unique_ptr<InspectedContext>>;
void discardInspectedContext(int contextGroupId, int contextId);
const ContextByIdMap* contextGroup(int contextGroupId);
void disconnect(V8InspectorSessionImpl*);
V8InspectorSessionImpl* sessionForContextGroup(int contextGroupId);
V8InspectorSessionImpl* sessionById(int sessionId);
InspectedContext* getContext(int groupId, int contextId) const;
V8DebuggerAgentImpl* enabledDebuggerAgentForGroup(int contextGroupId);
V8RuntimeAgentImpl* enabledRuntimeAgentForGroup(int contextGroupId);
V8ProfilerAgentImpl* enabledProfilerAgentForGroup(int contextGroupId);
V8Console* console();
void forEachContext(int contextGroupId,
std::function<void(InspectedContext*)> callback);
private:
v8::Isolate* m_isolate;
......@@ -122,16 +119,20 @@ class V8InspectorImpl : public V8Inspector {
int m_capturingStackTracesCount;
unsigned m_lastExceptionId;
int m_lastContextId;
int m_lastSessionId = 0;
using MuteExceptionsMap = protocol::HashMap<int, int>;
MuteExceptionsMap m_muteExceptionsMap;
using ContextByIdMap =
protocol::HashMap<int, std::unique_ptr<InspectedContext>>;
using ContextsByGroupMap =
protocol::HashMap<int, std::unique_ptr<ContextByIdMap>>;
ContextsByGroupMap m_contexts;
using SessionMap = protocol::HashMap<int, V8InspectorSessionImpl*>;
SessionMap m_sessions;
protocol::HashMap<int, V8InspectorSessionImpl*> m_sessionById;
using ConsoleStorageMap =
protocol::HashMap<int, std::unique_ptr<V8ConsoleMessageStorage>>;
......
......@@ -43,17 +43,19 @@ int V8ContextInfo::executionContextId(v8::Local<v8::Context> context) {
}
std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(
V8InspectorImpl* inspector, int contextGroupId,
V8InspectorImpl* inspector, int contextGroupId, int sessionId,
V8Inspector::Channel* channel, const StringView& state) {
return std::unique_ptr<V8InspectorSessionImpl>(
new V8InspectorSessionImpl(inspector, contextGroupId, channel, state));
return std::unique_ptr<V8InspectorSessionImpl>(new V8InspectorSessionImpl(
inspector, contextGroupId, sessionId, channel, state));
}
V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector,
int contextGroupId,
int sessionId,
V8Inspector::Channel* channel,
const StringView& savedState)
: m_contextGroupId(contextGroupId),
m_sessionId(sessionId),
m_inspector(inspector),
m_channel(channel),
m_customObjectFormatterEnabled(false),
......@@ -181,39 +183,17 @@ void V8InspectorSessionImpl::reset() {
void V8InspectorSessionImpl::discardInjectedScripts() {
m_inspectedObjects.clear();
const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_contextGroupId);
if (!contexts) return;
std::vector<int> keys;
keys.reserve(contexts->size());
for (auto& idContext : *contexts) keys.push_back(idContext.first);
for (auto& key : keys) {
contexts = m_inspector->contextGroup(m_contextGroupId);
if (!contexts) continue;
auto contextIt = contexts->find(key);
if (contextIt != contexts->end())
contextIt->second
->discardInjectedScript(); // This may destroy some contexts.
}
m_inspector->forEachContext(m_contextGroupId, [](InspectedContext* context) {
context->discardInjectedScript();
});
}
Response V8InspectorSessionImpl::findInjectedScript(
int contextId, InjectedScript*& injectedScript) {
injectedScript = nullptr;
if (!contextId)
return Response::Error("Cannot find context with specified id");
const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_contextGroupId);
if (!contexts)
return Response::Error("Cannot find context with specified id");
auto contextsIt = contexts->find(contextId);
if (contextsIt == contexts->end())
return Response::Error("Cannot find context with specified id");
const std::unique_ptr<InspectedContext>& context = contextsIt->second;
InspectedContext* context =
m_inspector->getContext(m_contextGroupId, contextId);
if (!context) return Response::Error("Cannot find context with specified id");
if (!context->getInjectedScript()) {
if (!context->createInjectedScript())
return Response::Error("Cannot access specified execution context");
......@@ -234,22 +214,11 @@ void V8InspectorSessionImpl::releaseObjectGroup(const StringView& objectGroup) {
}
void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) {
const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_contextGroupId);
if (!contexts) return;
std::vector<int> keys;
for (auto& idContext : *contexts) keys.push_back(idContext.first);
for (auto& key : keys) {
contexts = m_inspector->contextGroup(m_contextGroupId);
if (!contexts) continue;
auto contextsIt = contexts->find(key);
if (contextsIt == contexts->end()) continue;
InjectedScript* injectedScript = contextsIt->second->getInjectedScript();
if (injectedScript)
injectedScript->releaseObjectGroup(
objectGroup); // This may destroy some contexts.
}
m_inspector->forEachContext(
m_contextGroupId, [&objectGroup](InspectedContext* context) {
InjectedScript* injectedScript = context->getInjectedScript();
if (injectedScript) injectedScript->releaseObjectGroup(objectGroup);
});
}
bool V8InspectorSessionImpl::unwrapObject(
......@@ -319,22 +288,19 @@ V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context,
void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(bool enabled) {
m_customObjectFormatterEnabled = enabled;
const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_contextGroupId);
if (!contexts) return;
for (auto& idContext : *contexts) {
InjectedScript* injectedScript = idContext.second->getInjectedScript();
if (injectedScript)
injectedScript->setCustomObjectFormatterEnabled(enabled);
}
m_inspector->forEachContext(
m_contextGroupId, [&enabled](InspectedContext* context) {
InjectedScript* injectedScript = context->getInjectedScript();
if (injectedScript)
injectedScript->setCustomObjectFormatterEnabled(enabled);
});
}
void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_contextGroupId);
if (!contexts) return;
for (auto& idContext : *contexts)
agent->reportExecutionContextCreated(idContext.second.get());
m_inspector->forEachContext(m_contextGroupId,
[&agent](InspectedContext* context) {
agent->reportExecutionContextCreated(context);
});
}
void V8InspectorSessionImpl::dispatchProtocolMessage(
......
......@@ -32,8 +32,8 @@ class V8InspectorSessionImpl : public V8InspectorSession,
public protocol::FrontendChannel {
public:
static std::unique_ptr<V8InspectorSessionImpl> create(
V8InspectorImpl*, int contextGroupId, V8Inspector::Channel*,
const StringView& state);
V8InspectorImpl*, int contextGroupId, int sessionId,
V8Inspector::Channel*, const StringView& state);
~V8InspectorSessionImpl();
V8InspectorImpl* inspector() const { return m_inspector; }
......@@ -43,6 +43,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
V8ProfilerAgentImpl* profilerAgent() { return m_profilerAgent.get(); }
V8RuntimeAgentImpl* runtimeAgent() { return m_runtimeAgent.get(); }
int contextGroupId() const { return m_contextGroupId; }
int sessionId() const { return m_sessionId; }
Response findInjectedScript(int contextId, InjectedScript*&);
Response findInjectedScript(RemoteObjectIdBase*, InjectedScript*&);
......@@ -91,7 +92,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
static const unsigned kInspectedObjectBufferSize = 5;
private:
V8InspectorSessionImpl(V8InspectorImpl*, int contextGroupId,
V8InspectorSessionImpl(V8InspectorImpl*, int contextGroupId, int sessionId,
V8Inspector::Channel*, const StringView& state);
protocol::DictionaryValue* agentState(const String16& name);
......@@ -103,6 +104,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
void flushProtocolNotifications() override;
int m_contextGroupId;
int m_sessionId;
V8InspectorImpl* m_inspector;
V8Inspector::Channel* m_channel;
bool m_customObjectFormatterEnabled;
......
......@@ -61,12 +61,12 @@ namespace {
template <typename Callback>
class ProtocolPromiseHandler {
public:
static void add(V8InspectorImpl* inspector, v8::Local<v8::Context> context,
static void add(V8InspectorSessionImpl* session,
v8::Local<v8::Context> context,
v8::MaybeLocal<v8::Value> value,
const String16& notPromiseError, int contextGroupId,
int executionContextId, const String16& objectGroup,
bool returnByValue, bool generatePreview,
std::unique_ptr<Callback> callback) {
const String16& notPromiseError, int executionContextId,
const String16& objectGroup, bool returnByValue,
bool generatePreview, std::unique_ptr<Callback> callback) {
if (value.IsEmpty()) {
callback->sendFailure(Response::InternalError());
return;
......@@ -75,14 +75,15 @@ class ProtocolPromiseHandler {
callback->sendFailure(Response::Error(notPromiseError));
return;
}
V8InspectorImpl* inspector = session->inspector();
v8::MicrotasksScope microtasks_scope(inspector->isolate(),
v8::MicrotasksScope::kRunMicrotasks);
v8::Local<v8::Promise> promise =
v8::Local<v8::Promise>::Cast(value.ToLocalChecked());
Callback* rawCallback = callback.get();
ProtocolPromiseHandler<Callback>* handler = new ProtocolPromiseHandler(
inspector, contextGroupId, executionContextId, objectGroup,
returnByValue, generatePreview, std::move(callback));
session, executionContextId, objectGroup, returnByValue,
generatePreview, std::move(callback));
v8::Local<v8::Value> wrapper = handler->m_wrapper.Get(inspector->isolate());
v8::Local<v8::Function> thenCallbackFunction =
......@@ -154,19 +155,19 @@ class ProtocolPromiseHandler {
std::move(exceptionDetails));
}
ProtocolPromiseHandler(V8InspectorImpl* inspector, int contextGroupId,
ProtocolPromiseHandler(V8InspectorSessionImpl* session,
int executionContextId, const String16& objectGroup,
bool returnByValue, bool generatePreview,
std::unique_ptr<Callback> callback)
: m_inspector(inspector),
m_contextGroupId(contextGroupId),
: m_inspector(session->inspector()),
m_sessionId(session->sessionId()),
m_executionContextId(executionContextId),
m_objectGroup(objectGroup),
m_returnByValue(returnByValue),
m_generatePreview(generatePreview),
m_callback(std::move(callback)),
m_wrapper(inspector->isolate(),
v8::External::New(inspector->isolate(), this)) {
m_wrapper(m_inspector->isolate(),
v8::External::New(m_inspector->isolate(), this)) {
m_wrapper.SetWeak(this, cleanup, v8::WeakCallbackType::kParameter);
}
......@@ -184,8 +185,12 @@ class ProtocolPromiseHandler {
std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject(
v8::Local<v8::Value> value) {
InjectedScript::ContextScope scope(m_inspector, m_contextGroupId,
m_executionContextId);
V8InspectorSessionImpl* session = m_inspector->sessionById(m_sessionId);
if (!session) {
m_callback->sendFailure(Response::Error("No session"));
return nullptr;
}
InjectedScript::ContextScope scope(session, m_executionContextId);
Response response = scope.initialize();
if (!response.isSuccess()) {
m_callback->sendFailure(response);
......@@ -203,7 +208,7 @@ class ProtocolPromiseHandler {
}
V8InspectorImpl* m_inspector;
int m_contextGroupId;
int m_sessionId;
int m_executionContextId;
String16 m_objectGroup;
bool m_returnByValue;
......@@ -276,8 +281,7 @@ void V8RuntimeAgentImpl::evaluate(
return;
}
InjectedScript::ContextScope scope(m_inspector, m_session->contextGroupId(),
contextId);
InjectedScript::ContextScope scope(m_session, contextId);
response = scope.initialize();
if (!response.isSuccess()) {
callback->sendFailure(response);
......@@ -320,8 +324,8 @@ void V8RuntimeAgentImpl::evaluate(
return;
}
ProtocolPromiseHandler<EvaluateCallback>::add(
m_inspector, scope.context(), maybeResultValue,
"Result of the evaluation is not a promise", m_session->contextGroupId(),
m_session, scope.context(), maybeResultValue,
"Result of the evaluation is not a promise",
scope.injectedScript()->context()->contextId(), objectGroup.fromMaybe(""),
returnByValue.fromMaybe(false), generatePreview.fromMaybe(false),
std::move(callback));
......@@ -331,16 +335,15 @@ void V8RuntimeAgentImpl::awaitPromise(
const String16& promiseObjectId, Maybe<bool> returnByValue,
Maybe<bool> generatePreview,
std::unique_ptr<AwaitPromiseCallback> callback) {
InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
promiseObjectId);
InjectedScript::ObjectScope scope(m_session, promiseObjectId);
Response response = scope.initialize();
if (!response.isSuccess()) {
callback->sendFailure(response);
return;
}
ProtocolPromiseHandler<AwaitPromiseCallback>::add(
m_inspector, scope.context(), scope.object(),
"Could not find promise with given id", m_session->contextGroupId(),
m_session, scope.context(), scope.object(),
"Could not find promise with given id",
scope.injectedScript()->context()->contextId(), scope.objectGroupName(),
returnByValue.fromMaybe(false), generatePreview.fromMaybe(false),
std::move(callback));
......@@ -352,8 +355,7 @@ void V8RuntimeAgentImpl::callFunctionOn(
Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
Maybe<bool> userGesture, Maybe<bool> awaitPromise,
std::unique_ptr<CallFunctionOnCallback> callback) {
InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
objectId);
InjectedScript::ObjectScope scope(m_session, objectId);
Response response = scope.initialize();
if (!response.isSuccess()) {
callback->sendFailure(response);
......@@ -438,9 +440,8 @@ void V8RuntimeAgentImpl::callFunctionOn(
}
ProtocolPromiseHandler<CallFunctionOnCallback>::add(
m_inspector, scope.context(), maybeResultValue,
m_session, scope.context(), maybeResultValue,
"Result of the function call is not a promise",
m_session->contextGroupId(),
scope.injectedScript()->context()->contextId(), scope.objectGroupName(),
returnByValue.fromMaybe(false), generatePreview.fromMaybe(false),
std::move(callback));
......@@ -456,8 +457,7 @@ Response V8RuntimeAgentImpl::getProperties(
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
using protocol::Runtime::InternalPropertyDescriptor;
InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
objectId);
InjectedScript::ObjectScope scope(m_session, objectId);
Response response = scope.initialize();
if (!response.isSuccess()) return response;
......@@ -507,8 +507,7 @@ Response V8RuntimeAgentImpl::getProperties(
}
Response V8RuntimeAgentImpl::releaseObject(const String16& objectId) {
InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
objectId);
InjectedScript::ObjectScope scope(m_session, objectId);
Response response = scope.initialize();
if (!response.isSuccess()) return response;
scope.injectedScript()->releaseObject(objectId);
......@@ -550,8 +549,7 @@ Response V8RuntimeAgentImpl::compileScript(
Response response = ensureContext(m_inspector, m_session->contextGroupId(),
std::move(executionContextId), &contextId);
if (!response.isSuccess()) return response;
InjectedScript::ContextScope scope(m_inspector, m_session->contextGroupId(),
contextId);
InjectedScript::ContextScope scope(m_session, contextId);
response = scope.initialize();
if (!response.isSuccess()) return response;
......@@ -607,8 +605,7 @@ void V8RuntimeAgentImpl::runScript(
return;
}
InjectedScript::ContextScope scope(m_inspector, m_session->contextGroupId(),
contextId);
InjectedScript::ContextScope scope(m_session, contextId);
response = scope.initialize();
if (!response.isSuccess()) {
callback->sendFailure(response);
......@@ -650,9 +647,8 @@ void V8RuntimeAgentImpl::runScript(
return;
}
ProtocolPromiseHandler<RunScriptCallback>::add(
m_inspector, scope.context(), maybeResultValue.ToLocalChecked(),
m_session, scope.context(), maybeResultValue.ToLocalChecked(),
"Result of the script execution is not a promise",
m_session->contextGroupId(),
scope.injectedScript()->context()->contextId(), objectGroup.fromMaybe(""),
returnByValue.fromMaybe(false), generatePreview.fromMaybe(false),
std::move(callback));
......@@ -700,10 +696,9 @@ Response V8RuntimeAgentImpl::disable() {
void V8RuntimeAgentImpl::reset() {
m_compiledScripts.clear();
if (m_enabled) {
if (const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_session->contextGroupId())) {
for (auto& idContext : *contexts) idContext.second->setReported(false);
}
m_inspector->forEachContext(
m_session->contextGroupId(),
[](InspectedContext* context) { context->setReported(false); });
m_frontend.executionContextsCleared();
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment