1# Debugger.Script
2
3A `Debugger.Script` instance may refer to a sequence of bytecode in the
4debuggee or to a block of WebAssembly code. For the former, it is the
5[`Debugger`][debugger-object] API's presentation of a JSAPI `JSScript`
6object. The two cases are distinguished by their `format` property being
7`"js"` or `"wasm"`.
8
9## Debugger.Script for JSScripts
10
11For `Debugger.Script` instances referring to a `JSScript`, they are
12distinguished by their `format` property being `"js"`.
13
14Each of the following is represented by a single `JSScript` object:
15
16* The body of a function—that is, all the code in the function that is not
17  contained within some nested function.
18
19* The code passed to a single call to `eval`, excluding the bodies of any
20  functions that code defines.
21
22* The contents of a `<script>` element.
23
24* A DOM event handler, whether embedded in HTML or attached to the element
25  by other JavaScript code.
26
27* Code appearing in a `javascript:` URL.
28
29The [`Debugger`][debugger-object] interface constructs `Debugger.Script` objects as scripts
30of debuggee code are uncovered by the debugger: via the `onNewScript`
31handler method; via [`Debugger.Frame`][frame]'s `script` properties; via the
32`functionScript` method of [`Debugger.Object`][object] instances; and so on. For a
33given [`Debugger`][debugger-object] instance, SpiderMonkey constructs exactly one
34`Debugger.Script` instance for each underlying script object; debugger
35code can add its own properties to a script object and expect to find
36them later, use `==` to decide whether two expressions refer to the same
37script, and so on.
38
39(If more than one [`Debugger`][debugger-object] instance is debugging the same code, each
40[`Debugger`][debugger-object] gets a separate `Debugger.Script` instance for a given
41script. This allows the code using each [`Debugger`][debugger-object] instance to place
42whatever properties it likes on its `Debugger.Script` instances, without
43worrying about interfering with other debuggers.)
44
45A `Debugger.Script` instance is a strong reference to a JSScript object;
46it protects the script it refers to from being garbage collected.
47
48Note that SpiderMonkey may use the same `Debugger.Script` instances for
49equivalent functions or evaluated code—that is, scripts representing the
50same source code, at the same position in the same source file,
51evaluated in the same lexical environment.
52
53## Debugger.Script for WebAssembly
54
55For `Debugger.Script` instances referring to a block of WebAssembly code, they
56are distinguished by their `format` property being `"wasm"`.
57
58Currently only entire modules evaluated via `new WebAssembly.Module` are
59represented.
60
61`Debugger.Script` objects for WebAssembly are uncovered via `onNewScript` when
62a new WebAssembly module is instantiated and via the `findScripts` method on
63[`Debugger`][debugger-object] instances. SpiderMonkey constructs exactly one
64`Debugger.Script` for each underlying WebAssembly module per
65[`Debugger`][debugger-object] instance.
66
67A `Debugger.Script` instance is a strong reference to the underlying
68WebAssembly module; it protects the module it refers to from being garbage
69collected.
70
71Please note at the time of this writing, support for WebAssembly is
72very preliminary. Many properties and methods below throw.
73
74## Convention
75
76For descriptions of properties and methods below, if the behavior of the
77property or method differs between the instance referring to a `JSScript` or
78to a block of WebAssembly code, the text will be split into two sections,
79headed by "**if the instance refers to a `JSScript`**" and "**if the instance
80refers to WebAssembly code**", respectively. If the behavior does not differ,
81no such emphasized headings will appear.
82
83## Accessor Properties of the Debugger.Script Prototype Object
84
85A `Debugger.Script` instance inherits the following accessor properties
86from its prototype:
87
88### `isGeneratorFunction`
89True if this instance refers to a `JSScript` for a function defined with a
90`function*` expression or statement. False otherwise.
91
92### `isAsyncFunction`
93True if this instance refers to a `JSScript` for an async function, defined
94with an `async function` expression or statement. False otherwise.
95
96### `isFunction`
97True if this instance refers to a `JSScript` for a function. False
98otherwise.
99
100### `isModule`
101True if this instance refers to a `JSScript` that was parsed and loaded
102as an ECMAScript module. False otherwise.
103
104### `displayName`
105**If the instance refers to a `JSScript`**, this is the script's display
106name, if it has one. If the script has no display name &mdash; for example,
107if it is a top-level `eval` script &mdash; this is `undefined`.
108
109If the script's function has a given name, its display name is the same as
110its function's given name.
111
112If the script's function has no name, SpiderMonkey attempts to infer an
113appropriate name for it given its context. For example:
114
115```js
116function f() {}          // display name: f (the given name)
117var g = function () {};  // display name: g
118o.p = function () {};    // display name: o.p
119var q = {
120  r: function () {}      // display name: q.r
121};
122```
123
124Note that the display name may not be a proper JavaScript identifier,
125or even a proper expression: we attempt to find helpful names even when
126the function is not immediately assigned as the value of some variable
127or property. Thus, we use <code><i>a</i>/<i>b</i></code> to refer to
128the <i>b</i> defined within <i>a</i>, and <code><i>a</i>&lt;</code> to
129refer to a function that occurs somewhere within an expression that is
130assigned to <i>a</i>. For example:
131
132```js
133function h() {
134  var i = function() {};    // display name: h/i
135  f(function () {});        // display name: h/<
136}
137var s = f(function () {});  // display name: s<
138```
139
140**If the instance refers to WebAssembly code**, throw a `TypeError`.
141
142### `parameterNames`
143**If the instance refers to a `JSScript`**, the names of its parameters,
144as an array of strings. If the script is not a function script this is
145`undefined`.
146
147If the function uses destructuring parameters, the corresponding array elements
148are `undefined`. For example, if the referent is a function script declared in this
149way:
150
151```js
152function f(a, [b, c], {d, e:f}) { ... }
153```
154
155then this `Debugger.Script` instance's `parameterNames` property would
156have the value:
157
158```js
159["a", undefined, undefined]
160```
161
162**If the instance refers to WebAssembly code**, throw a `TypeError`.
163
164### `url`
165**If the instance refers to a `JSScript`**, the filename or URL from which
166this script's code was loaded. For scripts created by `eval` or the
167`Function` constructor, this may be a synthesized filename, starting with a
168valid URL and followed by information tracking how the code was introduced
169into the system; the entire string is not a valid URL. For
170`Function.prototype`'s script, this is `null`. If this `Debugger.Script`'s
171`source` property is non-`null`, then this is equal to `source.url`.
172
173**If the instance refers to WebAssembly code**, throw a `TypeError`.
174
175### `startLine`
176**If the instance refers to a `JSScript`**, the number of the line at
177which this script's code starts, within the file or document named by
178`url`.
179
180### `startColumn`
181**If the instance refers to a `JSScript`**, the zero-indexed number of the
182column at which this script's code starts, within the file or document
183named by `url`.  For functions, this is the start of the function's
184arguments:
185```js
186function f() { ... }
187//        ^ start (column 10)
188let g = x => x*x;
189//      ^ start (column 8)
190let h = (x) => x*x;
191//      ^ start (column 8)
192```
193For default class constructors, it is the start of the `class` keyword:
194```js
195let MyClass = class { };
196//            ^ start (column 14)
197```
198For scripts from other sources, such as `eval` or the `Function`
199constructor, it is typically 0:
200```js
201let f = new Function("  console.log('hello world');");
202//                    ^ start (column 0, from the string's perspective)
203```
204
205### `lineCount`
206**If the instance refers to a `JSScript`**, the number of lines this
207script's code occupies, within the file or document named by `url`.
208
209### `source`
210**If the instance refers to a `JSScript`**, the
211[`Debugger.Source`][source] instance representing the source code from
212which this script was produced. This is `null` if the source code was not
213retained.
214
215**If the instance refers to WebAssembly code**, the
216[`Debugger.Source`][source] instance representing the serialized text
217format of the WebAssembly code.
218
219### `sourceStart`
220**If the instance refers to a `JSScript`**, the character within the
221[`Debugger.Source`][source] instance given by `source` at which this
222script's code starts; zero-based. If this is a function's script, this is
223the index of the start of the `function` token in the source code.
224
225**If the instance refers to WebAssembly code**, throw a `TypeError`.
226
227### `sourceLength`
228**If the instance refers to a `JSScript`**, the length, in characters, of
229this script's code within the [`Debugger.Source`][source] instance given
230by `source`.
231
232**If the instance refers to WebAssembly code**, throw a `TypeError`.
233
234### `mainOffset`
235**If the instance refers to a `JSScript`**, the offset of the main
236entry point of the script, excluding any prologue.
237
238**If the instance refers to WebAssembly code**, throw a `TypeError`.
239
240### `global`
241**If the instance refers to a `JSScript`**, a [`Debugger.Object`][object]
242instance referring to the global object in whose scope this script
243runs. The result refers to the global directly, not via a wrapper or a
244`WindowProxy` ("outer window", in Firefox).
245
246**If the instance refers to WebAssembly code**, throw a `TypeError`.
247
248### `format`
249**If the instance refers to a `JSScript`**, `"js"`.
250
251**If the instance refers to WebAssembly code**, `"wasm"`.
252
253## Function Properties of the Debugger.Script Prototype Object
254
255The functions described below may only be called with a `this` value
256referring to a `Debugger.Script` instance; they may not be used as
257methods of other kinds of objects.
258
259### `getChildScripts()`
260**If the instance refers to a `JSScript`**, return a new array whose
261elements are Debugger.Script objects for each function
262in this script. Only direct children are included; nested
263children can be reached by walking the tree.
264
265**If the instance refers to WebAssembly code**, throw a `TypeError`.
266
267### `getPossibleBreakpoints(query)`
268Query for the recommended breakpoint locations available in SpiderMonkey.
269Returns a result array of objects with the following properties:
270 * `offset: number` - The offset the breakpoint.
271 * `lineNumber: number` - The line number of the breakpoint.
272 * `columnNumber: number` - The column number of the breakpoint.
273 * `isStepStart: boolean` - True if SpiderMonkey recommends that the
274   breakpoint be treated as a step location when users of debuggers
275   step to the next item. This _roughly_ translates to the start of
276   each statement, though not entirely.
277
278The `query` argument can be used to filter the set of breakpoints.
279The `query` object can contain the following properties:
280
281 * `minOffset: number` - The inclusive lower bound of `offset` values to include.
282 * `maxOffset: number` - The exclusive upper bound of `offset` values to include.
283 * `line: number` - Limit to breakpoints on the given line.
284 * `minLine: number` - The inclusive lower bound of lines to include.
285 * `minColumn: number` - The inclusive lower bound of the line/minLine column to include.
286 * `maxLine: number` - The exclusive upper bound of lines to include.
287 * `maxColumn: number` - The exclusive upper bound of the line/maxLine column to include.
288
289### `getPossibleBreakpointOffsets(query)`
290Query for the recommended breakpoint locations available in SpiderMonkey.
291Identical to getPossibleBreakpoints except this returns an array of `offset`
292values instead of offset metadata objects.
293
294### `getOffsetMetadata(offset)`
295Get metadata about a given bytecode offset.
296Returns an object with the following properties:
297  * `lineNumber: number` - The line number of the breakpoint.
298  * `columnNumber: number` - The column number of the breakpoint.
299  * `isBreakpoint: boolean` - True if this offset qualifies as a breakpoint,
300    defined using the same semantics used for `getPossibleBreakpoints()`.
301  * `isStepStart: boolean` - True if SpiderMonkey recommends that the
302    breakpoint be treated as a step location when users of debuggers
303    step to the next item. This _roughly_ translates to the start of
304    each statement, though not entirely.
305
306### `setBreakpoint(offset, handler)`
307**If the instance refers to a `JSScript`**, set a breakpoint at the
308bytecode instruction at <i>offset</i> in this script, reporting hits to
309the `hit` method of <i>handler</i>. If <i>offset</i> is not a valid offset
310in this script, throw an error.
311
312When execution reaches the given instruction, SpiderMonkey calls the
313`hit` method of <i>handler</i>, passing a [`Debugger.Frame`][frame]
314instance representing the currently executing stack frame. The `hit`
315method's return value should be a [resumption value][rv], determining
316how execution should continue.
317
318Any number of breakpoints may be set at a single location; when control
319reaches that point, SpiderMonkey calls their handlers in an unspecified
320order.
321
322Any number of breakpoints may use the same <i>handler</i> object.
323
324Breakpoint handler method calls are cross-compartment, intra-thread
325calls: the call takes place in the same thread that hit the breakpoint,
326and in the compartment containing the handler function (typically the
327debugger's compartment).
328
329The new breakpoint belongs to the [`Debugger`][debugger-object] instance to
330which this script belongs. Removing a global from the
331[`Debugger`][debugger-object] instance's set of debuggees clears all the
332breakpoints belonging to that [`Debugger`][debugger-object] instance in that
333global's scripts.
334
335### `getBreakpoints([offset])`
336**If the instance refers to a `JSScript`**, return an array containing the
337handler objects for all the breakpoints set at <i>offset</i> in this
338script. If <i>offset</i> is omitted, return the handlers of all
339breakpoints set anywhere in this script. If <i>offset</i> is present, but
340not a valid offset in this script, throw an error.
341
342**If the instance refers to WebAssembly code**, throw a `TypeError`.
343
344### `clearBreakpoint(handler, [offset])`
345**If the instance refers to a `JSScript`**, remove all breakpoints set in
346this [`Debugger`][debugger-object] instance that use <i>handler</i> as
347their handler. If <i>offset</i> is given, remove only those breakpoints
348set at <i>offset</i> that use <i>handler</i>; if <i>offset</i> is not a
349valid offset in this script, throw an error.
350
351Note that, if breakpoints using other handler objects are set at the
352same location(s) as <i>handler</i>, they remain in place.
353
354### `clearAllBreakpoints([offset])`
355**If the instance refers to a `JSScript`**, remove all breakpoints set in
356this script. If <i>offset</i> is present, remove all breakpoints set at
357that offset in this script; if <i>offset</i> is not a valid bytecode
358offset in this script, throw an error.
359
360### `getEffectfulOffsets()`
361**If the instance refers to a `JSScript`**, return an array
362containing the offsets of all bytecodes in the script which can have direct
363side effects that are visible outside the currently executing frame.  This
364includes, for example, operations that set properties or elements on
365objects, or that may set names in environments created outside the frame.
366
367### `getOffsetsCoverage()`:
368**If the instance refers to a `JSScript`**, return `null` or an array which
369contains information about the coverage of all opcodes. The elements of
370the array are objects, each of which describes a single opcode, and
371contains the following properties:
372
373 * `lineNumber`: the line number of the current opcode.
374
375 * `columnNumber`: the column number of the current opcode.
376
377 * `offset`: the bytecode instruction offset of the current opcode.
378
379 * `count`: the number of times the current opcode got executed.
380
381If this script has no coverage, or if it is not instrumented, then this
382function will return `null`. To ensure that the debuggee is instrumented,
383the flag `Debugger.collectCoverageInfo` should be set to `true`.
384
385**If the instance refers to WebAssembly code**, throw a `TypeError`.
386
387### `isInCatchScope([offset])`
388**If the instance refers to a `JSScript`**, this is `true` if this offset
389falls within the scope of a try block, and `false` otherwise.
390
391**If the instance refers to WebAssembly code**, throw a `TypeError`.
392
393### Deprecated Debugger.Script Prototype Functions
394
395The following functions have all been deprecated in favor of `getOffsetMetadata`,
396`getPossibleBreakpoints`, and `getPossibleBreakpointOffsets`. These functions
397all have an under-defined concept of what offsets are and are not included
398in their results.
399
400#### `getAllOffsets()`
401**If the instance refers to a `JSScript`**, return an array <i>L</i>
402describing the relationship between bytecode instruction offsets and
403source code positions in this script. <i>L</i> is sparse, and indexed by
404source line number. If a source line number <i>line</i> has no code, then
405<i>L</i> has no <i>line</i> property. If there is code for <i>line</i>,
406then <code><i>L</i>[<i>line</i>]</code> is an array of offsets of byte
407code instructions that are entry points to that line.
408
409For example, suppose we have a script for the following source code:
410
411```js
412a=[]
413for (i=1; i < 10; i++)
414    // It's hip to be square.
415    a[i] = i*i;
416```
417
418Calling `getAllOffsets()` on that code might yield an array like this:
419
420```js
421[[0], [5, 20], , [10]]
422```
423
424This array indicates that:
425
426* the first line's code starts at offset 0 in the script;
427
428* the `for` statement head has two entry points at offsets 5 and 20 (for
429the initialization, which is performed only once, and the loop test,
430which is performed at the start of each iteration);
431
432* the third line has no code;
433
434* and the fourth line begins at offset 10.
435
436**If the instance refers to WebAssembly code**, throw a `TypeError`.
437
438#### `getAllColumnOffsets()`
439**If the instance refers to a `JSScript`**, return an array describing the
440relationship between bytecode instruction offsets and source code
441positions in this script. Unlike getAllOffsets(), which returns all
442offsets that are entry points for each line, getAllColumnOffsets() returns
443all offsets that are entry points for each (line, column) pair.
444
445The elements of the array are objects, each of which describes a single
446entry point, and contains the following properties:
447
448* lineNumber: the line number for which offset is an entry point
449
450* columnNumber: the column number for which offset is an entry point
451
452* offset: the bytecode instruction offset of the entry point
453
454For example, suppose we have a script for the following source code:
455
456```js
457a=[]
458for (i=1; i < 10; i++)
459    // It's hip to be square.
460    a[i] = i*i;
461```
462
463Calling `getAllColumnOffsets()` on that code might yield an array like this:
464
465```js
466[{ lineNumber: 0, columnNumber: 0, offset: 0 },
467  { lineNumber: 1, columnNumber: 5, offset: 5 },
468  { lineNumber: 1, columnNumber: 10, offset: 20 },
469  { lineNumber: 3, columnNumber: 4, offset: 10 }]
470```
471
472**If the instance refers to WebAssembly code**, throw a `TypeError`.
473
474#### `getLineOffsets(line)`
475**If the instance refers to a `JSScript`**, return an array of bytecode
476instruction offsets representing the entry points to source line
477<i>line</i>. If the script contains no executable code at that line, the
478array returned is empty.
479
480#### `getOffsetLocation(offset)`
481**If the instance refers to a `JSScript`**, return an object describing the
482source code location responsible for the bytecode at <i>offset</i> in this
483script.  The object has the following properties:
484
485* `lineNumber`: the line number for which offset is an entry point
486
487* `columnNumber`: the column number for which offset is an entry point
488
489* `isEntryPoint`: true if the offset is a column entry point, as
490  would be reported by getAllColumnOffsets(); otherwise false.
491
492
493[debugger-object]: Debugger.md
494[source]: Debugger.Source.md
495[object]: Debugger.Object.md
496[frame]: Debugger.Frame.md
497[rv]: ./Conventions.html#resumption-values
498