"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"); } }; }(); exports.ArgumentListEvaluation = ArgumentListEvaluation; exports.Invoke = Invoke; exports.EvaluateCall = EvaluateCall; exports.PrepareForOrdinaryCall = PrepareForOrdinaryCall; exports.OrdinaryCallBindThis = OrdinaryCallBindThis; exports.OrdinaryCallEvaluateBody = OrdinaryCallEvaluateBody; exports.EvaluateDirectCall = EvaluateDirectCall; exports.EvaluateDirectCallWithArgList = EvaluateDirectCallWithArgList; exports.PrepareForTailCall = PrepareForTailCall; exports.Call = Call; var _environment = require("../environment.js"); var _errors = require("../errors.js"); var _realm = require("../realm.js"); var _Value = require("../values/Value.js"); var _Value2 = _interopRequireDefault(_Value); var _index = require("../values/index.js"); var _index2 = require("./index.js"); var _generator = require("../methods/generator.js"); var _completions = require("../completions.js"); var _get = require("../methods/get.js"); var _singletons = require("../singletons.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 }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /** * 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. */ // ECMA262 12.3.6.1 function ArgumentListEvaluation(realm, strictCode, env, argNodes) { if (Array.isArray(argNodes)) { var args = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = argNodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var node_ = _step.value; if (node_.type === "SpreadElement") { var node = node_; // 1. Let list be a new empty List. var list = args; // 2. Let spreadRef be the result of evaluating AssignmentExpression. var spreadRef = env.evaluate(node.argument, strictCode); // 3. Let spreadObj be ? GetValue(spreadRef). var spreadObj = _singletons.Environment.GetValue(realm, spreadRef); // 4. Let iterator be ? GetIterator(spreadObj). var iterator = (0, _index2.GetIterator)(realm, spreadObj); // 5. Repeat while (true) { // a. Let next be ? IteratorStep(iterator). var next = (0, _index2.IteratorStep)(realm, iterator); // b. If next is false, return list. if (!next) { break; } // c. Let nextArg be ? IteratorValue(next). var nextArg = (0, _index2.IteratorValue)(realm, next); // d. Append nextArg as the last element of list. list.push(nextArg); } } else { var ref = env.evaluate(node_, strictCode); var expr = _singletons.Environment.GetValue(realm, ref); args.push(expr); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return args; } else { var _node = argNodes; if (_node.expressions.length === 0) { // 1. Let templateLiteral be this TemplateLiteral. var templateLiteral = _node; // 2. Let siteObj be GetTemplateObject(templateLiteral). var siteObj = (0, _get.GetTemplateObject)(realm, templateLiteral); // 3. Return a List containing the one element which is siteObj. return [siteObj]; } else { // 1. Let templateLiteral be this TemplateLiteral. var _templateLiteral = _node; // 2. Let siteObj be GetTemplateObject(templateLiteral). var _siteObj = (0, _get.GetTemplateObject)(realm, _templateLiteral); // 3. Let firstSubRef be the result of evaluating Expression. var firstSubRef = env.evaluate(_node.expressions[0], strictCode); // 4. Let firstSub be ? GetValue(firstSubRef). var firstSub = _singletons.Environment.GetValue(realm, firstSubRef); // 5. Let restSub be SubstitutionEvaluation of TemplateSpans. var restSub = _node.expressions.slice(1, _node.expressions.length).map(function (expr) { return _singletons.Environment.GetValue(realm, env.evaluate(expr, strictCode)); }); // 6. ReturnIfAbrupt(restSub). // 7. Assert: restSub is a List. (0, _invariant2.default)(restSub.constructor === Array, "restSub is a List"); // 8. Return a List whose first element is siteObj, whose second elements is firstSub, and whose subsequent elements are the elements of restSub, in order. restSub may contain no elements. return [_siteObj, firstSub].concat(_toConsumableArray(restSub)); } } } // ECMA262 7.3.18 function Invoke(realm, V, P, argumentsList) { // 1. Assert: IsPropertyKey(P) is true. (0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P), "expected property key"); // 2. If argumentsList was not passed, let argumentsList be a new empty List. if (!argumentsList) argumentsList = []; // 3. Let func be ? GetV(V, P). var func = (0, _get.GetV)(realm, V, P); // 4. Return ? Call(func, V, argumentsList). return Call(realm, func, V, argumentsList); } // ECMA262 12.3.4.2 function EvaluateCall(realm, strictCode, env, ref, args) { var thisValue = void 0; // 1. Let func be ? GetValue(ref). var func = _singletons.Environment.GetValue(realm, ref); // 2. If Type(ref) is Reference, then if (ref instanceof _environment.Reference) { // a. If IsPropertyReference(ref) is true, then if (_singletons.Environment.IsPropertyReference(realm, ref)) { // i. Let thisValue be GetThisValue(ref). thisValue = (0, _get.GetThisValue)(realm, ref); } else { // b. Else, the base of ref is an Environment Record // i. Let refEnv be GetBase(ref). var refEnv = _singletons.Environment.GetBase(realm, ref); (0, _invariant2.default)(refEnv instanceof _environment.EnvironmentRecord); // ii. Let thisValue be refEnv.WithBaseObject(). thisValue = refEnv.WithBaseObject(); } } else { // 3. Else Type(ref) is not Reference, // a. Let thisValue be undefined. thisValue = realm.intrinsics.undefined; } // 4. Return ? EvaluateDirectCall(func, thisValue, arguments, tailPosition). return EvaluateDirectCall(realm, strictCode, env, ref, func, thisValue, args); } // ECMA262 9.2.1.1 function PrepareForOrdinaryCall(realm, F, newTarget) { // 1. Assert: Type(newTarget) is Undefined or Object. (0, _invariant2.default)(newTarget === undefined || newTarget instanceof _index.ObjectValue, "expected undefined or object value for new target"); // 2. Let callerContext be the running execution context. var callerContext = realm.getRunningContext(); // 3. Let calleeContext be a new ECMAScript code execution context. var calleeContext = realm.createExecutionContext(); // 4. Set the Function of calleeContext to F. calleeContext.setFunction(F); calleeContext.setCaller(realm.getRunningContext()); // 5. Let calleeRealm be the value of F's [[Realm]] internal slot. var calleeRealm = realm; // 6. Set the Realm of calleeContext to calleeRealm. calleeContext.realm = calleeRealm; // 7. Set the ScriptOrModule of calleeContext to the value of F's [[ScriptOrModule]] internal slot. calleeContext.ScriptOrModule = F.$ScriptOrModule; // 8. Let localEnv be NewFunctionEnvironment(F, newTarget). var localEnv = _singletons.Environment.NewFunctionEnvironment(realm, F, newTarget); // 9. Set the LexicalEnvironment of calleeContext to localEnv. calleeContext.lexicalEnvironment = localEnv; // 10. Set the VariableEnvironment of calleeContext to localEnv. calleeContext.variableEnvironment = localEnv; // 11. If callerContext is not already suspended, suspend callerContext. callerContext.suspend(); // 12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context. realm.pushContext(calleeContext); // 13. NOTE Any exception objects produced after this point are associated with calleeRealm. // 14. Return calleeContext. return calleeContext; } // ECMA262 9.2.1.2 function OrdinaryCallBindThis(realm, F, calleeContext, thisArgument) { // 1. Let thisMode be the value of F's [[ThisMode]] internal slot. var thisMode = F.$ThisMode; // 2. If thisMode is lexical, return NormalCompletion(undefined). if (thisMode === "lexical") return realm.intrinsics.undefined; // 3. Let calleeRealm be the value of F's [[Realm]] internal slot. var calleeRealm = F.$Realm; // 4. Let localEnv be the LexicalEnvironment of calleeContext. var localEnv = calleeContext.lexicalEnvironment; var thisValue = void 0; // 5. If thisMode is strict, let thisValue be thisArgument. if (thisMode === "strict") { thisValue = thisArgument; } else { // 6. Else, // a. If thisArgument is null or undefined, then if ((0, _index2.HasSomeCompatibleType)(thisArgument, _index.NullValue, _index.UndefinedValue)) { // i. Let globalEnv be calleeRealm.[[GlobalEnv]]. var globalEnv = realm.$GlobalEnv; // ii. Let globalEnvRec be globalEnv's EnvironmentRecord. var globalEnvRec = globalEnv.environmentRecord; (0, _invariant2.default)(globalEnvRec instanceof _environment.GlobalEnvironmentRecord); // iii. Let thisValue be globalEnvRec.[[GlobalThisValue]]. thisValue = globalEnvRec.$GlobalThisValue; } else { // b. Else, // i. Let thisValue be ! ToObject(thisArgument). thisValue = _singletons.To.ToObjectPartial(calleeRealm, thisArgument); // ii. NOTE ToObject produces wrapper objects using calleeRealm. } } // 7. Let envRec be localEnv's EnvironmentRecord. (0, _invariant2.default)(localEnv !== undefined); var envRec = localEnv.environmentRecord; // 8. Assert: The next step never returns an abrupt completion because envRec.[[ThisBindingStatus]] is not "initialized". // 9. Return envRec.BindThisValue(thisValue). return envRec.BindThisValue(thisValue); } // ECMA262 9.2.1.3 function OrdinaryCallEvaluateBody(realm, F, argumentsList) { if (F instanceof _index.NativeFunctionValue) { var env = realm.getRunningContext().lexicalEnvironment; try { return F.callCallback(env.environmentRecord.GetThisBinding(), argumentsList, env.environmentRecord.$NewTarget); } catch (err) { if (err instanceof _completions.AbruptCompletion) { return err; } else if (err instanceof Error) { throw err; } else { throw new _errors.FatalError(err); } } } else { (0, _invariant2.default)(F instanceof _index.ECMAScriptSourceFunctionValue); if (F.$FunctionKind === "generator") { // 1. Perform ? FunctionDeclarationInstantiation(functionObject, argumentsList). _singletons.Functions.FunctionDeclarationInstantiation(realm, F, argumentsList); // 2. Let G be ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorPrototype%", « [[GeneratorState]], [[GeneratorContext]] »). var G = _singletons.Create.OrdinaryCreateFromConstructor(realm, F, "GeneratorPrototype", { $GeneratorState: undefined, $GeneratorContext: undefined }); // 3. Perform GeneratorStart(G, FunctionBody). var code = F.$ECMAScriptCode; (0, _invariant2.default)(code !== undefined); (0, _generator.GeneratorStart)(realm, G, code); // 4. Return Completion{[[Type]]: return, [[Value]]: G, [[Target]]: empty}. return new _completions.ReturnCompletion(G, realm.currentLocation); } else { // 1. Perform ? FunctionDeclarationInstantiation(F, argumentsList). _singletons.Functions.FunctionDeclarationInstantiation(realm, F, argumentsList); // 2. Return the result of EvaluateBody of the parsed code that is the value of F's // [[ECMAScriptCode]] internal slot passing F as the argument. var priorSavedCompletion = realm.savedCompletion; try { realm.savedCompletion = undefined; var _code = F.$ECMAScriptCode; (0, _invariant2.default)(_code !== undefined); var context = realm.getRunningContext(); var c = context.lexicalEnvironment.evaluateCompletionDeref(_code, F.$Strict); // We are about the leave this function 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. c = _singletons.Functions.incorporateSavedCompletion(realm, c); var joinedEffects = void 0; if (c instanceof _completions.PossiblyNormalCompletion) { var e = realm.getCapturedEffects(c); if (e !== undefined) { // There were earlier, conditional exits from the function // We join together the current effects with the effects of any earlier returns that are tracked in c. realm.stopEffectCaptureAndUndoEffects(c); } else { e = (0, _realm.construct_empty_effects)(realm); } joinedEffects = _singletons.Join.joinEffectsAndPromoteNestedReturnCompletions(realm, c, e); } else if (c instanceof _completions.JoinedAbruptCompletions) { joinedEffects = _singletons.Join.joinEffectsAndPromoteNestedReturnCompletions(realm, c, (0, _realm.construct_empty_effects)(realm)); } if (joinedEffects !== undefined) { var result = joinedEffects[0]; if (result instanceof _completions.ReturnCompletion) { realm.applyEffects(joinedEffects); return result; } (0, _invariant2.default)(result instanceof _completions.JoinedAbruptCompletions); if (!(result.consequent instanceof _completions.ReturnCompletion || result.alternate instanceof _completions.ReturnCompletion)) { realm.applyEffects(joinedEffects); throw result; } // There is a normal return exit, but also one or more throw completions. // The throw completions must be extracted into a saved possibly normal completion // so that the caller can pick them up in its next completion. joinedEffects = extractAndSavePossiblyNormalCompletion(result); result = joinedEffects[0]; (0, _invariant2.default)(result instanceof _completions.ReturnCompletion); realm.applyEffects(joinedEffects); return result; } else { (0, _invariant2.default)(c instanceof _Value2.default || c instanceof _completions.AbruptCompletion); return c; } } finally { realm.incorporatePriorSavedCompletion(priorSavedCompletion); } } } function extractAndSavePossiblyNormalCompletion(c) { // There are throw completions that conditionally escape from the the call. // We need to carry on in normal mode (after arranging to capturing effects) // while stashing away the throw completions so that the next completion we return var _Join$unbundleReturnC = _singletons.Join.unbundleReturnCompletion(realm, c), _Join$unbundleReturnC2 = _slicedToArray(_Join$unbundleReturnC, 2), joinedEffects = _Join$unbundleReturnC2[0], possiblyNormalCompletion = _Join$unbundleReturnC2[1]; realm.composeWithSavedCompletion(possiblyNormalCompletion); return joinedEffects; } } // ECMA262 12.3.4.3 function EvaluateDirectCall(realm, strictCode, env, ref, func, thisValue, args, tailPosition) { // 1. Let argList be ? ArgumentListEvaluation(arguments). var argList = ArgumentListEvaluation(realm, strictCode, env, args); return EvaluateDirectCallWithArgList(realm, strictCode, env, ref, func, thisValue, argList, tailPosition); } function EvaluateDirectCallWithArgList(realm, strictCode, env, ref, func, thisValue, argList, tailPosition) { if (func instanceof _index.AbstractValue && _Value2.default.isTypeCompatibleWith(func.getType(), _index.FunctionValue)) { return _index.AbstractValue.createTemporalFromBuildFunction(realm, _Value2.default, [func].concat(argList), function (nodes) { var fun_args = nodes.slice(1); return t.callExpression(nodes[0], fun_args); }); } func = func.throwIfNotConcrete(); // 2. If Type(func) is not Object, throw a TypeError exception. if (!(func instanceof _index.ObjectValue)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "not an object"); } // 3. If IsCallable(func) is false, throw a TypeError exception. if (!(0, _index2.IsCallable)(realm, func)) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "not callable"); } // 4. If tailPosition is true, perform PrepareForTailCall(). if (tailPosition === true) PrepareForTailCall(realm); // 5. Let result be Call(func, thisValue, argList). var result = Call(realm, func, thisValue, argList); // 6. Assert: If tailPosition is true, the above call will not return here, but instead // evaluation will continue as if the following return has already occurred. // 7. Assert: If result is not an abrupt completion, then Type(result) is an ECMAScript language type. (0, _invariant2.default)(result instanceof _Value2.default, "expected language value type"); // 8. Return result. return result; } // ECMA262 14.6.3 function PrepareForTailCall(realm) { // 1. Let leafContext be the running execution context. var leafContext = realm.getRunningContext(); // 2. Suspend leafContext. leafContext.suspend(); // 3. Pop leafContext from the execution context stack. The execution context now on the // top of the stack becomes the running execution context. realm.onDestroyScope(leafContext.lexicalEnvironment); realm.popContext(leafContext); // TODO #1008 4. Assert: leafContext has no further use. It will never be activated as the running execution context. } // ECMA262 7.3.12 function Call(realm, F, V, argsList) { // 1. If argumentsList was not passed, let argumentsList be a new empty List. argsList = argsList || []; // 2. If IsCallable(F) is false, throw a TypeError exception. if ((0, _index2.IsCallable)(realm, F) === false) { throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "not callable"); } if (F instanceof _index.AbstractValue && _Value2.default.isTypeCompatibleWith(F.getType(), _index.FunctionValue)) { var fullArgs = [F].concat(argsList); return _index.AbstractValue.createTemporalFromBuildFunction(realm, _Value2.default, fullArgs, function (nodes) { var fun_args = nodes.slice(1); return t.callExpression(nodes[0], fun_args); }); } (0, _invariant2.default)(F instanceof _index.ObjectValue); // 3. Return ? F.[[Call]](V, argumentsList). (0, _invariant2.default)(F.$Call, "no call method on this value"); return F.$Call(V, argsList); } //# sourceMappingURL=call.js.map