diff options
Diffstat (limited to 'deps/v8/src/inspector')
36 files changed, 413 insertions, 299 deletions
diff --git a/deps/v8/src/inspector/custom-preview.h b/deps/v8/src/inspector/custom-preview.h index 1e8c74a154..d7b24adcce 100644 --- a/deps/v8/src/inspector/custom-preview.h +++ b/deps/v8/src/inspector/custom-preview.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_CUSTOM_PREVIEW_H_ #define V8_INSPECTOR_CUSTOM_PREVIEW_H_ +#include <memory> + #include "src/inspector/protocol/Protocol.h" #include "src/inspector/protocol/Runtime.h" diff --git a/deps/v8/src/inspector/injected-script.cc b/deps/v8/src/inspector/injected-script.cc index 18a10285dd..6afc6486e4 100644 --- a/deps/v8/src/inspector/injected-script.cc +++ b/deps/v8/src/inspector/injected-script.cc @@ -289,7 +289,7 @@ Response InjectedScript::getProperties( int sessionId = m_sessionId; v8::TryCatch tryCatch(isolate); - *properties = v8::base::make_unique<Array<PropertyDescriptor>>(); + *properties = std::make_unique<Array<PropertyDescriptor>>(); std::vector<PropertyMirror> mirrors; PropertyAccumulator accumulator(&mirrors); if (!ValueMirror::getProperties(context, object, ownProperties, @@ -366,10 +366,8 @@ Response InjectedScript::getInternalAndPrivateProperties( internalProperties, std::unique_ptr<protocol::Array<PrivatePropertyDescriptor>>* privateProperties) { - *internalProperties = - v8::base::make_unique<Array<InternalPropertyDescriptor>>(); - *privateProperties = - v8::base::make_unique<Array<PrivatePropertyDescriptor>>(); + *internalProperties = std::make_unique<Array<InternalPropertyDescriptor>>(); + *privateProperties = std::make_unique<Array<PrivatePropertyDescriptor>>(); if (!value->IsObject()) return Response::OK(); @@ -521,7 +519,7 @@ std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( if (columnSet.find(property->getName()) == columnSet.end()) continue; columnMap[property->getName()] = property.get(); } - auto filtered = v8::base::make_unique<Array<PropertyPreview>>(); + auto filtered = std::make_unique<Array<PropertyPreview>>(); for (const String16& column : selectedColumns) { if (columnMap.find(column) == columnMap.end()) continue; filtered->push_back(columnMap[column]->clone()); diff --git a/deps/v8/src/inspector/injected-script.h b/deps/v8/src/inspector/injected-script.h index d007e9121e..080769f712 100644 --- a/deps/v8/src/inspector/injected-script.h +++ b/deps/v8/src/inspector/injected-script.h @@ -31,6 +31,7 @@ #ifndef V8_INSPECTOR_INJECTED_SCRIPT_H_ #define V8_INSPECTOR_INJECTED_SCRIPT_H_ +#include <memory> #include <unordered_map> #include <unordered_set> diff --git a/deps/v8/src/inspector/inspected-context.cc b/deps/v8/src/inspector/inspected-context.cc index 8098aa5cac..03a799cb5b 100644 --- a/deps/v8/src/inspector/inspected-context.cc +++ b/deps/v8/src/inspector/inspected-context.cc @@ -112,7 +112,7 @@ InjectedScript* InspectedContext::getInjectedScript(int sessionId) { InjectedScript* InspectedContext::createInjectedScript(int sessionId) { std::unique_ptr<InjectedScript> injectedScript = - v8::base::make_unique<InjectedScript>(this, sessionId); + std::make_unique<InjectedScript>(this, sessionId); CHECK(m_injectedScripts.find(sessionId) == m_injectedScripts.end()); m_injectedScripts[sessionId] = std::move(injectedScript); return getInjectedScript(sessionId); diff --git a/deps/v8/src/inspector/inspected-context.h b/deps/v8/src/inspector/inspected-context.h index 4ec52dc1e4..68b865de67 100644 --- a/deps/v8/src/inspector/inspected-context.h +++ b/deps/v8/src/inspector/inspected-context.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_INSPECTED_CONTEXT_H_ #define V8_INSPECTOR_INSPECTED_CONTEXT_H_ +#include <memory> #include <unordered_map> #include <unordered_set> diff --git a/deps/v8/src/inspector/remote-object-id.h b/deps/v8/src/inspector/remote-object-id.h index b199032359..5a35c13e58 100644 --- a/deps/v8/src/inspector/remote-object-id.h +++ b/deps/v8/src/inspector/remote-object-id.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_REMOTE_OBJECT_ID_H_ #define V8_INSPECTOR_REMOTE_OBJECT_ID_H_ +#include <memory> + #include "src/inspector/protocol/Forward.h" namespace v8_inspector { diff --git a/deps/v8/src/inspector/search-util.h b/deps/v8/src/inspector/search-util.h index 3c8a9fe31c..5958a404f0 100644 --- a/deps/v8/src/inspector/search-util.h +++ b/deps/v8/src/inspector/search-util.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_SEARCH_UTIL_H_ #define V8_INSPECTOR_SEARCH_UTIL_H_ +#include <memory> + #include "src/inspector/protocol/Debugger.h" #include "src/inspector/string-util.h" diff --git a/deps/v8/src/inspector/string-16.cc b/deps/v8/src/inspector/string-16.cc index 3a91169ac8..3adffeddf1 100644 --- a/deps/v8/src/inspector/string-16.cc +++ b/deps/v8/src/inspector/string-16.cc @@ -84,6 +84,13 @@ String16 String16::fromInteger(size_t number) { } // static +String16 String16::fromInteger64(int64_t number) { + char buffer[50]; + v8::base::OS::SNPrintF(buffer, arraysize(buffer), "%" PRId64 "", number); + return String16(buffer); +} + +// static String16 String16::fromDouble(double number) { char arr[50]; v8::internal::Vector<char> buffer(arr, arraysize(arr)); diff --git a/deps/v8/src/inspector/string-16.h b/deps/v8/src/inspector/string-16.h index c1dd5cb929..910a2e49c6 100644 --- a/deps/v8/src/inspector/string-16.h +++ b/deps/v8/src/inspector/string-16.h @@ -37,6 +37,7 @@ class String16 { static String16 fromInteger(int); static String16 fromInteger(size_t); + static String16 fromInteger64(int64_t); static String16 fromDouble(double); static String16 fromDouble(double, int precision); diff --git a/deps/v8/src/inspector/string-util.cc b/deps/v8/src/inspector/string-util.cc index 20c8951e2a..bae5dd91a9 100644 --- a/deps/v8/src/inspector/string-util.cc +++ b/deps/v8/src/inspector/string-util.cc @@ -169,15 +169,6 @@ StringBufferImpl::StringBufferImpl(String16& string) { m_string = toStringView(m_owner); } -String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId) { - const size_t kBufferSize = 35; - - char buffer[kBufferSize]; - v8::base::OS::SNPrintF(buffer, kBufferSize, "(%08" PRIX64 "%08" PRIX64 ")", - debuggerId.first, debuggerId.second); - return String16(buffer); -} - String16 stackTraceIdToString(uintptr_t id) { String16Builder builder; builder.appendNumber(static_cast<size_t>(id)); diff --git a/deps/v8/src/inspector/string-util.h b/deps/v8/src/inspector/string-util.h index 513f436136..9b6a8bdd5d 100644 --- a/deps/v8/src/inspector/string-util.h +++ b/deps/v8/src/inspector/string-util.h @@ -101,13 +101,23 @@ class StringUtil { // therefore it's unnecessary to provide an implementation here. class Binary { public: - const uint8_t* data() const { UNIMPLEMENTED(); } - size_t size() const { UNIMPLEMENTED(); } + Binary() = default; + + const uint8_t* data() const { return bytes_->data(); } + size_t size() const { return bytes_->size(); } String toBase64() const { UNIMPLEMENTED(); } static Binary fromBase64(const String& base64, bool* success) { UNIMPLEMENTED(); } - static Binary fromSpan(const uint8_t* data, size_t size) { UNIMPLEMENTED(); } + static Binary fromSpan(const uint8_t* data, size_t size) { + return Binary(std::make_shared<std::vector<uint8_t>>(data, data + size)); + } + + private: + std::shared_ptr<std::vector<uint8_t>> bytes_; + + explicit Binary(std::shared_ptr<std::vector<uint8_t>> bytes) + : bytes_(bytes) {} }; } // namespace protocol @@ -149,7 +159,6 @@ class BinaryStringBuffer : public StringBuffer { DISALLOW_COPY_AND_ASSIGN(BinaryStringBuffer); }; -String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId); String16 stackTraceIdToString(uintptr_t id); } // namespace v8_inspector diff --git a/deps/v8/src/inspector/v8-console-message.cc b/deps/v8/src/inspector/v8-console-message.cc index 458e4d4027..e4c678a272 100644 --- a/deps/v8/src/inspector/v8-console-message.cc +++ b/deps/v8/src/inspector/v8-console-message.cc @@ -258,7 +258,7 @@ V8ConsoleMessage::wrapArguments(V8InspectorSessionImpl* session, v8::Local<v8::Context> context = inspectedContext->context(); auto args = - v8::base::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>(); + std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>(); v8::Local<v8::Value> value = m_arguments[0]->Get(isolate); if (value->IsObject() && m_type == ConsoleAPIType::kTable && @@ -341,8 +341,8 @@ void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, arguments = wrapArguments(session, generatePreview); if (!inspector->hasConsoleMessageStorage(contextGroupId)) return; if (!arguments) { - arguments = v8::base::make_unique< - protocol::Array<protocol::Runtime::RemoteObject>>(); + arguments = + std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>(); if (!m_message.isEmpty()) { std::unique_ptr<protocol::Runtime::RemoteObject> messageArg = protocol::Runtime::RemoteObject::create() diff --git a/deps/v8/src/inspector/v8-console-message.h b/deps/v8/src/inspector/v8-console-message.h index cca5b47265..04bd10ff73 100644 --- a/deps/v8/src/inspector/v8-console-message.h +++ b/deps/v8/src/inspector/v8-console-message.h @@ -7,7 +7,9 @@ #include <deque> #include <map> +#include <memory> #include <set> + #include "include/v8.h" #include "src/inspector/protocol/Console.h" #include "src/inspector/protocol/Forward.h" diff --git a/deps/v8/src/inspector/v8-console.cc b/deps/v8/src/inspector/v8-console.cc index 0f476f2316..f4d0ffa055 100644 --- a/deps/v8/src/inspector/v8-console.cc +++ b/deps/v8/src/inspector/v8-console.cc @@ -691,7 +691,7 @@ v8::Local<v8::Object> V8Console::createCommandLineAPI( v8::Local<v8::ArrayBuffer> data = v8::ArrayBuffer::New(isolate, sizeof(CommandLineAPIData)); - *static_cast<CommandLineAPIData*>(data->GetContents().Data()) = + *static_cast<CommandLineAPIData*>(data->GetBackingStore()->Data()) = CommandLineAPIData(this, sessionId); createBoundFunctionProperty(context, commandLineAPI, data, "dir", &V8Console::call<&V8Console::Dir>, diff --git a/deps/v8/src/inspector/v8-console.h b/deps/v8/src/inspector/v8-console.h index 03d89ced10..4d38c51a2a 100644 --- a/deps/v8/src/inspector/v8-console.h +++ b/deps/v8/src/inspector/v8-console.h @@ -106,14 +106,14 @@ class V8Console : public v8::debug::ConsoleDelegate { int)> static void call(const v8::FunctionCallbackInfo<v8::Value>& info) { CommandLineAPIData* data = static_cast<CommandLineAPIData*>( - info.Data().As<v8::ArrayBuffer>()->GetContents().Data()); + info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data()); (data->first->*func)(info, data->second); } template <void (V8Console::*func)(const v8::debug::ConsoleCallArguments&, const v8::debug::ConsoleContext&)> static void call(const v8::FunctionCallbackInfo<v8::Value>& info) { CommandLineAPIData* data = static_cast<CommandLineAPIData*>( - info.Data().As<v8::ArrayBuffer>()->GetContents().Data()); + info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data()); v8::debug::ConsoleCallArguments args(info); (data->first->*func)(args, v8::debug::ConsoleContext()); } diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.cc b/deps/v8/src/inspector/v8-debugger-agent-impl.cc index e5458823ea..18bf43fbbc 100644 --- a/deps/v8/src/inspector/v8-debugger-agent-impl.cc +++ b/deps/v8/src/inspector/v8-debugger-agent-impl.cc @@ -262,7 +262,7 @@ String16 scopeType(v8::debug::ScopeIterator::ScopeType type) { Response buildScopes(v8::Isolate* isolate, v8::debug::ScopeIterator* iterator, InjectedScript* injectedScript, std::unique_ptr<Array<Scope>>* scopes) { - *scopes = v8::base::make_unique<Array<Scope>>(); + *scopes = std::make_unique<Array<Scope>>(); if (!injectedScript) return Response::OK(); if (iterator->Done()) return Response::OK(); @@ -353,8 +353,8 @@ Response V8DebuggerAgentImpl::enable(Maybe<double> maxScriptsCacheSize, String16* outDebuggerId) { m_maxScriptCacheSize = v8::base::saturated_cast<size_t>( maxScriptsCacheSize.fromMaybe(std::numeric_limits<double>::max())); - *outDebuggerId = debuggerIdToString( - m_debugger->debuggerIdFor(m_session->contextGroupId())); + *outDebuggerId = + m_debugger->debuggerIdFor(m_session->contextGroupId()).toString(); if (enabled()) return Response::OK(); if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) @@ -472,7 +472,7 @@ Response V8DebuggerAgentImpl::setBreakpointByUrl( Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition, String16* outBreakpointId, std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { - *locations = v8::base::make_unique<Array<protocol::Debugger::Location>>(); + *locations = std::make_unique<Array<protocol::Debugger::Location>>(); int specified = (optionalURL.isJust() ? 1 : 0) + (optionalURLRegex.isJust() ? 1 : 0) + @@ -708,8 +708,8 @@ Response V8DebuggerAgentImpl::getPossibleBreakpoints( v8Start, v8End, restrictToFunction.fromMaybe(false), &v8Locations); } - *locations = v8::base::make_unique< - protocol::Array<protocol::Debugger::BreakLocation>>(); + *locations = + std::make_unique<protocol::Array<protocol::Debugger::BreakLocation>>(); for (size_t i = 0; i < v8Locations.size(); ++i) { std::unique_ptr<protocol::Debugger::BreakLocation> breakLocation = protocol::Debugger::BreakLocation::create() @@ -752,17 +752,19 @@ Response V8DebuggerAgentImpl::getStackTrace( std::unique_ptr<protocol::Runtime::StackTrace>* outStackTrace) { bool isOk = false; int64_t id = inStackTraceId->getId().toInteger64(&isOk); - std::pair<int64_t, int64_t> debuggerId; + if (!isOk) return Response::Error("Invalid stack trace id"); + + V8DebuggerId debuggerId; if (inStackTraceId->hasDebuggerId()) { - debuggerId = - m_debugger->debuggerIdFor(inStackTraceId->getDebuggerId(String16())); + debuggerId = V8DebuggerId(inStackTraceId->getDebuggerId(String16())); } else { debuggerId = m_debugger->debuggerIdFor(m_session->contextGroupId()); } - V8StackTraceId v8StackTraceId(id, debuggerId); - if (!isOk || v8StackTraceId.IsInvalid()) { + if (!debuggerId.isValid()) return Response::Error("Invalid stack trace id"); + + V8StackTraceId v8StackTraceId(id, debuggerId.pair()); + if (v8StackTraceId.IsInvalid()) return Response::Error("Invalid stack trace id"); - } auto stack = m_debugger->stackTraceFor(m_session->contextGroupId(), v8StackTraceId); if (!stack) { @@ -872,11 +874,10 @@ Response V8DebuggerAgentImpl::searchInContent( if (it == m_scripts.end()) return Response::Error("No script for id: " + scriptId); - *results = - v8::base::make_unique<protocol::Array<protocol::Debugger::SearchMatch>>( - searchInTextByLinesImpl(m_session, it->second->source(0), query, - optionalCaseSensitive.fromMaybe(false), - optionalIsRegex.fromMaybe(false))); + *results = std::make_unique<protocol::Array<protocol::Debugger::SearchMatch>>( + searchInTextByLinesImpl(m_session, it->second->source(0), query, + optionalCaseSensitive.fromMaybe(false), + optionalIsRegex.fromMaybe(false))); return Response::OK(); } @@ -961,6 +962,20 @@ Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId, return Response::OK(); } +Response V8DebuggerAgentImpl::getWasmBytecode(const String16& scriptId, + protocol::Binary* bytecode) { + if (!enabled()) return Response::Error(kDebuggerNotEnabled); + ScriptsMap::iterator it = m_scripts.find(scriptId); + if (it == m_scripts.end()) + return Response::Error("No script for id: " + scriptId); + v8::MemorySpan<const uint8_t> span; + if (!it->second->wasmBytecode().To(&span)) + return Response::Error("Script with id " + scriptId + + " is not WebAssembly"); + *bytecode = protocol::Binary::fromSpan(span.data(), span.size()); + return Response::OK(); +} + void V8DebuggerAgentImpl::pushBreakDetails( const String16& breakReason, std::unique_ptr<protocol::DictionaryValue> breakAuxData) { @@ -1040,13 +1055,7 @@ Response V8DebuggerAgentImpl::stepOut() { Response V8DebuggerAgentImpl::pauseOnAsyncCall( std::unique_ptr<protocol::Runtime::StackTraceId> inParentStackTraceId) { - bool isOk = false; - int64_t stackTraceId = inParentStackTraceId->getId().toInteger64(&isOk); - if (!isOk) { - return Response::Error("Invalid stack trace id"); - } - m_debugger->pauseOnAsyncCall(m_session->contextGroupId(), stackTraceId, - inParentStackTraceId->getDebuggerId(String16())); + // Deprecated, just return OK. return Response::OK(); } @@ -1270,11 +1279,11 @@ Response V8DebuggerAgentImpl::setBlackboxedRanges( Response V8DebuggerAgentImpl::currentCallFrames( std::unique_ptr<Array<CallFrame>>* result) { if (!isPaused()) { - *result = v8::base::make_unique<Array<CallFrame>>(); + *result = std::make_unique<Array<CallFrame>>(); return Response::OK(); } v8::HandleScope handles(m_isolate); - *result = v8::base::make_unique<Array<CallFrame>>(); + *result = std::make_unique<Array<CallFrame>>(); auto iterator = v8::debug::StackTraceIterator::Create(m_isolate); int frameOrdinal = 0; for (; !iterator->Done(); iterator->Advance(), frameOrdinal++) { @@ -1373,28 +1382,10 @@ V8DebuggerAgentImpl::currentExternalStackTrace() { if (externalParent.IsInvalid()) return nullptr; return protocol::Runtime::StackTraceId::create() .setId(stackTraceIdToString(externalParent.id)) - .setDebuggerId(debuggerIdToString(externalParent.debugger_id)) + .setDebuggerId(V8DebuggerId(externalParent.debugger_id).toString()) .build(); } -std::unique_ptr<protocol::Runtime::StackTraceId> -V8DebuggerAgentImpl::currentScheduledAsyncCall() { - v8_inspector::V8StackTraceId scheduledAsyncCall = - m_debugger->scheduledAsyncCall(); - if (scheduledAsyncCall.IsInvalid()) return nullptr; - std::unique_ptr<protocol::Runtime::StackTraceId> asyncCallStackTrace = - protocol::Runtime::StackTraceId::create() - .setId(stackTraceIdToString(scheduledAsyncCall.id)) - .build(); - // TODO(kozyatinskiy): extract this check to IsLocal function. - if (scheduledAsyncCall.debugger_id.first || - scheduledAsyncCall.debugger_id.second) { - asyncCallStackTrace->setDebuggerId( - debuggerIdToString(scheduledAsyncCall.debugger_id)); - } - return asyncCallStackTrace; -} - bool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPausedInContextGroup(m_session->contextGroupId()); } @@ -1602,7 +1593,7 @@ void V8DebuggerAgentImpl::didPause( } } - auto hitBreakpointIds = v8::base::make_unique<Array<String16>>(); + auto hitBreakpointIds = std::make_unique<Array<String16>>(); for (const auto& id : hitBreakpoints) { auto it = m_breakpointsOnScriptRun.find(id); @@ -1655,12 +1646,11 @@ void V8DebuggerAgentImpl::didPause( std::unique_ptr<Array<CallFrame>> protocolCallFrames; Response response = currentCallFrames(&protocolCallFrames); if (!response.isSuccess()) - protocolCallFrames = v8::base::make_unique<Array<CallFrame>>(); + protocolCallFrames = std::make_unique<Array<CallFrame>>(); m_frontend.paused(std::move(protocolCallFrames), breakReason, std::move(breakAuxData), std::move(hitBreakpointIds), - currentAsyncStackTrace(), currentExternalStackTrace(), - currentScheduledAsyncCall()); + currentAsyncStackTrace(), currentExternalStackTrace()); } void V8DebuggerAgentImpl::didContinue() { diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.h b/deps/v8/src/inspector/v8-debugger-agent-impl.h index 0a5a169907..e6b35b845a 100644 --- a/deps/v8/src/inspector/v8-debugger-agent-impl.h +++ b/deps/v8/src/inspector/v8-debugger-agent-impl.h @@ -6,6 +6,7 @@ #define V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_ #include <deque> +#include <memory> #include <unordered_map> #include <vector> @@ -94,6 +95,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) override; Response getScriptSource(const String16& scriptId, String16* scriptSource) override; + Response getWasmBytecode(const String16& scriptId, + protocol::Binary* bytecode) override; Response pause() override; Response resume() override; Response stepOver() override; @@ -165,7 +168,6 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*); std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace(); std::unique_ptr<protocol::Runtime::StackTraceId> currentExternalStackTrace(); - std::unique_ptr<protocol::Runtime::StackTraceId> currentScheduledAsyncCall(); void setPauseOnExceptionsImpl(int); diff --git a/deps/v8/src/inspector/v8-debugger-script.cc b/deps/v8/src/inspector/v8-debugger-script.cc index b83eafc96a..99511fc144 100644 --- a/deps/v8/src/inspector/v8-debugger-script.cc +++ b/deps/v8/src/inspector/v8-debugger-script.cc @@ -141,6 +141,12 @@ class ActualScript : public V8DebuggerScript { static_cast<int>(pos), static_cast<int>(substringLength)); return String16(buffer.get(), substringLength); } + v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const override { + v8::HandleScope scope(m_isolate); + auto script = this->script(); + if (!script->IsWasm()) return v8::Nothing<v8::MemorySpan<const uint8_t>>(); + return v8::Just(v8::debug::WasmScript::Cast(*script)->Bytecode()); + } int startLine() const override { return m_startLine; } int startColumn() const override { return m_startColumn; } int endLine() const override { return m_endLine; } @@ -281,9 +287,8 @@ class ActualScript : public V8DebuggerScript { m_startLine = script->LineOffset(); m_startColumn = script->ColumnOffset(); std::vector<int> lineEnds = script->LineEnds(); - CHECK(lineEnds.size()); - int source_length = lineEnds[lineEnds.size() - 1]; if (lineEnds.size()) { + int source_length = lineEnds[lineEnds.size() - 1]; m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1; if (lineEnds.size() > 1) { m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1; @@ -356,6 +361,9 @@ class WasmVirtualScript : public V8DebuggerScript { return m_wasmTranslation->GetSource(m_id, m_functionIndex) .substring(pos, len); } + v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const override { + return v8::Nothing<v8::MemorySpan<const uint8_t>>(); + } int startLine() const override { return m_wasmTranslation->GetStartLine(m_id, m_functionIndex); } @@ -462,17 +470,17 @@ class WasmVirtualScript : public V8DebuggerScript { std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj, bool isLiveEdit, V8DebuggerAgentImpl* agent, V8InspectorClient* client) { - return v8::base::make_unique<ActualScript>(isolate, scriptObj, isLiveEdit, - agent, client); + return std::make_unique<ActualScript>(isolate, scriptObj, isLiveEdit, agent, + client); } std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( v8::Isolate* isolate, WasmTranslation* wasmTranslation, v8::Local<v8::debug::WasmScript> underlyingScript, String16 id, String16 url, int functionIndex) { - return v8::base::make_unique<WasmVirtualScript>( - isolate, wasmTranslation, underlyingScript, std::move(id), std::move(url), - functionIndex); + return std::make_unique<WasmVirtualScript>(isolate, wasmTranslation, + underlyingScript, std::move(id), + std::move(url), functionIndex); } V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, diff --git a/deps/v8/src/inspector/v8-debugger-script.h b/deps/v8/src/inspector/v8-debugger-script.h index 547bb0a2cc..b53d2c15aa 100644 --- a/deps/v8/src/inspector/v8-debugger-script.h +++ b/deps/v8/src/inspector/v8-debugger-script.h @@ -30,6 +30,8 @@ #ifndef V8_INSPECTOR_V8_DEBUGGER_SCRIPT_H_ #define V8_INSPECTOR_V8_DEBUGGER_SCRIPT_H_ +#include <memory> + #include "src/base/macros.h" #include "src/inspector/string-16.h" #include "src/inspector/string-util.h" @@ -61,6 +63,7 @@ class V8DebuggerScript { virtual const String16& sourceMappingURL() const = 0; virtual String16 source(size_t pos, size_t len = UINT_MAX) const = 0; + virtual v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const = 0; virtual const String16& hash() const = 0; virtual int startLine() const = 0; virtual int startColumn() const = 0; diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc index 5ddc375a80..bd127b2c1c 100644 --- a/deps/v8/src/inspector/v8-debugger.cc +++ b/deps/v8/src/inspector/v8-debugger.cc @@ -64,6 +64,42 @@ class MatchPrototypePredicate : public v8::debug::QueryObjectPredicate { } // namespace +V8DebuggerId::V8DebuggerId(std::pair<int64_t, int64_t> pair) + : m_first(pair.first), m_second(pair.second) {} + +// static +V8DebuggerId V8DebuggerId::generate(v8::Isolate* isolate) { + V8DebuggerId debuggerId; + debuggerId.m_first = v8::debug::GetNextRandomInt64(isolate); + debuggerId.m_second = v8::debug::GetNextRandomInt64(isolate); + if (!debuggerId.m_first && !debuggerId.m_second) ++debuggerId.m_first; + return debuggerId; +} + +V8DebuggerId::V8DebuggerId(const String16& debuggerId) { + const UChar dot = '.'; + size_t pos = debuggerId.find(dot); + if (pos == String16::kNotFound) return; + bool ok = false; + int64_t first = debuggerId.substring(0, pos).toInteger64(&ok); + if (!ok) return; + int64_t second = debuggerId.substring(pos + 1).toInteger64(&ok); + if (!ok) return; + m_first = first; + m_second = second; +} + +String16 V8DebuggerId::toString() const { + return String16::fromInteger64(m_first) + "." + + String16::fromInteger64(m_second); +} + +bool V8DebuggerId::isValid() const { return m_first || m_second; } + +std::pair<int64_t, int64_t> V8DebuggerId::pair() const { + return std::make_pair(m_first, m_second); +} + V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) : m_isolate(isolate), m_inspector(inspector), @@ -107,7 +143,9 @@ void V8Debugger::disable() { if (--m_enableCount) return; clearContinueToLocation(); m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); + m_externalAsyncTaskPauseRequested = false; + m_taskWithScheduledBreakPauseRequested = false; + m_pauseOnNextCallRequested = false; m_pauseOnAsyncCall = false; m_wasmTranslation.Clear(); v8::debug::SetDebugDelegate(m_isolate, nullptr); @@ -171,12 +209,19 @@ void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) { m_targetContextGroupId != targetContextGroupId) { return; } - m_targetContextGroupId = targetContextGroupId; - m_breakRequested = pause; - if (pause) - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - else - v8::debug::ClearBreakOnNextFunctionCall(m_isolate); + if (pause) { + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_pauseOnNextCallRequested = true; + if (!didHaveBreak) { + m_targetContextGroupId = targetContextGroupId; + v8::debug::SetBreakOnNextFunctionCall(m_isolate); + } + } else { + m_pauseOnNextCallRequested = false; + if (!hasScheduledBreakOnNextFunctionCall()) { + v8::debug::ClearBreakOnNextFunctionCall(m_isolate); + } + } } bool V8Debugger::canBreakProgram() { @@ -275,21 +320,12 @@ bool V8Debugger::asyncStepOutOfFunction(int targetContextGroupId, void* parentTask = std::shared_ptr<AsyncStackTrace>(parent)->suspendedTaskId(); if (!parentTask) return false; - pauseOnAsyncCall(targetContextGroupId, - reinterpret_cast<uintptr_t>(parentTask), String16()); + m_targetContextGroupId = targetContextGroupId; + m_taskWithScheduledBreak = parentTask; continueProgram(targetContextGroupId); return true; } -void V8Debugger::pauseOnAsyncCall(int targetContextGroupId, uintptr_t task, - const String16& debuggerId) { - DCHECK(targetContextGroupId); - m_targetContextGroupId = targetContextGroupId; - - m_taskWithScheduledBreak = reinterpret_cast<void*>(task); - m_taskWithScheduledBreakDebuggerId = debuggerId; -} - void V8Debugger::terminateExecution( std::unique_ptr<TerminateExecutionCallback> callback) { if (m_terminateExecutionCallback) { @@ -390,10 +426,11 @@ void V8Debugger::handleProgramBreak( return; } m_targetContextGroupId = 0; - m_breakRequested = false; + m_pauseOnNextCallRequested = false; m_pauseOnAsyncCall = false; m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); + m_externalAsyncTaskPauseRequested = false; + m_taskWithScheduledBreakPauseRequested = false; bool scheduledOOMBreak = m_scheduledOOMBreak; bool scheduledAssertBreak = m_scheduledAssertBreak; @@ -470,31 +507,30 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit, void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited, bool has_compile_error) { + if (m_ignoreScriptParsedEventsCounter != 0) return; + int contextId; if (!script->ContextId().To(&contextId)) return; - if (script->IsWasm() && script->SourceMappingURL().IsEmpty()) { - WasmTranslation* wasmTranslation = &m_wasmTranslation; - m_inspector->forEachSession( - m_inspector->contextGroupId(contextId), - [&script, &wasmTranslation](V8InspectorSessionImpl* session) { - if (!session->debuggerAgent()->enabled()) return; - wasmTranslation->AddScript(script.As<v8::debug::WasmScript>(), - session->debuggerAgent()); - }); - } else if (m_ignoreScriptParsedEventsCounter == 0) { - v8::Isolate* isolate = m_isolate; - V8InspectorClient* client = m_inspector->client(); - m_inspector->forEachSession( - m_inspector->contextGroupId(contextId), - [&isolate, &script, &has_compile_error, &is_live_edited, - &client](V8InspectorSessionImpl* session) { - if (!session->debuggerAgent()->enabled()) return; - session->debuggerAgent()->didParseSource( - V8DebuggerScript::Create(isolate, script, is_live_edited, - session->debuggerAgent(), client), + + v8::Isolate* isolate = m_isolate; + V8InspectorClient* client = m_inspector->client(); + WasmTranslation& wasmTranslation = m_wasmTranslation; + + m_inspector->forEachSession( + m_inspector->contextGroupId(contextId), + [isolate, &script, has_compile_error, is_live_edited, client, + &wasmTranslation](V8InspectorSessionImpl* session) { + auto agent = session->debuggerAgent(); + if (!agent->enabled()) return; + if (script->IsWasm() && script->SourceMappingURL().IsEmpty()) { + wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); + } else { + agent->didParseSource( + V8DebuggerScript::Create(isolate, script, is_live_edited, agent, + client), !has_compile_error); - }); - } + } + }); } void V8Debugger::BreakProgramRequested( @@ -540,15 +576,15 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type, switch (type) { case v8::debug::kDebugPromiseThen: asyncTaskScheduledForStack("Promise.then", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugPromiseCatch: asyncTaskScheduledForStack("Promise.catch", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugPromiseFinally: asyncTaskScheduledForStack("Promise.finally", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugWillHandle: asyncTaskStartedForStack(task); @@ -786,7 +822,7 @@ void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { std::shared_ptr<AsyncStackTrace> V8Debugger::stackTraceFor( int contextGroupId, const V8StackTraceId& id) { - if (debuggerIdFor(contextGroupId) != id.debugger_id) return nullptr; + if (debuggerIdFor(contextGroupId).pair() != id.debugger_id) return nullptr; auto it = m_storedStackTraces.find(id.id); if (it == m_storedStackTraces.end()) return nullptr; return it->second.lock(); @@ -811,9 +847,13 @@ V8StackTraceId V8Debugger::storeCurrentStackTrace( ++m_asyncStacksCount; collectOldAsyncStacksIfNeeded(); - asyncTaskCandidateForStepping(reinterpret_cast<void*>(id), false); - - return V8StackTraceId(id, debuggerIdFor(contextGroupId)); + bool shouldPause = + m_pauseOnAsyncCall && contextGroupId == m_targetContextGroupId; + if (shouldPause) { + m_pauseOnAsyncCall = false; + v8::debug::ClearStepping(m_isolate); // Cancel step into. + } + return V8StackTraceId(id, debuggerIdFor(contextGroupId).pair(), shouldPause); } uintptr_t V8Debugger::storeStackTrace( @@ -829,13 +869,12 @@ void V8Debugger::externalAsyncTaskStarted(const V8StackTraceId& parent) { m_currentAsyncParent.emplace_back(); m_currentTasks.push_back(reinterpret_cast<void*>(parent.id)); - if (m_breakRequested) return; - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() && - reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) == parent.id && - m_taskWithScheduledBreakDebuggerId == - debuggerIdToString(parent.debugger_id)) { - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - } + if (!parent.should_pause) return; + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_externalAsyncTaskPauseRequested = true; + if (didHaveBreak) return; + m_targetContextGroupId = currentContextGroupId(); + v8::debug::SetBreakOnNextFunctionCall(m_isolate); } void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) { @@ -845,22 +884,16 @@ void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) { DCHECK(m_currentTasks.back() == reinterpret_cast<void*>(parent.id)); m_currentTasks.pop_back(); - if (m_taskWithScheduledBreakDebuggerId.isEmpty() || - reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) != parent.id || - m_taskWithScheduledBreakDebuggerId != - debuggerIdToString(parent.debugger_id)) { - return; - } - m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); - if (m_breakRequested) return; + if (!parent.should_pause) return; + m_externalAsyncTaskPauseRequested = false; + if (hasScheduledBreakOnNextFunctionCall()) return; v8::debug::ClearBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, bool recurring) { asyncTaskScheduledForStack(toString16(taskName), task, recurring); - asyncTaskCandidateForStepping(task, true); + asyncTaskCandidateForStepping(task); } void V8Debugger::asyncTaskCanceled(void* task) { @@ -936,46 +969,36 @@ void V8Debugger::asyncTaskFinishedForStack(void* task) { } } -void V8Debugger::asyncTaskCandidateForStepping(void* task, bool isLocal) { +void V8Debugger::asyncTaskCandidateForStepping(void* task) { if (!m_pauseOnAsyncCall) return; int contextGroupId = currentContextGroupId(); if (contextGroupId != m_targetContextGroupId) return; - if (isLocal) { - m_scheduledAsyncCall = v8_inspector::V8StackTraceId( - reinterpret_cast<uintptr_t>(task), std::make_pair(0, 0)); - } else { - m_scheduledAsyncCall = v8_inspector::V8StackTraceId( - reinterpret_cast<uintptr_t>(task), debuggerIdFor(contextGroupId)); - } - breakProgram(m_targetContextGroupId); - m_scheduledAsyncCall = v8_inspector::V8StackTraceId(); + m_taskWithScheduledBreak = task; + m_pauseOnAsyncCall = false; + v8::debug::ClearStepping(m_isolate); // Cancel step into. } void V8Debugger::asyncTaskStartedForStepping(void* task) { - if (m_breakRequested) return; // TODO(kozyatinskiy): we should search task in async chain to support // blackboxing. - if (m_taskWithScheduledBreakDebuggerId.isEmpty() && - task == m_taskWithScheduledBreak) { - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - } + if (task != m_taskWithScheduledBreak) return; + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_taskWithScheduledBreakPauseRequested = true; + if (didHaveBreak) return; + m_targetContextGroupId = currentContextGroupId(); + v8::debug::SetBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskFinishedForStepping(void* task) { - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() || - task != m_taskWithScheduledBreak) { - return; - } + if (task != m_taskWithScheduledBreak) return; m_taskWithScheduledBreak = nullptr; - if (m_breakRequested) return; + m_taskWithScheduledBreakPauseRequested = false; + if (hasScheduledBreakOnNextFunctionCall()) return; v8::debug::ClearBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskCanceledForStepping(void* task) { - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() || - task != m_taskWithScheduledBreak) - return; - m_taskWithScheduledBreak = nullptr; + asyncTaskFinishedForStepping(task); } void V8Debugger::allAsyncTasksCanceled() { @@ -1058,7 +1081,7 @@ std::shared_ptr<StackFrame> V8Debugger::symbolize( return std::shared_ptr<StackFrame>(it->second); } std::shared_ptr<StackFrame> frame(new StackFrame(isolate(), v8Frame)); - // TODO(clemensh): Figure out a way to do this translation only right before + // TODO(clemensb): Figure out a way to do this translation only right before // sending the stack trace over wire. if (v8Frame->IsWasm()) frame->translate(&m_wasmTranslation); if (m_maxAsyncCallStackDepth) { @@ -1073,27 +1096,15 @@ void V8Debugger::setMaxAsyncTaskStacksForTest(int limit) { m_maxAsyncCallStacks = limit; } -std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor(int contextGroupId) { +V8DebuggerId V8Debugger::debuggerIdFor(int contextGroupId) { auto it = m_contextGroupIdToDebuggerId.find(contextGroupId); if (it != m_contextGroupIdToDebuggerId.end()) return it->second; - std::pair<int64_t, int64_t> debuggerId( - v8::debug::GetNextRandomInt64(m_isolate), - v8::debug::GetNextRandomInt64(m_isolate)); - if (!debuggerId.first && !debuggerId.second) ++debuggerId.first; + V8DebuggerId debuggerId = V8DebuggerId::generate(m_isolate); m_contextGroupIdToDebuggerId.insert( it, std::make_pair(contextGroupId, debuggerId)); - m_serializedDebuggerIdToDebuggerId.insert( - std::make_pair(debuggerIdToString(debuggerId), debuggerId)); return debuggerId; } -std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor( - const String16& serializedDebuggerId) { - auto it = m_serializedDebuggerIdToDebuggerId.find(serializedDebuggerId); - if (it != m_serializedDebuggerIdToDebuggerId.end()) return it->second; - return std::make_pair(0, 0); -} - bool V8Debugger::addInternalObject(v8::Local<v8::Context> context, v8::Local<v8::Object> object, V8InternalValueType type) { @@ -1110,4 +1121,9 @@ void V8Debugger::dumpAsyncTaskStacksStateForTest() { fprintf(stdout, "\n"); } +bool V8Debugger::hasScheduledBreakOnNextFunctionCall() const { + return m_pauseOnNextCallRequested || m_taskWithScheduledBreakPauseRequested || + m_externalAsyncTaskPauseRequested; +} + } // namespace v8_inspector diff --git a/deps/v8/src/inspector/v8-debugger.h b/deps/v8/src/inspector/v8-debugger.h index ba64c4c032..a078d14f3d 100644 --- a/deps/v8/src/inspector/v8-debugger.h +++ b/deps/v8/src/inspector/v8-debugger.h @@ -6,6 +6,7 @@ #define V8_INSPECTOR_V8_DEBUGGER_H_ #include <list> +#include <memory> #include <unordered_map> #include <unordered_set> #include <vector> @@ -36,6 +37,31 @@ using protocol::Response; using TerminateExecutionCallback = protocol::Runtime::Backend::TerminateExecutionCallback; +// This debugger id tries to be unique by generating two random +// numbers, which should most likely avoid collisions. +// Debugger id has a 1:1 mapping to context group. It is used to +// attribute stack traces to a particular debugging, when doing any +// cross-debugger operations (e.g. async step in). +// See also Runtime.UniqueDebuggerId in the protocol. +class V8DebuggerId { + public: + V8DebuggerId() = default; + explicit V8DebuggerId(std::pair<int64_t, int64_t>); + explicit V8DebuggerId(const String16&); + V8DebuggerId(const V8DebuggerId&) V8_NOEXCEPT = default; + ~V8DebuggerId() = default; + + static V8DebuggerId generate(v8::Isolate*); + + String16 toString() const; + bool isValid() const; + std::pair<int64_t, int64_t> pair() const; + + private: + int64_t m_first = 0; + int64_t m_second = 0; +}; + class V8Debugger : public v8::debug::DebugDelegate, public v8::debug::AsyncEventDelegate { public: @@ -59,8 +85,6 @@ class V8Debugger : public v8::debug::DebugDelegate, void stepIntoStatement(int targetContextGroupId, bool breakOnAsyncCall); void stepOverStatement(int targetContextGroupId); void stepOutOfFunction(int targetContextGroupId); - void pauseOnAsyncCall(int targetContextGroupId, uintptr_t task, - const String16& debuggerId); void terminateExecution(std::unique_ptr<TerminateExecutionCallback> callback); @@ -121,13 +145,7 @@ class V8Debugger : public v8::debug::DebugDelegate, void setMaxAsyncTaskStacksForTest(int limit); void dumpAsyncTaskStacksStateForTest(); - v8_inspector::V8StackTraceId scheduledAsyncCall() { - return m_scheduledAsyncCall; - } - - std::pair<int64_t, int64_t> debuggerIdFor(int contextGroupId); - std::pair<int64_t, int64_t> debuggerIdFor( - const String16& serializedDebuggerId); + V8DebuggerId debuggerIdFor(int contextGroupId); std::shared_ptr<AsyncStackTrace> stackTraceFor(int contextGroupId, const V8StackTraceId& id); @@ -173,7 +191,7 @@ class V8Debugger : public v8::debug::DebugDelegate, void asyncTaskStartedForStack(void* task); void asyncTaskFinishedForStack(void* task); - void asyncTaskCandidateForStepping(void* task, bool isLocal); + void asyncTaskCandidateForStepping(void* task); void asyncTaskStartedForStepping(void* task); void asyncTaskFinishedForStepping(void* task); void asyncTaskCanceledForStepping(void* task); @@ -197,6 +215,8 @@ class V8Debugger : public v8::debug::DebugDelegate, int currentContextGroupId(); bool asyncStepOutOfFunction(int targetContextGroupId, bool onlyAtReturn); + bool hasScheduledBreakOnNextFunctionCall() const; + v8::Isolate* m_isolate; V8InspectorImpl* m_inspector; int m_enableCount; @@ -233,23 +253,24 @@ class V8Debugger : public v8::debug::DebugDelegate, std::unordered_map<V8DebuggerAgentImpl*, int> m_maxAsyncCallStackDepthMap; void* m_taskWithScheduledBreak = nullptr; - String16 m_taskWithScheduledBreakDebuggerId; - bool m_breakRequested = false; + // If any of the following three is true, we schedule pause on next JS + // execution using SetBreakOnNextFunctionCall. + bool m_externalAsyncTaskPauseRequested = false; // External async task. + bool m_taskWithScheduledBreakPauseRequested = false; // Local async task. + bool m_pauseOnNextCallRequested = false; // setPauseOnNextCall API call. v8::debug::ExceptionBreakState m_pauseOnExceptionsState; + // Whether we should pause on async call execution (if any) while stepping in. + // See Debugger.stepInto for details. bool m_pauseOnAsyncCall = false; - v8_inspector::V8StackTraceId m_scheduledAsyncCall; using StackTraceIdToStackTrace = std::unordered_map<uintptr_t, std::weak_ptr<AsyncStackTrace>>; StackTraceIdToStackTrace m_storedStackTraces; uintptr_t m_lastStackTraceId = 0; - std::unordered_map<int, std::pair<int64_t, int64_t>> - m_contextGroupIdToDebuggerId; - std::unordered_map<String16, std::pair<int64_t, int64_t>> - m_serializedDebuggerIdToDebuggerId; + std::unordered_map<int, V8DebuggerId> m_contextGroupIdToDebuggerId; std::unique_ptr<TerminateExecutionCallback> m_terminateExecutionCallback; diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc index fcee8a6ef3..02aa1ad9fe 100644 --- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc +++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc @@ -4,7 +4,6 @@ #include "src/inspector/v8-heap-profiler-agent-impl.h" -#include "src/base/template-utils.h" #include "src/inspector/injected-script.h" #include "src/inspector/inspected-context.h" #include "src/inspector/protocol/Protocol.h" @@ -128,7 +127,7 @@ class HeapStatsStream final : public v8::OutputStream { WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* updateData, int count) override { DCHECK_GT(count, 0); - auto statsDiff = v8::base::make_unique<protocol::Array<int>>(); + auto statsDiff = std::make_unique<protocol::Array<int>>(); for (int i = 0; i < count; ++i) { statsDiff->emplace_back(updateData[i].index); statsDiff->emplace_back(updateData[i].count); @@ -337,7 +336,7 @@ namespace { std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfileNode> buildSampingHeapProfileNode(v8::Isolate* isolate, const v8::AllocationProfile::Node* node) { - auto children = v8::base::make_unique< + auto children = std::make_unique< protocol::Array<protocol::HeapProfiler::SamplingHeapProfileNode>>(); for (const auto* child : node->children) children->emplace_back(buildSampingHeapProfileNode(isolate, child)); @@ -384,7 +383,7 @@ Response V8HeapProfilerAgentImpl::getSamplingProfile( if (!v8Profile) return Response::Error("V8 sampling heap profiler was not started."); v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); - auto samples = v8::base::make_unique< + auto samples = std::make_unique< protocol::Array<protocol::HeapProfiler::SamplingHeapProfileSample>>(); for (const auto& sample : v8Profile->GetSamples()) { samples->emplace_back( diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h index 5c2107d573..665e30be94 100644 --- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h +++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_V8_HEAP_PROFILER_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_HEAP_PROFILER_AGENT_IMPL_H_ +#include <memory> + #include "src/base/macros.h" #include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/HeapProfiler.h" diff --git a/deps/v8/src/inspector/v8-inspector-impl.cc b/deps/v8/src/inspector/v8-inspector-impl.cc index b764118079..e91dd7f7f4 100644 --- a/deps/v8/src/inspector/v8-inspector-impl.cc +++ b/deps/v8/src/inspector/v8-inspector-impl.cc @@ -439,7 +439,7 @@ protocol::Response V8InspectorImpl::EvaluateScope::setTimeout(double timeout) { } m_cancelToken.reset(new CancelToken()); v8::debug::GetCurrentPlatform()->CallDelayedOnWorkerThread( - v8::base::make_unique<TerminateTask>(m_isolate, m_cancelToken), timeout); + std::make_unique<TerminateTask>(m_isolate, m_cancelToken), timeout); return protocol::Response::OK(); } diff --git a/deps/v8/src/inspector/v8-inspector-impl.h b/deps/v8/src/inspector/v8-inspector-impl.h index 5b89cb0920..6276d6d7f6 100644 --- a/deps/v8/src/inspector/v8-inspector-impl.h +++ b/deps/v8/src/inspector/v8-inspector-impl.h @@ -33,6 +33,7 @@ #include <functional> #include <map> +#include <memory> #include <unordered_map> #include "src/base/macros.h" diff --git a/deps/v8/src/inspector/v8-inspector-session-impl.h b/deps/v8/src/inspector/v8-inspector-session-impl.h index 7a976bcd40..786dc2a048 100644 --- a/deps/v8/src/inspector/v8-inspector-session-impl.h +++ b/deps/v8/src/inspector/v8-inspector-session-impl.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_V8_INSPECTOR_SESSION_IMPL_H_ #define V8_INSPECTOR_V8_INSPECTOR_SESSION_IMPL_H_ +#include <memory> #include <vector> #include "src/base/macros.h" diff --git a/deps/v8/src/inspector/v8-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-profiler-agent-impl.cc index 3b02f7faa1..286a18a673 100644 --- a/deps/v8/src/inspector/v8-profiler-agent-impl.cc +++ b/deps/v8/src/inspector/v8-profiler-agent-impl.cc @@ -44,8 +44,8 @@ std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>> buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { unsigned lineCount = node->GetHitLineCount(); if (!lineCount) return nullptr; - auto array = v8::base::make_unique< - protocol::Array<protocol::Profiler::PositionTickInfo>>(); + auto array = + std::make_unique<protocol::Array<protocol::Profiler::PositionTickInfo>>(); std::vector<v8::CpuProfileNode::LineTick> entries(lineCount); if (node->GetLineTicks(&entries[0], lineCount)) { for (unsigned i = 0; i < lineCount; i++) { @@ -80,7 +80,7 @@ std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor( const int childrenCount = node->GetChildrenCount(); if (childrenCount) { - auto children = v8::base::make_unique<protocol::Array<int>>(); + auto children = std::make_unique<protocol::Array<int>>(); for (int i = 0; i < childrenCount; i++) children->emplace_back(node->GetChild(i)->GetNodeId()); result->setChildren(std::move(children)); @@ -98,7 +98,7 @@ std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor( std::unique_ptr<protocol::Array<int>> buildInspectorObjectForSamples( v8::CpuProfile* v8profile) { - auto array = v8::base::make_unique<protocol::Array<int>>(); + auto array = std::make_unique<protocol::Array<int>>(); int count = v8profile->GetSamplesCount(); for (int i = 0; i < count; i++) array->emplace_back(v8profile->GetSample(i)->GetNodeId()); @@ -107,7 +107,7 @@ std::unique_ptr<protocol::Array<int>> buildInspectorObjectForSamples( std::unique_ptr<protocol::Array<int>> buildInspectorObjectForTimestamps( v8::CpuProfile* v8profile) { - auto array = v8::base::make_unique<protocol::Array<int>>(); + auto array = std::make_unique<protocol::Array<int>>(); int count = v8profile->GetSamplesCount(); uint64_t lastTime = v8profile->GetStartTime(); for (int i = 0; i < count; i++) { @@ -130,7 +130,7 @@ void flattenNodesTree(V8InspectorImpl* inspector, std::unique_ptr<protocol::Profiler::Profile> createCPUProfile( V8InspectorImpl* inspector, v8::CpuProfile* v8profile) { auto nodes = - v8::base::make_unique<protocol::Array<protocol::Profiler::ProfileNode>>(); + std::make_unique<protocol::Array<protocol::Profiler::ProfileNode>>(); flattenNodesTree(inspector, v8profile->GetTopDownRoot(), nodes.get()); return protocol::Profiler::Profile::create() .setNodes(std::move(nodes)) @@ -338,18 +338,18 @@ Response coverageToProtocol( V8InspectorImpl* inspector, const v8::debug::Coverage& coverage, std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* out_result) { - auto result = v8::base::make_unique< - protocol::Array<protocol::Profiler::ScriptCoverage>>(); + auto result = + std::make_unique<protocol::Array<protocol::Profiler::ScriptCoverage>>(); v8::Isolate* isolate = inspector->isolate(); for (size_t i = 0; i < coverage.ScriptCount(); i++) { v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); v8::Local<v8::debug::Script> script = script_data.GetScript(); - auto functions = v8::base::make_unique< + auto functions = std::make_unique< protocol::Array<protocol::Profiler::FunctionCoverage>>(); for (size_t j = 0; j < script_data.FunctionCount(); j++) { v8::debug::Coverage::FunctionData function_data = script_data.GetFunctionData(j); - auto ranges = v8::base::make_unique< + auto ranges = std::make_unique< protocol::Array<protocol::Profiler::CoverageRange>>(); // Add function range. @@ -418,19 +418,19 @@ namespace { std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>> typeProfileToProtocol(V8InspectorImpl* inspector, const v8::debug::TypeProfile& type_profile) { - auto result = v8::base::make_unique< + auto result = std::make_unique< protocol::Array<protocol::Profiler::ScriptTypeProfile>>(); v8::Isolate* isolate = inspector->isolate(); for (size_t i = 0; i < type_profile.ScriptCount(); i++) { v8::debug::TypeProfile::ScriptData script_data = type_profile.GetScriptData(i); v8::Local<v8::debug::Script> script = script_data.GetScript(); - auto entries = v8::base::make_unique< + auto entries = std::make_unique< protocol::Array<protocol::Profiler::TypeProfileEntry>>(); for (const auto& entry : script_data.Entries()) { - auto types = v8::base::make_unique< - protocol::Array<protocol::Profiler::TypeObject>>(); + auto types = + std::make_unique<protocol::Array<protocol::Profiler::TypeObject>>(); for (const auto& type : entry.Types()) { types->emplace_back( protocol::Profiler::TypeObject::create() diff --git a/deps/v8/src/inspector/v8-profiler-agent-impl.h b/deps/v8/src/inspector/v8-profiler-agent-impl.h index 5370d39eb4..832d2ce139 100644 --- a/deps/v8/src/inspector/v8-profiler-agent-impl.h +++ b/deps/v8/src/inspector/v8-profiler-agent-impl.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_V8_PROFILER_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_PROFILER_AGENT_IMPL_H_ +#include <memory> #include <vector> #include "src/base/macros.h" diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.cc b/deps/v8/src/inspector/v8-runtime-agent-impl.cc index a8aee0b7f3..4dfc210edc 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.cc +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.cc @@ -235,7 +235,8 @@ void V8RuntimeAgentImpl::evaluate( Maybe<int> executionContextId, Maybe<bool> returnByValue, Maybe<bool> generatePreview, Maybe<bool> userGesture, Maybe<bool> awaitPromise, Maybe<bool> throwOnSideEffect, - Maybe<double> timeout, std::unique_ptr<EvaluateCallback> callback) { + Maybe<double> timeout, Maybe<bool> disableBreaks, + std::unique_ptr<EvaluateCallback> callback) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EvaluateScript"); int contextId = 0; @@ -272,9 +273,16 @@ void V8RuntimeAgentImpl::evaluate( } v8::MicrotasksScope microtasksScope(m_inspector->isolate(), v8::MicrotasksScope::kRunMicrotasks); + v8::debug::EvaluateGlobalMode mode = + v8::debug::EvaluateGlobalMode::kDefault; + if (throwOnSideEffect.fromMaybe(false)) { + mode = v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect; + } else if (disableBreaks.fromMaybe(false)) { + mode = v8::debug::EvaluateGlobalMode::kDisableBreaks; + } maybeResultValue = v8::debug::EvaluateGlobal( m_inspector->isolate(), toV8String(m_inspector->isolate(), expression), - throwOnSideEffect.fromMaybe(false)); + mode); } // Run microtasks before returning result. // Re-initialize after running client's code, as it could have destroyed @@ -613,7 +621,7 @@ Response V8RuntimeAgentImpl::globalLexicalScopeNames( v8::PersistentValueVector<v8::String> names(m_inspector->isolate()); v8::debug::GlobalLexicalScopeNames(scope.context(), &names); - *outNames = v8::base::make_unique<protocol::Array<String16>>(); + *outNames = std::make_unique<protocol::Array<String16>>(); for (size_t i = 0; i < names.Size(); ++i) { (*outNames)->emplace_back( toProtocolString(m_inspector->isolate(), names.Get(i))); diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.h b/deps/v8/src/inspector/v8-runtime-agent-impl.h index a2002e3660..7ecbafd611 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.h +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.h @@ -31,6 +31,7 @@ #ifndef V8_INSPECTOR_V8_RUNTIME_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_RUNTIME_AGENT_IMPL_H_ +#include <memory> #include <unordered_map> #include "src/base/macros.h" @@ -66,7 +67,7 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { Maybe<int> executionContextId, Maybe<bool> returnByValue, Maybe<bool> generatePreview, Maybe<bool> userGesture, Maybe<bool> awaitPromise, Maybe<bool> throwOnSideEffect, - Maybe<double> timeout, + Maybe<double> timeout, Maybe<bool> disableBreaks, std::unique_ptr<EvaluateCallback>) override; void awaitPromise(const String16& promiseObjectId, Maybe<bool> returnByValue, Maybe<bool> generatePreview, diff --git a/deps/v8/src/inspector/v8-schema-agent-impl.cc b/deps/v8/src/inspector/v8-schema-agent-impl.cc index 808f59b0bf..ae19416d1f 100644 --- a/deps/v8/src/inspector/v8-schema-agent-impl.cc +++ b/deps/v8/src/inspector/v8-schema-agent-impl.cc @@ -4,7 +4,6 @@ #include "src/inspector/v8-schema-agent-impl.h" -#include "src/base/template-utils.h" #include "src/inspector/protocol/Protocol.h" #include "src/inspector/v8-inspector-session-impl.h" @@ -19,9 +18,9 @@ V8SchemaAgentImpl::~V8SchemaAgentImpl() = default; Response V8SchemaAgentImpl::getDomains( std::unique_ptr<protocol::Array<protocol::Schema::Domain>>* result) { - *result = v8::base::make_unique< - std::vector<std::unique_ptr<protocol::Schema::Domain>>>( - m_session->supportedDomainsImpl()); + *result = + std::make_unique<std::vector<std::unique_ptr<protocol::Schema::Domain>>>( + m_session->supportedDomainsImpl()); return Response::OK(); } diff --git a/deps/v8/src/inspector/v8-schema-agent-impl.h b/deps/v8/src/inspector/v8-schema-agent-impl.h index b96cce1401..1251e98bc5 100644 --- a/deps/v8/src/inspector/v8-schema-agent-impl.h +++ b/deps/v8/src/inspector/v8-schema-agent-impl.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_V8_SCHEMA_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_SCHEMA_AGENT_IMPL_H_ +#include <memory> + #include "src/base/macros.h" #include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/Schema.h" diff --git a/deps/v8/src/inspector/v8-stack-trace-impl.cc b/deps/v8/src/inspector/v8-stack-trace-impl.cc index e2be811069..04feca284c 100644 --- a/deps/v8/src/inspector/v8-stack-trace-impl.cc +++ b/deps/v8/src/inspector/v8-stack-trace-impl.cc @@ -6,7 +6,6 @@ #include <algorithm> -#include "src/base/template-utils.h" #include "src/inspector/v8-debugger.h" #include "src/inspector/v8-inspector-impl.h" #include "src/inspector/wasm-translation.h" @@ -17,6 +16,10 @@ int V8StackTraceImpl::maxCallStackSizeToCapture = 200; namespace { +static const char kId[] = "id"; +static const char kDebuggerId[] = "debuggerId"; +static const char kShouldPause[] = "shouldPause"; + static const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast<v8::StackTrace::StackTraceOptions>( v8::StackTrace::kDetailed | @@ -74,7 +77,7 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( } auto inspectorFrames = - v8::base::make_unique<protocol::Array<protocol::Runtime::CallFrame>>(); + std::make_unique<protocol::Array<protocol::Runtime::CallFrame>>(); for (const std::shared_ptr<StackFrame>& frame : frames) { V8InspectorClient* client = nullptr; if (debugger && debugger->inspector()) @@ -102,7 +105,7 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( stackTrace->setParentId( protocol::Runtime::StackTraceId::create() .setId(stackTraceIdToString(externalParent.id)) - .setDebuggerId(debuggerIdToString(externalParent.debugger_id)) + .setDebuggerId(V8DebuggerId(externalParent.debugger_id).toString()) .build()); } return stackTrace; @@ -110,14 +113,47 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( } // namespace -V8StackTraceId::V8StackTraceId() : id(0), debugger_id(std::make_pair(0, 0)) {} +V8StackTraceId::V8StackTraceId() : id(0), debugger_id(V8DebuggerId().pair()) {} V8StackTraceId::V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id) : id(id), debugger_id(debugger_id) {} +V8StackTraceId::V8StackTraceId(uintptr_t id, + const std::pair<int64_t, int64_t> debugger_id, + bool should_pause) + : id(id), debugger_id(debugger_id), should_pause(should_pause) {} + +V8StackTraceId::V8StackTraceId(const StringView& json) + : id(0), debugger_id(V8DebuggerId().pair()) { + auto dict = + protocol::DictionaryValue::cast(protocol::StringUtil::parseJSON(json)); + if (!dict) return; + String16 s; + if (!dict->getString(kId, &s)) return; + bool isOk = false; + int64_t parsedId = s.toInteger64(&isOk); + if (!isOk || !parsedId) return; + if (!dict->getString(kDebuggerId, &s)) return; + V8DebuggerId debuggerId(s); + if (!debuggerId.isValid()) return; + if (!dict->getBoolean(kShouldPause, &should_pause)) return; + id = parsedId; + debugger_id = debuggerId.pair(); +} + bool V8StackTraceId::IsInvalid() const { return !id; } +std::unique_ptr<StringBuffer> V8StackTraceId::ToString() { + if (IsInvalid()) return nullptr; + auto dict = protocol::DictionaryValue::create(); + dict->setString(kId, String16::fromInteger64(id)); + dict->setString(kDebuggerId, V8DebuggerId(debugger_id).toString()); + dict->setBoolean(kShouldPause, should_pause); + String16 json = dict->toJSONString(); + return StringBufferImpl::adopt(json); +} + StackFrame::StackFrame(v8::Isolate* isolate, v8::Local<v8::StackFrame> v8Frame) : m_functionName(toProtocolString(isolate, v8Frame->GetFunctionName())), m_scriptId(String16::fromInteger(v8Frame->GetScriptId())), diff --git a/deps/v8/src/inspector/value-mirror.cc b/deps/v8/src/inspector/value-mirror.cc index 9edfbc1a21..903a5c6b02 100644 --- a/deps/v8/src/inspector/value-mirror.cc +++ b/deps/v8/src/inspector/value-mirror.cc @@ -372,8 +372,7 @@ class PrimitiveValueMirror final : public ValueMirror { .setType(m_type) .setDescription(descriptionForPrimitiveType(context, m_value)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); if (m_value->IsNull()) (*preview)->setSubtype(RemoteObject::SubtypeEnum::Null); @@ -438,8 +437,7 @@ class NumberMirror final : public ValueMirror { .setType(RemoteObject::TypeEnum::Number) .setDescription(description(&unserializable)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); } @@ -496,8 +494,7 @@ class BigIntMirror final : public ValueMirror { .setType(RemoteObject::TypeEnum::Bigint) .setDescription(descriptionForBigInt(context, m_value)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); } @@ -656,8 +653,7 @@ class FunctionMirror final : public ValueMirror { .setType(RemoteObject::TypeEnum::Function) .setDescription(descriptionForFunction(context, m_value)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); } @@ -939,7 +935,7 @@ class ObjectMirror final : public ValueMirror { v8::Local<v8::Context> context, bool forEntry, bool generatePreviewForTable, int* nameLimit, int* indexLimit, std::unique_ptr<ObjectPreview>* result) const { - auto properties = v8::base::make_unique<protocol::Array<PropertyPreview>>(); + auto properties = std::make_unique<protocol::Array<PropertyPreview>>(); std::unique_ptr<protocol::Array<EntryPreview>> entriesPreview; bool overflow = false; @@ -996,8 +992,7 @@ class ObjectMirror final : public ValueMirror { if (forEntry) { overflow = true; } else { - entriesPreview = - v8::base::make_unique<protocol::Array<EntryPreview>>(); + entriesPreview = std::make_unique<protocol::Array<EntryPreview>>(); for (const auto& entry : entries) { std::unique_ptr<ObjectPreview> valuePreview; entry.value->buildEntryPreview(context, nameLimit, indexLimit, @@ -1545,11 +1540,11 @@ std::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, const String16& subtype) { // TODO(alph): description and length retrieval should move to embedder. if (subtype == "node") { - return v8::base::make_unique<ObjectMirror>( - value, subtype, descriptionForNode(context, value)); + return std::make_unique<ObjectMirror>(value, subtype, + descriptionForNode(context, value)); } if (subtype == "error") { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Error, descriptionForError(context, value.As<v8::Object>(), ErrorType::kClient)); @@ -1562,14 +1557,14 @@ std::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, if (object->Get(context, toV8String(isolate, "length")) .ToLocal(&lengthValue)) { if (lengthValue->IsInt32()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Array, descriptionForCollection(isolate, object, lengthValue.As<v8::Int32>()->Value())); } } } - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, descriptionForObject(context->GetIsolate(), value.As<v8::Object>())); } @@ -1577,26 +1572,26 @@ std::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, v8::Local<v8::Value> value) { if (value->IsNull()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::Object); } if (value->IsBoolean()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::Boolean); } if (value->IsNumber()) { - return v8::base::make_unique<NumberMirror>(value.As<v8::Number>()); + return std::make_unique<NumberMirror>(value.As<v8::Number>()); } v8::Isolate* isolate = context->GetIsolate(); if (value->IsString()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::String); } if (value->IsBigInt()) { - return v8::base::make_unique<BigIntMirror>(value.As<v8::BigInt>()); + return std::make_unique<BigIntMirror>(value.As<v8::BigInt>()); } if (value->IsSymbol()) { - return v8::base::make_unique<SymbolMirror>(value.As<v8::Symbol>()); + return std::make_unique<SymbolMirror>(value.As<v8::Symbol>()); } auto clientSubtype = (value->IsUndefined() || value->IsObject()) ? clientFor(context)->valueSubtype(value) @@ -1606,121 +1601,121 @@ std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, return clientMirror(context, value, subtype); } if (value->IsUndefined()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::Undefined); } if (value->IsRegExp()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Regexp, descriptionForRegExp(isolate, value.As<v8::RegExp>())); } if (value->IsProxy()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Proxy, "Proxy"); } if (value->IsFunction()) { - return v8::base::make_unique<FunctionMirror>(value); + return std::make_unique<FunctionMirror>(value); } if (value->IsDate()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Date, descriptionForDate(context, value.As<v8::Date>())); } if (value->IsPromise()) { v8::Local<v8::Promise> promise = value.As<v8::Promise>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( promise, RemoteObject::SubtypeEnum::Promise, descriptionForObject(isolate, promise)); } if (value->IsNativeError()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Error, descriptionForError(context, value.As<v8::Object>(), ErrorType::kNative)); } if (value->IsMap()) { v8::Local<v8::Map> map = value.As<v8::Map>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Map, descriptionForCollection(isolate, map, map->Size())); } if (value->IsSet()) { v8::Local<v8::Set> set = value.As<v8::Set>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Set, descriptionForCollection(isolate, set, set->Size())); } if (value->IsWeakMap()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Weakmap, descriptionForObject(isolate, value.As<v8::Object>())); } if (value->IsWeakSet()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Weakset, descriptionForObject(isolate, value.As<v8::Object>())); } if (value->IsMapIterator() || value->IsSetIterator()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Iterator, descriptionForObject(isolate, value.As<v8::Object>())); } if (value->IsGeneratorObject()) { v8::Local<v8::Object> object = value.As<v8::Object>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( object, RemoteObject::SubtypeEnum::Generator, descriptionForObject(isolate, object)); } if (value->IsTypedArray()) { v8::Local<v8::TypedArray> array = value.As<v8::TypedArray>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Typedarray, descriptionForCollection(isolate, array, array->Length())); } if (value->IsArrayBuffer()) { v8::Local<v8::ArrayBuffer> buffer = value.As<v8::ArrayBuffer>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Arraybuffer, descriptionForCollection(isolate, buffer, buffer->ByteLength())); } if (value->IsSharedArrayBuffer()) { v8::Local<v8::SharedArrayBuffer> buffer = value.As<v8::SharedArrayBuffer>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Arraybuffer, descriptionForCollection(isolate, buffer, buffer->ByteLength())); } if (value->IsDataView()) { v8::Local<v8::DataView> view = value.As<v8::DataView>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Dataview, descriptionForCollection(isolate, view, view->ByteLength())); } V8InternalValueType internalType = v8InternalValueTypeFrom(context, v8::Local<v8::Object>::Cast(value)); if (value->IsArray() && internalType == V8InternalValueType::kScopeList) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, "internal#scopeList", descriptionForScopeList(value.As<v8::Array>())); } if (value->IsObject() && internalType == V8InternalValueType::kEntry) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, "internal#entry", descriptionForEntry(context, value.As<v8::Object>())); } if (value->IsObject() && internalType == V8InternalValueType::kScope) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, "internal#scope", descriptionForScope(context, value.As<v8::Object>())); } size_t length = 0; if (value->IsArray() || isArrayLike(context, value, &length)) { length = value->IsArray() ? value.As<v8::Array>()->Length() : length; - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Array, descriptionForCollection(isolate, value.As<v8::Object>(), length)); } if (value->IsObject()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, descriptionForObject(isolate, value.As<v8::Object>())); } return nullptr; diff --git a/deps/v8/src/inspector/wasm-translation.cc b/deps/v8/src/inspector/wasm-translation.cc index 4836a6bc4a..5a1526d142 100644 --- a/deps/v8/src/inspector/wasm-translation.cc +++ b/deps/v8/src/inspector/wasm-translation.cc @@ -67,15 +67,20 @@ class WasmTranslation::TranslatorImpl { column(column) {} }; - TranslatorImpl(v8::Isolate* isolate, v8::Local<v8::debug::WasmScript> script) + TranslatorImpl(v8::Isolate* isolate, WasmTranslation* translation, + v8::Local<v8::debug::WasmScript> script) : script_(isolate, script) { script_.AnnotateStrongRetainer(kGlobalScriptHandleLabel); + + ForEachFunction(script, [this, translation](String16& script_id, + int func_idx) { + translation->AddFakeScript(GetFakeScriptId(script_id, func_idx), this); + }); } - void Init(v8::Isolate* isolate, WasmTranslation* translation, - V8DebuggerAgentImpl* agent) { - // Register fake scripts for each function in this wasm module/script. - v8::Local<v8::debug::WasmScript> script = script_.Get(isolate); + template <typename Callback> + void ForEachFunction(v8::Local<v8::debug::WasmScript> script, + Callback callback) { int num_functions = script->NumFunctions(); int num_imported_functions = script->NumImportedFunctions(); DCHECK_LE(0, num_imported_functions); @@ -84,10 +89,18 @@ class WasmTranslation::TranslatorImpl { String16 script_id = String16::fromInteger(script->Id()); for (int func_idx = num_imported_functions; func_idx < num_functions; ++func_idx) { - AddFakeScript(isolate, script_id, func_idx, translation, agent); + callback(script_id, func_idx); } } + void ReportFakeScripts(v8::Isolate* isolate, WasmTranslation* translation, + V8DebuggerAgentImpl* agent) { + ForEachFunction( + script_.Get(isolate), [=](String16& script_id, int func_idx) { + ReportFakeScript(isolate, script_id, func_idx, translation, agent); + }); + } + void Translate(TransLocation* loc) { const OffsetTable& offset_table = GetOffsetTable(loc); DCHECK(!offset_table.empty()); @@ -212,9 +225,10 @@ class WasmTranslation::TranslatorImpl { return GetFakeScriptId(loc->script_id, loc->line); } - void AddFakeScript(v8::Isolate* isolate, const String16& underlyingScriptId, - int func_idx, WasmTranslation* translation, - V8DebuggerAgentImpl* agent) { + void ReportFakeScript(v8::Isolate* isolate, + const String16& underlyingScriptId, int func_idx, + WasmTranslation* translation, + V8DebuggerAgentImpl* agent) { String16 fake_script_id = GetFakeScriptId(underlyingScriptId, func_idx); String16 fake_script_url = GetFakeScriptUrl(isolate, func_idx); @@ -223,7 +237,6 @@ class WasmTranslation::TranslatorImpl { fake_script_id, std::move(fake_script_url), func_idx); - translation->AddFakeScript(fake_script->scriptId(), this); agent->didParseSource(std::move(fake_script), true); } @@ -254,6 +267,9 @@ class WasmTranslation::TranslatorImpl { // We assume to only disassemble a subset of the functions, so store them in a // map instead of an array. std::unordered_map<int, WasmSourceInformation> source_informations_; + + // Disallow copies, because our pointer is registered in translation. + DISALLOW_COPY_AND_ASSIGN(TranslatorImpl); }; constexpr char WasmTranslation::TranslatorImpl::kGlobalScriptHandleLabel[]; @@ -264,15 +280,11 @@ WasmTranslation::~WasmTranslation() { Clear(); } void WasmTranslation::AddScript(v8::Local<v8::debug::WasmScript> script, V8DebuggerAgentImpl* agent) { - std::unique_ptr<TranslatorImpl> impl; - impl.reset(new TranslatorImpl(isolate_, script)); - DCHECK(impl); - auto inserted = - wasm_translators_.insert(std::make_pair(script->Id(), std::move(impl))); - // Check that no mapping for this script id existed before. - DCHECK(inserted.second); - // impl has been moved, use the returned iterator to call Init. - inserted.first->second->Init(isolate_, this, agent); + auto& impl = wasm_translators_[script->Id()]; + if (impl == nullptr) { + impl = std::make_unique<TranslatorImpl>(isolate_, this, script); + } + impl->ReportFakeScripts(isolate_, this, agent); } void WasmTranslation::Clear() { diff --git a/deps/v8/src/inspector/wasm-translation.h b/deps/v8/src/inspector/wasm-translation.h index 2d41822e59..a19aa85205 100644 --- a/deps/v8/src/inspector/wasm-translation.h +++ b/deps/v8/src/inspector/wasm-translation.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_WASM_TRANSLATION_H_ #define V8_INSPECTOR_WASM_TRANSLATION_H_ +#include <memory> #include <unordered_map> #include "include/v8.h" |