summaryrefslogtreecommitdiffstats
path: root/js/src/doc/Debugger/Debugger.Environment.md
blob: e970f02653aca046260d76db76f93e12295f93f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# 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`.

`optimizedOut`
:   True if this environment is optimized out. False otherwise. For example,
    functions whose locals are never aliased may present optimized-out
    environments. When true, `getVariable` returns an ordinary JavaScript
    object whose `optimizedOut` property is true on all bindings, and
    `setVariable` throws a `ReferenceError`.


## 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>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.