@next-core/cook 2.2.18 → 2.3.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, DebuggerScope, DeclarativeEnvironment, ECMAScriptCode, Empty, Environment, ExecutionContext, FormalParameters, FunctionEnvironment, IsConstructor, NormalCompletion, ReferenceRecord, SourceNode } 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,6 +7,7 @@ export function cook(rootAst, codeSource) {
7
7
  var _hooks$beforeEvaluate3;
8
8
  let {
9
9
  rules,
10
+ debug,
10
11
  globalVariables = {},
11
12
  hooks = {}
12
13
  } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
@@ -41,9 +42,14 @@ export function cook(rootAst, codeSource) {
41
42
  TemplateMap.set(templateLiteral, template);
42
43
  return template;
43
44
  }
44
- function Evaluate(node, optionalChainRef) {
45
- var _hooks$beforeEvaluate, _hooks$beforeBranch, _hooks$beforeBranch2;
45
+ let currentNode;
46
+ function* Evaluate(node, optionalChainRef, forceYield) {
47
+ var _hooks$beforeEvaluate, _hooks$beforeBranch2;
46
48
  (_hooks$beforeEvaluate = hooks.beforeEvaluate) === null || _hooks$beforeEvaluate === void 0 || _hooks$beforeEvaluate.call(hooks, node);
49
+ currentNode = node;
50
+ if (debug && (forceYield || node.type.endsWith("Statement") && node.type !== "TryStatement" && node.type !== "BlockStatement" && node.type !== "ForStatement" && node.type !== "ForInStatement" && node.type !== "ForOfStatement")) {
51
+ yield;
52
+ }
47
53
  // Expressions:
48
54
  switch (node.type) {
49
55
  case "ArrayExpression":
@@ -54,10 +60,10 @@ export function cook(rootAst, codeSource) {
54
60
  if (!element) {
55
61
  array.length += 1;
56
62
  } else if (element.type === "SpreadElement") {
57
- const spreadValues = GetValue(Evaluate(element.argument));
63
+ const spreadValues = GetValue(yield* Evaluate(element.argument));
58
64
  array.push(...spreadValues);
59
65
  } else {
60
- array.push(GetValue(Evaluate(element)));
66
+ array.push(GetValue(yield* Evaluate(element)));
61
67
  }
62
68
  }
63
69
  return NormalCompletion(array);
@@ -71,9 +77,9 @@ export function cook(rootAst, codeSource) {
71
77
  }
72
78
  case "BinaryExpression":
73
79
  {
74
- const leftRef = Evaluate(node.left);
80
+ const leftRef = yield* Evaluate(node.left);
75
81
  const leftValue = GetValue(leftRef);
76
- const rightRef = Evaluate(node.right).Value;
82
+ const rightRef = (yield* Evaluate(node.right)).Value;
77
83
  const rightValue = GetValue(rightRef);
78
84
  if (expressionOnly && node.operator === "|>") {
79
85
  // Minimal pipeline operator is supported only in expression-only mode.
@@ -98,21 +104,22 @@ export function cook(rootAst, codeSource) {
98
104
  case "CallExpression":
99
105
  {
100
106
  // https://tc39.es/ecma262/#sec-function-calls
101
- const ref = Evaluate(node.callee, optionalChainRef).Value;
107
+ const ref = (yield* Evaluate(node.callee, optionalChainRef)).Value;
102
108
  const func = GetValue(ref);
103
109
  if ((func === undefined || func === null) && (node.optional || optionalChainRef !== null && optionalChainRef !== void 0 && optionalChainRef.skipped)) {
104
110
  optionalChainRef.skipped = true;
105
111
  return NormalCompletion(undefined);
106
112
  }
107
113
  sanitize(func);
108
- return EvaluateCall(func, ref, node.arguments, node.callee);
114
+ if (debug) yield;
115
+ return yield* EvaluateCall(func, ref, node.arguments, node.callee);
109
116
  }
110
117
  case "ChainExpression":
111
118
  // https://tc39.es/ecma262/#sec-optional-chains
112
- return Evaluate(node.expression, {});
119
+ return yield* Evaluate(node.expression, {});
113
120
  case "ConditionalExpression":
114
121
  // https://tc39.es/ecma262/#sec-conditional-operator
115
- return NormalCompletion(GetValue(Evaluate(GetValue(Evaluate(node.test)) ? node.consequent : node.alternate)));
122
+ return NormalCompletion(GetValue(yield* Evaluate(GetValue(yield* Evaluate(node.test)) ? node.consequent : node.alternate)));
116
123
  case "Identifier":
117
124
  // https://tc39.es/ecma262/#sec-identifiers
118
125
  return NormalCompletion(ResolveBinding(node.name));
@@ -134,14 +141,14 @@ export function cook(rootAst, codeSource) {
134
141
  case "LogicalExpression":
135
142
  {
136
143
  // https://tc39.es/ecma262/#sec-binary-logical-operators
137
- const leftValue = GetValue(Evaluate(node.left));
144
+ const leftValue = GetValue(yield* Evaluate(node.left));
138
145
  switch (node.operator) {
139
146
  case "&&":
140
- return NormalCompletion(leftValue && GetValue(Evaluate(node.right)));
147
+ return NormalCompletion(leftValue && GetValue(yield* Evaluate(node.right)));
141
148
  case "||":
142
- return NormalCompletion(leftValue || GetValue(Evaluate(node.right)));
149
+ return NormalCompletion(leftValue || GetValue(yield* Evaluate(node.right)));
143
150
  case "??":
144
- return NormalCompletion(leftValue ?? GetValue(Evaluate(node.right)));
151
+ return NormalCompletion(leftValue ?? GetValue(yield* Evaluate(node.right)));
145
152
  // istanbul ignore next
146
153
  default:
147
154
  throw new SyntaxError(
@@ -153,37 +160,41 @@ export function cook(rootAst, codeSource) {
153
160
  case "MemberExpression":
154
161
  {
155
162
  // https://tc39.es/ecma262/#sec-property-accessors
156
- const baseReference = Evaluate(node.object, optionalChainRef).Value;
163
+ const baseReference = (yield* Evaluate(node.object, optionalChainRef)).Value;
157
164
  const baseValue = GetValue(baseReference);
158
165
  if ((baseValue === undefined || baseValue === null) && (node.optional || optionalChainRef !== null && optionalChainRef !== void 0 && optionalChainRef.skipped)) {
159
166
  optionalChainRef.skipped = true;
160
167
  return NormalCompletion(undefined);
161
168
  }
162
169
  sanitize(baseValue);
163
- const result = node.computed ? EvaluatePropertyAccessWithExpressionKey(baseValue, node.property, true) : EvaluatePropertyAccessWithIdentifierKey(baseValue, node.property, true);
170
+ const result = node.computed ? yield* EvaluatePropertyAccessWithExpressionKey(baseValue, node.property, true) : EvaluatePropertyAccessWithIdentifierKey(baseValue, node.property, true);
164
171
  sanitize(result);
165
172
  return NormalCompletion(result);
166
173
  }
167
174
  case "NewExpression":
168
175
  // https://tc39.es/ecma262/#sec-new-operator
169
- return EvaluateNew(node.callee, node.arguments);
176
+ return yield* EvaluateNew(node.callee, node.arguments);
170
177
  case "ObjectExpression":
171
178
  {
172
179
  // https://tc39.es/ecma262/#sec-object-initializer
173
180
  const object = {};
174
181
  for (const prop of node.properties) {
175
182
  if (prop.type === "SpreadElement") {
176
- const fromValue = GetValue(Evaluate(prop.argument));
183
+ const fromValue = GetValue(yield* Evaluate(prop.argument));
177
184
  CopyDataProperties(object, fromValue, new Set());
178
185
  } else {
179
186
  if (prop.kind !== "init") {
180
187
  throw new SyntaxError("Unsupported object getter/setter");
181
188
  }
182
- const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : EvaluateComputedPropertyName(prop.key);
189
+ const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : yield* EvaluateComputedPropertyName(prop.key);
183
190
  if (propName === "__proto__") {
184
191
  throw new TypeError("Setting '__proto__' property is not allowed");
185
192
  }
186
- object[propName] = GetValue(Evaluate(prop.value));
193
+ const propValue = GetValue(yield* Evaluate(prop.value));
194
+ if (prop.method && typeof propValue === "function") {
195
+ SetFunctionName(propValue, propName);
196
+ }
197
+ object[propName] = propValue;
187
198
  }
188
199
  }
189
200
  return NormalCompletion(object);
@@ -193,7 +204,7 @@ export function cook(rootAst, codeSource) {
193
204
  // https://tc39.es/ecma262/#sec-comma-operator
194
205
  let result;
195
206
  for (const expr of node.expressions) {
196
- result = NormalCompletion(GetValue(Evaluate(expr)));
207
+ result = NormalCompletion(GetValue(yield* Evaluate(expr)));
197
208
  }
198
209
  return result;
199
210
  }
@@ -203,7 +214,7 @@ export function cook(rootAst, codeSource) {
203
214
  const chunks = [node.quasis[0].value.cooked];
204
215
  let index = 0;
205
216
  for (const expr of node.expressions) {
206
- const val = GetValue(Evaluate(expr));
217
+ const val = GetValue(yield* Evaluate(expr));
207
218
  chunks.push(String(val));
208
219
  chunks.push(node.quasis[index += 1].value.cooked);
209
220
  }
@@ -212,15 +223,16 @@ export function cook(rootAst, codeSource) {
212
223
  case "TaggedTemplateExpression":
213
224
  {
214
225
  // https://tc39.es/ecma262/#sec-tagged-templates
215
- const tagRef = Evaluate(node.tag).Value;
226
+ const tagRef = (yield* Evaluate(node.tag)).Value;
216
227
  const tagFunc = GetValue(tagRef);
217
228
  sanitize(tagFunc);
218
- return EvaluateCall(tagFunc, tagRef, node.quasi, node.tag);
229
+ if (debug) yield;
230
+ return yield* EvaluateCall(tagFunc, tagRef, node.quasi, node.tag);
219
231
  }
220
232
  case "UnaryExpression":
221
233
  {
222
234
  // https://tc39.es/ecma262/#sec-unary-operators
223
- const ref = Evaluate(node.argument).Value;
235
+ const ref = (yield* Evaluate(node.argument)).Value;
224
236
  if (!expressionOnly && node.operator === "delete") {
225
237
  // Delete operator is supported only in function mode.
226
238
  if (!(ref instanceof ReferenceRecord)) {
@@ -250,22 +262,26 @@ export function cook(rootAst, codeSource) {
250
262
  // https://tc39.es/ecma262/#sec-assignment-operators
251
263
  if (node.operator === "=") {
252
264
  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);
265
+ const lref = (yield* Evaluate(node.left)).Value;
266
+ let rval;
267
+ if (IsAnonymousFunctionDefinition(node.right) && node.left.type === "Identifier") {
268
+ rval = NamedEvaluation(node.right, node.left.name);
269
+ } else {
270
+ const rref = yield* Evaluate(node.right);
271
+ rval = GetValue(rref);
272
+ }
257
273
  PutValue(lref, rval);
258
274
  return NormalCompletion(rval);
259
275
  }
260
- const rref = Evaluate(node.right);
276
+ const rref = yield* Evaluate(node.right);
261
277
  const rval = GetValue(rref);
262
- DestructuringAssignmentEvaluation(node.left, rval);
278
+ yield* DestructuringAssignmentEvaluation(node.left, rval);
263
279
  return NormalCompletion(rval);
264
280
  }
265
281
  // Operators other than `=`.
266
- const lref = Evaluate(node.left).Value;
282
+ const lref = (yield* Evaluate(node.left)).Value;
267
283
  const lval = GetValue(lref);
268
- const rref = Evaluate(node.right);
284
+ const rref = yield* Evaluate(node.right);
269
285
  const rval = GetValue(rref);
270
286
  const r = ApplyStringOrNumericAssignment(lval, node.operator, rval);
271
287
  PutValue(lref, r);
@@ -281,7 +297,7 @@ export function cook(rootAst, codeSource) {
281
297
  const blockEnv = new DeclarativeEnvironment(oldEnv);
282
298
  BlockDeclarationInstantiation(node.body, blockEnv);
283
299
  getRunningContext().LexicalEnvironment = blockEnv;
284
- const blockValue = EvaluateStatementList(node.body);
300
+ const blockValue = yield* EvaluateStatementList(node.body);
285
301
  getRunningContext().LexicalEnvironment = oldEnv;
286
302
  return blockValue;
287
303
  }
@@ -296,18 +312,18 @@ export function cook(rootAst, codeSource) {
296
312
  return NormalCompletion(Empty);
297
313
  case "DoWhileStatement":
298
314
  // https://tc39.es/ecma262/#sec-do-while-statement
299
- return EvaluateBreakableStatement(DoWhileLoopEvaluation(node));
315
+ return EvaluateBreakableStatement(yield* DoWhileLoopEvaluation(node));
300
316
  case "ExpressionStatement":
301
317
  case "TSAsExpression":
302
318
  // https://tc39.es/ecma262/#sec-expression-statement
303
- return Evaluate(node.expression);
319
+ return yield* Evaluate(node.expression);
304
320
  case "ForInStatement":
305
321
  case "ForOfStatement":
306
322
  // https://tc39.es/ecma262/#sec-for-in-and-for-of-statements
307
- return EvaluateBreakableStatement(ForInOfLoopEvaluation(node));
323
+ return EvaluateBreakableStatement(yield* ForInOfLoopEvaluation(node));
308
324
  case "ForStatement":
309
325
  // https://tc39.es/ecma262/#sec-for-statement
310
- return EvaluateBreakableStatement(ForLoopEvaluation(node));
326
+ return EvaluateBreakableStatement(yield* ForLoopEvaluation(node));
311
327
  case "FunctionDeclaration":
312
328
  // https://tc39.es/ecma262/#sec-function-definitions
313
329
  return NormalCompletion(Empty);
@@ -317,41 +333,51 @@ export function cook(rootAst, codeSource) {
317
333
  return NormalCompletion(InstantiateOrdinaryFunctionExpression(node));
318
334
  case "IfStatement":
319
335
  // 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);
336
+ if (GetValue(yield* Evaluate(node.test))) {
337
+ var _hooks$beforeBranch;
338
+ (_hooks$beforeBranch = hooks.beforeBranch) === null || _hooks$beforeBranch === void 0 || _hooks$beforeBranch.call(hooks, node, "if");
339
+ return UpdateEmpty(yield* Evaluate(node.consequent), undefined);
340
+ }
341
+ (_hooks$beforeBranch2 = hooks.beforeBranch) === null || _hooks$beforeBranch2 === void 0 || _hooks$beforeBranch2.call(hooks, node, "else");
342
+ if (node.alternate) {
343
+ return UpdateEmpty(yield* Evaluate(node.alternate), undefined);
344
+ }
345
+ return NormalCompletion(undefined);
321
346
  case "ReturnStatement":
322
347
  {
323
348
  // https://tc39.es/ecma262/#sec-return-statement
324
349
  let v;
325
350
  if (node.argument) {
326
- const exprRef = Evaluate(node.argument);
351
+ const exprRef = yield* Evaluate(node.argument);
327
352
  v = GetValue(exprRef);
328
353
  }
354
+ currentNode = node;
329
355
  return new CompletionRecord("return", v);
330
356
  }
331
357
  case "ThrowStatement":
332
358
  // https://tc39.es/ecma262/#sec-throw-statement
333
- throw GetValue(Evaluate(node.argument));
359
+ throw GetValue(yield* Evaluate(node.argument));
334
360
  case "UpdateExpression":
335
361
  {
336
362
  // https://tc39.es/ecma262/#sec-update-expressions
337
- const lhs = Evaluate(node.argument).Value;
363
+ const lhs = (yield* Evaluate(node.argument)).Value;
338
364
  const oldValue = Number(GetValue(lhs));
339
365
  const newValue = node.operator === "++" ? oldValue + 1 : oldValue - 1;
340
366
  PutValue(lhs, newValue);
341
367
  return NormalCompletion(node.prefix ? newValue : oldValue);
342
368
  }
343
369
  case "SwitchCase":
344
- return EvaluateStatementList(node.consequent);
370
+ return yield* EvaluateStatementList(node.consequent);
345
371
  case "SwitchStatement":
346
372
  {
347
373
  // https://tc39.es/ecma262/#sec-switch-statement
348
- const exprRef = Evaluate(node.discriminant);
374
+ const exprRef = yield* Evaluate(node.discriminant);
349
375
  const switchValue = GetValue(exprRef);
350
376
  const oldEnv = getRunningContext().LexicalEnvironment;
351
377
  const blockEnv = new DeclarativeEnvironment(oldEnv);
352
378
  BlockDeclarationInstantiation(node.cases, blockEnv);
353
379
  getRunningContext().LexicalEnvironment = blockEnv;
354
- const R = CaseBlockEvaluation(node.cases, switchValue);
380
+ const R = yield* CaseBlockEvaluation(node.cases, switchValue);
355
381
  getRunningContext().LexicalEnvironment = oldEnv;
356
382
  return EvaluateBreakableStatement(R);
357
383
  }
@@ -360,18 +386,19 @@ export function cook(rootAst, codeSource) {
360
386
  // https://tc39.es/ecma262/#sec-try-statement
361
387
  let R;
362
388
  try {
363
- R = Evaluate(node.block);
389
+ R = yield* Evaluate(node.block);
364
390
  } catch (error) {
365
391
  if (node.handler) {
366
392
  var _hooks$beforeEvaluate2;
393
+ currentNode = node.handler;
367
394
  (_hooks$beforeEvaluate2 = hooks.beforeEvaluate) === null || _hooks$beforeEvaluate2 === void 0 || _hooks$beforeEvaluate2.call(hooks, node.handler);
368
- R = CatchClauseEvaluation(node.handler, error);
395
+ R = yield* CatchClauseEvaluation(node.handler, error);
369
396
  } else {
370
397
  throw error;
371
398
  }
372
399
  } finally {
373
400
  if (node.finalizer) {
374
- const F = Evaluate(node.finalizer);
401
+ const F = yield* Evaluate(node.finalizer);
375
402
  if (F.Type !== "normal") {
376
403
  R = F;
377
404
  }
@@ -384,6 +411,7 @@ export function cook(rootAst, codeSource) {
384
411
  // https://tc39.es/ecma262/#sec-declarations-and-the-variable-statement
385
412
  let result;
386
413
  for (const declarator of node.declarations) {
414
+ currentNode = declarator;
387
415
  if (!declarator.init) {
388
416
  // Assert: a declarator without init is always an identifier.
389
417
  if (node.kind === "var") {
@@ -393,23 +421,31 @@ export function cook(rootAst, codeSource) {
393
421
  result = InitializeReferencedBinding(lhs, undefined);
394
422
  }
395
423
  } else if (declarator.id.type === "Identifier") {
424
+ currentNode = declarator.init;
425
+ if (debug) yield;
396
426
  const bindingId = declarator.id.name;
397
427
  const lhs = ResolveBinding(bindingId);
398
- // Todo: IsAnonymousFunctionDefinition(Initializer)
399
- const rhs = Evaluate(declarator.init);
400
- const value = GetValue(rhs);
428
+ let value;
429
+ if (IsAnonymousFunctionDefinition(declarator.init)) {
430
+ value = NamedEvaluation(declarator.init, bindingId);
431
+ } else {
432
+ const rhs = yield* Evaluate(declarator.init);
433
+ value = GetValue(rhs);
434
+ }
401
435
  result = node.kind === "var" ? PutValue(lhs, value) : InitializeReferencedBinding(lhs, value);
402
436
  } else {
403
- const rhs = Evaluate(declarator.init);
437
+ currentNode = declarator.init;
438
+ if (debug) yield;
439
+ const rhs = yield* Evaluate(declarator.init);
404
440
  const rval = GetValue(rhs);
405
- result = BindingInitialization(declarator.id, rval, node.kind === "var" ? undefined : getRunningContext().LexicalEnvironment);
441
+ result = yield* BindingInitialization(declarator.id, rval, node.kind === "var" ? undefined : getRunningContext().LexicalEnvironment);
406
442
  }
407
443
  }
408
444
  return result;
409
445
  }
410
446
  case "WhileStatement":
411
447
  // https://tc39.es/ecma262/#sec-while-statement
412
- return EvaluateBreakableStatement(WhileLoopEvaluation(node));
448
+ return EvaluateBreakableStatement(yield* WhileLoopEvaluation(node));
413
449
  }
414
450
  }
415
451
  // eslint-disable-next-line no-console
@@ -431,9 +467,9 @@ export function cook(rootAst, codeSource) {
431
467
 
432
468
  // Try statements.
433
469
  // https://tc39.es/ecma262/#sec-runtime-semantics-catchclauseevaluation
434
- function CatchClauseEvaluation(node, thrownValue) {
470
+ function* CatchClauseEvaluation(node, thrownValue) {
435
471
  if (!node.param) {
436
- return Evaluate(node.body);
472
+ return yield* Evaluate(node.body);
437
473
  }
438
474
  const oldEnv = getRunningContext().LexicalEnvironment;
439
475
  const catchEnv = new DeclarativeEnvironment(oldEnv);
@@ -441,8 +477,8 @@ export function cook(rootAst, codeSource) {
441
477
  catchEnv.CreateMutableBinding(argName, false);
442
478
  }
443
479
  getRunningContext().LexicalEnvironment = catchEnv;
444
- BindingInitialization(node.param, thrownValue, catchEnv);
445
- const B = Evaluate(node.body);
480
+ yield* BindingInitialization(node.param, thrownValue, catchEnv);
481
+ const B = yield* Evaluate(node.body);
446
482
  getRunningContext().LexicalEnvironment = oldEnv;
447
483
  return B;
448
484
  }
@@ -455,7 +491,7 @@ export function cook(rootAst, codeSource) {
455
491
 
456
492
  // Switch statements.
457
493
  // https://tc39.es/ecma262/#sec-runtime-semantics-caseblockevaluation
458
- function CaseBlockEvaluation(cases, input) {
494
+ function* CaseBlockEvaluation(cases, input) {
459
495
  let V;
460
496
  const defaultCaseIndex = cases.findIndex(switchCase => !switchCase.test);
461
497
  const hasDefaultCase = defaultCaseIndex >= 0;
@@ -463,10 +499,10 @@ export function cook(rootAst, codeSource) {
463
499
  let found = false;
464
500
  for (const C of A) {
465
501
  if (!found) {
466
- found = CaseClauseIsSelected(C, input);
502
+ found = yield* CaseClauseIsSelected(C, input);
467
503
  }
468
504
  if (found) {
469
- const R = Evaluate(C);
505
+ const R = yield* Evaluate(C);
470
506
  if (R.Value !== Empty) {
471
507
  V = R.Value;
472
508
  }
@@ -483,10 +519,10 @@ export function cook(rootAst, codeSource) {
483
519
  if (!found) {
484
520
  for (const C of B) {
485
521
  if (!foundInB) {
486
- foundInB = CaseClauseIsSelected(C, input);
522
+ foundInB = yield* CaseClauseIsSelected(C, input);
487
523
  }
488
524
  if (foundInB) {
489
- const R = Evaluate(C);
525
+ const R = yield* Evaluate(C);
490
526
  if (R.Value !== Empty) {
491
527
  V = R.Value;
492
528
  }
@@ -499,7 +535,7 @@ export function cook(rootAst, codeSource) {
499
535
  if (foundInB) {
500
536
  return NormalCompletion(V);
501
537
  }
502
- const R = Evaluate(cases[defaultCaseIndex]);
538
+ const R = yield* Evaluate(cases[defaultCaseIndex]);
503
539
  if (R.Value !== Empty) {
504
540
  V = R.Value;
505
541
  }
@@ -509,7 +545,7 @@ export function cook(rootAst, codeSource) {
509
545
 
510
546
  // NOTE: The following is another complete iteration of the second CaseClauses.
511
547
  for (const C of B) {
512
- const R = Evaluate(C);
548
+ const R = yield* Evaluate(C);
513
549
  if (R.Value !== Empty) {
514
550
  V = R.Value;
515
551
  }
@@ -521,22 +557,22 @@ export function cook(rootAst, codeSource) {
521
557
  }
522
558
 
523
559
  // https://tc39.es/ecma262/#sec-runtime-semantics-caseclauseisselected
524
- function CaseClauseIsSelected(C, input) {
525
- const clauseSelector = GetValue(Evaluate(C.test));
560
+ function* CaseClauseIsSelected(C, input) {
561
+ const clauseSelector = GetValue(yield* Evaluate(C.test));
526
562
  return input === clauseSelector;
527
563
  }
528
564
 
529
565
  // While statements.
530
566
  // https://tc39.es/ecma262/#sec-runtime-semantics-whileloopevaluation
531
- function WhileLoopEvaluation(node) {
567
+ function* WhileLoopEvaluation(node) {
532
568
  let V;
533
569
  // eslint-disable-next-line no-constant-condition
534
570
  while (true) {
535
- const exprValue = GetValue(Evaluate(node.test));
571
+ const exprValue = GetValue(yield* Evaluate(node.test));
536
572
  if (!exprValue) {
537
573
  return NormalCompletion(V);
538
574
  }
539
- const stmtResult = Evaluate(node.body);
575
+ const stmtResult = yield* Evaluate(node.body);
540
576
  if (!LoopContinues(stmtResult)) {
541
577
  return UpdateEmpty(stmtResult, V);
542
578
  }
@@ -548,18 +584,18 @@ export function cook(rootAst, codeSource) {
548
584
 
549
585
  // Do-while Statements.
550
586
  // https://tc39.es/ecma262/#sec-runtime-semantics-dowhileloopevaluation
551
- function DoWhileLoopEvaluation(node) {
587
+ function* DoWhileLoopEvaluation(node) {
552
588
  let V;
553
589
  // eslint-disable-next-line no-constant-condition
554
590
  while (true) {
555
- const stmtResult = Evaluate(node.body);
591
+ const stmtResult = yield* Evaluate(node.body);
556
592
  if (!LoopContinues(stmtResult)) {
557
593
  return UpdateEmpty(stmtResult, V);
558
594
  }
559
595
  if (stmtResult.Value !== Empty) {
560
596
  V = stmtResult.Value;
561
597
  }
562
- const exprValue = GetValue(Evaluate(node.test));
598
+ const exprValue = GetValue(yield* Evaluate(node.test));
563
599
  if (!exprValue) {
564
600
  return NormalCompletion(V);
565
601
  }
@@ -568,22 +604,22 @@ export function cook(rootAst, codeSource) {
568
604
 
569
605
  // For in/of statements.
570
606
  // https://tc39.es/ecma262/#sec-runtime-semantics-forinofloopevaluation
571
- function ForInOfLoopEvaluation(node) {
607
+ function* ForInOfLoopEvaluation(node) {
572
608
  const lhs = node.left;
573
609
  const isVariableDeclaration = lhs.type === "VariableDeclaration";
574
610
  const lhsKind = isVariableDeclaration ? lhs.kind === "var" ? "varBinding" : "lexicalBinding" : "assignment";
575
611
  const uninitializedBoundNames = lhsKind === "lexicalBinding" ? collectBoundNames(lhs) : [];
576
612
  const iterationKind = node.type === "ForInStatement" ? "enumerate" : "iterate";
577
- const keyResult = ForInOfHeadEvaluation(uninitializedBoundNames, node.right, iterationKind);
613
+ const keyResult = yield* ForInOfHeadEvaluation(uninitializedBoundNames, node.right, iterationKind);
578
614
  if (keyResult.Type !== "normal") {
579
615
  // When enumerate, if the target is nil, a break completion will be returned.
580
616
  return keyResult;
581
617
  }
582
- return ForInOfBodyEvaluation(lhs, node.body, keyResult.Value, iterationKind, lhsKind);
618
+ return yield* ForInOfBodyEvaluation(lhs, node.body, keyResult.Value, iterationKind, lhsKind);
583
619
  }
584
620
 
585
621
  // https://tc39.es/ecma262/#sec-runtime-semantics-forinofheadevaluation
586
- function ForInOfHeadEvaluation(uninitializedBoundNames, expr, iterationKind) {
622
+ function* ForInOfHeadEvaluation(uninitializedBoundNames, expr, iterationKind) {
587
623
  const runningContext = getRunningContext();
588
624
  const oldEnv = runningContext.LexicalEnvironment;
589
625
  if (uninitializedBoundNames.length > 0) {
@@ -593,7 +629,7 @@ export function cook(rootAst, codeSource) {
593
629
  }
594
630
  runningContext.LexicalEnvironment = newEnv;
595
631
  }
596
- const exprRef = Evaluate(expr);
632
+ const exprRef = yield* Evaluate(expr, undefined, true);
597
633
  runningContext.LexicalEnvironment = oldEnv;
598
634
  const exprValue = GetValue(exprRef);
599
635
  if (iterationKind === "enumerate") {
@@ -606,7 +642,7 @@ export function cook(rootAst, codeSource) {
606
642
  const iterator = CreateListIteratorRecord(exprValue);
607
643
  return NormalCompletion(iterator);
608
644
  }
609
- function ForInOfBodyEvaluation(node, stmt, iteratorRecord, iterationKind, lhsKind) {
645
+ function* ForInOfBodyEvaluation(node, stmt, iteratorRecord, iterationKind, lhsKind) {
610
646
  const lhs = lhsKind === "assignment" ? node : node.declarations[0].id;
611
647
  const oldEnv = getRunningContext().LexicalEnvironment;
612
648
  let V;
@@ -618,11 +654,13 @@ export function cook(rootAst, codeSource) {
618
654
  const destructuring = lhs.type === "ObjectPattern" || lhs.type === "ArrayPattern";
619
655
  // eslint-disable-next-line no-constant-condition
620
656
  while (true) {
657
+ currentNode = lhs;
621
658
  const {
622
659
  done,
623
660
  value: nextValue
624
661
  } = iteratorRecord.next();
625
662
  if (done) {
663
+ if (debug) yield;
626
664
  return NormalCompletion(V);
627
665
  }
628
666
  let lhsRef;
@@ -631,15 +669,19 @@ export function cook(rootAst, codeSource) {
631
669
  iterationEnv = new DeclarativeEnvironment(oldEnv);
632
670
  ForDeclarationBindingInstantiation(node, iterationEnv);
633
671
  getRunningContext().LexicalEnvironment = iterationEnv;
672
+ if (debug) yield;
634
673
  if (!destructuring) {
635
674
  const [lhsName] = collectBoundNames(lhs);
636
675
  lhsRef = ResolveBinding(lhsName);
637
676
  }
638
- } else if (!destructuring) {
639
- lhsRef = Evaluate(lhs).Value;
677
+ } else {
678
+ if (debug) yield;
679
+ if (!destructuring) {
680
+ lhsRef = (yield* Evaluate(lhs)).Value;
681
+ }
640
682
  }
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);
683
+ 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);
684
+ const result = yield* Evaluate(stmt);
643
685
  getRunningContext().LexicalEnvironment = oldEnv;
644
686
  if (!LoopContinues(result)) {
645
687
  const status = UpdateEmpty(result, V);
@@ -668,13 +710,13 @@ export function cook(rootAst, codeSource) {
668
710
 
669
711
  // For statements.
670
712
  // https://tc39.es/ecma262/#sec-runtime-semantics-forloopevaluation
671
- function ForLoopEvaluation(node) {
713
+ function* ForLoopEvaluation(node) {
672
714
  var _node$init;
673
715
  if (((_node$init = node.init) === null || _node$init === void 0 ? void 0 : _node$init.type) === "VariableDeclaration") {
674
716
  // `for (var … ; … ; … ) …`
675
717
  if (node.init.kind === "var") {
676
- Evaluate(node.init);
677
- return ForBodyEvaluation(node.test, node.update, node.body, []);
718
+ yield* Evaluate(node.init);
719
+ return yield* ForBodyEvaluation(node.test, node.update, node.body, []);
678
720
  }
679
721
  // `for (let/const … ; … ; … ) …`
680
722
  const oldEnv = getRunningContext().LexicalEnvironment;
@@ -689,34 +731,34 @@ export function cook(rootAst, codeSource) {
689
731
  }
690
732
  }
691
733
  getRunningContext().LexicalEnvironment = loopEnv;
692
- Evaluate(node.init);
734
+ yield* Evaluate(node.init);
693
735
  const perIterationLets = isConst ? [] : Array.from(boundNames);
694
- const bodyResult = ForBodyEvaluation(node.test, node.update, node.body, perIterationLets);
736
+ const bodyResult = yield* ForBodyEvaluation(node.test, node.update, node.body, perIterationLets);
695
737
  getRunningContext().LexicalEnvironment = oldEnv;
696
738
  return bodyResult;
697
739
  }
698
740
  // `for ( … ; … ; … ) …`
699
741
  if (node.init) {
700
- const exprRef = Evaluate(node.init);
742
+ const exprRef = yield* Evaluate(node.init);
701
743
  GetValue(exprRef);
702
744
  }
703
- return ForBodyEvaluation(node.test, node.update, node.body, []);
745
+ return yield* ForBodyEvaluation(node.test, node.update, node.body, []);
704
746
  }
705
747
 
706
748
  // https://tc39.es/ecma262/#sec-forbodyevaluation
707
- function ForBodyEvaluation(test, increment, stmt, perIterationBindings) {
749
+ function* ForBodyEvaluation(test, increment, stmt, perIterationBindings) {
708
750
  CreatePerIterationEnvironment(perIterationBindings);
709
751
  let V;
710
752
  // eslint-disable-next-line no-constant-condition
711
753
  while (true) {
712
754
  if (test) {
713
- const testRef = Evaluate(test);
755
+ const testRef = yield* Evaluate(test, undefined, true);
714
756
  const testValue = GetValue(testRef);
715
757
  if (!testValue) {
716
758
  return NormalCompletion(V);
717
759
  }
718
760
  }
719
- const result = Evaluate(stmt);
761
+ const result = yield* Evaluate(stmt);
720
762
  if (!LoopContinues(result)) {
721
763
  return UpdateEmpty(result, V);
722
764
  }
@@ -725,7 +767,7 @@ export function cook(rootAst, codeSource) {
725
767
  }
726
768
  CreatePerIterationEnvironment(perIterationBindings);
727
769
  if (increment) {
728
- const incRef = Evaluate(increment);
770
+ const incRef = yield* Evaluate(increment, undefined, true);
729
771
  GetValue(incRef);
730
772
  }
731
773
  }
@@ -749,77 +791,80 @@ export function cook(rootAst, codeSource) {
749
791
 
750
792
  // Destructuring assignments.
751
793
  // https://tc39.es/ecma262/#sec-runtime-semantics-destructuringassignmentevaluation
752
- function DestructuringAssignmentEvaluation(pattern, value) {
794
+ function* DestructuringAssignmentEvaluation(pattern, value) {
753
795
  if (pattern.type === "ObjectPattern") {
754
796
  RequireObjectCoercible(value);
755
797
  if (pattern.properties.length > 0) {
756
- PropertyDestructuringAssignmentEvaluation(pattern.properties, value);
798
+ yield* PropertyDestructuringAssignmentEvaluation(pattern.properties, value);
757
799
  }
758
800
  return NormalCompletion(Empty);
759
801
  }
760
802
  const iteratorRecord = CreateListIteratorRecord(value);
761
- return IteratorDestructuringAssignmentEvaluation(pattern.elements, iteratorRecord);
803
+ return yield* IteratorDestructuringAssignmentEvaluation(pattern.elements, iteratorRecord);
762
804
  }
763
805
 
764
806
  // https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation
765
- function PropertyDestructuringAssignmentEvaluation(properties, value) {
807
+ function* PropertyDestructuringAssignmentEvaluation(properties, value) {
766
808
  const excludedNames = new Set();
767
809
  for (const prop of properties) {
768
810
  if (prop.type === "Property") {
769
- const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : EvaluateComputedPropertyName(prop.key);
811
+ const propName = !prop.computed && prop.key.type === "Identifier" ? prop.key.name : yield* EvaluateComputedPropertyName(prop.key);
770
812
  const valueTarget = prop.value.type === "AssignmentPattern" ? prop.value.left : prop.value;
771
813
  if (valueTarget.type === "Identifier") {
772
814
  const lref = ResolveBinding(valueTarget.name);
773
815
  let v = GetV(value, propName);
774
816
  if (prop.value.type === "AssignmentPattern" && v === undefined) {
775
- // Todo(steve): check IsAnonymousFunctionDefinition(Initializer)
776
- const defaultValue = Evaluate(prop.value.right);
777
- v = GetValue(defaultValue);
817
+ if (IsAnonymousFunctionDefinition(prop.value.right)) {
818
+ v = NamedEvaluation(prop.value.right, valueTarget.name);
819
+ } else {
820
+ const defaultValue = yield* Evaluate(prop.value.right);
821
+ v = GetValue(defaultValue);
822
+ }
778
823
  }
779
824
  PutValue(lref, v);
780
825
  excludedNames.add(propName);
781
826
  } else {
782
- KeyedDestructuringAssignmentEvaluation(prop.value, value, propName);
827
+ yield* KeyedDestructuringAssignmentEvaluation(prop.value, value, propName);
783
828
  excludedNames.add(propName);
784
829
  }
785
830
  } else {
786
- RestDestructuringAssignmentEvaluation(prop, value, excludedNames);
831
+ yield* RestDestructuringAssignmentEvaluation(prop, value, excludedNames);
787
832
  }
788
833
  }
789
834
  }
790
835
 
791
836
  // https://tc39.es/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
792
- function KeyedDestructuringAssignmentEvaluation(node, value, propertyName) {
837
+ function* KeyedDestructuringAssignmentEvaluation(node, value, propertyName) {
793
838
  const assignmentTarget = node.type === "AssignmentPattern" ? node.left : node;
794
839
  const isObjectOrArray = assignmentTarget.type === "ArrayPattern" || assignmentTarget.type === "ObjectPattern";
795
840
  let lref;
796
841
  if (!isObjectOrArray) {
797
- lref = Evaluate(assignmentTarget).Value;
842
+ lref = (yield* Evaluate(assignmentTarget)).Value;
798
843
  }
799
844
  const v = GetV(value, propertyName);
800
845
  let rhsValue;
801
846
  if (node.type === "AssignmentPattern" && v === undefined) {
802
- // Todo(steve): check IsAnonymousFunctionDefinition(Initializer)
803
- const defaultValue = Evaluate(node.right);
847
+ // `assignmentTarget.type` is never "Identifier" here.
848
+ const defaultValue = yield* Evaluate(node.right);
804
849
  rhsValue = GetValue(defaultValue);
805
850
  } else {
806
851
  rhsValue = v;
807
852
  }
808
853
  if (isObjectOrArray) {
809
- return DestructuringAssignmentEvaluation(assignmentTarget, rhsValue);
854
+ return yield* DestructuringAssignmentEvaluation(assignmentTarget, rhsValue);
810
855
  }
811
856
  return PutValue(lref, rhsValue);
812
857
  }
813
858
 
814
859
  // https://tc39.es/ecma262/#sec-runtime-semantics-restdestructuringassignmentevaluation
815
- function RestDestructuringAssignmentEvaluation(restProperty, value, excludedNames) {
816
- const lref = Evaluate(restProperty.argument).Value;
860
+ function* RestDestructuringAssignmentEvaluation(restProperty, value, excludedNames) {
861
+ const lref = (yield* Evaluate(restProperty.argument)).Value;
817
862
  const restObj = CopyDataProperties({}, value, excludedNames);
818
863
  return PutValue(lref, restObj);
819
864
  }
820
865
 
821
866
  // https://tc39.es/ecma262/#sec-runtime-semantics-iteratordestructuringassignmentevaluation
822
- function IteratorDestructuringAssignmentEvaluation(elements, iteratorRecord) {
867
+ function* IteratorDestructuringAssignmentEvaluation(elements, iteratorRecord) {
823
868
  let status = NormalCompletion(Empty);
824
869
  for (const element of elements) {
825
870
  if (!element) {
@@ -831,7 +876,7 @@ export function cook(rootAst, codeSource) {
831
876
  const isObjectOrArray = assignmentTarget.type === "ArrayPattern" || assignmentTarget.type === "ObjectPattern";
832
877
  let lref;
833
878
  if (!isObjectOrArray) {
834
- lref = Evaluate(assignmentTarget).Value;
879
+ lref = (yield* Evaluate(assignmentTarget)).Value;
835
880
  }
836
881
  let v;
837
882
  if (element.type !== "RestElement") {
@@ -841,9 +886,12 @@ export function cook(rootAst, codeSource) {
841
886
  } = iteratorRecord.next();
842
887
  const value = done ? undefined : nextValue;
843
888
  if (element.type === "AssignmentPattern" && value === undefined) {
844
- // Todo(steve): check IsAnonymousFunctionDefinition(Initializer)
845
- const defaultValue = Evaluate(element.right);
846
- v = GetValue(defaultValue);
889
+ if (IsAnonymousFunctionDefinition(element.right) && assignmentTarget.type === "Identifier") {
890
+ v = NamedEvaluation(element.right, assignmentTarget.name);
891
+ } else {
892
+ const defaultValue = yield* Evaluate(element.right);
893
+ v = GetValue(defaultValue);
894
+ }
847
895
  } else {
848
896
  v = value;
849
897
  }
@@ -865,7 +913,7 @@ export function cook(rootAst, codeSource) {
865
913
  }
866
914
  }
867
915
  if (isObjectOrArray) {
868
- status = DestructuringAssignmentEvaluation(assignmentTarget, v);
916
+ status = yield* DestructuringAssignmentEvaluation(assignmentTarget, v);
869
917
  } else {
870
918
  status = PutValue(lref, v);
871
919
  }
@@ -875,8 +923,8 @@ export function cook(rootAst, codeSource) {
875
923
 
876
924
  // Object expressions.
877
925
  // https://tc39.es/ecma262/#sec-evaluate-property-access-with-expression-key
878
- function EvaluatePropertyAccessWithExpressionKey(baseValue, expression, strict) {
879
- const propertyNameReference = Evaluate(expression);
926
+ function* EvaluatePropertyAccessWithExpressionKey(baseValue, expression, strict) {
927
+ const propertyNameReference = yield* Evaluate(expression);
880
928
  const propertyNameValue = GetValue(propertyNameReference);
881
929
  const propertyKey = ToPropertyKey(propertyNameValue);
882
930
  return new ReferenceRecord(baseValue, propertyKey, strict);
@@ -914,28 +962,36 @@ export function cook(rootAst, codeSource) {
914
962
 
915
963
  // Function declarations and expressions.
916
964
  // https://tc39.es/ecma262/#sec-evaluatecall
917
- function EvaluateCall(func, ref, args, callee) {
965
+ function* EvaluateCall(func, ref, args, callee) {
918
966
  let thisValue;
919
967
  if (ref instanceof ReferenceRecord) {
920
968
  if (IsPropertyReference(ref)) {
921
969
  thisValue = ref.Base;
922
970
  }
923
971
  }
924
- const argList = ArgumentListEvaluation(args);
972
+ const argList = yield* ArgumentListEvaluation(args);
925
973
  if (typeof func !== "function") {
926
974
  const funcName = codeSource.substring(callee.start, callee.end);
927
975
  throw new TypeError(`${funcName} is not a function`);
928
976
  }
977
+ if (debug) {
978
+ const debuggerCall = func[DebuggerCall];
979
+ if (debuggerCall) {
980
+ const result = yield* debuggerCall.apply(thisValue, argList);
981
+ sanitize(result);
982
+ return NormalCompletion(result);
983
+ }
984
+ }
929
985
  const result = func.apply(thisValue, argList);
930
986
  sanitize(result);
931
987
  return NormalCompletion(result);
932
988
  }
933
989
 
934
990
  // https://tc39.es/ecma262/#sec-evaluatenew
935
- function EvaluateNew(constructExpr, args) {
936
- const ref = Evaluate(constructExpr);
991
+ function* EvaluateNew(constructExpr, args) {
992
+ const ref = yield* Evaluate(constructExpr);
937
993
  const constructor = GetValue(ref);
938
- const argList = ArgumentListEvaluation(args);
994
+ const argList = yield* ArgumentListEvaluation(args);
939
995
  if (typeof constructor !== "function" || constructor[IsConstructor] === false) {
940
996
  const constructorName = codeSource.substring(constructExpr.start, constructExpr.end);
941
997
  throw new TypeError(`${constructorName} is not a constructor`);
@@ -948,32 +1004,39 @@ export function cook(rootAst, codeSource) {
948
1004
  }
949
1005
 
950
1006
  // https://tc39.es/ecma262/#sec-runtime-semantics-argumentlistevaluation
951
- function ArgumentListEvaluation(args) {
1007
+ function* ArgumentListEvaluation(args) {
952
1008
  const array = [];
953
1009
  if (Array.isArray(args)) {
954
1010
  for (const arg of args) {
955
1011
  if (arg.type === "SpreadElement") {
956
- const spreadValues = GetValue(Evaluate(arg.argument));
1012
+ const spreadValues = GetValue(yield* Evaluate(arg.argument));
957
1013
  array.push(...spreadValues);
958
1014
  } else {
959
- array.push(GetValue(Evaluate(arg)));
1015
+ array.push(GetValue(yield* Evaluate(arg)));
960
1016
  }
961
1017
  }
962
1018
  } else {
963
1019
  array.push(GetTemplateObject(args));
964
1020
  for (const expr of args.expressions) {
965
- array.push(GetValue(Evaluate(expr)));
1021
+ array.push(GetValue(yield* Evaluate(expr)));
966
1022
  }
967
1023
  }
968
1024
  return array;
969
1025
  }
970
1026
 
971
1027
  // https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist
972
- function CallFunction(closure, args) {
973
- var _hooks$beforeCall;
1028
+ function* CallFunction(closure, args) {
1029
+ var _hooks$beforeCall, _currentNode;
974
1030
  (_hooks$beforeCall = hooks.beforeCall) === null || _hooks$beforeCall === void 0 || _hooks$beforeCall.call(hooks, closure[SourceNode]);
975
1031
  PrepareForOrdinaryCall(closure);
976
- const result = OrdinaryCallEvaluateBody(closure, args);
1032
+ const result = yield* OrdinaryCallEvaluateBody(closure, args);
1033
+ if (((_currentNode = currentNode) === null || _currentNode === void 0 ? void 0 : _currentNode.type) !== "ReturnStatement") {
1034
+ currentNode = closure[SourceNode];
1035
+ }
1036
+ if (debug) yield {
1037
+ type: "return",
1038
+ value: result.Type === "return" ? result.Value : undefined
1039
+ };
977
1040
  executionContextStack.pop();
978
1041
  if (result.Type === "return") {
979
1042
  return result.Value;
@@ -993,24 +1056,24 @@ export function cook(rootAst, codeSource) {
993
1056
  }
994
1057
 
995
1058
  // https://tc39.es/ecma262/#sec-ordinarycallevaluatebody
996
- function OrdinaryCallEvaluateBody(F, args) {
997
- return EvaluateFunctionBody(F[ECMAScriptCode], F, args);
1059
+ function* OrdinaryCallEvaluateBody(F, args) {
1060
+ return yield* EvaluateFunctionBody(F[ECMAScriptCode], F, args);
998
1061
  }
999
1062
 
1000
1063
  // https://tc39.es/ecma262/#sec-runtime-semantics-evaluatefunctionbody
1001
- function EvaluateFunctionBody(body, F, args) {
1002
- FunctionDeclarationInstantiation(F, args);
1064
+ function* EvaluateFunctionBody(body, F, args) {
1065
+ yield* FunctionDeclarationInstantiation(F, args);
1003
1066
  if (Array.isArray(body)) {
1004
- return EvaluateStatementList(body);
1067
+ return yield* EvaluateStatementList(body);
1005
1068
  }
1006
- return new CompletionRecord("return", GetValue(Evaluate(body)));
1069
+ return new CompletionRecord("return", GetValue(yield* Evaluate(body)));
1007
1070
  }
1008
1071
 
1009
1072
  // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation
1010
- function EvaluateStatementList(statements) {
1073
+ function* EvaluateStatementList(statements) {
1011
1074
  let result = NormalCompletion(Empty);
1012
1075
  for (const stmt of statements) {
1013
- const s = Evaluate(stmt);
1076
+ const s = yield* Evaluate(stmt);
1014
1077
  if (s.Type !== "normal") {
1015
1078
  return s;
1016
1079
  }
@@ -1019,8 +1082,28 @@ export function cook(rootAst, codeSource) {
1019
1082
  return result;
1020
1083
  }
1021
1084
 
1085
+ // https://tc39.es/ecma262/#sec-isanonymousfunctiondefinition
1086
+ function IsAnonymousFunctionDefinition(node) {
1087
+ // No ParenthesizedExpression in ESTree.
1088
+ return node.type === "FunctionExpression" && !node.id || node.type === "ArrowFunctionExpression";
1089
+ }
1090
+
1091
+ // https://tc39.es/ecma262/#sec-runtime-semantics-namedevaluation
1092
+ function NamedEvaluation(node, name) {
1093
+ // No ParenthesizedExpression in ESTree.
1094
+ switch (node.type) {
1095
+ case "FunctionExpression":
1096
+ return InstantiateOrdinaryFunctionExpression(node, name);
1097
+ case "ArrowFunctionExpression":
1098
+ return InstantiateArrowFunctionExpression(node, name);
1099
+ // istanbul ignore next: should never happen
1100
+ default:
1101
+ throw new Error(`Unexpected node type for NamedEvaluation: ${node.type}`);
1102
+ }
1103
+ }
1104
+
1022
1105
  // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1023
- function FunctionDeclarationInstantiation(func, args) {
1106
+ function* FunctionDeclarationInstantiation(func, args) {
1024
1107
  const calleeContext = getRunningContext();
1025
1108
  const code = func[ECMAScriptCode];
1026
1109
  const formals = func[FormalParameters];
@@ -1055,7 +1138,7 @@ export function cook(rootAst, codeSource) {
1055
1138
  env.CreateMutableBinding(paramName, false);
1056
1139
  }
1057
1140
  const iteratorRecord = CreateListIteratorRecord(args);
1058
- IteratorBindingInitialization(formals, iteratorRecord, env);
1141
+ yield* IteratorBindingInitialization(formals, iteratorRecord, env);
1059
1142
  let varEnv;
1060
1143
  if (!hasParameterExpressions) {
1061
1144
  // NOTE: Only a single Environment Record is needed for the parameters
@@ -1111,37 +1194,50 @@ export function cook(rootAst, codeSource) {
1111
1194
 
1112
1195
  // https://tc39.es/ecma262/#sec-runtime-semantics-instantiatefunctionobject
1113
1196
  function InstantiateFunctionObject(func, scope) {
1114
- return OrdinaryFunctionCreate(func, scope, true);
1197
+ const F = OrdinaryFunctionCreate(func, scope, true);
1198
+ if (func.id) {
1199
+ SetFunctionName(F, func.id.name);
1200
+ }
1201
+ return F;
1115
1202
  }
1116
1203
 
1117
1204
  // https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
1118
- function InstantiateOrdinaryFunctionExpression(functionExpression) {
1205
+ function InstantiateOrdinaryFunctionExpression(functionExpression, name) {
1119
1206
  const scope = getRunningContext().LexicalEnvironment;
1120
1207
  if (functionExpression.id) {
1121
1208
  const name = functionExpression.id.name;
1122
1209
  const funcEnv = new DeclarativeEnvironment(scope);
1123
1210
  funcEnv.CreateImmutableBinding(name, false);
1124
1211
  const closure = OrdinaryFunctionCreate(functionExpression, funcEnv, true);
1212
+ SetFunctionName(closure, name);
1125
1213
  funcEnv.InitializeBinding(name, closure);
1126
1214
  return closure;
1127
1215
  } else {
1128
1216
  const closure = OrdinaryFunctionCreate(functionExpression, scope, true);
1217
+ SetFunctionName(closure, name ?? "");
1129
1218
  return closure;
1130
1219
  }
1131
1220
  }
1132
1221
 
1133
1222
  // https://tc39.es/ecma262/#sec-runtime-semantics-instantiatearrowfunctionexpression
1134
- function InstantiateArrowFunctionExpression(arrowFunction) {
1223
+ function InstantiateArrowFunctionExpression(arrowFunction, name) {
1135
1224
  const scope = getRunningContext().LexicalEnvironment;
1136
1225
  const closure = OrdinaryFunctionCreate(arrowFunction, scope, false);
1226
+ SetFunctionName(closure, name ?? "");
1137
1227
  return closure;
1138
1228
  }
1229
+ function SetFunctionName(F, name) {
1230
+ Object.defineProperty(F, "name", {
1231
+ value: name,
1232
+ configurable: true
1233
+ });
1234
+ }
1139
1235
 
1140
1236
  // https://tc39.es/ecma262/#sec-ordinaryfunctioncreate
1141
1237
  function OrdinaryFunctionCreate(sourceNode, scope, isConstructor) {
1142
1238
  const F = function () {
1143
1239
  // eslint-disable-next-line prefer-rest-params
1144
- return CallFunction(F, arguments);
1240
+ return unwind(CallFunction(F, arguments));
1145
1241
  };
1146
1242
  Object.defineProperties(F, {
1147
1243
  [SourceNode]: {
@@ -1160,39 +1256,47 @@ export function cook(rootAst, codeSource) {
1160
1256
  value: isConstructor
1161
1257
  }
1162
1258
  });
1259
+ if (debug) {
1260
+ Object.defineProperty(F, DebuggerCall, {
1261
+ value: function () {
1262
+ // eslint-disable-next-line prefer-rest-params
1263
+ return CallFunction(F, arguments);
1264
+ }
1265
+ });
1266
+ }
1163
1267
  return F;
1164
1268
  }
1165
1269
 
1166
1270
  // Patterns initialization.
1167
1271
  // https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
1168
- function BindingInitialization(node, value, environment) {
1272
+ function* BindingInitialization(node, value, environment) {
1169
1273
  switch (node.type) {
1170
1274
  case "Identifier":
1171
1275
  return InitializeBoundName(node.name, value, environment);
1172
1276
  case "ObjectPattern":
1173
1277
  RequireObjectCoercible(value);
1174
- return PropertyBindingInitialization(node.properties, value, environment);
1278
+ return yield* PropertyBindingInitialization(node.properties, value, environment);
1175
1279
  case "ArrayPattern":
1176
1280
  {
1177
1281
  const iteratorRecord = CreateListIteratorRecord(value);
1178
- return IteratorBindingInitialization(node.elements, iteratorRecord, environment);
1282
+ return yield* IteratorBindingInitialization(node.elements, iteratorRecord, environment);
1179
1283
  }
1180
1284
  }
1181
1285
  }
1182
1286
 
1183
1287
  // https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
1184
- function PropertyBindingInitialization(properties, value, environment) {
1288
+ function* PropertyBindingInitialization(properties, value, environment) {
1185
1289
  const excludedNames = new Set();
1186
1290
  for (const prop of properties) {
1187
1291
  if (prop.type === "RestElement") {
1188
1292
  return RestBindingInitialization(prop, value, environment, excludedNames);
1189
1293
  }
1190
1294
  if (!prop.computed && prop.key.type === "Identifier") {
1191
- KeyedBindingInitialization(prop.value, value, environment, prop.key.name);
1295
+ yield* KeyedBindingInitialization(prop.value, value, environment, prop.key.name);
1192
1296
  excludedNames.add(prop.key.name);
1193
1297
  } else {
1194
- const P = EvaluateComputedPropertyName(prop.key);
1195
- KeyedBindingInitialization(prop.value, value, environment, P);
1298
+ const P = yield* EvaluateComputedPropertyName(prop.key);
1299
+ yield* KeyedBindingInitialization(prop.value, value, environment, P);
1196
1300
  excludedNames.add(P);
1197
1301
  }
1198
1302
  }
@@ -1200,8 +1304,8 @@ export function cook(rootAst, codeSource) {
1200
1304
  }
1201
1305
 
1202
1306
  // https://tc39.es/ecma262/#prod-ComputedPropertyName
1203
- function EvaluateComputedPropertyName(node) {
1204
- const propName = GetValue(Evaluate(node));
1307
+ function* EvaluateComputedPropertyName(node) {
1308
+ const propName = GetValue(yield* Evaluate(node));
1205
1309
  return ToPropertyKey(propName);
1206
1310
  }
1207
1311
 
@@ -1216,7 +1320,7 @@ export function cook(rootAst, codeSource) {
1216
1320
  }
1217
1321
 
1218
1322
  // https://tc39.es/ecma262/#sec-runtime-semantics-iteratorbindinginitialization
1219
- function IteratorBindingInitialization(elements, iteratorRecord, environment) {
1323
+ function* IteratorBindingInitialization(elements, iteratorRecord, environment) {
1220
1324
  if (elements.length === 0) {
1221
1325
  return NormalCompletion(Empty);
1222
1326
  }
@@ -1255,7 +1359,7 @@ export function cook(rootAst, codeSource) {
1255
1359
  value
1256
1360
  } = iteratorRecord.next();
1257
1361
  if (done) {
1258
- result = BindingInitialization(node.argument, A, environment);
1362
+ result = yield* BindingInitialization(node.argument, A, environment);
1259
1363
  break;
1260
1364
  }
1261
1365
  A[n] = value;
@@ -1278,10 +1382,10 @@ export function cook(rootAst, codeSource) {
1278
1382
  v = value;
1279
1383
  }
1280
1384
  if (node.type === "AssignmentPattern" && v === undefined) {
1281
- const defaultValue = Evaluate(node.right);
1385
+ const defaultValue = yield* Evaluate(node.right);
1282
1386
  v = GetValue(defaultValue);
1283
1387
  }
1284
- result = BindingInitialization(bindingElement, v, environment);
1388
+ result = yield* BindingInitialization(bindingElement, v, environment);
1285
1389
  break;
1286
1390
  }
1287
1391
  case "Identifier":
@@ -1297,9 +1401,12 @@ export function cook(rootAst, codeSource) {
1297
1401
  v = value;
1298
1402
  }
1299
1403
  if (node.type === "AssignmentPattern" && v === undefined) {
1300
- // IsAnonymousFunctionDefinition(Initializer)
1301
- const defaultValue = Evaluate(node.right);
1302
- v = GetValue(defaultValue);
1404
+ if (IsAnonymousFunctionDefinition(node.right)) {
1405
+ v = NamedEvaluation(node.right, bindingId);
1406
+ } else {
1407
+ const defaultValue = yield* Evaluate(node.right);
1408
+ v = GetValue(defaultValue);
1409
+ }
1303
1410
  }
1304
1411
  result = environment ? InitializeReferencedBinding(lhs, v) : PutValue(lhs, v);
1305
1412
  break;
@@ -1311,16 +1418,19 @@ export function cook(rootAst, codeSource) {
1311
1418
  }
1312
1419
 
1313
1420
  // https://tc39.es/ecma262/#sec-runtime-semantics-keyedbindinginitialization
1314
- function KeyedBindingInitialization(node, value, environment, propertyName) {
1421
+ function* KeyedBindingInitialization(node, value, environment, propertyName) {
1315
1422
  const isIdentifier = node.type === "Identifier" || node.type === "AssignmentPattern" && node.left.type === "Identifier";
1316
1423
  if (isIdentifier) {
1317
1424
  const bindingId = node.type === "Identifier" ? node.name : node.left.name;
1318
1425
  const lhs = ResolveBinding(bindingId, environment);
1319
1426
  let v = GetV(value, propertyName);
1320
1427
  if (node.type === "AssignmentPattern" && v === undefined) {
1321
- // If IsAnonymousFunctionDefinition(Initializer)
1322
- const defaultValue = Evaluate(node.right);
1323
- v = GetValue(defaultValue);
1428
+ if (IsAnonymousFunctionDefinition(node.right)) {
1429
+ v = NamedEvaluation(node.right, bindingId);
1430
+ } else {
1431
+ const defaultValue = yield* Evaluate(node.right);
1432
+ v = GetValue(defaultValue);
1433
+ }
1324
1434
  }
1325
1435
  if (!environment) {
1326
1436
  return PutValue(lhs, v);
@@ -1329,10 +1439,10 @@ export function cook(rootAst, codeSource) {
1329
1439
  }
1330
1440
  let v = GetV(value, propertyName);
1331
1441
  if (node.type === "AssignmentPattern" && v === undefined) {
1332
- const defaultValue = Evaluate(node.right);
1442
+ const defaultValue = yield* Evaluate(node.right);
1333
1443
  v = GetValue(defaultValue);
1334
1444
  }
1335
- return BindingInitialization(node.type === "AssignmentPattern" ? node.left : node, v, environment);
1445
+ return yield* BindingInitialization(node.type === "AssignmentPattern" ? node.left : node, v, environment);
1336
1446
  }
1337
1447
 
1338
1448
  // https://tc39.es/ecma262/#sec-initializeboundname
@@ -1350,7 +1460,7 @@ export function cook(rootAst, codeSource) {
1350
1460
  }
1351
1461
  }
1352
1462
  if (expressionOnly) {
1353
- return GetValue(Evaluate(rootAst));
1463
+ return GetValue(unwind(Evaluate(rootAst)));
1354
1464
  }
1355
1465
  (_hooks$beforeEvaluate3 = hooks.beforeEvaluate) === null || _hooks$beforeEvaluate3 === void 0 || _hooks$beforeEvaluate3.call(hooks, rootAst);
1356
1466
  ThrowIfFunctionIsInvalid(rootAst);
@@ -1359,6 +1469,32 @@ export function cook(rootAst, codeSource) {
1359
1469
  rootEnv.CreateImmutableBinding(fn, true);
1360
1470
  const fo = InstantiateFunctionObject(rootAst, rootEnv);
1361
1471
  rootEnv.InitializeBinding(fn, fo);
1472
+ if (debug) {
1473
+ Object.defineProperties(fo, {
1474
+ [DebuggerScope]: {
1475
+ value: function () {
1476
+ return getRunningContext().LexicalEnvironment;
1477
+ }
1478
+ },
1479
+ [DebuggerNode]: {
1480
+ value: function () {
1481
+ return currentNode;
1482
+ }
1483
+ }
1484
+ });
1485
+ }
1362
1486
  return fo;
1363
1487
  }
1488
+ function unwind(iterator) {
1489
+ // eslint-disable-next-line no-constant-condition
1490
+ while (true) {
1491
+ const {
1492
+ done,
1493
+ value
1494
+ } = iterator.next();
1495
+ if (done) {
1496
+ return value;
1497
+ }
1498
+ }
1499
+ }
1364
1500
  //# sourceMappingURL=cook.js.map