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 #ifndef _KJSDEBUGGER_H_
0023 #define _KJSDEBUGGER_H_
0024 
0025 #include "global.h"
0026 #include <wtf/HashMap.h>
0027 #include "protect.h"
0028 
0029 namespace KJS
0030 {
0031 
0032 class DebuggerImp;
0033 class Interpreter;
0034 class ExecState;
0035 class JSObject;
0036 class JSValue;
0037 class UString;
0038 class List;
0039 class FunctionBodyNode;
0040 
0041 /**
0042  * @internal
0043  *
0044  * Provides an interface which receives notification about various
0045  * script-execution related events such as statement execution and function
0046  * calls.
0047  *
0048  * WARNING: This interface is still a work in progress and is not yet
0049  * officially publicly available. It is likely to change in binary incompatible
0050  * (and possibly source incompatible) ways in future versions. It is
0051  * anticipated that at some stage the interface will be frozen and made
0052  * available for general use.
0053  */
0054 class KJS_EXPORT Debugger
0055 {
0056 public:
0057 
0058     /**
0059      * Creates a new debugger
0060      */
0061     Debugger();
0062 
0063     /**
0064      * Destroys the debugger. If the debugger is attached to any interpreters,
0065      * it is automatically detached.
0066      */
0067     virtual ~Debugger();
0068 
0069     DebuggerImp *imp() const
0070     {
0071         return rep;
0072     }
0073 
0074     /**
0075      * Attaches the debugger to specified interpreter. This will cause this
0076      * object to receive notification of events from the interpreter.
0077      *
0078      * If the interpreter is deleted, the debugger will automatically be
0079      * detached.
0080      *
0081      * Note: only one debugger can be attached to an interpreter at a time.
0082      * Attaching another debugger to the same interpreter will cause the
0083      * original debugger to be detached from that interpreter.
0084      *
0085      * @param interp The interpreter to attach to
0086      *
0087      * @see detach()
0088      */
0089     virtual void attach(Interpreter *interp);
0090 
0091     /**
0092      * Detach the debugger from an interpreter
0093      *
0094      * @param interp The interpreter to detach from. If 0, the debugger will be
0095      * detached from all interpreters to which it is attached.
0096      *
0097      * @see attach()
0098      */
0099     virtual void detach(Interpreter *interp);
0100 
0101     /**
0102      * Called to notify the debugger that some javascript source code has
0103      * been parsed. For calls to Interpreter::evaluate(), this will be called
0104      * with the supplied source code before any other code is parsed.
0105      * Other situations in which this may be called include creation of a
0106      * function using the Function() constructor, or the eval() function.
0107      *
0108      * The default implementation does nothing. Override this method if
0109      * you want to process this event.
0110      *
0111      * @param exec The current execution state
0112      * @param sourceId The ID of the source code (corresponds to the
0113      * sourceId supplied in other functions such as atStatement()
0114      * @param sourceURL Where the source code that was parsed came from
0115      * @param source The source code that was parsed
0116      * @param startingLineNumber The line number at which parsing started
0117      * @param errorLine The line number at which parsing encountered an
0118      * error, or -1 if the source code was valid and parsed successfully
0119      * @param errorMsg The error description, or null if the source code
0120        was valid and parsed successfully
0121      * @return true if execution should be continue, false if it should
0122      * be aborted
0123      */
0124     virtual bool sourceParsed(ExecState *exec, int sourceId, const UString &sourceURL,
0125                               const UString &source, int startingLineNumber, int errorLine, const UString &errorMsg);
0126 
0127     /**
0128      * Called when an exception is thrown during script execution.
0129      *
0130      * The default implementation does nothing. Override this method if
0131      * you want to process this event.
0132      *
0133      * @param exec The current execution state
0134      * @param sourceId The ID of the source code being executed
0135      * @param lineno The line at which the error occurred
0136      * @param exception The exception object
0137      * @return true if execution should be continue, false if it should
0138      * be aborted
0139      */
0140     virtual bool exception(ExecState *exec, int sourceId, int lineno,
0141                            JSValue *exception);
0142 
0143     bool hasHandledException(ExecState *, JSValue *);
0144 
0145     /**
0146      * Called when a line of the script is reached (before it is executed)
0147      *
0148      * The default implementation does nothing. Override this method if
0149      * you want to process this event.
0150      *
0151      * @param exec The current execution state
0152      * @param sourceId The ID of the source code being executed
0153      * @param firstLine The starting line of the statement  that is about to be
0154      * executed
0155      * @param lastLine The ending line of the statement  that is about to be
0156      * executed (usually the same as firstLine)
0157      * @return true if execution should be continue, false if it should
0158      * be aborted
0159      */
0160     virtual bool atStatement(ExecState *exec, int sourceId, int firstLine,
0161                              int lastLine);
0162     /**
0163      * Called when the interpreter enters a new execution context (stack
0164      * frame). This can happen in three situations:
0165      *
0166      * <ul>
0167      *   <li>A call to Interpreter::evaluate(). This has a codeType of
0168      *   GlobalCode </li>
0169      *   <li>A call to the builtin eval() function. The sourceId corresponds to
0170      *   the code passed in to eval. This has a codeType of EvalCode. The
0171      *   lineno here is always 0 since execution starts at the beginning of
0172      *   the script.</li>
0173      *   <li>A function call. This only occurs for functions defined in
0174      *   ECMAScript code, whether via the normal function() { ... } syntax or
0175      *   a call to the built-in Function() constructor (anonymous functions).
0176      *   In the former case, the sourceId and lineno indicate the location at
0177      *   which the function was defined. For anonymous functions, the sourceId
0178      *   corresponds to the code passed into the Function() constructor.</li>
0179      * </ul>
0180      *
0181      * enterContext() is not called for functions implemented in the native
0182      * code, since these do not use an execution context.
0183      *
0184      * @param exec The current execution state (corresponding to the new stack)
0185      * @param sourceId The ID of the source code being executed
0186      * @param lineno The line that is about to be executed
0187      * @param function The function being called. 0 in non-function context.
0188      * @param args The arguments that were passed to the function
0189      * line is being executed. Empty in non-function contexts.
0190      *
0191      * @return true if execution should be continued, false if it should
0192      * be aborted
0193      */
0194     virtual bool enterContext(ExecState *exec, int sourceId, int lineno,
0195                               JSObject *function, const List &args);
0196 
0197     /**
0198      * Called when the interpreter exits an execution context. This always
0199      * corresponds to a previous call to enterContext()
0200      *
0201      * The default implementation does nothing. Override this method if
0202      * you want to process this event.
0203      *
0204      * @param exec The current execution state
0205      * @param sourceId The ID of the source code being executed
0206      * @param lineno The line that is about to be executed
0207      * @param function The function being returned from, if there is one
0208      * @return true if execution should be continue, false if it should
0209      * be aborted
0210      */
0211     virtual bool exitContext(ExecState *exec, int sourceId, int lineno,
0212                              JSObject *function);
0213 
0214     // Override this and return true if you want the debugger to report
0215     // pretty-printed versions of the source.
0216     virtual bool shouldReindentSources() const;
0217 
0218     // Override this to return true if the debugger should report
0219     // exceptions even if there is a try block waiting for it.
0220     virtual bool shouldReportCaught()    const;
0221 
0222     // The two methods below call the events but also keep track/use of line # information
0223     // so we can associate it with exceptions
0224     void reportAtStatement(ExecState *exec, int sourceId, int firstLine, int lastLine);
0225     void reportException(ExecState *exec, JSValue *exception);
0226 
0227     // This notifies the debugger of source being parsed, reindenting it if need be.
0228     void reportSourceParsed(ExecState *exec, FunctionBodyNode *body, int sourceId, UString sourceURL,
0229                             const UString &source, int startingLineNumber, int errorLine, const UString &errorMsg);
0230 private:
0231     DebuggerImp *rep;
0232     HashMap<Interpreter *, ProtectedPtr<JSValue> > latestExceptions;
0233     int lastLineRan;
0234     int lastSourceParsed; // Needed for attributing syntax exceptions at top-level
0235 public:
0236     static int debuggersPresent;
0237 };
0238 
0239 }
0240 
0241 #endif
0242