@next-core/cook 2.2.18 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/cook.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ApplyStringOrNumericAssignment, CreateListIteratorRecord, ApplyStringOrNumericBinaryOperator, GetV, GetValue, InitializeReferencedBinding, IsPropertyReference, LoopContinues, PutValue, RequireObjectCoercible, ToPropertyKey, UpdateEmpty, ApplyUnaryOperator, GetIdentifierReference, ForDeclarationBindingInstantiation, CopyDataProperties } from "./context-free.js";
2
- import { CompletionRecord, DeclarativeEnvironment, ECMAScriptCode, Empty, Environment, ExecutionContext, FormalParameters, FunctionEnvironment, IsConstructor, NormalCompletion, ReferenceRecord, SourceNode } from "./ExecutionContext.js";
2
+ import { CompletionRecord, DebuggerCall, DebuggerNode, DebuggerReturn, DebuggerScope, DeclarativeEnvironment, ECMAScriptCode, Empty, Environment, ExecutionContext, FormalParameters, FunctionEnvironment, IsConstructor, NormalCompletion, ReferenceRecord, SourceNode, Mode, ThisMode } from "./ExecutionContext.js";
3
3
  import { sanitize, isAllowedConstructor } from "./sanitize.js";
4
4
  import { collectBoundNames, collectScopedDeclarations, containsExpression } from "./traverse.js";
5
5
  /** For next-core internal usage only. */
