Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | # Debugger.Script |
michael@0 | 2 | |
michael@0 | 3 | A `Debugger.Script` instance refers to a sequence of bytecode in the |
michael@0 | 4 | debuggee; it is the [`Debugger`][debugger-object] API's presentation of a JSAPI `JSScript` |
michael@0 | 5 | object. Each of the following is represented by single JSScript object: |
michael@0 | 6 | |
michael@0 | 7 | * The body of a function—that is, all the code in the function that is not |
michael@0 | 8 | contained within some nested function. |
michael@0 | 9 | |
michael@0 | 10 | * The code passed to a single call to `eval`, excluding the bodies of any |
michael@0 | 11 | functions that code defines. |
michael@0 | 12 | |
michael@0 | 13 | * The contents of a `<script>` element. |
michael@0 | 14 | |
michael@0 | 15 | * A DOM event handler, whether embedded in HTML or attached to the element |
michael@0 | 16 | by other JavaScript code. |
michael@0 | 17 | |
michael@0 | 18 | * Code appearing in a `javascript:` URL. |
michael@0 | 19 | |
michael@0 | 20 | The [`Debugger`][debugger-object] interface constructs `Debugger.Script` objects as scripts |
michael@0 | 21 | of debuggee code are uncovered by the debugger: via the `onNewScript` |
michael@0 | 22 | handler method; via [`Debugger.Frame`][frame]'s `script` properties; via the |
michael@0 | 23 | `functionScript` method of [`Debugger.Object`][object] instances; and so on. For a |
michael@0 | 24 | given [`Debugger`][debugger-object] instance, SpiderMonkey constructs exactly one |
michael@0 | 25 | `Debugger.Script` instance for each underlying script object; debugger |
michael@0 | 26 | code can add its own properties to a script object and expect to find |
michael@0 | 27 | them later, use `==` to decide whether two expressions refer to the same |
michael@0 | 28 | script, and so on. |
michael@0 | 29 | |
michael@0 | 30 | (If more than one [`Debugger`][debugger-object] instance is debugging the same code, each |
michael@0 | 31 | [`Debugger`][debugger-object] gets a separate `Debugger.Script` instance for a given |
michael@0 | 32 | script. This allows the code using each [`Debugger`][debugger-object] instance to place |
michael@0 | 33 | whatever properties it likes on its `Debugger.Script` instances, without |
michael@0 | 34 | worrying about interfering with other debuggers.) |
michael@0 | 35 | |
michael@0 | 36 | A `Debugger.Script` instance is a strong reference to a JSScript object; |
michael@0 | 37 | it protects the script it refers to from being garbage collected. |
michael@0 | 38 | |
michael@0 | 39 | Note that SpiderMonkey may use the same `Debugger.Script` instances for |
michael@0 | 40 | equivalent functions or evaluated code—that is, scripts representing the |
michael@0 | 41 | same source code, at the same position in the same source file, |
michael@0 | 42 | evaluated in the same lexical environment. |
michael@0 | 43 | |
michael@0 | 44 | ## Accessor Properties of the Debugger.Script Prototype Object |
michael@0 | 45 | |
michael@0 | 46 | A `Debugger.Script` instance inherits the following accessor properties |
michael@0 | 47 | from its prototype: |
michael@0 | 48 | |
michael@0 | 49 | `url` |
michael@0 | 50 | : The filename or URL from which this script's code was loaded. If the |
michael@0 | 51 | `source` property is non-`null`, then this is equal to `source.url`. |
michael@0 | 52 | |
michael@0 | 53 | `startLine` |
michael@0 | 54 | : The number of the line at which this script's code starts, within the |
michael@0 | 55 | file or document named by `url`. |
michael@0 | 56 | |
michael@0 | 57 | `lineCount` |
michael@0 | 58 | : The number of lines this script's code occupies, within the file or |
michael@0 | 59 | document named by `url`. |
michael@0 | 60 | |
michael@0 | 61 | `source` |
michael@0 | 62 | : The [`Debugger.Source`][source] instance representing the source code from which |
michael@0 | 63 | this script was produced. This is `null` if the source code was not |
michael@0 | 64 | retained. |
michael@0 | 65 | |
michael@0 | 66 | `sourceStart` |
michael@0 | 67 | : The character within the [`Debugger.Source`][source] instance given by `source` at |
michael@0 | 68 | which this script's code starts; zero-based. If this is a function's |
michael@0 | 69 | script, this is the index of the start of the `function` token in the |
michael@0 | 70 | source code. |
michael@0 | 71 | |
michael@0 | 72 | `sourceLength` |
michael@0 | 73 | : The length, in characters, of this script's code within the |
michael@0 | 74 | [`Debugger.Source`][source] instance given by `source`. |
michael@0 | 75 | |
michael@0 | 76 | `global` |
michael@0 | 77 | : A [`Debugger.Object`][object] instance referring to the global object in whose |
michael@0 | 78 | scope this script runs. The result refers to the global directly, not |
michael@0 | 79 | via a wrapper or a `WindowProxy` ("outer window", in Firefox). |
michael@0 | 80 | |
michael@0 | 81 | `staticLevel` |
michael@0 | 82 | : The number of function bodies enclosing this script's code. |
michael@0 | 83 | |
michael@0 | 84 | Global code is at level zero; bodies of functions defined at the top |
michael@0 | 85 | level in global code are at level one; bodies of functions nested within |
michael@0 | 86 | those are at level two; and so on. |
michael@0 | 87 | |
michael@0 | 88 | A script for code passed to direct `eval` is at a static level one |
michael@0 | 89 | greater than that of the script containing the call to `eval`, because |
michael@0 | 90 | direct eval code runs within the caller's scope. However, a script for |
michael@0 | 91 | code passed to an indirect `eval` call is at static level zero, since it |
michael@0 | 92 | is evaluated in the global scope. |
michael@0 | 93 | |
michael@0 | 94 | Note that a generator's expressions are considered to be part of the |
michael@0 | 95 | body of a synthetic function, produced by the compiler. |
michael@0 | 96 | |
michael@0 | 97 | Scripts' static level be useful in deciding where to set breakpoints. |
michael@0 | 98 | For example, a breakpoint set on line 3 in this code: |
michael@0 | 99 | |
michael@0 | 100 | function f() { |
michael@0 | 101 | x = function g() { // line 2 |
michael@0 | 102 | // line 3; no code here |
michael@0 | 103 | ...; |
michael@0 | 104 | } |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | should be set in `g`'s script, not in `f`'s, even though neither script |
michael@0 | 108 | contains code at that line. In such a case, the most deeply nested |
michael@0 | 109 | script—the one with the highest static level—should receive the |
michael@0 | 110 | breakpoint. |
michael@0 | 111 | |
michael@0 | 112 | `strictMode` |
michael@0 | 113 | : This is `true` if this script's code is ECMAScript strict mode code, and |
michael@0 | 114 | `false` otherwise. |
michael@0 | 115 | |
michael@0 | 116 | `sourceMapURL` |
michael@0 | 117 | : If this script was produced by a minimizer or translated from some other |
michael@0 | 118 | language, and we know the URL of a <b>source map</b> document relating |
michael@0 | 119 | the source positions in this script to the corresponding source |
michael@0 | 120 | positions in the original source, then this property's value is that |
michael@0 | 121 | URL. Otherwise, this is `null`. |
michael@0 | 122 | |
michael@0 | 123 | (On the web, the translator may provide the source map URL in a |
michael@0 | 124 | specially formatted comment in the JavaScript source code, or via a |
michael@0 | 125 | header in the HTTP reply that carried the generated JavaScript.) |
michael@0 | 126 | |
michael@0 | 127 | ## Function Properties of the Debugger.Script Prototype Object |
michael@0 | 128 | |
michael@0 | 129 | The functions described below may only be called with a `this` value |
michael@0 | 130 | referring to a `Debugger.Script` instance; they may not be used as |
michael@0 | 131 | methods of other kinds of objects. |
michael@0 | 132 | |
michael@0 | 133 | <code>decompile([<i>pretty</i>])</code> |
michael@0 | 134 | : Return a string containing JavaScript source code equivalent to this |
michael@0 | 135 | script in its effect and result. If <i>pretty</i> is present and true, |
michael@0 | 136 | produce indented code with line breaks. |
michael@0 | 137 | |
michael@0 | 138 | (Note that [`Debugger.Object`][object] instances referring to functions also have |
michael@0 | 139 | a `decompile` method, whose result includes the function header and |
michael@0 | 140 | parameter names, so it is probably better to write |
michael@0 | 141 | <code><i>f</i>.decompile()</code> than to write |
michael@0 | 142 | <code><i>f</i>.getFunctionScript().decompile()</code>.) |
michael@0 | 143 | |
michael@0 | 144 | `getAllOffsets()` |
michael@0 | 145 | : Return an array <i>L</i> describing the relationship between bytecode |
michael@0 | 146 | instruction offsets and source code positions in this script. <i>L</i> |
michael@0 | 147 | is sparse, and indexed by source line number. If a source line number |
michael@0 | 148 | <i>line</i> has no code, then <i>L</i> has no <i>line</i> property. If |
michael@0 | 149 | there is code for <i>line</i>, then <code><i>L</i>[<i>line</i>]</code> is an array |
michael@0 | 150 | of offsets of byte code instructions that are entry points to that line. |
michael@0 | 151 | |
michael@0 | 152 | For example, suppose we have a script for the following source code: |
michael@0 | 153 | |
michael@0 | 154 | a=[] |
michael@0 | 155 | for (i=1; i < 10; i++) |
michael@0 | 156 | // It's hip to be square. |
michael@0 | 157 | a[i] = i*i; |
michael@0 | 158 | |
michael@0 | 159 | Calling `getAllOffsets()` on that code might yield an array like this: |
michael@0 | 160 | |
michael@0 | 161 | [[0], [5, 20], , [10]] |
michael@0 | 162 | |
michael@0 | 163 | This array indicates that: |
michael@0 | 164 | |
michael@0 | 165 | * the first line's code starts at offset 0 in the script; |
michael@0 | 166 | |
michael@0 | 167 | * the `for` statement head has two entry points at offsets 5 and 20 (for |
michael@0 | 168 | the initialization, which is performed only once, and the loop test, |
michael@0 | 169 | which is performed at the start of each iteration); |
michael@0 | 170 | |
michael@0 | 171 | * the third line has no code; |
michael@0 | 172 | |
michael@0 | 173 | * and the fourth line begins at offset 10. |
michael@0 | 174 | |
michael@0 | 175 | <code>getLineOffsets(<i>line</i>)</code> |
michael@0 | 176 | : Return an array of bytecode instruction offsets representing the entry |
michael@0 | 177 | points to source line <i>line</i>. If the script contains no executable |
michael@0 | 178 | code at that line, the array returned is empty. |
michael@0 | 179 | |
michael@0 | 180 | <code>getOffsetLine(<i>offset</i>)</code> |
michael@0 | 181 | : Return the source code line responsible for the bytecode at |
michael@0 | 182 | <i>offset</i> in this script. |
michael@0 | 183 | |
michael@0 | 184 | `getChildScripts()` |
michael@0 | 185 | : Return a new array whose elements are Debugger.Script objects for each |
michael@0 | 186 | function and each generator expression in this script. Only direct |
michael@0 | 187 | children are included; nested children can be reached by walking the |
michael@0 | 188 | tree. |
michael@0 | 189 | |
michael@0 | 190 | <code>setBreakpoint(<i>offset</i>, <i>handler</i>)</code> |
michael@0 | 191 | : Set a breakpoint at the bytecode instruction at <i>offset</i> in this |
michael@0 | 192 | script, reporting hits to the `hit` method of <i>handler</i>. If |
michael@0 | 193 | <i>offset</i> is not a valid offset in this script, throw an error. |
michael@0 | 194 | |
michael@0 | 195 | When execution reaches the given instruction, SpiderMonkey calls the |
michael@0 | 196 | `hit<code> method of <i>handler</i>, passing a [</code>Debugger.Frame`][frame] instance |
michael@0 | 197 | representing the currently executing stack frame. The `hit` method's |
michael@0 | 198 | return value should be a [resumption value][rv], determining how execution should |
michael@0 | 199 | continue. |
michael@0 | 200 | |
michael@0 | 201 | Any number of breakpoints may be set at a single location; when control |
michael@0 | 202 | reaches that point, SpiderMonkey calls their handlers in an unspecified |
michael@0 | 203 | order. |
michael@0 | 204 | |
michael@0 | 205 | Any number of breakpoints may use the same <i>handler</i> object. |
michael@0 | 206 | |
michael@0 | 207 | Breakpoint handler method calls are cross-compartment, intra-thread |
michael@0 | 208 | calls: the call takes place in the same thread that hit the breakpoint, |
michael@0 | 209 | and in the compartment containing the handler function (typically the |
michael@0 | 210 | debugger's compartment). |
michael@0 | 211 | |
michael@0 | 212 | The new breakpoint belongs to the [`Debugger`][debugger-object] instance to which this |
michael@0 | 213 | script belongs; disabling the [`Debugger`][debugger-object] instance disables this |
michael@0 | 214 | breakpoint. |
michael@0 | 215 | |
michael@0 | 216 | <code>getBreakpoints([<i>offset</i>])</code> |
michael@0 | 217 | : Return an array containing the handler objects for all the breakpoints |
michael@0 | 218 | set at <i>offset</i> in this script. If <i>offset</i> is omitted, return |
michael@0 | 219 | the handlers of all breakpoints set anywhere in this script. If |
michael@0 | 220 | <i>offset</i> is present, but not a valid offset in this script, throw |
michael@0 | 221 | an error. |
michael@0 | 222 | |
michael@0 | 223 | <code>clearBreakpoints(handler, [<i>offset</i>])</code> |
michael@0 | 224 | : Remove all breakpoints set in this [`Debugger`][debugger-object] instance that use |
michael@0 | 225 | <i>handler</i> as their handler. If <i>offset</i> is given, remove only |
michael@0 | 226 | those breakpoints set at <i>offset</i> that use <i>handler</i>; if |
michael@0 | 227 | <i>offset</i> is not a valid offset in this script, throw an error. |
michael@0 | 228 | |
michael@0 | 229 | Note that, if breakpoints using other handler objects are set at the |
michael@0 | 230 | same location(s) as <i>handler</i>, they remain in place. |
michael@0 | 231 | |
michael@0 | 232 | <code>clearAllBreakpoints([<i>offset</i>])</code> |
michael@0 | 233 | : Remove all breakpoints set in this script. If <i>offset</i> is present, |
michael@0 | 234 | remove all breakpoints set at that offset in this script; if |
michael@0 | 235 | <i>offset</i> is not a valid bytecode offset in this script, throw an |
michael@0 | 236 | error. |
michael@0 | 237 | |
michael@0 | 238 |