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

1301 lines
52 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.EnvironmentImplementation = undefined;
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; }; }(); /**
* 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 _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _index = require("../values/index.js");
var _environment = require("../environment.js");
var _completions = require("../completions.js");
var _errors = require("../errors.js");
var _ObjectExpression = require("../evaluators/ObjectExpression.js");
var _index2 = require("./index.js");
var _singletons = require("../singletons.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var EnvironmentImplementation = exports.EnvironmentImplementation = function () {
function EnvironmentImplementation() {
_classCallCheck(this, EnvironmentImplementation);
}
_createClass(EnvironmentImplementation, [{
key: "IsSuperReference",
// ECMA262 6.2.3
// IsSuperReference(V). Returns true if this reference has a thisValue component.
value: function IsSuperReference(realm, V) {
return V.thisValue !== undefined;
}
// ECMA262 6.2.3
// HasPrimitiveBase(V). Returns true if Type(base) is Boolean, String, Symbol, or Number.
}, {
key: "HasPrimitiveBase",
value: function HasPrimitiveBase(realm, V) {
var base = this.GetBase(realm, V);
// void | ObjectValue | BooleanValue | StringValue | SymbolValue | NumberValue | EnvironmentRecord | AbstractValue;
if (!base || base instanceof _environment.EnvironmentRecord) return false;
var type = base.getType();
return type === _index.BooleanValue || type === _index.StringValue || type === _index.SymbolValue || type === _index.NumberValue;
}
// ECMA262 6.2.3
// GetReferencedName(V). Returns the referenced name component of the reference V.
}, {
key: "GetReferencedName",
value: function GetReferencedName(realm, V) {
if (V.referencedName instanceof _index.AbstractValue) {
_index.AbstractValue.reportIntrospectionError(V.referencedName);
throw new _errors.FatalError();
}
return V.referencedName;
}
}, {
key: "GetReferencedNamePartial",
value: function GetReferencedNamePartial(realm, V) {
return V.referencedName;
}
// ECMA262 6.2.3.1
}, {
key: "GetValue",
value: function GetValue(realm, V) {
var val = this._dereference(realm, V);
if (val instanceof _index.AbstractValue) return realm.simplifyAndRefineAbstractValue(val);
return val;
}
}, {
key: "GetConditionValue",
value: function GetConditionValue(realm, V) {
var val = this._dereference(realm, V);
if (val instanceof _index.AbstractValue) return realm.simplifyAndRefineAbstractCondition(val);
return val;
}
}, {
key: "_dereference",
value: function _dereference(realm, V) {
// This step is not necessary as we propagate completions with exceptions.
// 1. ReturnIfAbrupt(V).
// 2. If Type(V) is not Reference, return V.
if (!(V instanceof _environment.Reference)) return V;
// 3. Let base be GetBase(V).
var base = this.GetBase(realm, V);
// 4. If IsUnresolvableReference(V) is true, throw a ReferenceError exception.
if (this.IsUnresolvableReference(realm, V)) {
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError, V.referencedName.toString() + " is not defined");
}
// 5. If IsPropertyReference(V) is true, then
if (this.IsPropertyReference(realm, V)) {
// a. If HasPrimitiveBase(V) is true, then
if (this.HasPrimitiveBase(realm, V)) {
// i. Assert: In this case, base will never be null or undefined.
(0, _invariant2.default)(base instanceof _index.Value && !(0, _index2.HasSomeCompatibleType)(base, _index.UndefinedValue, _index.NullValue));
// ii. Let base be To.ToObject(base).
base = _singletons.To.ToObjectPartial(realm, base);
}
(0, _invariant2.default)(base instanceof _index.ObjectValue || base instanceof _index.AbstractObjectValue);
// b. Return ? base.[[Get]](GetReferencedName(V), GetThisValue(V)).
return base.$GetPartial(this.GetReferencedNamePartial(realm, V), (0, _index2.GetThisValue)(realm, V));
}
// 6. Else base must be an Environment Record,
if (base instanceof _environment.EnvironmentRecord) {
// a. Return ? base.GetBindingValue(GetReferencedName(V), IsStrictReference(V)) (see 8.1.1).
var referencedName = this.GetReferencedName(realm, V);
(0, _invariant2.default)(typeof referencedName === "string");
return base.GetBindingValue(referencedName, this.IsStrictReference(realm, V));
}
(0, _invariant2.default)(false);
}
// ECMA262 6.2.3
// IsStrictReference(V). Returns the strict reference flag component of the reference V.
}, {
key: "IsStrictReference",
value: function IsStrictReference(realm, V) {
return V.strict;
}
// ECMA262 6.2.3
// IsPropertyReference(V). Returns true if either the base value is an object or HasPrimitiveBase(V) is true; otherwise returns false.
}, {
key: "IsPropertyReference",
value: function IsPropertyReference(realm, V) {
// V.base is AbstractValue | void | ObjectValue | BooleanValue | StringValue | SymbolValue | NumberValue | EnvironmentRecord;
return V.base instanceof _index.AbstractValue || V.base instanceof _index.ObjectValue || this.HasPrimitiveBase(realm, V);
}
// ECMA262 6.2.3
// GetBase(V). Returns the base value component of the reference V.
}, {
key: "GetBase",
value: function GetBase(realm, V) {
return V.base;
}
// ECMA262 6.2.3
// IsUnresolvableReference(V). Returns true if the base value is undefined and false otherwise.
}, {
key: "IsUnresolvableReference",
value: function IsUnresolvableReference(realm, V) {
return !V.base;
}
// ECMA262 8.1.2.2
}, {
key: "NewDeclarativeEnvironment",
value: function NewDeclarativeEnvironment(realm, E) {
var active = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
// 1. Let env be a new Lexical Environment.
var env = new _environment.LexicalEnvironment(realm);
if (active) realm.activeLexicalEnvironments.add(env);
// 2. Let envRec be a new declarative Environment Record containing no bindings.
var envRec = new _environment.DeclarativeEnvironmentRecord(realm);
// 3. Set env's EnvironmentRecord to envRec.
env.environmentRecord = envRec;
// 4. Set the outer lexical environment reference of env to E.
env.parent = E;
// 5. Return env.
return env;
}
}, {
key: "BoundNames",
value: function BoundNames(realm, node) {
return Object.keys(t.getOuterBindingIdentifiers(node));
}
// ECMA262 13.3.3.2
}, {
key: "ContainsExpression",
value: function ContainsExpression(realm, node) {
if (!node) {
return false;
}
switch (node.type) {
case "ObjectPattern":
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = node.properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var prop = _step.value;
if (this.ContainsExpression(realm, prop)) return true;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return false;
case "ArrayPattern":
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = node.elements[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var elem = _step2.value;
if (this.ContainsExpression(realm, elem)) return true;
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return false;
case "RestElement":
return this.ContainsExpression(realm, node.argument);
case "AssignmentPattern":
return true;
default:
return false;
}
}
// ECMA262 8.3.2
}, {
key: "ResolveBinding",
value: function ResolveBinding(realm, name, strict, env) {
// 1. If env was not passed or if env is undefined, then
if (!env) {
// a. Let env be the running execution context's LexicalEnvironment.
env = realm.getRunningContext().lexicalEnvironment;
}
// 2. Assert: env is a Lexical Environment.
(0, _invariant2.default)(env instanceof _environment.LexicalEnvironment, "expected lexical environment");
// 3. If the code matching the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
// 4. Return ? GetIdentifierReference(env, name, strict).
return this.GetIdentifierReference(realm, env, name, strict);
}
// ECMA262 8.1.2.1
}, {
key: "GetIdentifierReference",
value: function GetIdentifierReference(realm, lex, name, strict) {
// 1. If lex is the value null, then
if (!lex) {
// a. Return a value of type Reference whose base value is undefined, whose referenced name is name, and whose strict reference flag is strict.
return new _environment.Reference(undefined, name, strict);
}
// 2. Let envRec be lex's EnvironmentRecord.
var envRec = lex.environmentRecord;
// 3. Let exists be ? envRec.HasBinding(name).
var exists = envRec.HasBinding(name);
// 4. If exists is true, then
if (exists) {
// a. Return a value of type Reference whose base value is envRec, whose referenced name is name, and whose strict reference flag is strict.
return new _environment.Reference(envRec, name, strict);
} else {
// 5. Else,
// a. Let outer be the value of lex's outer environment reference.
var outer = lex.parent;
// b. Return ? GetIdentifierReference(outer, name, strict).
return this.GetIdentifierReference(realm, outer, name, strict);
}
}
// ECMA262 6.2.3.4
}, {
key: "InitializeReferencedBinding",
value: function InitializeReferencedBinding(realm, V, W) {
// 1. ReturnIfAbrupt(V).
// 2. ReturnIfAbrupt(W).
// 3. Assert: Type(V) is Reference.
(0, _invariant2.default)(V instanceof _environment.Reference, "expected reference");
// 4. Assert: IsUnresolvableReference(V) is false.
(0, _invariant2.default)(!this.IsUnresolvableReference(realm, V), "expected resolvable reference");
// 5. Let base be GetBase(V).
var base = this.GetBase(realm, V);
// 6. Assert: base is an Environment Record.
(0, _invariant2.default)(base instanceof _environment.EnvironmentRecord, "expected environment record");
// 7. Return base.InitializeBinding(GetReferencedName(V), W).
var referencedName = this.GetReferencedName(realm, V);
(0, _invariant2.default)(typeof referencedName === "string");
return base.InitializeBinding(referencedName, W);
}
// ECMA262 13.2.14
}, {
key: "BlockDeclarationInstantiation",
value: function BlockDeclarationInstantiation(realm, strictCode, body, env) {
// 1. Let envRec be env's EnvironmentRecord.
var envRec = env.environmentRecord;
// 2. Assert: envRec is a declarative Environment Record.
(0, _invariant2.default)(envRec instanceof _environment.DeclarativeEnvironmentRecord, "expected declarative environment record");
// 3. Let declarations be the LexicallyScopedDeclarations of code.
var declarations = [];
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = body[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var node = _step3.value;
if (node.type === "ClassDeclaration" || node.type === "FunctionDeclaration" || node.type === "VariableDeclaration" && node.kind !== "var") {
declarations.push(node);
}
}
// 4. For each element d in declarations do
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = declarations[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var d = _step4.value;
// a. For each element dn of the BoundNames of d do
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = this.BoundNames(realm, d)[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var dn = _step5.value;
if (envRec.HasBinding(dn)) {
//ECMA262 13.2.1
throw realm.createErrorThrowCompletion(realm.intrinsics.SyntaxError, dn + " already declared");
}
// i. If IsConstantDeclaration of d is true, then
if (d.type === "VariableDeclaration" && d.kind === "const") {
// 1. Perform ! envRec.CreateImmutableBinding(dn, true).
envRec.CreateImmutableBinding(dn, true);
} else {
// ii. Else,
// 1. Perform ! envRec.CreateMutableBinding(dn, false).
envRec.CreateMutableBinding(dn, false);
}
}
// b. If d is a GeneratorDeclaration production or a FunctionDeclaration production, then
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
if (d.type === "FunctionDeclaration") {
// i. Let fn be the sole element of the BoundNames of d.
var fn = this.BoundNames(realm, d)[0];
// ii. Let fo be the result of performing InstantiateFunctionObject for d with argument env.
var fo = env.evaluate(d, strictCode);
(0, _invariant2.default)(fo instanceof _index.Value);
// iii. Perform envRec.InitializeBinding(fn, fo).
envRec.InitializeBinding(fn, fo);
}
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
}
// ECMA262 8.1.2.5
}, {
key: "NewGlobalEnvironment",
value: function NewGlobalEnvironment(realm, G, thisValue) {
// 1. Let env be a new Lexical Environment.
var env = new _environment.LexicalEnvironment(realm);
// 2. Let objRec be a new object Environment Record containing G as the binding object.
var objRec = new _environment.ObjectEnvironmentRecord(realm, G);
// 3. Let dclRec be a new declarative Environment Record containing no bindings.
var dclRec = new _environment.DeclarativeEnvironmentRecord(realm);
// 4. Let globalRec be a new global Environment Record.
var globalRec = new _environment.GlobalEnvironmentRecord(realm);
// 5. Set globalRec.[[ObjectRecord]] to objRec.
globalRec.$ObjectRecord = objRec;
// 6. Set globalRec.[[GlobalThisValue]] to thisValue.
globalRec.$GlobalThisValue = thisValue;
// 7. Set globalRec.[[DeclarativeRecord]] to dclRec.
globalRec.$DeclarativeRecord = dclRec;
// 8. Set globalRec.[[VarNames]] to a new empty List.
globalRec.$VarNames = [];
// 9. Set env's EnvironmentRecord to globalRec.
env.environmentRecord = globalRec;
realm.activeLexicalEnvironments.add(env);
// 10. Set the outer lexical environment reference of env to null.
env.parent = null;
// 11. Return env.
return env;
}
// ECMA262 8.1.2.3
}, {
key: "NewObjectEnvironment",
value: function NewObjectEnvironment(realm, O, E) {
// 1. Let env be a new Lexical Environment.
var env = new _environment.LexicalEnvironment(realm);
realm.activeLexicalEnvironments.add(env);
// 2. Let envRec be a new object Environment Record containing O as the binding object.
var envRec = new _environment.ObjectEnvironmentRecord(realm, O);
// 3. Set env's EnvironmentRecord to envRec.
env.environmentRecord = envRec;
// 4. Set the outer lexical environment reference of env to E.
env.parent = E;
// 5. Return env.
return env;
}
// ECMA262 8.1.2.4
}, {
key: "NewFunctionEnvironment",
value: function NewFunctionEnvironment(realm, F, newTarget) {
// 1. Assert: F is an ECMAScript function.
(0, _invariant2.default)(F instanceof _index.ECMAScriptFunctionValue, "expected a function");
// 2. Assert: Type(newTarget) is Undefined or Object.
(0, _invariant2.default)(newTarget === undefined || newTarget instanceof _index.ObjectValue, "expected undefined or object value for new target");
// 3. Let env be a new Lexical Environment.
var env = new _environment.LexicalEnvironment(realm);
realm.activeLexicalEnvironments.add(env);
// 4. Let envRec be a new function Environment Record containing no bindings.
var envRec = new _environment.FunctionEnvironmentRecord(realm);
// 5. Set envRec.[[FunctionObject]] to F.
envRec.$FunctionObject = F;
// 6. If F's [[ThisMode]] internal slot is lexical, set envRec.[[ThisBindingStatus]] to "lexical".
if (F.$ThisMode === "lexical") {
envRec.$ThisBindingStatus = "lexical";
} else {
// 7. Else, set envRec.[[ThisBindingStatus]] to "uninitialized".
envRec.$ThisBindingStatus = "uninitialized";
}
// 8. Let home be the value of F's [[HomeObject]] internal slot.
var home = F.$HomeObject;
// 9. Set envRec.[[HomeObject]] to home.
envRec.$HomeObject = home;
// 10. Set envRec.[[NewTarget]] to newTarget.
envRec.$NewTarget = newTarget;
// 11. Set env's EnvironmentRecord to envRec.
env.environmentRecord = envRec;
// 12. Set the outer lexical environment reference of env to the value of F's [[Environment]] internal slot.
env.parent = F.$Environment;
// 13. Return env.
return env;
}
// ECMA262 8.3.1
}, {
key: "GetActiveScriptOrModule",
value: function GetActiveScriptOrModule(realm) {
// The GetActiveScriptOrModule abstract operation is used to determine the running script or module, based on the active function object.
// GetActiveScriptOrModule performs the following steps:
//
// If the execution context stack is empty, return null.
if (realm.contextStack.length === 0) return null;
// Let ec be the topmost execution context on the execution context stack whose Function component's [[ScriptOrModule]] component is not null.
// If such an execution context exists, return ec's Function component's [[ScriptOrModule]] slot's value.
var ec = void 0;
for (var i = realm.contextStack.length - 1; i >= 0; i--) {
ec = realm.contextStack[i];
var F = ec.function;
if (F == null) continue;
if (F.$ScriptOrModule instanceof Object) {
return F.$ScriptOrModule;
}
}
// Otherwise, let ec be the running execution context.
ec = realm.getRunningContext();
// Assert: ec's ScriptOrModule component is not null.
(0, _invariant2.default)(ec.ScriptOrModule !== null);
// Return ec's ScriptOrModule component.
return ec.ScriptOrModule;
}
// ECMA262 8.3.3
}, {
key: "GetThisEnvironment",
value: function GetThisEnvironment(realm) {
// 1. Let lex be the running execution context's LexicalEnvironment.
var lex = realm.getRunningContext().lexicalEnvironment;
// 2. Repeat
while (true) {
// a. Let envRec be lex's EnvironmentRecord.
var envRec = lex.environmentRecord;
// b. Let exists be envRec.HasThisBinding().
var exists = envRec.HasThisBinding();
// c. If exists is true, return envRec.
if (exists) return envRec;
// d. Let outer be the value of lex's outer environment reference.
var outer = lex.parent;
(0, _invariant2.default)(outer);
// e. Let lex be outer.
lex = outer;
}
(0, _invariant2.default)(false);
}
// ECMA262 8.3.4
}, {
key: "ResolveThisBinding",
value: function ResolveThisBinding(realm) {
// 1. Let envRec be GetThisEnvironment( ).
var envRec = this.GetThisEnvironment(realm);
// 2. Return ? envRec.GetThisBinding().
return envRec.GetThisBinding();
}
}, {
key: "BindingInitialization",
value: function BindingInitialization(realm, node, value, strictCode, environment) {
if (node.type === "ArrayPattern") {
// ECMA262 13.3.3.5
// 1. Let iterator be ? GetIterator(value).
var iterator = (0, _index2.GetIterator)(realm, value);
// 2. Let iteratorRecord be Record {[[Iterator]]: iterator, [[Done]]: false}.
var iteratorRecord = {
$Iterator: iterator,
$Done: false
};
var result = void 0;
// 3. Let result be IteratorBindingInitialization for ArrayBindingPattern using iteratorRecord and environment as arguments.
try {
result = this.IteratorBindingInitialization(realm, node.elements, iteratorRecord, strictCode, environment);
} catch (error) {
// 4. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, result).
if (iteratorRecord.$Done === false && error instanceof _completions.AbruptCompletion) {
throw (0, _index2.IteratorClose)(realm, iterator, error);
}
throw error;
}
// 4. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iterator, result).
if (iteratorRecord.$Done === false) {
var completion = (0, _index2.IteratorClose)(realm, iterator, new _completions.NormalCompletion(realm.intrinsics.undefined));
if (completion instanceof _completions.AbruptCompletion) {
throw completion;
}
}
// 5. Return result.
return result;
} else if (node.type === "ObjectPattern") {
// ECMA262 13.3.3.5
// BindingPattern : ObjectBindingPattern
// 1. Perform ? RequireObjectCoercible(value).
(0, _index2.RequireObjectCoercible)(realm, value);
// 2. Return the result of performing BindingInitialization for ObjectBindingPattern using value and environment as arguments.
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = node.properties[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var property = _step6.value;
var env = environment ? environment : realm.getRunningContext().lexicalEnvironment;
// 1. Let P be the result of evaluating PropertyName.
var P = (0, _ObjectExpression.EvalPropertyName)(property, env, realm, strictCode);
// 2. ReturnIfAbrupt(P).
// 3. Return the result of performing KeyedBindingInitialization for BindingElement using value, environment, and P as arguments.
this.KeyedBindingInitialization(realm, property.value, value, strictCode, environment, P);
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
} else if (node.type === "Identifier") {
// ECMA262 12.1.5
// 1. Let name be StringValue of Identifier.
var name = node.name;
// 2. Return ? InitializeBoundName(name, value, environment).
return this.InitializeBoundName(realm, name, value, environment);
} else {
(0, _invariant2.default)(node.type === "VariableDeclaration");
// ECMA262 13.7.5.9
var _iteratorNormalCompletion7 = true;
var _didIteratorError7 = false;
var _iteratorError7 = undefined;
try {
for (var _iterator7 = node.declarations[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
var decl = _step7.value;
this.BindingInitialization(realm, decl.id, value, strictCode, environment);
}
} catch (err) {
_didIteratorError7 = true;
_iteratorError7 = err;
} finally {
try {
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
} finally {
if (_didIteratorError7) {
throw _iteratorError7;
}
}
}
}
}
// ECMA262 13.3.3.6
// ECMA262 14.1.19
}, {
key: "IteratorBindingInitialization",
value: function IteratorBindingInitialization(realm, formals, iteratorRecord, strictCode, environment) {
var env = environment ? environment : realm.getRunningContext().lexicalEnvironment;
// Check if the last formal is a rest element. If so then we want to save the
// element and handle it separately after we iterate through the other
// formals. This also enforces that a rest element may only ever be in the
// last position.
var restEl = void 0;
if (formals.length > 0) {
var lastFormal = formals[formals.length - 1];
if (lastFormal !== null && lastFormal.type === "RestElement") {
restEl = lastFormal;
formals = formals.slice(0, -1);
}
}
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 === null) {
// Elision handling in IteratorDestructuringAssignmentEvaluation
// 1. If iteratorRecord.[[Done]] is false, then
if (iteratorRecord.$Done === false) {
// a. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
var _next2 = void 0;
try {
_next2 = (0, _index2.IteratorStep)(realm, iteratorRecord.$Iterator);
} catch (e) {
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// c. ReturnIfAbrupt(next).
throw e;
}
// d. If next is false, set iteratorRecord.[[Done]] to true.
if (_next2 === false) {
iteratorRecord.$Done = true;
}
}
// 2. Return NormalCompletion(empty).
continue;
}
var Initializer = void 0;
if (param.type === "AssignmentPattern") {
Initializer = param.right;
param = param.left;
}
if (param.type === "Identifier") {
// SingleNameBinding : BindingIdentifier Initializer
// 1. Let bindingId be StringValue of BindingIdentifier.
var bindingId = param.name;
// 2. Let lhs be ? ResolveBinding(bindingId, environment).
var _lhs = this.ResolveBinding(realm, param.name, strictCode, environment);
// Initialized later in the algorithm.
var v = void 0;
// 3. If iteratorRecord.[[Done]] is false, then
if (iteratorRecord.$Done === false) {
// a. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
var _next3 = void 0;
try {
_next3 = (0, _index2.IteratorStep)(realm, iteratorRecord.$Iterator);
} catch (e) {
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// c. ReturnIfAbrupt(next).
throw e;
}
// d. If next is false, set iteratorRecord.[[Done]] to true.
if (_next3 === false) {
iteratorRecord.$Done = true;
// Normally this assignment would be done in step 4, but we do it
// here so that Flow knows `v` will always be initialized by step 5.
v = realm.intrinsics.undefined;
} else {
// e. Else,
// i. Let v be IteratorValue(next).
try {
v = (0, _index2.IteratorValue)(realm, _next3);
} catch (e) {
// ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// iii. ReturnIfAbrupt(v).
throw e;
}
}
} else {
// 4. If iteratorRecord.[[Done]] is true, let v be undefined.
v = realm.intrinsics.undefined;
}
// 5. If Initializer is present and v is undefined, then
if (Initializer && v instanceof _index.UndefinedValue) {
// a. Let defaultValue be the result of evaluating Initializer.
var defaultValue = env.evaluate(Initializer, strictCode);
// b. Let v be ? GetValue(defaultValue).
v = this.GetValue(realm, defaultValue);
// c. If IsAnonymousFunctionDefinition(Initializer) is true, then
if ((0, _index2.IsAnonymousFunctionDefinition)(realm, Initializer) && v instanceof _index.ObjectValue) {
// i. Let hasNameProperty be ? HasOwnProperty(v, "name").
var hasNameProperty = (0, _index2.HasOwnProperty)(realm, v, "name");
// ii. If hasNameProperty is false, perform SetFunctionName(v, bindingId).
if (hasNameProperty === false) {
_singletons.Functions.SetFunctionName(realm, v, bindingId);
}
}
}
// 6. If environment is undefined, return ? PutValue(lhs, v).
if (!environment) {
_singletons.Properties.PutValue(realm, _lhs, v);
continue;
}
// 7. Return InitializeReferencedBinding(lhs, v).
this.InitializeReferencedBinding(realm, _lhs, v);
continue;
} else {
(0, _invariant2.default)(param.type === "ObjectPattern" || param.type === "ArrayPattern");
// BindingElement : BindingPatternInitializer
// Initialized later in the algorithm.
var _v = void 0;
// 1. If iteratorRecord.[[Done]] is false, then
if (iteratorRecord.$Done === false) {
// a. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
var _next4 = void 0;
try {
_next4 = (0, _index2.IteratorStep)(realm, iteratorRecord.$Iterator);
} catch (e) {
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// c. ReturnIfAbrupt(next).
throw e;
}
// d. If next is false, set iteratorRecord.[[Done]] to true.
if (_next4 === false) {
iteratorRecord.$Done = true;
// Normally this assignment would be done in step 2, but we do it
// here so that Flow knows `v` will always be initialized by step 3.
_v = realm.intrinsics.undefined;
} else {
// e. Else,
// i. Let v be IteratorValue(next).
try {
_v = (0, _index2.IteratorValue)(realm, _next4);
} catch (e) {
// ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// iii. ReturnIfAbrupt(v).
throw e;
}
}
} else {
// 2. If iteratorRecord.[[Done]] is true, let v be undefined.
_v = realm.intrinsics.undefined;
}
// 3. If Initializer is present and v is undefined, then
if (Initializer && _v instanceof _index.UndefinedValue) {
// a. Let defaultValue be the result of evaluating Initializer.
var _defaultValue = env.evaluate(Initializer, strictCode);
// b. Let v be ? GetValue(defaultValue).
_v = this.GetValue(realm, _defaultValue);
}
// 4. Return the result of performing BindingInitialization of BindingPattern with v and environment as the arguments.
this.BindingInitialization(realm, param, _v, strictCode, environment);
continue;
}
}
// Handle the rest element if we have one.
} catch (err) {
_didIteratorError8 = true;
_iteratorError8 = err;
} finally {
try {
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
} finally {
if (_didIteratorError8) {
throw _iteratorError8;
}
}
}
if (restEl && restEl.argument.type === "Identifier") {
// BindingRestElement : ...BindingIdentifier
// 1. Let lhs be ? ResolveBinding(StringValue of BindingIdentifier, environment).
var lhs = this.ResolveBinding(realm, restEl.argument.name, strictCode, environment);
// 2. Let A be ArrayCreate(0).
var A = _singletons.Create.ArrayCreate(realm, 0);
// 3. Let n be 0.
var n = 0;
// 4. Repeat,
while (true) {
// Initialized later in the algorithm.
var next = void 0;
// a. If iteratorRecord.[[Done]] is false, then
if (iteratorRecord.$Done === false) {
// i. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
try {
next = (0, _index2.IteratorStep)(realm, iteratorRecord.$Iterator);
} catch (e) {
// ii. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// iii. ReturnIfAbrupt(next).
throw e;
}
// iv. If next is false, set iteratorRecord.[[Done]] to true.
if (next === false) {
iteratorRecord.$Done = true;
}
}
// b. If iteratorRecord.[[Done]] is true, then
if (iteratorRecord.$Done === true) {
// i. If environment is undefined, return ? PutValue(lhs, A).
if (!environment) {
_singletons.Properties.PutValue(realm, lhs, A);
break;
}
// ii. Return InitializeReferencedBinding(lhs, A).
this.InitializeReferencedBinding(realm, lhs, A);
break;
}
// Given the nature of the algorithm this should always be true, however
// it is difficult to arrange the code in such a way where Flow's control
// flow analysis will pick that up, so we add an invariant here.
(0, _invariant2.default)(next instanceof _index.ObjectValue);
// c. Let nextValue be IteratorValue(next).
var nextValue = void 0;
try {
nextValue = (0, _index2.IteratorValue)(realm, next);
} catch (e) {
// d. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// e. ReturnIfAbrupt(nextValue).
throw e;
}
// f. Let status be CreateDataProperty(A, ! To.ToString(n), nextValue).
var status = _singletons.Create.CreateDataProperty(realm, A, n.toString(), nextValue);
// g. Assert: status is true.
(0, _invariant2.default)(status, "expected to create data property");
// h. Increment n by 1.
n += 1;
}
} else if (restEl) {
(0, _invariant2.default)(restEl.argument.type === "ArrayPattern" || restEl.argument.type === "ObjectPattern");
// 1. Let A be ArrayCreate(0).
var _A = _singletons.Create.ArrayCreate(realm, 0);
// 2. Let n be 0.
var _n = 0;
// 3. Repeat,
while (true) {
// Initialized later in the algorithm.
var _next = void 0;
// a. If iteratorRecord.[[Done]] is false, then
if (iteratorRecord.$Done === false) {
// i. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
try {
_next = (0, _index2.IteratorStep)(realm, iteratorRecord.$Iterator);
} catch (e) {
// ii. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// iii. ReturnIfAbrupt(next).
throw e;
}
// iv. If next is false, set iteratorRecord.[[Done]] to true.
if (_next === false) {
iteratorRecord.$Done = true;
}
}
// b. If iteratorRecord.[[Done]] is true, then
if (iteratorRecord.$Done === true) {
// i. Return the result of performing BindingInitialization of BindingPattern with A and environment as the arguments.
this.BindingInitialization(realm, restEl.argument, _A, strictCode, environment);
break;
}
// Given the nature of the algorithm this should always be true, however
// it is difficult to arrange the code in such a way where Flow's control
// flow analysis will pick that up, so we add an invariant here.
(0, _invariant2.default)(_next instanceof _index.ObjectValue);
// c. Let nextValue be IteratorValue(next).
var _nextValue = void 0;
try {
_nextValue = (0, _index2.IteratorValue)(realm, _next);
} catch (e) {
// d. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
if (e instanceof _completions.AbruptCompletion) {
iteratorRecord.$Done = true;
}
// e. ReturnIfAbrupt(nextValue).
throw e;
}
// f. Let status be CreateDataProperty(A, ! To.ToString(n), nextValue).
var _status = _singletons.Create.CreateDataProperty(realm, _A, _n.toString(), _nextValue);
// g. Assert: status is true.
(0, _invariant2.default)(_status, "expected to create data property");
// h. Increment n by 1.
_n += 1;
}
}
}
// ECMA262 12.1.5.1
}, {
key: "InitializeBoundName",
value: function InitializeBoundName(realm, name, value, environment) {
// 1. Assert: Type(name) is String.
(0, _invariant2.default)(typeof name === "string", "expected name to be a string");
// 2. If environment is not undefined, then
if (environment) {
// a. Let env be the EnvironmentRecord component of environment.
var env = environment.environmentRecord;
// b. Perform env.InitializeBinding(name, value).
env.InitializeBinding(name, value);
// c. Return NormalCompletion(undefined).
return realm.intrinsics.undefined;
} else {
// 3. Else,
// a. Let lhs be ResolveBinding(name).
// Note that the undefined environment implies non-strict.
var lhs = this.ResolveBinding(realm, name, false);
// b. Return ? PutValue(lhs, value).
return _singletons.Properties.PutValue(realm, lhs, value);
}
}
// ECMA262 12.3.1.3 and 13.7.5.6
}, {
key: "IsDestructuring",
value: function IsDestructuring(ast) {
switch (ast.type) {
case "VariableDeclaration":
var _iteratorNormalCompletion9 = true;
var _didIteratorError9 = false;
var _iteratorError9 = undefined;
try {
for (var _iterator9 = ast.declarations[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
var decl = _step9.value;
switch (decl.type) {
case "VariableDeclarator":
switch (decl.id.type) {
case "ArrayPattern":
case "AssignmentPattern":
case "ObjectPattern":
return true;
default:
break;
}
break;
default:
break;
}
}
} catch (err) {
_didIteratorError9 = true;
_iteratorError9 = err;
} finally {
try {
if (!_iteratorNormalCompletion9 && _iterator9.return) {
_iterator9.return();
}
} finally {
if (_didIteratorError9) {
throw _iteratorError9;
}
}
}
return false;
case "ArrayLiteral":
case "ObjectLiteral":
return true;
case "ArrayPattern":
case "ObjectPattern":
return true;
default:
return false;
}
}
// ECMA262 13.3.3.7
}, {
key: "KeyedBindingInitialization",
value: function KeyedBindingInitialization(realm, node, value, strictCode, environment, propertyName) {
var env = environment ? environment : realm.getRunningContext().lexicalEnvironment;
var Initializer = void 0;
if (node.type === "AssignmentPattern") {
Initializer = node.right;
node = node.left;
}
if (node.type === "Identifier") {
// SingleNameBinding : BindingIdentifier Initializer
// 1. Let bindingId be StringValue of BindingIdentifier.
var bindingId = node.name;
// 2. Let lhs be ? ResolveBinding(bindingId, environment).
var lhs = this.ResolveBinding(realm, bindingId, strictCode, environment);
// 3. Let v be ? GetV(value, propertyName).
var v = (0, _index2.GetV)(realm, value, propertyName);
// 4. If Initializer is present and v is undefined, then
if (Initializer && v instanceof _index.UndefinedValue) {
// a. Let defaultValue be the result of evaluating Initializer.
var defaultValue = env.evaluate(Initializer, strictCode);
// b. Let v be ? GetValue(defaultValue).
v = this.GetValue(realm, defaultValue);
// c. If IsAnonymousFunctionDefinition(Initializer) is true, then
if ((0, _index2.IsAnonymousFunctionDefinition)(realm, Initializer) && v instanceof _index.ObjectValue) {
// i. Let hasNameProperty be ? HasOwnProperty(v, "name").
var hasNameProperty = (0, _index2.HasOwnProperty)(realm, v, "name");
// ii. If hasNameProperty is false, perform SetFunctionName(v, bindingId).
if (hasNameProperty === false) {
_singletons.Functions.SetFunctionName(realm, v, bindingId);
}
}
}
// 5. If environment is undefined, return ? PutValue(lhs, v).
if (!environment) return _singletons.Properties.PutValue(realm, lhs, v);
// 6. Return InitializeReferencedBinding(lhs, v).
return this.InitializeReferencedBinding(realm, lhs, v);
} else if (node.type === "ObjectPattern" || node.type === "ArrayPattern") {
// BindingElement : BindingPattern Initializer
// 1. Let v be ? GetV(value, propertyName).
var _v2 = (0, _index2.GetV)(realm, value, propertyName);
// 2. If Initializer is present and v is undefined, then
if (Initializer && _v2 instanceof _index.UndefinedValue) {
// a. Let defaultValue be the result of evaluating Initializer.
var _defaultValue2 = env.evaluate(Initializer, strictCode);
// b. Let v be ? GetValue(defaultValue).
_v2 = this.GetValue(realm, _defaultValue2);
}
// 3. Return the result of performing BindingInitialization for BindingPattern passing v and environment as arguments.
return this.BindingInitialization(realm, node, _v2, strictCode, env);
}
}
}]);
return EnvironmentImplementation;
}();
//# sourceMappingURL=environment.js.map