Chromium Code Reviews| Index: src/inspector/v8-debugger-agent-impl.cc |
| diff --git a/src/inspector/v8-debugger-agent-impl.cc b/src/inspector/v8-debugger-agent-impl.cc |
| index 664c2ed095a0545d2ee655c3b15178e21e056f3f..8cb20a220be7390909472818accf80b015f33bc0 100644 |
| --- a/src/inspector/v8-debugger-agent-impl.cc |
| +++ b/src/inspector/v8-debugger-agent-impl.cc |
| @@ -50,6 +50,8 @@ static const char isRegex[] = "isRegex"; |
| static const char lineNumber[] = "lineNumber"; |
| static const char columnNumber[] = "columnNumber"; |
| static const char condition[] = "condition"; |
| +static const char sourceLineHint[] = "sourceLineHint"; |
| + |
| static const char skipAllPauses[] = "skipAllPauses"; |
| } // namespace DebuggerAgentState |
| @@ -58,6 +60,8 @@ static const char kBacktraceObjectGroup[] = "backtrace"; |
| static const char kDebuggerNotEnabled[] = "Debugger agent is not enabled"; |
| static const char kDebuggerNotPaused[] = |
| "Can only perform operation while paused."; |
| +static const int kSourceLineHintToCheck = 32; |
| +static const int kSourceLineHintMaxLength = 128; |
| namespace { |
| @@ -241,13 +245,15 @@ Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { |
| static std::unique_ptr<protocol::DictionaryValue> |
| buildObjectForBreakpointCookie(const String16& url, int lineNumber, |
| int columnNumber, const String16& condition, |
| - bool isRegex) { |
| + bool isRegex, const String16& sourceLineHint) { |
| std::unique_ptr<protocol::DictionaryValue> breakpointObject = |
| protocol::DictionaryValue::create(); |
| breakpointObject->setString(DebuggerAgentState::url, url); |
| breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); |
| breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); |
| breakpointObject->setString(DebuggerAgentState::condition, condition); |
| + breakpointObject->setString(DebuggerAgentState::sourceLineHint, |
| + sourceLineHint); |
| breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex); |
| return breakpointObject; |
| } |
| @@ -295,20 +301,24 @@ Response V8DebuggerAgentImpl::setBreakpointByUrl( |
| if (breakpointsCookie->get(breakpointId)) |
| return Response::Error("Breakpoint at specified location already exists."); |
| - breakpointsCookie->setObject( |
| - breakpointId, buildObjectForBreakpointCookie( |
| - url, lineNumber, columnNumber, condition, isRegex)); |
| - |
| ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition); |
| + String16 sourceLineHint; |
| for (const auto& script : m_scripts) { |
| if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) |
| continue; |
| breakpoint.script_id = script.first; |
| - std::unique_ptr<protocol::Debugger::Location> location = |
| - resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); |
| + sourceLineHint = |
| + script.second->lineAt(lineNumber, kSourceLineHintMaxLength); |
| + std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( |
| + breakpointId, breakpoint, UserBreakpointSource, String16()); |
| if (location) (*locations)->addItem(std::move(location)); |
| } |
| + breakpointsCookie->setObject( |
| + breakpointId, |
| + buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, |
| + isRegex, sourceLineHint)); |
| + |
| *outBreakpointId = breakpointId; |
| return Response::OK(); |
| } |
| @@ -327,8 +337,8 @@ Response V8DebuggerAgentImpl::setBreakpoint( |
| m_breakpointIdToDebuggerBreakpointIds.end()) { |
| return Response::Error("Breakpoint at specified location already exists."); |
| } |
| - *actualLocation = |
| - resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); |
| + *actualLocation = resolveBreakpoint(breakpointId, breakpoint, |
| + UserBreakpointSource, String16()); |
| if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); |
| *outBreakpointId = breakpointId; |
| return Response::OK(); |
| @@ -455,10 +465,30 @@ bool V8DebuggerAgentImpl::isFunctionBlackboxed(const String16& scriptId, |
| std::distance(ranges.begin(), itStartRange) % 2; |
| } |
| +namespace { |
| +bool checkLine(V8DebuggerScript* script, int lineNumber, const String16& hint) { |
| + if (lineNumber < script->startLine() || lineNumber > script->endLine()) |
| + return false; |
| + return script->lineAt(lineNumber, kSourceLineHintMaxLength) == hint; |
| +} |
| + |
| +int ajustLineNumber(V8DebuggerScript* script, int lineNumber, |
|
alph
2017/02/08 02:02:08
adjust
|
| + const String16& hint) { |
| + if (hint.isEmpty()) return lineNumber; |
| + if (checkLine(script, lineNumber, hint)) return lineNumber; |
| + for (int i = 1; i < kSourceLineHintToCheck / 2; ++i) { |
| + if (checkLine(script, lineNumber + i, hint)) return lineNumber + i; |
| + if (checkLine(script, lineNumber - i, hint)) return lineNumber - i; |
| + } |
| + return lineNumber; |
| +} |
| +} // namespace |
| + |
| std::unique_ptr<protocol::Debugger::Location> |
| V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, |
| const ScriptBreakpoint& breakpoint, |
| - BreakpointSource source) { |
| + BreakpointSource source, |
| + const String16& sourceLineHint) { |
| v8::HandleScope handles(m_isolate); |
| DCHECK(enabled()); |
| // FIXME: remove these checks once crbug.com/520702 is resolved. |
| @@ -466,12 +496,17 @@ V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, |
| CHECK(!breakpoint.script_id.isEmpty()); |
| ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id); |
| if (scriptIterator == m_scripts.end()) return nullptr; |
| - if (breakpoint.line_number < scriptIterator->second->startLine() || |
| - scriptIterator->second->endLine() < breakpoint.line_number) |
| + |
| + V8DebuggerScript* script = scriptIterator->second.get(); |
| + ScriptBreakpoint translatedBreakpoint = breakpoint; |
| + translatedBreakpoint.line_number = |
| + ajustLineNumber(script, translatedBreakpoint.line_number, sourceLineHint); |
| + if (translatedBreakpoint.line_number < script->startLine() || |
| + script->endLine() < translatedBreakpoint.line_number) { |
| return nullptr; |
| + } |
| // Translate from protocol location to v8 location for the debugger. |
| - ScriptBreakpoint translatedBreakpoint = breakpoint; |
| m_debugger->wasmTranslation()->TranslateProtocolLocationToWasmScriptLocation( |
| &translatedBreakpoint.script_id, &translatedBreakpoint.line_number, |
| &translatedBreakpoint.column_number); |
| @@ -506,7 +541,7 @@ Response V8DebuggerAgentImpl::searchInContent( |
| return Response::Error("No script for id: " + scriptId); |
| std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = |
| - searchInTextByLinesImpl(m_session, it->second->source(m_isolate), query, |
| + searchInTextByLinesImpl(m_session, it->second->source(), query, |
| optionalCaseSensitive.fromMaybe(false), |
| optionalIsRegex.fromMaybe(false)); |
| *results = protocol::Array<protocol::Debugger::SearchMatch>::create(); |
| @@ -585,7 +620,7 @@ Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId, |
| if (it == m_scripts.end()) |
| return Response::Error("No script for id: " + scriptId); |
| v8::HandleScope handles(m_isolate); |
| - *scriptSource = it->second->source(m_isolate); |
| + *scriptSource = it->second->source(); |
| return Response::OK(); |
| } |
| @@ -979,7 +1014,7 @@ bool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPaused(); } |
| void V8DebuggerAgentImpl::didParseSource( |
| std::unique_ptr<V8DebuggerScript> script, bool success) { |
| v8::HandleScope handles(m_isolate); |
| - String16 scriptSource = script->source(m_isolate); |
| + String16 scriptSource = script->source(); |
| if (!success) script->setSourceURL(findSourceURL(scriptSource, false)); |
| if (!success) |
| script->setSourceMappingURL(findSourceMapURL(scriptSource, false)); |
| @@ -1022,14 +1057,14 @@ void V8DebuggerAgentImpl::didParseSource( |
| m_frontend.scriptParsed( |
| scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), |
| scriptRef->endLine(), scriptRef->endColumn(), contextId, |
| - scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam), |
| + scriptRef->hash(), std::move(executionContextAuxDataParam), |
| isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam, |
| isModuleParam); |
| else |
| m_frontend.scriptFailedToParse( |
| scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), |
| scriptRef->endLine(), scriptRef->endColumn(), contextId, |
| - scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam), |
| + scriptRef->hash(), std::move(executionContextAuxDataParam), |
| std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam); |
| if (scriptURL.isEmpty() || !success) return; |
| @@ -1045,6 +1080,7 @@ void V8DebuggerAgentImpl::didParseSource( |
| bool isRegex; |
| breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); |
| String16 url; |
| + String16 sourceLineHint; |
| breakpointObject->getString(DebuggerAgentState::url, &url); |
| if (!matches(m_inspector, scriptURL, url, isRegex)) continue; |
| ScriptBreakpoint breakpoint; |
| @@ -1055,8 +1091,10 @@ void V8DebuggerAgentImpl::didParseSource( |
| &breakpoint.column_number); |
| breakpointObject->getString(DebuggerAgentState::condition, |
| &breakpoint.condition); |
| - std::unique_ptr<protocol::Debugger::Location> location = |
| - resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource); |
| + breakpointObject->getString(DebuggerAgentState::sourceLineHint, |
| + &sourceLineHint); |
| + std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint( |
| + cookie.first, breakpoint, UserBreakpointSource, sourceLineHint); |
| if (location) |
| m_frontend.breakpointResolved(cookie.first, std::move(location)); |
| } |
| @@ -1163,7 +1201,7 @@ void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, |
| const String16& condition) { |
| ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition); |
| String16 breakpointId = generateBreakpointId(breakpoint, source); |
| - resolveBreakpoint(breakpointId, breakpoint, source); |
| + resolveBreakpoint(breakpointId, breakpoint, source, String16()); |
| } |
| void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, |