|
1 # General Conventions |
|
2 |
|
3 This page describes general conventions used in the [`Debugger`][debugger] API, |
|
4 and defines some terminology used throughout the specification. |
|
5 |
|
6 |
|
7 ## Properties |
|
8 |
|
9 Properties of objects that comprise the `Debugger` interface, and those |
|
10 that the interface creates, follow some general conventions: |
|
11 |
|
12 - Instances and prototypes are extensible; you can add your own properties |
|
13 and methods to them. |
|
14 |
|
15 - Properties are configurable. This applies to both "own" and prototype |
|
16 properties, and to both methods and data properties. (Leaving these |
|
17 properties open to redefinition will hopefully make it easier for |
|
18 JavaScript debugger code to cope with bugs, bug fixes, and changes in the |
|
19 interface over time.) |
|
20 |
|
21 - Method properties are writable. |
|
22 |
|
23 - We prefer inherited accessor properties to own data properties. Both are |
|
24 read using the same syntax, but inherited accessors seem like a more |
|
25 accurate reflection of what's going on. Unless otherwise noted, these |
|
26 properties have getters but no setters, as they cannot meaningfully be |
|
27 assigned to. |
|
28 |
|
29 |
|
30 ## Debuggee Values |
|
31 |
|
32 The `Debugger` interface follows some conventions to help debuggers safely |
|
33 inspect and modify the debuggee's objects and values. Primitive values are |
|
34 passed freely between debugger and debuggee; copying or wrapping is handled |
|
35 transparently. Objects received from the debuggee (including host objects |
|
36 like DOM elements) are fronted in the debugger by `Debugger.Object` |
|
37 instances, which provide reflection-oriented methods for inspecting their |
|
38 referents; see `Debugger.Object`, below. |
|
39 |
|
40 Of the debugger's objects, only `Debugger.Object` instances may be passed |
|
41 to the debuggee: when this occurs, the debuggee receives the |
|
42 `Debugger.Object`'s referent, not the `Debugger.Object` instance itself. |
|
43 |
|
44 In the descriptions below, the term "debuggee value" means either a |
|
45 primitive value or a `Debugger.Object` instance; it is a value that might |
|
46 be received from the debuggee, or that could be passed to the debuggee. |
|
47 |
|
48 |
|
49 ## Debuggee Code |
|
50 |
|
51 Each `Debugger` instance maintains a set of global objects that, taken |
|
52 together, comprise the debuggee. Code evaluated in the scope of a debuggee |
|
53 global object, directly or indirectly, is considered *debuggee code*. |
|
54 Similarly: |
|
55 |
|
56 - a *debuggee frame* is a frame running debuggee code; |
|
57 |
|
58 - a *debuggee function* is a function that closes over a debuggee |
|
59 global object (and thus the function's code is debuggee code); |
|
60 |
|
61 - a *debuggee environment* is an environment whose outermost |
|
62 enclosing environment is a debuggee global object; and |
|
63 |
|
64 - a *debuggee script* is a script containing debuggee code. |
|
65 |
|
66 |
|
67 ## Completion Values |
|
68 |
|
69 When a debuggee stack frame completes its execution, or when some sort |
|
70 of debuggee call initiated by the debugger finishes, the `Debugger` |
|
71 interface provides a value describing how the code completed; these are |
|
72 called *completion values*. A completion value has one of the |
|
73 following forms: |
|
74 |
|
75 <code>{ return: <i>value</i> }</code> |
|
76 : The code completed normally, returning <i>value</i>. <i>Value</i> is a |
|
77 debuggee value. |
|
78 |
|
79 <code>{ yield: <i>value</i> }</code> |
|
80 : <i>(Not yet implemented.)</i> The running code is a generator frame |
|
81 which has yielded <i>value</i>. <i>Value</i> is a debuggee value. |
|
82 |
|
83 <code>{ throw: <i>value</i> }</code> |
|
84 : The code threw <i>value</i> as an exception. <i>Value</i> is a debuggee |
|
85 value. |
|
86 |
|
87 `null` |
|
88 : The code was terminated, as if by the "slow script" dialog box. |
|
89 |
|
90 If control reaches the end of a generator frame, the completion value is |
|
91 <code>{ throw: <i>stop</i> }</code> where <i>stop</i> is a |
|
92 `Debugger.Object` object representing the `StopIteration` object being |
|
93 thrown. |
|
94 |
|
95 |
|
96 ## Resumption Values |
|
97 |
|
98 As the debuggee runs, the `Debugger` interface calls various |
|
99 debugger-provided handler functions to report the debuggee's behavior. |
|
100 Some of these calls can return a value indicating how the debuggee's |
|
101 execution should continue; these are called *resumption values*. A |
|
102 resumption value has one of the following forms: |
|
103 |
|
104 `undefined` |
|
105 : The debuggee should continue execution normally. |
|
106 |
|
107 <code>{ return: <i>value</i> }</code> |
|
108 : Return <i>value</i> immediately as the current value of the function. |
|
109 <i>Value</i> must be a debuggee value. (Most handler functions support |
|
110 this, except those whose descriptions say otherwise.) If the function |
|
111 was called as a constructor (that is, via a `new` expression), then |
|
112 <i>value</i> serves as the value returned by the function's body, not |
|
113 that produced by the `new` expression: if the value is not an object, |
|
114 the `new` expression returns the frame's `this` value. |
|
115 |
|
116 <code>{ yield: <i>value</i> }</code> |
|
117 : <i>(Not yet implemented.)</i> Yield <i>value</i> immediately as the |
|
118 next value of the current frame, which must be a generator frame. |
|
119 <i>Value</i> is a debuggee value. The current frame must be a generator |
|
120 frame that has not yet completed in some other way. You may use `yield` |
|
121 resumption values to substitute a new value or one already yielded by a |
|
122 generator, or to make a generator yield additional values. |
|
123 |
|
124 <code>{ throw: <i>value</i> }</code> |
|
125 : Throw <i>value</i> as an exception from the current bytecode |
|
126 instruction. <i>Value</i> must be a debuggee value. |
|
127 |
|
128 `null` |
|
129 : Terminate the debuggee, as if it had been cancelled by the "slow script" |
|
130 dialog box. |
|
131 |
|
132 If a function that would normally return a resumption value to indicate |
|
133 how the debuggee should continue instead throws an exception, we never |
|
134 propagate such an exception to the debuggee; instead, we call the |
|
135 associated `Debugger` instance's `uncaughtExceptionHook` property, as |
|
136 described below. |
|
137 |
|
138 |
|
139 ## The `Debugger.DebuggeeWouldRun` Exception |
|
140 |
|
141 Some debugger operations that appear to simply inspect the debuggee's state |
|
142 may actually cause debuggee code to run. For example, reading a variable |
|
143 might run a getter function on the global or on a `with` expression's |
|
144 operand; and getting an object's property descriptor will run a handler |
|
145 trap if the object is a proxy. To protect the debugger's integrity, only |
|
146 methods whose stated purpose is to run debuggee code can do so. These |
|
147 methods are called [invocation functions][inv fr], and they follow certain |
|
148 common conventions to report the debuggee's behavior safely. For other |
|
149 methods, if their normal operation would cause debuggee code to run, they |
|
150 throw an instance of the `Debugger.DebuggeeWouldRun` exception. |
|
151 |
|
152 A `Debugger.DebuggeeWouldRun` exception may have a `cause` property, |
|
153 providing more detailed information on why the debuggee would have run. The |
|
154 `cause` property's value is one of the following strings: |
|
155 |
|
156 <i>cause</i> value meaning |
|
157 -------------------- -------------------------------------------------------------------------------- |
|
158 "proxy" Carrying out the operation would have caused a proxy handler to run. |
|
159 "getter" Carrying out the operation would have caused an object property getter to run. |
|
160 "setter" Carrying out the operation would have caused an object property setter to run. |
|
161 |
|
162 If the system can't determine why control attempted to enter the debuggee, |
|
163 it will leave the exception's `cause` property undefined. |