1579 lines
54 KiB
JavaScript
1579 lines
54 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.Reference = exports.LexicalEnvironment = exports.GlobalEnvironmentRecord = exports.FunctionEnvironmentRecord = exports.ObjectEnvironmentRecord = exports.DeclarativeEnvironmentRecord = exports.EnvironmentRecord = 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; }; }();
|
|
|
|
exports.leakBinding = leakBinding;
|
|
exports.canBecomeAnObject = canBecomeAnObject;
|
|
|
|
var _completions = require("./completions.js");
|
|
|
|
var _errors = require("./errors.js");
|
|
|
|
var _options = require("./options");
|
|
|
|
var _realm = require("./realm.js");
|
|
|
|
var _index = require("./values/index.js");
|
|
|
|
var _babelGenerator = require("babel-generator");
|
|
|
|
var _babelGenerator2 = _interopRequireDefault(_babelGenerator);
|
|
|
|
var _parse = require("./utils/parse.js");
|
|
|
|
var _parse2 = _interopRequireDefault(_parse);
|
|
|
|
var _invariant = require("./invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
var _traverseFast = require("./utils/traverse-fast.js");
|
|
|
|
var _traverseFast2 = _interopRequireDefault(_traverseFast);
|
|
|
|
var _index2 = require("./methods/index.js");
|
|
|
|
var _singletons = require("./singletons.js");
|
|
|
|
var _babelTypes = require("babel-types");
|
|
|
|
var t = _interopRequireWildcard(_babelTypes);
|
|
|
|
var _index3 = require("./domains/index.js");
|
|
|
|
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 _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
|
|
* 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 sourceMap = require("source-map");
|
|
|
|
function deriveGetBinding(realm, binding) {
|
|
var types = _index3.TypesDomain.topVal;
|
|
var values = _index3.ValuesDomain.topVal;
|
|
(0, _invariant2.default)(realm.generator !== undefined);
|
|
return realm.generator.derive(types, values, [], function (_, context) {
|
|
return context.serializeBinding(binding);
|
|
});
|
|
}
|
|
|
|
function leakBinding(binding) {
|
|
var realm = binding.environment.realm;
|
|
if (!binding.hasLeaked) {
|
|
realm.recordModifiedBinding(binding).hasLeaked = true;
|
|
}
|
|
}
|
|
|
|
// ECMA262 8.1.1
|
|
|
|
var EnvironmentRecord = exports.EnvironmentRecord = function EnvironmentRecord(realm) {
|
|
_classCallCheck(this, EnvironmentRecord);
|
|
|
|
(0, _invariant2.default)(realm, "expected realm");
|
|
this.realm = realm;
|
|
this.isReadOnly = false;
|
|
};
|
|
|
|
// ECMA262 8.1.1.1
|
|
var DeclarativeEnvironmentRecord = exports.DeclarativeEnvironmentRecord = function (_EnvironmentRecord) {
|
|
_inherits(DeclarativeEnvironmentRecord, _EnvironmentRecord);
|
|
|
|
function DeclarativeEnvironmentRecord(realm) {
|
|
_classCallCheck(this, DeclarativeEnvironmentRecord);
|
|
|
|
var _this = _possibleConstructorReturn(this, (DeclarativeEnvironmentRecord.__proto__ || Object.getPrototypeOf(DeclarativeEnvironmentRecord)).call(this, realm));
|
|
|
|
_this.bindings = Object.create(null);
|
|
_this.frozen = false;
|
|
return _this;
|
|
}
|
|
// Frozen Records cannot have bindings created or deleted but can have bindings updated
|
|
|
|
|
|
_createClass(DeclarativeEnvironmentRecord, [{
|
|
key: "HasBinding",
|
|
|
|
|
|
// ECMA262 8.1.1.1.1
|
|
value: function HasBinding(N) {
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. If envRec has a binding for the name that is the value of N, return true.
|
|
if (envRec.bindings[N]) return true;
|
|
|
|
// 3. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.2
|
|
|
|
}, {
|
|
key: "CreateMutableBinding",
|
|
value: function CreateMutableBinding(N, D) {
|
|
var isGlobal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
|
|
(0, _invariant2.default)(!this.frozen);
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Assert: envRec does not already have a binding for N.
|
|
(0, _invariant2.default)(!envRec.bindings[N], "shouldn't have the binding " + N);
|
|
|
|
// 3. Create a mutable binding in envRec for N and record that it is uninitialized. If D is true, record that the newly created binding may be deleted by a subsequent DeleteBinding call.
|
|
this.bindings[N] = realm.recordModifiedBinding({
|
|
initialized: false,
|
|
mutable: true,
|
|
deletable: D,
|
|
environment: envRec,
|
|
name: N,
|
|
isGlobal: isGlobal,
|
|
hasLeaked: false
|
|
});
|
|
|
|
// 4. Return NormalCompletion(empty).
|
|
return realm.intrinsics.undefined;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.3
|
|
|
|
}, {
|
|
key: "CreateImmutableBinding",
|
|
value: function CreateImmutableBinding(N, S) {
|
|
var isGlobal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
|
|
(0, _invariant2.default)(!this.frozen);
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Assert: envRec does not already have a binding for N.
|
|
(0, _invariant2.default)(!envRec.bindings[N], "shouldn't have the binding " + N);
|
|
|
|
// 3. Create an immutable binding in envRec for N and record that it is uninitialized. If S is true, record that the newly created binding is a strict binding.
|
|
this.bindings[N] = realm.recordModifiedBinding({
|
|
initialized: false,
|
|
strict: S,
|
|
deletable: false,
|
|
environment: envRec,
|
|
name: N,
|
|
isGlobal: isGlobal,
|
|
hasLeaked: false
|
|
});
|
|
|
|
// 4. Return NormalCompletion(empty).
|
|
return realm.intrinsics.undefined;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.4
|
|
|
|
}, {
|
|
key: "InitializeBinding",
|
|
value: function InitializeBinding(N, V) {
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
var binding = envRec.bindings[N];
|
|
|
|
// 2. Assert: envRec must have an uninitialized binding for N.
|
|
(0, _invariant2.default)(binding && !binding.initialized, "shouldn't have the binding " + N);
|
|
|
|
// 3. Set the bound value for N in envRec to V.
|
|
this.realm.recordModifiedBinding(binding).value = V;
|
|
|
|
// 4. Record that the binding for N in envRec has been initialized.
|
|
binding.initialized = true;
|
|
|
|
// 5. Return NormalCompletion(empty).
|
|
return this.realm.intrinsics.empty;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.5
|
|
|
|
}, {
|
|
key: "SetMutableBinding",
|
|
value: function SetMutableBinding(N, V, S) {
|
|
// We can mutate frozen bindings because of captured bindings.
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
var binding = envRec.bindings[N];
|
|
|
|
// 2. If envRec does not have a binding for N, then
|
|
if (!binding) {
|
|
// a. If S is true, throw a ReferenceError exception.
|
|
if (S) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError, N + " not found");
|
|
}
|
|
|
|
// b. Perform envRec.CreateMutableBinding(N, true).
|
|
envRec.CreateMutableBinding(N, true);
|
|
|
|
// c. Perform envRec.InitializeBinding(N, V).
|
|
envRec.InitializeBinding(N, V);
|
|
|
|
// d. Return NormalCompletion(empty).
|
|
return this.realm.intrinsics.empty;
|
|
}
|
|
|
|
// 3. If the binding for N in envRec is a strict binding, let S be true.
|
|
if (binding.strict) S = true;
|
|
|
|
// 4. If the binding for N in envRec has not yet been initialized, throw a ReferenceError exception.
|
|
if (!binding.initialized) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError, N + " has not yet been initialized");
|
|
} else if (binding.mutable) {
|
|
// 5. Else if the binding for N in envRec is a mutable binding, change its bound value to V.
|
|
if (binding.hasLeaked) {
|
|
_singletons.Leak.leakValue(realm, V);
|
|
(0, _invariant2.default)(realm.generator);
|
|
realm.generator.emitBindingAssignment(binding, V);
|
|
} else {
|
|
realm.recordModifiedBinding(binding).value = V;
|
|
}
|
|
} else {
|
|
// 6. Else,
|
|
// a. Assert: This is an attempt to change the value of an immutable binding.
|
|
|
|
// b. If S is true, throw a TypeError exception.
|
|
if (S) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "attempt to change immutable binding");
|
|
}
|
|
}
|
|
|
|
// 7. Return NormalCompletion(empty).
|
|
return this.realm.intrinsics.empty;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.6
|
|
|
|
}, {
|
|
key: "GetBindingValue",
|
|
value: function GetBindingValue(N, S) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
var binding = envRec.bindings[N];
|
|
|
|
// 2. Assert: envRec has a binding for N.
|
|
(0, _invariant2.default)(binding, "expected binding");
|
|
|
|
// 3. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.
|
|
if (!binding.initialized) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError);
|
|
}
|
|
|
|
// 4. Return the value currently bound to N in envRec.
|
|
if (binding.hasLeaked) {
|
|
return deriveGetBinding(realm, binding);
|
|
}
|
|
(0, _invariant2.default)(binding.value);
|
|
return binding.value;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.7
|
|
|
|
}, {
|
|
key: "DeleteBinding",
|
|
value: function DeleteBinding(N) {
|
|
(0, _invariant2.default)(!this.frozen);
|
|
// 1. Let envRec be the declarative Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Assert: envRec has a binding for the name that is the value of N.
|
|
(0, _invariant2.default)(envRec.bindings[N], "expected binding to exist");
|
|
|
|
// 3. If the binding for N in envRec cannot be deleted, return false.
|
|
if (!envRec.bindings[N].deletable) return false;
|
|
|
|
// 4. Remove the binding for N from envRec.
|
|
this.realm.recordModifiedBinding(envRec.bindings[N]).value = undefined;
|
|
delete envRec.bindings[N];
|
|
|
|
// 5. Return true.
|
|
return true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.8
|
|
|
|
}, {
|
|
key: "HasThisBinding",
|
|
value: function HasThisBinding() {
|
|
// 1. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.9
|
|
|
|
}, {
|
|
key: "HasSuperBinding",
|
|
value: function HasSuperBinding() {
|
|
// 1. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.1.10
|
|
|
|
}, {
|
|
key: "WithBaseObject",
|
|
value: function WithBaseObject() {
|
|
// 1. Return undefined.
|
|
return this.realm.intrinsics.undefined;
|
|
}
|
|
}]);
|
|
|
|
return DeclarativeEnvironmentRecord;
|
|
}(EnvironmentRecord);
|
|
|
|
// ECMA262 8.1.1.2
|
|
|
|
|
|
var ObjectEnvironmentRecord = exports.ObjectEnvironmentRecord = function (_EnvironmentRecord2) {
|
|
_inherits(ObjectEnvironmentRecord, _EnvironmentRecord2);
|
|
|
|
function ObjectEnvironmentRecord(realm, obj) {
|
|
_classCallCheck(this, ObjectEnvironmentRecord);
|
|
|
|
var _this2 = _possibleConstructorReturn(this, (ObjectEnvironmentRecord.__proto__ || Object.getPrototypeOf(ObjectEnvironmentRecord)).call(this, realm));
|
|
|
|
_this2.object = obj;
|
|
return _this2;
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.1
|
|
|
|
|
|
_createClass(ObjectEnvironmentRecord, [{
|
|
key: "HasBinding",
|
|
value: function HasBinding(N) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let bindings be the binding object for envRec.
|
|
var bindings = this.object;
|
|
|
|
// 3. Let foundBinding be ? HasProperty(bindings, N).
|
|
var foundBinding = (0, _index2.HasProperty)(realm, bindings, N);
|
|
|
|
// 4. If foundBinding is false, return false.
|
|
if (!foundBinding) return false;
|
|
|
|
// 5. If the withEnvironment flag of envRec is false, return true.
|
|
if (!envRec.withEnvironment) return true;
|
|
|
|
// 6. Let unscopables be ? Get(bindings, @@unscopables).
|
|
var unscopables = (0, _index2.Get)(realm, bindings, realm.intrinsics.SymbolUnscopables);
|
|
|
|
// 7. If Type(unscopables) is Object, then
|
|
if (unscopables instanceof _index.ObjectValue || unscopables instanceof _index.AbstractObjectValue) {
|
|
// a. Let blocked be ToBoolean(? Get(unscopables, N)).
|
|
var blocked = _singletons.To.ToBooleanPartial(realm, (0, _index2.Get)(realm, unscopables, N));
|
|
|
|
// b. If blocked is true, return false.
|
|
if (blocked) return false;
|
|
}
|
|
unscopables.throwIfNotConcrete();
|
|
|
|
// 8. Return true.
|
|
return true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.2
|
|
|
|
}, {
|
|
key: "CreateMutableBinding",
|
|
value: function CreateMutableBinding(N, D) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let bindings be the binding object for envRec.
|
|
var bindings = envRec.object;
|
|
|
|
// 3. If D is true, let configValue be true; otherwise let configValue be false.
|
|
var configValue = D ? true : false;
|
|
|
|
// 4. Return ? DefinePropertyOrThrow(bindings, N, PropertyDescriptor{[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: configValue}).
|
|
return new _index.BooleanValue(realm, _singletons.Properties.DefinePropertyOrThrow(realm, bindings, N, {
|
|
value: realm.intrinsics.undefined,
|
|
writable: true,
|
|
enumerable: true,
|
|
configurable: configValue
|
|
}));
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.3
|
|
|
|
}, {
|
|
key: "CreateImmutableBinding",
|
|
value: function CreateImmutableBinding(N, S) {
|
|
// The concrete Environment Record method CreateImmutableBinding is never used within this specification in association with object Environment Records.
|
|
(0, _invariant2.default)(false);
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.4
|
|
|
|
}, {
|
|
key: "InitializeBinding",
|
|
value: function InitializeBinding(N, V) {
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Assert: envRec must have an uninitialized binding for N.
|
|
// 3. Record that the binding for N in envRec has been initialized.
|
|
|
|
// 4. Return ? envRec.SetMutableBinding(N, V, false).
|
|
return envRec.SetMutableBinding(N, V, false);
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.5
|
|
|
|
}, {
|
|
key: "SetMutableBinding",
|
|
value: function SetMutableBinding(N, V, S) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let bindings be the binding object for envRec.
|
|
var bindings = envRec.object;
|
|
|
|
// 3. Return ? Set(bindings, N, V, S).
|
|
return new _index.BooleanValue(realm, _singletons.Properties.Set(realm, bindings, N, V, S));
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.6
|
|
|
|
}, {
|
|
key: "GetBindingValue",
|
|
value: function GetBindingValue(N, S) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let bindings be the binding object for envRec.
|
|
var bindings = envRec.object;
|
|
|
|
// 3. Let value be ? HasProperty(bindings, N).
|
|
var value = (0, _index2.HasProperty)(realm, bindings, N);
|
|
|
|
// 4. If value is false, then
|
|
if (!value) {
|
|
// a. If S is false, return the value undefined; otherwise throw a ReferenceError exception.
|
|
if (!S) {
|
|
return realm.intrinsics.undefined;
|
|
} else {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError);
|
|
}
|
|
}
|
|
|
|
// 5. Return ? Get(bindings, N).
|
|
return (0, _index2.Get)(realm, bindings, N);
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.7
|
|
|
|
}, {
|
|
key: "DeleteBinding",
|
|
value: function DeleteBinding(N) {
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let bindings be the binding object for envRec.
|
|
var bindings = envRec.object;
|
|
|
|
// 3. Return ? bindings.[[Delete]](N).
|
|
return bindings.$Delete(N);
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.8
|
|
|
|
}, {
|
|
key: "HasThisBinding",
|
|
value: function HasThisBinding() {
|
|
// 1. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.9
|
|
|
|
}, {
|
|
key: "HasSuperBinding",
|
|
value: function HasSuperBinding() {
|
|
// 1. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.2.10
|
|
|
|
}, {
|
|
key: "WithBaseObject",
|
|
value: function WithBaseObject() {
|
|
// 1. Let envRec be the object Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. If the withEnvironment flag of envRec is true, return the binding object for envRec.
|
|
if (envRec.withEnvironment) return envRec.object;
|
|
|
|
// 3. Otherwise, return undefined.
|
|
return this.realm.intrinsics.undefined;
|
|
}
|
|
}]);
|
|
|
|
return ObjectEnvironmentRecord;
|
|
}(EnvironmentRecord);
|
|
|
|
// ECMA262 8.1.1.3
|
|
|
|
|
|
var FunctionEnvironmentRecord = exports.FunctionEnvironmentRecord = function (_DeclarativeEnvironme) {
|
|
_inherits(FunctionEnvironmentRecord, _DeclarativeEnvironme);
|
|
|
|
function FunctionEnvironmentRecord() {
|
|
_classCallCheck(this, FunctionEnvironmentRecord);
|
|
|
|
return _possibleConstructorReturn(this, (FunctionEnvironmentRecord.__proto__ || Object.getPrototypeOf(FunctionEnvironmentRecord)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(FunctionEnvironmentRecord, [{
|
|
key: "BindThisValue",
|
|
|
|
|
|
// ECMA262 8.1.1.3.1
|
|
value: function BindThisValue(V) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the function Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Assert: envRec.[[ThisBindingStatus]] is not "lexical".
|
|
(0, _invariant2.default)(envRec.$ThisBindingStatus !== "lexical", "this binding status shouldn't be lexical");
|
|
|
|
// 3. If envRec.[[ThisBindingStatus]] is "initialized", throw a ReferenceError exception.
|
|
if (envRec.$ThisBindingStatus === "initialized") {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError);
|
|
}
|
|
|
|
// 4. Set envRec.[[ThisValue]] to V.
|
|
envRec.$ThisValue = V;
|
|
|
|
// 5. Set envRec.[[ThisBindingStatus]] to "initialized".
|
|
envRec.$ThisBindingStatus = "initialized";
|
|
|
|
// 6. Return V.
|
|
return V;
|
|
}
|
|
|
|
// ECMA262 8.1.1.3.2
|
|
|
|
}, {
|
|
key: "HasThisBinding",
|
|
value: function HasThisBinding() {
|
|
// 1. Let envRec be the function Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. If envRec.[[ThisBindingStatus]] is "lexical", return false; otherwise, return true.
|
|
return envRec.$ThisBindingStatus === "lexical" ? false : true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.3.3
|
|
|
|
}, {
|
|
key: "HasSuperBinding",
|
|
value: function HasSuperBinding() {
|
|
// 1. Let envRec be the function Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. If envRec.[[ThisBindingStatus]] is "lexical", return false.
|
|
if (envRec.$ThisBindingStatus === "lexical") return false;
|
|
|
|
// 3. If envRec.[[HomeObject]] has the value undefined, return false; otherwise, return true.
|
|
if (envRec.$HomeObject === undefined) {
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// ECMA262 8.1.1.3.4
|
|
|
|
}, {
|
|
key: "GetThisBinding",
|
|
value: function GetThisBinding() {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the function Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Assert: envRec.[[ThisBindingStatus]] is not "lexical".
|
|
(0, _invariant2.default)(envRec.$ThisBindingStatus !== "lexical", "this binding status shouldn't be lexical");
|
|
|
|
// 3. If envRec.[[ThisBindingStatus]] is "uninitialized", throw a ReferenceError exception.
|
|
if (envRec.$ThisBindingStatus === "uninitialized") {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError);
|
|
}
|
|
|
|
// 4. Return envRec.[[ThisValue]].
|
|
return envRec.$ThisValue;
|
|
}
|
|
|
|
// ECMA262 8.1.1.3.5
|
|
|
|
}, {
|
|
key: "GetSuperBase",
|
|
value: function GetSuperBase() {
|
|
// 1. Let envRec be the function Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let home be the value of envRec.[[HomeObject]].
|
|
var home = envRec.$HomeObject;
|
|
|
|
// 3. If home has the value undefined, return undefined.
|
|
if (home === undefined) return this.realm.intrinsics.undefined;
|
|
|
|
// 4. Assert: Type(home) is Object.
|
|
(0, _invariant2.default)(home instanceof _index.ObjectValue, "expected object value");
|
|
|
|
// 5. Return ? home.[[GetPrototypeOf]]().
|
|
return home.$GetPrototypeOf();
|
|
}
|
|
}]);
|
|
|
|
return FunctionEnvironmentRecord;
|
|
}(DeclarativeEnvironmentRecord);
|
|
|
|
// ECMA262 8.1.1.4
|
|
|
|
|
|
var GlobalEnvironmentRecord = exports.GlobalEnvironmentRecord = function (_EnvironmentRecord3) {
|
|
_inherits(GlobalEnvironmentRecord, _EnvironmentRecord3);
|
|
|
|
function GlobalEnvironmentRecord() {
|
|
_classCallCheck(this, GlobalEnvironmentRecord);
|
|
|
|
return _possibleConstructorReturn(this, (GlobalEnvironmentRecord.__proto__ || Object.getPrototypeOf(GlobalEnvironmentRecord)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(GlobalEnvironmentRecord, [{
|
|
key: "HasBinding",
|
|
|
|
|
|
// ECMA262 8.1.1.4.1
|
|
value: function HasBinding(N) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, return true.
|
|
if (DclRec.HasBinding(N)) return true;
|
|
|
|
// 4. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 5. Return ? ObjRec.HasBinding(N).
|
|
return ObjRec.HasBinding(N);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.2
|
|
|
|
}, {
|
|
key: "CreateMutableBinding",
|
|
value: function CreateMutableBinding(N, D) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, throw a TypeError exception.
|
|
if (DclRec.HasBinding(N)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 4. Return DclRec.CreateMutableBinding(N, D).
|
|
return DclRec.CreateMutableBinding(N, D, true);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.3
|
|
|
|
}, {
|
|
key: "CreateImmutableBinding",
|
|
value: function CreateImmutableBinding(N, S) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, throw a TypeError exception.
|
|
if (DclRec.HasBinding(N)) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
|
|
}
|
|
|
|
// 4. Return DclRec.CreateImmutableBinding(N, S).
|
|
return DclRec.CreateImmutableBinding(N, S, true);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.4
|
|
|
|
}, {
|
|
key: "InitializeBinding",
|
|
value: function InitializeBinding(N, V) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, then
|
|
if (DclRec.HasBinding(N)) {
|
|
// a. Return DclRec.InitializeBinding(N, V).
|
|
return DclRec.InitializeBinding(N, V);
|
|
}
|
|
|
|
// 4. Assert: If the binding exists, it must be in the object Environment Record.
|
|
|
|
// 5. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 6. Return ? ObjRec.InitializeBinding(N, V).
|
|
return ObjRec.InitializeBinding(N, V);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.5
|
|
|
|
}, {
|
|
key: "SetMutableBinding",
|
|
value: function SetMutableBinding(N, V, S) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, then
|
|
if (DclRec.HasBinding(N)) {
|
|
// a. Return DclRec.SetMutableBinding(N, V, S).
|
|
return DclRec.SetMutableBinding(N, V, S);
|
|
}
|
|
|
|
// 4. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 5. Return ? ObjRec.SetMutableBinding(N, V, S).
|
|
return ObjRec.SetMutableBinding(N, V, S);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.6
|
|
|
|
}, {
|
|
key: "GetBindingValue",
|
|
value: function GetBindingValue(N, S) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, then
|
|
if (DclRec.HasBinding(N)) {
|
|
// a. Return DclRec.GetBindingValue(N, S).
|
|
return DclRec.GetBindingValue(N, S);
|
|
}
|
|
|
|
// 4. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 5. Return ? ObjRec.GetBindingValue(N, S).
|
|
return ObjRec.GetBindingValue(N, S);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.7
|
|
|
|
}, {
|
|
key: "DeleteBinding",
|
|
value: function DeleteBinding(N) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. If DclRec.HasBinding(N) is true, then
|
|
if (DclRec.HasBinding(N)) {
|
|
// a. Return DclRec.DeleteBinding(N).
|
|
return DclRec.DeleteBinding(N);
|
|
}
|
|
|
|
// 4. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 5. Let globalObject be the binding object for ObjRec.
|
|
var globalObject = ObjRec.object;
|
|
|
|
// 6. Let existingProp be ? HasOwnProperty(globalObject, N).
|
|
var existingProp = (0, _index2.HasOwnProperty)(realm, globalObject, N);
|
|
|
|
// 7. If existingProp is true, then
|
|
if (existingProp) {
|
|
// a. Let status be ? ObjRec.DeleteBinding(N).
|
|
var status = ObjRec.DeleteBinding(N);
|
|
|
|
// b. If status is true, then
|
|
if (status) {
|
|
// i. Let varNames be envRec.[[VarNames]].
|
|
var varNames = envRec.$VarNames;
|
|
|
|
// ii. If N is an element of varNames, remove that element from the varNames.
|
|
if (varNames.indexOf(N) >= 0) {
|
|
varNames.splice(varNames.indexOf(N), 1);
|
|
}
|
|
}
|
|
|
|
// c. Return status.
|
|
return status;
|
|
}
|
|
|
|
// 8. Return true.
|
|
return true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.8
|
|
|
|
}, {
|
|
key: "HasThisBinding",
|
|
value: function HasThisBinding() {
|
|
// 1. Return true.
|
|
return true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.9
|
|
|
|
}, {
|
|
key: "HasSuperBinding",
|
|
value: function HasSuperBinding() {
|
|
// 1. Return true.
|
|
return true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.10
|
|
|
|
}, {
|
|
key: "WithBaseObject",
|
|
value: function WithBaseObject() {
|
|
// 1. Return undefined.
|
|
return this.realm.intrinsics.undefined;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.11
|
|
|
|
}, {
|
|
key: "GetThisBinding",
|
|
value: function GetThisBinding() {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
(0, _invariant2.default)(envRec.$GlobalThisValue);
|
|
// 2. Return envRec.[[GlobalThisValue]].
|
|
return envRec.$GlobalThisValue;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.12
|
|
|
|
}, {
|
|
key: "HasVarDeclaration",
|
|
value: function HasVarDeclaration(N) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let varDeclaredNames be envRec.[[VarNames]].
|
|
var varDeclaredNames = envRec.$VarNames;
|
|
|
|
// 3. If varDeclaredNames contains the value of N, return true.
|
|
if (varDeclaredNames.indexOf(N) >= 0) return true;
|
|
|
|
// 4. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.13
|
|
|
|
}, {
|
|
key: "HasLexicalDeclaration",
|
|
value: function HasLexicalDeclaration(N) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let DclRec be envRec.[[DeclarativeRecord]].
|
|
var DclRec = envRec.$DeclarativeRecord;
|
|
|
|
// 3. Return DclRec.HasBinding(N).
|
|
return DclRec.HasBinding(N);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.14
|
|
|
|
}, {
|
|
key: "HasRestrictedGlobalProperty",
|
|
value: function HasRestrictedGlobalProperty(N) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 3. Let globalObject be the binding object for ObjRec.
|
|
var globalObject = ObjRec.object;
|
|
|
|
// 4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
|
|
var existingProp = globalObject.$GetOwnProperty(N);
|
|
|
|
// 5. If existingProp is undefined, return false.
|
|
if (!existingProp) return false;
|
|
_singletons.Properties.ThrowIfMightHaveBeenDeleted(existingProp.value);
|
|
|
|
// 6. If existingProp.[[Configurable]] is true, return false.
|
|
if (existingProp.configurable) return false;
|
|
|
|
// 7. Return true.
|
|
return true;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.15
|
|
|
|
}, {
|
|
key: "CanDeclareGlobalVar",
|
|
value: function CanDeclareGlobalVar(N) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 3. Let globalObject be the binding object for ObjRec.
|
|
var globalObject = ObjRec.object;
|
|
|
|
// 4. Let hasProperty be ? HasOwnProperty(globalObject, N).
|
|
var hasProperty = (0, _index2.HasOwnProperty)(realm, globalObject, N);
|
|
|
|
// 5. If hasProperty is true, return true.
|
|
if (hasProperty) return true;
|
|
|
|
// 6. Return ? IsExtensible(globalObject).
|
|
return (0, _index2.IsExtensible)(realm, globalObject);
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.16
|
|
|
|
}, {
|
|
key: "CanDeclareGlobalFunction",
|
|
value: function CanDeclareGlobalFunction(N) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 3. Let globalObject be the binding object for ObjRec.
|
|
var globalObject = ObjRec.object;
|
|
|
|
// 4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
|
|
var existingProp = globalObject.$GetOwnProperty(N);
|
|
|
|
// 5. If existingProp is undefined, return ? IsExtensible(globalObject).
|
|
if (!existingProp) return (0, _index2.IsExtensible)(realm, globalObject);
|
|
_singletons.Properties.ThrowIfMightHaveBeenDeleted(existingProp.value);
|
|
|
|
// 6. If existingProp.[[Configurable]] is true, return true.
|
|
if (existingProp.configurable) return true;
|
|
|
|
// 7. If IsDataDescriptor(existingProp) is true and existingProp has attribute values {[[Writable]]: true, [[Enumerable]]: true}, return true.
|
|
if ((0, _index2.IsDataDescriptor)(realm, existingProp) && existingProp.writable && existingProp.enumerable) {
|
|
return true;
|
|
}
|
|
|
|
// 8. Return false.
|
|
return false;
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.17
|
|
|
|
}, {
|
|
key: "CreateGlobalVarBinding",
|
|
value: function CreateGlobalVarBinding(N, D) {
|
|
var realm = this.realm;
|
|
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 3. Let globalObject be the binding object for ObjRec.
|
|
var globalObject = ObjRec.object;
|
|
|
|
// 4. Let hasProperty be ? HasOwnProperty(globalObject, N).
|
|
var hasProperty = (0, _index2.HasOwnProperty)(realm, globalObject, N);
|
|
|
|
// 5. Let extensible be ? IsExtensible(globalObject).
|
|
var extensible = (0, _index2.IsExtensible)(realm, globalObject);
|
|
|
|
// 6. If hasProperty is false and extensible is true, then
|
|
if (!hasProperty && extensible) {
|
|
// a. Perform ? ObjRec.CreateMutableBinding(N, D).
|
|
ObjRec.CreateMutableBinding(N, D);
|
|
|
|
// b. Perform ? ObjRec.InitializeBinding(N, undefined).
|
|
ObjRec.InitializeBinding(N, this.realm.intrinsics.undefined);
|
|
}
|
|
|
|
// 7. Let varDeclaredNames be envRec.[[VarNames]].
|
|
var varDeclaredNames = envRec.$VarNames;
|
|
|
|
// 8. If varDeclaredNames does not contain the value of N, then
|
|
if (varDeclaredNames.indexOf(N) < 0) {
|
|
// a. Append N to varDeclaredNames.
|
|
varDeclaredNames.push(N);
|
|
}
|
|
|
|
// 9. Return NormalCompletion(empty).
|
|
}
|
|
|
|
// ECMA262 8.1.1.4.18
|
|
|
|
}, {
|
|
key: "CreateGlobalFunctionBinding",
|
|
value: function CreateGlobalFunctionBinding(N, V, D) {
|
|
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
|
var envRec = this;
|
|
|
|
// 2. Let ObjRec be envRec.[[ObjectRecord]].
|
|
var ObjRec = envRec.$ObjectRecord;
|
|
|
|
// 3. Let globalObject be the binding object for ObjRec.
|
|
var globalObject = ObjRec.object;
|
|
|
|
// 4. Let existingProp be ? globalObject.[[GetOwnProperty]](N).
|
|
var existingProp = globalObject.$GetOwnProperty(N);
|
|
|
|
// 5. If existingProp is undefined or existingProp.[[Configurable]] is true, then
|
|
var desc = void 0;
|
|
if (!existingProp || existingProp.configurable) {
|
|
// a. Let desc be the PropertyDescriptor{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D}.
|
|
desc = { value: V, writable: true, enumerable: true, configurable: D };
|
|
} else {
|
|
// 6. Else,
|
|
_singletons.Properties.ThrowIfMightHaveBeenDeleted(existingProp.value);
|
|
// a. Let desc be the PropertyDescriptor{[[Value]]: V }.
|
|
desc = { value: V };
|
|
}
|
|
|
|
// 7. Perform ? DefinePropertyOrThrow(globalObject, N, desc).
|
|
_singletons.Properties.DefinePropertyOrThrow(this.realm, globalObject, N, desc);
|
|
|
|
// 8. Record that the binding for N in ObjRec has been initialized.
|
|
|
|
// 9. Perform ? Set(globalObject, N, V, false).
|
|
_singletons.Properties.Set(this.realm, globalObject, N, V, false);
|
|
|
|
// 10. Let varDeclaredNames be envRec.[[VarNames]].
|
|
var varDeclaredNames = envRec.$VarNames;
|
|
|
|
// 11. If varDeclaredNames does not contain the value of N, then
|
|
if (varDeclaredNames.indexOf(N) < 0) {
|
|
// a. Append N to varDeclaredNames.
|
|
varDeclaredNames.push(N);
|
|
}
|
|
|
|
// 12. Return NormalCompletion(empty).
|
|
}
|
|
}]);
|
|
|
|
return GlobalEnvironmentRecord;
|
|
}(EnvironmentRecord);
|
|
|
|
// ECMA262 8.1
|
|
|
|
|
|
var uid = 0;
|
|
|
|
var LexicalEnvironment = exports.LexicalEnvironment = function () {
|
|
function LexicalEnvironment(realm) {
|
|
_classCallCheck(this, LexicalEnvironment);
|
|
|
|
(0, _invariant2.default)(realm, "expected realm");
|
|
this.realm = realm;
|
|
this.destroyed = false;
|
|
this._uid = uid++;
|
|
}
|
|
|
|
// For debugging it is convenient to have an ID for each of these.
|
|
|
|
|
|
_createClass(LexicalEnvironment, [{
|
|
key: "destroy",
|
|
value: function destroy() {
|
|
this.destroyed = true;
|
|
// Once the containing environment is destroyed, we can no longer add or remove entries from the environmentRecord
|
|
// (but we can update existing values).
|
|
if (this.environmentRecord instanceof DeclarativeEnvironmentRecord) {
|
|
this.environmentRecord.frozen = true;
|
|
}
|
|
}
|
|
}, {
|
|
key: "assignToGlobal",
|
|
value: function assignToGlobal(globalAst, rvalue) {
|
|
var globalValue = this.evaluate(globalAst, false);
|
|
_singletons.Properties.PutValue(this.realm, globalValue, rvalue);
|
|
}
|
|
}, {
|
|
key: "partiallyEvaluateCompletionDeref",
|
|
value: function partiallyEvaluateCompletionDeref(ast, strictCode, metadata) {
|
|
var _partiallyEvaluateCom = this.partiallyEvaluateCompletion(ast, strictCode, metadata),
|
|
_partiallyEvaluateCom2 = _slicedToArray(_partiallyEvaluateCom, 3),
|
|
result = _partiallyEvaluateCom2[0],
|
|
partial_ast = _partiallyEvaluateCom2[1],
|
|
partial_io = _partiallyEvaluateCom2[2];
|
|
|
|
if (result instanceof Reference) {
|
|
result = _singletons.Environment.GetValue(this.realm, result);
|
|
}
|
|
return [result, partial_ast, partial_io];
|
|
}
|
|
}, {
|
|
key: "partiallyEvaluateCompletion",
|
|
value: function partiallyEvaluateCompletion(ast, strictCode, metadata) {
|
|
try {
|
|
return this.partiallyEvaluate(ast, strictCode, metadata);
|
|
} catch (err) {
|
|
if (err instanceof _completions.Completion) return [err, ast, []];
|
|
if (err instanceof Error)
|
|
// rethrowing Error should preserve stack trace
|
|
throw err;
|
|
// let's wrap into a proper Error to create stack trace
|
|
throw new _errors.FatalError(err);
|
|
}
|
|
}
|
|
}, {
|
|
key: "evaluateCompletionDeref",
|
|
value: function evaluateCompletionDeref(ast, strictCode, metadata) {
|
|
var result = this.evaluateCompletion(ast, strictCode, metadata);
|
|
if (result instanceof Reference) result = _singletons.Environment.GetValue(this.realm, result);
|
|
return result;
|
|
}
|
|
}, {
|
|
key: "evaluateCompletion",
|
|
value: function evaluateCompletion(ast, strictCode, metadata) {
|
|
try {
|
|
return this.evaluate(ast, strictCode, metadata);
|
|
} catch (err) {
|
|
if ((err instanceof _completions.JoinedAbruptCompletions || err instanceof _completions.PossiblyNormalCompletion) && err.containsBreakOrContinue()) {
|
|
_index.AbstractValue.reportIntrospectionError(err.joinCondition);
|
|
throw new _errors.FatalError();
|
|
}
|
|
if (err instanceof _completions.AbruptCompletion) return err;
|
|
if (err instanceof Error)
|
|
// rethrowing Error should preserve stack trace
|
|
throw err;
|
|
// let's wrap into a proper Error to create stack trace
|
|
throw new _errors.FatalError(err);
|
|
}
|
|
}
|
|
}, {
|
|
key: "evaluateAbstractCompletion",
|
|
value: function evaluateAbstractCompletion(ast, strictCode, metadata) {
|
|
try {
|
|
return this.evaluateAbstract(ast, strictCode, metadata);
|
|
} catch (err) {
|
|
if (err instanceof _completions.Completion) return err;
|
|
if (err instanceof Error)
|
|
// rethrowing Error should preserve stack trace
|
|
throw err;
|
|
// let's wrap into a proper Error to create stack trace
|
|
if (err instanceof Object) throw new _errors.FatalError(err.constructor.name + ": " + err);
|
|
throw new _errors.FatalError(err);
|
|
}
|
|
}
|
|
}, {
|
|
key: "concatenateAndParse",
|
|
value: function concatenateAndParse(sources) {
|
|
var sourceType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "script";
|
|
|
|
var asts = [];
|
|
var code = {};
|
|
var directives = [];
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = sources[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var source = _step.value;
|
|
|
|
try {
|
|
var node = (0, _parse2.default)(this.realm, source.fileContents, source.filePath, sourceType);
|
|
if (source.sourceMapContents && source.sourceMapContents.length > 0) this.fixup_source_locations(node, source.sourceMapContents);
|
|
this.fixup_filenames(node);
|
|
asts = asts.concat(node.program.body);
|
|
code[source.filePath] = source.fileContents;
|
|
directives = directives.concat(node.program.directives);
|
|
} catch (e) {
|
|
if (e instanceof _completions.ThrowCompletion) {
|
|
var error = e.value;
|
|
if (error instanceof _index.ObjectValue) {
|
|
var message = error.$Get("message", error);
|
|
message.value = "Syntax error: " + message.value;
|
|
e.location.source = source.filePath;
|
|
// the position was not located properly on the
|
|
// syntax errors happen on one given position, so start position = end position
|
|
e.location.start = { line: e.location.line, column: e.location.column };
|
|
e.location.end = { line: e.location.line, column: e.location.column };
|
|
var diagnostic = new _errors.CompilerDiagnostic(message.value, e.location, "PP1004", "FatalError");
|
|
this.realm.handleError(diagnostic);
|
|
throw new _errors.FatalError(message.value);
|
|
}
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
return [t.file(t.program(asts, directives)), code];
|
|
}
|
|
}, {
|
|
key: "executeSources",
|
|
value: function executeSources(sources) {
|
|
var sourceType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "script";
|
|
var onParse = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
|
|
|
|
var context = new _realm.ExecutionContext();
|
|
context.lexicalEnvironment = this;
|
|
context.variableEnvironment = this;
|
|
context.realm = this.realm;
|
|
this.realm.pushContext(context);
|
|
var res = void 0,
|
|
code = void 0;
|
|
try {
|
|
var ast = void 0;
|
|
|
|
var _concatenateAndParse = this.concatenateAndParse(sources, sourceType);
|
|
|
|
var _concatenateAndParse2 = _slicedToArray(_concatenateAndParse, 2);
|
|
|
|
ast = _concatenateAndParse2[0];
|
|
code = _concatenateAndParse2[1];
|
|
|
|
if (onParse) onParse(ast);
|
|
res = this.evaluateCompletion(ast, false);
|
|
} finally {
|
|
this.realm.popContext(context);
|
|
this.realm.onDestroyScope(context.lexicalEnvironment);
|
|
if (!this.destroyed) this.realm.onDestroyScope(this);
|
|
(0, _invariant2.default)(this.realm.activeLexicalEnvironments.size === 0);
|
|
}
|
|
if (res instanceof _completions.AbruptCompletion) return [res, code];
|
|
|
|
return [_singletons.Environment.GetValue(this.realm, res), code];
|
|
}
|
|
}, {
|
|
key: "executePartialEvaluator",
|
|
value: function executePartialEvaluator(sources) {
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _options.defaultOptions;
|
|
var sourceType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "script";
|
|
|
|
var _concatenateAndParse3 = this.concatenateAndParse(sources, sourceType),
|
|
_concatenateAndParse4 = _slicedToArray(_concatenateAndParse3, 2),
|
|
ast = _concatenateAndParse4[0],
|
|
code = _concatenateAndParse4[1];
|
|
|
|
var context = new _realm.ExecutionContext();
|
|
context.lexicalEnvironment = this;
|
|
context.variableEnvironment = this;
|
|
context.realm = this.realm;
|
|
this.realm.pushContext(context);
|
|
var partialAST = void 0;
|
|
try {
|
|
var res = void 0;
|
|
|
|
var _partiallyEvaluateCom3 = this.partiallyEvaluateCompletionDeref(ast, false);
|
|
|
|
var _partiallyEvaluateCom4 = _slicedToArray(_partiallyEvaluateCom3, 2);
|
|
|
|
res = _partiallyEvaluateCom4[0];
|
|
partialAST = _partiallyEvaluateCom4[1];
|
|
|
|
if (res instanceof _completions.AbruptCompletion) return res;
|
|
} finally {
|
|
this.realm.popContext(context);
|
|
this.realm.onDestroyScope(context.lexicalEnvironment);
|
|
if (!this.destroyed) this.realm.onDestroyScope(this);
|
|
(0, _invariant2.default)(this.realm.activeLexicalEnvironments.size === 0);
|
|
}
|
|
(0, _invariant2.default)(partialAST.type === "File");
|
|
var fileAst = partialAST;
|
|
var prog = t.program(fileAst.program.body, ast.program.directives);
|
|
this.fixup_filenames(prog);
|
|
return (0, _babelGenerator2.default)(prog, { sourceMaps: options.sourceMaps }, code);
|
|
}
|
|
}, {
|
|
key: "execute",
|
|
value: function execute(code, filename) {
|
|
var map = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
|
|
var sourceType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "script";
|
|
var onParse = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
|
|
|
|
var context = new _realm.ExecutionContext();
|
|
context.lexicalEnvironment = this;
|
|
context.variableEnvironment = this;
|
|
context.realm = this.realm;
|
|
|
|
this.realm.pushContext(context);
|
|
|
|
var ast = void 0,
|
|
res = void 0;
|
|
try {
|
|
try {
|
|
ast = (0, _parse2.default)(this.realm, code, filename, sourceType);
|
|
} catch (e) {
|
|
if (e instanceof _completions.ThrowCompletion) return e;
|
|
throw e;
|
|
}
|
|
if (onParse) onParse(ast);
|
|
if (map.length > 0) this.fixup_source_locations(ast, map);
|
|
this.fixup_filenames(ast);
|
|
res = this.evaluateCompletion(ast, false);
|
|
} finally {
|
|
this.realm.popContext(context);
|
|
// Avoid destroying "this" scope as execute may be called many times.
|
|
if (context.lexicalEnvironment !== this) this.realm.onDestroyScope(context.lexicalEnvironment);
|
|
(0, _invariant2.default)(this.realm.activeLexicalEnvironments.size === 1);
|
|
}
|
|
if (res instanceof _completions.AbruptCompletion) return res;
|
|
|
|
return _singletons.Environment.GetValue(this.realm, res);
|
|
}
|
|
}, {
|
|
key: "fixup_source_locations",
|
|
value: function fixup_source_locations(ast, map) {
|
|
var smc = new sourceMap.SourceMapConsumer(map);
|
|
(0, _traverseFast2.default)(ast, function (node) {
|
|
var loc = node.loc;
|
|
if (!loc) return false;
|
|
fixup(loc, loc.start);
|
|
fixup(loc, loc.end);
|
|
fixup_comments(node.leadingComments);
|
|
fixup_comments(node.innerComments);
|
|
fixup_comments(node.trailingComments);
|
|
return false;
|
|
|
|
function fixup(new_loc, new_pos) {
|
|
var old_pos = smc.originalPositionFor({ line: new_pos.line, column: new_pos.column });
|
|
if (old_pos.source === null) return;
|
|
new_pos.line = old_pos.line;
|
|
new_pos.column = old_pos.column;
|
|
new_loc.source = old_pos.source;
|
|
}
|
|
|
|
function fixup_comments(comments) {
|
|
if (!comments) return;
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = comments[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var c = _step2.value;
|
|
|
|
var cloc = c.loc;
|
|
if (!cloc) continue;
|
|
fixup(cloc, cloc.start);
|
|
fixup(cloc, cloc.end);
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: "fixup_filenames",
|
|
value: function fixup_filenames(ast) {
|
|
(0, _traverseFast2.default)(ast, function (node) {
|
|
var loc = node.loc;
|
|
if (!loc || !loc.source) {
|
|
node.leadingComments = null;
|
|
node.innerComments = null;
|
|
node.trailingComments = null;
|
|
node.loc = null;
|
|
} else {
|
|
var filename = loc.source;
|
|
loc.filename = filename;
|
|
fixup_comments(node.leadingComments, filename);
|
|
fixup_comments(node.innerComments, filename);
|
|
fixup_comments(node.trailingComments, filename);
|
|
}
|
|
return false;
|
|
|
|
function fixup_comments(comments, filename) {
|
|
if (!comments) return;
|
|
var _iteratorNormalCompletion3 = true;
|
|
var _didIteratorError3 = false;
|
|
var _iteratorError3 = undefined;
|
|
|
|
try {
|
|
for (var _iterator3 = comments[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
var c = _step3.value;
|
|
|
|
if (c.loc) {
|
|
c.loc.filename = filename;
|
|
c.loc.source = filename;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError3 = true;
|
|
_iteratorError3 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
|
_iterator3.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError3) {
|
|
throw _iteratorError3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: "evaluate",
|
|
value: function evaluate(ast, strictCode, metadata) {
|
|
if (this.realm.debuggerInstance) {
|
|
this.realm.debuggerInstance.checkForActions(ast);
|
|
}
|
|
var res = this.evaluateAbstract(ast, strictCode, metadata);
|
|
(0, _invariant2.default)(res instanceof _index.Value || res instanceof Reference, ast.type);
|
|
return res;
|
|
}
|
|
}, {
|
|
key: "evaluateAbstract",
|
|
value: function evaluateAbstract(ast, strictCode, metadata) {
|
|
this.realm.currentLocation = ast.loc;
|
|
this.realm.testTimeout();
|
|
|
|
var evaluator = this.realm.evaluators[ast.type];
|
|
if (evaluator) {
|
|
var result = evaluator(ast, strictCode, this, this.realm, metadata);
|
|
return result;
|
|
}
|
|
|
|
throw new TypeError("Unsupported node type " + ast.type);
|
|
}
|
|
}, {
|
|
key: "partiallyEvaluate",
|
|
value: function partiallyEvaluate(ast, strictCode, metadata) {
|
|
var partialEvaluator = this.realm.partialEvaluators[ast.type];
|
|
if (partialEvaluator) {
|
|
return partialEvaluator(ast, strictCode, this, this.realm, metadata);
|
|
}
|
|
|
|
var err = new TypeError("Unsupported node type " + ast.type);
|
|
throw err;
|
|
}
|
|
}]);
|
|
|
|
return LexicalEnvironment;
|
|
}();
|
|
|
|
// ECMA262 6.2.3
|
|
// A Reference is a resolved name or property binding. A Reference consists of three components, the base value,
|
|
// the referenced name and the Boolean valued strict reference flag. The base value is either undefined, an Object,
|
|
// a Boolean, a String, a Symbol, a Number, or an Environment Record. A base value of undefined indicates that the
|
|
// Reference could not be resolved to a binding. The referenced name is a String or Symbol value.
|
|
|
|
|
|
function canBecomeAnObject(base) {
|
|
var type = base.getType();
|
|
return type === _index.BooleanValue || type === _index.StringValue || type === _index.SymbolValue || type === _index.NumberValue;
|
|
}
|
|
|
|
var Reference = exports.Reference = function Reference(base, refName, strict, thisValue) {
|
|
_classCallCheck(this, Reference);
|
|
|
|
(0, _invariant2.default)(base instanceof _index.AbstractObjectValue || base === undefined || base instanceof _index.ObjectValue || base instanceof EnvironmentRecord || canBecomeAnObject(base));
|
|
this.base = base;
|
|
this.referencedName = refName;
|
|
(0, _invariant2.default)(!(refName instanceof _index.AbstractValue) || !(refName.mightNotBeString() && refName.mightNotBeNumber()));
|
|
this.strict = strict;
|
|
this.thisValue = thisValue;
|
|
(0, _invariant2.default)(thisValue === undefined || !(base instanceof EnvironmentRecord));
|
|
};
|
|
//# sourceMappingURL=environment.js.map
|