mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 966720: Check Debugger docs into the SpiderMonkey tree. DONTBUILD r=jorendorff
This commit is contained in:
parent
1cfc05dded
commit
446dcb93fb
163
js/src/doc/Debugger/Conventions.md
Normal file
163
js/src/doc/Debugger/Conventions.md
Normal file
@ -0,0 +1,163 @@
|
||||
# General Conventions
|
||||
|
||||
This page describes general conventions used in the [`Debugger`][debugger] API,
|
||||
and defines some terminology used throughout the specification.
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Properties of objects that comprise the `Debugger` interface, and those
|
||||
that the interface creates, follow some general conventions:
|
||||
|
||||
- Instances and prototypes are extensible; you can add your own properties
|
||||
and methods to them.
|
||||
|
||||
- Properties are configurable. This applies to both "own" and prototype
|
||||
properties, and to both methods and data properties. (Leaving these
|
||||
properties open to redefinition will hopefully make it easier for
|
||||
JavaScript debugger code to cope with bugs, bug fixes, and changes in the
|
||||
interface over time.)
|
||||
|
||||
- Method properties are writable.
|
||||
|
||||
- We prefer inherited accessor properties to own data properties. Both are
|
||||
read using the same syntax, but inherited accessors seem like a more
|
||||
accurate reflection of what's going on. Unless otherwise noted, these
|
||||
properties have getters but no setters, as they cannot meaningfully be
|
||||
assigned to.
|
||||
|
||||
|
||||
## Debuggee Values
|
||||
|
||||
The `Debugger` interface follows some conventions to help debuggers safely
|
||||
inspect and modify the debuggee's objects and values. Primitive values are
|
||||
passed freely between debugger and debuggee; copying or wrapping is handled
|
||||
transparently. Objects received from the debuggee (including host objects
|
||||
like DOM elements) are fronted in the debugger by `Debugger.Object`
|
||||
instances, which provide reflection-oriented methods for inspecting their
|
||||
referents; see `Debugger.Object`, below.
|
||||
|
||||
Of the debugger's objects, only `Debugger.Object` instances may be passed
|
||||
to the debuggee: when this occurs, the debuggee receives the
|
||||
`Debugger.Object`'s referent, not the `Debugger.Object` instance itself.
|
||||
|
||||
In the descriptions below, the term "debuggee value" means either a
|
||||
primitive value or a `Debugger.Object` instance; it is a value that might
|
||||
be received from the debuggee, or that could be passed to the debuggee.
|
||||
|
||||
|
||||
## Debuggee Code
|
||||
|
||||
Each `Debugger` instance maintains a set of global objects that, taken
|
||||
together, comprise the debuggee. Code evaluated in the scope of a debuggee
|
||||
global object, directly or indirectly, is considered *debuggee code*.
|
||||
Similarly:
|
||||
|
||||
- a *debuggee frame* is a frame running debuggee code;
|
||||
|
||||
- a *debuggee function* is a function that closes over a debuggee
|
||||
global object (and thus the function's code is debuggee code);
|
||||
|
||||
- a *debuggee environment* is an environment whose outermost
|
||||
enclosing environment is a debuggee global object; and
|
||||
|
||||
- a *debuggee script* is a script containing debuggee code.
|
||||
|
||||
|
||||
## Completion Values
|
||||
|
||||
When a debuggee stack frame completes its execution, or when some sort
|
||||
of debuggee call initiated by the debugger finishes, the `Debugger`
|
||||
interface provides a value describing how the code completed; these are
|
||||
called *completion values*. A completion value has one of the
|
||||
following forms:
|
||||
|
||||
<code>{ return: <i>value</i> }</code>
|
||||
: The code completed normally, returning <i>value</i>. <i>Value</i> is a
|
||||
debuggee value.
|
||||
|
||||
<code>{ yield: <i>value</i> }</code>
|
||||
: <i>(Not yet implemented.)</i> The running code is a generator frame
|
||||
which has yielded <i>value</i>. <i>Value</i> is a debuggee value.
|
||||
|
||||
<code>{ throw: <i>value</i> }</code>
|
||||
: The code threw <i>value</i> as an exception. <i>Value</i> is a debuggee
|
||||
value.
|
||||
|
||||
`null`
|
||||
: The code was terminated, as if by the "slow script" dialog box.
|
||||
|
||||
If control reaches the end of a generator frame, the completion value is
|
||||
<code>{ throw: <i>stop</i> }</code> where <i>stop</i> is a
|
||||
`Debugger.Object` object representing the `StopIteration` object being
|
||||
thrown.
|
||||
|
||||
|
||||
## Resumption Values
|
||||
|
||||
As the debuggee runs, the `Debugger` interface calls various
|
||||
debugger-provided handler functions to report the debuggee's behavior.
|
||||
Some of these calls can return a value indicating how the debuggee's
|
||||
execution should continue; these are called *resumption values*. A
|
||||
resumption value has one of the following forms:
|
||||
|
||||
`undefined`
|
||||
: The debuggee should continue execution normally.
|
||||
|
||||
<code>{ return: <i>value</i> }</code>
|
||||
: Return <i>value</i> immediately as the current value of the function.
|
||||
<i>Value</i> must be a debuggee value. (Most handler functions support
|
||||
this, except those whose descriptions say otherwise.) If the function
|
||||
was called as a constructor (that is, via a `new` expression), then
|
||||
<i>value</i> serves as the value returned by the function's body, not
|
||||
that produced by the `new` expression: if the value is not an object,
|
||||
the `new` expression returns the frame's `this` value.
|
||||
|
||||
<code>{ yield: <i>value</i> }</code>
|
||||
: <i>(Not yet implemented.)</i> Yield <i>value</i> immediately as the
|
||||
next value of the current frame, which must be a generator frame.
|
||||
<i>Value</i> is a debuggee value. The current frame must be a generator
|
||||
frame that has not yet completed in some other way. You may use `yield`
|
||||
resumption values to substitute a new value or one already yielded by a
|
||||
generator, or to make a generator yield additional values.
|
||||
|
||||
<code>{ throw: <i>value</i> }</code>
|
||||
: Throw <i>value</i> as an exception from the current bytecode
|
||||
instruction. <i>Value</i> must be a debuggee value.
|
||||
|
||||
`null`
|
||||
: Terminate the debuggee, as if it had been cancelled by the "slow script"
|
||||
dialog box.
|
||||
|
||||
If a function that would normally return a resumption value to indicate
|
||||
how the debuggee should continue instead throws an exception, we never
|
||||
propagate such an exception to the debuggee; instead, we call the
|
||||
associated `Debugger` instance's `uncaughtExceptionHook` property, as
|
||||
described below.
|
||||
|
||||
|
||||
## The `Debugger.DebuggeeWouldRun` Exception
|
||||
|
||||
Some debugger operations that appear to simply inspect the debuggee's state
|
||||
may actually cause debuggee code to run. For example, reading a variable
|
||||
might run a getter function on the global or on a `with` expression's
|
||||
operand; and getting an object's property descriptor will run a handler
|
||||
trap if the object is a proxy. To protect the debugger's integrity, only
|
||||
methods whose stated purpose is to run debuggee code can do so. These
|
||||
methods are called [invocation functions][inv fr], and they follow certain
|
||||
common conventions to report the debuggee's behavior safely. For other
|
||||
methods, if their normal operation would cause debuggee code to run, they
|
||||
throw an instance of the `Debugger.DebuggeeWouldRun` exception.
|
||||
|
||||
A `Debugger.DebuggeeWouldRun` exception may have a `cause` property,
|
||||
providing more detailed information on why the debuggee would have run. The
|
||||
`cause` property's value is one of the following strings:
|
||||
|
||||
<i>cause</i> value meaning
|
||||
-------------------- --------------------------------------------------------------------------------
|
||||
"proxy" Carrying out the operation would have caused a proxy handler to run.
|
||||
"getter" Carrying out the operation would have caused an object property getter to run.
|
||||
"setter" Carrying out the operation would have caused an object property setter to run.
|
||||
|
||||
If the system can't determine why control attempted to enter the debuggee,
|
||||
it will leave the exception's `cause` property undefined.
|
186
js/src/doc/Debugger/Debugger-API.md
Normal file
186
js/src/doc/Debugger/Debugger-API.md
Normal file
@ -0,0 +1,186 @@
|
||||
# The `Debugger` Interface
|
||||
|
||||
Mozilla's JavaScript engine, SpiderMonkey, provides a debugging interface
|
||||
named `Debugger` which lets JavaScript code observe and manipulate the
|
||||
execution of other JavaScript code. Both Firefox's built-in developer tools
|
||||
and the Firebug add-on use `Debugger` to implement their JavaScript
|
||||
debuggers. However, `Debugger` is quite general, and can be used to
|
||||
implement other kinds of tools like tracers, coverage analysis,
|
||||
patch-and-continue, and so on.
|
||||
|
||||
`Debugger` has three essential qualities:
|
||||
|
||||
- It is a *source level* interface: it operates in terms of the JavaScript
|
||||
language, not machine language. It operates on JavaScript objects, stack
|
||||
frames, environments, and code, and presents a consistent interface
|
||||
regardless of whether the debuggee is interpreted, compiled, or
|
||||
optimized. If you have a strong command of the JavaScript language, you
|
||||
should have all the background you need to use `Debugger` successfully,
|
||||
even if you have never looked into the language's implementation.
|
||||
|
||||
- It is for use *by JavaScript code*. JavaScript is both the debuggee
|
||||
language and the tool implementation language, so the qualities that make
|
||||
JavaScript effective on the web can be brought to bear in crafting tools
|
||||
for developers. As is expected of JavaScript APIs, `Debugger` is a
|
||||
*sound* interface: using (or even misusing) `Debugger` should never cause
|
||||
Gecko to crash. Errors throw proper JavaScript exceptions.
|
||||
|
||||
- It is an *intra-thread* debugging API. Both the debuggee and the code
|
||||
using `Debugger` to observe it must run in the same thread. Cross-thread,
|
||||
cross-process, and cross-device tools must use `Debugger` to observe the
|
||||
debuggee from within the same thread, and then handle any needed
|
||||
communication themselves. (Firefox's builtin tools have a
|
||||
[protocol][protocol] defined for this purpose.)
|
||||
|
||||
In Gecko, the `Debugger` API is available to chrome code only. By design,
|
||||
it ought not to introduce security holes, so in principle it could be made
|
||||
available to content as well; but it is hard to justify the security risks
|
||||
of the additional attack surface.
|
||||
|
||||
|
||||
## Debugger Instances and Shadow Objects
|
||||
|
||||
`Debugger` reflects every aspect of the debuggee's state as a JavaScript
|
||||
value—not just actual JavaScript values like objects and primitives,
|
||||
but also stack frames, environments, scripts, and compilation units, which
|
||||
are not normally accessible as objects in their own right.
|
||||
|
||||
Here is a JavaScript program in the process of running a timer callback function:
|
||||
|
||||
![A running JavaScript program and its Debugger shadows][img-shadows]
|
||||
|
||||
This diagram shows the various types of shadow objects that make up the
|
||||
Debugger API (which all follow some [general conventions][conventions]):
|
||||
|
||||
- A [`Debugger.Object`][object] represents a debuggee object, offering a
|
||||
reflection-oriented API that protects the debugger from accidentally
|
||||
invoking getters, setters, proxy traps, and so on.
|
||||
|
||||
- A [`Debugger.Script`][script] represents a block of JavaScript
|
||||
code—either a function body or a top-level script. Given a
|
||||
`Debugger.Script`, one can set breakpoints, translate between source
|
||||
positions and bytecode offsets (a deviation from the "source level"
|
||||
design principle), and find other static characteristics of the code.
|
||||
|
||||
- A [`Debugger.Frame`][frame] represents a running stack frame. You can use
|
||||
these to walk the stack and find each frame's script and environment. You
|
||||
can also set `onStep` and `onPop` handlers on frames.
|
||||
|
||||
- A [`Debugger.Environment`][environment] represents an environment,
|
||||
associating variable names with storage locations. Environments may
|
||||
belong to a running stack frame, captured by a function closure, or
|
||||
reflect some global object's properties as variables.
|
||||
|
||||
The [`Debugger`][debugger-object] instance itself is not really a shadow of
|
||||
anything in the debuggee; rather, it maintains the set of global objects
|
||||
which are to be considered debuggees. A `Debugger` observes only execution
|
||||
taking place in the scope of these global objects. You can set functions to
|
||||
be called when new stack frames are pushed; when new code is loaded; and so
|
||||
on.
|
||||
|
||||
Omitted from this picture are [`Debugger.Source`][source] instances, which
|
||||
represent JavaScript compilation units. A `Debugger.Source` can furnish a
|
||||
full copy of its source code, and explain how the code entered the system,
|
||||
whether via a call to `eval`, a `<script>` element, or otherwise. A
|
||||
`Debugger.Script` points to the `Debugger.Source` from which it is derived.
|
||||
|
||||
All these types follow some [general conventions][conventions], which you
|
||||
should look through before drilling down into any particular type's
|
||||
specification.
|
||||
|
||||
All shadow objects are unique per `Debugger` and per referent. For a given
|
||||
`Debugger`, there is exactly one `Debugger.Object` that refers to a
|
||||
particular debuggee object; exactly one `Debugger.Frame` for a particular
|
||||
stack frame; and so on. Thus, a tool can store metadata about a shadow's
|
||||
referent as a property on the shadow itself, and count on finding that
|
||||
metadata again if it comes across the same referent. And since shadows are
|
||||
per-`Debugger`, tools can do so without worrying about interfering with
|
||||
other tools that use their own `Debugger` instances.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
You can try out `Debugger` yourself in Firefox's Scratchpad.
|
||||
|
||||
1) Visit the URL `about:config`, and set the `devtools.chrome.enabled`
|
||||
preference to `true`:
|
||||
|
||||
![Setting the 'devtools.chrome.enabled' preference][img-chrome-pref]
|
||||
|
||||
2) Save the following HTML text to a file, and visit the file in your
|
||||
browser:
|
||||
|
||||
<div onclick="var x = 'snoo'; debugger;">Click me!</div>
|
||||
|
||||
3) Open a developer Scratchpad (Menu button > Developer > Scratchpad), and
|
||||
select "Browser" from the "Environment" menu. (This menu will not be
|
||||
present unless you have changed the preference as explained above.)
|
||||
|
||||
![Selecting the 'browser' context in the Scratchpad][img-scratchpad-browser]
|
||||
|
||||
4) Enter the following code in the Scratchpad:
|
||||
|
||||
// This simply defines 'Debugger' in this Scratchpad;
|
||||
// it doesn't actually start debugging anything.
|
||||
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
||||
addDebuggerToGlobal(window);
|
||||
|
||||
// Create a 'Debugger' instance.
|
||||
var dbg = new Debugger;
|
||||
|
||||
// Get the current tab's content window, and make it a debuggee.
|
||||
var w = gBrowser.selectedBrowser.contentWindow.wrappedJSObject;
|
||||
dbg.addDebuggee(w);
|
||||
|
||||
// When the debuggee executes a 'debugger' statement, evaluate
|
||||
// the expression 'x' in that stack frame, and show its value.
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
alert('hit debugger statement; x = ' + frame.eval('x').return);
|
||||
}
|
||||
|
||||
5) In the Scratchpad, ensure that no text is selected, and press the "Run"
|
||||
button.
|
||||
|
||||
6) Now, click on the text that says "Click me!" in the web page. This runs
|
||||
the `div` element's `onclick` handler. When control reaches the
|
||||
`debugger;` statement, `Debugger` calls your callback function, passing
|
||||
a `Debugger.Frame` instance. Your callback function evaluates the
|
||||
expression `x` in the given stack frame, and displays the alert:
|
||||
|
||||
![The Debugger callback displaying an alert][img-example-alert]
|
||||
|
||||
7) Press "Run" in the Scratchpad again. Now, clicking on the "Click me!"
|
||||
text causes *two* alerts to show—one for each `Debugger`
|
||||
instance.
|
||||
|
||||
Multiple `Debugger` instances can observe the same debuggee. Re-running
|
||||
the code in the Scratchpad created a fresh `Debugger` instance, added
|
||||
the same web page as its debuggee, and then registered a fresh
|
||||
`debugger;` statement handler with the new instance. When you clicked
|
||||
on the `div` element, both of them ran. This shows how any number of
|
||||
`Debugger`-based tools can observe a single web page
|
||||
simultaneously—although, since the order in which their handlers
|
||||
run is not specified, such tools should probably only observe, and not
|
||||
influence, the debuggee's behavior.
|
||||
|
||||
8) Close the web page and the Scratchpad.
|
||||
|
||||
Since both the Scratchpad's global object and the debuggee window are
|
||||
now gone, the `Debugger` instances will be garbage collected, since
|
||||
they can no longer have any visible effect on Firefox's behavior. The
|
||||
`Debugger` API tries to interact with garbage collection as
|
||||
transparently as possible; for example, if both a `Debugger.Object`
|
||||
instance and its referent are not reachable, they will both be
|
||||
collected, even while the `Debugger` instance to which the shadow
|
||||
belonged continues to exist.
|
||||
|
||||
|
||||
## Gecko-specific features
|
||||
|
||||
While the `Debugger` core API deals only with concepts common to any
|
||||
JavaScript implementation, it also includes some Gecko-specific features:
|
||||
|
||||
- [Global tracking][global] supports debugging all the code running in a
|
||||
Gecko instance at once—the 'chrome debugging' model.
|
||||
- [Object wrapper][wrapper] functions help manipulate object references
|
||||
that cross privilege boundaries.
|
231
js/src/doc/Debugger/Debugger.Environment.md
Normal file
231
js/src/doc/Debugger/Debugger.Environment.md
Normal file
@ -0,0 +1,231 @@
|
||||
# Debugger.Environment
|
||||
|
||||
A `Debugger.Environment` instance represents a lexical environment,
|
||||
associating names with variables. Each [`Debugger.Frame`][frame] instance
|
||||
representing a debuggee frame has an associated environment object
|
||||
describing the variables in scope in that frame; and each
|
||||
[`Debugger.Object`][object] instance representing a debuggee function has an
|
||||
environment object representing the environment the function has closed
|
||||
over.
|
||||
|
||||
ECMAScript environments form a tree, in which each local environment is
|
||||
parented by its enclosing environment (in ECMAScript terms, its 'outer'
|
||||
environment). We say an environment <i>binds</i> an identifier if that
|
||||
environment itself associates the identifier with a variable, independently
|
||||
of its outer environments. We say an identifier is <i>in scope</i> in an
|
||||
environment if the identifier is bound in that environment or any enclosing
|
||||
environment.
|
||||
|
||||
SpiderMonkey creates `Debugger.Environment` instances as needed as the
|
||||
debugger inspects stack frames and function objects; calling
|
||||
`Debugger.Environment` as a function or constructor raises a `TypeError`
|
||||
exception.
|
||||
|
||||
SpiderMonkey creates exactly one `Debugger.Environment` instance for each
|
||||
environment it presents via a given [`Debugger`][debugger-object] instance:
|
||||
if the debugger encounters the same environment through two different
|
||||
routes (perhaps two functions have closed over the same environment),
|
||||
SpiderMonkey presents the same `Debugger.Environment` instance to the
|
||||
debugger each time. This means that the debugger can use the `==` operator
|
||||
to recognize when two `Debugger.Environment` instances refer to the same
|
||||
environment in the debuggee, and place its own properties on a
|
||||
`Debugger.Environment` instance to store metadata about particular
|
||||
environments.
|
||||
|
||||
(If more than one [`Debugger`][debugger-object] instance is debugging the
|
||||
same code, each [`Debugger`][debugger-object] gets a separate
|
||||
`Debugger.Environment` instance for a given environment. This allows the
|
||||
code using each [`Debugger`][debugger-object] instance to place whatever
|
||||
properties it likes on its own [`Debugger.Object`][object] instances,
|
||||
without worrying about interfering with other debuggers.)
|
||||
|
||||
If a `Debugger.Environment` instance's referent is not a debuggee
|
||||
environment, then attempting to access its properties (other than
|
||||
`inspectable`) or call any its methods throws an instance of `Error`.
|
||||
|
||||
`Debugger.Environment` instances protect their referents from the
|
||||
garbage collector; as long as the `Debugger.Environment` instance is
|
||||
live, the referent remains live. Garbage collection has no visible
|
||||
effect on `Debugger.Environment` instances.
|
||||
|
||||
|
||||
## Accessor Properties of the Debugger.Environment Prototype Object
|
||||
|
||||
A `Debugger.Environment` instance inherits the following accessor
|
||||
properties from its prototype:
|
||||
|
||||
`inspectable`
|
||||
: True if this environment is a debuggee environment, and can therefore
|
||||
be inspected. False otherwise. All other properties and methods of
|
||||
`Debugger.Environment` instances throw if applied to a non-inspectable
|
||||
environment.
|
||||
|
||||
`type`
|
||||
: The type of this environment object, one of the following values:
|
||||
|
||||
* "declarative", indicating that the environment is a declarative
|
||||
environment record. Function calls, calls to `eval`, `let` blocks,
|
||||
`catch` blocks, and the like create declarative environment records.
|
||||
|
||||
* "object", indicating that the environment's bindings are the
|
||||
properties of an object. The global object and DOM elements appear in
|
||||
the chain of environments via object environments. (Note that `with`
|
||||
statements have their own environment type.)
|
||||
|
||||
* "with", indicating that the environment was introduced by a `with`
|
||||
statement.
|
||||
|
||||
`parent`
|
||||
: The environment that encloses this one (the "outer" environment, in
|
||||
ECMAScript terminology), or `null` if this is the outermost environment.
|
||||
|
||||
`object`
|
||||
: A [`Debugger.Object`][object] instance referring to the object whose
|
||||
properties this environment reflects. If this is a declarative
|
||||
environment record, this accessor throws a `TypeError` (since
|
||||
declarative environment records have no such object). Both `"object"`
|
||||
and `"with"` environments have `object` properties that provide the
|
||||
object whose properties they reflect as variable bindings.
|
||||
|
||||
`callee`
|
||||
: If this environment represents the variable environment (the top-level
|
||||
environment within the function, which receives `var` definitions) for
|
||||
a call to a function <i>f</i>, then this property's value is a
|
||||
[`Debugger.Object`][object] instance referring to <i>f</i>. Otherwise,
|
||||
this property's value is `null`.
|
||||
|
||||
|
||||
|
||||
## Function Properties of the Debugger.Environment Prototype Object
|
||||
|
||||
The methods described below may only be called with a `this` value
|
||||
referring to a `Debugger.Environment` instance; they may not be used as
|
||||
methods of other kinds of objects.
|
||||
|
||||
`names()`
|
||||
: Return an array of strings giving the names of the identifiers bound by
|
||||
this environment. The result does not include the names of identifiers
|
||||
bound by enclosing environments.
|
||||
|
||||
<code>getVariable(<i>name</i>)</code>
|
||||
: Return the value of the variable bound to <i>name</i> in this
|
||||
environment, or `undefined` if this environment does not bind
|
||||
<i>name</i>. <i>Name</i> must be a string that is a valid ECMAScript
|
||||
identifier name. The result is a debuggee value.
|
||||
|
||||
JavaScript engines often omit variables from environments, to save space
|
||||
and reduce execution time. If the given variable should be in scope, but
|
||||
`getVariable` is unable to produce its value, it returns an ordinary
|
||||
JavaScript object (not a [`Debugger.Object`][object] instance) whose
|
||||
`optimizedOut` property is `true`.
|
||||
|
||||
This is not an [invocation function][inv fr];
|
||||
if this call would cause debuggee code to run (say, because the
|
||||
environment is a `"with"` environment, and <i>name</i> refers to an
|
||||
accessor property of the `with` statement's operand), this call throws a
|
||||
[`Debugger.DebuggeeWouldRun`][wouldrun]
|
||||
exception.
|
||||
|
||||
<code>setVariable(<i>name</i>, <i>value</i>)</code>
|
||||
: Store <i>value</i> as the value of the variable bound to <i>name</i> in
|
||||
this environment. <i>Name</i> must be a string that is a valid
|
||||
ECMAScript identifier name; <i>value</i> must be a debuggee value.
|
||||
|
||||
If this environment binds no variable named <i>name</i>, throw a
|
||||
`ReferenceError`.
|
||||
|
||||
This is not an [invocation function][inv fr];
|
||||
if this call would cause debuggee code to run, this call throws a
|
||||
[`Debugger.DebuggeeWouldRun`][wouldrun]
|
||||
exception.
|
||||
|
||||
<code>getVariableDescriptor(<i>name</i>)</code>
|
||||
: Return an property descriptor describing the variable bound to
|
||||
<i>name</i> in this environment, of the sort returned by
|
||||
`Debugger.Object.prototype.getOwnPropertyDescriptor`. <i>Name</i> must
|
||||
be a string whose value is a valid ECMAScript identifier name.
|
||||
|
||||
If this is an `"object"` or `"with"` environment record, this simply
|
||||
returns the descriptor for the given property of the environment's
|
||||
object. If this is a declarative environment record, this returns a
|
||||
descriptor reflecting the binding's mutability as the descriptor's
|
||||
`writable` property, and its deletability as the descriptor's
|
||||
`configurable` property. All declarative environment record bindings are
|
||||
marked as `enumerable`. <i>(This isn't great; the semantics of variables
|
||||
in declarative enviroments don't really match those of properties, so
|
||||
writing code that operates properly on descriptors for either kind may
|
||||
be difficult.)</i>
|
||||
|
||||
If this environment binds no variable named <i>name</i>, throw a
|
||||
`ReferenceError`.
|
||||
|
||||
<code>defineVariable(<i>name</i>, <i>descriptor</i>)</code>
|
||||
: Create or reconfigure the variable bound to <i>name</i> in this
|
||||
environment according to <i>descriptor</i>. <i>Descriptor</i> is the
|
||||
sort of value returned by `getVariableDescriptor`. On success, return
|
||||
`undefined`; on failure, throw an appropriate exception. <i>Name</i>
|
||||
must be a string whose value is a valid ECMAScript identifier name.
|
||||
|
||||
If implementation restrictions prevent SpiderMonkey from creating or
|
||||
reconfiguring the variable as requested, this call throws an `Error`
|
||||
exception.
|
||||
|
||||
<code>deleteVariable(<i>name</i>)</code>
|
||||
: Delete this environment's binding for <i>name</i>.
|
||||
|
||||
If this environment binds no variable named <i>name</i>, throw a
|
||||
`ReferenceError`.
|
||||
|
||||
If implementation restrictions prevent SpiderMonkey from deleting the
|
||||
variable as requested, this call throws an `Error` exception.
|
||||
|
||||
<code>find(<i>name</i>)</code>
|
||||
: Return a reference to the innermost environment, starting with this
|
||||
environment, that binds <i>name</i>. If <i>name</i> is not in scope in
|
||||
this environment, return `null`. <i>Name</i> must be a string whose
|
||||
value is a valid ECMAScript identifier name.
|
||||
|
||||
<code>eval(<i>code</i>)</code> <i>(future plan)</i>
|
||||
: Evaluate <i>code</i> in this environment, and return a
|
||||
[completion value][cv] describing how it completed. <i>Code</i> is a
|
||||
string. All extant handler methods, breakpoints, watchpoints, and so on
|
||||
remain active during the call. This function follows the
|
||||
[invocation function conventions][inv fr].
|
||||
|
||||
<i>Code</i> is interpreted as strict mode code when it contains a Use
|
||||
Strict Directive.
|
||||
|
||||
If <i>code</i> is not strict mode code, then variable declarations in
|
||||
<i>code</i> affect this environment. (In the terms used by the
|
||||
ECMAScript specification, the `VariableEnvironment` of the execution
|
||||
context for the eval code is the `VariableEnvironment` this
|
||||
`Debugger.Environment` instance represents.) If implementation
|
||||
restrictions prevent SpiderMonkey from extending this environment as
|
||||
requested, this call throws an `Error` exception.
|
||||
|
||||
<code>evalWithBindings(<i>code</i>, <i>bindings</i>)</code> <i>(future plan)</i>
|
||||
: Like `eval`, but evaluate <i>code</i> in this environment, extended with
|
||||
bindings from the object <i>bindings</i>. For each own enumerable
|
||||
property of <i>bindings</i> named <i>name</i> whose value is
|
||||
<i>value</i>, include a variable in the environment in which <i>code</i>
|
||||
is evaluated named <i>name</i>, whose value is <i>value</i>. Each
|
||||
<i>value</i> must be a debuggee value. (This is not like a `with`
|
||||
statement: <i>code</i> may access, assign to, and delete the introduced
|
||||
bindings without having any effect on the <i>bindings</i> object.)
|
||||
|
||||
This method allows debugger code to introduce temporary bindings that
|
||||
are visible to the given debuggee code and which refer to debugger-held
|
||||
debuggee values, and do so without mutating any existing debuggee
|
||||
environment.
|
||||
|
||||
Note that, like `eval`, declarations in the <i>code</i> passed to
|
||||
`evalWithBindings` affect this environment, even as <i>code</i> is
|
||||
evaluated with <i>bindings</i> visible. (In the terms used by the
|
||||
ECMAScript specification, the `VariableEnvironment` of the execution
|
||||
context for the eval code is the `VariableEnvironment` this environment
|
||||
represents, and the <i>bindings</i> appear in a new declarative
|
||||
environment, which is the eval code's `LexicalEnvironment`.) If
|
||||
implementation restrictions prevent SpiderMonkey from extending this
|
||||
environment as requested, this call throws an `Error` exception.
|
||||
|
||||
|
421
js/src/doc/Debugger/Debugger.Frame.md
Normal file
421
js/src/doc/Debugger/Debugger.Frame.md
Normal file
@ -0,0 +1,421 @@
|
||||
# Debugger.Frame
|
||||
|
||||
A `Debugger.Frame` instance represents a [visible stack frame][vf]. Given a
|
||||
`Debugger.Frame` instance, you can find the script the frame is executing,
|
||||
walk the stack to older frames, find the lexical environment in which the
|
||||
execution is taking place, and so on.
|
||||
|
||||
For a given [`Debugger`][debugger-object] instance, SpiderMonkey creates
|
||||
only one `Debugger.Frame` instance for a given visible frame. Every handler
|
||||
method called while the debuggee is running in a given frame is given the
|
||||
same frame object. Similarly, walking the stack back to a previously
|
||||
accessed frame yields the same frame object as before. Debugger code can
|
||||
add its own properties to a frame object and expect to find them later, use
|
||||
`==` to decide whether two expressions refer to the same frame, and so on.
|
||||
|
||||
(If more than one [`Debugger`][debugger-object] instance is debugging the
|
||||
same code, each [`Debugger`][debugger-object] gets a separate
|
||||
`Debugger.Frame` instance for a given frame. This allows the code using
|
||||
each [`Debugger`][debugger-object] instance to place whatever properties it
|
||||
likes on its `Debugger.Frame` instances, without worrying about interfering
|
||||
with other debuggers.)
|
||||
|
||||
When the debuggee pops a stack frame (say, because a function call has
|
||||
returned or an exception has been thrown from it), the `Debugger.Frame`
|
||||
instance referring to that frame becomes inactive: its `live` property
|
||||
becomes `false`, and accessing its other properties or calling its methods
|
||||
throws an exception. Note that frames only become inactive at times that
|
||||
are predictable for the debugger: when the debuggee runs, or when the
|
||||
debugger removes frames from the stack itself.
|
||||
|
||||
Stack frames that represent the control state of generator-iterator objects
|
||||
behave in a special way, described in [Generator Frames][generator] below.
|
||||
|
||||
|
||||
## Visible Frames
|
||||
|
||||
When inspecting the call stack, [`Debugger`][debugger-object] does not
|
||||
reveal all the frames that are actually present on the stack: while it does
|
||||
reveal all frames running debuggee code, it omits frames running the
|
||||
debugger's own code, and omits most frames running non-debuggee code. We
|
||||
call those stack frames a [`Debugger`][debugger-object] does reveal
|
||||
<i>visible frames</i>.
|
||||
|
||||
A frame is a visible frame if any of the following are true:
|
||||
|
||||
* it is running [debuggee code][dbg code];
|
||||
|
||||
* its immediate caller is a frame running debuggee code; or
|
||||
|
||||
* it is a [`"debugger"` frame][inv fr],
|
||||
representing the continuation of debuggee code invoked by the debugger.
|
||||
|
||||
The "immediate caller" rule means that, when debuggee code calls a
|
||||
non-debuggee function, it looks like a call to a primitive: you see a frame
|
||||
for the non-debuggee function that was accessible to the debuggee, but any
|
||||
further calls that function makes are treated as internal details, and
|
||||
omitted from the stack trace. If the non-debuggee function eventually calls
|
||||
back into debuggee code, then those frames are visible.
|
||||
|
||||
(Note that the debuggee is not considered an "immediate caller" of handler
|
||||
methods it triggers. Even though the debuggee and debugger share the same
|
||||
JavaScript stack, frames pushed for SpiderMonkey's calls to handler methods
|
||||
to report events in the debuggee are never considered visible frames.)
|
||||
|
||||
|
||||
## Invocation Functions and "debugger" Frames
|
||||
|
||||
An <i>invocation function</i> is any function in this interface that allows
|
||||
the debugger to invoke code in the debuggee:
|
||||
`Debugger.Object.prototype.call`, `Debugger.Frame.prototype.eval`, and so
|
||||
on.
|
||||
|
||||
While invocation functions differ in the code to be run and how to pass
|
||||
values to it, they all follow this general procedure:
|
||||
|
||||
1. Let <i>older</i> be the youngest visible frame on the stack, or `null`
|
||||
if there is no such frame. (This is never one of the the debugger's own
|
||||
frames; those never appear as `Debugger.Frame` instances.)
|
||||
|
||||
2. Push a `"debugger"` frame on the stack, with <i>older</i> as its
|
||||
`older` property.
|
||||
|
||||
3. Invoke the debuggee code as appropriate for the given invocation
|
||||
function, with the `"debugger"` frame as its continuation. For example,
|
||||
`Debugger.Frame.prototype.eval` pushes an `"eval"` frame for code it
|
||||
runs, whereas `Debugger.Object.prototype.call` pushes a `"call"` frame.
|
||||
|
||||
4. When the debuggee code completes, whether by returning, throwing an
|
||||
exception or being terminated, pop the `"debugger"` frame, and return an
|
||||
appropriate [completion value][cv] from the invocation function to the
|
||||
debugger.
|
||||
|
||||
When a debugger calls an invocation function to run debuggee code, that
|
||||
code's continuation is the debugger, not the next debuggee code frame.
|
||||
Pushing a `"debugger"` frame makes this continuation explicit, and makes it
|
||||
easier to find the extent of the stack created for the invocation.
|
||||
|
||||
|
||||
## Accessor Properties of the Debugger.Frame Prototype Object
|
||||
|
||||
A `Debugger.Frame` instance inherits the following accessor properties from
|
||||
its prototype:
|
||||
|
||||
`type`
|
||||
: A string describing what sort of frame this is:
|
||||
|
||||
* `"call"`: a frame running a function call. (We may not be able to obtain
|
||||
frames for calls to host functions.)
|
||||
|
||||
* `"eval"`: a frame running code passed to `eval`.
|
||||
|
||||
* `"global"`: a frame running global code (JavaScript that is neither of
|
||||
the above).
|
||||
|
||||
* `"debugger"`: a frame for a call to user code invoked by the debugger
|
||||
(see the `eval` method below).
|
||||
|
||||
`this`
|
||||
: The value of `this` for this frame (a debuggee value).
|
||||
|
||||
`older`
|
||||
: The next-older visible frame, in which control will resume when this
|
||||
frame completes. If there is no older frame, this is `null`. (On a
|
||||
suspended generator frame, the value of this property is `null`; see
|
||||
[Generator Frames][generator].)
|
||||
|
||||
`depth`
|
||||
: The depth of this frame, counting from oldest to youngest; the oldest
|
||||
frame has a depth of zero.
|
||||
|
||||
`live`
|
||||
: True if the frame this `Debugger.Frame` instance refers to is still on
|
||||
the stack (or, in the case of generator-iterator objects, has not yet
|
||||
finished its iteration); false if it has completed execution or been
|
||||
popped in some other way.
|
||||
|
||||
`script`
|
||||
: The script being executed in this frame (a [`Debugger.Script`][script]
|
||||
instance), or `null` on frames that do not represent calls to debuggee
|
||||
code. On frames whose `callee` property is not null, this is equal to
|
||||
`callee.script`.
|
||||
|
||||
`offset`
|
||||
: The offset of the bytecode instruction currently being executed in
|
||||
`script`, or `undefined` if the frame's `script` property is `null`.
|
||||
|
||||
`environment`
|
||||
: The lexical environment within which evaluation is taking place (a
|
||||
[`Debugger.Environment`][environment] instance), or `null` on frames
|
||||
that do not represent the evaluation of debuggee code, like calls
|
||||
non-debuggee functions, host functions or `"debugger"` frames.
|
||||
|
||||
`callee`
|
||||
: The function whose application created this frame, as a debuggee value,
|
||||
or `null` if this is not a `"call"` frame.
|
||||
|
||||
`generator`
|
||||
: True if this frame is a generator frame, false otherwise.
|
||||
|
||||
`constructing`
|
||||
: True if this frame is for a function called as a constructor, false
|
||||
otherwise.
|
||||
|
||||
`arguments`
|
||||
: The arguments passed to the current frame, or `null` if this is not a
|
||||
`"call"` frame. When non-`null`, this is an object, allocated in the
|
||||
same global as the debugger, with `Array.prototype` on its prototype
|
||||
chain, a non-writable `length` property, and properties whose names are
|
||||
array indices. Each property is a read-only accessor property whose
|
||||
getter returns the current value of the corresponding parameter. When
|
||||
the referent frame is popped, the argument value's properties' getters
|
||||
throw an error.
|
||||
|
||||
|
||||
## Handler Methods of Debugger.Frame Instances
|
||||
|
||||
Each `Debugger.Frame` instance inherits accessor properties holding handler
|
||||
functions for SpiderMonkey to call when given events occur in the frame.
|
||||
|
||||
Calls to frames' handler methods are cross-compartment, intra-thread calls:
|
||||
the call takes place in the thread to which the frame belongs, and runs in
|
||||
the compartment to which the handler method belongs.
|
||||
|
||||
`Debugger.Frame` instances inherit the following handler method properties:
|
||||
|
||||
`onStep`
|
||||
: This property must be either `undefined` or a function. If it is a
|
||||
function, SpiderMonkey calls it when execution in this frame makes a
|
||||
small amount of progress, passing no arguments and providing this
|
||||
`Debugger.Frame` instance as the `this`value. The function should
|
||||
return a [resumption value][rv] specifying how the debuggee's execution
|
||||
should proceed.
|
||||
|
||||
What constitutes "a small amount of progress" varies depending on the
|
||||
implementation, but it is fine-grained enough to implement useful
|
||||
"step" and "next" behavior.
|
||||
|
||||
If multiple [`Debugger`][debugger-object] instances each have
|
||||
`Debugger.Frame` instances for a given stack frame with `onStep`
|
||||
handlers set, their handlers are run in an unspecified order. If any
|
||||
`onStep` handler forces the frame to return early (by returning a
|
||||
resumption value other than `undefined`), any remaining debuggers'
|
||||
`onStep` handlers do not run.
|
||||
|
||||
This property is ignored on frames that are not executing debuggee
|
||||
code, like `"call"` frames for calls to host functions and `"debugger"`
|
||||
frames.
|
||||
|
||||
`onPop`
|
||||
: This property must be either `undefined` or a function. If it is a
|
||||
function, SpiderMonkey calls it just before this frame is popped,
|
||||
passing a [completion value][cv] indicating how this frame's execution
|
||||
completed, and providing this `Debugger.Frame` instance as the `this`
|
||||
value. The function should return a [resumption value][rv] indicating
|
||||
how execution should proceed. On newly created frames, this property's
|
||||
value is `undefined`.
|
||||
|
||||
When an `onPop` call reports the completion of a construction call
|
||||
(that is, a function called via the `new` operator), the completion
|
||||
value passed to the handler describes the value returned by the
|
||||
function body. If this value is not an object, it may be different from
|
||||
the value produced by the `new` expression, which will be the value of
|
||||
the frame's `this` property. (In ECMAScript terms, the `onPop` handler
|
||||
receives the value returned by the `[[Call]]` method, not the value
|
||||
returned by the `[[Construct]]` method.)
|
||||
|
||||
When a debugger handler function forces a frame to complete early, by
|
||||
returning a `{ return:... }`, `{ throw:... }`, or `null` resumption
|
||||
value, SpiderMonkey calls the frame's `onPop` handler, if any. The
|
||||
completion value passed in this case reflects the resumption value that
|
||||
caused the frame to complete.
|
||||
|
||||
When SpiderMonkey calls an `onPop` handler for a frame that is throwing
|
||||
an exception or being terminated, and the handler returns `undefined`,
|
||||
then SpiderMonkey proceeds with the exception or termination. That is,
|
||||
an `undefined` resumption value leaves the frame's throwing and
|
||||
termination process undisturbed.
|
||||
|
||||
<i>(Not yet implemented.)</i> When a generator frame yields a value,
|
||||
SpiderMonkey calls its `Debugger.Frame` instance's `onPop` handler
|
||||
method, if present, passing a `yield` resumption value; however, the
|
||||
`Debugger.Frame` instance remains live.
|
||||
|
||||
If multiple [`Debugger`][debugger-object] instances each have
|
||||
`Debugger.Frame` instances for a given stack frame with `onPop`
|
||||
handlers set, their handlers are run in an unspecified order. The
|
||||
resumption value each handler returns establishes the completion value
|
||||
reported to the next handler.
|
||||
|
||||
This property is ignored on `"debugger"` frames.
|
||||
|
||||
`onResume`
|
||||
: This property must be either `undefined` or a function. If it is a
|
||||
function, SpiderMonkey calls it if the current frame is a generator
|
||||
frame whose execution has just been resumed. The function should return
|
||||
a [resumption value][rv] indicating how execution should proceed. On
|
||||
newly created frames, this property's value is `undefined`.
|
||||
|
||||
If the program resumed the generator by calling its `send` method and
|
||||
passing a value, then <i>value</i> is that value. Otherwise,
|
||||
<i>value</i> is `undefined`.
|
||||
|
||||
|
||||
## Function Properties of the Debugger.Frame Prototype Object
|
||||
|
||||
The functions described below may only be called with a `this` value
|
||||
referring to a `Debugger.Frame` instance; they may not be used as
|
||||
methods of other kinds of objects.
|
||||
|
||||
<code id="eval">eval(<i>code</i>, [<i>options</i>])</code>
|
||||
: Evaluate <i>code</i> in the execution context of this frame, and return
|
||||
a [completion value][cv] describing how it completed. <i>Code</i> is a
|
||||
string. If this frame's `environment` property is `null`, throw a
|
||||
`TypeError`. All extant handler methods, breakpoints, watchpoints, and
|
||||
so on remain active during the call. This function follows the
|
||||
[invocation function conventions][inv fr].
|
||||
|
||||
<i>Code</i> is interpreted as strict mode code when it contains a Use
|
||||
Strict Directive, or the code executing in this frame is strict mode
|
||||
code.
|
||||
|
||||
If <i>code</i> is not strict mode code, then variable declarations in
|
||||
<i>code</i> affect the environment of this frame. (In the terms used by
|
||||
the ECMAScript specification, the `VariableEnvironment` of the
|
||||
execution context for the eval code is the `VariableEnvironment` of the
|
||||
execution context that this frame represents.) If implementation
|
||||
restrictions prevent SpiderMonkey from extending this frame's
|
||||
environment as requested, this call throws an Error exception.
|
||||
|
||||
If given, <i>options</i> should be an object whose properties specify
|
||||
details of how the evaluation should occur. The `eval` method
|
||||
recognizes the following properties:
|
||||
|
||||
<code>url</code>
|
||||
: The filename or URL to which we should attribute <i>code</i>. If this
|
||||
property is omitted, the URL defaults to `"debugger eval code"`.
|
||||
|
||||
<code>lineNumber</code>
|
||||
: The line number at which the evaluated code should be claimed to begin
|
||||
within <i>url</i>.
|
||||
|
||||
<code>evalWithBindings(<i>code</i>, <i>bindings</i>, [<i>options</i>])</code>
|
||||
: Like `eval`, but evaluate <i>code</i> in the environment of this frame,
|
||||
extended with bindings from the object <i>bindings</i>. For each own
|
||||
enumerable property of <i>bindings</i> named <i>name</i> whose value is
|
||||
<i>value</i>, include a variable in the environment in which
|
||||
<i>code</i> is evaluated named <i>name</i>, whose value is
|
||||
<i>value</i>. Each <i>value</i> must be a debuggee value. (This is not
|
||||
like a `with` statement: <i>code</i> may access, assign to, and delete
|
||||
the introduced bindings without having any effect on the
|
||||
<i>bindings</i> object.)
|
||||
|
||||
This method allows debugger code to introduce temporary bindings that
|
||||
are visible to the given debuggee code and which refer to debugger-held
|
||||
debuggee values, and do so without mutating any existing debuggee
|
||||
environment.
|
||||
|
||||
Note that, like `eval`, declarations in the <i>code</i> passed to
|
||||
`evalWithBindings` affect the environment of this frame, even as that
|
||||
environment is extended by bindings visible within <i>code</i>. (In the
|
||||
terms used by the ECMAScript specification, the `VariableEnvironment`
|
||||
of the execution context for the eval code is the `VariableEnvironment`
|
||||
of the execution context that this frame represents, and the
|
||||
<i>bindings</i> appear in a new declarative environment, which is the
|
||||
eval code's `LexicalEnvironment`.) If implementation restrictions
|
||||
prevent SpiderMonkey from extending this frame's environment as
|
||||
requested, this call throws an `Error` exception.
|
||||
|
||||
The <i>options</i> argument is as for
|
||||
[`Debugger.Frame.prototype.eval`][fr eval], described above.
|
||||
|
||||
<code>pop(<i>completion</i>)</code> <i>(future plan)</i>
|
||||
: Pop this frame (and any younger frames) from the stack as if this frame
|
||||
had completed as specified by the completion value <i>completion</i>.
|
||||
|
||||
Note that this does <i>not</i> resume the debuggee's execution; it
|
||||
merely adjusts the debuggee's state to what it would be if this frame's
|
||||
execution had completed. The debuggee will only resume execution when
|
||||
you return from the handler method that brought control to the debugger
|
||||
originally.
|
||||
|
||||
This cannot remove any `"call"` frames for calls to host functions from
|
||||
the stack. (We might be able to make this work eventually, but it will
|
||||
take some cleverness.)
|
||||
|
||||
<code>replaceCall(<i>function</i>, <i>this</i>, <i>arguments</i>)</code> <i>(future plan)</i>
|
||||
: Pop any younger frames from the stack, and then change this frame into
|
||||
a frame for a call to <i>function</i>, with the given <i>this</i> value
|
||||
and <i>arguments</i>. <i>This</i> should be a debuggee value, or
|
||||
`{ asConstructor: true }` to invoke <i>function</i> as a constructor,
|
||||
in which case SpiderMonkey provides an appropriate `this` value itself.
|
||||
<i>Arguments</i> should be an array of debuggee values. This frame must
|
||||
be a `"call"` frame.
|
||||
|
||||
This can be used as a primitive in implementing some forms of a "patch
|
||||
and continue" debugger feature.
|
||||
|
||||
Note that this does <i>not</i> resume the debuggee's execution; it
|
||||
merely adjusts the debuggee's state to what it would be if this frame
|
||||
were about to make this call. The debuggee will only resume execution
|
||||
when you return from the handler method that brought control to the
|
||||
debugger originally.
|
||||
|
||||
Like `pop`, this cannot remove `"call"` frames for calls to host
|
||||
functions from the stack.
|
||||
|
||||
|
||||
## Generator Frames
|
||||
|
||||
<i>Not all behavior described in this section has been implemented
|
||||
yet.</i>
|
||||
|
||||
SpiderMonkey supports generator-iterator objects, which produce a series of
|
||||
values by repeatedly suspending the execution of a function or expression.
|
||||
For example, calling a function that uses `yield` produces a
|
||||
generator-iterator object, as does evaluating a generator expression like
|
||||
`(i*i for each (i in [1,2,3]))`.
|
||||
|
||||
A generator-iterator object refers to a stack frame with no fixed
|
||||
continuation frame. While the generator's code is running, its continuation
|
||||
is whatever frame called its `next` method; while the generator is
|
||||
suspended, it has no particular continuation frame; and when it resumes
|
||||
again, the continuation frame for that resumption could be different from
|
||||
that of the previous resumption.
|
||||
|
||||
A `Debugger.Frame` instance representing a generator frame differs from an
|
||||
ordinary stack frame as follows:
|
||||
|
||||
* A generator frame's `generator` property is true.
|
||||
|
||||
* A generator frame disappears from the stack each time the generator
|
||||
yields a value and is suspended, and reappears atop the stack when it is
|
||||
resumed to produce the generator's next value. The same `Debugger.Frame`
|
||||
instance refers to the generator frame until it returns, throws an
|
||||
exception, or is terminated.
|
||||
|
||||
* A generator frame's `older` property refers to the frame's continuation
|
||||
frame while the generator is running, and is `null` while the generator
|
||||
is suspended.
|
||||
|
||||
* A generator frame's `depth` property reflects the frame's position on
|
||||
the stack when the generator is resumed, and is `null` while the
|
||||
generator is suspended.
|
||||
|
||||
* A generator frame's `live` property remains true until the frame
|
||||
returns, throws an exception, or is terminated. Thus, generator frames
|
||||
can be live while not present on the stack.
|
||||
|
||||
The other `Debugger.Frame` methods and accessor properties work as
|
||||
described on generator frames, even when the generator frame is suspended.
|
||||
You may examine a suspended generator frame's variables, and use its
|
||||
`script` and `offset` members to see which `yield` it is suspended at.
|
||||
|
||||
A `Debugger.Frame` instance referring to a generator-iterator frame has a
|
||||
strong reference to the generator-iterator object; the frame (and its
|
||||
object) will live as long as the `Debugger.Frame` instance does. However,
|
||||
when the generator function returns, throws an exception, or is terminated,
|
||||
thus ending the iteration, the `Debugger.Frame` instance becomes inactive
|
||||
and its `live` property becomes `false`, just as would occur for any other
|
||||
sort of frame that is popped. A non-live `Debugger.Frame` instance no
|
||||
longer holds a strong reference to the generator-iterator object.
|
534
js/src/doc/Debugger/Debugger.Object.md
Normal file
534
js/src/doc/Debugger/Debugger.Object.md
Normal file
@ -0,0 +1,534 @@
|
||||
# Debugger.Object
|
||||
|
||||
A `Debugger.Object` instance represents an object in the debuggee,
|
||||
providing reflection-oriented methods to inspect and modify its referent.
|
||||
The referent's properties do not appear directly as properties of the
|
||||
`Debugger.Object` instance; the debugger can access them only through
|
||||
methods like `Debugger.Object.prototype.getOwnPropertyDescriptor` and
|
||||
`Debugger.Object.prototype.defineProperty`, ensuring that the debugger will
|
||||
not inadvertently invoke the referent's getters and setters.
|
||||
|
||||
SpiderMonkey creates exactly one `Debugger.Object` instance for each
|
||||
debuggee object it presents to a given [`Debugger`][debugger-object]
|
||||
instance: if the debugger encounters the same object through two different
|
||||
routes (perhaps two functions are called on the same object), SpiderMonkey
|
||||
presents the same `Debugger.Object` instance to the debugger each time.
|
||||
This means that the debugger can use the `==` operator to recognize when
|
||||
two `Debugger.Object` instances refer to the same debuggee object, and
|
||||
place its own properties on a `Debugger.Object` instance to store metadata
|
||||
about particular debuggee objects.
|
||||
|
||||
JavaScript code in different compartments can have different views of the
|
||||
same object. For example, in Firefox, code in privileged compartments sees
|
||||
content DOM element objects without redefinitions or extensions made to
|
||||
that object's properties by content code. (In Firefox terminology,
|
||||
privileged code sees the element through an "xray wrapper".) To ensure that
|
||||
debugger code sees each object just as the debuggee would, each
|
||||
`Debugger.Object` instance presents its referent as it would be seen from a
|
||||
particular compartment. This "viewing compartment" is chosen to match the
|
||||
way the debugger came across the referent. As a consequence, a single
|
||||
[`Debugger`][debugger-object] instance may actually have several
|
||||
`Debugger.Object` instances: one for each compartment from which the
|
||||
referent is viewed.
|
||||
|
||||
If more than one [`Debugger`][debugger-object] instance is debugging the
|
||||
same code, each [`Debugger`][debugger-object] gets a separate
|
||||
`Debugger.Object` instance for a given object. This allows the code using
|
||||
each [`Debugger`][debugger-object] instance to place whatever properties it
|
||||
likes on its own `Debugger.Object` instances, without worrying about
|
||||
interfering with other debuggers.
|
||||
|
||||
While most `Debugger.Object` instances are created by SpiderMonkey in the
|
||||
process of exposing debuggee's behavior and state to the debugger, the
|
||||
debugger can use `Debugger.Object.prototype.makeDebuggeeValue` to create
|
||||
`Debugger.Object` instances for given debuggee objects, or use
|
||||
`Debugger.Object.prototype.copy` and `Debugger.Object.prototype.create` to
|
||||
create new objects in debuggee compartments, allocated as if by particular
|
||||
debuggee globals.
|
||||
|
||||
`Debugger.Object` instances protect their referents from the garbage
|
||||
collector; as long as the `Debugger.Object` instance is live, the referent
|
||||
remains live. This means that garbage collection has no visible effect on
|
||||
`Debugger.Object` instances.
|
||||
|
||||
|
||||
## Accessor Properties of the Debugger.Object prototype
|
||||
|
||||
A `Debugger.Object` instance inherits the following accessor properties
|
||||
from its prototype:
|
||||
|
||||
`proto`
|
||||
: The referent's prototype (as a new `Debugger.Object` instance), or
|
||||
`null` if it has no prototype.
|
||||
|
||||
`class`
|
||||
: A string naming the ECMAScript `[[Class]]` of the referent.
|
||||
|
||||
`callable`
|
||||
: `true` if the referent is a callable object (such as a function or a
|
||||
function proxy); false otherwise.
|
||||
|
||||
`name`
|
||||
: The name of the referent, if it is a named function. If the referent is
|
||||
an anonymous function, or not a function at all, this is `undefined`.
|
||||
|
||||
This accessor returns whatever name appeared after the `function`
|
||||
keyword in the source code, regardless of whether the function is the
|
||||
result of instantiating a function declaration (which binds the
|
||||
function to its name in the enclosing scope) or evaluating a function
|
||||
expression (which binds the function to its name only within the
|
||||
function's body).
|
||||
|
||||
`displayName`
|
||||
: The referent's display name, if the referent is a function with a
|
||||
display name. If the referent is not a function, or if it has no display
|
||||
name, this is `undefined`.
|
||||
|
||||
If a function has a given name, its display name is the same as its
|
||||
given name. In this case, the `displayName` and `name` properties are
|
||||
equal.
|
||||
|
||||
If a function has no name, SpiderMonkey attempts to infer an appropriate
|
||||
name for it given its context. For example:
|
||||
|
||||
function f() {} // display name: f (the given name)
|
||||
var g = function () {}; // display name: g
|
||||
o.p = function () {}; // display name: o.p
|
||||
var q = {
|
||||
r: function () {} // display name: q.r
|
||||
};
|
||||
|
||||
Note that the display name may not be a proper JavaScript identifier,
|
||||
or even a proper expression: we attempt to find helpful names even when
|
||||
the function is not immediately assigned as the value of some variable
|
||||
or property. Thus, we use <code><i>a</i>/<i>b</i></code> to refer to
|
||||
the <i>b</i> defined within <i>a</i>, and <code><i>a</i><</code> to
|
||||
refer to a function that occurs somewhere within an expression that is
|
||||
assigned to <i>a</i>. For example:
|
||||
|
||||
function h() {
|
||||
var i = function() {}; // display name: h/i
|
||||
f(function () {}); // display name: h/<
|
||||
}
|
||||
var s = f(function () {}); // display name: s<
|
||||
|
||||
`parameterNames`
|
||||
: If the referent is a debuggee function, the names of the its parameters,
|
||||
as an array of strings. If the referent is not a debuggee function, or
|
||||
not a function at all, this is `undefined`.
|
||||
|
||||
If the referent is a host function for which parameter names are not
|
||||
available, return an array with one element per parameter, each of which
|
||||
is `undefined`.
|
||||
|
||||
If the referent is a function proxy, return an empty array.
|
||||
|
||||
If the referent uses destructuring parameters, then the array's elements
|
||||
reflect the structure of the parameters. For example, if the referent is
|
||||
a function declared in this way:
|
||||
|
||||
function f(a, [b, c], {d, e:f}) { ... }
|
||||
|
||||
then this `Debugger.Object` instance's `parameterNames` property would
|
||||
have the value:
|
||||
|
||||
["a", ["b", "c"], {d:"d", e:"f"}]
|
||||
|
||||
`script`
|
||||
: If the referent is a function that is debuggee code, this is that
|
||||
function's script, as a [`Debugger.Script`][script] instance. If the
|
||||
referent is a function proxy or not debuggee code, this is `undefined`.
|
||||
|
||||
`environment`
|
||||
: If the referent is a function that is debuggee code, a
|
||||
[`Debugger.Environment`][environment] instance representing the lexical
|
||||
environment enclosing the function when it was created. If the referent
|
||||
is a function proxy or not debuggee code, this is `undefined`.
|
||||
|
||||
`proxyHandler`
|
||||
: If the referent is a proxy whose handler object was allocated by
|
||||
debuggee code, this is its handler object—the object whose methods are
|
||||
invoked to implement accesses of the proxy's properties. If the referent
|
||||
is not a proxy whose handler object was allocated by debuggee code, this
|
||||
is `null`.
|
||||
|
||||
`proxyCallTrap`
|
||||
: If the referent is a function proxy whose handler object was allocated
|
||||
by debuggee code, this is its call trap function—the function called
|
||||
when the function proxy is called. If the referent is not a function
|
||||
proxy whose handler object was allocated by debuggee code, this is
|
||||
`null`.
|
||||
|
||||
`proxyConstructTrap`
|
||||
: If the referent is a function proxy whose handler object was allocated
|
||||
by debuggee code, its construction trap function—the function called
|
||||
when the function proxy is called via a `new` expression. If the
|
||||
referent is not a function proxy whose handler object was allocated by
|
||||
debuggee code, this is `null`.
|
||||
|
||||
`global`
|
||||
: A `Debugger.Object` instance referring to the global object in whose
|
||||
scope the referent was allocated. This does not unwrap cross-compartment
|
||||
wrappers: if the referent is a wrapper, the result refers to the
|
||||
wrapper's global, not the wrapped object's global. The result refers to
|
||||
the global directly, not via a wrapper.
|
||||
|
||||
`hostAnnotations`
|
||||
: A JavaScript object providing further metadata about the referent, or
|
||||
`null` if none is available. The metadata object is in the same
|
||||
compartment as this `Debugger.Object` instance. The same metadata
|
||||
object is returned each time for a given `Debugger.Object` instance.
|
||||
|
||||
A typical JavaScript embedding provides "host objects" to expose
|
||||
application-specific functionality to scripts. The `hostAnnotations`
|
||||
accessor consults the embedding for additional information about the
|
||||
referent that might be of interest to the debugger. The returned
|
||||
object's properties' meanings are up to the embedding. For example, a
|
||||
web browser might provide host annotations for global objects to
|
||||
distinguish top-level windows, iframes, and internal JavaScript scopes.
|
||||
|
||||
By convention, host annotation objects have a string-valued `"type"`
|
||||
property that, taken together with the object's class, indicate what
|
||||
sort of thing the referent is. The host annotation object's other
|
||||
properties provide further details, as appropriate for the type. For
|
||||
example, in Firefox, a metadata object for a JavaScript Module's global
|
||||
object might look like this:
|
||||
|
||||
{ "type":"jsm", "uri":"resource:://gre/modules/XPCOMUtils.jsm" }
|
||||
|
||||
Firefox provides [DebuggerHostAnnotationsForFirefox annotations] for its
|
||||
host objects.
|
||||
|
||||
|
||||
|
||||
## Function Properties of the Debugger.Object prototype
|
||||
|
||||
The functions described below may only be called with a `this` value
|
||||
referring to a `Debugger.Object` instance; they may not be used as methods
|
||||
of other kinds of objects. The descriptions use "referent" to mean "the
|
||||
referent of this `Debugger.Object` instance".
|
||||
|
||||
Unless otherwise specified, these methods are not
|
||||
[invocation functions][inv fr]; if a call would cause debuggee code to run
|
||||
(say, because it gets or sets an accessor property whose handler is
|
||||
debuggee code, or because the referent is a proxy whose traps are debuggee
|
||||
code), the call throws a [`Debugger.DebuggeeWouldRun`][wouldrun] exception.
|
||||
|
||||
<code>getProperty(<i>name</i>)</code>
|
||||
: Return the value of the referent's property named <i>name</i>, or
|
||||
`undefined` if it has no such property. <i>Name</i> must be a string.
|
||||
The result is a debuggee value.
|
||||
|
||||
<code>setProperty(<i>name</i>, <i>value</i>)</code>
|
||||
: Store <i>value</i> as the value of the referent's property named
|
||||
<i>name</i>, creating the property if it does not exist. <i>Name</i>
|
||||
must be a string; <i>value</i> must be a debuggee value.
|
||||
|
||||
<code>getOwnPropertyDescriptor(<i>name</i>)</code>
|
||||
: Return a property descriptor for the property named <i>name</i> of the
|
||||
referent. If the referent has no such property, return `undefined`.
|
||||
(This function behaves like the standard
|
||||
`Object.getOwnPropertyDescriptor` function, except that the object being
|
||||
inspected is implicit; the property descriptor returned is allocated as
|
||||
if by code scoped to the debugger's global object (and is thus in the
|
||||
debugger's compartment); and its `value`, `get`, and `set` properties,
|
||||
if present, are debuggee values.)
|
||||
|
||||
`getOwnPropertyNames()`
|
||||
: Return an array of strings naming all the referent's own properties, as
|
||||
if <code>Object.getOwnPropertyNames(<i>referent</i>)</code> had been
|
||||
called in the debuggee, and the result copied in the scope of the
|
||||
debugger's global object.
|
||||
|
||||
<code>defineProperty(<i>name</i>, <i>attributes</i>)</code>
|
||||
: Define a property on the referent named <i>name</i>, as described by
|
||||
the property descriptor <i>descriptor</i>. Any `value`, `get`, and
|
||||
`set` properties of <i>attributes</i> must be debuggee values. (This
|
||||
function behaves like `Object.defineProperty`, except that the target
|
||||
object is implicit, and in a different compartment from the function
|
||||
and descriptor.)
|
||||
|
||||
<code>defineProperties(<i>properties</i>)</code>
|
||||
: Add the properties given by <i>properties</i> to the referent. (This
|
||||
function behaves like `Object.defineProperties`, except that the target
|
||||
object is implicit, and in a different compartment from the
|
||||
<i>properties</i> argument.)
|
||||
|
||||
<code>deleteProperty(<i>name</i>)</code>
|
||||
: Remove the referent's property named <i>name</i>. Return true if the
|
||||
property was successfully removed, or if the referent has no such
|
||||
property. Return false if the property is non-configurable.
|
||||
|
||||
`seal()`
|
||||
: Prevent properties from being added to or deleted from the referent.
|
||||
Return this `Debugger.Object` instance. (This function behaves like the
|
||||
standard `Object.seal` function, except that the object to be sealed is
|
||||
implicit and in a different compartment from the caller.)
|
||||
|
||||
`freeze()`
|
||||
: Prevent properties from being added to or deleted from the referent, and
|
||||
mark each property as non-writable. Return this `Debugger.Object`
|
||||
instance. (This function behaves like the standard `Object.freeze`
|
||||
function, except that the object to be sealed is implicit and in a
|
||||
different compartment from the caller.)
|
||||
|
||||
`preventExtensions()`
|
||||
: Prevent properties from being added to the referent. (This function
|
||||
behaves like the standard `Object.preventExtensions` function, except
|
||||
that the object to operate on is implicit and in a different compartment
|
||||
from the caller.)
|
||||
|
||||
`isSealed()`
|
||||
: Return true if the referent is sealed—that is, if it is not extensible,
|
||||
and all its properties have been marked as non-configurable. (This
|
||||
function behaves like the standard `Object.isSealed` function, except
|
||||
that the object inspected is implicit and in a different compartment
|
||||
from the caller.)
|
||||
|
||||
`isFrozen()`
|
||||
: Return true if the referent is frozen—that is, if it is not extensible,
|
||||
and all its properties have been marked as non-configurable and
|
||||
read-only. (This function behaves like the standard `Object.isFrozen`
|
||||
function, except that the object inspected is implicit and in a
|
||||
different compartment from the caller.)
|
||||
|
||||
`isExtensible()`
|
||||
: Return true if the referent is extensible—that is, if it can have new
|
||||
properties defined on it. (This function behaves like the standard
|
||||
`Object.isExtensible` function, except that the object inspected is
|
||||
implicit and in a different compartment from the caller.)
|
||||
|
||||
<code>copy(<i>value</i>)</code>
|
||||
: Apply the HTML5 "structured cloning" algorithm to create a copy of
|
||||
<i>value</i> in the referent's global object (and thus in the referent's
|
||||
compartment), and return a `Debugger.Object` instance referring to the
|
||||
copy.
|
||||
|
||||
Note that this returns primitive values unchanged. This means you can
|
||||
use `Debugger.Object.prototype.copy` as a generic "debugger value to
|
||||
debuggee value" conversion function—within the limitations of the
|
||||
"structured cloning" algorithm.
|
||||
|
||||
<code>create(<i>prototype</i>, [<i>properties</i>])</code>
|
||||
: Create a new object in the referent's global (and thus in the
|
||||
referent's compartment), and return a `Debugger.Object` referring to
|
||||
it. The new object's prototype is <i>prototype</i>, which must be an
|
||||
`Debugger.Object` instance. The new object's properties are as given by
|
||||
<i>properties</i>, as if <i>properties</i> were passed to
|
||||
`Debugger.Object.prototype.defineProperties`, with the new
|
||||
`Debugger.Object` instance as the `this` value.
|
||||
|
||||
<code>makeDebuggeeValue(<i>value</i>)</code>
|
||||
: Return the debuggee value that represents <i>value</i> in the debuggee.
|
||||
If <i>value</i> is a primitive, we return it unchanged; if <i>value</i>
|
||||
is an object, we return the `Debugger.Object` instance representing
|
||||
that object, wrapped appropriately for use in this `Debugger.Object`'s
|
||||
referent's compartment.
|
||||
|
||||
Note that, if <i>value</i> is an object, it need not be one allocated
|
||||
in a debuggee global, nor even a debuggee compartment; it can be any
|
||||
object the debugger wishes to use as a debuggee value.
|
||||
|
||||
As described above, each `Debugger.Object` instance presents its
|
||||
referent as viewed from a particular compartment. Given a
|
||||
`Debugger.Object` instance <i>d</i> and an object <i>o</i>, the call
|
||||
<code><i>d</i>.makeDebuggeeValue(<i>o</i>)</code> returns a
|
||||
`Debugger.Object` instance that presents <i>o</i> as it would be seen
|
||||
by code in <i>d</i>'s compartment.
|
||||
|
||||
<code>decompile([<i>pretty</i>])</code>
|
||||
: If the referent is a function that is debuggee code, return the
|
||||
JavaScript source code for a function definition equivalent to the
|
||||
referent function in its effect and result, as a string. If
|
||||
<i>pretty</i> is present and true, produce indented code with line
|
||||
breaks. If the referent is not a function that is debuggee code, return
|
||||
`undefined`.
|
||||
|
||||
<code>call(<i>this</i>, <i>argument</i>, ...)</code>
|
||||
: If the referent is callable, call it with the given <i>this</i> value
|
||||
and <i>argument</i> values, and return a [completion value][cv]
|
||||
describing how the call completed. <i>This</i> should be a debuggee
|
||||
value, or `{ asConstructor: true }` to invoke the referent as a
|
||||
constructor, in which case SpiderMonkey provides an appropriate `this`
|
||||
value itself. Each <i>argument</i> must be a debuggee value. All extant
|
||||
handler methods, breakpoints, watchpoints, and so on remain active
|
||||
during the call. If the referent is not callable, throw a `TypeError`.
|
||||
This function follows the [invocation function conventions][inv fr].
|
||||
|
||||
<code>apply(<i>this</i>, <i>arguments</i>)</code>
|
||||
: If the referent is callable, call it with the given <i>this</i> value
|
||||
and the argument values in <i>arguments</i>, and return a
|
||||
[completion value][cv] describing how the call completed. <i>This</i>
|
||||
should be a debuggee value, or `{ asConstructor: true }` to invoke
|
||||
<i>function</i> as a constructor, in which case SpiderMonkey provides
|
||||
an appropriate `this` value itself. <i>Arguments</i> must either be an
|
||||
array (in the debugger) of debuggee values, or `null` or `undefined`,
|
||||
which are treated as an empty array. All extant handler methods,
|
||||
breakpoints, watchpoints, and so on remain active during the call. If
|
||||
the referent is not callable, throw a `TypeError`. This function
|
||||
follows the [invocation function conventions][inv fr].
|
||||
|
||||
<code>evalInGlobal(<i>code</i>, [<i>options</i>])</code>
|
||||
: If the referent is a global object, evaluate <i>code</i> in that global
|
||||
environment, and return a [completion value][cv] describing how it completed.
|
||||
<i>Code</i> is a string. All extant handler methods, breakpoints,
|
||||
watchpoints, and so on remain active during the call. This function
|
||||
follows the [invocation function conventions][inv fr].
|
||||
If the referent is not a global object, throw a `TypeError` exception.
|
||||
|
||||
<i>Code</i> is interpreted as strict mode code when it contains a Use
|
||||
Strict Directive.
|
||||
|
||||
If <i>code</i> is not strict mode code, then variable declarations in
|
||||
<i>code</i> affect the referent global object. (In the terms used by the
|
||||
ECMAScript specification, the `VariableEnvironment` of the execution
|
||||
context for the eval code is the referent.)
|
||||
|
||||
The <i>options</i> argument is as for [`Debugger.Frame.prototype.eval`][fr eval].
|
||||
|
||||
<code>evalInGlobalWithBindings(<i>code</i>, <i>bindings</i>, [<i>options</i>])</code>
|
||||
: Like `evalInGlobal`, but evaluate <i>code</i> using the referent as the
|
||||
variable object, but with a lexical environment extended with bindings
|
||||
from the object <i>bindings</i>. For each own enumerable property of
|
||||
<i>bindings</i> named <i>name</i> whose value is <i>value</i>, include a
|
||||
variable in the lexical environment in which <i>code</i> is evaluated
|
||||
named <i>name</i>, whose value is <i>value</i>. Each <i>value</i> must
|
||||
be a debuggee value. (This is not like a `with` statement: <i>code</i>
|
||||
may access, assign to, and delete the introduced bindings without having
|
||||
any effect on the <i>bindings</i> object.)
|
||||
|
||||
This method allows debugger code to introduce temporary bindings that
|
||||
are visible to the given debuggee code and which refer to debugger-held
|
||||
debuggee values, and do so without mutating any existing debuggee
|
||||
environment.
|
||||
|
||||
Note that, like `evalInGlobal`, if the code passed to
|
||||
`evalInGlobalWithBindings` is not strict mode code, then any
|
||||
declarations it contains affect the referent global object, even as
|
||||
<i>code</i> is evaluated in an environment extended according to
|
||||
<i>bindings</i>. (In the terms used by the ECMAScript specification, the
|
||||
`VariableEnvironment` of the execution context for non-strict eval code
|
||||
is the referent, and the <i>bindings</i> appear in a new declarative
|
||||
environment, which is the eval code's `LexicalEnvironment`.)
|
||||
|
||||
The <i>options</i> argument is as for [`Debugger.Frame.prototype.eval`][fr eval].
|
||||
|
||||
`asEnvironment()`
|
||||
: If the referent is a global object, return the [`Debugger.Environment`][environment]
|
||||
instance representing the referent as a variable environment for
|
||||
evaluating code. If the referent is not a global object, throw a
|
||||
`TypeError`.
|
||||
|
||||
<code>setObjectWatchpoint(<i>handler</i>)</code> <i>(future plan)</i>
|
||||
: Set a watchpoint on all the referent's own properties, reporting events
|
||||
by calling <i>handler</i>'s methods. Any previous watchpoint handler on
|
||||
this `Debugger.Object` instance is replaced. If <i>handler</i> is null,
|
||||
the referent is no longer watched. <i>Handler</i> may have the following
|
||||
methods, called under the given circumstances:
|
||||
|
||||
<code>add(<i>frame</i>, <i>name</i>, <i>descriptor</i>)</code>
|
||||
: A property named <i>name</i> has been added to the referent.
|
||||
<i>Descriptor</i> is a property descriptor of the sort accepted by
|
||||
`Debugger.Object.prototype.defineProperty`, giving the newly added
|
||||
property's attributes.
|
||||
|
||||
<code>delete(<i>frame</i>, <i>name</i>)</code>
|
||||
: The property named <i>name</i> is about to be deleted from the referent.
|
||||
|
||||
<code>change(<i>frame</i>, <i>name</i>, <i>oldDescriptor</i>, <i>newDescriptor</i>)</code>
|
||||
: The existing property named <i>name</i> on the referent is being changed
|
||||
from those given by <i>oldDescriptor</i> to those given by
|
||||
<i>newDescriptor</i>. This handler method is only called when attributes
|
||||
of the property other than its value are being changed; if only the
|
||||
value is changing, SpiderMonkey calls the handler's `set` method.
|
||||
|
||||
<code>set(<i>frame</i>, <i>oldValue</i>, <i>newValue</i>)</code>
|
||||
: The data property named <i>name</i> of the referent is about to have its
|
||||
value changed from <i>oldValue</i> to <i>newValue</i>.
|
||||
|
||||
SpiderMonkey only calls this method on assignments to data properties
|
||||
that will succeed; assignments to un-writable data properties fail
|
||||
without notifying the debugger.
|
||||
|
||||
<code>extensionsPrevented(<i>frame</i>)</code>
|
||||
: The referent has been made non-extensible, as if by a call to
|
||||
`Object.preventExtensions`.
|
||||
|
||||
For all watchpoint handler methods:
|
||||
|
||||
* Handler calls receive the handler object itself as the `this` value.
|
||||
|
||||
* The <i>frame</i> argument is the current stack frame, whose code is
|
||||
about to perform the operation on the object being reported.
|
||||
|
||||
* If the method returns `undefined`, then SpiderMonkey makes the announced
|
||||
change to the object, and continues execution normally. If the method
|
||||
returns an object:
|
||||
|
||||
* If the object has a `superseded` property whose value is a true value,
|
||||
then SpiderMonkey does not make the announced change.
|
||||
|
||||
* If the object has a `resume` property, its value is taken as a
|
||||
[resumption value][rv], indicating how
|
||||
execution should proceed. (However, `return` resumption values are not
|
||||
supported.)
|
||||
|
||||
* If a given method is absent from <i>handler</i>, then events of that
|
||||
sort are ignored. The watchpoint consults <i>handler</i>'s properties
|
||||
each time an event occurs, so adding methods to or removing methods from
|
||||
<i>handler</i> after setting the watchpoint enables or disables
|
||||
reporting of the corresponding events.
|
||||
|
||||
* Values passed to <i>handler</i>'s methods are debuggee values.
|
||||
Descriptors passed to <i>handler</i>'s methods are ordinary objects in
|
||||
the debugger's compartment, except for `value`, `get`, and `set`
|
||||
properties in descriptors, which are debuggee values; they are the sort
|
||||
of value expected by `Debugger.Object.prototype.defineProperty`.
|
||||
|
||||
* Watchpoint handler calls are cross-compartment, intra-thread calls: the
|
||||
call takes place in the same thread that changed the property, and in
|
||||
<i>handler</i>'s method's compartment (typically the same as the
|
||||
debugger's compartment).
|
||||
|
||||
The new watchpoint belongs to the [`Debugger`][debugger-object] instance to which this
|
||||
`Debugger.Object` instance belongs; disabling the [`Debugger`][debugger-object] instance
|
||||
disables this watchpoint.
|
||||
|
||||
`clearObjectWatchpoint()` <i>(future plan)</i>
|
||||
: Remove any object watchpoint set on the referent.
|
||||
|
||||
<code>setPropertyWatchpoint(<i>name</i>, <i>handler</i>)</code> <i>(future plan)</i>
|
||||
: Set a watchpoint on the referent's property named <i>name</i>, reporting
|
||||
events by calling <i>handler</i>'s methods. Any previous watchpoint
|
||||
handler on this property for this `Debugger.Object` instance is
|
||||
replaced. If <i>handler</i> is null, the property is no longer watched.
|
||||
<i>Handler</i> is as described for
|
||||
`Debugger.Object.prototype.setObjectWatchpoint`, except that it does not
|
||||
receive `extensionsPrevented` events.
|
||||
|
||||
<code>clearPropertyWatchpoint(<i>name</i>)</code> <i>(future plan)</i>
|
||||
: Remove any watchpoint set on the referent's property named <i>name</i>.
|
||||
|
||||
`unwrap()`
|
||||
: If the referent is a wrapper that this `Debugger.Object`'s compartment
|
||||
is permitted to unwrap, return a `Debugger.Object` instance referring to
|
||||
the wrapped object. If we are not permitted to unwrap the referent,
|
||||
return `null`. If the referent is not a wrapper, return this
|
||||
`Debugger.Object` instance unchanged.
|
||||
|
||||
`unsafeDereference()`
|
||||
: Return the referent of this `Debugger.Object` instance.
|
||||
|
||||
If the referent is an inner object (say, an HTML5 `Window` object),
|
||||
return the corresponding outer object (say, the HTML5 `WindowProxy`
|
||||
object). This makes `unsafeDereference` more useful in producing values
|
||||
appropriate for direct use by debuggee code, without using [invocation functions][inv fr].
|
||||
|
||||
This method pierces the membrane of `Debugger.Object` instances meant to
|
||||
protect debugger code from debuggee code, and allows debugger code to
|
||||
access debuggee objects through the standard cross-compartment wrappers,
|
||||
rather than via `Debugger.Object`'s reflection-oriented interfaces. This
|
||||
method makes it easier to gradually adapt large code bases to this
|
||||
Debugger API: adapted portions of the code can use `Debugger.Object`
|
||||
instances, but use this method to pass direct object references to code
|
||||
that has not yet been updated.
|
238
js/src/doc/Debugger/Debugger.Script.md
Normal file
238
js/src/doc/Debugger/Debugger.Script.md
Normal file
@ -0,0 +1,238 @@
|
||||
# Debugger.Script
|
||||
|
||||
A `Debugger.Script` instance refers to a sequence of bytecode in the
|
||||
debuggee; it is the [`Debugger`][debugger-object] API's presentation of a JSAPI `JSScript`
|
||||
object. Each of the following is represented by single JSScript object:
|
||||
|
||||
* The body of a function—that is, all the code in the function that is not
|
||||
contained within some nested function.
|
||||
|
||||
* The code passed to a single call to `eval`, excluding the bodies of any
|
||||
functions that code defines.
|
||||
|
||||
* The contents of a `<script>` element.
|
||||
|
||||
* A DOM event handler, whether embedded in HTML or attached to the element
|
||||
by other JavaScript code.
|
||||
|
||||
* Code appearing in a `javascript:` URL.
|
||||
|
||||
The [`Debugger`][debugger-object] interface constructs `Debugger.Script` objects as scripts
|
||||
of debuggee code are uncovered by the debugger: via the `onNewScript`
|
||||
handler method; via [`Debugger.Frame`][frame]'s `script` properties; via the
|
||||
`functionScript` method of [`Debugger.Object`][object] instances; and so on. For a
|
||||
given [`Debugger`][debugger-object] instance, SpiderMonkey constructs exactly one
|
||||
`Debugger.Script` instance for each underlying script object; debugger
|
||||
code can add its own properties to a script object and expect to find
|
||||
them later, use `==` to decide whether two expressions refer to the same
|
||||
script, and so on.
|
||||
|
||||
(If more than one [`Debugger`][debugger-object] instance is debugging the same code, each
|
||||
[`Debugger`][debugger-object] gets a separate `Debugger.Script` instance for a given
|
||||
script. This allows the code using each [`Debugger`][debugger-object] instance to place
|
||||
whatever properties it likes on its `Debugger.Script` instances, without
|
||||
worrying about interfering with other debuggers.)
|
||||
|
||||
A `Debugger.Script` instance is a strong reference to a JSScript object;
|
||||
it protects the script it refers to from being garbage collected.
|
||||
|
||||
Note that SpiderMonkey may use the same `Debugger.Script` instances for
|
||||
equivalent functions or evaluated code—that is, scripts representing the
|
||||
same source code, at the same position in the same source file,
|
||||
evaluated in the same lexical environment.
|
||||
|
||||
## Accessor Properties of the Debugger.Script Prototype Object
|
||||
|
||||
A `Debugger.Script` instance inherits the following accessor properties
|
||||
from its prototype:
|
||||
|
||||
`url`
|
||||
: The filename or URL from which this script's code was loaded. If the
|
||||
`source` property is non-`null`, then this is equal to `source.url`.
|
||||
|
||||
`startLine`
|
||||
: The number of the line at which this script's code starts, within the
|
||||
file or document named by `url`.
|
||||
|
||||
`lineCount`
|
||||
: The number of lines this script's code occupies, within the file or
|
||||
document named by `url`.
|
||||
|
||||
`source`
|
||||
: The [`Debugger.Source`][source] instance representing the source code from which
|
||||
this script was produced. This is `null` if the source code was not
|
||||
retained.
|
||||
|
||||
`sourceStart`
|
||||
: The character within the [`Debugger.Source`][source] instance given by `source` at
|
||||
which this script's code starts; zero-based. If this is a function's
|
||||
script, this is the index of the start of the `function` token in the
|
||||
source code.
|
||||
|
||||
`sourceLength`
|
||||
: The length, in characters, of this script's code within the
|
||||
[`Debugger.Source`][source] instance given by `source`.
|
||||
|
||||
`global`
|
||||
: A [`Debugger.Object`][object] instance referring to the global object in whose
|
||||
scope this script runs. The result refers to the global directly, not
|
||||
via a wrapper or a `WindowProxy` ("outer window", in Firefox).
|
||||
|
||||
`staticLevel`
|
||||
: The number of function bodies enclosing this script's code.
|
||||
|
||||
Global code is at level zero; bodies of functions defined at the top
|
||||
level in global code are at level one; bodies of functions nested within
|
||||
those are at level two; and so on.
|
||||
|
||||
A script for code passed to direct `eval` is at a static level one
|
||||
greater than that of the script containing the call to `eval`, because
|
||||
direct eval code runs within the caller's scope. However, a script for
|
||||
code passed to an indirect `eval` call is at static level zero, since it
|
||||
is evaluated in the global scope.
|
||||
|
||||
Note that a generator's expressions are considered to be part of the
|
||||
body of a synthetic function, produced by the compiler.
|
||||
|
||||
Scripts' static level be useful in deciding where to set breakpoints.
|
||||
For example, a breakpoint set on line 3 in this code:
|
||||
|
||||
function f() {
|
||||
x = function g() { // line 2
|
||||
// line 3; no code here
|
||||
...;
|
||||
}
|
||||
}
|
||||
|
||||
should be set in `g`'s script, not in `f`'s, even though neither script
|
||||
contains code at that line. In such a case, the most deeply nested
|
||||
script—the one with the highest static level—should receive the
|
||||
breakpoint.
|
||||
|
||||
`strictMode`
|
||||
: This is `true` if this script's code is ECMAScript strict mode code, and
|
||||
`false` otherwise.
|
||||
|
||||
`sourceMapURL`
|
||||
: If this script was produced by a minimizer or translated from some other
|
||||
language, and we know the URL of a <b>source map</b> document relating
|
||||
the source positions in this script to the corresponding source
|
||||
positions in the original source, then this property's value is that
|
||||
URL. Otherwise, this is `null`.
|
||||
|
||||
(On the web, the translator may provide the source map URL in a
|
||||
specially formatted comment in the JavaScript source code, or via a
|
||||
header in the HTTP reply that carried the generated JavaScript.)
|
||||
|
||||
## Function Properties of the Debugger.Script Prototype Object
|
||||
|
||||
The functions described below may only be called with a `this` value
|
||||
referring to a `Debugger.Script` instance; they may not be used as
|
||||
methods of other kinds of objects.
|
||||
|
||||
<code>decompile([<i>pretty</i>])</code>
|
||||
: Return a string containing JavaScript source code equivalent to this
|
||||
script in its effect and result. If <i>pretty</i> is present and true,
|
||||
produce indented code with line breaks.
|
||||
|
||||
(Note that [`Debugger.Object`][object] instances referring to functions also have
|
||||
a `decompile` method, whose result includes the function header and
|
||||
parameter names, so it is probably better to write
|
||||
<code><i>f</i>.decompile()</code> than to write
|
||||
<code><i>f</i>.getFunctionScript().decompile()</code>.)
|
||||
|
||||
`getAllOffsets()`
|
||||
: Return an array <i>L</i> describing the relationship between bytecode
|
||||
instruction offsets and source code positions in this script. <i>L</i>
|
||||
is sparse, and indexed by source line number. If a source line number
|
||||
<i>line</i> has no code, then <i>L</i> has no <i>line</i> property. If
|
||||
there is code for <i>line</i>, then <code><i>L</i>[<i>line</i>]</code> is an array
|
||||
of offsets of byte code instructions that are entry points to that line.
|
||||
|
||||
For example, suppose we have a script for the following source code:
|
||||
|
||||
a=[]
|
||||
for (i=1; i < 10; i++)
|
||||
// It's hip to be square.
|
||||
a[i] = i*i;
|
||||
|
||||
Calling `getAllOffsets()` on that code might yield an array like this:
|
||||
|
||||
[[0], [5, 20], , [10]]
|
||||
|
||||
This array indicates that:
|
||||
|
||||
* the first line's code starts at offset 0 in the script;
|
||||
|
||||
* the `for` statement head has two entry points at offsets 5 and 20 (for
|
||||
the initialization, which is performed only once, and the loop test,
|
||||
which is performed at the start of each iteration);
|
||||
|
||||
* the third line has no code;
|
||||
|
||||
* and the fourth line begins at offset 10.
|
||||
|
||||
<code>getLineOffsets(<i>line</i>)</code>
|
||||
: Return an array of bytecode instruction offsets representing the entry
|
||||
points to source line <i>line</i>. If the script contains no executable
|
||||
code at that line, the array returned is empty.
|
||||
|
||||
<code>getOffsetLine(<i>offset</i>)</code>
|
||||
: Return the source code line responsible for the bytecode at
|
||||
<i>offset</i> in this script.
|
||||
|
||||
`getChildScripts()`
|
||||
: Return a new array whose elements are Debugger.Script objects for each
|
||||
function and each generator expression in this script. Only direct
|
||||
children are included; nested children can be reached by walking the
|
||||
tree.
|
||||
|
||||
<code>setBreakpoint(<i>offset</i>, <i>handler</i>)</code>
|
||||
: Set a breakpoint at the bytecode instruction at <i>offset</i> in this
|
||||
script, reporting hits to the `hit` method of <i>handler</i>. If
|
||||
<i>offset</i> is not a valid offset in this script, throw an error.
|
||||
|
||||
When execution reaches the given instruction, SpiderMonkey calls the
|
||||
`hit<code> method of <i>handler</i>, passing a [</code>Debugger.Frame`][frame] instance
|
||||
representing the currently executing stack frame. The `hit` method's
|
||||
return value should be a [resumption value][rv], determining how execution should
|
||||
continue.
|
||||
|
||||
Any number of breakpoints may be set at a single location; when control
|
||||
reaches that point, SpiderMonkey calls their handlers in an unspecified
|
||||
order.
|
||||
|
||||
Any number of breakpoints may use the same <i>handler</i> object.
|
||||
|
||||
Breakpoint handler method calls are cross-compartment, intra-thread
|
||||
calls: the call takes place in the same thread that hit the breakpoint,
|
||||
and in the compartment containing the handler function (typically the
|
||||
debugger's compartment).
|
||||
|
||||
The new breakpoint belongs to the [`Debugger`][debugger-object] instance to which this
|
||||
script belongs; disabling the [`Debugger`][debugger-object] instance disables this
|
||||
breakpoint.
|
||||
|
||||
<code>getBreakpoints([<i>offset</i>])</code>
|
||||
: Return an array containing the handler objects for all the breakpoints
|
||||
set at <i>offset</i> in this script. If <i>offset</i> is omitted, return
|
||||
the handlers of all breakpoints set anywhere in this script. If
|
||||
<i>offset</i> is present, but not a valid offset in this script, throw
|
||||
an error.
|
||||
|
||||
<code>clearBreakpoints(handler, [<i>offset</i>])</code>
|
||||
: Remove all breakpoints set in this [`Debugger`][debugger-object] instance that use
|
||||
<i>handler</i> as their handler. If <i>offset</i> is given, remove only
|
||||
those breakpoints set at <i>offset</i> that use <i>handler</i>; if
|
||||
<i>offset</i> is not a valid offset in this script, throw an error.
|
||||
|
||||
Note that, if breakpoints using other handler objects are set at the
|
||||
same location(s) as <i>handler</i>, they remain in place.
|
||||
|
||||
<code>clearAllBreakpoints([<i>offset</i>])</code>
|
||||
: Remove all breakpoints set in this script. If <i>offset</i> is present,
|
||||
remove all breakpoints set at that offset in this script; if
|
||||
<i>offset</i> is not a valid bytecode offset in this script, throw an
|
||||
error.
|
||||
|
||||
|
212
js/src/doc/Debugger/Debugger.Source.md
Normal file
212
js/src/doc/Debugger/Debugger.Source.md
Normal file
@ -0,0 +1,212 @@
|
||||
# Debugger.Source
|
||||
|
||||
A `Debugger.Source` instance represents a piece of JavaScript source
|
||||
code: its properties provide the source code itself as a string, and
|
||||
describe where it came from. Each [`Debugger.Script`][script] instance refers to
|
||||
the `Debugger.Source` instance holding the source code from which it was
|
||||
produced.
|
||||
|
||||
If a single piece of source code contains both top-level code and
|
||||
function definitions, perhaps with nested functions, then the
|
||||
[`Debugger.Script`][script] instances for those all refer to the same
|
||||
`Debugger.Source` instance. Each script indicates the substring of the
|
||||
overall source to which it corresponds.
|
||||
|
||||
A `Debugger.Source` instance may represent only a portion of a larger
|
||||
source document. For example, an HTML document can contain JavaScript in
|
||||
multiple `<script>` elements and event handler content attributes.
|
||||
In this case, there may be either a single `Debugger.Source` instance
|
||||
for the entire HTML document, with each [`Debugger.Script`][script] referring to
|
||||
its substring of the document; or there may be a separate
|
||||
`Debugger.Source` instance for each `<script>` element and
|
||||
attribute. The choice is left up to the implementation.
|
||||
|
||||
If a given piece of source code is presented to the JavaScript
|
||||
implementation more than once, with the same origin metadata, the
|
||||
JavaScript implementation may generate a fresh `Debugger.Source`
|
||||
instance to represent each presentation, or it may use a single
|
||||
`Debugger.Source` instance to represent them all.
|
||||
|
||||
Each [`Debugger`][debugger-object] instance has a separate collection of `Debugger.Source`
|
||||
instances representing the source code that has been presented to the
|
||||
system.
|
||||
|
||||
A debugger may place its own properties on `Debugger.Source` instances,
|
||||
to store metadata about particular pieces of source code.
|
||||
|
||||
|
||||
## Accessor Properties of the Debugger.Source Prototype Object
|
||||
|
||||
A `Debugger.Source` instance inherits the following accessor properties
|
||||
from its prototype:
|
||||
|
||||
`text`
|
||||
: The JavaScript source code, as a string. The value satisfies the
|
||||
`Program`, `FunctionDeclaration`, or `FunctionExpression` productions in
|
||||
the ECMAScript standard.
|
||||
|
||||
`enclosingStart` <i>(future plan)</i>
|
||||
: The position within the enclosing document at which this source's text
|
||||
starts. This is a zero-based character offset. (The length of this
|
||||
script within the enclosing document is `source.length`.)
|
||||
|
||||
`lineCount` <i>(future plan)</i>
|
||||
: The number of lines in the source code. If there are characters after
|
||||
the last newline in the source code, those count as a final line;
|
||||
otherwise, `lineCount` is equal to the number of newlines in the source
|
||||
code.
|
||||
|
||||
`url`
|
||||
: The URL from which this source was loaded, if this source was loaded
|
||||
from a URL. Otherwise, this is `undefined`. Source may be loaded from a
|
||||
URL in the following ways:
|
||||
|
||||
* The URL may appear as the `src` attribute of a `<script>` element
|
||||
in markup text.
|
||||
|
||||
* The URL may be passed to the `Worker` web worker constructor, or the web
|
||||
worker `importScripts` function.
|
||||
|
||||
* The URL may be the name of a XPCOM JavaScript module or subscript.
|
||||
|
||||
(Note that code passed to `eval`, the `Function` constructor, or a
|
||||
similar function is <i>not</i> considered to be loaded from a URL; the
|
||||
`url` accessor on `Debugger.Source` instances for such sources should
|
||||
return `undefined`.)
|
||||
|
||||
`element`
|
||||
: The [`Debugger.Object`][object] instance referring to the DOM element to which
|
||||
this source code belongs, if any, or `undefined` if it belongs to no DOM
|
||||
element. Source belongs to a DOM element in the following cases:
|
||||
|
||||
* Source belongs to a `<script>` element if it is the element's text
|
||||
content (that is, it is written out as the body of the `<script>`
|
||||
element in the markup text), or is the source document referenced by its
|
||||
`src` attribute.
|
||||
|
||||
* Source belongs to a DOM element if it is an event handler content
|
||||
attribute (that is, if it is written out in the markup text as an
|
||||
attribute value).
|
||||
|
||||
* Source belongs to a DOM element if it was assigned to one of the
|
||||
element's event handler IDL attributes as a string. (Note that one may
|
||||
assign both strings and functions to DOM elements' event handler IDL
|
||||
attributes. If one assigns a function, that function's script's source
|
||||
does <i>not</i> belong to the DOM element; the function's definition
|
||||
must appear elsewhere.)
|
||||
|
||||
(If the sources attached to a DOM element change, the `Debugger.Source`
|
||||
instances representing superceded code still refer to the DOM element;
|
||||
this accessor only reflects origins, not current relationships.)
|
||||
|
||||
`elementAttributeName`
|
||||
: If this source belongs to a DOM element because it is an event handler
|
||||
content attribute or an event handler IDL attribute, this is the name of
|
||||
that attribute, a string. Otherwise, this is `undefined`.
|
||||
|
||||
`introductionType`
|
||||
: A string indicating how this source code was introduced into the system.
|
||||
This accessor returns one of the following values:
|
||||
|
||||
* `"eval"`, for code passed to `eval`.
|
||||
|
||||
* `"Function"`, for code passed to the `Function` constructor.
|
||||
|
||||
* `"Worker"`, for code loaded by calling the Web worker constructor—the
|
||||
worker's main script.
|
||||
|
||||
* `"importScripts"`, for code by calling `importScripts` in a web worker.
|
||||
|
||||
* `"eventHandler"`, for code assigned to DOM elements' event handler IDL
|
||||
attributes as a string.
|
||||
|
||||
* `"scriptElement"`, for code belonging to `<script>` elements.
|
||||
|
||||
* `"javascriptURL"`, for code presented in `javascript:` URLs.
|
||||
|
||||
* `"setTimeout"`, for code passed to `setTimeout` as a string.
|
||||
|
||||
* `"setInterval"`, for code passed to `setInterval` as a string.
|
||||
|
||||
* `undefined`, if the implementation doesn't know how the code was
|
||||
introduced.
|
||||
|
||||
`introductionScript`, `introductionScriptOffset` <i>(future plan)</i>
|
||||
: If this source was introduced by calling a function from debuggee code,
|
||||
then `introductionScript` is the [`Debugger.Script`][script] instance referring to
|
||||
the script containing that call, and `introductionScriptOffset` is the
|
||||
call's bytecode offset within that script. Otherwise, these are both
|
||||
`undefined`. Taken together, these properties indicate the location of
|
||||
the introducing call.
|
||||
|
||||
For the purposes of these accessors, assignments to accessor properties
|
||||
are treated as function calls. Thus, setting a DOM element's event
|
||||
handler IDL attribute by assigning to the corresponding JavaScript
|
||||
property creates a source whose `introductionScript` and
|
||||
`introductionScriptOffset` refer to the property assignment.
|
||||
|
||||
Since a `<script>` element parsed from a web page's original HTML
|
||||
was not introduced by any scripted call, its source's
|
||||
`introductionScript` and `introductionScriptOffset` accessors both
|
||||
return `undefined`.
|
||||
|
||||
If a `<script>` element was dynamically inserted into a document,
|
||||
then these accessors refer to the call that actually caused the script
|
||||
to run—usually the call that made the element part of the document.
|
||||
Thus, they do <i>not</i> refer to the call that created the element;
|
||||
stored the source as the element's text child; made the element a child
|
||||
of some uninserted parent node that was later inserted; or the like.
|
||||
|
||||
Although the main script of a worker thread is introduced by a call to
|
||||
`Worker` or `SharedWorker`, these accessors always return `undefined` on
|
||||
such script's sources. A worker's main script source and the call that
|
||||
created the worker are always in separate threads, but [`Debugger`][debugger-object] is an
|
||||
inherently single-threaded facility: its debuggees must all run in the
|
||||
same thread. Since the global that created the worker is in a different
|
||||
thread, it is guaranteed not to be a debuggee of the [`Debugger`][debugger-object] instance
|
||||
that owns this source; and thus the creating call is never "in debuggee
|
||||
code". Relating a worker to its creator, and other multi-threaded
|
||||
debugging concerns, are out of scope for [`Debugger`][debugger-object].
|
||||
|
||||
|
||||
|
||||
## Function Properties of the Debugger.Source Prototype Object
|
||||
|
||||
<code>substring(<i>start</i>, [<i>end</i>])</code> <i>(future plan)</i>
|
||||
: Return a substring of this instance's `source` property, starting at
|
||||
<i>start</i> and extending to, but not including, <i>end</i>. If
|
||||
<i>end</i> is `undefined`, the substring returned extends to the end of
|
||||
the source.
|
||||
|
||||
Both indices are zero-based. If either is `NaN` or negative, it is
|
||||
replaced with zero. If either is greater than the length of the source,
|
||||
it is replaced with the length of the source. If <i>start</i> is larger
|
||||
than <i>end</i>, they are swapped. (This is meant to be consistent with
|
||||
the way `String.prototype.substring` interprets its arguments.)
|
||||
|
||||
<code>lineToPosition(<i>line</i>)</code> <i>(future plan)</i>
|
||||
: Return an object of the form
|
||||
<code>{ line:<i>line</i>, start:<i>start</i>, length:<i>length</i> }</code>, where
|
||||
<i>start</i> is the character index within `source` of the first
|
||||
character of line number <i>line</i>, and <i>length</i> is the length of
|
||||
that line in characters, including the final newline, if any. The first
|
||||
line is numbered one. If <i>line</i> is negative or greater than the
|
||||
number of lines in this `Debugger.Source` instance, then return `null`.
|
||||
|
||||
<code>positionToLine(<i>start</i>)</code> <i>(future plan)</i>
|
||||
: Return an object of the form
|
||||
<code>{ line:<i>line</i>, start:<i>start</i>, length:<i>length</i> }</code>, where
|
||||
<i>line</i> is the line number containing the character position
|
||||
<i>start</i>, and <i>length</i> is the length of that line in
|
||||
characters, including the final newline, if any. The first line is
|
||||
numbered one. If <i>start</i> is negative or greater than the length of
|
||||
the source code, then return `null`.
|
||||
|
||||
<code>findScripts(<i>query</i>)</code> <i>(future plan)</i>
|
||||
: Return an array of [`Debugger.Script`][script] instances for all debuggee scripts
|
||||
matching <i>query</i> that are produced from this `Debugger.Source`
|
||||
instance. Aside from the restriction to scripts produced from this
|
||||
source, <i>query</i> is interpreted as for
|
||||
`Debugger.prototype.findScripts`.
|
||||
|
||||
|
395
js/src/doc/Debugger/Debugger.md
Normal file
395
js/src/doc/Debugger/Debugger.md
Normal file
@ -0,0 +1,395 @@
|
||||
# The Debugger Object
|
||||
|
||||
When called as a constructor, the `Debugger` object creates a new
|
||||
`Debugger` instance.
|
||||
|
||||
<code>new Debugger([<i>global</i>, ...])</code>
|
||||
: Create a debugger object, and apply its [`addDebuggee`][add] method to
|
||||
each of the given <i>global</i> objects to add them as the initial
|
||||
debuggees.
|
||||
|
||||
## Accessor Properties of the Debugger Prototype Object
|
||||
|
||||
A `Debugger` instance inherits the following accessor properties from
|
||||
its prototype:
|
||||
|
||||
`enabled`
|
||||
: A boolean value indicating whether this `Debugger` instance's handlers,
|
||||
breakpoints, watchpoints, and the like are currently enabled. It is an
|
||||
accessor property with a getter and setter: assigning to it enables or
|
||||
disables this `Debugger` instance; reading it produces true if the
|
||||
instance is enabled, or false otherwise. This property is initially
|
||||
`true` in a freshly created `Debugger` instance.
|
||||
|
||||
This property gives debugger code a single point of control for
|
||||
disentangling itself from the debuggee, regardless of what sort of
|
||||
events or handlers or "points" we add to the interface.
|
||||
|
||||
`uncaughtExceptionHook`
|
||||
: Either `null` or a function that SpiderMonkey calls when a call to a
|
||||
debug event handler, breakpoint handler, watchpoint handler, or similar
|
||||
function throws some exception, which we refer to as
|
||||
<i>debugger-exception</i> here. Exceptions thrown in the debugger are
|
||||
not propagated to debuggee code; instead, SpiderMonkey calls this
|
||||
function, passing <i>debugger-exception</i> as its sole argument and
|
||||
the `Debugger` instance as the `this` value. This function should
|
||||
return a [resumption value][rv], which determines how the debuggee
|
||||
should continue.
|
||||
|
||||
If the uncaught exception hook itself throws an exception,
|
||||
<i>uncaught-hook-exception</i>, SpiderMonkey throws a new error object,
|
||||
<i>confess-to-debuggee-exception</i>, to the debuggee whose message
|
||||
blames the debugger, and includes textual descriptions of
|
||||
<i>uncaught-hook-exception</i> and the original
|
||||
<i>debugger-exception</i>.
|
||||
|
||||
If `uncaughtExceptionHook`'s value is `null`, SpiderMonkey throws an
|
||||
exception to the debuggee whose message blames the debugger, and
|
||||
includes a textual description of <i>debugger-exception</i>.
|
||||
|
||||
Assigning anything other than a callable value or `null` to this
|
||||
property throws a `TypeError` exception.
|
||||
|
||||
(This is not an ideal way to handle debugger bugs, but the hope here is
|
||||
that some sort of backstop, even if imperfect, will make life easier for
|
||||
debugger developers. For example, an uncaught exception hook may have
|
||||
access to browser-level features like the `alert` function, which this
|
||||
API's implementation does not, making it possible to present debugger
|
||||
errors to the developer in a way suited to the context.)
|
||||
|
||||
|
||||
## Debugger Handler Functions
|
||||
|
||||
Each `Debugger` instance inherits accessor properties with which you can
|
||||
store handler functions for SpiderMonkey to call when given events occur
|
||||
in debuggee code.
|
||||
|
||||
When one of the events described below occurs in debuggee code, the engine
|
||||
pauses the debuggee and calls the corresponding debugging handler on each
|
||||
`Debugger` instance that is observing the debuggee. The handler functions
|
||||
receive the `Debugger` instance as their `this` value. Most handler
|
||||
functions can return a [resumption value][rv] indicating how the debuggee's
|
||||
execution should proceed.
|
||||
|
||||
On a new `Debugger` instance, each of these properties is initially
|
||||
`undefined`. Any value assigned to a debugging handler must be either a
|
||||
function or `undefined`; otherwise a `TypeError` is thrown.
|
||||
|
||||
Handler functions run in the same thread in which the event occurred.
|
||||
They run in the compartment to which they belong, not in a debuggee
|
||||
compartment.
|
||||
|
||||
<code>onNewScript(<i>script</i>, <i>global</i>)</code>
|
||||
: New code, represented by the [`Debugger.Script`][script] instance
|
||||
<i>script</i>, has been loaded in the scope of the debuggee global
|
||||
object <i>global</i>. <i>global</i> is a [`Debugger.Object`][object]
|
||||
instance whose referent is the global object.
|
||||
|
||||
This method's return value is ignored.
|
||||
|
||||
<code>onDebuggerStatement(<i>frame</i>)</code>
|
||||
: Debuggee code has executed a <i>debugger</i> statement in <i>frame</i>.
|
||||
This method should return a [resumption value][rv] specifying how the
|
||||
debuggee's execution should proceed.
|
||||
|
||||
<code>onEnterFrame(<i>frame</i>)</code>
|
||||
: The stack frame <i>frame</i> is about to begin executing code.
|
||||
(Naturally, <i>frame</i> is currently the youngest
|
||||
[visible frame][vf].) This method should return
|
||||
a [resumption value][rv] specifying how the debuggee's execution should
|
||||
proceed.
|
||||
|
||||
SpiderMonkey only calls `onEnterFrame` to report
|
||||
[visible][vf], non-`"debugger"` frames.
|
||||
|
||||
<code>onThrow(<i>frame</i>, <i>value</i>) <i>(future plan)</i></code>
|
||||
: The exception <i>value</i> is being thrown by <i>frame</i>, which is
|
||||
running debuggee code. This method should return a
|
||||
[resumption value][rv] specifying how the debuggee's execution should
|
||||
proceed. If it returns `undefined`, the exception is thrown as normal.
|
||||
|
||||
A call to the `onThrow` handler is typically followed by one or more
|
||||
calls to the `onExceptionUnwind` handler.
|
||||
|
||||
*(pending discussion)* If the debuggee executes
|
||||
`try { throw 0; } finally { f(); }` and `f()` executes without error,
|
||||
the `onThrow` handler is called only once. The debugger is not notified
|
||||
when the exception is set aside in order to execute the `finally` block,
|
||||
nor when it is restored after the `finally` block completes normally.
|
||||
|
||||
*(An alternative design here would be: onException(status, frame, value)
|
||||
where status is one of the strings "throw", "unwind", "catch",
|
||||
"finally", "rethrow". JS\_SaveExceptionState would trigger a "finally"
|
||||
event, JS\_RestoreExceptionState would trigger a "rethrow",
|
||||
JS\_ClearPendingException would trigger a "catch"; not sure what
|
||||
JS\_DropExceptionState or a return/throw from a finally block should
|
||||
do.)*
|
||||
|
||||
<code>onExceptionUnwind(<i>frame</i>, <i>value</i>)</code>
|
||||
: The exception <i>value</i> has been thrown, and has propagated to
|
||||
<i>frame</i>; <i>frame</i> is the youngest remaining stack frame, and is a
|
||||
debuggee frame. This method should return a [resumption value][rv]
|
||||
specifying how the debuggee's execution should proceed. If it returns
|
||||
`undefined`, the exception continues to propagate as normal: if control in
|
||||
`frame` is in a `try` block, control jumps to the corresponding `catch` or
|
||||
`finally` block; otherwise, <i>frame</i> is popped, and the exception
|
||||
propagates to <i>frame</i>'s caller.
|
||||
|
||||
When an exception's propagation causes control to enter a `finally`
|
||||
block, the exception is temporarily set aside. If the `finally` block
|
||||
finishes normally, the exception resumes propagation, and the debugger's
|
||||
`onExceptionUnwind` handler is called again, in the same frame. (The
|
||||
other possibility is for the `finally` block to exit due to a `return`,
|
||||
`continue`, or `break` statement, or a new exception. In those cases the
|
||||
old exception does not continue to propagate; it is discarded.)
|
||||
|
||||
<code>sourceHandler(<i>ASuffusionOfYellow</i>)</code>
|
||||
: This method is never called. If it is ever called, a contradiction has
|
||||
been proven, and the debugger is free to assume that everything is true.
|
||||
|
||||
<code>onError(<i>frame</i>, <i>report</i>)</code>
|
||||
: SpiderMonkey is about to report an error in <i>frame</i>. <i>Report</i>
|
||||
is an object describing the error, with the following properties:
|
||||
|
||||
`message`
|
||||
: The fully formatted error message.
|
||||
|
||||
`file`
|
||||
: If present, the source file name, URL, etc. (If this property is
|
||||
present, the <i>line</i> property will be too, and vice versa.)
|
||||
|
||||
`line`
|
||||
: If present, the source line number at which the error occurred.
|
||||
|
||||
`lineText`
|
||||
: If present, this is the source code of the offending line.
|
||||
|
||||
`offset`
|
||||
: The index of the character within lineText at which the error occurred.
|
||||
|
||||
`warning`
|
||||
: Present and true if this is a warning; absent otherwise.
|
||||
|
||||
`strict`
|
||||
: Present and true if this error or warning is due to the strict option
|
||||
(not to be confused with ES strict mode)
|
||||
|
||||
`exception`
|
||||
: Present and true if an exception will be thrown; absent otherwise.
|
||||
|
||||
`arguments`
|
||||
: An array of strings, representing the arguments substituted into the
|
||||
error message.
|
||||
|
||||
This method's return value is ignored.
|
||||
|
||||
`onNewGlobalObject(global)`
|
||||
: A new global object, <i>global</i>, has been created. The application
|
||||
embedding the JavaScript implementation may provide details about what
|
||||
kind of global it is via <code><i>global</i>.hostAnnotations</code>.
|
||||
|
||||
This handler method should return a [resumption value][rv] specifying how
|
||||
the debuggee's execution should proceed. However, note that a <code>{ return:
|
||||
<i>value</i> }</code> resumption value is treated like `undefined` ("continue
|
||||
normally"); <i>value</i> is ignored. (Allowing the handler to substitute
|
||||
its own value for the new global object doesn't seem useful.)
|
||||
|
||||
This handler method is only available to debuggers running in privileged
|
||||
code ("chrome", in Firefox). Most functions provided by this `Debugger`
|
||||
API observe activity in only those globals that are reachable by the
|
||||
API's user, thus imposing capability-based restrictions on a
|
||||
`Debugger`'s reach. However, the `onNewGlobalObject` method allows the
|
||||
API user to monitor all global object creation that occurs anywhere
|
||||
within the JavaScript system (the "JSRuntime", in SpiderMonkey terms),
|
||||
thereby escaping the capability-based limits. For this reason,
|
||||
`onNewGlobalObject` is only available to privileged code.
|
||||
|
||||
|
||||
|
||||
## Function Properties of the Debugger Prototype Object
|
||||
|
||||
The functions described below may only be called with a `this` value
|
||||
referring to a `Debugger` instance; they may not be used as methods of
|
||||
other kinds of objects.
|
||||
|
||||
<code id="addDebuggee">addDebuggee(<i>global</i>)</code>
|
||||
: Add the global object designated by <i>global</i> to the set of global
|
||||
objects this `Debugger` instance is debugging. If the designated global
|
||||
is already a debuggee, this has no effect. Return this `Debugger`'s
|
||||
[`Debugger.Object`][object] instance referring to the designated global.
|
||||
|
||||
The value <i>global</i> may be any of the following:
|
||||
|
||||
* A global object.
|
||||
|
||||
* An HTML5 `WindowProxy` object (an "outer window", in Firefox
|
||||
terminology), which is treated as if the `Window` object of the
|
||||
browsing context's active document (the "inner window") were passed.
|
||||
|
||||
* A cross-compartment wrapper of an object; we apply the prior rules to
|
||||
the wrapped object.
|
||||
|
||||
* A [`Debugger.Object`][object] instance belonging to this `Debugger` instance;
|
||||
we apply the prior rules to the referent.
|
||||
|
||||
* Any other sort of value is treated as a `TypeError`. (Note that each
|
||||
rule is only applied once in the process of resolving a given
|
||||
<i>global</i> argument. Thus, for example, a [`Debugger.Object`][object]
|
||||
referring to a second [`Debugger.Object`][object] which refers to a global does
|
||||
not designate that global for the purposes of this function.)
|
||||
|
||||
The global designated by <i>global</i> must be in a different
|
||||
compartment than this `Debugger` instance itself. If adding the
|
||||
designated global's compartment would create a cycle of debugger and
|
||||
debuggee compartments, this method throws an error.
|
||||
|
||||
This method returns the [`Debugger.Object`][object] instance whose referent is
|
||||
the designated global object.
|
||||
|
||||
The `Debugger` instance does not hold a strong reference to its
|
||||
debuggee globals: if a debuggee global is not otherwise reachable, then
|
||||
it is dropped from the `Debugger`'s set of debuggees. (Naturally, the
|
||||
[`Debugger.Object`][object] instance this method returns does hold a strong
|
||||
reference to the added global.)
|
||||
|
||||
<code>removeDebuggee(<i>global</i>)</code>
|
||||
: Remove the global object designated by <i>global</i> from this
|
||||
`Debugger` instance's set of debuggees. Return `undefined`.
|
||||
|
||||
This method interprets <i>global</i> using the same rules that
|
||||
[`addDebuggee`][add] does.
|
||||
|
||||
<code>hasDebuggee(<i>global</i>)</code>
|
||||
: Return `true` if the global object designated by <i>global</i> is a
|
||||
debuggee of this `Debugger` instance.
|
||||
|
||||
This method interprets <i>global</i> using the same rules that
|
||||
[`addDebuggee`][add] does.
|
||||
|
||||
`getDebuggees()`
|
||||
: Return an array of distinct [`Debugger.Object`][object] instances whose referents
|
||||
are all the global objects this `Debugger` instance is debugging.
|
||||
|
||||
Since `Debugger` instances don't hold strong references to their
|
||||
debuggee globals, if a debuggee global is otherwise unreachable, it may
|
||||
be dropped at any moment from the array this method returns.
|
||||
|
||||
`getNewestFrame()`
|
||||
: Return a [`Debugger.Frame`][frame] instance referring to the youngest
|
||||
[visible frame][vf] currently on the calling thread's stack, or `null`
|
||||
if there are no visible frames on the stack.
|
||||
|
||||
<code>findSources([<i>query</i>]) <i>(not yet implemented)</i></code>
|
||||
: Return an array of all [`Debugger.Source`][source] instances matching
|
||||
<i>query</i>. Each source appears only once in the array. <i>Query</i>
|
||||
is an object whose properties restrict which sources are returned; a
|
||||
source must meet all the criteria given by <i>query</i> to be returned.
|
||||
If <i>query</i> is omitted, we return all sources of all debuggee
|
||||
scripts.
|
||||
|
||||
<i>Query</i> may have the following properties:
|
||||
|
||||
`url`
|
||||
: The source's `url` property must be equal to this value.
|
||||
|
||||
`global`
|
||||
: The source must have been evaluated in the scope of the given global
|
||||
object. If this property's value is a [`Debugger.Object`][object] instance
|
||||
belonging to this `Debugger` instance, then its referent is used. If the
|
||||
object is not a global object, then the global in whose scope it was
|
||||
allocated is used.
|
||||
|
||||
Note that the result may include sources that can no longer ever be
|
||||
used by the debuggee: say, eval code that has finished running, or
|
||||
source for unreachable functions. Whether such sources appear can be
|
||||
affected by the garbage collector's behavior, so this function's result
|
||||
is not entirely deterministic.
|
||||
|
||||
<code>findScripts([<i>query</i>])</code>
|
||||
: Return an array of [`Debugger.Script`][script] instances for all debuggee scripts
|
||||
matching <i>query</i>. Each instance appears only once in the array.
|
||||
<i>Query</i> is an object whose properties restrict which scripts are
|
||||
returned; a script must meet all the criteria given by <i>query</i> to
|
||||
be returned. If <i>query</i> is omitted, we return the [`Debugger.Script`][script]
|
||||
instances for all debuggee scripts.
|
||||
|
||||
<i>Query</i> may have the following properties:
|
||||
|
||||
`url`
|
||||
: The script's `url` property must be equal to this value.
|
||||
|
||||
`source` <i>(not yet implemented)</i>
|
||||
: The script's `source` property must be equal to this value.
|
||||
|
||||
`line`
|
||||
: The script must at least partially cover the given source line. If this
|
||||
property is present, the `url` property must be present as well.
|
||||
|
||||
`column`
|
||||
: The script must include given column on the line given by the `line`
|
||||
property. If this property is present, the `url` and `line` properties
|
||||
must both be present as well.
|
||||
|
||||
`innermost`
|
||||
: If this property is present and true, the script must be the innermost
|
||||
script covering the given source location; scripts of enclosing code are
|
||||
omitted.
|
||||
|
||||
`global`
|
||||
: The script must be in the scope of the given global object. If this
|
||||
property's value is a [`Debugger.Object`][object] instance belonging to this
|
||||
`Debugger` instance, then its referent is used. If the object is not a
|
||||
global object, then the global in whose scope it was allocated is used.
|
||||
|
||||
All properties of <i>query</i> are optional. Passing an empty object
|
||||
returns all debuggee code scripts.
|
||||
|
||||
Note that the result may include [`Debugger.Script`][script] instances for
|
||||
scripts that can no longer ever be used by the debuggee, say, those for
|
||||
eval code that has finished running, or unreachable functions. Whether
|
||||
such scripts appear can be affected by the garbage collector's
|
||||
behavior, so this function's behavior is not entirely deterministic.
|
||||
|
||||
<code>clearBreakpoint(<i>handler</i>)</code>
|
||||
: Remove all breakpoints set in this `Debugger` instance that use
|
||||
<i>handler</i> as their handler. Note that, if breakpoints using other
|
||||
handler objects are set at the same location(s) as <i>handler</i>, they
|
||||
remain in place.
|
||||
|
||||
`clearAllBreakpoints()`
|
||||
: Remove all breakpoints set using this `Debugger` instance.
|
||||
|
||||
`clearAllWatchpoints()` <i>(future plan)</i>
|
||||
: Clear all watchpoints owned by this `Debugger` instance.
|
||||
|
||||
`findAllGlobals()`
|
||||
: Return an array of [`Debugger.Object`][object] instances referring to all the
|
||||
global objects present in this JavaScript instance. The application may
|
||||
provide details about what kind of globals they are via the
|
||||
[`Debugger.Object`][object] instances' `hostAnnotations` accessors.
|
||||
|
||||
The results of this call can be affected in non-deterministic ways by
|
||||
the details of the JavaScript implementation. The array may include
|
||||
[`Debugger.Object`][object] instances referring to global objects that are not
|
||||
actually reachable by the debuggee or any other code in the system.
|
||||
(Naturally, once the function has returned, the array's
|
||||
[`Debugger.Object`][object] instances strongly reference the globals they refer
|
||||
to.)
|
||||
|
||||
This handler method is only available to debuggers running in privileged
|
||||
code ("chrome", in Firefox). Most functions provided by this `Debugger`
|
||||
API observe activity in only those globals that are reachable by the
|
||||
API's user, thus imposing capability-based restrictions on a
|
||||
`Debugger`'s reach. However, `findAllGlobals` allows the API user to
|
||||
find all global objects anywhere within the JavaScript system (the
|
||||
"JSRuntime", in SpiderMonkey terms), thereby escaping the
|
||||
capability-based limits. For this reason, `findAllGlobals` is only
|
||||
available to privileged code.
|
||||
|
||||
<code>makeGlobalObjectReference(<i>global</i>)</code>
|
||||
: Return the [`Debugger.Object`][object] whose referent is the global object
|
||||
designated by <i>global</i>, without adding the designated global as a
|
||||
debuggee. If <i>global</i> does not designate a global object, throw a
|
||||
`TypeError`. Determine which global is designated by <i>global</i>
|
||||
using the same rules as [`Debugger.prototype.addDebuggee`][add].
|
||||
|
BIN
js/src/doc/Debugger/debugger-alert.png
Normal file
BIN
js/src/doc/Debugger/debugger-alert.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
js/src/doc/Debugger/enable-chrome-devtools.png
Normal file
BIN
js/src/doc/Debugger/enable-chrome-devtools.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
js/src/doc/Debugger/scratchpad-browser-environment.png
Normal file
BIN
js/src/doc/Debugger/scratchpad-browser-environment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
997
js/src/doc/Debugger/shadows.svg
Normal file
997
js/src/doc/Debugger/shadows.svg
Normal file
@ -0,0 +1,997 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="650"
|
||||
height="400"
|
||||
id="svg10302"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="shadows.svg"
|
||||
viewBox="0 0 650 400">
|
||||
<defs
|
||||
id="defs10304">
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-0"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-3"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-4"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-2"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-6"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-6"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-7"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-3"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-1"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-63"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-8"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-6"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-1-7"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-63-9"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-8-4"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-6-4"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-4"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-4"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-79"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-8"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-11"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-9"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-0"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-0"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-2"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-96"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-2"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-4"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-1-72"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-63-1"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-8-8"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-6-8"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-67"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-5"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-78"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-89"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-1-6"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-63-5"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-8-3"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-6-5"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="DotS"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotS-1-8"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3941-63-18"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none;marker-end:none"
|
||||
transform="matrix(0.2,0,0,0.2,1.48,0.2)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send-8-35"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3888-6-2"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.6369231"
|
||||
inkscape:cx="338.70355"
|
||||
inkscape:cy="200"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="alertLater"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="867"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata10307">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="debuggeeset"
|
||||
inkscape:label="debuggeeset"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
style="fill:#c8c0c0;fill-opacity:1;stroke:#000000;stroke-width:2.18226266;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:4.36452564, 4.36452564;stroke-dashoffset:0;display:inline"
|
||||
id="rect3755-3-0-6-1-8-6"
|
||||
width="171.31711"
|
||||
height="150.68491"
|
||||
x="0.10979491"
|
||||
y="248.55035"
|
||||
ry="4.814189"
|
||||
rx="4.0350175" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.11999989px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="9.8749857"
|
||||
y="268.84415"
|
||||
id="text22690"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan22692"
|
||||
x="9.8749857"
|
||||
y="268.84415">Debugger</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="shadows"
|
||||
inkscape:label="shadows"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-5-68"
|
||||
width="119.42149"
|
||||
height="42.397526"
|
||||
x="25.236485"
|
||||
y="160.0201"
|
||||
ry="11.065418"
|
||||
rx="11.065418" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-8"
|
||||
width="177.65483"
|
||||
height="46.614746"
|
||||
x="209.36084"
|
||||
y="336.41965"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-3-43"
|
||||
width="149.12187"
|
||||
height="46.614746"
|
||||
x="237.8938"
|
||||
y="287.1636"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-5-6-1"
|
||||
width="119.42149"
|
||||
height="42.397526"
|
||||
x="192.17702"
|
||||
y="161.09923"
|
||||
ry="11.065418"
|
||||
rx="11.065418" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-5-2-4"
|
||||
width="136.4054"
|
||||
height="46.614731"
|
||||
x="26.006214"
|
||||
y="336.41965"
|
||||
ry="11.065418"
|
||||
rx="11.065418" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-1-5-9"
|
||||
width="242.77243"
|
||||
height="75.739441"
|
||||
x="183.31783"
|
||||
y="47.05508"
|
||||
ry="6.1249413"
|
||||
rx="6.1249394" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:#ffffff;stroke-width:2.92859435;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
id="rect3755-1-5-1-7-2"
|
||||
width="186.27605"
|
||||
height="18.674528"
|
||||
x="285.59784"
|
||||
y="66.98394"
|
||||
ry="6.1249413"
|
||||
rx="6.1249399" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-1-0"
|
||||
width="194.03011"
|
||||
height="46.614746"
|
||||
x="413.20236"
|
||||
y="336.41989"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105" />
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-3-4-6"
|
||||
width="90.035484"
|
||||
height="46.614746"
|
||||
x="296.98013"
|
||||
y="237.91023"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="33.257587"
|
||||
y="378.20139"
|
||||
id="text4037"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4039"
|
||||
x="33.257587"
|
||||
y="378.20139">Debugger.Object</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="218.72287"
|
||||
y="377.52206"
|
||||
id="text4041"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4043"
|
||||
x="218.72287"
|
||||
y="377.52206">Debugger.Environment</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="421.84915"
|
||||
y="377.52206"
|
||||
id="text4045"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4047"
|
||||
x="421.84915"
|
||||
y="377.52206">Debugger.Frame</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="29.181461"
|
||||
y="196.81334"
|
||||
id="text4049"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4051"
|
||||
x="29.181461"
|
||||
y="196.81334">Debugger.Object</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="199.2216"
|
||||
y="197.89247"
|
||||
id="text4053"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4055"
|
||||
x="199.2216"
|
||||
y="197.89247">Debugger.Object</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="190.1888"
|
||||
y="118.00808"
|
||||
id="text4057"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4059"
|
||||
x="190.1888"
|
||||
y="118.00808">Debugger.Script</tspan></text>
|
||||
<rect
|
||||
style="fill:#969696;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-1-5-8"
|
||||
width="194.03011"
|
||||
height="46.614746"
|
||||
x="413.20236"
|
||||
y="287.1636"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="global"
|
||||
inkscape:label="global"
|
||||
transform="translate(0,-344.09448)"
|
||||
class="flip"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="fill:#ffd257;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1"
|
||||
width="177.9265"
|
||||
height="46.614887"
|
||||
x="201.82011"
|
||||
y="664.15881"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105"
|
||||
class="nonvalue" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.12208748px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="210.6344"
|
||||
y="691.88666"
|
||||
id="text10970"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0007628,0.99923778)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10972"
|
||||
x="210.6344"
|
||||
y="691.88666">global environment</tspan></text>
|
||||
<rect
|
||||
style="fill:#83d4ff;fill-opacity:1;stroke:none"
|
||||
id="rect3755-5-2"
|
||||
width="136.61398"
|
||||
height="46.614872"
|
||||
x="18.810663"
|
||||
y="664.15881"
|
||||
ry="11.065418"
|
||||
rx="11.065418" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS-1);marker-end:url(#Arrow1Send-8)"
|
||||
d="m 204.0527,687.46628 -46.26685,0"
|
||||
id="path11163-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.12208748px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="3.020442"
|
||||
y="659.44391"
|
||||
id="text15699"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0007628,0.99923778)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan15701"
|
||||
x="3.020442"
|
||||
y="659.44391">global object:</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.12208748px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="87.051254"
|
||||
y="698.41443"
|
||||
id="text15703"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0007628,0.99923778)"><tspan
|
||||
sodipodi:role="line"
|
||||
x="87.051254"
|
||||
y="698.41443"
|
||||
id="tspan15707">Date; Math; ...</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="scripts"
|
||||
inkscape:label="scripts"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
transform="translate(0,-652.36218)"
|
||||
style="fill:#83ff9a;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-1-5"
|
||||
width="243.14369"
|
||||
height="75.73967"
|
||||
x="176.36284"
|
||||
y="683.0611"
|
||||
ry="6.1249409"
|
||||
rx="6.1249394"
|
||||
class="nonvalue" />
|
||||
<rect
|
||||
transform="translate(0,-652.36218)"
|
||||
style="fill:#83ff9a;fill-opacity:1;stroke:#e6e4dd;stroke-width:2.92859435000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
id="rect3755-1-5-1-7"
|
||||
width="186.56091"
|
||||
height="18.674585"
|
||||
x="278.79929"
|
||||
y="702.98999"
|
||||
ry="6.1249409"
|
||||
rx="6.1249399"
|
||||
class="nonvalue" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="code"
|
||||
inkscape:label="code"
|
||||
class="flip"
|
||||
style="display:inline">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.12208748px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="182.99957"
|
||||
y="699.52692"
|
||||
id="text10314"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(1.0007628,0,0,0.99923777,0,-652.36218)"><tspan
|
||||
sodipodi:role="line"
|
||||
x="182.99957"
|
||||
y="699.52692"
|
||||
id="tspan4518">function alertLater(msg, delay) {</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="182.99957"
|
||||
y="717.1795"
|
||||
id="tspan4527"> setTimeout( function () { alert(msg); },</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="182.99957"
|
||||
y="734.83215"
|
||||
id="tspan4529"> delay);</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="182.99957"
|
||||
y="752.48474"
|
||||
id="tspan4531">}</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="alertLater"
|
||||
inkscape:label="alertLater"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
transform="translate(0,-652.36218)"
|
||||
style="fill:#83d4ff;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-5"
|
||||
width="119.60412"
|
||||
height="42.397655"
|
||||
x="18.039759"
|
||||
y="796.02643"
|
||||
ry="11.065418"
|
||||
rx="11.065418" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:13.91893291px;font-style:normal;font-weight:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="98.427589"
|
||||
y="811.1579"
|
||||
id="text3761-6"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(1.0007628,0,0,0.99923778,0,-652.36218)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3763-0"
|
||||
x="98.427589"
|
||||
y="811.1579">[[Code]]:</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:13.91893291px;font-style:normal;font-weight:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="98.427589"
|
||||
y="831.64917"
|
||||
id="text3765-0"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(1.0007628,0,0,0.99923778,0,-652.36218)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3767-2"
|
||||
x="98.427589"
|
||||
y="831.64917">[[Scope]]:</tspan></text>
|
||||
<path
|
||||
transform="translate(0,-652.36218)"
|
||||
style="fill:none;stroke:#e6e4dd;stroke-width:2.95684338000000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
d="m 18.039736,817.89404 119.601824,0"
|
||||
id="path3773-4-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.12208748px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="2.4066608"
|
||||
y="791.50812"
|
||||
id="text10404"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(1.0007628,0,0,0.99923778,0,-652.36218)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10406"
|
||||
x="2.4066608"
|
||||
y="791.50812">alertLater:</tspan></text>
|
||||
<path
|
||||
transform="translate(0,-652.36218)"
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS);marker-end:url(#Arrow1Send);display:inline"
|
||||
d="m 113.60688,806.63271 c 0,-45.02374 23.466,-83.54273 59.2075,-83.54273"
|
||||
id="path3868-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
transform="translate(0,-652.36218)"
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS);marker-end:url(#Arrow1Send);display:inline"
|
||||
d="m 113.60688,827.22105 c 51.73315,0 90.50566,99.84829 90.50566,141.32477"
|
||||
id="path3868-4-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.12208748px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="87.051254"
|
||||
y="991.61841"
|
||||
id="text15703-4"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(1.0007628,0,0,0.99923778,0,-652.36218)"><tspan
|
||||
sodipodi:role="line"
|
||||
x="89.299202"
|
||||
y="991.61841"
|
||||
id="tspan15707-0">alertLater; </tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="call1env"
|
||||
inkscape:label="call1env"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
style="fill:#ffd257;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-3"
|
||||
width="149.34991"
|
||||
height="46.614887"
|
||||
x="229.7888"
|
||||
y="270.80811"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105"
|
||||
class="nonvalue" />
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g3550"
|
||||
transform="matrix(0.58886915,0,0,0.58797179,4.5262952,-176.54364)">
|
||||
<text
|
||||
transform="scale(1.0009935,0.9990075)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text13153"
|
||||
y="795.71594"
|
||||
x="499.133"
|
||||
style="font-size:22px;font-style:normal;font-weight:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="795.71594"
|
||||
x="499.133"
|
||||
id="tspan13155"
|
||||
sodipodi:role="line">msg:</tspan><tspan
|
||||
y="823.21594"
|
||||
x="499.133"
|
||||
sodipodi:role="line"
|
||||
id="tspan3538">delay:</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3540"
|
||||
y="794.92615"
|
||||
x="507"
|
||||
style="font-size:22px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="794.92615"
|
||||
x="507"
|
||||
id="tspan3542"
|
||||
sodipodi:role="line">'xlerb'</tspan><tspan
|
||||
id="tspan3544"
|
||||
y="822.42615"
|
||||
x="507"
|
||||
sodipodi:role="line">1000</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="anon"
|
||||
inkscape:label="anon"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
style="fill:#83d4ff;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-5-6"
|
||||
width="119.60412"
|
||||
height="42.397655"
|
||||
x="185.84294"
|
||||
y="143.66425"
|
||||
ry="11.065418"
|
||||
rx="11.065418" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:13.91893291px;font-style:normal;font-weight:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="266.10284"
|
||||
y="158.2981"
|
||||
id="text3761-6-0"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0007628,0.99923778)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3763-0-7"
|
||||
x="266.10284"
|
||||
y="158.2981">[[Code]]:</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:13.91893291px;font-style:normal;font-weight:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="266.10284"
|
||||
y="178.78937"
|
||||
id="text3765-0-7"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.0007628,0.99923778)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3767-2-6"
|
||||
x="266.10284"
|
||||
y="178.78937">[[Scope]]:</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#e6e4dd;stroke-width:2.95684338000000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
d="m 185.84293,165.53187 119.60182,0"
|
||||
id="path3773-4-3-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS);marker-end:url(#Arrow1Send);display:inline"
|
||||
d="m 285.44496,176.59077 c 0,31.25836 -38.08897,59.76616 -38.08897,91.05227"
|
||||
id="path3868-4-0-4-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS);marker-end:url(#Arrow1Send);display:inline"
|
||||
d="m 285.95088,154.47813 c 165.68371,0 170.77148,-32.93057 158.20494,-82.18402"
|
||||
id="path3868-4-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="fire"
|
||||
inkscape:label="fire"
|
||||
style="display:inline"
|
||||
class="flip">
|
||||
<rect
|
||||
style="fill:#ff9457;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-1-4"
|
||||
width="194.03011"
|
||||
height="46.614746"
|
||||
x="406.38477"
|
||||
y="320.06448"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105"
|
||||
class="nonvalue" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="434.10962"
|
||||
y="346.93411"
|
||||
id="text10970-7-4"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="434.10962"
|
||||
y="346.93411"
|
||||
id="tspan3534-4"><tspan
|
||||
style="font-style:italic;-inkscape-font-specification:Sans Italic"
|
||||
id="tspan5754">anonymous</tspan>()</tspan></text>
|
||||
<rect
|
||||
style="fill:#ffd257;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-3-4"
|
||||
width="90.035484"
|
||||
height="46.614746"
|
||||
x="289.10324"
|
||||
y="221.55482"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105"
|
||||
class="nonvalue" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:italic;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans;-inkscape-font-specification:Sans Italic"
|
||||
x="312.99686"
|
||||
y="248.05814"
|
||||
id="text5774"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5776"
|
||||
x="312.99686"
|
||||
y="248.05814">empty</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS-1);marker-end:url(#Arrow1Send-8);display:inline"
|
||||
d="m 415.85979,342.35006 c -51.09645,0 11.10573,-95.59507 -39.0289,-95.59507"
|
||||
id="path11163-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#DotS-1);marker-end:url(#Arrow1Send-8);display:inline"
|
||||
d="m 588.68444,343.33325 c 66.19678,0 27.60009,-283.14206 -117.22439,-283.14206"
|
||||
id="path11163-1-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="call2"
|
||||
inkscape:label="call2"
|
||||
class="flip"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="fill:#ff9457;fill-opacity:1;stroke:none;display:inline"
|
||||
id="rect3755-3-0-6-1-1-5-4"
|
||||
width="194.03011"
|
||||
height="46.614746"
|
||||
x="406.38477"
|
||||
y="270.80817"
|
||||
ry="4.0393105"
|
||||
rx="4.0393105"
|
||||
class="nonvalue" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:12.93533993px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="433.86328"
|
||||
y="298.87103"
|
||||
id="text6389"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6391"
|
||||
x="433.86328"
|
||||
y="298.87103">alert('xlerb')</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 35 KiB |
Loading…
Reference in New Issue
Block a user