"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.GlobalDeclarationInstantiation = GlobalDeclarationInstantiation; exports.default = function (ast, strictCode, env, realm) { strictCode = (0, _strict2.default)(ast); GlobalDeclarationInstantiation(realm, ast, env, strictCode); var val = void 0; var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { for (var _iterator11 = ast.body[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var node = _step11.value; if (node.type !== "FunctionDeclaration") { var res = env.evaluateCompletionDeref(node, strictCode); if (res instanceof _completions.AbruptCompletion) { if (!realm.useAbstractInterpretation) throw res; // We are about the leave this program and this presents a join point where all non exeptional control flows // converge into a single flow using the joined effects as the new state. res = _singletons.Functions.incorporateSavedCompletion(realm, res); // The call to incorporateSavedCompletion above, has taken care of the join because res is abrupt. // What remains to be done is to emit throw statements to the generator. if (res instanceof _completions.JoinedAbruptCompletions) { emitConditionalThrow(res.joinCondition, res.consequent, res.alternate); res = res.value; } else if (res instanceof _completions.ThrowCompletion) { emitThrow(res.value); res = realm.intrinsics.undefined; } else { (0, _invariant2.default)(false); // other kinds of abrupt completions should not get this far } } if (!(res instanceof _index.EmptyValue)) { val = res; } } } } catch (err) { _didIteratorError11 = true; _iteratorError11 = err; } finally { try { if (!_iteratorNormalCompletion11 && _iterator11.return) { _iterator11.return(); } } finally { if (_didIteratorError11) { throw _iteratorError11; } } } var directives = ast.directives; if (!val && directives && directives.length) { var directive = directives[directives.length - 1]; val = env.evaluate(directive, strictCode); (0, _invariant2.default)(val instanceof _index.Value); } // We are about to leave this program and this presents a join point where all control flows // converge into a single flow and the joined effects become the final state. if (val instanceof _index.Value) { val = _singletons.Functions.incorporateSavedCompletion(realm, val); if (val instanceof _completions.PossiblyNormalCompletion) { // There are still some conditional throws to emit and state still has to be joined in. _singletons.Join.stopEffectCaptureJoinApplyAndReturnCompletion(val, new _completions.ReturnCompletion(realm.intrinsics.undefined), realm); // The global state has now been updated to the join of all the flows reaching this join point emitConditionalThrow(val.joinCondition, val.consequent, val.alternate); val = val.value; } } else { // program was empty. Nothing to do. } (0, _invariant2.default)(val === undefined || val instanceof _index.Value); return val || realm.intrinsics.empty; function emitThrow(value) { var generator = realm.generator; (0, _invariant2.default)(generator !== undefined); generator.emitStatement([value], function (_ref) { var _ref2 = _slicedToArray(_ref, 1), argument = _ref2[0]; return t.throwStatement(argument); }); } function emitConditionalThrow(condition, trueBranch, falseBranch) { var generator = realm.generator; (0, _invariant2.default)(generator !== undefined); var _deconstruct = deconstruct(condition, trueBranch, falseBranch), _deconstruct2 = _slicedToArray(_deconstruct, 2), args = _deconstruct2[0], buildfunc = _deconstruct2[1]; generator.emitStatement(args, buildfunc); } function deconstruct(condition, trueBranch, falseBranch) { var targs = void 0; var tfunc = void 0; var fargs = void 0; var ffunc = void 0; if (trueBranch instanceof _completions.JoinedAbruptCompletions) { var _deconstruct3 = deconstruct(trueBranch.joinCondition, trueBranch.consequent, trueBranch.alternate); var _deconstruct4 = _slicedToArray(_deconstruct3, 2); targs = _deconstruct4[0]; tfunc = _deconstruct4[1]; } else if (trueBranch instanceof _completions.ThrowCompletion) { targs = [trueBranch.value]; tfunc = function tfunc(_ref3) { var _ref4 = _slicedToArray(_ref3, 1), argument = _ref4[0]; return t.throwStatement(argument); }; } else { targs = []; tfunc = function tfunc(nodes) { return t.emptyStatement(); }; } if (falseBranch instanceof _completions.JoinedAbruptCompletions) { var _deconstruct5 = deconstruct(falseBranch.joinCondition, falseBranch.consequent, falseBranch.alternate); var _deconstruct6 = _slicedToArray(_deconstruct5, 2); fargs = _deconstruct6[0]; ffunc = _deconstruct6[1]; } else if (falseBranch instanceof _completions.ThrowCompletion) { fargs = [falseBranch.value]; ffunc = function ffunc(_ref5) { var _ref6 = _slicedToArray(_ref5, 1), argument = _ref6[0]; return t.throwStatement(argument); }; } else { fargs = []; ffunc = function ffunc(nodes) { return t.emptyStatement(); }; } var args = [condition].concat(targs).concat(fargs); var func = function func(nodes) { return t.ifStatement(nodes[0], tfunc(nodes.splice(1, targs.length)), ffunc(nodes.splice(targs.length + 1, fargs.length))); }; return [args, func]; } }; var _completions = require("../completions.js"); var _index = require("../values/index.js"); var _environment = require("../environment.js"); var _singletons = require("../singletons.js"); var _strict = require("../utils/strict.js"); var _strict2 = _interopRequireDefault(_strict); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _traverseFast = require("../utils/traverse-fast.js"); var _traverseFast2 = _interopRequireDefault(_traverseFast); 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 }; } // ECMA262 15.1.11 function GlobalDeclarationInstantiation(realm, ast, env, strictCode) { realm.getRunningContext().isStrict = realm.isStrict = strictCode; // 1. Let envRec be env's EnvironmentRecord. var envRec = env.environmentRecord; // 2. Assert: envRec is a global Environment Record. (0, _invariant2.default)(envRec instanceof _environment.GlobalEnvironmentRecord, "expected global environment record"); // 3. Let lexNames be the LexicallyDeclaredNames of script. var lexNames = []; // 4. Let varNames be the VarDeclaredNames of script. var varNames = []; (0, _traverseFast2.default)(ast, function (node) { if (node.type === "VariableDeclaration") { if (node.kind === "var") { varNames = varNames.concat(_singletons.Environment.BoundNames(realm, node)); } else { lexNames = lexNames.concat(_singletons.Environment.BoundNames(realm, node)); } } else if (node.type === "FunctionExpression" || node.type === "FunctionDeclaration") { return true; } return false; }); // 5. For each name in lexNames, do var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = lexNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var name = _step.value; // a. If envRec.HasVarDeclaration(name) is true, throw a SyntaxError exception. if (envRec.HasVarDeclaration(name)) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, name + " already declared with var"); } // b. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError exception. if (envRec.HasLexicalDeclaration(name)) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, name + " already declared with let or const"); } // c. Let hasRestrictedGlobal be ? envRec.HasRestrictedGlobalProperty(name). var hasRestrictedGlobal = envRec.HasRestrictedGlobalProperty(name); // d. If hasRestrictedGlobal is true, throw a SyntaxError exception. if (hasRestrictedGlobal) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, name + " global object is restricted"); } } // 6. For each name in varNames, do } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = varNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _name = _step2.value; // a. If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError exception. if (envRec.HasLexicalDeclaration(_name)) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, _name + " already declared with let or const"); } } // 7. Let varDeclarations be the VarScopedDeclarations of script. } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } var varDeclarations = _singletons.Functions.FindVarScopedDeclarations(ast); // 8. Let functionsToInitialize be a new empty List. var functionsToInitialize = []; // 9. Let declaredFunctionNames be a new empty List. var declaredFunctionNames = []; // 10. For each d in varDeclarations, in reverse list order do var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = varDeclarations.reverse()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var d = _step3.value; // a. If d is neither a VariableDeclaration or a ForBinding, then if (d.type !== "VariableDeclaration") { // i. Assert: d is either a FunctionDeclaration or a GeneratorDeclaration. (0, _invariant2.default)(d.type === "FunctionDeclaration", "expected function"); // ii. NOTE If there are multiple FunctionDeclarations for the same name, the last declaration is used. // iii. Let fn be the sole element of the BoundNames of d. var fn = _singletons.Environment.BoundNames(realm, d)[0]; // iv. If fn is not an element of declaredFunctionNames, then if (declaredFunctionNames.indexOf(fn) < 0) { // 1. Let fnDefinable be ? envRec.CanDeclareGlobalFunction(fn). var fnDefinable = envRec.CanDeclareGlobalFunction(fn); // 2. If fnDefinable is false, throw a TypeError exception. if (!fnDefinable) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, fn + ": global function declarations are not allowed"); } // 3. Append fn to declaredFunctionNames. declaredFunctionNames.push(fn); // 4. Insert d as the first element of functionsToInitialize. functionsToInitialize.unshift(d); } } } // 11. Let declaredVarNames be a new empty List. } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } var declaredVarNames = []; // 12. For each d in varDeclarations, do var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = varDeclarations[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var _d = _step4.value; // a. If d is a VariableDeclaration or a ForBinding, then if (_d.type === "VariableDeclaration") { // i. For each String vn in the BoundNames of d, do var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = _singletons.Environment.BoundNames(realm, _d)[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var _vn = _step9.value; // ii. If vn is not an element of declaredFunctionNames, then if (declaredFunctionNames.indexOf(_vn) < 0) { // 1. Let vnDefinable be ? envRec.CanDeclareGlobalVar(vn). var vnDefinable = envRec.CanDeclareGlobalVar(_vn); // 2. If vnDefinable is false, throw a TypeError exception. if (!vnDefinable) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, _vn + ": global variable declarations are not allowed"); } // 3. If vn is not an element of declaredVarNames, then if (declaredVarNames.indexOf(_vn) < 0) { // a. Append vn to declaredVarNames. declaredVarNames.push(_vn); } } } } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } } } // 13. NOTE: No abnormal terminations occur after this algorithm step if the global object is an ordinary object. However, if the global object is a Proxy exotic object it may exhibit behaviours that cause abnormal terminations in some of the following steps. // 14. NOTE: Annex B.3.3.2 adds additional steps at this point. // 15. Let lexDeclarations be the LexicallyScopedDeclarations of script. } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } var lexDeclarations = []; var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = ast.body[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var s = _step5.value; if (s.type === "VariableDeclaration" && s.kind !== "var") { lexDeclarations.push(s); } } // 16. For each element d in lexDeclarations do } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { for (var _iterator6 = lexDeclarations[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { var _d2 = _step6.value; // a. NOTE Lexically declared names are only instantiated here but not initialized. // b. For each element dn of the BoundNames of d do var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { for (var _iterator10 = _singletons.Environment.BoundNames(realm, _d2)[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { var dn = _step10.value; // i. If IsConstantDeclaration of d is true, then if (_d2.kind === "const") { // 1. Perform ? envRec.CreateImmutableBinding(dn, true). envRec.CreateImmutableBinding(dn, true); } else { // ii. Else, // 1. Perform ? envRec.CreateMutableBinding(dn, false). envRec.CreateMutableBinding(dn, false); } } } catch (err) { _didIteratorError10 = true; _iteratorError10 = err; } finally { try { if (!_iteratorNormalCompletion10 && _iterator10.return) { _iterator10.return(); } } finally { if (_didIteratorError10) { throw _iteratorError10; } } } } // 17. For each production f in functionsToInitialize, do } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = functionsToInitialize[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var f = _step7.value; // a. Let fn be the sole element of the BoundNames of f. var fn = _singletons.Environment.BoundNames(realm, f)[0]; // b. Let fo be the result of performing InstantiateFunctionObject for f with argument env. var fo = env.evaluate(f, strictCode); (0, _invariant2.default)(fo instanceof _index.Value); // c. Perform ? envRec.CreateGlobalFunctionBinding(fn, fo, false). envRec.CreateGlobalFunctionBinding(fn, fo, false); } // 18. For each String vn in declaredVarNames, in list order do } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = declaredVarNames[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var vn = _step8.value; // a. Perform ? envRec.CreateGlobalVarBinding(vn, false). envRec.CreateGlobalVarBinding(vn, false); } // 19. Return NormalCompletion(empty). } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } return realm.intrinsics.empty; } //# sourceMappingURL=Program.js.map