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