2192 lines
88 KiB
JavaScript
2192 lines
88 KiB
JavaScript
"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
|