1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
5 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#include "debugger.h"
24#include "nodes.h"
25#include <config-kjs.h>
26#include "ustring.h"
27
28#include "internal.h"
29
30using namespace KJS;
31
32// ------------------------------ Debugger -------------------------------------
33
34namespace KJS {
35 struct AttachedInterpreter
36 {
37 AttachedInterpreter(Interpreter *i, AttachedInterpreter *ai) : interp(i), next(ai) { ++Debugger::debuggersPresent; }
38 ~AttachedInterpreter() { --Debugger::debuggersPresent; }
39 Interpreter *interp;
40 AttachedInterpreter *next;
41 };
42
43}
44
45int Debugger::debuggersPresent = 0;
46
47Debugger::Debugger()
48{
49 lastLineRan = 0;
50 rep = new DebuggerImp();
51 lastSourceParsed = -1;
52}
53
54Debugger::~Debugger()
55{
56 detach(0);
57 delete rep;
58}
59
60void Debugger::attach(Interpreter* interp)
61{
62 Debugger *other = interp->debugger();
63 if (other == this)
64 return;
65 if (other)
66 other->detach(interp);
67 interp->setDebugger(this);
68 rep->interps = new AttachedInterpreter(interp, rep->interps);
69}
70
71void Debugger::detach(Interpreter* interp)
72{
73 // iterate the addresses where AttachedInterpreter pointers are stored
74 // so we can unlink items from the list
75 AttachedInterpreter **p = &rep->interps;
76 AttachedInterpreter *q;
77 while ((q = *p)) {
78 if (!interp || q->interp == interp) {
79 *p = q->next;
80 q->interp->setDebugger(0);
81 delete q;
82 } else
83 p = &q->next;
84 }
85
86 if (interp)
87 latestExceptions.remove(interp);
88 else
89 latestExceptions.clear();
90}
91
92bool Debugger::hasHandledException(ExecState *exec, JSValue *exception)
93{
94 if (latestExceptions.get(exec->dynamicInterpreter()).get() == exception)
95 return true;
96
97 latestExceptions.set(exec->dynamicInterpreter(), exception);
98 return false;
99}
100
101bool Debugger::sourceParsed(ExecState * /*exec*/, int /*sourceId*/, const UString &/*sourceURL*/,
102 const UString &/*source*/, int /*startingLineNumber*/, int /*errorLine*/, const UString & /*errorMsg*/)
103{
104 return true;
105}
106
107bool Debugger::exception(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/,
108 JSValue * /*exception*/)
109{
110 return true;
111}
112
113bool Debugger::atStatement(ExecState * /*exec*/, int /*sourceId*/, int /*firstLine*/,
114 int /*lastLine*/)
115{
116 return true;
117}
118
119void Debugger::reportAtStatement(ExecState *exec, int sourceId, int firstLine, int lastLine)
120{
121 lastLineRan = firstLine;
122 atStatement(exec, sourceId, firstLine, lastLine);
123}
124
125void Debugger::reportException(ExecState *exec, JSValue *exceptionVal)
126{
127 if (!hasHandledException(exec, exceptionVal))
128 exception(exec, exec->currentBody() ? exec->currentBody()->sourceId() : lastSourceParsed, lastLineRan, exceptionVal);
129}
130
131bool Debugger::enterContext(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/,
132 JSObject * /*function*/, const List & /*args*/)
133{
134 return true;
135}
136
137bool Debugger::exitContext(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/,
138 JSObject * /*function*/)
139{
140 return true;
141}
142
143bool Debugger::shouldReindentSources() const
144{
145 return false;
146}
147
148bool Debugger::shouldReportCaught() const
149{
150 return false;
151}
152
153void Debugger::reportSourceParsed(ExecState *exec, FunctionBodyNode *body,
154 int sourceId, UString sourceURL, const UString &source,
155 int startingLineNumber, int errorLine, const UString &errorMsg)
156{
157 lastSourceParsed = sourceId;
158 UString code = source;
159 if (shouldReindentSources() && body)
160 code = body->reindent(startingLineNumber);
161 sourceParsed(exec, sourceId, sourceURL, code, startingLineNumber, errorLine, errorMsg);
162}
163