File indexing completed on 2024-05-12 15:43:17

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
0004  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
0005  *
0006  *  This library is free software; you can redistribute it and/or
0007  *  modify it under the terms of the GNU Lesser General Public
0008  *  License as published by the Free Software Foundation; either
0009  *  version 2 of the License, or (at your option) any later version.
0010  *
0011  *  This library is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  *  Lesser General Public License for more details.
0015  *
0016  *  You should have received a copy of the GNU Lesser General Public
0017  *  License along with this library; if not, write to the Free Software
0018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0019  *
0020  */
0021 
0022 #include "debugger.h"
0023 #include "nodes.h"
0024 #include "ustring.h"
0025 
0026 #include "internal.h"
0027 
0028 using namespace KJS;
0029 
0030 // ------------------------------ Debugger -------------------------------------
0031 
0032 namespace KJS
0033 {
0034 struct AttachedInterpreter {
0035     AttachedInterpreter(Interpreter *i, AttachedInterpreter *ai) : interp(i), next(ai)
0036     {
0037         ++Debugger::debuggersPresent;
0038     }
0039     ~AttachedInterpreter()
0040     {
0041         --Debugger::debuggersPresent;
0042     }
0043     Interpreter *interp;
0044     AttachedInterpreter *next;
0045 };
0046 
0047 }
0048 
0049 int Debugger::debuggersPresent = 0;
0050 
0051 Debugger::Debugger()
0052 {
0053     lastLineRan = 0;
0054     rep = new DebuggerImp();
0055     lastSourceParsed = -1;
0056 }
0057 
0058 Debugger::~Debugger()
0059 {
0060     detach(nullptr);
0061     delete rep;
0062 }
0063 
0064 void Debugger::attach(Interpreter *interp)
0065 {
0066     Debugger *other = interp->debugger();
0067     if (other == this) {
0068         return;
0069     }
0070     if (other) {
0071         other->detach(interp);
0072     }
0073     interp->setDebugger(this);
0074     rep->interps = new AttachedInterpreter(interp, rep->interps);
0075 }
0076 
0077 void Debugger::detach(Interpreter *interp)
0078 {
0079     // iterate the addresses where AttachedInterpreter pointers are stored
0080     // so we can unlink items from the list
0081     AttachedInterpreter **p = &rep->interps;
0082     AttachedInterpreter *q;
0083     while ((q = *p)) {
0084         if (!interp || q->interp == interp) {
0085             *p = q->next;
0086             q->interp->setDebugger(nullptr);
0087             delete q;
0088         } else {
0089             p = &q->next;
0090         }
0091     }
0092 
0093     if (interp) {
0094         latestExceptions.remove(interp);
0095     } else {
0096         latestExceptions.clear();
0097     }
0098 }
0099 
0100 bool Debugger::hasHandledException(ExecState *exec, JSValue *exception)
0101 {
0102     if (latestExceptions.get(exec->dynamicInterpreter()).get() == exception) {
0103         return true;
0104     }
0105 
0106     latestExceptions.set(exec->dynamicInterpreter(), exception);
0107     return false;
0108 }
0109 
0110 bool Debugger::sourceParsed(ExecState * /*exec*/, int /*sourceId*/, const UString &/*sourceURL*/,
0111                             const UString &/*source*/, int /*startingLineNumber*/, int /*errorLine*/, const UString & /*errorMsg*/)
0112 {
0113     return true;
0114 }
0115 
0116 bool Debugger::exception(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/,
0117                          JSValue * /*exception*/)
0118 {
0119     return true;
0120 }
0121 
0122 bool Debugger::atStatement(ExecState * /*exec*/, int /*sourceId*/, int /*firstLine*/,
0123                            int /*lastLine*/)
0124 {
0125     return true;
0126 }
0127 
0128 void Debugger::reportAtStatement(ExecState *exec, int sourceId, int firstLine, int lastLine)
0129 {
0130     lastLineRan = firstLine;
0131     atStatement(exec, sourceId, firstLine, lastLine);
0132 }
0133 
0134 void Debugger::reportException(ExecState *exec, JSValue *exceptionVal)
0135 {
0136     if (!hasHandledException(exec, exceptionVal)) {
0137         exception(exec, exec->currentBody() ? exec->currentBody()->sourceId() : lastSourceParsed, lastLineRan, exceptionVal);
0138     }
0139 }
0140 
0141 bool Debugger::enterContext(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/,
0142                             JSObject * /*function*/, const List & /*args*/)
0143 {
0144     return true;
0145 }
0146 
0147 bool Debugger::exitContext(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/,
0148                            JSObject * /*function*/)
0149 {
0150     return true;
0151 }
0152 
0153 bool Debugger::shouldReindentSources() const
0154 {
0155     return false;
0156 }
0157 
0158 bool Debugger::shouldReportCaught() const
0159 {
0160     return false;
0161 }
0162 
0163 void Debugger::reportSourceParsed(ExecState *exec, FunctionBodyNode *body,
0164                                   int sourceId, UString sourceURL, const UString &source,
0165                                   int startingLineNumber, int errorLine, const UString &errorMsg)
0166 {
0167     lastSourceParsed = sourceId;
0168     UString code = source;
0169     if (shouldReindentSources() && body) {
0170         code = body->reindent(startingLineNumber);
0171     }
0172     sourceParsed(exec, sourceId, sourceURL, code, startingLineNumber, errorLine, errorMsg);
0173 }