@@ -7,10 +7,19 @@ export function cook(rootAst, codeSource) {
7
7
  var _hooks$beforeEvaluate3;
8
8
  let {
9
9
  rules,
10
+ debug,
11
+ externalSourceForDebug,
10
12
  globalVariables = {},
13
+ // Allow debugger to override Array constructor.
14
+ ArrayConstructor = Array,
11
15
  hooks = {}
12
16
  } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
13
17
  const expressionOnly = rootAst.type !== "FunctionDeclaration";
18
+ function doSanitize(cooked) {
19
+ if (!externalSourceForDebug) {
20
+ sanitize(cooked);
21
+ }
22
+ }
14
23
  const rootEnv = new DeclarativeEnvironment(null);
15
24
  const rootContext = new ExecutionContext();
16
25
  rootContext.VariableEnvironment = rootEnv;
@@ -41,23 +50,28 @@ export function cook(rootAst, codeSource) {
41
50
  TemplateMap.set(templateLiteral, template);
42
51
  return template;
43
52
  }
44
- function Evaluate(node, optionalChainRef) {
45
- var _hooks$beforeEvaluate, _hooks$beforeBranch, _hooks$beforeBranch2;
53
+ let currentNode;
54
+ function* Evaluate(node, optionalChainRef, forceYield) {
55
+ var _hooks$beforeEvaluate, _hooks$beforeBranch2;
46
56
  (_hooks$beforeEvaluate = hooks.beforeEvaluate) === null || _hooks$beforeEvaluate === void 0 || _hooks$beforeEvaluate.call(hooks, node);
57
+ currentNode = node;
58
+ if (debug && (forceYield || node.type.endsWith("Statement") && node.type !== "TryStatement" && node.type !== "BlockStatement" && node.type !== "ForStatement" && node.type !== "ForInStatement" && node.type !== "ForOfStatement")) {
59
+ yield;
60
+ }
47
61
  // Expressions:
48
62
  switch (node.type) {
49
63
  case "ArrayExpression":
50
64
  {
51
65
  // https://tc39.es/ecma262/#sec-array-initializer
52
- const array = [];
66
+ const array = new ArrayConstructor();
53
67
  for (const element of node.elements) {
54
68
  if (!element) {
55
69
  array.length += 1;
56
70
  } else if (element.type === "SpreadElement") {
57
- const spreadValues = GetValue(Evaluate(element.argument));
71
+ const spreadValues = GetValue(yield* Evaluate(element.argument));
58
72
  array.push(...spreadValues);
59
73
  } else {
60
- array.push(GetValue(Evaluate(element)));
74
+ array.push(GetValue(yield* Evaluate(element)));
61
75
  }
62
76
  }
63
77
  return NormalCompletion(array);
@@ -71,9 +85,9 @@ export function cook(rootAst, codeSource) {
71
85
  }
72
86
  case "BinaryExpression":
73
87
  {
74
- const leftRef = Evaluate(node.left);
88
+ const leftRef = yield* Evaluate(node.left);
75
89
  const leftValue = GetValue(leftRef);
76
- const rightRef = Evaluate(node.right).Value;
90
+ const rightRef = yield* Evaluate(node.right);
77
91
  const rightValue = GetValue(rightRef);
78
92
  if (expressionOnly && node.operator === "|>") {
79
93
  // Minimal pipeline operator is supported only in expression-only mode.
@@ -98,21 +112,22 @@ export function cook(rootAst, codeSource) {
98
112
  case "CallExpression":
99
113
  {
100
114
  // https://tc39.es/ecma262/#sec-function-calls
101
- const ref = Evaluate(node.callee, optionalChainRef).Value;
115
+ const ref = (yield* Evaluate(node.callee, optionalChainRef)).Value;
102
116
  const func = GetValue(ref);
103
117
  if ((func === undefined || func === null) && (node.optional || optionalChainRef !== null && optionalChainRef !== void 0 && optionalChainRef.skipped)) {
104
118
  optionalChainRef.skipped = true;
105
119
  return NormalCompletion(undefined);
106
120
  }
107
- sanitize(func);
108
- return EvaluateCall(func, ref, node.arguments, node.callee);
121
+ doSanitize(func);
122
+ if (debug) yield;
123
+ return yield* EvaluateCall(func, ref, node.arguments, node.callee);
109
124
  }
110
125
  case "ChainExpression":
111
126
  // https://tc39.es/ecma262/#sec-optional-chains
112
- return Evaluate(node.expression, {});
127
+ return yield* Evaluate(node.expression, {});
113
128
  case "ConditionalExpression":
114
129
  // https://tc39.es/ecma262/#sec-conditional-operator
115
- return NormalCompletion(GetValue(Evaluate(GetValue(Evaluate(node.test)) ? node.consequent : node.alternate)));
130
+ return NormalCompletion(GetValue(yield* Evaluate(GetValue(yield* Evaluate(node.test)) ? node.consequent : node.alternate)));
116
131
  case "Identifier":
117
132
  // https://tc39.es/ecma262/#sec-identifiers
118
133
  return NormalCompletion(ResolveBinding(node.name));
@@ -134,14 +149,14 @@ export function cook(rootAst, codeSource) {
134
149
  case "LogicalExpression":
135
150
  {
136
151
  // https://tc39.es/ecma262/#sec-binary-logical-operators
137
- const leftValue = GetValue(Evaluate(node.left));
152
+ const leftValue = GetValue(yield* Evaluate(node.left));
138
153
  switch (node.operator) {
139
154
  case "&&":
140
- return NormalCompletion(leftValue && GetValue(Evaluate(node.right)));
155
+ return NormalCompletion(leftValue && GetValue(yield* Evaluate(node.right)));
141
156
  case "||":
142
- return NormalCompletion(leftValue || GetValue(Evaluate(node.right)));
157
+ return NormalCompletion(leftValue || GetValue(yield* Evaluate(node.right)));
143
158
  case "??":
144
- return NormalCompletion(leftValue ?? GetValue(Evaluate(node.right)));
159
+ return NormalCompletion(leftValue ?? GetValue(yield* Evaluate(node.right)));
145
160
  // istanbul ignore next
146
161
  default:
147
162
  throw new SyntaxError(
@@ -153,37 +168,41 @@ export function cook(rootAst, codeSource) {
153
168
  case "MemberExpression":
154
169
  {
155
170
  // https://tc39.es/ecma262/#sec-property-accessors
156
- const baseReference = Evaluate(node.object, optionalChainRef).Value;
171
+ const baseReference = (yield* Evaluate(node.object, optionalChainRef)).Value;
157
172
  const baseValue = GetValue(baseReference);
158
173
  if ((baseValue === undefined || baseValue === null) && (node.optional || optionalChainRef !== null && optionalChainRef !== void 0 && optionalChainRef.skipped)) {
159
174
  optionalChainRef.skipped = true;
160
175
  return NormalCompletion(undefined);
161
176
  }
162
- sanitize(baseValue);
163
- const result = node.computed ? EvaluatePropertyAccessWithExpressionKey(baseValue, node.property, true) : EvaluatePropertyAccessWithIdentifierKey(baseValue, node.property, true);
164
- sanitize(result);
177
+ doSanitize(baseValue);
178
+ const result = node.computed ? yield* EvaluatePropertyAccessWithExpressionKey(baseValue, node.property, true) : EvaluatePropertyAccessWithIdentifierKey(baseValue, node.property, true);
179
+ doSanitize(result);
165
180
  return NormalCompletion(result);
166
181
  }
167
182
  case "NewExpression":
168
183
  // https://tc39.es/ecma262/#sec-new-operator
169
- return EvaluateNew(node.callee, node.arguments);
184
+ return yield* EvaluateNew(node.callee, node.arguments);
170
185
  case "ObjectExpression":
171
186
  {
172
187
  // https://tc39.es/ecma262/#sec-object-initializer
173
188
  const object = {};
174
189
  for (const prop of node.properties) {
175
190
  if (prop.type === "SpreadElement") {
176
- const fromValue = GetValue(Evaluate(prop.argument));
191
+ const fromValue = GetValue(yield* Evaluate(prop.argument));
177
192
  CopyDataProperties(object, fromValue, new Set());
178
193
  } else {
179
194
  if (prop.kind !== "init") {
180
195
  throw new SyntaxError("Unsupported object getter/setter");
181
196
  }
182
- const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : EvaluateComputedPropertyName(prop.key);
197
+ const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : yield* EvaluateComputedPropertyName(prop.key);
183
198
  if (propName === "__proto__") {
184
199
  throw new TypeError("Setting '__proto__' property is not allowed");
185
200
  }
186
- object[propName] = GetValue(Evaluate(prop.value));
201
+ const propValue = GetValue(yield* Evaluate(prop.value));
202
+ if (prop.method && typeof propValue === "function") {
203
+ SetFunctionName(propValue, propName);
204
+ }
205
+ object[propName] = propValue;
187
206
  }
188
207
  }
189
208
  return NormalCompletion(object);
@@ -193,7 +212,7 @@ export function cook(rootAst, codeSource) {
193
212
  // https://tc39.es/ecma262/#sec-comma-operator
194
213
  let result;
195
214
  for (const expr of node.expressions) {
196
- result = NormalCompletion(GetValue(Evaluate(expr)));
215
+ result = NormalCompletion(GetValue(yield* Evaluate(expr)));
197
216
  }
198
217
  return result;
199
218
  }
@@ -203,7 +222,7 @@ export function cook(rootAst, codeSource) {
203
222
  const chunks = [node.quasis[0].value.cooked];
204
223
  let index = 0;
205
224
  for (const expr of node.expressions) {
206
- const val = GetValue(Evaluate(expr));
225
+ const val = GetValue(yield* Evaluate(expr));
207
226
  chunks.push(String(val));
208
227
  chunks.push(node.quasis[index += 1].value.cooked);
209
228
  }
@@ -212,15 +231,16 @@ export function cook(rootAst, codeSource) {
212
231
  case "TaggedTemplateExpression":
213
232
  {
214
233
  // https://tc39.es/ecma262/#sec-tagged-templates
215
- const tagRef = Evaluate(node.tag).Value;
234
+ const tagRef = (yield* Evaluate(node.tag)).Value;
216
235
  const tagFunc = GetValue(tagRef);
217
- sanitize(tagFunc);
218
- return EvaluateCall(tagFunc, tagRef, node.quasi, node.tag);
236
+ doSanitize(tagFunc);
237
+ if (debug) yield;
238
+ return yield* EvaluateCall(tagFunc, tagRef, node.quasi, node.tag);
219
239
  }
220
240
  case "UnaryExpression":
221
241
  {
222
242
  // https://tc39.es/ecma262/#sec-unary-operators
223
- const ref = Evaluate(node.argument).Value;
243
+ const ref = (yield* Evaluate(node.argument)).Value;
224
244
  if (!expressionOnly && node.operator === "delete") {
225
245
  // Delete operator is supported only in function mode.
226
246
  if (!(ref instanceof ReferenceRecord)) {
@@ -250,22 +270,26 @@ export function cook(rootAst, codeSource) {
250
270
  // https://tc39.es/ecma262/#sec-assignment-operators
251
271
  if (node.operator === "=") {
252
272
  if (!(node.left.type === "ArrayPattern" || node.left.type === "ObjectPattern")) {
253
- const lref = Evaluate(node.left).Value;
254
- // Todo: IsAnonymousFunctionDefinition(lref)
255
- const rref = Evaluate(node.right);
256
- const rval = GetValue(rref);
273
+ const lref = (yield* Evaluate(node.left)).Value;
274
+ let rval;
275
+ if (IsAnonymousFunctionDefinition(node.right) && node.left.type === "Identifier") {
276
+ rval = NamedEvaluation(node.right, node.left.name);
277
+ } else {
278
+ const rref = yield* Evaluate(node.right);
279
+ rval = GetValue(rref);
280
+ }
257
281
  PutValue(lref, rval);
258
282
  return NormalCompletion(rval);
259
283
  }
260
- const rref = Evaluate(node.right);
284
+ const rref = yield* Evaluate(node.right);
261
285
  const rval = GetValue(rref);
262
- DestructuringAssignmentEvaluation(node.left, rval);
286
+ yield* DestructuringAssignmentEvaluation(node.left, rval);
263
287
  return NormalCompletion(rval);
264
288
  }
265
289
  // Operators other than `=`.
266
- const lref = Evaluate(node.left).Value;
290
+ const lref = (yield* Evaluate(node.left)).Value;
267
291
  const lval = GetValue(lref);
268
- const rref = Evaluate(node.right);
292
+ const rref = yield* Evaluate(node.right);
269
293
  const rval = GetValue(rref);
270
294
  const r = ApplyStringOrNumericAssignment(lval, node.operator, rval);
271
295
  PutValue(lref, r);
@@ -281,7 +305,7 @@ export function cook(rootAst, codeSource) {
281
305
  const blockEnv = new DeclarativeEnvironment(oldEnv);
282
306
  BlockDeclarationInstantiation(node.body, blockEnv);
283
307
  getRunningContext().LexicalEnvironment = blockEnv;
284
- const blockValue = EvaluateStatementList(node.body);
308
+ const blockValue = yield* EvaluateStatementList(node.body);
285
309
  getRunningContext().LexicalEnvironment = oldEnv;
286
310
  return blockValue;
287
311
  }
@@ -296,18 +320,18 @@ export function cook(rootAst, codeSource) {
296
320
  return NormalCompletion(Empty);
297
321
  case "DoWhileStatement":
298
322
  // https://tc39.es/ecma262/#sec-do-while-statement
299
- return EvaluateBreakableStatement(DoWhileLoopEvaluation(node));
323
+ return EvaluateBreakableStatement(yield* DoWhileLoopEvaluation(node));
300
324
  case "ExpressionStatement":
301
325
  case "TSAsExpression":
302
326
  // https://tc39.es/ecma262/#sec-expression-statement
303
- return Evaluate(node.expression);
327
+ return yield* Evaluate(node.expression);
304
328
  case "ForInStatement":
305
329
  case "ForOfStatement":
306
330
  // https://tc39.es/ecma262/#sec-for-in-and-for-of-statements
307
- return EvaluateBreakableStatement(ForInOfLoopEvaluation(node));
331
+ return EvaluateBreakableStatement(yield* ForInOfLoopEvaluation(node));
308
332
  case "ForStatement":
309
333
  // https://tc39.es/ecma262/#sec-for-statement
310
- return EvaluateBreakableStatement(ForLoopEvaluation(node));
334
+ return EvaluateBreakableStatement(yield* ForLoopEvaluation(node));
311
335
  case "FunctionDeclaration":
312
336
  // https://tc39.es/ecma262/#sec-function-definitions
313
337
  return NormalCompletion(Empty);
@@ -317,41 +341,58 @@ export function cook(rootAst, codeSource) {
317
341
  return NormalCompletion(InstantiateOrdinaryFunctionExpression(node));
318
342
  case "IfStatement":
319
343
  // https://tc39.es/ecma262/#sec-if-statement
320
- return GetValue(Evaluate(node.test)) ? ((_hooks$beforeBranch = hooks.beforeBranch) !== null && _hooks$beforeBranch !== void 0 && _hooks$beforeBranch.call(hooks, node, "if"), UpdateEmpty(Evaluate(node.consequent), undefined)) : ((_hooks$beforeBranch2 = hooks.beforeBranch) !== null && _hooks$beforeBranch2 !== void 0 && _hooks$beforeBranch2.call(hooks, node, "else"), node.alternate) ? UpdateEmpty(Evaluate(node.alternate), undefined) : NormalCompletion(undefined);
344
+ if (GetValue(yield* Evaluate(node.test))) {
345
+ var _hooks$beforeBranch;
346
+ (_hooks$beforeBranch = hooks.beforeBranch) === null || _hooks$beforeBranch === void 0 || _hooks$beforeBranch.call(hooks, node, "if");
347
+ return UpdateEmpty(yield* Evaluate(node.consequent), undefined);
348
+ }
349
+ (_hooks$beforeBranch2 = hooks.beforeBranch) === null || _hooks$beforeBranch2 === void 0 || _hooks$beforeBranch2.call(hooks, node, "else");
350
+ if (node.alternate) {
351
+ return UpdateEmpty(yield* Evaluate(node.alternate), undefined);
352
+ }
353
+ return NormalCompletion(undefined);
321
354
  case "ReturnStatement":
322
355
  {
323
356
  // https://tc39.es/ecma262/#sec-return-statement
324
357
  let v;
325
358
  if (node.argument) {
326
- const exprRef = Evaluate(node.argument);
359
+ const exprRef = yield* Evaluate(node.argument);
327
360
  v = GetValue(exprRef);
328
361
  }
329
362
  return new CompletionRecord("return", v);
330
363
  }
364
+ case "ThisExpression":
365
+ {
366
+ if (!externalSourceForDebug) {
367
+ break;
368
+ }
369
+ const envRec = GetThisEnvironment();
370
+ return NormalCompletion(envRec.GetThisBinding());
371
+ }
331
372
  case "ThrowStatement":
332
373
  // https://tc39.es/ecma262/#sec-throw-statement
333
- throw GetValue(Evaluate(node.argument));
374
+ throw GetValue(yield* Evaluate(node.argument));
334
375
  case "UpdateExpression":
335
376
  {
336
377
  // https://tc39.es/ecma262/#sec-update-expressions
337
- const lhs = Evaluate(node.argument).Value;
378
+ const lhs = (yield* Evaluate(node.argument)).Value;
338
379
  const oldValue = Number(GetValue(lhs));
339
380
  const newValue = node.operator === "++" ? oldValue + 1 : oldValue - 1;
340
381
  PutValue(lhs, newValue);
341
382
  return NormalCompletion(node.prefix ? newValue : oldValue);
342
383
  }
343
384
  case "SwitchCase":
344
- return EvaluateStatementList(node.consequent);
385
+ return yield* EvaluateStatementList(node.consequent);
345
386
  case "SwitchStatement":
346
387
  {
347
388
  // https://tc39.es/ecma262/#sec-switch-statement
348
- const exprRef = Evaluate(node.discriminant);
389
+ const exprRef = yield* Evaluate(node.discriminant);
349
390
  const switchValue = GetValue(exprRef);
350
391
  const oldEnv = getRunningContext().LexicalEnvironment;
351
392
  const blockEnv = new DeclarativeEnvironment(oldEnv);
352
393
  BlockDeclarationInstantiation(node.cases, blockEnv);
353
394
  getRunningContext().LexicalEnvironment = blockEnv;
354
- const R = CaseBlockEvaluation(node.cases, switchValue);
395
+ const R = yield* CaseBlockEvaluation(node.cases, switchValue);
355
396
  getRunningContext().LexicalEnvironment = oldEnv;
356
397
  return EvaluateBreakableStatement(R);
357
398
  }
@@ -360,18 +401,19 @@ export function cook(rootAst, codeSource) {
360
401
  // https://tc39.es/ecma262/#sec-try-statement
361
402
  let R;
362
403
  try {
363
- R = Evaluate(node.block);
404
+ R = yield* Evaluate(node.block);
364
405
  } catch (error) {
365
406
  if (node.handler) {
366
407
  var _hooks$beforeEvaluate2;
408
+ currentNode = node.handler;
367
409
  (_hooks$beforeEvaluate2 = hooks.beforeEvaluate) === null || _hooks$beforeEvaluate2 === void 0 || _hooks$beforeEvaluate2.call(hooks, node.handler);
368
- R = CatchClauseEvaluation(node.handler, error);
410
+ R = yield* CatchClauseEvaluation(node.handler, error);
369
411
  } else {
370
412
  throw error;
371
413
  }
372
414
  } finally {
373
415
  if (node.finalizer) {
374
- const F = Evaluate(node.finalizer);
416
+ const F = yield* Evaluate(node.finalizer);
375
417
  if (F.Type !== "normal") {
376
418
  R = F;
377
419
  }
@@ -384,6 +426,7 @@ export function cook(rootAst, codeSource) {
384
426
  // https://tc39.es/ecma262/#sec-declarations-and-the-variable-statement
385
427
  let result;
386
428
  for (const declarator of node.declarations) {
429
+ currentNode = declarator;
387
430
  if (!declarator.init) {
388
431
  // Assert: a declarator without init is always an identifier.
389
432
  if (node.kind === "var") {
@@ -393,23 +436,31 @@ export function cook(rootAst, codeSource) {
393
436
  result = InitializeReferencedBinding(lhs, undefined);
394
437
  }
395
438
  } else if (declarator.id.type === "Identifier") {
439
+ currentNode = declarator.init;
440
+ if (debug) yield;
396
441
  const bindingId = declarator.id.name;
397
442
  const lhs = ResolveBinding(bindingId);
398
- // Todo: IsAnonymousFunctionDefinition(Initializer)
399
- const rhs = Evaluate(declarator.init);
400
- const value = GetValue(rhs);
443
+ let value;
444
+ if (IsAnonymousFunctionDefinition(declarator.init)) {
445
+ value = NamedEvaluation(declarator.init, bindingId);
446
+ } else {
447
+ const rhs = yield* Evaluate(declarator.init);
448
+ value = GetValue(rhs);
449
+ }
401
450
  result = node.kind === "var" ? PutValue(lhs, value) : InitializeReferencedBinding(lhs, value);
402
451
  } else {
403
- const rhs = Evaluate(declarator.init);
452
+ currentNode = declarator.init;
453
+ if (debug) yield;
454
+ const rhs = yield* Evaluate(declarator.init);
404
455
  const rval = GetValue(rhs);
405
- result = BindingInitialization(declarator.id, rval, node.kind === "var" ? undefined : getRunningContext().LexicalEnvironment);
456
+ result = yield* BindingInitialization(declarator.id, rval, node.kind === "var" ? undefined : getRunningContext().LexicalEnvironment);
406
457
  }
407
458
  }
408
459
  return result;
409
460
  }
410
461
  case "WhileStatement":
411
462
  // https://tc39.es/ecma262/#sec-while-statement
412
- return EvaluateBreakableStatement(WhileLoopEvaluation(node));
463
+ return EvaluateBreakableStatement(yield* WhileLoopEvaluation(node));
413
464
  }
414
465
  }
415
466
  // eslint-disable-next-line no-console
@@ -431,9 +482,9 @@ export function cook(rootAst, codeSource) {
431
482
 
432
483
  // Try statements.
433
484
  // https://tc39.es/ecma262/#sec-runtime-semantics-catchclauseevaluation
434
- function CatchClauseEvaluation(node, thrownValue) {
485
+ function* CatchClauseEvaluation(node, thrownValue) {
435
486
  if (!node.param) {
436
- return Evaluate(node.body);
487
+ return yield* Evaluate(node.body);
437
488
  }
438
489
  const oldEnv = getRunningContext().LexicalEnvironment;
439
490
  const catchEnv = new DeclarativeEnvironment(oldEnv);
@@ -441,8 +492,8 @@ export function cook(rootAst, codeSource) {
441
492
  catchEnv.CreateMutableBinding(argName, false);
442
493
  }
443
494
  getRunningContext().LexicalEnvironment = catchEnv;
444
- BindingInitialization(node.param, thrownValue, catchEnv);
445
- const B = Evaluate(node.body);
495
+ yield* BindingInitialization(node.param, thrownValue, catchEnv);
496
+ const B = yield* Evaluate(node.body);
446
497
  getRunningContext().LexicalEnvironment = oldEnv;
447
498
  return B;
448
499
  }
@@ -455,7 +506,7 @@ export function cook(rootAst, codeSource) {
455
506
 
456
507
  // Switch statements.
457
508
  // https://tc39.es/ecma262/#sec-runtime-semantics-caseblockevaluation
458
- function CaseBlockEvaluation(cases, input) {
509
+ function* CaseBlockEvaluation(cases, input) {
459
510
  let V;
460
511
  const defaultCaseIndex = cases.findIndex(switchCase => !switchCase.test);
461
512
  const hasDefaultCase = defaultCaseIndex >= 0;
@@ -463,10 +514,10 @@ export function cook(rootAst, codeSource) {
463
514
  let found = false;
464
515
  for (const C of A) {
465
516
  if (!found) {
466
- found = CaseClauseIsSelected(C, input);
517
+ found = yield* CaseClauseIsSelected(C, input);
467
518
  }
468
519
  if (found) {
469
- const R = Evaluate(C);
520
+ const R = yield* Evaluate(C);
470
521
  if (R.Value !== Empty) {
471
522
  V = R.Value;
472
523
  }
@@ -483,10 +534,10 @@ export function cook(rootAst, codeSource) {
483
534
  if (!found) {
484
535
  for (const C of B) {
485
536
  if (!foundInB) {
486
- foundInB = CaseClauseIsSelected(C, input);
537
+ foundInB = yield* CaseClauseIsSelected(C, input);
487
538
  }
488
539
  if (foundInB) {
489
- const R = Evaluate(C);
540
+ const R = yield* Evaluate(C);
490
541
  if (R.Value !== Empty) {
491
542
  V = R.Value;
492
543
  }
@@ -499,7 +550,7 @@ export function cook(rootAst, codeSource) {
499
550
  if (foundInB) {
500
551
  return NormalCompletion(V);
501
552
  }
502
- const R = Evaluate(cases[defaultCaseIndex]);
553
+ const R = yield* Evaluate(cases[defaultCaseIndex]);
503
554
  if (R.Value !== Empty) {
504
555
  V = R.Value;
505
556
  }
@@ -509,7 +560,7 @@ export function cook(rootAst, codeSource) {
509
560
 
510
561
  // NOTE: The following is another complete iteration of the second CaseClauses.
511
562
  for (const C of B) {
512
- const R = Evaluate(C);
563
+ const R = yield* Evaluate(C);
513
564
  if (R.Value !== Empty) {
514
565
  V = R.Value;
515
566
  }
@@ -521,22 +572,22 @@ export function cook(rootAst, codeSource) {
521
572
  }
522
573
 
523
574
  // https://tc39.es/ecma262/#sec-runtime-semantics-caseclauseisselected
524
- function CaseClauseIsSelected(C, input) {
525
- const clauseSelector = GetValue(Evaluate(C.test));
575
+ function* CaseClauseIsSelected(C, input) {
576
+ const clauseSelector = GetValue(yield* Evaluate(C.test));
526
577
  return input === clauseSelector;
527
578
  }
528
579
 
529
580
  // While statements.
530
581
  // https://tc39.es/ecma262/#sec-runtime-semantics-whileloopevaluation
531
- function WhileLoopEvaluation(node) {
582
+ function* WhileLoopEvaluation(node) {
532
583
  let V;
533
584
  // eslint-disable-next-line no-constant-condition
534
585
  while (true) {
535
- const exprValue = GetValue(Evaluate(node.test));
586
+ const exprValue = GetValue(yield* Evaluate(node.test));
536
587
  if (!exprValue) {
537
588
  return NormalCompletion(V);
538
589
  }
539
- const stmtResult = Evaluate(node.body);
590
+ const stmtResult = yield* Evaluate(node.body);
540
591
  if (!LoopContinues(stmtResult)) {
541
592
  return UpdateEmpty(stmtResult, V);
542
593
  }
@@ -548,18 +599,18 @@ export function cook(rootAst, codeSource) {
548
599
 
549
600
  // Do-while Statements.
550
601
  // https://tc39.es/ecma262/#sec-runtime-semantics-dowhileloopevaluation
551
- function DoWhileLoopEvaluation(node) {
602
+ function* DoWhileLoopEvaluation(node) {
552
603
  let V;
553
604
  // eslint-disable-next-line no-constant-condition
554
605
  while (true) {
555
- const stmtResult = Evaluate(node.body);
606
+ const stmtResult = yield* Evaluate(node.body);
556
607
  if (!LoopContinues(stmtResult)) {
557
608
  return UpdateEmpty(stmtResult, V);
558
609
  }
559
610
  if (stmtResult.Value !== Empty) {
560
611
  V = stmtResult.Value;
561
612
  }
562
- const exprValue = GetValue(Evaluate(node.test));
613
+ const exprValue = GetValue(yield* Evaluate(node.test));
563
614
  if (!exprValue) {
564
615
  return NormalCompletion(V);
565
616
  }
@@ -568,22 +619,22 @@ export function cook(rootAst, codeSource) {
568
619
 
569
620
  // For in/of statements.
570
621
  // https://tc39.es/ecma262/#sec-runtime-semantics-forinofloopevaluation
571
- function ForInOfLoopEvaluation(node) {
622
+ function* ForInOfLoopEvaluation(node) {
572
623
  const lhs = node.left;
573
624
  const isVariableDeclaration = lhs.type === "VariableDeclaration";
574
625
  const lhsKind = isVariableDeclaration ? lhs.kind === "var" ? "varBinding" : "lexicalBinding" : "assignment";
575
626
  const uninitializedBoundNames = lhsKind === "lexicalBinding" ? collectBoundNames(lhs) : [];
576
627
  const iterationKind = node.type === "ForInStatement" ? "enumerate" : "iterate";
577
- const keyResult = ForInOfHeadEvaluation(uninitializedBoundNames, node.right, iterationKind);
628
+ const keyResult = yield* ForInOfHeadEvaluation(uninitializedBoundNames, node.right, iterationKind);
578
629
  if (keyResult.Type !== "normal") {
579
630
  // When enumerate, if the target is nil, a break completion will be returned.
580
631
  return keyResult;
581
632
  }
582
- return ForInOfBodyEvaluation(lhs, node.body, keyResult.Value, iterationKind, lhsKind);
633
+ return yield* ForInOfBodyEvaluation(lhs, node.body, keyResult.Value, iterationKind, lhsKind);
583
634
  }
584
635
 
585
636
  // https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
586
- function ForInOfHeadEvaluation(uninitializedBoundNames, expr, iterationKind) {
637
+ function* ForInOfHeadEvaluation(uninitializedBoundNames, expr, iterationKind) {
587
638
  const runningContext = getRunningContext();
588
639
  const oldEnv = runningContext.LexicalEnvironment;
589
640
  if (uninitializedBoundNames.length > 0) {
@@ -593,7 +644,7 @@ export function cook(rootAst, codeSource) {
593
644
  }
594
645
  runningContext.LexicalEnvironment = newEnv;
595
646
  }
596
- const exprRef = Evaluate(expr);
647
+ const exprRef = yield* Evaluate(expr, undefined, true);
597
648
  runningContext.LexicalEnvironment = oldEnv;
598
649
  const exprValue = GetValue(exprRef);
599
650
  if (iterationKind === "enumerate") {
@@ -606,7 +657,7 @@ export function cook(rootAst, codeSource) {
606
657
  const iterator = CreateListIteratorRecord(exprValue);
607
658
  return NormalCompletion(iterator);
608
659
  }
609
- function ForInOfBodyEvaluation(node, stmt, iteratorRecord, iterationKind, lhsKind) {
660
+ function* ForInOfBodyEvaluation(node, stmt, iteratorRecord, iterationKind, lhsKind) {
610
661
  const lhs = lhsKind === "assignment" ? node : node.declarations[0].id;
611
662
  const oldEnv = getRunningContext().LexicalEnvironment;
612
663
  let V;
@@ -618,11 +669,13 @@ export function cook(rootAst, codeSource) {
618
669
  const destructuring = lhs.type === "ObjectPattern" || lhs.type === "ArrayPattern";
619
670
  // eslint-disable-next-line no-constant-condition
620
671
  while (true) {
672
+ currentNode = lhs;
621
673
  const {
622
674
  done,
623
675
  value: nextValue
624
676
  } = iteratorRecord.next();
625
677
  if (done) {
678
+ if (debug) yield;
626
679
  return NormalCompletion(V);
627
680
  }
628
681
  let lhsRef;
@@ -631,15 +684,19 @@ export function cook(rootAst, codeSource) {
631
684
  iterationEnv = new DeclarativeEnvironment(oldEnv);
632
685
  ForDeclarationBindingInstantiation(node, iterationEnv);
633
686
  getRunningContext().LexicalEnvironment = iterationEnv;
687
+ if (debug) yield;
634
688
  if (!destructuring) {
635
689
  const [lhsName] = collectBoundNames(lhs);
636
690
  lhsRef = ResolveBinding(lhsName);
637
691
  }
638
- } else if (!destructuring) {
639
- lhsRef = Evaluate(lhs).Value;
692
+ } else {
693
+ if (debug) yield;
694
+ if (!destructuring) {
695
+ lhsRef = (yield* Evaluate(lhs)).Value;
696
+ }
640
697
  }
641
- destructuring ? lhsKind === "assignment" ? DestructuringAssignmentEvaluation(lhs, nextValue) : lhsKind === "varBinding" ? BindingInitialization(lhs, nextValue, undefined) : BindingInitialization(lhs, nextValue, iterationEnv) : lhsKind === "lexicalBinding" ? InitializeReferencedBinding(lhsRef, nextValue) : PutValue(lhsRef, nextValue);
642
- const result = Evaluate(stmt);
698
+ destructuring ? lhsKind === "assignment" ? yield* DestructuringAssignmentEvaluation(lhs, nextValue) : lhsKind === "varBinding" ? yield* BindingInitialization(lhs, nextValue, undefined) : yield* BindingInitialization(lhs, nextValue, iterationEnv) : lhsKind === "lexicalBinding" ? InitializeReferencedBinding(lhsRef, nextValue) : PutValue(lhsRef, nextValue);
699
+ const result = yield* Evaluate(stmt);
643
700
  getRunningContext().LexicalEnvironment = oldEnv;
644
701
  if (!LoopContinues(result)) {
645
702
  const status = UpdateEmpty(result, V);
@@ -668,13 +725,13 @@ export function cook(rootAst, codeSource) {
668
725
 
669
726
  // For statements.
670
727
  // https://tc39.es/ecma262/#sec-runtime-semantics-forloopevaluation
671
- function ForLoopEvaluation(node) {
728
+ function* ForLoopEvaluation(node) {
672
729
  var _node$init;
673
730
  if (((_node$init = node.init) === null || _node$init === void 0 ? void 0 : _node$init.type) === "VariableDeclaration") {
674
731
  // `for (var … ; … ; … ) …`
675
732
  if (node.init.kind === "var") {
676
- Evaluate(node.init);
677
- return ForBodyEvaluation(node.test, node.update, node.body, []);
733
+ yield* Evaluate(node.init);
734
+ return yield* ForBodyEvaluation(node.test, node.update, node.body, []);
678
735
  }
679
736
  // `for (let/const … ; … ; … ) …`
680
737
  const oldEnv = getRunningContext().LexicalEnvironment;
@@ -689,34 +746,34 @@ export function cook(rootAst, codeSource) {
689
746
  }
690
747
  }
691
748
  getRunningContext().LexicalEnvironment = loopEnv;
692
- Evaluate(node.init);
749
+ yield* Evaluate(node.init);
693
750
  const perIterationLets = isConst ? [] : Array.from(boundNames);
694
- const bodyResult = ForBodyEvaluation(node.test, node.update, node.body, perIterationLets);
751
+ const bodyResult = yield* ForBodyEvaluation(node.test, node.update, node.body, perIterationLets);
695
752
  getRunningContext().LexicalEnvironment = oldEnv;
696
753
  return bodyResult;
697
754
  }
698
755
  // `for ( … ; … ; … ) …`
699
756
  if (node.init) {
700
- const exprRef = Evaluate(node.init);
757
+ const exprRef = yield* Evaluate(node.init);
701
758
  GetValue(exprRef);
702
759
  }
703
- return ForBodyEvaluation(node.test, node.update, node.body, []);
760
+ return yield* ForBodyEvaluation(node.test, node.update, node.body, []);
704
761
  }
705
762
 
706
763
  // https://tc39.es/ecma262/#sec-forbodyevaluation
707
- function ForBodyEvaluation(test, increment, stmt, perIterationBindings) {
764
+ function* ForBodyEvaluation(test, increment, stmt, perIterationBindings) {
708
765
  CreatePerIterationEnvironment(perIterationBindings);
709
766
  let V;
710
767
  // eslint-disable-next-line no-constant-condition
711
768
  while (true) {
712
769
  if (test) {
713
- const testRef = Evaluate(test);
770
+ const testRef = yield* Evaluate(test, undefined, true);
714
771
  const testValue = GetValue(testRef);
715
772
  if (!testValue) {
716
773
  return NormalCompletion(V);
717
774
  }
718
775
  }
719
- const result = Evaluate(stmt);
776
+ const result = yield* Evaluate(stmt);
720
777
  if (!LoopContinues(result)) {
721
778
  return UpdateEmpty(result, V);
722
779
  }
@@ -725,7 +782,7 @@ export function cook(rootAst, codeSource) {
725
782
  }
726
783
  CreatePerIterationEnvironment(perIterationBindings);
727
784
  if (increment) {
728
- const incRef = Evaluate(increment);
785
+ const incRef = yield* Evaluate(increment, undefined, true);
729
786
  GetValue(incRef);
730
787
  }
731
788
  }
@@ -749,77 +806,80 @@ export function cook(rootAst, codeSource) {
749
806
 
750
807
  // Destructuring assignments.
751
808
  // https://tc39.es/ecma262/#sec-runtime-semantics-destructuringassignmentevaluation
752
- function DestructuringAssignmentEvaluation(pattern, value) {
809
+ function* DestructuringAssignmentEvaluation(pattern, value) {
753
810
  if (pattern.type === "ObjectPattern") {
754
811
  RequireObjectCoercible(value);
755
812
  if (pattern.properties.length > 0) {
756
- PropertyDestructuringAssignmentEvaluation(pattern.properties, value);
813
+ yield* PropertyDestructuringAssignmentEvaluation(pattern.properties, value);
757
814
  }
758
815
  return NormalCompletion(Empty);
759
816
  }
760
817
  const iteratorRecord = CreateListIteratorRecord(value);
761
- return IteratorDestructuringAssignmentEvaluation(pattern.elements, iteratorRecord);
818
+ return yield* IteratorDestructuringAssignmentEvaluation(pattern.elements, iteratorRecord);
762
819
  }
763
820
 
764
821
  // https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation
765
- function PropertyDestructuringAssignmentEvaluation(properties, value) {
822
+ function* PropertyDestructuringAssignmentEvaluation(properties, value) {
766
823
  const excludedNames = new Set();
767
824
  for (const prop of properties) {
768
825
  if (prop.type === "Property") {
769
- const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : EvaluateComputedPropertyName(prop.key);
826
+ const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : yield* EvaluateComputedPropertyName(prop.key);
770
827
  const valueTarget = prop.value.type === "AssignmentPattern" ? prop.value.left : prop.value;
771
828
  if (valueTarget.type === "Identifier") {
772
829
  const lref = ResolveBinding(valueTarget.name);
773
830
  let v = GetV(value, propName);
774
831
  if (prop.value.type === "AssignmentPattern" && v === undefined) {
775
- // Todo(steve): check IsAnonymousFunctionDefinition(Initializer)
776
- const defaultValue = Evaluate(prop.value.right);
777
- v = GetValue(defaultValue);
832
+ if (IsAnonymousFunctionDefinition(prop.value.right)) {
833
+ v = NamedEvaluation(prop.value.right, valueTarget.name);
834
+ } else {
835
+ const defaultValue = yield* Evaluate(prop.value.right);
836
+ v = GetValue(defaultValue);
837
+ }
778
838
  }
779
839
  PutValue(lref, v);
780
840
  excludedNames.add(propName);
781
841
  } else {
782
- KeyedDestructuringAssignmentEvaluation(prop.value, value, propName);
842
+ yield* KeyedDestructuringAssignmentEvaluation(prop.value, value, propName);
783
843
  excludedNames.add(propName);
784
844
  }
785
845
  } else {
786
- RestDestructuringAssignmentEvaluation(prop, value, excludedNames);
846
+ yield* RestDestructuringAssignmentEvaluation(prop, value, excludedNames);
787
847
  }
788
848
  }
789
849
  }
790
850
 
791
851
  // https://tc39.es/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
792
- function KeyedDestructuringAssignmentEvaluation(node, value, propertyName) {
852
+ function* KeyedDestructuringAssignmentEvaluation(node, value, propertyName) {
793
853
  const assignmentTarget = node.type === "AssignmentPattern" ? node.left : node;
794
854
  const isObjectOrArray = assignmentTarget.type === "ArrayPattern" || assignmentTarget.type === "ObjectPattern";
795
855
  let lref;
796
856
  if (!isObjectOrArray) {
797
- lref = Evaluate(assignmentTarget).Value;
857
+ lref = (yield* Evaluate(assignmentTarget)).Value;
798
858
  }
799
859
  const v = GetV(value, propertyName);
800
860
  let rhsValue;
801
861
  if (node.type === "AssignmentPattern" && v === undefined) {
802
- // Todo(steve): check IsAnonymousFunctionDefinition(Initializer)
803
- const defaultValue = Evaluate(node.right);
862
+ // `assignmentTarget.type` is never "Identifier" here.
863
+ const defaultValue = yield* Evaluate(node.right);
804
864
  rhsValue = GetValue(defaultValue);
805
865
  } else {
806
866
  rhsValue = v;
807
867
  }
808
868
  if (isObjectOrArray) {
809
- return DestructuringAssignmentEvaluation(assignmentTarget, rhsValue);
869
+ return yield* DestructuringAssignmentEvaluation(assignmentTarget, rhsValue);
810
870
  }
811
871
  return PutValue(lref, rhsValue);
812
872
  }
813
873
 
814
874
  // https://tc39.es/ecma262/#sec-runtime-semantics-restdestructuringassignmentevaluation
815
- function RestDestructuringAssignmentEvaluation(restProperty, value, excludedNames) {
816
- const lref = Evaluate(restProperty.argument).Value;
875
+ function* RestDestructuringAssignmentEvaluation(restProperty, value, excludedNames) {
876
+ const lref = (yield* Evaluate(restProperty.argument)).Value;
817
877
  const restObj = CopyDataProperties({}, value, excludedNames);
818
878
  return PutValue(lref, restObj);
819
879
  }
820
880
 
821
881
  // https://tc39.es/ecma262/#sec-runtime-semantics-iteratordestructuringassignmentevaluation
822
- function IteratorDestructuringAssignmentEvaluation(elements, iteratorRecord) {
882
+ function* IteratorDestructuringAssignmentEvaluation(elements, iteratorRecord) {
823
883
  let status = NormalCompletion(Empty);
824
884
  for (const element of elements) {
825
885
  if (!element) {
@@ -831,7 +891,7 @@ export function cook(rootAst, codeSource) {
831
891
  const isObjectOrArray = assignmentTarget.type === "ArrayPattern" || assignmentTarget.type === "ObjectPattern";
832
892
  let lref;
833
893
  if (!isObjectOrArray) {
834
- lref = Evaluate(assignmentTarget).Value;
894
+ lref = (yield* Evaluate(assignmentTarget)).Value;
835
895
  }
836
896
  let v;
837
897
  if (element.type !== "RestElement") {
@@ -841,15 +901,18 @@ export function cook(rootAst, codeSource) {
841
901
  } = iteratorRecord.next();
842
902
  const value = done ? undefined : nextValue;
843
903
  if (element.type === "AssignmentPattern" && value === undefined) {
844
- // Todo(steve): check IsAnonymousFunctionDefinition(Initializer)
845
- const defaultValue = Evaluate(element.right);
846
- v = GetValue(defaultValue);
904
+ if (IsAnonymousFunctionDefinition(element.right) && assignmentTarget.type === "Identifier") {
905
+ v = NamedEvaluation(element.right, assignmentTarget.name);
906
+ } else {
907
+ const defaultValue = yield* Evaluate(element.right);
908
+ v = GetValue(defaultValue);
909
+ }
847
910
  } else {
848
911
  v = value;
849
912
  }
850
913
  } else {
851
914
  // RestElement
852
- v = [];
915
+ v = new ArrayConstructor();
853
916
  let n = 0;
854
917
  // eslint-disable-next-line no-constant-condition
855
918
  while (true) {
@@ -865,7 +928,7 @@ export function cook(rootAst, codeSource) {
865
928
  }
866
929
  }
867
930
  if (isObjectOrArray) {
868
- status = DestructuringAssignmentEvaluation(assignmentTarget, v);
931
+ status = yield* DestructuringAssignmentEvaluation(assignmentTarget, v);
869
932
  } else {
870
933
  status = PutValue(lref, v);
871
934
  }
@@ -875,8 +938,8 @@ export function cook(rootAst, codeSource) {
875
938
 
876
939
  // Object expressions.
877
940
  // https://tc39.es/ecma262/#sec-evaluate-property-access-with-expression-key
878
- function EvaluatePropertyAccessWithExpressionKey(baseValue, expression, strict) {
879
- const propertyNameReference = Evaluate(expression);
941
+ function* EvaluatePropertyAccessWithExpressionKey(baseValue, expression, strict) {
942
+ const propertyNameReference = yield* Evaluate(expression);
880
943
  const propertyNameValue = GetValue(propertyNameReference);
881
944
  const propertyKey = ToPropertyKey(propertyNameValue);
882
945
  return new ReferenceRecord(baseValue, propertyKey, strict);
@@ -914,33 +977,41 @@ export function cook(rootAst, codeSource) {
914
977
 
915
978
  // Function declarations and expressions.
916
979
  // https://tc39.es/ecma262/#sec-evaluatecall
917
- function EvaluateCall(func, ref, args, callee) {
980
+ function* EvaluateCall(func, ref, args, callee) {
918
981
  let thisValue;
919
982
  if (ref instanceof ReferenceRecord) {
920
983
  if (IsPropertyReference(ref)) {
921
984
  thisValue = ref.Base;
922
985
  }
923
986
  }
924
- const argList = ArgumentListEvaluation(args);
987
+ const argList = yield* ArgumentListEvaluation(args);
925
988
  if (typeof func !== "function") {
926
989
  const funcName = codeSource.substring(callee.start, callee.end);
927
990
  throw new TypeError(`${funcName} is not a function`);
928
991
  }
992
+ if (debug || externalSourceForDebug) {
993
+ const debuggerCall = func[DebuggerCall];
994
+ if (debuggerCall) {
995
+ const result = yield* debuggerCall.apply(thisValue, argList);
996
+ doSanitize(result);
997
+ return NormalCompletion(result);
998
+ }
999
+ }
929
1000
  const result = func.apply(thisValue, argList);
930
- sanitize(result);
1001
+ doSanitize(result);
931
1002
  return NormalCompletion(result);
932
1003
  }
933
1004
 
934
1005
  // https://tc39.es/ecma262/#sec-evaluatenew
935
- function EvaluateNew(constructExpr, args) {
936
- const ref = Evaluate(constructExpr);
1006
+ function* EvaluateNew(constructExpr, args) {
1007
+ const ref = yield* Evaluate(constructExpr);
937
1008
  const constructor = GetValue(ref);
938
- const argList = ArgumentListEvaluation(args);
1009
+ const argList = yield* ArgumentListEvaluation(args);
939
1010
  if (typeof constructor !== "function" || constructor[IsConstructor] === false) {
940
1011
  const constructorName = codeSource.substring(constructExpr.start, constructExpr.end);
941
1012
  throw new TypeError(`${constructorName} is not a constructor`);
942
1013
  }
943
- if (!isAllowedConstructor(constructor)) {
1014
+ if (!externalSourceForDebug && !isAllowedConstructor(constructor) && constructor !== ArrayConstructor) {
944
1015
  const constructorName = codeSource.substring(constructExpr.start, constructExpr.end);
945
1016
  throw new TypeError(`${constructorName} is not an allowed constructor`);
946
1017
  }
@@ -948,32 +1019,43 @@ export function cook(rootAst, codeSource) {
948
1019
  }
949
1020
 
950
1021
  // https://tc39.es/ecma262/#sec-runtime-semantics-argumentlistevaluation
951
- function ArgumentListEvaluation(args) {
1022
+ function* ArgumentListEvaluation(args) {
952
1023
  const array = [];
953
1024
  if (Array.isArray(args)) {
954
1025
  for (const arg of args) {
955
1026
  if (arg.type === "SpreadElement") {
956
- const spreadValues = GetValue(Evaluate(arg.argument));
1027
+ const spreadValues = GetValue(yield* Evaluate(arg.argument));
957
1028
  array.push(...spreadValues);
958
1029
  } else {
959
- array.push(GetValue(Evaluate(arg)));
1030
+ array.push(GetValue(yield* Evaluate(arg)));
960
1031
  }
961
1032
  }
962
1033
  } else {
963
1034
  array.push(GetTemplateObject(args));
964
1035
  for (const expr of args.expressions) {
965
- array.push(GetValue(Evaluate(expr)));
1036
+ array.push(GetValue(yield* Evaluate(expr)));
966
1037
  }
967
1038
  }
968
1039
  return array;
969
1040
  }
970
1041
 
971
1042
  // https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist
972
- function CallFunction(closure, args) {
1043
+ function* CallFunction(closure, thisArgument, args) {
973
1044
  var _hooks$beforeCall;
974
1045
  (_hooks$beforeCall = hooks.beforeCall) === null || _hooks$beforeCall === void 0 || _hooks$beforeCall.call(hooks, closure[SourceNode]);
975
- PrepareForOrdinaryCall(closure);
976
- const result = OrdinaryCallEvaluateBody(closure, args);
1046
+ const calleeContext = PrepareForOrdinaryCall(closure);
1047
+ OrdinaryCallBindThis(closure, calleeContext, thisArgument);
1048
+ const result = yield* OrdinaryCallEvaluateBody(closure, args);
1049
+ if (debug) {
1050
+ currentNode = {
1051
+ ...closure[SourceNode],
1052
+ [DebuggerReturn]: true
1053
+ };
1054
+ yield {
1055
+ type: "return",
1056
+ value: result.Type === "return" ? result.Value : undefined
1057
+ };
1058
+ }
977
1059
  executionContextStack.pop();
978
1060
  if (result.Type === "return") {
979
1061
  return result.Value;
@@ -985,32 +1067,39 @@ export function cook(rootAst, codeSource) {
985
1067
  function PrepareForOrdinaryCall(F) {
986
1068
  const calleeContext = new ExecutionContext();
987
1069
  calleeContext.Function = F;
988
- const localEnv = new FunctionEnvironment(F[Environment]);
1070
+ const localEnv = new FunctionEnvironment(F);
989
1071
  calleeContext.VariableEnvironment = localEnv;
990
1072
  calleeContext.LexicalEnvironment = localEnv;
991
1073
  executionContextStack.push(calleeContext);
992
1074
  return calleeContext;
993
1075
  }
1076
+ function OrdinaryCallBindThis(F, calleeContext, thisArgument) {
1077
+ if (F[ThisMode] === Mode.LEXICAL) {
1078
+ return;
1079
+ }
1080
+ const localEnv = calleeContext.LexicalEnvironment;
1081
+ localEnv === null || localEnv === void 0 || localEnv.BindThisValue(thisArgument);
1082
+ }
994
1083
 
995
1084
  // https://tc39.es/ecma262/#sec-ordinarycallevaluatebody
996
- function OrdinaryCallEvaluateBody(F, args) {
997
- return EvaluateFunctionBody(F[ECMAScriptCode], F, args);
1085
+ function* OrdinaryCallEvaluateBody(F, args) {
1086
+ return yield* EvaluateFunctionBody(F[ECMAScriptCode], F, args);
998
1087
  }
999
1088
 
1000
1089
  // https://tc39.es/ecma262/#sec-runtime-semantics-evaluatefunctionbody
1001
- function EvaluateFunctionBody(body, F, args) {
1002
- FunctionDeclarationInstantiation(F, args);
1090
+ function* EvaluateFunctionBody(body, F, args) {
1091
+ yield* FunctionDeclarationInstantiation(F, args);
1003
1092
  if (Array.isArray(body)) {
1004
- return EvaluateStatementList(body);
1093
+ return yield* EvaluateStatementList(body);
1005
1094
  }
1006
- return new CompletionRecord("return", GetValue(Evaluate(body)));
1095
+ return new CompletionRecord("return", GetValue(yield* Evaluate(body)));
1007
1096
  }
1008
1097
 
1009
1098
  // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation
1010
- function EvaluateStatementList(statements) {
1099
+ function* EvaluateStatementList(statements) {
1011
1100
  let result = NormalCompletion(Empty);
1012
1101
  for (const stmt of statements) {
1013
- const s = Evaluate(stmt);
1102
+ const s = yield* Evaluate(stmt);
1014
1103
  if (s.Type !== "normal") {
1015
1104
  return s;
1016
1105
  }
@@ -1018,9 +1107,39 @@ export function cook(rootAst, codeSource) {
1018
1107
  }
1019
1108
  return result;
1020
1109
  }
1110
+ function GetThisEnvironment() {
1111
+ let env = getRunningContext().LexicalEnvironment;
1112
+ while (env) {
1113
+ if (env.HasThisBinding()) {
1114
+ return env;
1115
+ }
1116
+ env = env.OuterEnv;
1117
+ }
1118
+ throw new Error("Accessing global this is forbidden");
1119
+ }
1120
+
1121
+ // https://tc39.es/ecma262/#sec-isanonymousfunctiondefinition
1122
+ function IsAnonymousFunctionDefinition(node) {
1123
+ // No ParenthesizedExpression in ESTree.
1124
+ return node.type === "FunctionExpression" && !node.id || node.type === "ArrowFunctionExpression";
1125
+ }
1126
+
1127
+ // https://tc39.es/ecma262/#sec-runtime-semantics-namedevaluation
1128
+ function NamedEvaluation(node, name) {
1129
+ // No ParenthesizedExpression in ESTree.
1130
+ switch (node.type) {
1131
+ case "FunctionExpression":
1132
+ return InstantiateOrdinaryFunctionExpression(node, name);
1133
+ case "ArrowFunctionExpression":
1134
+ return InstantiateArrowFunctionExpression(node, name);
1135
+ // istanbul ignore next: should never happen
1136
+ default:
1137
+ throw new Error(`Unexpected node type for NamedEvaluation: ${node.type}`);
1138
+ }
1139
+ }
1021
1140
 
1022
1141
  // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1023
- function FunctionDeclarationInstantiation(func, args) {
1142
+ function* FunctionDeclarationInstantiation(func, args) {
1024
1143
  const calleeContext = getRunningContext();
1025
1144
  const code = func[ECMAScriptCode];
1026
1145
  const formals = func[FormalParameters];
@@ -1049,20 +1168,44 @@ export function cook(rootAst, codeSource) {
1049
1168
  throw new SyntaxError("Var declaration is not recommended, use `let` or `const` instead");
1050
1169
  }
1051
1170
  }
1171
+
1172
+ // let argumentsObjectNeeded = true;
1173
+ // if (func[ThisMode] === Mode.LEXICAL) {
1174
+ // // NOTE: Arrow functions never have an arguments object.
1175
+ // argumentsObjectNeeded = false;
1176
+ // } else if (parameterNames.includes("arguments")) {
1177
+ // argumentsObjectNeeded = false;
1178
+ // } else if (!hasParameterExpressions && (
1179
+ // varNames.includes("arguments") ||
1180
+ // collectBoundNames(collectScopedDeclarations(code, { var: false })).includes("arguments")
1181
+ // )) {
1182
+ // argumentsObjectNeeded = false;
1183
+ // }
1184
+ // NOTE: In strict mode, no parameter/function/var/lexical names can be "arguments".
1185
+ const argumentsObjectNeeded = !!externalSourceForDebug && func[ThisMode] !== Mode.LEXICAL;
1052
1186
  const env = calleeContext.LexicalEnvironment;
1053
1187
  for (const paramName of parameterNames) {
1054
1188
  // In strict mode, it's guaranteed no duplicate params exist.
1055
1189
  env.CreateMutableBinding(paramName, false);
1056
1190
  }
1191
+ let parameterBindings = parameterNames;
1192
+ if (argumentsObjectNeeded) {
1193
+ const ao = CreateUnmappedArgumentsObject(args);
1194
+ env.CreateImmutableBinding("arguments", false);
1195
+ env.InitializeBinding("arguments", ao);
1196
+ parameterBindings = parameterNames.concat("arguments");
1197
+ }
1057
1198
  const iteratorRecord = CreateListIteratorRecord(args);
1058
- IteratorBindingInitialization(formals, iteratorRecord, env);
1199
+ yield* IteratorBindingInitialization(formals, iteratorRecord, env);
1059
1200
  let varEnv;
1060
1201
  if (!hasParameterExpressions) {
1061
1202
  // NOTE: Only a single Environment Record is needed for the parameters
1062
1203
  // and top-level vars.
1063
1204
  // `varNames` are unique.
1205
+ const instantiatedVarNames = [...parameterBindings];
1064
1206
  for (const n of varNames) {
1065
- if (!parameterNames.includes(n)) {
1207
+ if (!instantiatedVarNames.includes(n)) {
1208
+ instantiatedVarNames.push(n);
1066
1209
  env.CreateMutableBinding(n, false);
1067
1210
  env.InitializeBinding(n, undefined);
1068
1211
  }
@@ -1075,15 +1218,19 @@ export function cook(rootAst, codeSource) {
1075
1218
  varEnv = new DeclarativeEnvironment(env);
1076
1219
  calleeContext.VariableEnvironment = varEnv;
1077
1220
  // `varNames` are unique.
1221
+ const instantiatedVarNames = [];
1078
1222
  for (const n of varNames) {
1079
- varEnv.CreateMutableBinding(n, false);
1080
- let initialValue;
1081
- if (parameterNames.includes(n) && !functionNames.includes(n)) {
1082
- initialValue = env.GetBindingValue(n, false);
1223
+ if (!instantiatedVarNames.includes(n)) {
1224
+ instantiatedVarNames.push(n);
1225
+ varEnv.CreateMutableBinding(n, false);
1226
+ let initialValue;
1227
+ if (parameterBindings.includes(n) && !functionNames.includes(n)) {
1228
+ initialValue = env.GetBindingValue(n, false);
1229
+ }
1230
+ varEnv.InitializeBinding(n, initialValue);
1231
+ // NOTE: A var with the same name as a formal parameter initially has
1232
+ // the same value as the corresponding initialized parameter.
1083
1233
  }
1084
- varEnv.InitializeBinding(n, initialValue);
1085
- // NOTE: A var with the same name as a formal parameter initially has
1086
- // the same value as the corresponding initialized parameter.
1087
1234
  }
1088
1235
  }
1089
1236
  const lexEnv = varEnv;
@@ -1108,40 +1255,78 @@ export function cook(rootAst, codeSource) {
1108
1255
  varEnv.SetMutableBinding(fn, fo, false);
1109
1256
  }
1110
1257
  }
1258
+ function CreateUnmappedArgumentsObject(args) {
1259
+ const argList = [...args];
1260
+ const argumentObject = {};
1261
+ Object.defineProperty(argumentObject, "length", {
1262
+ value: argList.length,
1263
+ writable: true,
1264
+ configurable: true
1265
+ });
1266
+ for (let index = 0; index < argList.length; index++) {
1267
+ argumentObject[String(index)] = argList[index];
1268
+ }
1269
+ Object.defineProperty(argumentObject, Symbol.iterator, {
1270
+ value: Array.prototype.values,
1271
+ writable: true,
1272
+ configurable: true
1273
+ });
1274
+ const ThrowTypeError = () => {
1275
+ throw new TypeError("'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them");
1276
+ };
1277
+ Object.defineProperty(argumentObject, "callee", {
1278
+ get: ThrowTypeError,
1279
+ set: ThrowTypeError
1280
+ });
1281
+ return argumentObject;
1282
+ }
1111
1283
 
1112
1284
  // https://tc39.es/ecma262/#sec-runtime-semantics-instantiatefunctionobject
1113
1285
  function InstantiateFunctionObject(func, scope) {
1114
- return OrdinaryFunctionCreate(func, scope, true);
1286
+ const F = OrdinaryFunctionCreate(func, scope, true, false);
1287
+ if (func.id) {
1288
+ SetFunctionName(F, func.id.name);
1289
+ }
1290
+ return F;
1115
1291
  }
1116
1292
 
1117
1293
  // https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
1118
- function InstantiateOrdinaryFunctionExpression(functionExpression) {
1294
+ function InstantiateOrdinaryFunctionExpression(functionExpression, name) {
1119
1295
  const scope = getRunningContext().LexicalEnvironment;
1120
1296
  if (functionExpression.id) {
1121
1297
  const name = functionExpression.id.name;
1122
1298
  const funcEnv = new DeclarativeEnvironment(scope);
1123
1299
  funcEnv.CreateImmutableBinding(name, false);
1124
- const closure = OrdinaryFunctionCreate(functionExpression, funcEnv, true);
1300
+ const closure = OrdinaryFunctionCreate(functionExpression, funcEnv, true, false);
1301
+ SetFunctionName(closure, name);
1125
1302
  funcEnv.InitializeBinding(name, closure);
1126
1303
  return closure;
1127
1304
  } else {
1128
- const closure = OrdinaryFunctionCreate(functionExpression, scope, true);
1305
+ const closure = OrdinaryFunctionCreate(functionExpression, scope, true, false);
1306
+ SetFunctionName(closure, name ?? "");
1129
1307
  return closure;
1130
1308
  }
1131
1309
  }
1132
1310
 
1133
1311
  // https://tc39.es/ecma262/#sec-runtime-semantics-instantiatearrowfunctionexpression
1134
- function InstantiateArrowFunctionExpression(arrowFunction) {
1312
+ function InstantiateArrowFunctionExpression(arrowFunction, name) {
1135
1313
  const scope = getRunningContext().LexicalEnvironment;
1136
- const closure = OrdinaryFunctionCreate(arrowFunction, scope, false);
1314
+ const closure = OrdinaryFunctionCreate(arrowFunction, scope, false, true);
1315
+ SetFunctionName(closure, name ?? "");
1137
1316
  return closure;
1138
1317
  }
1318
+ function SetFunctionName(F, name) {
1319
+ Object.defineProperty(F, "name", {
1320
+ value: name,
1321
+ configurable: true
1322
+ });
1323
+ }
1139
1324
 
1140
1325
  // https://tc39.es/ecma262/#sec-ordinaryfunctioncreate
1141
- function OrdinaryFunctionCreate(sourceNode, scope, isConstructor) {
1326
+ function OrdinaryFunctionCreate(sourceNode, scope, isConstructor, lexicalThis) {
1142
1327
  const F = function () {
1143
1328
  // eslint-disable-next-line prefer-rest-params
1144
- return CallFunction(F, arguments);
1329
+ return unwind(CallFunction(F, this, arguments));
1145
1330
  };
1146
1331
  Object.defineProperties(F, {
1147
1332
  [SourceNode]: {
@@ -1158,41 +1343,52 @@ export function cook(rootAst, codeSource) {
1158
1343
  },
1159
1344
  [IsConstructor]: {
1160
1345
  value: isConstructor
1346
+ },
1347
+ [ThisMode]: {
1348
+ value: lexicalThis ? Mode.LEXICAL : Mode.STRICT
1161
1349
  }
1162
1350
  });
1351
+ if (debug || externalSourceForDebug) {
1352
+ Object.defineProperty(F, DebuggerCall, {
1353
+ value: function () {
1354
+ // eslint-disable-next-line prefer-rest-params
1355
+ return CallFunction(F, this, arguments);
1356
+ }
1357
+ });
1358
+ }
1163
1359
  return F;
1164
1360
  }
1165
1361
 
1166
1362
  // Patterns initialization.
1167
1363
  // https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
1168
- function BindingInitialization(node, value, environment) {
1364
+ function* BindingInitialization(node, value, environment) {
1169
1365
  switch (node.type) {
1170
1366
  case "Identifier":
1171
1367
  return InitializeBoundName(node.name, value, environment);
1172
1368
  case "ObjectPattern":
1173
1369
  RequireObjectCoercible(value);
1174
- return PropertyBindingInitialization(node.properties, value, environment);
1370
+ return yield* PropertyBindingInitialization(node.properties, value, environment);
1175
1371
  case "ArrayPattern":
1176
1372
  {
1177
1373
  const iteratorRecord = CreateListIteratorRecord(value);
1178
- return IteratorBindingInitialization(node.elements, iteratorRecord, environment);
1374
+ return yield* IteratorBindingInitialization(node.elements, iteratorRecord, environment);
1179
1375
  }
1180
1376
  }
1181
1377
  }
1182
1378
 
1183
1379
  // https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
1184
- function PropertyBindingInitialization(properties, value, environment) {
1380
+ function* PropertyBindingInitialization(properties, value, environment) {
1185
1381
  const excludedNames = new Set();
1186
1382
  for (const prop of properties) {
1187
1383
  if (prop.type === "RestElement") {
1188
1384
  return RestBindingInitialization(prop, value, environment, excludedNames);
1189
1385
  }
1190
1386
  if (!prop.computed && prop.key.type === "Identifier") {
1191
- KeyedBindingInitialization(prop.value, value, environment, prop.key.name);
1387
+ yield* KeyedBindingInitialization(prop.value, value, environment, prop.key.name);
1192
1388
  excludedNames.add(prop.key.name);
1193
1389
  } else {
1194
- const P = EvaluateComputedPropertyName(prop.key);
1195
- KeyedBindingInitialization(prop.value, value, environment, P);
1390
+ const P = yield* EvaluateComputedPropertyName(prop.key);
1391
+ yield* KeyedBindingInitialization(prop.value, value, environment, P);
1196
1392
  excludedNames.add(P);
1197
1393
  }
1198
1394
  }
@@ -1200,8 +1396,8 @@ export function cook(rootAst, codeSource) {
1200
1396
  }
1201
1397
 
1202
1398
  // https://tc39.es/ecma262/#prod-ComputedPropertyName
1203
- function EvaluateComputedPropertyName(node) {
1204
- const propName = GetValue(Evaluate(node));
1399
+ function* EvaluateComputedPropertyName(node) {
1400
+ const propName = GetValue(yield* Evaluate(node));
1205
1401
  return ToPropertyKey(propName);
1206
1402
  }
1207
1403
 
@@ -1216,7 +1412,7 @@ export function cook(rootAst, codeSource) {
1216
1412
  }
1217
1413
 
1218
1414
  // https://tc39.es/ecma262/#sec-runtime-semantics-iteratorbindinginitialization
1219
- function IteratorBindingInitialization(elements, iteratorRecord, environment) {
1415
+ function* IteratorBindingInitialization(elements, iteratorRecord, environment) {
1220
1416
  if (elements.length === 0) {
1221
1417
  return NormalCompletion(Empty);
1222
1418
  }
@@ -1230,7 +1426,7 @@ export function cook(rootAst, codeSource) {
1230
1426
  // Rest element.
1231
1427
  if (node.argument.type === "Identifier") {
1232
1428
  const lhs = ResolveBinding(node.argument.name, environment);
1233
- const A = [];
1429
+ const A = new ArrayConstructor();
1234
1430
  let n = 0;
1235
1431
  // eslint-disable-next-line no-constant-condition
1236
1432
  while (true) {
@@ -1246,7 +1442,7 @@ export function cook(rootAst, codeSource) {
1246
1442
  n++;
1247
1443
  }
1248
1444
  } else {
1249
- const A = [];
1445
+ const A = new ArrayConstructor();
1250
1446
  let n = 0;
1251
1447
  // eslint-disable-next-line no-constant-condition
1252
1448
  while (true) {
@@ -1255,7 +1451,7 @@ export function cook(rootAst, codeSource) {
1255
1451
  value
1256
1452
  } = iteratorRecord.next();
1257
1453
  if (done) {
1258
- result = BindingInitialization(node.argument, A, environment);
1454
+ result = yield* BindingInitialization(node.argument, A, environment);
1259
1455
  break;
1260
1456
  }
1261
1457
  A[n] = value;
@@ -1278,10 +1474,10 @@ export function cook(rootAst, codeSource) {
1278
1474
  v = value;
1279
1475
  }
1280
1476
  if (node.type === "AssignmentPattern" && v === undefined) {
1281
- const defaultValue = Evaluate(node.right);
1477
+ const defaultValue = yield* Evaluate(node.right);
1282
1478
  v = GetValue(defaultValue);
1283
1479
  }
1284
- result = BindingInitialization(bindingElement, v, environment);
1480
+ result = yield* BindingInitialization(bindingElement, v, environment);
1285
1481
  break;
1286
1482
  }
1287
1483
  case "Identifier":
@@ -1297,9 +1493,12 @@ export function cook(rootAst, codeSource) {
1297
1493
  v = value;
1298
1494
  }
1299
1495
  if (node.type === "AssignmentPattern" && v === undefined) {
1300
- // IsAnonymousFunctionDefinition(Initializer)
1301
- const defaultValue = Evaluate(node.right);
1302
- v = GetValue(defaultValue);
1496
+ if (IsAnonymousFunctionDefinition(node.right)) {
1497
+ v = NamedEvaluation(node.right, bindingId);
1498
+ } else {
1499
+ const defaultValue = yield* Evaluate(node.right);
1500
+ v = GetValue(defaultValue);
1501
+ }
1303
1502
  }
1304
1503
  result = environment ? InitializeReferencedBinding(lhs, v) : PutValue(lhs, v);
1305
1504
  break;
@@ -1311,16 +1510,19 @@ export function cook(rootAst, codeSource) {
1311
1510
  }
1312
1511
 
1313
1512
  // https://tc39.es/ecma262/#sec-runtime-semantics-keyedbindinginitialization
1314
- function KeyedBindingInitialization(node, value, environment, propertyName) {
1513
+ function* KeyedBindingInitialization(node, value, environment, propertyName) {
1315
1514
  const isIdentifier = node.type === "Identifier" || node.type === "AssignmentPattern" && node.left.type === "Identifier";
1316
1515
  if (isIdentifier) {
1317
1516
  const bindingId = node.type === "Identifier" ? node.name : node.left.name;
1318
1517
  const lhs = ResolveBinding(bindingId, environment);
1319
1518
  let v = GetV(value, propertyName);
1320
1519
  if (node.type === "AssignmentPattern" && v === undefined) {
1321
- // If IsAnonymousFunctionDefinition(Initializer)
1322
- const defaultValue = Evaluate(node.right);
1323
- v = GetValue(defaultValue);
1520
+ if (IsAnonymousFunctionDefinition(node.right)) {
1521
+ v = NamedEvaluation(node.right, bindingId);
1522
+ } else {
1523
+ const defaultValue = yield* Evaluate(node.right);
1524
+ v = GetValue(defaultValue);
1525
+ }
1324
1526
  }
1325
1527
  if (!environment) {
1326
1528
  return PutValue(lhs, v);
@@ -1329,10 +1531,10 @@ export function cook(rootAst, codeSource) {
1329
1531
  }
1330
1532
  let v = GetV(value, propertyName);
1331
1533
  if (node.type === "AssignmentPattern" && v === undefined) {
1332
- const defaultValue = Evaluate(node.right);
1534
+ const defaultValue = yield* Evaluate(node.right);
1333
1535
  v = GetValue(defaultValue);
1334
1536
  }
1335
- return BindingInitialization(node.type === "AssignmentPattern" ? node.left : node, v, environment);
1537
+ return yield* BindingInitialization(node.type === "AssignmentPattern" ? node.left : node, v, environment);
1336
1538
  }
1337
1539
 
1338
1540
  // https://tc39.es/ecma262/#sec-initializeboundname
@@ -1350,7 +1552,7 @@ export function cook(rootAst, codeSource) {
1350
1552
  }
1351
1553
  }
1352
1554
  if (expressionOnly) {
1353
- return GetValue(Evaluate(rootAst));
1555
+ return GetValue(unwind(Evaluate(rootAst)));
1354
1556
  }
1355
1557
  (_hooks$beforeEvaluate3 = hooks.beforeEvaluate) === null || _hooks$beforeEvaluate3 === void 0 || _hooks$beforeEvaluate3.call(hooks, rootAst);
1356
1558
  ThrowIfFunctionIsInvalid(rootAst);
@@ -1359,6 +1561,32 @@ export function cook(rootAst, codeSource) {
1359
1561
  rootEnv.CreateImmutableBinding(fn, true);
1360
1562
  const fo = InstantiateFunctionObject(rootAst, rootEnv);
1361
1563
  rootEnv.InitializeBinding(fn, fo);
1564
+ if (debug) {
1565
+ Object.defineProperties(fo, {
1566
+ [DebuggerScope]: {
1567
+ value: function () {
1568
+ return getRunningContext().LexicalEnvironment;
1569
+ }
1570
+ },
1571
+ [DebuggerNode]: {
1572
+ value: function () {
1573
+ return currentNode;
1574
+ }
1575
+ }
1576
+ });
1577
+ }
1362
1578
  return fo;
1363
1579
  }
1580
+ function unwind(iterator) {
1581
+ // eslint-disable-next-line no-constant-condition
1582
+ while (true) {
1583
+ const {
1584
+ done,
1585
+ value
1586
+ } = iterator.next();
1587
+ if (done) {
1588
+ return value;
1589
+ }
1590
+ }
1591
+ }
1364
1592
  //# sourceMappingURL=cook.js.map