"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FunctionImplementation = undefined; 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"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof 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. */ var _errors = require("../errors.js"); var _completions = require("../completions.js"); var _realm = require("../realm.js"); var _environment = require("../environment.js"); var _index = require("../values/index.js"); var _call = require("./call.js"); var _abstract = require("../methods/abstract.js"); var _construct = require("../methods/construct.js"); var _index2 = require("../methods/index.js"); var _iterator32 = require("../methods/iterator.js"); var _ObjectExpression = require("../evaluators/ObjectExpression.js"); var _singletons = require("../singletons.js"); var _traverseFast = require("../utils/traverse-fast.js"); var _traverseFast2 = _interopRequireDefault(_traverseFast); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _parse = require("../utils/parse.js"); var _parse2 = _interopRequireDefault(_parse); var _strict = require("../utils/strict.js"); var _strict2 = _interopRequireDefault(_strict); 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 }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function InternalCall(realm, F, thisArgument, argsList, tracerIndex) { // 1. Assert: F is an ECMAScript function object. (0, _invariant2.default)(F instanceof _index.FunctionValue, "expected function value"); // Tracing: Give all registered tracers a chance to detour, wrapping around each other if needed. var _loop = function _loop() { var tracer = realm.tracers[tracerIndex]; var nextIndex = ++tracerIndex; var detourResult = tracer.detourCall(F, thisArgument, argsList, undefined, function () { return InternalCall(realm, F, thisArgument, argsList, nextIndex); }); if (detourResult instanceof _index.Value) return { v: detourResult }; }; while (tracerIndex < realm.tracers.length) { var _ret = _loop(); if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v; } // 2. If F's [[FunctionKind]] internal slot is "classConstructor", throw a TypeError exception. if (F.$FunctionKind === "classConstructor") throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "not callable"); // 3. Let callerContext be the running execution context. var callerContext = realm.getRunningContext(); // 4. Let calleeContext be PrepareForOrdinaryCall(F, undefined). var calleeContext = (0, _call.PrepareForOrdinaryCall)(realm, F, undefined); var calleeEnv = calleeContext.lexicalEnvironment; var result = void 0; try { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = realm.tracers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var t1 = _step.value; t1.beforeCall(F, thisArgument, argsList, undefined); } // 5. Assert: calleeContext is now the running execution context. } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } (0, _invariant2.default)(realm.getRunningContext() === calleeContext, "calleeContext should be current execution context"); // 6. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument). (0, _call.OrdinaryCallBindThis)(realm, F, calleeContext, thisArgument); // 7. Let result be OrdinaryCallEvaluateBody(F, argumentsList). result = (0, _call.OrdinaryCallEvaluateBody)(realm, F, argsList); } finally { // 8. Remove calleeContext from the execution context stack and restore callerContext as the running execution context. realm.popContext(calleeContext); realm.onDestroyScope(calleeContext.lexicalEnvironment); if (calleeContext.lexicalEnvironment !== calleeEnv) realm.onDestroyScope(calleeEnv); (0, _invariant2.default)(realm.getRunningContext() === callerContext); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = realm.tracers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var t2 = _step2.value; t2.afterCall(F, thisArgument, argsList, undefined, result); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } // 9. If result.[[Type]] is return, return NormalCompletion(result.[[Value]]). if (result instanceof _completions.ReturnCompletion) { return result.value; } if (result instanceof _completions.JoinedAbruptCompletions) { result = _singletons.Join.joinAndRemoveNestedReturnCompletions(realm, result); } // 10. ReturnIfAbrupt(result). or if possibly abrupt if (result instanceof _completions.Completion) { throw result; } // 11. Return NormalCompletion(undefined). return realm.intrinsics.undefined; } // ECMA262 9.4.1.1 function $BoundCall(realm, F, thisArgument, argumentsList) { // 1. Let target be the value of F's [[BoundTargetFunction]] internal slot. var target = F.$BoundTargetFunction; // 2. Let boundThis be the value of F's [[BoundThis]] internal slot. var boundThis = F.$BoundThis; // 3. Let boundArgs be the value of F's [[BoundArguments]] internal slot. var boundArgs = F.$BoundArguments; // 4. Let args be a new list containing the same values as the list boundArgs in the same order followed // by the same values as the list argumentsList in the same order. var args = boundArgs.concat(argumentsList); // 5. Return ? Call(target, boundThis, args). return (0, _call.Call)(realm, target, boundThis, args); } // ECMA262 9.4.1.2 function $BoundConstruct(realm, F, argumentsList, newTarget) { // 1. Let target be the value of F's [[BoundTargetFunction]] internal slot. var target = F.$BoundTargetFunction; // 2. Assert: target has a [[Construct]] internal method. (0, _invariant2.default)(target.$Construct !== undefined, "doesn't have a construct internal method"); // 3. Let boundArgs be the value of F's [[BoundArguments]] internal slot. var boundArgs = F.$BoundArguments; // 4. Let args be a new list containing the same values as the list boundArgs in the same order followed // by the same values as the list argumentsList in the same order. var args = boundArgs.concat(argumentsList); // 5. If SameValue(F, newTarget) is true, let newTarget be target. if ((0, _abstract.SameValue)(realm, F, newTarget)) newTarget = target; // 6. Return ? Construct(target, args, newTarget). return (0, _construct.Construct)(realm, target, args, newTarget); } function InternalConstruct(realm, F, argumentsList, newTarget, thisArgument, tracerIndex) { // 1. Assert: F is an ECMAScript function object. (0, _invariant2.default)(F instanceof _index.FunctionValue, "expected function"); // 2. Assert: Type(newTarget) is Object. (0, _invariant2.default)(newTarget instanceof _index.ObjectValue, "expected object"); if (!realm.hasRunningContext()) { (0, _invariant2.default)(realm.useAbstractInterpretation); throw new _errors.FatalError("no running context"); } // 3. Let callerContext be the running execution context. var callerContext = realm.getRunningContext(); // 4. Let kind be F's [[ConstructorKind]] internal slot. var kind = F.$ConstructorKind; // 5. If kind is "base", then if (thisArgument === undefined && kind === "base") { // a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%"). thisArgument = _singletons.Create.OrdinaryCreateFromConstructor(realm, newTarget, "ObjectPrototype"); } // Tracing: Give all registered tracers a chance to detour, wrapping around each other if needed. var _loop2 = function _loop2() { var tracer = realm.tracers[tracerIndex]; var nextIndex = ++tracerIndex; var detourResult = tracer.detourCall(F, thisArgument, argumentsList, newTarget, function () { return InternalConstruct(realm, F, argumentsList, newTarget, thisArgument, nextIndex); }); if (detourResult instanceof _index.ObjectValue) return { v: detourResult }; (0, _invariant2.default)(detourResult === undefined); }; while (tracerIndex < realm.tracers.length) { var _ret2 = _loop2(); if ((typeof _ret2 === "undefined" ? "undefined" : _typeof(_ret2)) === "object") return _ret2.v; } // 6. Let calleeContext be PrepareForOrdinaryCall(F, newTarget). var calleeContext = (0, _call.PrepareForOrdinaryCall)(realm, F, newTarget); var calleeEnv = calleeContext.lexicalEnvironment; // 7. Assert: calleeContext is now the running execution context. (0, _invariant2.default)(realm.getRunningContext() === calleeContext, "expected calleeContext to be running context"); var result = void 0, envRec = void 0; try { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = realm.tracers[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var t1 = _step3.value; t1.beforeCall(F, thisArgument, argumentsList, newTarget); } // 8. If kind is "base", perform OrdinaryCallBindThis(F, calleeContext, thisArgument). } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } if (kind === "base") { (0, _invariant2.default)(thisArgument, "this wasn't initialized for some reason"); (0, _call.OrdinaryCallBindThis)(realm, F, calleeContext, thisArgument); } // 9. Let constructorEnv be the LexicalEnvironment of calleeContext. var constructorEnv = calleeContext.lexicalEnvironment; // 10. Let envRec be constructorEnv's EnvironmentRecord. envRec = constructorEnv.environmentRecord; // 11. Let result be OrdinaryCallEvaluateBody(F, argumentsList). result = (0, _call.OrdinaryCallEvaluateBody)(realm, F, argumentsList); } finally { // 12. Remove calleeContext from the execution context stack and restore callerContext as the running execution context. realm.popContext(calleeContext); realm.onDestroyScope(calleeContext.lexicalEnvironment); if (calleeContext.lexicalEnvironment !== calleeEnv) realm.onDestroyScope(calleeEnv); (0, _invariant2.default)(realm.getRunningContext() === callerContext); var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = realm.tracers[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var t2 = _step4.value; t2.afterCall(F, thisArgument, argumentsList, newTarget, result); } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } // 13. If result.[[Type]] is return, then if (result instanceof _completions.ReturnCompletion) { // a. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]). if (result.value.mightBeObject()) { return result.value.throwIfNotConcreteObject(); } // b. If kind is "base", return NormalCompletion(thisArgument). if (kind === "base") { (0, _invariant2.default)(thisArgument, "this wasn't initialized for some reason"); return thisArgument; } // c. If result.[[Value]] is not undefined, throw a TypeError exception. if (!result.value.mightBeUndefined()) throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "constructor must return Object"); result.value.throwIfNotConcrete(); } else if (result instanceof _completions.AbruptCompletion) { // 14. Else, ReturnIfAbrupt(result). throw result; } // 15. Return ? envRec.GetThisBinding(). var envRecThisBinding = envRec.GetThisBinding(); (0, _invariant2.default)(envRecThisBinding instanceof _index.ObjectValue); return envRecThisBinding; } var FunctionImplementation = exports.FunctionImplementation = function () { function FunctionImplementation() { _classCallCheck(this, FunctionImplementation); } _createClass(FunctionImplementation, [{ key: "FindVarScopedDeclarations", value: function FindVarScopedDeclarations(ast_node) { function FindVarScopedDeclarationsFor(ast, level) { var statements = []; switch (ast.type) { case "Program": statements = ast.body; break; case "BlockStatement": statements = ast.body; break; case "DoWhileStatement": statements = [ast.body]; break; case "WhileStatement": statements = [ast.body]; break; case "IfStatement": var astIfStatement = ast; statements = [astIfStatement.consequent, astIfStatement.alternate]; break; case "ForStatement": var astForStatement = ast; statements = [astForStatement.init, astForStatement.body]; break; case "ForInStatement": var astForInStatement = ast; statements = [astForInStatement.left, astForInStatement.body]; break; case "ForOfStatement": var astForOfStatement = ast; statements = [astForOfStatement.left, astForOfStatement.body]; break; case "LabeledStatement": statements = [ast.body]; break; case "WithStatement": statements = [ast.body]; break; case "SwitchStatement": var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = ast.cases[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var switchCase = _step5.value; statements = statements.concat(switchCase.consequent); } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } break; case "TryStatement": var astTryStatement = ast; statements = [astTryStatement.block]; if (astTryStatement.finalizer) statements.push(astTryStatement.finalizer); if (astTryStatement.handler) statements.push(astTryStatement.handler.body); break; case "VariableDeclaration": return ast.kind === "var" ? [ast] : []; case "FunctionDeclaration": return level < 2 ? [ast] : []; default: return []; } var decls = []; var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { for (var _iterator6 = statements[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { var statement = _step6.value; if (statement) { decls = decls.concat(FindVarScopedDeclarationsFor(statement, level + 1)); } } } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } return decls; } return FindVarScopedDeclarationsFor(ast_node, 0); } // ECMA262 9.2.12 }, { key: "FunctionDeclarationInstantiation", value: function FunctionDeclarationInstantiation(realm, func, argumentsList) { // 1. Let calleeContext be the running execution context. var calleeContext = realm.getRunningContext(); // 2. Let env be the LexicalEnvironment of calleeContext. var env = calleeContext.lexicalEnvironment; // 3. Let envRec be env's EnvironmentRecord. var envRec = env.environmentRecord; // 4. Let code be the value of the [[ECMAScriptCode]] internal slot of func. var code = func.$ECMAScriptCode; (0, _invariant2.default)(code !== undefined); // 5. Let strict be the value of the [[Strict]] internal slot of func. var strict = func.$Strict; // 6. Let formals be the value of the [[FormalParameters]] internal slot of func. var formals = func.$FormalParameters; (0, _invariant2.default)(formals !== undefined); // 7. Let parameterNames be the BoundNames of formals. var parameterNames = Object.create(null); var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = formals[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var param = _step7.value; var paramBindings = t.getBindingIdentifiers(param, true); for (var _name in paramBindings) { parameterNames[_name] = (parameterNames[_name] || []).concat(paramBindings[_name]); } } // 8. If parameterNames has any duplicate entries, let hasDuplicates be true. Otherwise, let hasDuplicates be false. } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } var hasDuplicates = false; for (var name in parameterNames) { var identifiers = parameterNames[name]; if (identifiers.length > 1) hasDuplicates = true; } parameterNames = Object.keys(parameterNames); // 9. Let simpleParameterList be IsSimpleParameterList of formals. var simpleParameterList = true; var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = formals[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var _param = _step8.value; if (_param.type !== "Identifier") { simpleParameterList = false; break; } } // 10. Let hasParameterExpressions be ContainsExpression of formals. } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } var hasParameterExpressions = false; (0, _invariant2.default)(formals !== undefined); var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = formals[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var _param2 = _step9.value; if (_singletons.Environment.ContainsExpression(realm, _param2)) { hasParameterExpressions = true; break; } } // 11. Let varNames be the VarDeclaredNames of code. } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } var varNames = []; (0, _traverseFast2.default)(code, function (node) { if (node.type === "VariableDeclaration" && node.kind === "var") { varNames = varNames.concat(Object.keys(t.getBindingIdentifiers(node))); } if (node.type === "FunctionExpression" || node.type === "FunctionDeclaration") { return true; } return false; }); // 12. Let varDeclarations be the VarScopedDeclarations of code. var varDeclarations = this.FindVarScopedDeclarations(code); // 13. Let lexicalNames be the LexicallyDeclaredNames of code. var lexicalNames = []; // 14. Let functionNames be an empty List. var functionNames = []; // 15. Let functionsToInitialize be an empty List. var functionsToInitialize = []; // 16. For each d in varDeclarations, in reverse list order do var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { for (var _iterator10 = varDeclarations.reverse()[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { var d = _step10.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" || d.type === "GeneratorDeclaration"); // ii. Let fn be the sole element of the BoundNames of d. var fn = _singletons.Environment.BoundNames(realm, d)[0]; // iii. If fn is not an element of functionNames, then if (functionNames.indexOf(fn) < 0) { // 1. Insert fn as the first element of functionNames. functionNames.unshift(fn); // 2. NOTE If there are multiple FunctionDeclarations or GeneratorDeclarations for the same name, the last declaration is used. // 3. Insert d as the first element of functionsToInitialize. functionsToInitialize.unshift(d); } } } // 17. Let argumentsObjectNeeded be true. } catch (err) { _didIteratorError10 = true; _iteratorError10 = err; } finally { try { if (!_iteratorNormalCompletion10 && _iterator10.return) { _iterator10.return(); } } finally { if (_didIteratorError10) { throw _iteratorError10; } } } var argumentsObjectNeeded = true; // 18. If the value of the [[realmMode]] internal slot of func is lexical, then if (func.$ThisMode === "lexical") { // a. NOTE Arrow functions never have an arguments objects. // b. Let argumentsObjectNeeded be false. argumentsObjectNeeded = false; } else if (parameterNames.indexOf("arguments") >= 0) { // 19. Else if "arguments" is an element of parameterNames, then // a. Let argumentsObjectNeeded be false. argumentsObjectNeeded = false; } else if (hasParameterExpressions === false) { // 20. Else if hasParameterExpressions is false, then // a. If "arguments" is an element of functionNames or if "arguments" is an element of lexicalNames, then if (functionNames.indexOf("arguments") >= 0 || lexicalNames.indexOf("arguments") >= 0) { // i. Let argumentsObjectNeeded be false. argumentsObjectNeeded = true; } } // 21. For each String paramName in parameterNames, do var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { for (var _iterator11 = parameterNames[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var paramName = _step11.value; // a. Let alreadyDeclared be envRec.HasBinding(paramName). var alreadyDeclared = envRec.HasBinding(paramName); // b. NOTE Early errors ensure that duplicate parameter names can only occur in non-strict functions that do not have parameter default values or rest parameters. // c. If alreadyDeclared is false, then if (alreadyDeclared === false) { // i. Perform ! envRec.CreateMutableBinding(paramName, false). envRec.CreateMutableBinding(paramName, false); // ii. If hasDuplicates is true, then if (hasDuplicates === true) { // 1. Perform ! envRec.InitializeBinding(paramName, undefined). envRec.InitializeBinding(paramName, realm.intrinsics.undefined); } } } // 22. If argumentsObjectNeeded is true, then } catch (err) { _didIteratorError11 = true; _iteratorError11 = err; } finally { try { if (!_iteratorNormalCompletion11 && _iterator11.return) { _iterator11.return(); } } finally { if (_didIteratorError11) { throw _iteratorError11; } } } if (argumentsObjectNeeded === true) { var ao = void 0; // a. If strict is true or if simpleParameterList is false, then if (strict === true || simpleParameterList === false) { // i. Let ao be CreateUnmappedArgumentsObject(argumentsList). ao = _singletons.Create.CreateUnmappedArgumentsObject(realm, argumentsList); } else { // b. Else, // i. NOTE mapped argument object is only provided for non-strict functions that don't have a rest parameter, any parameter default value initializers, or any destructured parameters. // ii. Let ao be CreateMappedArgumentsObject(func, formals, argumentsList, envRec). (0, _invariant2.default)(formals !== undefined); ao = _singletons.Create.CreateMappedArgumentsObject(realm, func, formals, argumentsList, envRec); } // c. If strict is true, then if (strict === true) { // i. Perform ! envRec.CreateImmutableBinding("arguments", false). envRec.CreateImmutableBinding("arguments", false); } else { // d. Else, // i. Perform ! envRec.CreateMutableBinding("arguments", false). envRec.CreateMutableBinding("arguments", false); } // e. Call envRec.InitializeBinding("arguments", ao). envRec.InitializeBinding("arguments", ao); // f. Append "arguments" to parameterNames. parameterNames.push("arguments"); } // 23. Let iteratorRecord be Record {[[Iterator]]: CreateListIterator(argumentsList), [[Done]]: false}. var iteratorRecord = { $Iterator: (0, _iterator32.CreateListIterator)(realm, argumentsList), $Done: false }; // 24. If hasDuplicates is true, then if (hasDuplicates === true) { // a. Perform ? IteratorBindingInitialization for formals with iteratorRecord and undefined as arguments. (0, _invariant2.default)(formals !== undefined); _singletons.Environment.IteratorBindingInitialization(realm, formals, iteratorRecord, strict); } else { // 25. Else, // a. Perform ? IteratorBindingInitialization for formals with iteratorRecord and env as arguments. (0, _invariant2.default)(formals !== undefined); _singletons.Environment.IteratorBindingInitialization(realm, formals, iteratorRecord, strict, env); } // 26. If hasParameterExpressions is false, then var varEnv = void 0, varEnvRec = void 0; if (hasParameterExpressions === false) { // a. NOTE Only a single lexical environment is needed for the parameters and top-level vars. // b. Let instantiatedVarNames be a copy of the List parameterNames. var instantiatedVarNames = parameterNames.slice(); // c. For each n in varNames, do var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { for (var _iterator12 = varNames[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { var n = _step12.value; // i. If n is not an element of instantiatedVarNames, then if (instantiatedVarNames.indexOf(n) < 0) { // 1. Append n to instantiatedVarNames. instantiatedVarNames.push(n); // 2. Perform ! envRec.CreateMutableBinding(n, false). envRec.CreateMutableBinding(n, false); // 3. Call envRec.InitializeBinding(n, undefined). envRec.InitializeBinding(n, realm.intrinsics.undefined); } } // e. Let varEnv be env. } catch (err) { _didIteratorError12 = true; _iteratorError12 = err; } finally { try { if (!_iteratorNormalCompletion12 && _iterator12.return) { _iterator12.return(); } } finally { if (_didIteratorError12) { throw _iteratorError12; } } } varEnv = env; // f. Let varEnvRec be envRec. varEnvRec = envRec; } else { // 27. Else, // a. NOTE A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. // b. Let varEnv be NewDeclarativeEnvironment(env). varEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, env); // At this point we haven't set any context's lexical environment to varEnv (and we might never do so), // so it shouldn't be active realm.activeLexicalEnvironments.delete(varEnv); // c. Let varEnvRec be varEnv's EnvironmentRecord. varEnvRec = varEnv.environmentRecord; // d. Set the VariableEnvironment of calleeContext to varEnv. calleeContext.variableEnvironment = varEnv; // e. Let instantiatedVarNames be a new empty List. var _instantiatedVarNames = []; // f. For each n in varNames, do var _iteratorNormalCompletion13 = true; var _didIteratorError13 = false; var _iteratorError13 = undefined; try { for (var _iterator13 = varNames[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { var _n = _step13.value; // i. If n is not an element of instantiatedVarNames, then if (_instantiatedVarNames.indexOf(_n) < 0) { // 1. Append n to instantiatedVarNames. _instantiatedVarNames.push(_n); // 2. Perform ! varEnvRec.CreateMutableBinding(n, false). varEnvRec.CreateMutableBinding(_n, false); // 3. If n is not an element of parameterNames or if n is an element of functionNames, let initialValue be undefined. var initialValue = void 0; if (parameterNames.indexOf(_n) < 0 || functionNames.indexOf(_n) < 0) { initialValue = realm.intrinsics.undefined; } else { // 4. Else, // a. Let initialValue be ! envRec.GetBindingValue(n, false). initialValue = envRec.GetBindingValue(_n, false); } // 5. Call varEnvRec.InitializeBinding(n, initialValue). varEnvRec.InitializeBinding(_n, initialValue); // 6. NOTE vars whose names are the same as a formal parameter, initially have the same value as the corresponding initialized parameter. } } } catch (err) { _didIteratorError13 = true; _iteratorError13 = err; } finally { try { if (!_iteratorNormalCompletion13 && _iterator13.return) { _iterator13.return(); } } finally { if (_didIteratorError13) { throw _iteratorError13; } } } } // 28. NOTE: Annex B.3.3.1 adds additional steps at realm point. var lexEnv = void 0; // 29. If strict is false, then if (strict === false) { // a. Let lexEnv be NewDeclarativeEnvironment(varEnv). lexEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, varEnv); // b. NOTE: Non-strict functions use a separate lexical Environment Record for top-level lexical declarations so that a direct eval (see 12.3.4.1) can determine whether any var scoped declarations introduced by the eval code conflict with pre-existing top-level lexically scoped declarations. realm is not needed for strict functions because a strict direct eval always places all declarations into a new Environment Record. } else { // 30. Else, let lexEnv be varEnv. lexEnv = varEnv; // Since we previously removed varEnv, make sure to re-add it when it's used. realm.activeLexicalEnvironments.add(varEnv); } // 31. Let lexEnvRec be lexEnv's EnvironmentRecord. var lexEnvRec = lexEnv.environmentRecord; // 32. Set the LexicalEnvironment of calleeContext to lexEnv. calleeContext.lexicalEnvironment = lexEnv; // 33. Let lexDeclarations be the LexicallyScopedDeclarations of code. var lexDeclarations = []; // 34. For each element d in lexDeclarations do var _iteratorNormalCompletion14 = true; var _didIteratorError14 = false; var _iteratorError14 = undefined; try { for (var _iterator14 = lexDeclarations[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { var _d = _step14.value; // a. NOTE A lexically declared name cannot be the same as a function/generator declaration, formal parameter, or a var name. Lexically declared names are only instantiated here but not initialized. // b. For each element dn of the BoundNames of d do var _iteratorNormalCompletion16 = true; var _didIteratorError16 = false; var _iteratorError16 = undefined; try { for (var _iterator16 = _singletons.Environment.BoundNames(realm, _d)[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { var dn = _step16.value; // i. If IsConstantDeclaration of d is true, then if (_d.kind === "const") { // 1. Perform ! lexEnvRec.CreateImmutableBinding(dn, true). lexEnvRec.CreateImmutableBinding(dn, true); } else { // ii. Else, // 1. Perform ! lexEnvRec.CreateMutableBinding(dn, false). lexEnvRec.CreateMutableBinding(dn, false); } } } catch (err) { _didIteratorError16 = true; _iteratorError16 = err; } finally { try { if (!_iteratorNormalCompletion16 && _iterator16.return) { _iterator16.return(); } } finally { if (_didIteratorError16) { throw _iteratorError16; } } } } // 35. For each parsed grammar phrase f in functionsToInitialize, do } catch (err) { _didIteratorError14 = true; _iteratorError14 = err; } finally { try { if (!_iteratorNormalCompletion14 && _iterator14.return) { _iterator14.return(); } } finally { if (_didIteratorError14) { throw _iteratorError14; } } } var _iteratorNormalCompletion15 = true; var _didIteratorError15 = false; var _iteratorError15 = undefined; try { for (var _iterator15 = functionsToInitialize[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { var f = _step15.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 lexEnv. var fo = lexEnv.evaluate(f, strict); (0, _invariant2.default)(fo instanceof _index.Value); // c. Perform ! varEnvRec.SetMutableBinding(fn, fo, false). varEnvRec.SetMutableBinding(fn, fo, false); } // 36. Return NormalCompletion(empty). } catch (err) { _didIteratorError15 = true; _iteratorError15 = err; } finally { try { if (!_iteratorNormalCompletion15 && _iterator15.return) { _iterator15.return(); } } finally { if (_didIteratorError15) { throw _iteratorError15; } } } return realm.intrinsics.empty; } // ECMA262 9.2.11 }, { key: "SetFunctionName", value: function SetFunctionName(realm, F, name, prefix) { // 1. Assert: F is an extensible object that does not have a name own property. (0, _invariant2.default)(F.getExtensible(), "expected object to be extensible and not have a name property"); // 2. Assert: Type(name) is either Symbol or String. (0, _invariant2.default)(typeof name === "string" || name instanceof _index.StringValue || name instanceof _index.SymbolValue || name instanceof _index.AbstractValue, "expected name to be a string or symbol"); if (typeof name === "string") name = new _index.StringValue(realm, name); // 3. Assert: If prefix was passed, then Type(prefix) is String. (0, _invariant2.default)(prefix === undefined || typeof prefix === "string", "expected prefix to be a string if passed"); // 4. If Type(name) is Symbol, then if (name instanceof _index.SymbolValue) { // a. Let description be name's [[Description]] value. var description = name.$Description; // b. If description is undefined, let name be the empty String. if (description === undefined) { name = realm.intrinsics.emptyString; } else { // c. Else, let name be the concatenation of "[", description, and "]". (0, _invariant2.default)(description instanceof _index.Value); name = new _index.StringValue(realm, "[" + description.throwIfNotConcreteString().value + "]"); } } // 5. If prefix was passed, then if (prefix) { // a. Let name be the concatenation of prefix, code unit 0x0020 (SPACE), and name. if (name instanceof _index.AbstractValue) { var prefixVal = new _index.StringValue(realm, prefix + " "); name = _index.AbstractValue.createFromBinaryOp(realm, "+", prefixVal, name, name.expressionLocation); } else { name = new _index.StringValue(realm, prefix + " " + name.value); } } // 6. Return ! DefinePropertyOrThrow(F, "name", PropertyDescriptor{[[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}). return _singletons.Properties.DefinePropertyOrThrow(realm, F, "name", { value: name, enumerable: false, writable: false, configurable: true }); } // ECMA262 9.2.3 }, { key: "FunctionInitialize", value: function FunctionInitialize(realm, F, kind, ParameterList, Body, Scope) { // Note that F is a new object, and we can thus write to internal slots (0, _invariant2.default)(realm.isNewObject(F)); // 1. Assert: F is an extensible object that does not have a length own property. (0, _invariant2.default)(F.getExtensible(), "expected to be extensible and no length property"); // 2. Let len be the ExpectedArgumentCount of ParameterList. var len = 0; var _iteratorNormalCompletion17 = true; var _didIteratorError17 = false; var _iteratorError17 = undefined; try { for (var _iterator17 = ParameterList[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { var FormalParameter = _step17.value; if (FormalParameter.type === "AssignmentPattern") { break; } len += 1; } // 3. Perform ! DefinePropertyOrThrow(F, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}). } catch (err) { _didIteratorError17 = true; _iteratorError17 = err; } finally { try { if (!_iteratorNormalCompletion17 && _iterator17.return) { _iterator17.return(); } } finally { if (_didIteratorError17) { throw _iteratorError17; } } } _singletons.Properties.DefinePropertyOrThrow(realm, F, "length", { value: new _index.NumberValue(realm, len), writable: false, enumerable: false, configurable: true }); // 4. Let Strict be the value of the [[Strict]] internal slot of F. var Strict = F.$Strict; if (!Strict) { _singletons.Properties.DefinePropertyOrThrow(realm, F, "caller", { value: new _index.UndefinedValue(realm), writable: true, enumerable: false, configurable: true }); } // 5. Set the [[Environment]] internal slot of F to the value of Scope. F.$Environment = Scope; // 6. Set the [[FormalParameters]] internal slot of F to ParameterList. F.$FormalParameters = ParameterList; // 7. Set the [[ECMAScriptCode]] internal slot of F to Body. Body.uniqueOrderedTag = realm.functionBodyUniqueTagSeed++; F.$ECMAScriptCode = Body; // 8. Set the [[ScriptOrModule]] internal slot of F to GetActiveScriptOrModule(). F.$ScriptOrModule = _singletons.Environment.GetActiveScriptOrModule(realm); // 9. If kind is Arrow, set the [[realmMode]] internal slot of F to lexical. if (kind === "arrow") { F.$ThisMode = "lexical"; } else if (Strict === true) { // 10. Else if Strict is true, set the [[realmMode]] internal slot of F to strict. F.$ThisMode = "strict"; } else { // 11. Else set the [[realmMode]] internal slot of F to global. F.$ThisMode = "global"; } // Return F. return F; } // ECMA262 9.2.6 }, { key: "GeneratorFunctionCreate", value: function GeneratorFunctionCreate(realm, kind, ParameterList, Body, Scope, Strict) { // 1. Let functionPrototype be the intrinsic object %Generator%. var functionPrototype = realm.intrinsics.Generator; // 2. Let F be FunctionAllocate(functionPrototype, Strict, "generator"). var F = this.FunctionAllocate(realm, functionPrototype, Strict, "generator"); // 3. Return FunctionInitialize(F, kind, ParameterList, Body, Scope). return this.FunctionInitialize(realm, F, kind, ParameterList, Body, Scope); } // ECMA262 9.2.7 }, { key: "AddRestrictedFunctionProperties", value: function AddRestrictedFunctionProperties(F, realm) { // 1. Assert: realm.[[Intrinsics]].[[%ThrowTypeError%]] exists and has been initialized. // 2. Let thrower be realm.[[Intrinsics]].[[%ThrowTypeError%]]. var thrower = realm.intrinsics.ThrowTypeError; (0, _invariant2.default)(thrower); var desc = { get: thrower, set: thrower, enumerable: false, configurable: true }; // 3. Perform ! DefinePropertyOrThrow(F, "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true}). _singletons.Properties.DefinePropertyOrThrow(realm, F, "caller", desc); // 4. Return ! DefinePropertyOrThrow(F, "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true}). return _singletons.Properties.DefinePropertyOrThrow(realm, F, "arguments", desc); } // ECMA262 9.2.1 }, { key: "$Call", value: function $Call(realm, F, thisArgument, argsList) { return InternalCall(realm, F, thisArgument, argsList, 0); } // ECMA262 9.2.2 }, { key: "$Construct", value: function $Construct(realm, F, argumentsList, newTarget) { return InternalConstruct(realm, F, argumentsList, newTarget, undefined, 0); } // ECMA262 9.2.3 }, { key: "FunctionAllocate", value: function FunctionAllocate(realm, functionPrototype, strict, functionKind) { var _this = this; // 1. Assert: Type(functionPrototype) is Object. (0, _invariant2.default)(functionPrototype instanceof _index.ObjectValue, "expected functionPrototype to be an object"); // 2. Assert: functionKind is either "normal", "non-constructor" or "generator". (0, _invariant2.default)(functionKind === "normal" || functionKind === "non-constructor" || functionKind === "generator", "invalid functionKind"); // 3. If functionKind is "normal", let needsConstruct be true. var needsConstruct = void 0; if (functionKind === "normal") { needsConstruct = true; } else { // 4. Else, let needsConstruct be false. needsConstruct = false; } // 5. If functionKind is "non-constructor", let functionKind be "normal". if (functionKind === "non-constructor") { functionKind = "normal"; } // 6. Let F be a newly created ECMAScript function object with the internal slots listed in Table 27. All of those internal slots are initialized to undefined. var F = new _index.ECMAScriptSourceFunctionValue(realm); // 7. Set F's essential internal methods to the default ordinary object definitions specified in 9.1. // 8. Set F's [[Call]] internal method to the definition specified in 9.2.1. F.$Call = function (thisArgument, argsList) { return _this.$Call(realm, F, thisArgument, argsList); }; // 9. If needsConstruct is true, then if (needsConstruct === true) { // a. Set F's [[Construct]] internal method to the definition specified in 9.2.2. F.$Construct = function (argumentsList, newTarget) { return _this.$Construct(realm, F, argumentsList, newTarget); }; // b. Set the [[ConstructorKind]] internal slot of F to "base". F.$ConstructorKind = "base"; } // 10. Set the [[Strict]] internal slot of F to strict. F.$Strict = strict; // 11. Set the [[FunctionKind]] internal slot of F to functionKind. F.$FunctionKind = functionKind; // 12. Set the [[Prototype]] internal slot of F to functionPrototype. F.$Prototype = functionPrototype; // 13. Set the [[Extensible]] internal slot of F to true. F.setExtensible(true); // 14. Set the [[Realm]] internal slot of F to the current Realm Record. F.$Realm = realm; // 15. Return F. return F; } // ECMA262 9.4.1.3 }, { key: "BoundFunctionCreate", value: function BoundFunctionCreate(realm, targetFunction, boundThis, boundArgs) { // 1. Assert: Type(targetFunction) is Object. (0, _invariant2.default)(targetFunction instanceof _index.ObjectValue, "expected an object"); // 2. Let proto be ? targetFunction.[[GetPrototypeOf]](). var proto = targetFunction.$GetPrototypeOf(); // 3. Let obj be a newly created object. var obj = new _index.BoundFunctionValue(realm); // 4. Set obj's essential internal methods to the default ordinary object definitions specified in 9.1. // 5. Set the [[Call]] internal method of obj as described in 9.4.1.1. obj.$Call = function (thisArgument, argsList) { return $BoundCall(realm, obj, thisArgument, argsList); }; // 6. If targetFunction has a [[Construct]] internal method, then if (targetFunction.$Construct) { // a. Set the [[Construct]] internal method of obj as described in 9.4.1.2. obj.$Construct = function (thisArgument, argsList) { return $BoundConstruct(realm, obj, thisArgument, argsList); }; } // 7. Set the [[Prototype]] internal slot of obj to proto. obj.$Prototype = proto; // 8. Set the [[Extensible]] internal slot of obj to true. obj.setExtensible(true); // 9. Set the [[BoundTargetFunction]] internal slot of obj to targetFunction. obj.$BoundTargetFunction = targetFunction; // 10. Set the [[BoundThis]] internal slot of obj to the value of boundThis. obj.$BoundThis = boundThis; // 11. Set the [[BoundArguments]] internal slot of obj to boundArgs. obj.$BoundArguments = boundArgs; // 12. Return obj. return obj; } // ECMA262 18.2.1.1 }, { key: "PerformEval", value: function PerformEval(realm, x, evalRealm, strictCaller, direct) { // 1. Assert: If direct is false, then strictCaller is also false. if (direct === false) (0, _invariant2.default)(strictCaller === false, "strictCaller is only allowed on direct eval"); // 2. If Type(x) is not String, return x. if (!(x instanceof _index.StringValue)) return x; // 3. Let script be the ECMAScript code that is the result of parsing x, interpreted as UTF-16 encoded Unicode text // as described in 6.1.4, for the goal symbol Script. If the parse fails, throw a SyntaxError exception. If any // early errors are detected, throw a SyntaxError or a ReferenceError exception, depending on the type of the // error (but see also clause 16). Parsing and early error detection may be interweaved in an implementation // dependent manner. var ast = (0, _parse2.default)(realm, x.value, "eval", "script"); var script = ast.program; // 4. If script Contains ScriptBody is false, return undefined. if (!script.body) return realm.intrinsics.undefined; // 5. Let body be the ScriptBody of script. var body = t.blockStatement(script.body, script.directives); // 6. If strictCaller is true, let strictEval be true. var strictEval = void 0; if (strictCaller) { strictEval = true; } else { // 7. Else, let strictEval be IsStrict of script. strictEval = (0, _strict2.default)(script); } // 8. Let ctx be the running execution context. If direct is true, ctx will be the execution context that // performed the direct eval. If direct is false, ctx will be the execution context for the invocation of // the eval function. var ctx = realm.getRunningContext(); // 9. If direct is true, then var lexEnv = void 0, varEnv = void 0; if (direct) { // a. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment). lexEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, ctx.lexicalEnvironment); // b. Let varEnv be ctx's VariableEnvironment. varEnv = ctx.variableEnvironment; } else { // 10. Else, // a. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]). lexEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, evalRealm.$GlobalEnv); // b. Let varEnv be evalRealm.[[GlobalEnv]]. varEnv = evalRealm.$GlobalEnv; } // 11. If strictEval is true, let varEnv be lexEnv. if (strictEval) varEnv = lexEnv; // 12. If ctx is not already suspended, suspend ctx. ctx.suspend(); // 13. Let evalCxt be a new ECMAScript code execution context. var evalCxt = new _realm.ExecutionContext(); evalCxt.isStrict = strictEval; // 14. Set the evalCxt's Function to null. evalCxt.setFunction(null); // 15. Set the evalCxt's Realm to evalRealm. evalCxt.setRealm(evalRealm); // 16. Set the evalCxt's ScriptOrModule to ctx's ScriptOrModule. evalCxt.ScriptOrModule = ctx.ScriptOrModule; // 17. Set the evalCxt's VariableEnvironment to varEnv. evalCxt.variableEnvironment = varEnv; // 18. Set the evalCxt's LexicalEnvironment to lexEnv. evalCxt.lexicalEnvironment = lexEnv; // 19. Push evalCxt on to the execution context stack; evalCxt is now the running execution context. realm.pushContext(evalCxt); var result = void 0; try { // 20. Let result be EvalDeclarationInstantiation(body, varEnv, lexEnv, strictEval). (0, _invariant2.default)(varEnv); try { result = this.EvalDeclarationInstantiation(realm, body, varEnv, lexEnv, strictEval); } catch (e) { if (e instanceof _completions.AbruptCompletion) { result = e; } else { throw e; } } (0, _invariant2.default)(result instanceof _index.Value || result instanceof _completions.AbruptCompletion); // 21. If result.[[Type]] is normal, then if (result instanceof _index.Value) { // Evaluate expressions that passed for directives. if (script.directives) { var _iteratorNormalCompletion18 = true; var _didIteratorError18 = false; var _iteratorError18 = undefined; try { for (var _iterator18 = script.directives[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) { var directive = _step18.value; result = new _index.StringValue(realm, directive.value.value); } } catch (err) { _didIteratorError18 = true; _iteratorError18 = err; } finally { try { if (!_iteratorNormalCompletion18 && _iterator18.return) { _iterator18.return(); } } finally { if (_didIteratorError18) { throw _iteratorError18; } } } } // a. Let result be the result of evaluating body. result = this.EvaluateStatements(script.body, result, strictEval, lexEnv, realm); } // 22. If result.[[Type]] is normal and result.[[Value]] is empty, then if (result instanceof _index.EmptyValue) { // a. Let result be NormalCompletion(undefined). result = realm.intrinsics.undefined; } } finally { // 23. Suspend evalCxt and remove it from the execution context stack. evalCxt.suspend(); realm.popContext(evalCxt); realm.onDestroyScope(evalCxt.lexicalEnvironment); } // 24. Resume the context that is now on the top of the execution context stack as the running execution context. (0, _invariant2.default)(realm.getRunningContext() === ctx); ctx.resume(); // 25. Return Completion(result). if (result instanceof _index.Value) { return result; } else { (0, _invariant2.default)(result instanceof _completions.AbruptCompletion); throw result; } } // If c is an abrupt completion and realm.savedCompletion is defined, the result is an instance of // JoinedAbruptCompletions and the effects that have been captured since the PossiblyNormalCompletion instance // in realm.savedCompletion has been created, becomes the effects of the branch that terminates in c. // If c is a normal completion, the result is realm.savedCompletion, with its value updated to c. // If c is undefined, the result is just realm.savedCompletion. // Call this only when a join point has been reached. }, { key: "incorporateSavedCompletion", value: function incorporateSavedCompletion(realm, c) { var savedCompletion = realm.savedCompletion; if (savedCompletion !== undefined) { if (savedCompletion.savedPathConditions) { realm.pathConditions = savedCompletion.savedPathConditions; } realm.savedCompletion = undefined; if (c === undefined) return savedCompletion; if (c instanceof _index.Value) { _singletons.Join.updatePossiblyNormalCompletionWithValue(realm, savedCompletion, c); return savedCompletion; } else { var e = realm.getCapturedEffects(savedCompletion); (0, _invariant2.default)(e !== undefined); realm.stopEffectCaptureAndUndoEffects(savedCompletion); var joined_effects = _singletons.Join.joinPossiblyNormalCompletionWithAbruptCompletion(realm, savedCompletion, c, e); realm.applyEffects(joined_effects); var jc = joined_effects[0]; (0, _invariant2.default)(jc instanceof _completions.AbruptCompletion); return jc; } } return c; } }, { key: "EvaluateStatements", value: function EvaluateStatements(body, initialBlockValue, strictCode, blockEnv, realm) { var blockValue = initialBlockValue; var _iteratorNormalCompletion19 = true; var _didIteratorError19 = false; var _iteratorError19 = undefined; try { for (var _iterator19 = body[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) { var node = _step19.value; if (node.type !== "FunctionDeclaration") { var res = blockEnv.evaluateCompletionDeref(node, strictCode); if (!(res instanceof _index.EmptyValue)) { if (res instanceof _completions.AbruptCompletion) throw (0, _index2.UpdateEmpty)(realm, res, blockValue || realm.intrinsics.empty); (0, _invariant2.default)(res instanceof _index.Value); blockValue = res; } } } // 7. Return blockValue. } catch (err) { _didIteratorError19 = true; _iteratorError19 = err; } finally { try { if (!_iteratorNormalCompletion19 && _iterator19.return) { _iterator19.return(); } } finally { if (_didIteratorError19) { throw _iteratorError19; } } } return blockValue || realm.intrinsics.empty; } }, { key: "PartiallyEvaluateStatements", value: function PartiallyEvaluateStatements(body, blockValue, strictCode, blockEnv, realm) { var statementAsts = []; var _iteratorNormalCompletion20 = true; var _didIteratorError20 = false; var _iteratorError20 = undefined; try { for (var _iterator20 = body[Symbol.iterator](), _step20; !(_iteratorNormalCompletion20 = (_step20 = _iterator20.next()).done); _iteratorNormalCompletion20 = true) { var node = _step20.value; if (node.type !== "FunctionDeclaration") { var _blockEnv$partiallyEv = blockEnv.partiallyEvaluateCompletionDeref(node, strictCode), _blockEnv$partiallyEv2 = _slicedToArray(_blockEnv$partiallyEv, 3), res = _blockEnv$partiallyEv2[0], nast = _blockEnv$partiallyEv2[1], nio = _blockEnv$partiallyEv2[2]; var _iteratorNormalCompletion21 = true; var _didIteratorError21 = false; var _iteratorError21 = undefined; try { for (var _iterator21 = nio[Symbol.iterator](), _step21; !(_iteratorNormalCompletion21 = (_step21 = _iterator21.next()).done); _iteratorNormalCompletion21 = true) { var ioAst = _step21.value; statementAsts.push(ioAst); } } catch (err) { _didIteratorError21 = true; _iteratorError21 = err; } finally { try { if (!_iteratorNormalCompletion21 && _iterator21.return) { _iterator21.return(); } } finally { if (_didIteratorError21) { throw _iteratorError21; } } } statementAsts.push(nast); if (!(res instanceof _index.EmptyValue)) { if (blockValue === undefined || blockValue instanceof _index.Value) { if (res instanceof _completions.AbruptCompletion) return [(0, _index2.UpdateEmpty)(realm, res, blockValue || realm.intrinsics.empty), statementAsts]; (0, _invariant2.default)(res instanceof _completions.NormalCompletion || res instanceof _index.Value); blockValue = res; } } } } // 7. Return blockValue. } catch (err) { _didIteratorError20 = true; _iteratorError20 = err; } finally { try { if (!_iteratorNormalCompletion20 && _iterator20.return) { _iterator20.return(); } } finally { if (_didIteratorError20) { throw _iteratorError20; } } } return [blockValue || realm.intrinsics.empty, statementAsts]; } // ECMA262 9.2.5 }, { key: "FunctionCreate", value: function FunctionCreate(realm, kind, ParameterList, Body, Scope, Strict, prototype) { // 1. If the prototype argument was not passed, then if (!prototype) { // a. Let prototype be the intrinsic object %FunctionPrototype%. prototype = realm.intrinsics.FunctionPrototype; } // 2. If kind is not Normal, let allocKind be "non-constructor". var allocKind = void 0; if (kind !== "normal") { allocKind = "non-constructor"; } else { // 3. Else, let allocKind be "normal". allocKind = "normal"; } // 4. Let F be FunctionAllocate(prototype, Strict, allocKind). var F = this.FunctionAllocate(realm, prototype, Strict, allocKind); // ECMAScript 2016, section 17: // "Every other data property described in clauses 18 through 26 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified." // Because we call `AddRestrictedFunctionProperties` on `FunctionPrototype`, accessing property "arguments" will raise a `TypeError` by default. // However, in non-strict mode this behavior is not desired, so we will add them as own properties of each `FunctionValue`, in accordance with ECMA 17. // Note: "arguments" ***MUST NOT*** be set if the function is in strict mode or is an arrow, method, constructor, or generator function. // See 16.2 "Forbidden Extensions" if (!Strict && kind === "normal") { _singletons.Properties.DefinePropertyOrThrow(realm, F, "arguments", { value: realm.intrinsics.undefined, enumerable: false, writable: true, configurable: true }); } // 5. Return FunctionInitialize(F, kind, ParameterList, Body, Scope). return this.FunctionInitialize(realm, F, kind, ParameterList, Body, Scope); } // ECMA262 18.2.1.2 }, { key: "EvalDeclarationInstantiation", value: function EvalDeclarationInstantiation(realm, body, varEnv, lexEnv, strict) { // 1. Let varNames be the VarDeclaredNames of body. var varNames = []; (0, _traverseFast2.default)(body, function (node) { if (node.type === "VariableDeclaration" && node.kind === "var") { varNames = varNames.concat(Object.keys(t.getBindingIdentifiers(node))); } if (node.type === "FunctionExpression" || node.type === "FunctionDeclaration") { return true; } return false; }); // 2. Let varDeclarations be the VarScopedDeclarations of body. var varDeclarations = this.FindVarScopedDeclarations(body); // 3. Let lexEnvRec be lexEnv's EnvironmentRecord. var lexEnvRec = lexEnv.environmentRecord; // 4. Let varEnvRec be varEnv's EnvironmentRecord. var varEnvRec = varEnv.environmentRecord; // 5. If strict is false, then if (!strict) { // a. If varEnvRec is a global Environment Record, then if (varEnvRec instanceof _environment.GlobalEnvironmentRecord) { // i. For each name in varNames, do var _iteratorNormalCompletion22 = true; var _didIteratorError22 = false; var _iteratorError22 = undefined; try { for (var _iterator22 = varNames[Symbol.iterator](), _step22; !(_iteratorNormalCompletion22 = (_step22 = _iterator22.next()).done); _iteratorNormalCompletion22 = true) { var name = _step22.value; // 1. If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError exception. if (varEnvRec.HasLexicalDeclaration(name)) { throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, new _index.StringValue(realm, name + " global object is restricted")); } // 2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration. } } catch (err) { _didIteratorError22 = true; _iteratorError22 = err; } finally { try { if (!_iteratorNormalCompletion22 && _iterator22.return) { _iterator22.return(); } } finally { if (_didIteratorError22) { throw _iteratorError22; } } } } // b. Let thisLex be lexEnv. var thisLex = lexEnv; // c. Assert: The following loop will terminate. // d. Repeat while thisLex is not the same as varEnv, while (thisLex !== varEnv) { // i. Let thisEnvRec be thisLex's EnvironmentRecord. var thisEnvRec = thisLex.environmentRecord; // ii. If thisEnvRec is not an object Environment Record, then if (!(thisEnvRec instanceof _environment.ObjectEnvironmentRecord)) { // 1. NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts. // 2. For each name in varNames, do var _iteratorNormalCompletion23 = true; var _didIteratorError23 = false; var _iteratorError23 = undefined; try { for (var _iterator23 = varNames[Symbol.iterator](), _step23; !(_iteratorNormalCompletion23 = (_step23 = _iterator23.next()).done); _iteratorNormalCompletion23 = true) { var _name2 = _step23.value; // a. If thisEnvRec.HasBinding(name) is true, then if (thisEnvRec.HasBinding(_name2)) { // i. Throw a SyntaxError exception. throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, _name2 + " global object is restricted"); // ii. NOTE: Annex B.3.5 defines alternate semantics for the above step. } // b. NOTE: A direct eval will not hoist var declaration over a like-named lexical declaration. } } catch (err) { _didIteratorError23 = true; _iteratorError23 = err; } finally { try { if (!_iteratorNormalCompletion23 && _iterator23.return) { _iterator23.return(); } } finally { if (_didIteratorError23) { throw _iteratorError23; } } } } // iii. Let thisLex be thisLex's outer environment reference. thisLex = thisLex.parent; (0, _invariant2.default)(thisLex !== null); } } // 6. Let functionsToInitialize be a new empty List. var functionsToInitialize = []; // 7. Let declaredFunctionNames be a new empty List. var declaredFunctionNames = []; // 8. For each d in varDeclarations, in reverse list order do var _iteratorNormalCompletion24 = true; var _didIteratorError24 = false; var _iteratorError24 = undefined; try { for (var _iterator24 = varDeclarations.reverse()[Symbol.iterator](), _step24; !(_iteratorNormalCompletion24 = (_step24 = _iterator24.next()).done); _iteratorNormalCompletion24 = true) { var d = _step24.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" || d.type === "GeneratorDeclaration"); // 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. If varEnvRec is a global Environment Record, then if (varEnvRec instanceof _environment.GlobalEnvironmentRecord) { // a. Let fnDefinable be ? varEnvRec.CanDeclareGlobalFunction(fn). var fnDefinable = varEnvRec.CanDeclareGlobalFunction(fn); // b. If fnDefinable is false, throw a TypeError exception. if (!fnDefinable) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, fn + " is not definable"); } } // 2. Append fn to declaredFunctionNames. declaredFunctionNames.push(fn); // 3. Insert d as the first element of functionsToInitialize. functionsToInitialize.unshift(d); } } } // 9. NOTE: Annex B.3.3.3 adds additional steps at this point. // 10. Let declaredVarNames be a new empty List. } catch (err) { _didIteratorError24 = true; _iteratorError24 = err; } finally { try { if (!_iteratorNormalCompletion24 && _iterator24.return) { _iterator24.return(); } } finally { if (_didIteratorError24) { throw _iteratorError24; } } } var declaredVarNames = []; // 11. For each d in varDeclarations, do var _iteratorNormalCompletion25 = true; var _didIteratorError25 = false; var _iteratorError25 = undefined; try { for (var _iterator25 = varDeclarations[Symbol.iterator](), _step25; !(_iteratorNormalCompletion25 = (_step25 = _iterator25.next()).done); _iteratorNormalCompletion25 = true) { var _d2 = _step25.value; // a. If d is a VariableDeclaration or a ForBinding, then if (_d2.type === "VariableDeclaration") { // i. For each String vn in the BoundNames of d, do var _iteratorNormalCompletion30 = true; var _didIteratorError30 = false; var _iteratorError30 = undefined; try { for (var _iterator30 = _singletons.Environment.BoundNames(realm, _d2)[Symbol.iterator](), _step30; !(_iteratorNormalCompletion30 = (_step30 = _iterator30.next()).done); _iteratorNormalCompletion30 = true) { var _vn = _step30.value; // 1. If vn is not an element of declaredFunctionNames, then if (declaredFunctionNames.indexOf(_vn) < 0) { // a. If varEnvRec is a global Environment Record, then if (varEnvRec instanceof _environment.GlobalEnvironmentRecord) { // i. Let vnDefinable be ? varEnvRec.CanDeclareGlobalVar(vn). var vnDefinable = varEnvRec.CanDeclareGlobalVar(_vn); // ii. If vnDefinable is false, throw a TypeError exception. if (!vnDefinable) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, _vn + " is not definable"); } } // b. If vn is not an element of declaredVarNames, then if (declaredVarNames.indexOf(_vn) < 0) { // i. Append vn to declaredVarNames. declaredVarNames.push(_vn); } } } } catch (err) { _didIteratorError30 = true; _iteratorError30 = err; } finally { try { if (!_iteratorNormalCompletion30 && _iterator30.return) { _iterator30.return(); } } finally { if (_didIteratorError30) { throw _iteratorError30; } } } } } // 12. NOTE: No abnormal terminations occur after this algorithm step unless varEnvRec is a global Environment Record and the global object is a Proxy exotic object. // 13. Let lexDeclarations be the LexicallyScopedDeclarations of body. } catch (err) { _didIteratorError25 = true; _iteratorError25 = err; } finally { try { if (!_iteratorNormalCompletion25 && _iterator25.return) { _iterator25.return(); } } finally { if (_didIteratorError25) { throw _iteratorError25; } } } var lexDeclarations = []; var _iteratorNormalCompletion26 = true; var _didIteratorError26 = false; var _iteratorError26 = undefined; try { for (var _iterator26 = body.body[Symbol.iterator](), _step26; !(_iteratorNormalCompletion26 = (_step26 = _iterator26.next()).done); _iteratorNormalCompletion26 = true) { var s = _step26.value; if (s.type === "VariableDeclaration" && s.kind !== "var") { lexDeclarations.push(s); } } // 14. For each element d in lexDeclarations do } catch (err) { _didIteratorError26 = true; _iteratorError26 = err; } finally { try { if (!_iteratorNormalCompletion26 && _iterator26.return) { _iterator26.return(); } } finally { if (_didIteratorError26) { throw _iteratorError26; } } } var _iteratorNormalCompletion27 = true; var _didIteratorError27 = false; var _iteratorError27 = undefined; try { for (var _iterator27 = lexDeclarations[Symbol.iterator](), _step27; !(_iteratorNormalCompletion27 = (_step27 = _iterator27.next()).done); _iteratorNormalCompletion27 = true) { var _d3 = _step27.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 _iteratorNormalCompletion31 = true; var _didIteratorError31 = false; var _iteratorError31 = undefined; try { for (var _iterator31 = _singletons.Environment.BoundNames(realm, _d3)[Symbol.iterator](), _step31; !(_iteratorNormalCompletion31 = (_step31 = _iterator31.next()).done); _iteratorNormalCompletion31 = true) { var dn = _step31.value; // c. If IsConstantDeclaration of d is true, then if (_d3.kind === "const") { // i. Perform ? lexEnvRec.CreateImmutableBinding(dn, true). lexEnvRec.CreateImmutableBinding(dn, true); } else { // d. Else, // i. Perform ? lexEnvRec.CreateMutableBinding(dn, false). lexEnvRec.CreateMutableBinding(dn, false); } } } catch (err) { _didIteratorError31 = true; _iteratorError31 = err; } finally { try { if (!_iteratorNormalCompletion31 && _iterator31.return) { _iterator31.return(); } } finally { if (_didIteratorError31) { throw _iteratorError31; } } } } // 15. For each production f in functionsToInitialize, do } catch (err) { _didIteratorError27 = true; _iteratorError27 = err; } finally { try { if (!_iteratorNormalCompletion27 && _iterator27.return) { _iterator27.return(); } } finally { if (_didIteratorError27) { throw _iteratorError27; } } } var _iteratorNormalCompletion28 = true; var _didIteratorError28 = false; var _iteratorError28 = undefined; try { for (var _iterator28 = functionsToInitialize[Symbol.iterator](), _step28; !(_iteratorNormalCompletion28 = (_step28 = _iterator28.next()).done); _iteratorNormalCompletion28 = true) { var f = _step28.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 lexEnv. var fo = lexEnv.evaluate(f, strict); (0, _invariant2.default)(fo instanceof _index.Value); // c. If varEnvRec is a global Environment Record, then if (varEnvRec instanceof _environment.GlobalEnvironmentRecord) { // i. Perform ? varEnvRec.CreateGlobalFunctionBinding(fn, fo, true). varEnvRec.CreateGlobalFunctionBinding(fn, fo, true); } else { // d. Else, // i. Let bindingExists be varEnvRec.HasBinding(fn). var bindingExists = varEnvRec.HasBinding(fn); // ii. If bindingExists is false, then if (!bindingExists) { // 1. Let status be ! varEnvRec.CreateMutableBinding(fn, true). varEnvRec.CreateMutableBinding(fn, true); // 2. Assert: status is not an abrupt completion because of validation preceding step 12. // 3. Perform ! varEnvRec.InitializeBinding(fn, fo). varEnvRec.InitializeBinding(fn, fo); } else { // iii. Else, // 1. Perform ! varEnvRec.SetMutableBinding(fn, fo, false). varEnvRec.SetMutableBinding(fn, fo, false); } } } // 16. For each String vn in declaredVarNames, in list order do } catch (err) { _didIteratorError28 = true; _iteratorError28 = err; } finally { try { if (!_iteratorNormalCompletion28 && _iterator28.return) { _iterator28.return(); } } finally { if (_didIteratorError28) { throw _iteratorError28; } } } var _iteratorNormalCompletion29 = true; var _didIteratorError29 = false; var _iteratorError29 = undefined; try { for (var _iterator29 = declaredVarNames[Symbol.iterator](), _step29; !(_iteratorNormalCompletion29 = (_step29 = _iterator29.next()).done); _iteratorNormalCompletion29 = true) { var vn = _step29.value; // a. If varEnvRec is a global Environment Record, then if (varEnvRec instanceof _environment.GlobalEnvironmentRecord) { // i. Perform ? varEnvRec.CreateGlobalVarBinding(vn, true). varEnvRec.CreateGlobalVarBinding(vn, true); } else { // b. Else, // i. Let bindingExists be varEnvRec.HasBinding(vn). var _bindingExists = varEnvRec.HasBinding(vn); // ii. If bindingExists is false, then if (!_bindingExists) { // 1. Let status be ! varEnvRec.CreateMutableBinding(vn, true). varEnvRec.CreateMutableBinding(vn, true); // 2. Assert: status is not an abrupt completion because of validation preceding step 12. // 3. Perform ! varEnvRec.InitializeBinding(vn, undefined). varEnvRec.InitializeBinding(vn, realm.intrinsics.undefined); } } } // 17. Return NormalCompletion(empty). } catch (err) { _didIteratorError29 = true; _iteratorError29 = err; } finally { try { if (!_iteratorNormalCompletion29 && _iterator29.return) { _iterator29.return(); } } finally { if (_didIteratorError29) { throw _iteratorError29; } } } return realm.intrinsics.empty; } // ECMA 9.2.10 }, { key: "MakeMethod", value: function MakeMethod(realm, F, homeObject) { // Note that F is a new object, and we can thus write to internal slots (0, _invariant2.default)(realm.isNewObject(F)); // 1. Assert: F is an ECMAScript function object. (0, _invariant2.default)(F instanceof _index.ECMAScriptSourceFunctionValue, "F is an ECMAScript function object."); // 2. Assert: Type(homeObject) is Object. (0, _invariant2.default)(homeObject instanceof _index.ObjectValue, "Type(homeObject) is Object."); // 3. Set the [[HomeObject]] internal slot of F to homeObject. F.$HomeObject = homeObject; // 4. Return NormalCompletion(undefined). return realm.intrinsics.undefined; } // ECMA 14.3.8 }, { key: "DefineMethod", value: function DefineMethod(realm, prop, obj, env, strictCode, functionPrototype) { // 1. Let propKey be the result of evaluating PropertyName. var propKey = (0, _ObjectExpression.EvalPropertyName)(prop, env, realm, strictCode); // 2. ReturnIfAbrupt(propKey). // 3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false. var strict = strictCode || (0, _strict2.default)(prop.body); // 4. Let scope be the running execution context's LexicalEnvironment. var scope = env; // 5. If functionPrototype was passed as a parameter, let kind be Normal; otherwise let kind be Method. var kind = void 0; if (functionPrototype) { // let kind be Normal; kind = "normal"; } else { // otherwise let kind be Method. kind = "method"; } // 6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody, scope, strict). If functionPrototype was passed as a parameter, then pass its value as the prototype optional argument of FunctionCreate. var closure = this.FunctionCreate(realm, kind, prop.params, prop.body, scope, strict, functionPrototype); // 7. Perform MakeMethod(closure, object). this.MakeMethod(realm, closure, obj); // 8. Return the Record{[[Key]]: propKey, [[Closure]]: closure}. return { $Key: propKey, $Closure: closure }; } }]); return FunctionImplementation; }(); //# sourceMappingURL=function.js.map