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 }