prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
340 lines (254 loc) • 14.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.InternalGetResultValue = InternalGetResultValue;
exports.LoopContinues = LoopContinues;
exports.ForInOfHeadEvaluation = ForInOfHeadEvaluation;
exports.ForInOfBodyEvaluation = ForInOfBodyEvaluation;
exports.default = _default;
var _errors = require("../errors.js");
var _environment = require("../environment.js");
var _completions = require("../completions.js");
var _index = require("../values/index.js");
var _invariant = _interopRequireDefault(require("../invariant.js"));
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.Completion) {
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 || completion instanceof _completions.NormalCompletion) return true;
if (completion instanceof _completions.JoinedAbruptCompletions) {
return LoopContinues(realm, completion.consequent, labelSet) || LoopContinues(realm, completion.alternate, labelSet);
} // 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.
let envRec = env.environmentRecord; // 2. Assert: envRec is a declarative Environment Record.
(0, _invariant.default)(envRec instanceof _environment.DeclarativeEnvironmentRecord); // 3. For each element name of the BoundNames of ForBinding do
for (let name of _singletons.Environment.BoundNames(realm, ast)) {
// 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);
}
}
} // ECMA262 13.7.5.12
function ForInOfHeadEvaluation(realm, env, TDZnames, expr, iterationKind, strictCode) {
// 1. Let oldEnv be the running execution context's LexicalEnvironment.
let 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).
let TDZ = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv); // c. Let TDZEnvRec be TDZ's EnvironmentRecord.
let TDZEnvRec = TDZ.environmentRecord; // d. For each string name in TDZnames, do
for (let name of TDZnames) {
// i. Perform ! TDZEnvRec.CreateMutableBinding(name, false).
TDZEnvRec.CreateMutableBinding(name, false);
} // e. Set the running execution context's LexicalEnvironment to TDZ.
realm.getRunningContext().lexicalEnvironment = TDZ;
env = TDZ;
}
let exprRef;
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.
let lexEnv = realm.getRunningContext().lexicalEnvironment;
if (lexEnv !== oldEnv) realm.onDestroyScope(lexEnv);
realm.getRunningContext().lexicalEnvironment = oldEnv;
}
env = oldEnv; // 5. Let exprValue be ? GetValue(exprRef).
let 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, null);
} // b. Let obj be ToObject(exprValue).
let obj = _singletons.To.ToObject(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, _invariant.default)(iterationKind === "iterate", "expected iterationKind to be iterate");
if (exprValue instanceof _index.AbstractValue) {
let 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.
let oldEnv = realm.getRunningContext().lexicalEnvironment; // 2. Let V be undefined.
let V = realm.intrinsics.undefined; // 3. Let destructuring be IsDestructuring of lhs.
let 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, _invariant.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).
let nextResult = (0, _index2.IteratorStep)(realm, iterator); // b. If nextResult is false, return NormalCompletion(V).
if (!nextResult) return V; // c. Let nextValue be ? IteratorValue(nextResult).
let nextValue = (0, _index2.IteratorValue)(realm, nextResult); // d. If lhsKind is either assignment or varBinding, then
let iterationEnv;
let lhsRef;
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, _invariant.default)(lhsKind === "lexicalBinding", "expected lhsKind to be lexicalBinding");
(0, _invariant.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) {
let names = _singletons.Environment.BoundNames(realm, lhs); // 1. Assert: lhs binds a single name.
(0, _invariant.default)(names.length === 1, "expected single name"); // 2. Let lhsName be the sole element of BoundNames of lhs.
let lhsName = names[0]; // 3. Let lhsRef be ! ResolveBinding(lhsName).
lhsRef = _singletons.Environment.ResolveBinding(realm, lhsName, strictCode);
}
} // f. If destructuring is false, then
let status;
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, _invariant.default)(lhsRef instanceof _environment.Reference);
status = _singletons.Environment.InitializeReferencedBinding(realm, lhsRef, nextValue);
} else {
// iii. Else,
// 1. Let status be PutValue(lhsRef, nextValue).
(0, _invariant.default)(lhsRef !== undefined);
status = _singletons.Properties.PutValue(realm, lhsRef, nextValue);
}
} else {
// g. Else,
// i. If lhsKind is assignment, then
if (lhsKind === "assignment") {
(0, _invariant.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, _invariant.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, _invariant.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.
let result = env.evaluateCompletion(stmt, strictCode);
(0, _invariant.default)(result instanceof _index.Value || result instanceof _completions.AbruptCompletion); // j. Set the running execution context's LexicalEnvironment to oldEnv.
let 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, _invariant.default)(result instanceof _completions.AbruptCompletion);
result = (0, _index2.UpdateEmpty)(realm, result, V);
(0, _invariant.default)(result instanceof _completions.AbruptCompletion);
throw (0, _index2.IteratorClose)(realm, iterator, result);
} // l. If result.[[Value]] is not empty, let V be result.[[Value]].
let resultValue = InternalGetResultValue(realm, result);
if (!(resultValue instanceof _index.EmptyValue)) V = resultValue;
}
/* istanbul ignore next */
(0, _invariant.default)(false); // can't get here but there is no other way to make Flow happy
} // ECMA262 13.7.5.11
function _default(ast, strictCode, env, realm, labelSet) {
let {
left,
right,
body
} = ast;
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).
let keyResult = ForInOfHeadEvaluation(realm, env, [], right, "iterate", strictCode);
(0, _invariant.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).
let keyResult = ForInOfHeadEvaluation(realm, env, _singletons.Environment.BoundNames(realm, left), right, "iterate", strictCode);
(0, _invariant.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).
let keyResult = ForInOfHeadEvaluation(realm, env, [], right, "iterate", strictCode);
(0, _invariant.default)(keyResult instanceof _index.ObjectValue); // 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet).
return ForInOfBodyEvaluation(realm, env, left, body, keyResult, "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;
}
}
//# sourceMappingURL=ForOfStatement.js.map