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

275 lines
17 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
* 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.
*/
exports.default = function (ast, strictCode, env, realm, labelSet) {
var left = ast.left,
right = ast.right,
body = ast.body;
function reportErrorAndThrowIfNotConcrete(val, loc) {
if (val instanceof _index2.AbstractValue) reportError(realm, loc);
}
try {
if (left.type === "VariableDeclaration") {
if (left.kind === "var") {
// for (var ForBinding in Expression) Statement
// 1. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
var keyResult = (0, _ForOfStatement.ForInOfHeadEvaluation)(realm, env, [], right, "enumerate", strictCode);
if (keyResult.isPartialObject() && keyResult.isSimpleObject()) {
return emitResidualLoopIfSafe(ast, strictCode, env, realm, left, right, keyResult, body);
}
reportErrorAndThrowIfNotConcrete(keyResult, right.loc);
(0, _invariant2.default)(keyResult instanceof _index2.ObjectValue);
// 2. Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet).
return (0, _ForOfStatement.ForInOfBodyEvaluation)(realm, env, left.declarations[0].id, body, keyResult, "varBinding", labelSet, strictCode);
} else {
// for (ForDeclaration in Expression) Statement
// 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate).
var _keyResult = (0, _ForOfStatement.ForInOfHeadEvaluation)(realm, env, _singletons.Environment.BoundNames(realm, left), right, "enumerate", strictCode);
reportErrorAndThrowIfNotConcrete(_keyResult, right.loc);
(0, _invariant2.default)(_keyResult instanceof _index2.ObjectValue);
// 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet).
return (0, _ForOfStatement.ForInOfBodyEvaluation)(realm, env, left, body, _keyResult, "lexicalBinding", labelSet, strictCode);
}
} else {
// for (LeftHandSideExpression in Expression) Statement
// 1. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
var _keyResult2 = (0, _ForOfStatement.ForInOfHeadEvaluation)(realm, env, [], right, "enumerate", strictCode);
reportErrorAndThrowIfNotConcrete(_keyResult2, right.loc);
(0, _invariant2.default)(_keyResult2 instanceof _index2.ObjectValue);
// 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet).
return (0, _ForOfStatement.ForInOfBodyEvaluation)(realm, env, left, body, _keyResult2, "assignment", labelSet, strictCode);
}
} catch (e) {
if (e instanceof _completions.BreakCompletion) {
if (!e.target) return (0, _index.UpdateEmpty)(realm, e, realm.intrinsics.undefined).value;
}
throw e;
}
};
var _completions = require("../completions.js");
var _environment = require("../environment.js");
var _errors = require("../errors.js");
var _ForOfStatement = require("./ForOfStatement.js");
var _index = require("../methods/index.js");
var _singletons = require("../singletons.js");
var _index2 = require("../values/index.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// helper func to report error
function reportError(realm, loc) {
var error = new _errors.CompilerDiagnostic("for in loops over unknown objects are not yet supported", loc, "PP0013", "FatalError");
realm.handleError(error);
throw new _errors.FatalError();
}
// ECMA262 13.7.5.11
function emitResidualLoopIfSafe(ast, strictCode, env, realm, lh, obexpr, ob, body) {
(0, _invariant2.default)(ob.isSimpleObject());
var oldEnv = realm.getRunningContext().lexicalEnvironment;
var blockEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv);
realm.getRunningContext().lexicalEnvironment = blockEnv;
try {
var envRec = blockEnv.environmentRecord;
(0, _invariant2.default)(envRec instanceof _environment.DeclarativeEnvironmentRecord, "expected declarative environment record");
var absStr = _index2.AbstractValue.createFromType(realm, _index2.StringValue);
var boundName = void 0;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _singletons.Environment.BoundNames(realm, lh)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var n = _step.value;
(0, _invariant2.default)(boundName === undefined);
boundName = t.identifier(n);
envRec.CreateMutableBinding(n, false);
envRec.InitializeBinding(n, absStr);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var _realm$evaluateNodeFo = realm.evaluateNodeForEffects(body, strictCode, blockEnv),
_realm$evaluateNodeFo2 = _slicedToArray(_realm$evaluateNodeFo, 5),
compl = _realm$evaluateNodeFo2[0],
gen = _realm$evaluateNodeFo2[1],
bindings = _realm$evaluateNodeFo2[2],
properties = _realm$evaluateNodeFo2[3],
createdObj = _realm$evaluateNodeFo2[4];
if (compl instanceof _index2.Value && gen.empty() && bindings.size === 0 && properties.size === 1) {
(0, _invariant2.default)(createdObj.size === 0); // or there will be more than one property
var targetObject = void 0;
var sourceObject = void 0;
properties.forEach(function (desc, key, map) {
if (key.object.unknownProperty === key) {
targetObject = key.object;
(0, _invariant2.default)(desc !== undefined);
var sourceValue = desc.value;
if (sourceValue instanceof _index2.AbstractValue) {
// because sourceValue was written to key.object.unknownProperty it must be that
var cond = sourceValue.args[0];
// and because the write always creates a value of this shape
(0, _invariant2.default)(cond instanceof _index2.AbstractValue && cond.kind === "template for property name condition");
if (sourceValue.args[2] instanceof _index2.UndefinedValue) {
// check that the value that was assigned itself came from
// an expression of the form sourceObject[absStr].
var mem = sourceValue.args[1];
while (mem instanceof _index2.AbstractValue) {
if (mem.kind === "sentinel member expression" && mem.args[0] instanceof _index2.ObjectValue && mem.args[1] === absStr) {
sourceObject = mem.args[0];
break;
}
// check if mem is a test for absStr being equal to a known property
// if so skip over it until we get to the expression of the form sourceObject[absStr].
var condition = mem.args[0];
if (condition instanceof _index2.AbstractValue && condition.kind === "check for known property") {
if (condition.args[0] === absStr) {
mem = mem.args[2];
continue;
}
}
break;
}
}
}
}
});
if (targetObject instanceof _index2.ObjectValue && sourceObject !== undefined) {
var o = ob;
if (ob instanceof _index2.AbstractObjectValue && !ob.values.isTop() && ob.values.getElements().size === 1) {
// Note that it is not safe, in general, to extract a concrete object from the values domain of
// an abstract object. We can get away with it here only because the concrete object does not
// escape the code below and is thus never referenced directly in generated code because of this logic.
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = ob.values.getElements()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var oe = _step2.value;
o = oe;
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
var generator = realm.generator;
(0, _invariant2.default)(generator !== undefined);
// make target object simple and partial, so that it returns a fully
// abstract value for every property it is queried for.
targetObject.makeSimple();
targetObject.makePartial();
if (sourceObject === o) {
// Known enumerable properties of sourceObject can become known properties of targetObject.
(0, _invariant2.default)(sourceObject.isPartialObject());
sourceObject.makeNotPartial();
// EnumerableOwnProperties is sufficient because sourceObject is simple
var keyValPairs = (0, _index.EnumerableOwnProperties)(realm, sourceObject, "key+value");
sourceObject.makePartial();
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = keyValPairs[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var keyVal = _step3.value;
(0, _invariant2.default)(keyVal instanceof _index2.ArrayValue);
var key = keyVal.$Get("0", keyVal);
var val = keyVal.$Get("1", keyVal);
(0, _invariant2.default)(key instanceof _index2.StringValue); // sourceObject is simple
targetObject.$Set(key, val, targetObject);
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
}
// add loop to generator
(0, _invariant2.default)(boundName != null);
generator.emitForInStatement(o, lh, sourceObject, targetObject, boundName);
return realm.intrinsics.undefined;
}
}
} finally {
// 6. Set the running execution context's LexicalEnvironment to oldEnv.
realm.getRunningContext().lexicalEnvironment = oldEnv;
realm.onDestroyScope(blockEnv);
}
reportError(realm, obexpr.loc);
(0, _invariant2.default)(false);
}
//# sourceMappingURL=ForInStatement.js.map