michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Header for JavaScript Debugging support - All public functions michael@0: */ michael@0: michael@0: #ifndef jsdebug_h___ michael@0: #define jsdebug_h___ michael@0: michael@0: #include "jstypes.h" michael@0: #include "js/TypeDecls.h" michael@0: michael@0: extern "C" { michael@0: michael@0: /* michael@0: * The linkage of JSD API functions differs depending on whether the file is michael@0: * used within the JSD library or not. Any source file within the JSD michael@0: * libraray should define EXPORT_JSD_API whereas any client of the library michael@0: * should not. michael@0: */ michael@0: #ifdef EXPORT_JSD_API michael@0: #define JSD_PUBLIC_API(t) JS_EXPORT_API(t) michael@0: #define JSD_PUBLIC_DATA(t) JS_EXPORT_DATA(t) michael@0: #else michael@0: #define JSD_PUBLIC_API(t) JS_IMPORT_API(t) michael@0: #define JSD_PUBLIC_DATA(t) JS_IMPORT_DATA(t) michael@0: #endif michael@0: michael@0: #define JSD_FRIEND_API(t) JSD_PUBLIC_API(t) michael@0: #define JSD_FRIEND_DATA(t) JSD_PUBLIC_DATA(t) michael@0: michael@0: /***************************************************************************/ michael@0: /* Opaque typedefs for handles */ michael@0: michael@0: typedef struct JSDContext JSDContext; michael@0: typedef struct JSDScript JSDScript; michael@0: typedef struct JSDSourceText JSDSourceText; michael@0: typedef struct JSDThreadState JSDThreadState; michael@0: typedef struct JSDStackFrameInfo JSDStackFrameInfo; michael@0: typedef struct JSDValue JSDValue; michael@0: typedef struct JSDProperty JSDProperty; michael@0: typedef struct JSDObject JSDObject; michael@0: michael@0: /***************************************************************************/ michael@0: /* High Level calls */ michael@0: michael@0: /* michael@0: * callback stuff for calls in EXE to be accessed by this code michael@0: * when it lives in an explicitly loaded DLL michael@0: */ michael@0: michael@0: /* michael@0: * This callback allows JSD to inform the embedding when JSD has been michael@0: * turned on or off. This is especially useful in the Java-based debugging michael@0: * system used in mozilla because the debugger applet controls starting michael@0: * up the JSD system. michael@0: */ michael@0: typedef void michael@0: (* JSD_SetContextProc)(JSDContext* jsdc, void* user); michael@0: michael@0: /* This struct could have more fields in future versions */ michael@0: typedef struct michael@0: { michael@0: unsigned size; /* size of this struct (init before use)*/ michael@0: JSD_SetContextProc setContext; michael@0: } JSD_UserCallbacks; michael@0: michael@0: /* michael@0: * Used by an embedding to tell JSD what JSRuntime to use and to set michael@0: * callbacks without starting up JSD. This assumes only one JSRuntime michael@0: * will be used. This exists to support the mozilla Java-based debugger michael@0: * system. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_SetUserCallbacks(JSRuntime* jsrt, michael@0: JSD_UserCallbacks* callbacks, michael@0: void* user); michael@0: michael@0: /* michael@0: * Startup JSD. michael@0: * This version of the init function requires that JSD_SetUserCallbacks() michael@0: * has been previously called (with a non-nullptr callback struct pointer) michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDContext*) michael@0: JSD_DebuggerOn(void); michael@0: michael@0: /* michael@0: * Startup JSD on a particular JSRuntime with (optional) callbacks michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDContext*) michael@0: JSD_DebuggerOnForUser(JSRuntime* jsrt, michael@0: JSD_UserCallbacks* callbacks, michael@0: void* user); michael@0: michael@0: /* michael@0: * Startup JSD in an application that uses compartments. Debugger michael@0: * objects will be allocated in the same compartment as scopeobj. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDContext*) michael@0: JSD_DebuggerOnForUserWithCompartment(JSRuntime* jsrt, michael@0: JSD_UserCallbacks* callbacks, michael@0: void* user, michael@0: JSObject* scopeobj); michael@0: michael@0: /* michael@0: * Shutdown JSD for this JSDContext michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_DebuggerOff(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Pause JSD for this JSDContext michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_DebuggerPause(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Unpause JSD for this JSDContext michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_DebuggerUnpause(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Get the Major Version (initial JSD release used major version = 1) michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetMajorVersion(void); michael@0: michael@0: /* michael@0: * Get the Minor Version (initial JSD release used minor version = 0) michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetMinorVersion(void); michael@0: michael@0: /* michael@0: * Returns the default JSD global associated with a given JSDContext. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSObject*) michael@0: JSD_GetDefaultGlobal(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Returns a JSRuntime this context is associated with michael@0: */ michael@0: extern JSD_PUBLIC_API(JSRuntime*) michael@0: JSD_GetJSRuntime(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set the private data for this context, returns previous value michael@0: */ michael@0: extern JSD_PUBLIC_API(void *) michael@0: JSD_SetContextPrivate(JSDContext *jsdc, void *data); michael@0: michael@0: /* michael@0: * Get the private data for this context michael@0: */ michael@0: extern JSD_PUBLIC_API(void *) michael@0: JSD_GetContextPrivate(JSDContext *jsdc); michael@0: michael@0: /* michael@0: * Clear profile data for all scripts michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_ClearAllProfileData(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Context flags. michael@0: */ michael@0: michael@0: /* Include native frames in JSDThreadStates. */ michael@0: #define JSD_INCLUDE_NATIVE_FRAMES 0x01 michael@0: /* michael@0: * Normally, if a script has a 0 in JSD_SCRIPT_PROFILE_BIT it is included in michael@0: * profile data, otherwise it is not profiled. Setting the JSD_PROFILE_WHEN_SET michael@0: * flag reverses this convention. michael@0: */ michael@0: #define JSD_PROFILE_WHEN_SET 0x02 michael@0: /* michael@0: * Normally, when the script in the top frame of a thread state has a 1 in michael@0: * JSD_SCRIPT_DEBUG_BIT, the execution hook is ignored. Setting the michael@0: * JSD_DEBUG_WHEN_SET flag reverses this convention. michael@0: */ michael@0: #define JSD_DEBUG_WHEN_SET 0x04 michael@0: /* michael@0: * When this flag is set the internal call hook will collect profile data. michael@0: */ michael@0: #define JSD_COLLECT_PROFILE_DATA 0x08 michael@0: /* michael@0: * When this flag is set, stack frames that are disabled for debugging michael@0: * will not appear in the call stack chain. michael@0: */ michael@0: #define JSD_HIDE_DISABLED_FRAMES 0x10 michael@0: /* michael@0: * When this flag is set, the debugger will only check the michael@0: * JSD_SCRIPT_DEBUG_BIT on the top (most recent) stack frame. This michael@0: * makes it possible to stop in an enabled frame which was called from michael@0: * a stack that contains a disabled frame. michael@0: * michael@0: * When this flag is *not* set, any stack that contains a disabled frame michael@0: * will not be debugged (the execution hook will not be invoked.) michael@0: * michael@0: * This only applies when the reason for calling the hook would have michael@0: * been JSD_HOOK_INTERRUPTED or JSD_HOOK_THROW. JSD_HOOK_BREAKPOINT, michael@0: * JSD_HOOK_DEBUG_REQUESTED, and JSD_HOOK_DEBUGGER_KEYWORD always stop, michael@0: * regardless of this setting, as long as the top frame is not disabled. michael@0: * michael@0: * If JSD_HIDE_DISABLED_FRAMES is set, this is effectively set as well. michael@0: */ michael@0: #define JSD_MASK_TOP_FRAME_ONLY 0x20 michael@0: michael@0: /* michael@0: * 0x40 was formerly used to hook into object creation. michael@0: */ michael@0: #define JSD_DISABLE_OBJECT_TRACE_RETIRED 0x40 michael@0: michael@0: michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_SetContextFlags (JSDContext* jsdc, uint32_t flags); michael@0: michael@0: extern JSD_PUBLIC_API(uint32_t) michael@0: JSD_GetContextFlags (JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Notify JSD that this JSContext is 'in use'. This allows JSD to hook the michael@0: * ErrorReporter. For the most part this is done automatically whenever michael@0: * events like script loading happen. But, it is a good idea to call this michael@0: * from the embedding when new contexts come into use. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_JSContextInUse(JSDContext* jsdc, JSContext* context); michael@0: michael@0: /* michael@0: * Find the JSDContext (if any) associated with the JSRuntime of a michael@0: * given JSContext. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDContext*) michael@0: JSD_JSDContextForJSContext(JSContext* context); michael@0: michael@0: /***************************************************************************/ michael@0: /* Script functions */ michael@0: michael@0: /* michael@0: * Lock the entire script subsystem. This grabs a highlevel lock that michael@0: * protects the JSD internal information about scripts. It is important michael@0: * to wrap script related calls in this lock in multithreaded situations michael@0: * -- i.e. where the debugger is running on a different thread than the michael@0: * interpreter -- or when multiple debugger threads may be accessing this michael@0: * subsystem. It is safe (and best) to use this locking even if the michael@0: * environment might not be multi-threaded. Safely nestable. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_LockScriptSubsystem(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Unlock the entire script subsystem -- see JSD_LockScriptSubsystem michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_UnlockScriptSubsystem(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Iterate through all the active scripts for this JSDContext. michael@0: * NOTE: must initialize iterp to nullptr to start iteration. michael@0: * NOTE: must lock and unlock the subsystem michael@0: * example: michael@0: * michael@0: * JSDScript jsdscript; michael@0: * JSDScript iter = nullptr; michael@0: * michael@0: * JSD_LockScriptSubsystem(jsdc); michael@0: * while((jsdscript = JSD_IterateScripts(jsdc, &iter)) != nullptr) { michael@0: * *** use jsdscript here *** michael@0: * } michael@0: * JSD_UnlockScriptSubsystem(jsdc); michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDScript*) michael@0: JSD_IterateScripts(JSDContext* jsdc, JSDScript **iterp); michael@0: michael@0: /* michael@0: * Get the number of times this script has been called. michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetScriptCallCount(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the max number of times this script called itself, directly or indirectly. michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetScriptMaxRecurseDepth(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the shortest execution time recorded. michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetScriptMinExecutionTime(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the longest execution time recorded. michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the total amount of time spent in this script. michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the shortest execution time recorded, excluding time spent in called michael@0: * functions. michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the longest execution time recorded, excluding time spent in called michael@0: * functions. michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the total amount of time spent in this script, excluding time spent michael@0: * in called functions. michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Clear profile data for this script. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_ClearScriptProfileData(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the JSScript for a JSDScript michael@0: */ michael@0: extern JSD_PUBLIC_API(JSScript*) michael@0: JSD_GetJSScript(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Get the JSFunction for a JSDScript michael@0: */ michael@0: extern JSD_PUBLIC_API(JSFunction*) michael@0: JSD_GetJSFunction(JSDContext* jsdc, JSDScript *script); michael@0: michael@0: /* michael@0: * Determines whether or not to collect profile information for this michael@0: * script. The context flag JSD_PROFILE_WHEN_SET decides the logic. michael@0: */ michael@0: #define JSD_SCRIPT_PROFILE_BIT 0x01 michael@0: /* michael@0: * Determines whether or not to ignore breakpoints, etc. in this script. michael@0: * The context flag JSD_DEBUG_WHEN_SET decides the logic. michael@0: */ michael@0: #define JSD_SCRIPT_DEBUG_BIT 0x02 michael@0: /* michael@0: * Determines whether to invoke the onScriptDestroy callback for this michael@0: * script. The default is for this to be true if the onScriptCreated michael@0: * callback was invoked for this script. michael@0: */ michael@0: #define JSD_SCRIPT_CALL_DESTROY_HOOK_BIT 0x04 michael@0: michael@0: extern JSD_PUBLIC_API(uint32_t) michael@0: JSD_GetScriptFlags(JSDContext *jsdc, JSDScript* jsdscript); michael@0: michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_SetScriptFlags(JSDContext *jsdc, JSDScript* jsdscript, uint32_t flags); michael@0: michael@0: /* michael@0: * Set the private data for this script, returns previous value michael@0: */ michael@0: extern JSD_PUBLIC_API(void *) michael@0: JSD_SetScriptPrivate(JSDScript* jsdscript, void *data); michael@0: michael@0: /* michael@0: * Get the private data for this script michael@0: */ michael@0: extern JSD_PUBLIC_API(void *) michael@0: JSD_GetScriptPrivate(JSDScript* jsdscript); michael@0: michael@0: /* michael@0: * Determine if this script is still loaded in the interpreter michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsActiveScript(JSDContext* jsdc, JSDScript *jsdscript); michael@0: michael@0: /* michael@0: * Get the filename associated with this script michael@0: */ michael@0: extern JSD_PUBLIC_API(const char*) michael@0: JSD_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript); michael@0: michael@0: /* michael@0: * Get the function name associated with this script (nullptr if not a michael@0: * function). If the function does not have a name the result is the michael@0: * string "anonymous". michael@0: * *** new for gecko 2.0 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSString *) michael@0: JSD_GetScriptFunctionId(JSDContext* jsdc, JSDScript *jsdscript); michael@0: michael@0: /* michael@0: * Get the base linenumber of the sourcefile from which this script was loaded. michael@0: * This is one-based -- i.e. the first line of a file is line '1'. This may michael@0: * return 0 if this infomation is unknown. michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetScriptBaseLineNumber(JSDContext* jsdc, JSDScript *jsdscript); michael@0: michael@0: /* michael@0: * Get the count of source lines associated with this script (1 or greater) michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript); michael@0: michael@0: /* michael@0: * Declaration of callback for notification of script creation and destruction. michael@0: * 'creating' is true if creating new script, false if destroying existing michael@0: * script (callback called just before actual destruction). michael@0: * 'callerdata' is what was passed to JSD_SetScriptHook to set the hook. michael@0: */ michael@0: typedef void michael@0: (* JSD_ScriptHookProc)(JSDContext* jsdc, michael@0: JSDScript* jsdscript, michael@0: bool creating, michael@0: void* callerdata); michael@0: michael@0: /* michael@0: * Set a hook to be called when scripts are created or destroyed (loaded or michael@0: * unloaded). michael@0: * 'callerdata' can be whatever you want it to be. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc hook, void* callerdata); michael@0: michael@0: /* michael@0: * Get the current script hook. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_GetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc* hook, void** callerdata); michael@0: michael@0: /* michael@0: * Get a 'Program Counter' value for a given line. This represents the location michael@0: * of the first bit of executable code for this line of source. This 'pc' should michael@0: * be considered an opaque handle. michael@0: * 0 is returned for invalid scripts, or lines that lie outside the script. michael@0: * If no code is on the given line, then the returned pc represents the first michael@0: * code within the script (if any) after the given line. michael@0: * This function can be used to set breakpoints -- see JSD_SetExecutionHook michael@0: */ michael@0: extern JSD_PUBLIC_API(uintptr_t) michael@0: JSD_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, unsigned line); michael@0: michael@0: /* michael@0: * Get the source line number for a given 'Program Counter' location. michael@0: * Returns 0 if no source line information is appropriate (or available) for michael@0: * the given pc. michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetClosestLine(JSDContext* jsdc, JSDScript* jsdscript, uintptr_t pc); michael@0: michael@0: /* michael@0: * Get a list of lines and the corresponding earliest PC for each (see michael@0: * JSD_GetClosestPC). Lines with no PCs associated will not be returned. michael@0: * nullptr may be passed for either lines or pcs to avoid filling anything in michael@0: * for that argument. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_GetLinePCs(JSDContext* jsdc, JSDScript* jsdscript, michael@0: unsigned startLine, unsigned maxLines, michael@0: unsigned* count, unsigned** lines, uintptr_t** pcs); michael@0: michael@0: /* these are only used in cases where scripts are created outside of JS*/ michael@0: michael@0: /* michael@0: * Direct call to notify JSD that a script has been created. michael@0: * Embeddings that use the normal jsapi script functions need not call this. michael@0: * Any embedding that follows the (discouraged!) practice of contructing script michael@0: * structures manually should call this function to inform JSD. (older ssjs michael@0: * systems do this). michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_ScriptCreated(JSDContext* jsdc, michael@0: JSContext *cx, michael@0: const char *filename, /* URL this script loads from */ michael@0: unsigned lineno, /* line where this script starts */ michael@0: JSScript *script, michael@0: JSFunction *fun); michael@0: michael@0: /* michael@0: * see JSD_ScriptCreated michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_ScriptDestroyed(JSDContext* jsdc, michael@0: JSFreeOp *fop, michael@0: JSScript *script); michael@0: michael@0: /***************************************************************************/ michael@0: /* Source Text functions */ michael@0: michael@0: /* michael@0: * In some embeddings (e.g. mozilla) JavaScript source code from a 'file' may be michael@0: * execute before the entire 'file' has even been loaded. This system supports michael@0: * access to such incrmentally loaded source. It also allows for the possibility michael@0: * that source loading may fail or be aborted (though the source that did load michael@0: * may still be usable). Remember that this source is the entire 'file' michael@0: * contents and that the JavaScript code may only be part of that source. michael@0: * michael@0: * For any given URL there can only be one source text item (the most recently michael@0: * loaded). michael@0: */ michael@0: michael@0: /* these coorespond to netscape.jsdebug.SourceTextItem.java values - michael@0: * change in both places if anywhere michael@0: */ michael@0: michael@0: typedef enum michael@0: { michael@0: JSD_SOURCE_INITED = 0, /* initialized, but contains no source yet */ michael@0: JSD_SOURCE_PARTIAL = 1, /* some source loaded, more expected */ michael@0: JSD_SOURCE_COMPLETED = 2, /* all source finished loading */ michael@0: JSD_SOURCE_ABORTED = 3, /* user aborted loading, some may be loaded */ michael@0: JSD_SOURCE_FAILED = 4, /* loading failed, some may be loaded */ michael@0: JSD_SOURCE_CLEARED = 5 /* text has been cleared by debugger */ michael@0: } JSDSourceStatus; michael@0: michael@0: /* michael@0: * Lock the entire source text subsystem. This grabs a highlevel lock that michael@0: * protects the JSD internal information about sources. It is important to michael@0: * wrap source text related calls in this lock in multithreaded situations michael@0: * -- i.e. where the debugger is running on a different thread than the michael@0: * interpreter (or the loader of sources) -- or when multiple debugger michael@0: * threads may be accessing this subsystem. It is safe (and best) to use michael@0: * this locking even if the environment might not be multi-threaded. michael@0: * Safely Nestable. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_LockSourceTextSubsystem(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Unlock the entire source text subsystem. see JSD_LockSourceTextSubsystem. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_UnlockSourceTextSubsystem(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Iterate the source test items. Use the same pattern of calls shown in michael@0: * the example for JSD_IterateScripts - NOTE that the SourceTextSubsystem. michael@0: * must be locked before and unlocked after iterating. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDSourceText*) michael@0: JSD_IterateSources(JSDContext* jsdc, JSDSourceText **iterp); michael@0: michael@0: /* michael@0: * Find the source text item for the given URL (or filename - or whatever michael@0: * string the given embedding uses to describe source locations). michael@0: * Returns nullptr if not found. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDSourceText*) michael@0: JSD_FindSourceForURL(JSDContext* jsdc, const char* url); michael@0: michael@0: /* michael@0: * Get the URL string associated with the given source text item michael@0: */ michael@0: extern JSD_PUBLIC_API(const char*) michael@0: JSD_GetSourceURL(JSDContext* jsdc, JSDSourceText* jsdsrc); michael@0: michael@0: /* michael@0: * Get the actual source text. This gives access to the actual storage of michael@0: * the source - it sHould *not* be written to. michael@0: * The buffer is NOT zero terminated (nor is it guaranteed to have space to michael@0: * hold a zero terminating char). michael@0: * XXX this is 8-bit character data. Unicode source is not yet supported. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_GetSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc, michael@0: const char** ppBuf, int* pLen); michael@0: michael@0: /* michael@0: * Clear the text -- delete the text and set the status to JSD_SOURCE_CLEARED. michael@0: * This is useful if source is done loading and the debugger wishes to store michael@0: * the text data itself (e.g. in a Java String). This allows avoidance of michael@0: * storing the same text in multiple places. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_ClearSourceText(JSDContext* jsdc, JSDSourceText* jsdsrc); michael@0: michael@0: /* michael@0: * Return the status of the source text item. see JSDSourceStatus enum. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDSourceStatus) michael@0: JSD_GetSourceStatus(JSDContext* jsdc, JSDSourceText* jsdsrc); michael@0: michael@0: /* michael@0: * Has the source been altered since the last call to JSD_SetSourceDirty? michael@0: * Use of JSD_IsSourceDirty and JSD_SetSourceDirty is still supported, but michael@0: * discouraged in favor of the JSD_GetSourceAlterCount system. This dirty michael@0: * scheme ASSUMES that there is only one consumer of the data. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc); michael@0: michael@0: /* michael@0: * Clear the dirty flag michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_SetSourceDirty(JSDContext* jsdc, JSDSourceText* jsdsrc, bool dirty); michael@0: michael@0: /* michael@0: * Each time a source text item is altered this value is incremented. Any michael@0: * consumer can store this value when they retieve other data about the michael@0: * source text item and then check later to see if the current value is michael@0: * different from their stored value. Thus they can know if they have stale michael@0: * data or not. NOTE: this value is not gauranteed to start at any given number. michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc); michael@0: michael@0: /* michael@0: * Force an increment in the alter count for a source text item. This is michael@0: * normally automatic when the item changes, but a give consumer may want to michael@0: * force this to amke an item appear to have changed even if it has not. michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_IncrementSourceAlterCount(JSDContext* jsdc, JSDSourceText* jsdsrc); michael@0: michael@0: /* michael@0: * Destroy *all* the source text items michael@0: * (new for server-side USE WITH CARE) michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_DestroyAllSources( JSDContext* jsdc ); michael@0: michael@0: /* functions for adding source items */ michael@0: michael@0: /* michael@0: * Add a new item for a given URL. If an item already exists for the given URL michael@0: * then the old item is removed. michael@0: * 'url' may not be nullptr. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDSourceText*) michael@0: JSD_NewSourceText(JSDContext* jsdc, const char* url); michael@0: michael@0: /* michael@0: * Append text (or change status -- e.g. set completed) for a source text michael@0: * item. Text need not be zero terminated. Callers should consider the returned michael@0: * JSDSourceText to be the 'current' item for future use. This may return michael@0: * nullptr if called after this item has been replaced by a call to michael@0: * JSD_NewSourceText. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDSourceText*) michael@0: JSD_AppendSourceText(JSDContext* jsdc, michael@0: JSDSourceText* jsdsrc, michael@0: const char* text, /* *not* zero terminated */ michael@0: size_t length, michael@0: JSDSourceStatus status); michael@0: michael@0: /* michael@0: * Unicode varient of JSD_AppendSourceText. michael@0: * michael@0: * NOTE: At this point text is stored in 8bit ASCII so this function just michael@0: * extracts the bottom 8bits from each jschar. At some future point we may michael@0: * switch to storing and exposing 16bit Unicode. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDSourceText*) michael@0: JSD_AppendUCSourceText(JSDContext* jsdc, michael@0: JSDSourceText* jsdsrc, michael@0: const jschar* text, /* *not* zero terminated */ michael@0: size_t length, michael@0: JSDSourceStatus status); michael@0: /* michael@0: * Convienence function for adding complete source of url in one call. michael@0: * same as: michael@0: * JSDSourceText* jsdsrc; michael@0: * JSD_LOCK_SOURCE_TEXT(jsdc); michael@0: * jsdsrc = jsd_NewSourceText(jsdc, url); michael@0: * if(jsdsrc) michael@0: * jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc, michael@0: * text, length, JSD_SOURCE_PARTIAL); michael@0: * if(jsdsrc) michael@0: * jsdsrc = jsd_AppendSourceText(jsdc, jsdsrc, michael@0: * nullptr, 0, JSD_SOURCE_COMPLETED); michael@0: * JSD_UNLOCK_SOURCE_TEXT(jsdc); michael@0: * return jsdsrc ? true : false; michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_AddFullSourceText(JSDContext* jsdc, michael@0: const char* text, /* *not* zero terminated */ michael@0: size_t length, michael@0: const char* url); michael@0: michael@0: /***************************************************************************/ michael@0: /* Execution/Interrupt Hook functions */ michael@0: michael@0: /* possible 'type' params for JSD_ExecutionHookProc */ michael@0: #define JSD_HOOK_INTERRUPTED 0 michael@0: #define JSD_HOOK_BREAKPOINT 1 michael@0: #define JSD_HOOK_DEBUG_REQUESTED 2 michael@0: #define JSD_HOOK_DEBUGGER_KEYWORD 3 michael@0: #define JSD_HOOK_THROW 4 michael@0: michael@0: /* legal return values for JSD_ExecutionHookProc */ michael@0: #define JSD_HOOK_RETURN_HOOK_ERROR 0 michael@0: #define JSD_HOOK_RETURN_CONTINUE 1 michael@0: #define JSD_HOOK_RETURN_ABORT 2 michael@0: #define JSD_HOOK_RETURN_RET_WITH_VAL 3 michael@0: #define JSD_HOOK_RETURN_THROW_WITH_VAL 4 michael@0: #define JSD_HOOK_RETURN_CONTINUE_THROW 5 michael@0: michael@0: /* michael@0: * Implement a callback of this form in order to hook execution. michael@0: */ michael@0: typedef unsigned michael@0: (* JSD_ExecutionHookProc)(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: unsigned type, michael@0: void* callerdata, michael@0: JS::Value* rval); michael@0: michael@0: /* possible 'type' params for JSD_CallHookProc */ michael@0: #define JSD_HOOK_TOPLEVEL_START 0 /* about to evaluate top level script */ michael@0: #define JSD_HOOK_TOPLEVEL_END 1 /* done evaluting top level script */ michael@0: #define JSD_HOOK_FUNCTION_CALL 2 /* about to call a function */ michael@0: #define JSD_HOOK_FUNCTION_RETURN 3 /* done calling function */ michael@0: michael@0: /* michael@0: * Implement a callback of this form in order to hook function call/returns. michael@0: * Return true from a TOPLEVEL_START or FUNCTION_CALL type call hook if you michael@0: * want to hear about the TOPLEVEL_END or FUNCTION_RETURN too. Return value is michael@0: * ignored to TOPLEVEL_END and FUNCTION_RETURN type hooks. michael@0: */ michael@0: typedef bool michael@0: (* JSD_CallHookProc)(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: unsigned type, michael@0: void* callerdata); michael@0: michael@0: /* michael@0: * Set Hook to be called whenever the given pc is about to be executed -- michael@0: * i.e. for 'trap' or 'breakpoint' michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetExecutionHook(JSDContext* jsdc, michael@0: JSDScript* jsdscript, michael@0: uintptr_t pc, michael@0: JSD_ExecutionHookProc hook, michael@0: void* callerdata); michael@0: michael@0: /* michael@0: * Clear the hook for this pc michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearExecutionHook(JSDContext* jsdc, michael@0: JSDScript* jsdscript, michael@0: uintptr_t pc); michael@0: michael@0: /* michael@0: * Clear all the pc specific hooks for this script michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearAllExecutionHooksForScript(JSDContext* jsdc, JSDScript* jsdscript); michael@0: michael@0: /* michael@0: * Clear all the pc specific hooks for the entire JSRuntime associated with michael@0: * this JSDContext michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearAllExecutionHooks(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set a hook to be called before the next instruction is executed. Depending michael@0: * on the threading situation and whether or not an JS code is currently michael@0: * executing the hook might be called before this call returns, or at some michael@0: * future time. The hook will continue to be called as each instruction michael@0: * executes until cleared. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetInterruptHook(JSDContext* jsdc, michael@0: JSD_ExecutionHookProc hook, michael@0: void* callerdata); michael@0: michael@0: /* michael@0: * Call the interrupt hook at least once per source line michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_EnableSingleStepInterrupts(JSDContext* jsdc, JSDScript *jsdscript, bool enable); michael@0: michael@0: /* michael@0: * Clear the current interrupt hook. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearInterruptHook(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set the hook that should be called whenever a JSD_ErrorReporter hook michael@0: * returns JSD_ERROR_REPORTER_DEBUG. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetDebugBreakHook(JSDContext* jsdc, michael@0: JSD_ExecutionHookProc hook, michael@0: void* callerdata); michael@0: michael@0: /* michael@0: * Clear the debug break hook michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearDebugBreakHook(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set the hook that should be called when the 'debugger' keyword is michael@0: * encountered by the JavaScript interpreter during execution. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetDebuggerHook(JSDContext* jsdc, michael@0: JSD_ExecutionHookProc hook, michael@0: void* callerdata); michael@0: michael@0: /* michael@0: * Clear the 'debugger' keyword hook michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearDebuggerHook(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set the hook that should be called when a JS exception is thrown. michael@0: * NOTE: the 'do default' return value is: JSD_HOOK_RETURN_CONTINUE_THROW michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetThrowHook(JSDContext* jsdc, michael@0: JSD_ExecutionHookProc hook, michael@0: void* callerdata); michael@0: /* michael@0: * Clear the throw hook michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearThrowHook(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set the hook that should be called when a toplevel script begins or completes. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetTopLevelHook(JSDContext* jsdc, michael@0: JSD_CallHookProc hook, michael@0: void* callerdata); michael@0: /* michael@0: * Clear the toplevel call hook michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearTopLevelHook(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Set the hook that should be called when a function call or return happens. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetFunctionHook(JSDContext* jsdc, michael@0: JSD_CallHookProc hook, michael@0: void* callerdata); michael@0: /* michael@0: * Clear the function call hook michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_ClearFunctionHook(JSDContext* jsdc); michael@0: michael@0: /***************************************************************************/ michael@0: /* Stack Frame functions */ michael@0: michael@0: /* michael@0: * Get the count of call stack frames for the given JSDThreadState michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetCountOfStackFrames(JSDContext* jsdc, JSDThreadState* jsdthreadstate); michael@0: michael@0: /* michael@0: * Get the 'current' call stack frame for the given JSDThreadState michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDStackFrameInfo*) michael@0: JSD_GetStackFrame(JSDContext* jsdc, JSDThreadState* jsdthreadstate); michael@0: michael@0: /* michael@0: * Get the JSContext for the given JSDThreadState michael@0: */ michael@0: extern JSD_PUBLIC_API(JSContext*) michael@0: JSD_GetJSContext(JSDContext* jsdc, JSDThreadState* jsdthreadstate); michael@0: michael@0: /* michael@0: * Get the calling call stack frame for the given frame michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDStackFrameInfo*) michael@0: JSD_GetCallingStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Get the script for the given call stack frame michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDScript*) michael@0: JSD_GetScriptForStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Get the 'Program Counter' for the given call stack frame michael@0: */ michael@0: extern JSD_PUBLIC_API(uintptr_t) michael@0: JSD_GetPCForStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Get the JavaScript Call Object for the given call stack frame. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetCallObjectForStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Get the head of the scope chain for the given call stack frame. michael@0: * the chain can be traversed using JSD_GetValueParent. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetScopeChainForStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Get the 'this' Object for the given call stack frame. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetThisForStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Get the name of the function executing in this stack frame. Especially useful michael@0: * for native frames (without script objects.) michael@0: * *** new for gecko 2.0 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSString *) michael@0: JSD_GetIdForStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * True if stack frame represents a frame created as a result of a debugger michael@0: * evaluation. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsStackFrameDebugger(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * True if stack frame is constructing a new object. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsStackFrameConstructing(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe); michael@0: michael@0: /* michael@0: * Evaluate the given unicode source code in the context of the given stack frame. michael@0: * returns true and puts result in rval on success, false on failure. michael@0: * NOTE: The ErrorReporter hook might be called if this fails. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_EvaluateUCScriptInStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe, michael@0: const jschar *bytes, unsigned length, michael@0: const char *filename, unsigned lineno, michael@0: JS::MutableHandleValue rval); michael@0: michael@0: /* michael@0: * Same as above, but does not eat exceptions. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_AttemptUCScriptInStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe, michael@0: const jschar *bytes, unsigned length, michael@0: const char *filename, unsigned lineno, michael@0: JS::MutableHandleValue rval); michael@0: michael@0: /* single byte character version of JSD_EvaluateUCScriptInStackFrame */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_EvaluateScriptInStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe, michael@0: const char *bytes, unsigned length, michael@0: const char *filename, unsigned lineno, JS::MutableHandleValue rval); michael@0: michael@0: /* michael@0: * Same as above, but does not eat exceptions. michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_AttemptScriptInStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe, michael@0: const char *bytes, unsigned length, michael@0: const char *filename, unsigned lineno, JS::MutableHandleValue rval); michael@0: michael@0: /* michael@0: * Convert the given JS::Value to a string michael@0: * NOTE: The ErrorReporter hook might be called if this fails. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSString*) michael@0: JSD_ValToStringInStackFrame(JSDContext* jsdc, michael@0: JSDThreadState* jsdthreadstate, michael@0: JSDStackFrameInfo* jsdframe, michael@0: JS::Value val); michael@0: michael@0: /* michael@0: * Get the JSDValue currently being thrown as an exception (may be nullptr). michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate); michael@0: michael@0: /* michael@0: * Set the JSDValue currently being thrown as an exception. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate, michael@0: JSDValue* jsdval); michael@0: michael@0: /***************************************************************************/ michael@0: /* Error Reporter functions */ michael@0: michael@0: /* michael@0: * XXX The ErrorReporter Hook scheme is going to change soon to more michael@0: * Fully support exceptions. michael@0: */ michael@0: michael@0: /* legal return values for JSD_ErrorReporter */ michael@0: #define JSD_ERROR_REPORTER_PASS_ALONG 0 /* pass along to regular reporter */ michael@0: #define JSD_ERROR_REPORTER_RETURN 1 /* don't pass to error reporter */ michael@0: #define JSD_ERROR_REPORTER_DEBUG 2 /* force call to DebugBreakHook */ michael@0: #define JSD_ERROR_REPORTER_CLEAR_RETURN 3 /* clear exception and don't pass */ michael@0: michael@0: /* michael@0: * Implement a callback of this form in order to hook the ErrorReporter michael@0: */ michael@0: typedef unsigned michael@0: (* JSD_ErrorReporter)(JSDContext* jsdc, michael@0: JSContext* cx, michael@0: const char* message, michael@0: JSErrorReport* report, michael@0: void* callerdata); michael@0: michael@0: /* Set ErrorReporter hook */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_SetErrorReporter(JSDContext* jsdc, michael@0: JSD_ErrorReporter reporter, michael@0: void* callerdata); michael@0: michael@0: /* Get Current ErrorReporter hook */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_GetErrorReporter(JSDContext* jsdc, michael@0: JSD_ErrorReporter* reporter, michael@0: void** callerdata); michael@0: michael@0: /***************************************************************************/ michael@0: /* Generic locks that callers can use for their own purposes */ michael@0: michael@0: struct JSDStaticLock; michael@0: michael@0: /* michael@0: * Is Locking and GetThread supported in this build? michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsLockingAndThreadIdSupported(); michael@0: michael@0: /* michael@0: * Create a reentrant/nestable lock michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDStaticLock*) michael@0: JSD_CreateLock(); michael@0: michael@0: /* michael@0: * Aquire lock for this thread (or block until available). Increments a michael@0: * counter if this thread already owns the lock. michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_Lock(JSDStaticLock* lock); michael@0: michael@0: /* michael@0: * Release lock for this thread (or decrement the counter if JSD_Lock michael@0: * was previous called more than once). michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_Unlock(JSDStaticLock* lock); michael@0: michael@0: /* michael@0: * For debugging only if not (JS_THREADSAFE AND DEBUG) then returns true michael@0: * So JSD_IsLocked(lock) may not equal !JSD_IsUnlocked(lock) michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsLocked(JSDStaticLock* lock); michael@0: michael@0: /* michael@0: * See above... michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsUnlocked(JSDStaticLock* lock); michael@0: michael@0: /* michael@0: * return an ID uniquely identifying this thread. michael@0: */ michael@0: extern JSD_PUBLIC_API(void*) michael@0: JSD_CurrentThread(); michael@0: michael@0: /***************************************************************************/ michael@0: /* Value and Property Functions --- All NEW for 1.1 --- */ michael@0: michael@0: /* michael@0: * NOTE: JSDValue and JSDProperty objects are reference counted. This allows michael@0: * for rooting these objects AND any underlying garbage collected JS::Values. michael@0: * ALL JSDValue and JSDProperty objects returned by the functions below michael@0: * MUST eventually be released using the appropriate JSD_Dropxxx function. michael@0: */ michael@0: michael@0: /* michael@0: * Create a new JSDValue to wrap the given JS::Value michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_NewValue(JSDContext* jsdc, JS::Value val); michael@0: michael@0: /* michael@0: * Release the JSDValue. After this call the object MUST not be referenced again! michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_DropValue(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Get the JS::Value wrapped by this JSDValue michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JS::Value) michael@0: JSD_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Clear all property and association information about the given JSDValue. michael@0: * Such information will be lazily regenerated when later accessed. This michael@0: * function must be called to make changes to the properties of an object michael@0: * visible to the accessor functions below (if the properties et.al. have michael@0: * changed since a previous call to those accessors). michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_RefreshValue(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /**************************************************/ michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a JSObject? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueObject(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a number (int or double)? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueNumber(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap an int? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueInt(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a double? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueDouble(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a JSString? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueString(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a bool? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueBoolean(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a JSVAL_NULL? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueNull(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a JSVAL_VOID? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueVoid(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a primative (not a JSObject)? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValuePrimitive(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a function? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueFunction(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Does the JSDValue wrap a native function? michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_IsValueNative(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /**************************************************/ michael@0: michael@0: /* michael@0: * Return bool value (does NOT do conversion). michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(bool) michael@0: JSD_GetValueBoolean(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Return int32_t value (does NOT do conversion). michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(int32_t) michael@0: JSD_GetValueInt(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Return double value (does NOT do conversion). michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(double) michael@0: JSD_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Return JSString value (DOES do conversion if necessary). michael@0: * NOTE that the JSString returned is not protected from garbage michael@0: * collection. It should be immediately read or wrapped using michael@0: * JSD_NewValue(jsdc,STRING_TO_JSVAL(str)) if necessary. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSString*) michael@0: JSD_GetValueString(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Return name of function IFF JSDValue represents a function. michael@0: * *** new for gecko 2.0 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSString *) michael@0: JSD_GetValueFunctionId(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Return function object IFF JSDValue represents a function or an object michael@0: * wrapping a function. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSFunction*) michael@0: JSD_GetValueFunction(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /**************************************************/ michael@0: michael@0: /* michael@0: * Return the number of properties for the JSDValue. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetCountOfProperties(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Iterate through the properties of the JSDValue. michael@0: * Use form similar to that shown for JSD_IterateScripts (no locking required). michael@0: * NOTE: each JSDProperty returned must eventually be released by calling michael@0: * JSD_DropProperty. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDProperty*) michael@0: JSD_IterateProperties(JSDContext* jsdc, JSDValue* jsdval, JSDProperty **iterp); michael@0: michael@0: /* michael@0: * Get the JSDProperty for the property of this JSDVal with this name. michael@0: * NOTE: must eventually release by calling JSD_DropProperty (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDProperty*) michael@0: JSD_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name); michael@0: michael@0: /* michael@0: * Get the prototype object for this JSDValue. michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Get the parent object for this JSDValue. michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetValueParent(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Get the ctor object for this JSDValue (or likely its prototype's ctor). michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Get the name of the class for this object. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(const char*) michael@0: JSD_GetValueClassName(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Get the script for the given value if the given value represents a michael@0: * scripted function. Otherwise, return null. michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDScript*) michael@0: JSD_GetScriptForValue(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /**************************************************/ michael@0: michael@0: /* possible or'd together bitflags returned by JSD_GetPropertyFlags michael@0: * michael@0: * XXX these must stay the same as the JSPD_ flags in js/OldDebugAPI.h michael@0: */ michael@0: #define JSDPD_ENUMERATE JSPD_ENUMERATE /* visible to for/in loop */ michael@0: #define JSDPD_READONLY JSPD_READONLY /* assignment is error */ michael@0: #define JSDPD_PERMANENT JSPD_PERMANENT /* property cannot be deleted */ michael@0: #define JSDPD_ALIAS JSPD_ALIAS /* property has an alias id */ michael@0: #define JSDPD_EXCEPTION JSPD_EXCEPTION /* exception occurred looking up */ michael@0: /* proprety, value is exception */ michael@0: #define JSDPD_ERROR JSPD_ERROR /* native getter returned false */ michael@0: /* without throwing an exception */ michael@0: /* this is not one of the JSPD_ flags in js/OldDebugAPI.h - don't overlap! */ michael@0: #define JSDPD_HINTED 0x800 /* found via explicit lookup */ michael@0: michael@0: /* michael@0: * Release this JSDProperty michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_DropProperty(JSDContext* jsdc, JSDProperty* jsdprop); michael@0: michael@0: /* michael@0: * Get the JSDValue represeting the name of this property (int or string) michael@0: * NOTE: must eventually release by calling JSD_DropValue michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetPropertyName(JSDContext* jsdc, JSDProperty* jsdprop); michael@0: michael@0: /* michael@0: * Get the JSDValue represeting the current value of this property michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetPropertyValue(JSDContext* jsdc, JSDProperty* jsdprop); michael@0: michael@0: /* michael@0: * Get the JSDValue represeting the alias of this property (if JSDPD_ALIAS set) michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetPropertyAlias(JSDContext* jsdc, JSDProperty* jsdprop); michael@0: michael@0: /* michael@0: * Get the flags for this property michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetPropertyFlags(JSDContext* jsdc, JSDProperty* jsdprop); michael@0: michael@0: /***************************************************************************/ michael@0: /* Object Functions --- All NEW for 1.1 --- */ michael@0: michael@0: /* michael@0: * JSDObjects exist to allow a means of iterating through all JSObjects in the michael@0: * engine. They are created and destroyed as the wrapped JSObjects are created michael@0: * and destroyed in the engine. JSDObjects additionally track the location in michael@0: * the JavaScript source where their wrapped JSObjects were created and the name michael@0: * and location of the (non-native) constructor used. michael@0: * michael@0: * NOTE: JSDObjects are NOT reference counted. The have only weak links to michael@0: * jsObjects - thus they do not inhibit garbage collection of JSObjects. If michael@0: * you need a JSDObject to safely persist then wrap it in a JSDValue (using michael@0: * jsd_GetValueForObject). michael@0: */ michael@0: michael@0: /* michael@0: * Lock the entire Object subsystem -- see JSD_UnlockObjectSubsystem michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_LockObjectSubsystem(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Unlock the entire Object subsystem -- see JSD_LockObjectSubsystem michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(void) michael@0: JSD_UnlockObjectSubsystem(JSDContext* jsdc); michael@0: michael@0: /* michael@0: * Iterate through the known objects michael@0: * Use form similar to that shown for JSD_IterateScripts. michael@0: * NOTE: the ObjectSubsystem must be locked before and unlocked after iterating. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDObject*) michael@0: JSD_IterateObjects(JSDContext* jsdc, JSDObject** iterp); michael@0: michael@0: /* michael@0: * Get the JSObject represented by this JSDObject michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSObject*) michael@0: JSD_GetWrappedObject(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: /* michael@0: * Get the URL of the line of source that caused this object to be created. michael@0: * May be nullptr. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(const char*) michael@0: JSD_GetObjectNewURL(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: /* michael@0: * Get the line number of the line of source that caused this object to be michael@0: * created. May be 0 indicating that the line number is unknown. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetObjectNewLineNumber(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: /* michael@0: * Get the URL of the line of source of the constructor for this object. michael@0: * May be nullptr. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(const char*) michael@0: JSD_GetObjectConstructorURL(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: /* michael@0: * Get the line number of the line of source of the constructor for this object. michael@0: * created. May be 0 indicating that the line number is unknown. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(unsigned) michael@0: JSD_GetObjectConstructorLineNumber(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: /* michael@0: * Get the name of the constructor for this object. michael@0: * May be nullptr. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(const char*) michael@0: JSD_GetObjectConstructorName(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: /* michael@0: * Get JSDObject representing this JSObject. michael@0: * May return nullptr. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDObject*) michael@0: JSD_GetJSDObjectForJSObject(JSDContext* jsdc, JSObject* jsobj); michael@0: michael@0: /* michael@0: * Get JSDObject representing this JSDValue. michael@0: * May return nullptr. michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDObject*) michael@0: JSD_GetObjectForValue(JSDContext* jsdc, JSDValue* jsdval); michael@0: michael@0: /* michael@0: * Create a JSDValue to wrap (and root) this JSDObject. michael@0: * NOTE: must eventually release by calling JSD_DropValue (if not nullptr) michael@0: * *** new for version 1.1 **** michael@0: */ michael@0: extern JSD_PUBLIC_API(JSDValue*) michael@0: JSD_GetValueForObject(JSDContext* jsdc, JSDObject* jsdobj); michael@0: michael@0: } // extern "C" michael@0: michael@0: #endif /* jsdebug_h___ */