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