/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code * * The Initial Developer of the Original Code is * Netscape Communications Corporation * Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. * * Alternatively, the contents of this file may be used under the * terms of the GNU Public License (the "GPL"), in which case the * provisions of the GPL are applicable instead of those above. * If you wish to allow use of your version of this file only * under the terms of the GPL and not to allow others to use your * version of this file under the MPL, indicate your decision by * deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete * the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * Contributor(s): * Robert Ginda, * */ #include "nsISupports.idl" %{ C++ #include "jsdebug.h" #include "nsAReadableString.h" %} [ptr] native JSDContext(JSDContext); [ptr] native JSDObject(JSDObject); [ptr] native JSDProperty(JSDProperty); [ptr] native JSDScript(JSDScript); [ptr] native JSDStackFrameInfo(JSDStackFrameInfo); [ptr] native JSDThreadState(JSDThreadState); [ptr] native JSDValue(JSDValue); [ptr] native JSRuntime(JSRuntime); native jsuword(jsuword); /* interfaces we declare in this file */ interface jsdIDebuggerService; interface jsdIScriptEnumerator; interface jsdIScriptHook; interface jsdIExecutionHook; interface jsdIEphemeral; interface jsdIPC; interface jsdIStackFrame; interface jsdIScript; interface jsdIValue; interface jsdIObject; interface jsdIProperty; /** * Debugger service. It's not a good idea to have more than one active client of * the debugger service. */ [scriptable, uuid(01be7f9a-1dd2-11b2-9d55-aaf919b27c73)] interface jsdIDebuggerService : nsISupports { /** * Called when a jsdIScript is created or destroyed. */ attribute jsdIScriptHook scriptHook; /** * Called when the engine encounters a breakpoint. */ attribute jsdIExecutionHook breakpointHook; /** * Called when the engine encounters the debugger keyword. */ attribute jsdIExecutionHook debuggerHook; /** * Called when an exception goes uncaught. */ attribute jsdIExecutionHook errorHook; /** * Called before the next PC is executed. */ attribute jsdIExecutionHook interruptHook; /** * Called when an exception is thrown (even if it will be caught.) */ attribute jsdIExecutionHook throwHook; /** * |true| if the debugger service has been turned on. This does not * necessarily mean another app is actively using the service, as the * autostart pref may have turned the service on. */ readonly attribute boolean isOn; /** * Turn on the debugger. This function should only be called from JavaScript * code. The debugger will be enabled on the runtime the call is made on, * as determined by nsIXPCNativeCallContext. */ void on (); /** * Turn on the debugger for a given runtime. * * @param rt The runtime you want to debug. You cannot turn the debugger * on for multiple runtimes. */ [noscript] void onForRuntime (in JSRuntime rt); /** * Turn the debugger off. This will invalidate all of your jsdIEphemeral * derived objects, and clear all of your breakpoints. In theory you * should be able to turn the debugger back on at some later time without * any problems. */ void off (); /** * Force the engine to perform garbage collection. */ void GC(); /** * Ignore/unignore execution hooks which are triggered by a context with a * particular global object. * * @param glob Global object to ignore/unignore. For the typical Mozilla * context, global objects are DOM windows. * * @param state |true| to ignore this global object, |false| to unignore. * If state is |false| and the the glob passed in is not * currently ignored, this method will throw an * NS_ERROR_INVALID_PARAM exception. */ //void filterGlobalObject (in nsISupports glob, in boolean state); /** * Enumerate all scripts the debugger knows about. Any scripts created * before you turned the debugger on, or after turning the debugger off * will not be available unless the autostart perf is set. * * @param enumerator jsdIScriptEnumerator instance to be called back for * the enumeration. */ void enumerateScripts (in jsdIScriptEnumerator enumerator); /** * Clear all breakpoints in all scripts. */ void clearAllBreakpoints (); /** * XXX temporary hacks * These routines are used to nest and unnest UI event loops. */ unsigned long enterNestedEventLoop (); unsigned long exitNestedEventLoop (); }; /* callback interfaces */ /** * Pass an instance of one of these to jsdIDebuggerService::enumerateScripts. */ [scriptable, uuid(4c2f706e-1dd2-11b2-9ebc-85a06e948830)] interface jsdIScriptEnumerator : nsISupports { /** * The enumerateScript method will be called once for every script the * debugger knows about. */ boolean enumerateScript (in jsdIScript script); }; /** * Set jsdIDebuggerService::scriptHook to an instance of one of these. */ [scriptable, uuid(ae89a7e2-1dd1-11b2-8c2f-af82086291a5)] interface jsdIScriptHook : nsISupports { /** * Called when scripts are created. */ void onScriptCreated (in jsdIScript script); /** * Called when the JavaScript engine destroys a script. The jsdIScript * object passed in will already be invalidated. */ void onScriptDestroyed (in jsdIScript script); }; /** * Hook instances of this interface up to the * jsdIDebuggerService::breakpointHook, debuggerHook, errorHook, interruptHook, * and throwHook properties. */ [scriptable, uuid(9a7b6ad0-1dd1-11b2-a789-fcfae96356a2)] interface jsdIExecutionHook : nsISupports { const unsigned long TYPE_INTERRUPTED = 0; const unsigned long TYPE_BREAKPOINT = 1; const unsigned long TYPE_DEBUG_REQUESTED = 2; const unsigned long TYPE_DEBUGGER_KEYWORD = 3; const unsigned long TYPE_THROW = 4; /** * Indicates unrecoverable error processing the hook. This will cause * the script being executed to be aborted without raising a JavaScript * exception. */ const unsigned long RETURN_HOOK_ERROR = 0; /** * Continue processing normally. This is the "do nothing special" return * value for all hook types *except* TYPE_THROW. Returning RETURN_CONTINUE * from TYPE_THROW cause the exception to be ignored. Return * RETURN_CONTINUE_THROW to continue exception processing from TYPE_THROW * hooks. */ const unsigned long RETURN_CONTINUE = 1; const unsigned long RETURN_ABORT = 2; const unsigned long RETURN_RET_WITH_VAL = 3; const unsigned long RETURN_THROW_WITH_VAL = 4; const unsigned long RETURN_CONTINUE_THROW = 5; /** * @param frame A jsdIStackFrame object representing the bottom stack frame. * @param type One of the jsdIExecutionHook::TYPE_ constants. * @param val in - Current exception (if any) when this method is called. * out - If you return RETURN_THROW_WITH_VAL, value to be * thrown. * If you return RETURN_RET_WITH_VAL, value to return. * All other return values, not significant. * @retval One of the jsdIExecutionHook::RETURN_* constants. */ unsigned long onExecute (in jsdIStackFrame frame, in unsigned long type, inout jsdIValue val); }; /** * Objects which inherit this interface may go away, with (jsdIScript) or * without (all others) notification. These objects are generally wrappers * around JSD structures that go away when you call jsdService::Off(). */ [scriptable, uuid(46f1e23e-1dd2-11b2-9ceb-8285f2e95e69)] interface jsdIEphemeral : nsISupports { /** * |true| if this object is still valid. If not, many or all of the methods * and/or properties of the inheritor may no longer be callable. */ readonly attribute boolean isValid; /** * Mark this instance as invalid. */ [noscript] void invalidate(); }; /* handle objects */ /** * XXX can't reflect the jsuword pc because it'll change sizes on 64 bit systems, * but we could represent all pcs as offsets, and store them in ulongs. This * would allow us to get rid of jsdIPC, and simplify things in some places. The * only tradeoff would be that scripts with more than 2^32 instructions would * have pc's we can't represent. If you're script is that large, you need more * help than the debugger can provide. */ [scriptable, uuid(e7c8ea2c-1dd1-11b2-9242-f2768e04e92e)] interface jsdIPC : nsISupports { /** Internal use only. */ [noscript] readonly attribute jsuword pc; }; /** * Stack frame objects. These are only valid inside the jsdIExecutionHook which * gave it to you. After you return from that handler the bottom frame, and any * frame you found attached through it, are invalidated via the jsdIEphemeral * interface. Once a jsdIStackFrame has been invalidated all method and * property accesses will throw a NS_ERROR_NOT_AVAILABLE exception. */ [scriptable, uuid(b6d50784-1dd1-11b2-a932-882246c6fe45)] interface jsdIStackFrame : jsdIEphemeral { /** Internal use only. */ [noscript] readonly attribute JSDContext JSDContext; /** Internal use only. */ [noscript] readonly attribute JSDThreadState JSDThreadState; /** Internal use only. */ [noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo; /** * Link to the caller's stack frame. */ readonly attribute jsdIStackFrame callingFrame; /** * Script running in this stack frame. */ readonly attribute jsdIScript script; /** * Current program counter in this stack frame. */ readonly attribute jsdIPC pc; /** * Current line number (using the script's pc to line map.) */ readonly attribute unsigned long line; /** * Function object running in this stack frame. */ readonly attribute jsdIValue callee; /** * Top object in the scope chain. */ readonly attribute jsdIValue scope; /** * |this| object for this stack frame. */ readonly attribute jsdIValue thisValue; /** * Evaluate arbitrary JavaScript in this stack frame. * @param bytes Script to be evaluated. * @param fileName Filename to compile this script under. This is the * filename you'll see in error messages, etc. * @param line Starting line number for this script. One based. * @retval Result of evaluating the script. */ jsdIValue eval (in AString bytes, in string fileName, in unsigned long line); /* boolean eval (in AString bytes, in string fileName, in unsigned long line, out result); */ }; /** * Script object. In JavaScript engine terms, there's a single script for each * function, and one for the top level script. */ [scriptable, uuid(a38f65ca-1dd1-11b2-95d5-ff2947e9c920)] interface jsdIScript : jsdIEphemeral { /** Internal use only. */ [noscript] readonly attribute JSDContext JSDContext; /** Internal use only. */ [noscript] readonly attribute JSDScript JSDScript; /** * Filename given for this script when it was compiled. * This data is copied from the underlying structure when the jsdIScript * instance is created and is therefore available even after the script is * invalidated. */ readonly attribute string fileName; /** * Function name for this script. "anonymous" for unnamed functions (or * a function actually named anonymous), empty for top level scripts. * This data is copied from the underlying structure when the jsdIScript * instance is created and is therefore available even after the script is * invalidated. */ readonly attribute string functionName; /** * Line number in source file containing the first line of this script. * This data is copied from the underlying structure when the jsdIScript * instance is created and is therefore available even after the script is * invalidated. */ readonly attribute unsigned long baseLineNumber; /** * Total number of lines in this script. * This data is copied from the underlying structure when the jsdIScript * instance is created and is therefore available even after the script is * invalidated. */ readonly attribute unsigned long lineExtent; /** * Get the closest line number to a given PC. */ unsigned long pcToLine (in jsdIPC pc); /** * Get the first PC associated with a line. */ jsdIPC lineToPc (in unsigned long line); /** * Set a breakpoint at a PC in this script. */ void setBreakpoint (in jsdIPC pc); /** * Clear a breakpoint at a PC in this script. */ void clearBreakpoint (in jsdIPC pc); /** * Clear all breakpoints set in this script. */ void clearAllBreakpoints (); }; /** * Value objects. Represents typeless JavaScript values (jsval in SpiderMonkey * terminology.) These are valid until the debugger is turned off. Holding a * jsdIValue adds a root for the underlying JavaScript value, so don't keep it * if you don't need to. */ [scriptable, uuid(b7964304-1dd1-11b2-ba20-cf4205772e9d)] interface jsdIValue : jsdIEphemeral { /** Internal use only. */ [noscript] readonly attribute JSDContext JSDContext; /** Internal use only. */ [noscript] readonly attribute JSDValue JSDValue; /** * |false| unless the value is a function declared in script. */ readonly attribute boolean isNative; /** * |true| if the value represents a number, either double or integer. * |false| for all other values, including numbers assigned as strings * (eg. x = "1";) */ readonly attribute boolean isNumber; /** * |true| if the value represents a JavaScript primitive number or string */ readonly attribute boolean isPrimitive; /** Value is either |true| or |false|. */ const unsigned long TYPE_BOOLEAN = 0; /** Value is a primitive number that is too large to fit in an integer. */ const unsigned long TYPE_DOUBLE = 1; /** Value is a number that fits into an integer. */ const unsigned long TYPE_INT = 2; /** Value is a function. */ const unsigned long TYPE_FUNCTION = 3; /** Value is |null|. */ const unsigned long TYPE_NULL = 4; /** Value is an object. */ const unsigned long TYPE_OBJECT = 5; /** Value is a primitive string. */ const unsigned long TYPE_STRING = 6; /** Value is void. */ const unsigned long TYPE_VOID = 7; /** * One of the TYPE_* values above. */ readonly attribute unsigned long jsType; /** * Prototype value if this value represents an object, null if the value is * not an object or the object has no prototype. */ readonly attribute jsdIValue jsPrototype; /** * Parent value if this value represents an object, null if the value is not * an object or the object has no parent. */ readonly attribute jsdIValue jsParent; /** * Class name if this value represents an object. Empty string if the value * is not an object. */ readonly attribute string jsClassName; /** * Constructor name if this value represents an object. Empty string if the * value is not an object. */ readonly attribute jsdIValue jsConstructor; /** * Function name if this value represents a function. Empty string if the * value is not a function. */ readonly attribute string jsFunctionName; /** * Value if interpreted as a boolean. Converts if necessary. */ readonly attribute boolean booleanValue; /** * Value if interpreted as a double. Converts if necessary. */ readonly attribute double doubleValue; /** * Value if interpreted as an integer. Converts if necessary. */ readonly attribute long intValue; /** * Value if interpreted as an object. */ readonly attribute jsdIObject objectValue; /** * Value if interpreted as a string. Converts if necessary. */ readonly attribute string stringValue; /** * Number of properties. 0 if the value is not an object, or the value is * an object but has no properties. */ readonly attribute long propertyCount; /** * Retrieves all properties if this value represents an object. If this * value is not an object a 0 element array is returned. * @param propArray Array of jsdIProperty values for this value. * @param length Size of array. */ void getProperties ([array, size_is(length)] out jsdIProperty propArray, out unsigned long length); /** * Retrieves a single property from the value. Only valid if the value * represents an object. * @param name Name of the property to retrieve. * @retval jsdIProperty for the requested property name or null if no * property exists for the requested name. */ jsdIProperty getProperty (in string name); /** * jsdIValues are wrappers around JavaScript engine structures. Much of the * data is copied instead of shared. The refresh method is used to resync * the jsdIValue with the underlying structure. */ void refresh(); }; /** * Properties specific to values which are also objects. * XXX We don't add roots for these yet, so make sure you hold on to the * jsdIValue from whence your jsdIObject instance came for at least as long as * you hold the jsdIObject. * XXX Maybe the jsClassName, jsConstructorName, and property related attribute/ * functions from jsdIValue should move to this interface. We could inherit from * jsdIValue or use interface flattening or something. */ [scriptable, uuid(d500e8b8-1dd1-11b2-89a1-cdf55d91cbbd)] interface jsdIObject : nsISupports { /** Internal use only. */ [noscript] readonly attribute JSDContext JSDContext; /** Internal use only. */ [noscript] readonly attribute JSDObject JSDObject; /** * The URL (filename) that contains the script which caused this object * to be created. */ readonly attribute string creatorURL; /** * Line number in the creatorURL where this object was created. */ readonly attribute unsigned long creatorLine; /** * The URL (filename) that contains the script which defined the constructor * used to create this object. */ readonly attribute string constructorURL; /** * Line number in the creatorURL where this object was created. */ readonly attribute unsigned long constructorLine; /** * jsdIValue for this object. */ readonly attribute jsdIValue value; }; /** * Representation of a property of an object. When an instance is invalid, all * method and property access will result in a NS_UNAVAILABLE error. */ [scriptable, uuid(b8816e56-1dd1-11b2-81dc-8ba99a833d9e)] interface jsdIProperty : jsdIEphemeral { /** Internal use only. */ [noscript] readonly attribute JSDContext JSDContext; /** Internal use only. */ [noscript] readonly attribute JSDProperty JSDProperty; /** visible to for/in loop */ const unsigned long FLAG_ENUMERATE = 0x01; /** assignment is error */ const unsigned long FLAG_READONLY = 0x02; /** property cannot be deleted */ const unsigned long FLAG_PERMANENT = 0x04; /** property has an alias id */ const unsigned long FLAG_ALIAS = 0x08; /** argument to function */ const unsigned long FLAG_ARGUMENT = 0x10; /** local variable in function */ const unsigned long FLAG_VARIABLE = 0x20; /** found via explicit lookup */ const unsigned long FLAG_HINTED = 0x800; /** FLAG_* values OR'd together, representing the flags for this property. */ readonly attribute unsigned long flags; /** jsdIValue representing the alias for this property. */ readonly attribute jsdIValue alias; /** name for this property. */ readonly attribute jsdIValue name; /** value of this property. */ readonly attribute jsdIValue value; /** slot number if this property is a local variable or parameter. */ readonly attribute unsigned long varArgSlot; }; /* [scriptable, uuid(a2dd25a4-1dd1-11b2-bda6-ed525acd4c35)] interface jsdIContext : nsISupports { [noscript] readonly attribute JSDContext JSDContext; }; [scriptable, uuid(a47adad2-1dd1-11b2-b9e9-8e67a47beca5)] interface jsdISourceText : nsISupports {}; [scriptable, uuid(b6d1c006-1dd1-11b2-b9d8-b4d1ccfb74d8)] interface jsdIThreadState : nsISupports { [noscript] readonly attribute JSDContext JSDContext; [noscript] readonly attribute JSDThreadState JSDThreadState; readonly attribute unsigned long frameCount; readonly attribute jsdIStackFrame topFrame; attribute jsdIValue pendingException; }; */