- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / InspectorDebuggerAgent.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010-2011 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "core/inspector/InspectorDebuggerAgent.h"
32 #include "core/inspector/JavaScriptCallFrame.h"
33
34 #include "InspectorFrontend.h"
35 #include "bindings/v8/ScriptDebugServer.h"
36 #include "bindings/v8/ScriptObject.h"
37 #include "bindings/v8/ScriptSourceCode.h"
38 #include "core/fetch/Resource.h"
39 #include "core/inspector/ContentSearchUtils.h"
40 #include "core/inspector/InjectedScript.h"
41 #include "core/inspector/InjectedScriptManager.h"
42 #include "core/inspector/InspectorPageAgent.h"
43 #include "core/inspector/InspectorState.h"
44 #include "core/inspector/InstrumentingAgents.h"
45 #include "core/inspector/ScriptArguments.h"
46 #include "core/inspector/ScriptCallStack.h"
47 #include "core/platform/text/RegularExpression.h"
48 #include "platform/JSONValues.h"
49 #include "wtf/text/WTFString.h"
50
51 using WebCore::TypeBuilder::Array;
52 using WebCore::TypeBuilder::Debugger::FunctionDetails;
53 using WebCore::TypeBuilder::Debugger::ScriptId;
54 using WebCore::TypeBuilder::Runtime::RemoteObject;
55
56 namespace WebCore {
57
58 namespace DebuggerAgentState {
59 static const char debuggerEnabled[] = "debuggerEnabled";
60 static const char javaScriptBreakpoints[] = "javaScriptBreakopints";
61 static const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
62
63 // Breakpoint properties.
64 static const char url[] = "url";
65 static const char isRegex[] = "isRegex";
66 static const char lineNumber[] = "lineNumber";
67 static const char columnNumber[] = "columnNumber";
68 static const char condition[] = "condition";
69 static const char isAnti[] = "isAnti";
70 static const char skipStackPattern[] = "skipStackPattern";
71 static const char skipAllPauses[] = "skipAllPauses";
72 static const char skipAllPausesExpiresOnReload[] = "skipAllPausesExpiresOnReload";
73
74 };
75
76 static const int numberOfStepsBeforeStepOut = 10;
77
78 const char InspectorDebuggerAgent::backtraceObjectGroup[] = "backtrace";
79
80 static String breakpointIdSuffix(InspectorDebuggerAgent::BreakpointSource source)
81 {
82     switch (source) {
83     case InspectorDebuggerAgent::UserBreakpointSource:
84         break;
85     case InspectorDebuggerAgent::DebugCommandBreakpointSource:
86         return ":debug";
87     case InspectorDebuggerAgent::MonitorCommandBreakpointSource:
88         return ":monitor";
89     }
90     return String();
91 }
92
93 static String generateBreakpointId(const String& scriptId, int lineNumber, int columnNumber, InspectorDebuggerAgent::BreakpointSource source)
94 {
95     return scriptId + ':' + String::number(lineNumber) + ':' + String::number(columnNumber) + breakpointIdSuffix(source);
96 }
97
98 InspectorDebuggerAgent::InspectorDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
99     : InspectorBaseAgent<InspectorDebuggerAgent>("Debugger", instrumentingAgents, inspectorState)
100     , m_injectedScriptManager(injectedScriptManager)
101     , m_frontend(0)
102     , m_pausedScriptState(0)
103     , m_javaScriptPauseScheduled(false)
104     , m_listener(0)
105     , m_skipStepInCount(numberOfStepsBeforeStepOut)
106     , m_skipAllPauses(false)
107 {
108     // FIXME: make breakReason optional so that there was no need to init it with "other".
109     clearBreakDetails();
110     m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, ScriptDebugServer::DontPauseOnExceptions);
111 }
112
113 InspectorDebuggerAgent::~InspectorDebuggerAgent()
114 {
115     ASSERT(!m_instrumentingAgents->inspectorDebuggerAgent());
116 }
117
118 void InspectorDebuggerAgent::enable()
119 {
120     m_instrumentingAgents->setInspectorDebuggerAgent(this);
121
122     // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends
123     scriptDebugServer().setBreakpointsActivated(true);
124     startListeningScriptDebugServer();
125
126     if (m_listener)
127         m_listener->debuggerWasEnabled();
128 }
129
130 void InspectorDebuggerAgent::disable()
131 {
132     m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, JSONObject::create());
133     m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, ScriptDebugServer::DontPauseOnExceptions);
134     m_state->setString(DebuggerAgentState::skipStackPattern, "");
135     m_instrumentingAgents->setInspectorDebuggerAgent(0);
136
137     stopListeningScriptDebugServer();
138     scriptDebugServer().clearBreakpoints();
139     scriptDebugServer().clearCompiledScripts();
140     clear();
141
142     if (m_listener)
143         m_listener->debuggerWasDisabled();
144
145     m_skipAllPauses = false;
146 }
147
148 bool InspectorDebuggerAgent::enabled()
149 {
150     return m_state->getBoolean(DebuggerAgentState::debuggerEnabled);
151 }
152
153 void InspectorDebuggerAgent::enable(ErrorString*)
154 {
155     if (enabled())
156         return;
157
158     enable();
159     m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
160
161     ASSERT(m_frontend);
162 }
163
164 void InspectorDebuggerAgent::disable(ErrorString*)
165 {
166     if (!enabled())
167         return;
168
169     disable();
170     m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
171 }
172
173 static PassOwnPtr<RegularExpression> compileSkipCallFramePattern(String patternText)
174 {
175     if (patternText.isEmpty())
176         return nullptr;
177     OwnPtr<RegularExpression> result = adoptPtr(new RegularExpression(patternText, TextCaseSensitive));
178     if (!result->isValid())
179         result.clear();
180     return result.release();
181 }
182
183 void InspectorDebuggerAgent::restore()
184 {
185     if (enabled()) {
186         m_frontend->globalObjectCleared();
187         enable();
188         long pauseState = m_state->getLong(DebuggerAgentState::pauseOnExceptionsState);
189         String error;
190         setPauseOnExceptionsImpl(&error, pauseState);
191         m_cachedSkipStackRegExp = compileSkipCallFramePattern(m_state->getString(DebuggerAgentState::skipStackPattern));
192         m_skipAllPauses = m_state->getBoolean(DebuggerAgentState::skipAllPauses);
193         if (m_skipAllPauses && m_state->getBoolean(DebuggerAgentState::skipAllPausesExpiresOnReload)) {
194             m_skipAllPauses = false;
195             m_state->setBoolean(DebuggerAgentState::skipAllPauses, false);
196         }
197     }
198 }
199
200 void InspectorDebuggerAgent::setFrontend(InspectorFrontend* frontend)
201 {
202     m_frontend = frontend->debugger();
203 }
204
205 void InspectorDebuggerAgent::clearFrontend()
206 {
207     m_frontend = 0;
208
209     if (!enabled())
210         return;
211
212     disable();
213
214     // FIXME: due to m_state->mute() hack in InspectorController, debuggerEnabled is actually set to false only
215     // in InspectorState, but not in cookie. That's why after navigation debuggerEnabled will be true,
216     // but after front-end re-open it will still be false.
217     m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
218 }
219
220 void InspectorDebuggerAgent::setBreakpointsActive(ErrorString*, bool active)
221 {
222     scriptDebugServer().setBreakpointsActivated(active);
223 }
224
225 void InspectorDebuggerAgent::setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload)
226 {
227     m_skipAllPauses = skipped;
228     bool untilReloadValue = untilReload && *untilReload;
229     m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
230     m_state->setBoolean(DebuggerAgentState::skipAllPausesExpiresOnReload, untilReloadValue);
231 }
232
233 void InspectorDebuggerAgent::pageDidCommitLoad()
234 {
235     if (m_state->getBoolean(DebuggerAgentState::skipAllPausesExpiresOnReload)) {
236         m_skipAllPauses = false;
237         m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
238     }
239 }
240
241 bool InspectorDebuggerAgent::isPaused()
242 {
243     return scriptDebugServer().isPaused();
244 }
245
246 bool InspectorDebuggerAgent::runningNestedMessageLoop()
247 {
248     return scriptDebugServer().runningNestedMessageLoop();
249 }
250
251 void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type)
252 {
253     if (source == ConsoleAPIMessageSource && type == AssertMessageType && scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions)
254         breakProgram(InspectorFrontend::Debugger::Reason::Assert, 0);
255 }
256
257 void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long)
258 {
259     addMessageToConsole(source, type);
260 }
261
262 void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long)
263 {
264     addMessageToConsole(source, type);
265 }
266
267 String InspectorDebuggerAgent::preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
268 {
269     return scriptDebugServer().preprocessEventListener(frame, source, url, functionName);
270 }
271
272 PassOwnPtr<ScriptSourceCode> InspectorDebuggerAgent::preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
273 {
274     return scriptDebugServer().preprocess(frame, sourceCode);
275 }
276
277 static PassRefPtr<JSONObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, bool isRegex, bool isAnti)
278 {
279     RefPtr<JSONObject> breakpointObject = JSONObject::create();
280     breakpointObject->setString(DebuggerAgentState::url, url);
281     breakpointObject->setNumber(DebuggerAgentState::lineNumber, lineNumber);
282     breakpointObject->setNumber(DebuggerAgentState::columnNumber, columnNumber);
283     breakpointObject->setString(DebuggerAgentState::condition, condition);
284     breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex);
285     breakpointObject->setBoolean(DebuggerAgentState::isAnti, isAnti);
286     return breakpointObject;
287 }
288
289 static bool matches(const String& url, const String& pattern, bool isRegex)
290 {
291     if (isRegex) {
292         RegularExpression regex(pattern, TextCaseSensitive);
293         return regex.match(url) != -1;
294     }
295     return url == pattern;
296 }
297
298 void InspectorDebuggerAgent::setBreakpointByUrl(ErrorString* errorString, int lineNumber, const String* const optionalURL, const String* const optionalURLRegex, const int* const optionalColumnNumber, const String* const optionalCondition, const bool* isAntiBreakpoint, TypeBuilder::Debugger::BreakpointId* outBreakpointId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations)
299 {
300     locations = Array<TypeBuilder::Debugger::Location>::create();
301     if (!optionalURL == !optionalURLRegex) {
302         *errorString = "Either url or urlRegex must be specified.";
303         return;
304     }
305
306     bool isAntiBreakpointValue = isAntiBreakpoint && *isAntiBreakpoint;
307
308     String url = optionalURL ? *optionalURL : *optionalURLRegex;
309     int columnNumber;
310     if (optionalColumnNumber) {
311         columnNumber = *optionalColumnNumber;
312         if (columnNumber < 0) {
313             *errorString = "Incorrect column number";
314             return;
315         }
316     } else {
317         columnNumber = isAntiBreakpointValue ? -1 : 0;
318     }
319     String condition = optionalCondition ? *optionalCondition : "";
320     bool isRegex = optionalURLRegex;
321
322     String breakpointId = (isRegex ? "/" + url + "/" : url) + ':' + String::number(lineNumber) + ':' + String::number(columnNumber);
323     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
324     if (breakpointsCookie->find(breakpointId) != breakpointsCookie->end()) {
325         *errorString = "Breakpoint at specified location already exists.";
326         return;
327     }
328
329     breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, isRegex, isAntiBreakpointValue));
330     m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie);
331
332     if (!isAntiBreakpointValue) {
333         ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
334         for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
335             if (!matches(it->value.url, url, isRegex))
336                 continue;
337             RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(breakpointId, it->key, breakpoint, UserBreakpointSource);
338             if (location)
339                 locations->addItem(location);
340         }
341     }
342     *outBreakpointId = breakpointId;
343 }
344
345 static bool parseLocation(ErrorString* errorString, PassRefPtr<JSONObject> location, String* scriptId, int* lineNumber, int* columnNumber)
346 {
347     if (!location->getString("scriptId", scriptId) || !location->getNumber("lineNumber", lineNumber)) {
348         // FIXME: replace with input validation.
349         *errorString = "scriptId and lineNumber are required.";
350         return false;
351     }
352     *columnNumber = 0;
353     location->getNumber("columnNumber", columnNumber);
354     return true;
355 }
356
357 void InspectorDebuggerAgent::setBreakpoint(ErrorString* errorString, const RefPtr<JSONObject>& location, const String* const optionalCondition, TypeBuilder::Debugger::BreakpointId* outBreakpointId, RefPtr<TypeBuilder::Debugger::Location>& actualLocation)
358 {
359     String scriptId;
360     int lineNumber;
361     int columnNumber;
362
363     if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNumber))
364         return;
365
366     String condition = optionalCondition ? *optionalCondition : emptyString();
367
368     String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumber, UserBreakpointSource);
369     if (m_breakpointIdToDebugServerBreakpointIds.find(breakpointId) != m_breakpointIdToDebugServerBreakpointIds.end()) {
370         *errorString = "Breakpoint at specified location already exists.";
371         return;
372     }
373     ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
374     actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint, UserBreakpointSource);
375     if (actualLocation)
376         *outBreakpointId = breakpointId;
377     else
378         *errorString = "Could not resolve breakpoint";
379 }
380
381 void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakpointId)
382 {
383     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
384     JSONObject::iterator it = breakpointsCookie->find(breakpointId);
385     bool isAntibreakpoint = false;
386     if (it != breakpointsCookie->end()) {
387         RefPtr<JSONObject> breakpointObject = it->value->asObject();
388         breakpointObject->getBoolean(DebuggerAgentState::isAnti, &isAntibreakpoint);
389         breakpointsCookie->remove(breakpointId);
390         m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie);
391     }
392
393     if (!isAntibreakpoint)
394         removeBreakpoint(breakpointId);
395 }
396
397 void InspectorDebuggerAgent::removeBreakpoint(const String& breakpointId)
398 {
399     BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
400     if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
401         return;
402     for (size_t i = 0; i < debugServerBreakpointIdsIterator->value.size(); ++i) {
403         const String& debugServerBreakpointId = debugServerBreakpointIdsIterator->value[i];
404         scriptDebugServer().removeBreakpoint(debugServerBreakpointId);
405         m_serverBreakpoints.remove(debugServerBreakpointId);
406     }
407     m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator);
408 }
409
410 void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt)
411 {
412     bool interstateLocation = interstateLocationOpt ? *interstateLocationOpt : false;
413     if (!m_continueToLocationBreakpointId.isEmpty()) {
414         scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
415         m_continueToLocationBreakpointId = "";
416     }
417
418     String scriptId;
419     int lineNumber;
420     int columnNumber;
421
422     if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNumber))
423         return;
424
425     ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
426     m_continueToLocationBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &lineNumber, &columnNumber, interstateLocation);
427     resume(errorString);
428 }
429
430 void InspectorDebuggerAgent::getStepInPositions(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::Location> >& positions)
431 {
432     if (!isPaused() || m_currentCallStack.isNull()) {
433         *errorString = "Attempt to access callframe when debugger is not on pause";
434         return;
435     }
436     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
437     if (injectedScript.hasNoValue()) {
438         *errorString = "Inspected frame has gone";
439         return;
440     }
441
442     injectedScript.getStepInPositions(errorString, m_currentCallStack, callFrameId, positions);
443 }
444
445 void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& callFrames)
446 {
447     if (!assertPaused(errorString))
448         return;
449     scriptDebugServer().updateCallStack(&m_currentCallStack);
450     callFrames = currentCallFrames();
451 }
452
453 String InspectorDebuggerAgent::scriptURL(JavaScriptCallFrame* frame)
454 {
455     String scriptIdString = String::number(frame->sourceID());
456     ScriptsMap::iterator it = m_scripts.find(scriptIdString);
457     if (it == m_scripts.end())
458         return String();
459     return it->value.url;
460 }
461
462 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptionPause(RefPtr<JavaScriptCallFrame>& topFrame)
463 {
464     if (m_skipAllPauses)
465         return ScriptDebugListener::Continue;
466
467     String topFrameScriptUrl = scriptURL(topFrame.get());
468     if (m_cachedSkipStackRegExp && !topFrameScriptUrl.isEmpty() && m_cachedSkipStackRegExp->match(topFrameScriptUrl) != -1)
469         return ScriptDebugListener::Continue;
470
471     // Prepare top frame parameters;
472     int topFrameLineNumber = topFrame->line();
473     int topFrameColumnNumber = topFrame->column();
474
475     // Match against breakpoints.
476     if (topFrameScriptUrl.isEmpty())
477         return ScriptDebugListener::NoSkip;
478
479     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
480     for (JSONObject::iterator it = breakpointsCookie->begin(); it != breakpointsCookie->end(); ++it) {
481         RefPtr<JSONObject> breakpointObject = it->value->asObject();
482         bool isAntibreakpoint;
483         breakpointObject->getBoolean(DebuggerAgentState::isAnti, &isAntibreakpoint);
484         if (!isAntibreakpoint)
485             continue;
486
487         int breakLineNumber;
488         breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakLineNumber);
489         int breakColumnNumber;
490         breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakColumnNumber);
491
492         if (breakLineNumber != topFrameLineNumber)
493             continue;
494
495         if (breakColumnNumber != -1 && breakColumnNumber != topFrameColumnNumber)
496             continue;
497
498         bool isRegex;
499         breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex);
500         String url;
501         breakpointObject->getString(DebuggerAgentState::url, &url);
502         if (!matches(topFrameScriptUrl, url, isRegex))
503             continue;
504
505         return ScriptDebugListener::Continue;
506     }
507
508     return ScriptDebugListener::NoSkip;
509 }
510
511 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipBreakpointPause(RefPtr<JavaScriptCallFrame>& topFrame)
512 {
513     if (m_skipAllPauses)
514         return ScriptDebugListener::Continue;
515     return ScriptDebugListener::NoSkip;
516 }
517
518 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPause(RefPtr<JavaScriptCallFrame>& topFrame)
519 {
520     if (m_skipAllPauses)
521         return ScriptDebugListener::Continue;
522
523     if (m_cachedSkipStackRegExp) {
524         String scriptUrl = scriptURL(topFrame.get());
525         if (!scriptUrl.isEmpty() && m_cachedSkipStackRegExp->match(scriptUrl) != -1) {
526             if (m_skipStepInCount > 0) {
527                 --m_skipStepInCount;
528                 return ScriptDebugListener::StepInto;
529             }
530             return ScriptDebugListener::StepOut;
531         }
532     }
533     return ScriptDebugListener::NoSkip;
534 }
535
536 PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint& breakpoint, BreakpointSource source)
537 {
538     ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
539     if (scriptIterator == m_scripts.end())
540         return 0;
541     Script& script = scriptIterator->value;
542     if (breakpoint.lineNumber < script.startLine || script.endLine < breakpoint.lineNumber)
543         return 0;
544
545     int actualLineNumber;
546     int actualColumnNumber;
547     String debugServerBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &actualLineNumber, &actualColumnNumber, false);
548     if (debugServerBreakpointId.isEmpty())
549         return 0;
550
551     m_serverBreakpoints.set(debugServerBreakpointId, std::make_pair(breakpointId, source));
552
553     BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
554     if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
555         debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).iterator;
556     debugServerBreakpointIdsIterator->value.append(debugServerBreakpointId);
557
558     RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
559         .setScriptId(scriptId)
560         .setLineNumber(actualLineNumber);
561     location->setColumnNumber(actualColumnNumber);
562     return location;
563 }
564
565 static PassRefPtr<JSONObject> scriptToInspectorObject(ScriptObject scriptObject)
566 {
567     if (scriptObject.hasNoValue())
568         return 0;
569     RefPtr<JSONValue> value = scriptObject.toJSONValue(scriptObject.scriptState());
570     if (!value)
571         return 0;
572     return value->asObject();
573 }
574
575 void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& scriptId, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Array<WebCore::TypeBuilder::Page::SearchMatch> >& results)
576 {
577     bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
578     bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
579
580     ScriptsMap::iterator it = m_scripts.find(scriptId);
581     if (it != m_scripts.end())
582         results = ContentSearchUtils::searchInTextByLines(it->value.source, query, caseSensitive, isRegex);
583     else
584         *error = "No script for id: " + scriptId;
585 }
586
587 void InspectorDebuggerAgent::setScriptSource(ErrorString* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result)
588 {
589     bool previewOnly = preview && *preview;
590     ScriptObject resultObject;
591     if (!scriptDebugServer().setScriptSource(scriptId, newContent, previewOnly, error, errorData, &m_currentCallStack, &resultObject))
592         return;
593     newCallFrames = currentCallFrames();
594     RefPtr<JSONObject> object = scriptToInspectorObject(resultObject);
595     if (object)
596         result = object;
597 }
598 void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result)
599 {
600     if (!isPaused() || m_currentCallStack.isNull()) {
601         *errorString = "Attempt to access callframe when debugger is not on pause";
602         return;
603     }
604     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
605     if (injectedScript.hasNoValue()) {
606         *errorString = "Inspected frame has gone";
607         return;
608     }
609
610     injectedScript.restartFrame(errorString, m_currentCallStack, callFrameId, &result);
611     scriptDebugServer().updateCallStack(&m_currentCallStack);
612     newCallFrames = currentCallFrames();
613 }
614
615 void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& scriptId, String* scriptSource)
616 {
617     ScriptsMap::iterator it = m_scripts.find(scriptId);
618     if (it != m_scripts.end())
619         *scriptSource = it->value.source;
620     else
621         *error = "No script for id: " + scriptId;
622 }
623
624 void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>& details)
625 {
626     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(functionId);
627     if (injectedScript.hasNoValue()) {
628         *errorString = "Function object id is obsolete";
629         return;
630     }
631     injectedScript.getFunctionDetails(errorString, functionId, &details);
632 }
633
634 void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data)
635 {
636     if (m_javaScriptPauseScheduled)
637         return;
638     m_breakReason = breakReason;
639     m_breakAuxData = data;
640     scriptDebugServer().setPauseOnNextStatement(true);
641 }
642
643 void InspectorDebuggerAgent::cancelPauseOnNextStatement()
644 {
645     if (m_javaScriptPauseScheduled)
646         return;
647     clearBreakDetails();
648     scriptDebugServer().setPauseOnNextStatement(false);
649 }
650
651 void InspectorDebuggerAgent::didFireTimer()
652 {
653     cancelPauseOnNextStatement();
654 }
655
656 void InspectorDebuggerAgent::didHandleEvent()
657 {
658     cancelPauseOnNextStatement();
659 }
660
661 void InspectorDebuggerAgent::pause(ErrorString*)
662 {
663     if (m_javaScriptPauseScheduled)
664         return;
665     clearBreakDetails();
666     scriptDebugServer().setPauseOnNextStatement(true);
667     m_javaScriptPauseScheduled = true;
668 }
669
670 void InspectorDebuggerAgent::resume(ErrorString* errorString)
671 {
672     if (!assertPaused(errorString))
673         return;
674     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
675     scriptDebugServer().continueProgram();
676 }
677
678 ScriptValue InspectorDebuggerAgent::resolveCallFrame(ErrorString* errorString, const String* callFrameId)
679 {
680     if (!callFrameId)
681         return ScriptValue();
682     if (!isPaused() || m_currentCallStack.isNull()) {
683         *errorString = "Attempt to access callframe when debugger is not on pause";
684         return ScriptValue();
685     }
686     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*callFrameId);
687     if (injectedScript.hasNoValue()) {
688         *errorString = "Inspected frame has gone";
689         return ScriptValue();
690     }
691     return injectedScript.findCallFrameById(errorString, m_currentCallStack, *callFrameId);
692 }
693
694 void InspectorDebuggerAgent::stepOver(ErrorString* errorString, const String* callFrameId)
695 {
696     if (!assertPaused(errorString))
697         return;
698     ScriptValue frame = resolveCallFrame(errorString, callFrameId);
699     if (!errorString->isEmpty())
700         return;
701     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
702     scriptDebugServer().stepOverStatement(frame);
703 }
704
705 void InspectorDebuggerAgent::stepInto(ErrorString* errorString)
706 {
707     if (!assertPaused(errorString))
708         return;
709     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
710     scriptDebugServer().stepIntoStatement();
711     if (m_listener)
712         m_listener->stepInto();
713 }
714
715 void InspectorDebuggerAgent::stepOut(ErrorString* errorString, const String* callFrameId)
716 {
717     if (!assertPaused(errorString))
718         return;
719     ScriptValue frame = resolveCallFrame(errorString, callFrameId);
720     if (!errorString->isEmpty())
721         return;
722     m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
723     scriptDebugServer().stepOutOfFunction(frame);
724 }
725
726 void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString* errorString, const String& stringPauseState)
727 {
728     ScriptDebugServer::PauseOnExceptionsState pauseState;
729     if (stringPauseState == "none")
730         pauseState = ScriptDebugServer::DontPauseOnExceptions;
731     else if (stringPauseState == "all")
732         pauseState = ScriptDebugServer::PauseOnAllExceptions;
733     else if (stringPauseState == "uncaught")
734         pauseState = ScriptDebugServer::PauseOnUncaughtExceptions;
735     else {
736         *errorString = "Unknown pause on exceptions mode: " + stringPauseState;
737         return;
738     }
739     setPauseOnExceptionsImpl(errorString, pauseState);
740 }
741
742 void InspectorDebuggerAgent::setPauseOnExceptionsImpl(ErrorString* errorString, int pauseState)
743 {
744     scriptDebugServer().setPauseOnExceptionsState(static_cast<ScriptDebugServer::PauseOnExceptionsState>(pauseState));
745     if (scriptDebugServer().pauseOnExceptionsState() != pauseState)
746         *errorString = "Internal error. Could not change pause on exceptions state";
747     else
748         m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, pauseState);
749 }
750
751 void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
752 {
753     if (!isPaused() || m_currentCallStack.isNull()) {
754         *errorString = "Attempt to access callframe when debugger is not on pause";
755         return;
756     }
757     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
758     if (injectedScript.hasNoValue()) {
759         *errorString = "Inspected frame has gone";
760         return;
761     }
762
763     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState();
764     if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) {
765         if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptions)
766             scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions);
767         muteConsole();
768     }
769
770     injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : false, &result, wasThrown);
771
772     if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) {
773         unmuteConsole();
774         if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState)
775             scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState);
776     }
777 }
778
779 void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<ScriptId>* scriptId, TypeBuilder::OptOutput<String>* syntaxErrorMessage)
780 {
781     InjectedScript injectedScript = injectedScriptForEval(errorString, 0);
782     if (injectedScript.hasNoValue()) {
783         *errorString = "Inspected frame has gone";
784         return;
785     }
786
787     String scriptIdValue;
788     String exceptionMessage;
789     scriptDebugServer().compileScript(injectedScript.scriptState(), expression, sourceURL, &scriptIdValue, &exceptionMessage);
790     if (!scriptIdValue && !exceptionMessage) {
791         *errorString = "Script compilation failed";
792         return;
793     }
794     *syntaxErrorMessage = exceptionMessage;
795     *scriptId = scriptIdValue;
796 }
797
798 void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
799 {
800     InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
801     if (injectedScript.hasNoValue()) {
802         *errorString = "Inspected frame has gone";
803         return;
804     }
805
806     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState();
807     if (doNotPauseOnExceptionsAndMuteConsole && *doNotPauseOnExceptionsAndMuteConsole) {
808         if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptions)
809             scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions);
810         muteConsole();
811     }
812
813     ScriptValue value;
814     bool wasThrownValue;
815     String exceptionMessage;
816     scriptDebugServer().runScript(injectedScript.scriptState(), scriptId, &value, &wasThrownValue, &exceptionMessage);
817     *wasThrown = wasThrownValue;
818     if (value.hasNoValue()) {
819         *errorString = "Script execution failed";
820         return;
821     }
822     result = injectedScript.wrapObject(value, objectGroup ? *objectGroup : "");
823     if (wasThrownValue)
824         result->setDescription(exceptionMessage);
825
826     if (doNotPauseOnExceptionsAndMuteConsole && *doNotPauseOnExceptionsAndMuteConsole) {
827         unmuteConsole();
828         if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState)
829             scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState);
830     }
831 }
832
833 void InspectorDebuggerAgent::setOverlayMessage(ErrorString*, const String*)
834 {
835 }
836
837 void InspectorDebuggerAgent::setVariableValue(ErrorString* errorString, int scopeNumber, const String& variableName, const RefPtr<JSONObject>& newValue, const String* callFrameId, const String* functionObjectId)
838 {
839     InjectedScript injectedScript;
840     if (callFrameId) {
841         if (!isPaused() || m_currentCallStack.isNull()) {
842             *errorString = "Attempt to access callframe when debugger is not on pause";
843             return;
844         }
845         injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*callFrameId);
846         if (injectedScript.hasNoValue()) {
847             *errorString = "Inspected frame has gone";
848             return;
849         }
850     } else if (functionObjectId) {
851         injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*functionObjectId);
852         if (injectedScript.hasNoValue()) {
853             *errorString = "Function object id cannot be resolved";
854             return;
855         }
856     } else {
857         *errorString = "Either call frame or function object must be specified";
858         return;
859     }
860     String newValueString = newValue->toJSONString();
861
862     injectedScript.setVariableValue(errorString, m_currentCallStack, callFrameId, functionObjectId, scopeNumber, variableName, newValueString);
863 }
864
865 void InspectorDebuggerAgent::skipStackFrames(ErrorString* errorString, const String* pattern)
866 {
867     OwnPtr<RegularExpression> compiled;
868     String patternValue = pattern ? *pattern : "";
869     if (!patternValue.isEmpty()) {
870         compiled = compileSkipCallFramePattern(patternValue);
871         if (!compiled) {
872             *errorString = "Invalid regular expression";
873             return;
874         }
875     }
876     m_state->setString(DebuggerAgentState::skipStackPattern, patternValue);
877     m_cachedSkipStackRegExp = compiled.release();
878 }
879
880 void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText)
881 {
882     if (scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions) {
883         RefPtr<JSONObject> directive = JSONObject::create();
884         directive->setString("directiveText", directiveText);
885         breakProgram(InspectorFrontend::Debugger::Reason::CSPViolation, directive.release());
886     }
887 }
888
889 PassRefPtr<Array<TypeBuilder::Debugger::CallFrame> > InspectorDebuggerAgent::currentCallFrames()
890 {
891     if (!m_pausedScriptState)
892         return Array<TypeBuilder::Debugger::CallFrame>::create();
893     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState);
894     if (injectedScript.hasNoValue()) {
895         ASSERT_NOT_REACHED();
896         return Array<TypeBuilder::Debugger::CallFrame>::create();
897     }
898     return injectedScript.wrapCallFrames(m_currentCallStack);
899 }
900
901 String InspectorDebuggerAgent::sourceMapURLForScript(const Script& script)
902 {
903     bool deprecated;
904     String sourceMapURL = ContentSearchUtils::findSourceMapURL(script.source, ContentSearchUtils::JavaScriptMagicComment, &deprecated);
905     if (!sourceMapURL.isEmpty()) {
906         // FIXME: add deprecated console message here.
907         return sourceMapURL;
908     }
909
910     if (script.url.isEmpty())
911         return String();
912
913     InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent();
914     if (!pageAgent)
915         return String();
916     return pageAgent->resourceSourceMapURL(script.url);
917 }
918
919 // JavaScriptDebugListener functions
920
921 void InspectorDebuggerAgent::didParseSource(const String& scriptId, const Script& script)
922 {
923     // Don't send script content to the front end until it's really needed.
924     const bool* isContentScript = script.isContentScript ? &script.isContentScript : 0;
925     String sourceMapURL = sourceMapURLForScript(script);
926     String* sourceMapURLParam = sourceMapURL.isNull() ? 0 : &sourceMapURL;
927     String sourceURL;
928     if (!script.startLine && !script.startColumn) {
929         bool deprecated;
930         sourceURL = ContentSearchUtils::findSourceURL(script.source, ContentSearchUtils::JavaScriptMagicComment, &deprecated);
931         // FIXME: add deprecated console message here.
932     }
933     bool hasSourceURL = !sourceURL.isEmpty();
934     String scriptURL = hasSourceURL ? sourceURL : script.url;
935     bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : 0;
936     m_frontend->scriptParsed(scriptId, scriptURL, script.startLine, script.startColumn, script.endLine, script.endColumn, isContentScript, sourceMapURLParam, hasSourceURLParam);
937
938     m_scripts.set(scriptId, script);
939
940     if (scriptURL.isEmpty())
941         return;
942
943     RefPtr<JSONObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
944     for (JSONObject::iterator it = breakpointsCookie->begin(); it != breakpointsCookie->end(); ++it) {
945         RefPtr<JSONObject> breakpointObject = it->value->asObject();
946         bool isAntibreakpoint;
947         breakpointObject->getBoolean(DebuggerAgentState::isAnti, &isAntibreakpoint);
948         if (isAntibreakpoint)
949             continue;
950         bool isRegex;
951         breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex);
952         String url;
953         breakpointObject->getString(DebuggerAgentState::url, &url);
954         if (!matches(scriptURL, url, isRegex))
955             continue;
956         ScriptBreakpoint breakpoint;
957         breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakpoint.lineNumber);
958         breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakpoint.columnNumber);
959         breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.condition);
960         RefPtr<TypeBuilder::Debugger::Location> location = resolveBreakpoint(it->key, scriptId, breakpoint, UserBreakpointSource);
961         if (location)
962             m_frontend->breakpointResolved(it->key, location);
963     }
964 }
965
966 void InspectorDebuggerAgent::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage)
967 {
968     m_frontend->scriptFailedToParse(url, data, firstLine, errorLine, errorMessage);
969 }
970
971 void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
972 {
973     ASSERT(scriptState && !m_pausedScriptState);
974     m_pausedScriptState = scriptState;
975     m_currentCallStack = callFrames;
976
977     m_skipStepInCount = numberOfStepsBeforeStepOut;
978
979     if (!exception.hasNoValue()) {
980         InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
981         if (!injectedScript.hasNoValue()) {
982             m_breakReason = InspectorFrontend::Debugger::Reason::Exception;
983             m_breakAuxData = injectedScript.wrapObject(exception, "backtrace")->openAccessors();
984             // m_breakAuxData might be null after this.
985         }
986     }
987
988     RefPtr<Array<String> > hitBreakpointIds = Array<String>::create();
989
990     for (Vector<String>::const_iterator i = hitBreakpoints.begin(); i != hitBreakpoints.end(); ++i) {
991         DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIterator = m_serverBreakpoints.find(*i);
992         if (breakpointIterator != m_serverBreakpoints.end()) {
993             const String& localId = breakpointIterator->value.first;
994             hitBreakpointIds->addItem(localId);
995
996             BreakpointSource source = breakpointIterator->value.second;
997             if (m_breakReason == InspectorFrontend::Debugger::Reason::Other && source == DebugCommandBreakpointSource)
998                 m_breakReason = InspectorFrontend::Debugger::Reason::DebugCommand;
999         }
1000     }
1001
1002     m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds);
1003     m_javaScriptPauseScheduled = false;
1004
1005     if (!m_continueToLocationBreakpointId.isEmpty()) {
1006         scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
1007         m_continueToLocationBreakpointId = "";
1008     }
1009     if (m_listener)
1010         m_listener->didPause();
1011 }
1012
1013 void InspectorDebuggerAgent::didContinue()
1014 {
1015     m_pausedScriptState = 0;
1016     m_currentCallStack = ScriptValue();
1017     clearBreakDetails();
1018     m_frontend->resumed();
1019 }
1020
1021 bool InspectorDebuggerAgent::canBreakProgram()
1022 {
1023     return scriptDebugServer().canBreakProgram();
1024 }
1025
1026 void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data)
1027 {
1028     m_breakReason = breakReason;
1029     m_breakAuxData = data;
1030     scriptDebugServer().breakProgram();
1031 }
1032
1033 void InspectorDebuggerAgent::clear()
1034 {
1035     m_pausedScriptState = 0;
1036     m_currentCallStack = ScriptValue();
1037     m_scripts.clear();
1038     m_breakpointIdToDebugServerBreakpointIds.clear();
1039     m_continueToLocationBreakpointId = String();
1040     clearBreakDetails();
1041     m_javaScriptPauseScheduled = false;
1042     ErrorString error;
1043     setOverlayMessage(&error, 0);
1044 }
1045
1046 bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString)
1047 {
1048     if (!m_pausedScriptState) {
1049         *errorString = "Can only perform operation while paused.";
1050         return false;
1051     }
1052     return true;
1053 }
1054
1055 void InspectorDebuggerAgent::clearBreakDetails()
1056 {
1057     m_breakReason = InspectorFrontend::Debugger::Reason::Other;
1058     m_breakAuxData = 0;
1059 }
1060
1061 void InspectorDebuggerAgent::setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource source, const String& condition)
1062 {
1063     String breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumber, source);
1064     ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
1065     resolveBreakpoint(breakpointId, scriptId, breakpoint, source);
1066 }
1067
1068 void InspectorDebuggerAgent::removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource source)
1069 {
1070     removeBreakpoint(generateBreakpointId(scriptId, lineNumber, columnNumber, source));
1071 }
1072
1073 void InspectorDebuggerAgent::reset()
1074 {
1075     m_scripts.clear();
1076     m_breakpointIdToDebugServerBreakpointIds.clear();
1077     if (m_frontend)
1078         m_frontend->globalObjectCleared();
1079 }
1080
1081 } // namespace WebCore
1082