You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| 7 (endfinally) || Exits a finally block, resuming any previous operation (such as a break, return, throw, etc.) |
99
99
100
100
# State
101
-
The `_`, `f`, `y`, and `t` variables make up the persistent state of the `__generator` function. Each variable
101
+
The `_`, `f`, `y`, `t`, and `g` variables make up the persistent state of the `__generator` function. Each variable
102
102
has a specific purpose, as described in the following sections:
103
103
104
104
## The `_` variable
@@ -148,6 +148,12 @@ The `t` variable is a temporary variable that stores one of the following values
148
148
149
149
> NOTE: None of the above cases overlap.
150
150
151
+
## The `g` variable
152
+
The `g` variable is a temporary variable that holds onto the generator object for the purpose of attaching a
153
+
`Symbol.iterator` method (if its available), and holds onto that value until the generator is started, allowing
154
+
155
+
it to also act as the [`suspendedStart`](https://tc39.es/ecma262/#table-internal-slots-of-generator-instances) state.
156
+
151
157
# Protected Regions
152
158
A **Protected Region** is a region within the `body` function that indicates a
153
159
`try..catch..finally` statement. It consists of a 4-tuple that contains 4 labels:
@@ -164,13 +170,18 @@ The final step of the `__generator` helper is the allocation of an object that i
164
170
`Generator` protocol, to be used by the `__awaiter` helper:
@@ -219,13 +230,25 @@ The main body of the `step` function consists of a `while` loop which continues
219
230
instructions until the generator exits or is suspended:
220
231
221
232
```ts
222
-
while (_) try...
233
+
while (g&& (g=0, op[0] && (_=0)), _) try...
223
234
```
224
235
236
+
During the first call to `next()`, `return()`, or `throw()`, the generator will be in the `suspendedStart` state. This
237
+
is indicated by the `g` variable being "truthy" since it still holds a reference to the generator object. If `g` is
238
+
"truthy", then we reset it and check whether the first instruction sent to the generator (`op[0]`) is either a
239
+
`return` (`op[0] === 1`) or `throw` (`op[0] === 2`) Opcode, indicating an abrupt completion.
240
+
241
+
If the first instruction is abrupt, we can emulate [GeneratorResumeAbrupt](https://tc39.es/ecma262/#sec-generatorresumeabrupt)
242
+
by setting the state variable (`_`) to a falsy value, which will skip the loop body and
243
+
[complete the generator](#handling-a-completed-generator).
244
+
245
+
If this is _not_ the first instruction sent to the generator, or if the first instruction was `next()`, we will proceed
246
+
to evaluate the loop body.
247
+
225
248
When the generator has run to completion, the `_` state variable will be cleared, forcing the loop
226
249
to exit.
227
250
228
-
## Evaluating the generator body.
251
+
## Evaluating the generator body
229
252
```ts
230
253
try {
231
254
...
@@ -272,8 +295,8 @@ reduce the overall footprint of the helper.
272
295
The first two statements of the `try..finally` statement handle delegation for `yield*`:
273
296
274
297
```ts
275
-
if (f=1, y&& (t=y[op[0] &2?"return":op[0] ?"throw":"next"]) &&!(t=t.call(y, op[1])).done) returnt;
0 commit comments