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 — for example, 107if it is a top-level `eval` script — 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><</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