Files
2023-08-01 13:49:46 +02:00

411 lines
16 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.InternalGetResultValue = InternalGetResultValue;
exports.LoopContinues = LoopContinues;
exports.ForInOfHeadEvaluation = ForInOfHeadEvaluation;
exports.ForInOfBodyEvaluation = ForInOfBodyEvaluation;
exports.default = function (ast, strictCode, env, realm, labelSet) {
var left = ast.left,
right = ast.right,
body = ast.body;
try {
if (left.type === "VariableDeclaration") {
if (left.kind === "var") {
// for (var ForBinding o fAssignmentExpression) Statement
// 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
var keyResult = ForInOfHeadEvaluation(realm, env, [], right, "iterate", strictCode);
(0, _invariant2.default)(keyResult instanceof _index.ObjectValue);
// 2. Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet).
return ForInOfBodyEvaluation(realm, env, left.declarations[0].id, body, keyResult, "varBinding", labelSet, strictCode);
} else {
// for (ForDeclaration of AssignmentExpression) Statement
// 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate).
var _keyResult = ForInOfHeadEvaluation(realm, env, _singletons.Environment.BoundNames(realm, left), right, "iterate", strictCode);
(0, _invariant2.default)(_keyResult instanceof _index.ObjectValue);
// 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet).
return ForInOfBodyEvaluation(realm, env, left, body, _keyResult, "lexicalBinding", labelSet, strictCode);
}
} else {
// for (LeftHandSideExpression of AssignmentExpression) Statement
// 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate).
var _keyResult2 = ForInOfHeadEvaluation(realm, env, [], right, "iterate", strictCode);
(0, _invariant2.default)(_keyResult2 instanceof _index.ObjectValue);
// 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet).
return ForInOfBodyEvaluation(realm, env, left, body, _keyResult2, "assignment", labelSet, strictCode);
}
} catch (e) {
if (e instanceof _completions.BreakCompletion) {
if (!e.target) return (0, _index2.UpdateEmpty)(realm, e, realm.intrinsics.undefined).value;
}
throw e;
}
};
var _errors = require("../errors.js");
var _environment = require("../environment.js");
var _completions = require("../completions.js");
var _index = require("../values/index.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _index2 = require("../methods/index.js");
var _singletons = require("../singletons.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
function InternalGetResultValue(realm, result) {
if (result instanceof _completions.AbruptCompletion) {
return result.value;
} else {
return result;
}
}
// ECMA262 13.7.1.2
function LoopContinues(realm, completion, labelSet) {
// 1. If completion.[[Type]] is normal, return true.
if (completion instanceof _index.Value) return true;
(0, _invariant2.default)(completion instanceof _completions.AbruptCompletion);
// 2. If completion.[[Type]] is not continue, return false.
if (!(completion instanceof _completions.ContinueCompletion)) return false;
// 3. If completion.[[Target]] is empty, return true.
if (!completion.target) return true;
// 4. If completion.[[Target]] is an element of labelSet, return true.
if (labelSet != null && labelSet.indexOf(completion.target) >= 0) return true;
// 5. Return false.
return false;
}
// ECMA262 13.7.5.10
function BindingInstantiation(realm, ast, env) {
// ast = ForDeclaration : LetOrConst ForBinding
// 1. Let envRec be environment's EnvironmentRecord.
var envRec = env.environmentRecord;
// 2. Assert: envRec is a declarative Environment Record.
(0, _invariant2.default)(envRec instanceof _environment.DeclarativeEnvironmentRecord);
// 3. For each element name of the BoundNames of ForBinding do
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _singletons.Environment.BoundNames(realm, ast)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var name = _step.value;
// a. If IsConstantDeclaration of LetOrConst is true, then
if (ast.kind === "const") {
// i. Perform ! envRec.CreateImmutableBinding(name, true).
envRec.CreateImmutableBinding(name, true);
} else {
// b.
// i. Perform ! envRec.CreateMutableBinding(name, false).
envRec.CreateMutableBinding(name, false);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
// ECMA262 13.7.5.12
function ForInOfHeadEvaluation(realm, env, TDZnames, expr, iterationKind, strictCode) {
// 1. Let oldEnv be the running execution context's LexicalEnvironment.
var oldEnv = realm.getRunningContext().lexicalEnvironment;
// 2. If TDZnames is not an empty List, then
if (TDZnames.length) {
// a. Assert: TDZnames has no duplicate entries.
// b. Let TDZ be NewDeclarativeEnvironment(oldEnv).
var TDZ = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv);
// c. Let TDZEnvRec be TDZ's EnvironmentRecord.
var TDZEnvRec = TDZ.environmentRecord;
// d. For each string name in TDZnames, do
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = TDZnames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var name = _step2.value;
// i. Perform ! TDZEnvRec.CreateMutableBinding(name, false).
TDZEnvRec.CreateMutableBinding(name, false);
}
// e. Set the running execution context's LexicalEnvironment to TDZ.
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
realm.getRunningContext().lexicalEnvironment = TDZ;
env = TDZ;
}
var exprRef = void 0;
try {
// 3. Let exprRef be the result of evaluating expr.
exprRef = env.evaluate(expr, strictCode);
} finally {
// 4. Set the running execution context's LexicalEnvironment to oldEnv.
var lexEnv = realm.getRunningContext().lexicalEnvironment;
if (lexEnv !== oldEnv) realm.onDestroyScope(lexEnv);
realm.getRunningContext().lexicalEnvironment = oldEnv;
}
env = oldEnv;
// 5. Let exprValue be ? GetValue(exprRef).
var exprValue = _singletons.Environment.GetValue(realm, exprRef);
// 6. If iterationKind is enumerate, then
if (iterationKind === "enumerate") {
// a. If exprValue.[[Value]] is null or undefined, then
if (exprValue instanceof _index.NullValue || exprValue instanceof _index.UndefinedValue) {
// i. Return Completion{[[Type]]: break, [[Value]]: empty, [[Target]]: empty}.
throw new _completions.BreakCompletion(realm.intrinsics.empty, expr.loc, undefined);
}
// b. Let obj be ToObject(exprValue).
var obj = _singletons.To.ToObjectPartial(realm, exprValue);
// c. Return ? EnumerateObjectProperties(obj).
if (obj.isPartialObject() || obj instanceof _index.AbstractObjectValue) {
return obj;
} else {
return _singletons.Properties.EnumerateObjectProperties(realm, obj);
}
} else {
// 8. Else,
// 1. Assert: iterationKind is iterate.
(0, _invariant2.default)(iterationKind === "iterate", "expected iterationKind to be iterate");
if (exprValue instanceof _index.AbstractValue) {
var error = new _errors.CompilerDiagnostic("for of loops over unknown collections are not yet supported", expr.loc, "PP0014", "FatalError");
realm.handleError(error);
throw new _errors.FatalError();
}
// 1. Return ? GetIterator(exprValue).
return (0, _index2.GetIterator)(realm, exprValue);
}
}
// ECMA262 13.7.5.13
function ForInOfBodyEvaluation(realm, env, lhs, stmt, iterator, lhsKind, labelSet, strictCode) {
// 1. Let oldEnv be the running execution context's LexicalEnvironment.
var oldEnv = realm.getRunningContext().lexicalEnvironment;
// 2. Let V be undefined.
var V = realm.intrinsics.undefined;
// 3. Let destructuring be IsDestructuring of lhs.
var destructuring = _singletons.Environment.IsDestructuring(lhs);
// 4. If destructuring is true and if lhsKind is assignment, then
if (destructuring && lhsKind === "assignment") {
// a. Assert: lhs is a LeftHandSideExpression.
(0, _invariant2.default)(lhs.type !== "VariableDeclaration");
// b. Let assignmentPattern be the parse of the source text corresponding to lhs using AssignmentPattern as the goal symbol.
}
// 5. Repeat
while (true) {
// a. Let nextResult be ? IteratorStep(iterator).
var nextResult = (0, _index2.IteratorStep)(realm, iterator);
// b. If nextResult is false, return NormalCompletion(V).
if (!nextResult) return V;
// c. Let nextValue be ? IteratorValue(nextResult).
var nextValue = (0, _index2.IteratorValue)(realm, nextResult);
// d. If lhsKind is either assignment or varBinding, then
var iterationEnv = void 0;
var lhsRef = void 0;
if (lhsKind === "assignment" || lhsKind === "varBinding") {
// i. If destructuring is false, then
if (!destructuring) {
// 1. Let lhsRef be the result of evaluating lhs. (It may be evaluated repeatedly.)
lhsRef = env.evaluateCompletion(lhs, strictCode);
}
} else {
// e. Else,
// i. Assert: lhsKind is lexicalBinding.
(0, _invariant2.default)(lhsKind === "lexicalBinding", "expected lhsKind to be lexicalBinding");
(0, _invariant2.default)(lhs.type === "VariableDeclaration");
// ii. Assert: lhs is a ForDeclaration.
// iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv).
iterationEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv);
// iv. Perform BindingInstantiation for lhs passing iterationEnv as the argument.
BindingInstantiation(realm, lhs, iterationEnv);
// v. Set the running execution context's LexicalEnvironment to iterationEnv.
realm.getRunningContext().lexicalEnvironment = iterationEnv;
env = iterationEnv;
// vi. If destructuring is false, then
if (!destructuring) {
var names = _singletons.Environment.BoundNames(realm, lhs);
// 1. Assert: lhs binds a single name.
(0, _invariant2.default)(names.length === 1, "expected single name");
// 2. Let lhsName be the sole element of BoundNames of lhs.
var lhsName = names[0];
// 3. Let lhsRef be ! ResolveBinding(lhsName).
lhsRef = _singletons.Environment.ResolveBinding(realm, lhsName, strictCode);
}
}
// f. If destructuring is false, then
var status = void 0;
try {
if (!destructuring) {
// i. If lhsRef is an abrupt completion, then
if (lhsRef instanceof _completions.AbruptCompletion) {
// 1. Let status be lhsRef.
status = lhsRef;
} else if (lhsKind === "lexicalBinding") {
// ii. Else if lhsKind is lexicalBinding, then
// 1. Let status be InitializeReferencedBinding(lhsRef, nextValue).
(0, _invariant2.default)(lhsRef instanceof _environment.Reference);
status = _singletons.Environment.InitializeReferencedBinding(realm, lhsRef, nextValue);
} else {
// iii. Else,
// 1. Let status be PutValue(lhsRef, nextValue).
(0, _invariant2.default)(lhsRef !== undefined);
status = _singletons.Properties.PutValue(realm, lhsRef, nextValue);
}
} else {
// g. Else,
// i. If lhsKind is assignment, then
if (lhsKind === "assignment") {
(0, _invariant2.default)(lhs.type === "ArrayPattern" || lhs.type === "ObjectPattern");
// 1. Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument.
status = (0, _index2.DestructuringAssignmentEvaluation)(realm, lhs, nextValue, strictCode, iterationEnv || env);
} else if (lhsKind === "varBinding") {
// ii. Else if lhsKind is varBinding, then
// 1. Assert: lhs is a ForBinding.
// 2. Let status be the result of performing BindingInitialization for lhs passing nextValue and undefined as the arguments.
status = _singletons.Environment.BindingInitialization(realm, lhs, nextValue, strictCode, undefined);
} else {
// iii. Else,
// 1. Assert: lhsKind is lexicalBinding.
(0, _invariant2.default)(lhsKind === "lexicalBinding");
// 2. Assert: lhs is a ForDeclaration.
// 3. Let status be the result of performing BindingInitialization for lhs passing nextValue and iterationEnv as arguments.
(0, _invariant2.default)(iterationEnv !== undefined);
status = _singletons.Environment.BindingInitialization(realm, lhs, nextValue, strictCode, iterationEnv);
}
}
} catch (e) {
if (e instanceof _completions.AbruptCompletion) {
status = e;
} else {
throw e;
}
}
// h. If status is an abrupt completion, then
if (status instanceof _completions.AbruptCompletion) {
// i. Set the running execution context's LexicalEnvironment to oldEnv.
realm.getRunningContext().lexicalEnvironment = oldEnv;
// ii. Return ? IteratorClose(iterator, status).
throw (0, _index2.IteratorClose)(realm, iterator, status);
}
// i. Let result be the result of evaluating stmt.
var result = env.evaluateCompletion(stmt, strictCode);
(0, _invariant2.default)(result instanceof _index.Value || result instanceof _completions.AbruptCompletion);
// j. Set the running execution context's LexicalEnvironment to oldEnv.
var lexEnv = realm.getRunningContext().lexicalEnvironment;
if (lexEnv !== oldEnv) realm.onDestroyScope(lexEnv);
realm.getRunningContext().lexicalEnvironment = oldEnv;
env = oldEnv;
// k. If LoopContinues(result, labelSet) is false, return ? IteratorClose(iterator, UpdateEmpty(result, V)).
if (!LoopContinues(realm, result, labelSet)) {
(0, _invariant2.default)(result instanceof _completions.AbruptCompletion);
result = (0, _index2.UpdateEmpty)(realm, result, V);
(0, _invariant2.default)(result instanceof _completions.AbruptCompletion);
throw (0, _index2.IteratorClose)(realm, iterator, result);
}
// l. If result.[[Value]] is not empty, let V be result.[[Value]].
var resultValue = InternalGetResultValue(realm, result);
if (!(resultValue instanceof _index.EmptyValue)) V = resultValue;
}
/* istanbul ignore next */
(0, _invariant2.default)(false); // can't get here but there is no other way to make Flow happy
}
// ECMA262 13.7.5.11
//# sourceMappingURL=ForOfStatement.js.map