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

1555 lines
68 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.PropertiesImplementation = 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; }; }(); /**
* 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 _completions = require("../completions.js");
var _realm = require("../realm.js");
var _index = require("../values/index.js");
var _ObjectExpression = require("../evaluators/ObjectExpression");
var _environment = require("../environment.js");
var _errors = require("../errors.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _index2 = require("../methods/index.js");
var _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
var _singletons = require("../singletons.js");
var _strict3 = require("../utils/strict.js");
var _strict4 = _interopRequireDefault(_strict3);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function StringKey(key) {
if (key instanceof _index.StringValue) key = key.value;
if (typeof key !== "string") {
// The generator currently only supports string keys.
throw new _errors.FatalError();
}
return key;
}
function InternalDescriptorPropertyToValue(realm, value) {
if (value === undefined) return realm.intrinsics.undefined;
if (typeof value === "boolean") return new _index.BooleanValue(realm, value);
(0, _invariant2.default)(value instanceof _index.Value);
return value;
}
function InternalGetPropertiesKey(P) {
if (typeof P === "string") {
return P;
} else if (P instanceof _index.StringValue) {
return P.value;
} else if (P instanceof _index.SymbolValue) {
return P;
}
// otherwise, undefined
}
function InternalGetPropertiesMap(O, P) {
if (typeof P === "string" || P instanceof _index.StringValue) {
return O.properties;
} else if (P instanceof _index.SymbolValue) {
return O.symbols;
} else {
(0, _invariant2.default)(false);
}
}
function InternalSetProperty(realm, O, P, desc) {
var map = InternalGetPropertiesMap(O, P);
var key = InternalGetPropertiesKey(P);
var propertyBinding = map.get(key);
if (propertyBinding === undefined) {
propertyBinding = { descriptor: undefined, object: O, key: key };
map.set(key, propertyBinding);
}
realm.recordModifiedProperty(propertyBinding);
propertyBinding.descriptor = desc;
}
function InternalUpdatedProperty(realm, O, P, oldDesc) {
var generator = realm.generator;
if (!generator) return;
if (!O.isIntrinsic()) return;
if (P instanceof _index.SymbolValue) return;
if (P instanceof _index.StringValue) P = P.value;
(0, _invariant2.default)(!O.isLeakedObject()); // leaked objects are never updated
(0, _invariant2.default)(typeof P === "string");
var propertyBinding = InternalGetPropertiesMap(O, P).get(P);
(0, _invariant2.default)(propertyBinding !== undefined); // The callers ensure this
var desc = propertyBinding.descriptor;
if (desc === undefined) {
// The property is being deleted
if (O === realm.$GlobalObject) {
generator.emitGlobalDelete(P, realm.getRunningContext().isStrict);
} else {
generator.emitPropertyDelete(O, P);
}
} else {
var descValue = desc.value || realm.intrinsics.undefined;
(0, _invariant2.default)(descValue instanceof _index.Value);
if (oldDesc === undefined) {
// The property is being created
if (O === realm.$GlobalObject) {
if ((0, _index2.IsDataDescriptor)(realm, desc)) {
if ((0, _babelTypes.isValidIdentifier)(P) && !desc.configurable && desc.enumerable && desc.writable) {
generator.emitGlobalDeclaration(P, descValue);
} else if (desc.configurable && desc.enumerable && desc.writable) {
generator.emitGlobalAssignment(P, descValue, realm.getRunningContext().isStrict);
} else {
generator.emitDefineProperty(O, P, desc);
}
} else {
generator.emitDefineProperty(O, P, desc);
}
} else {
if ((0, _index2.IsDataDescriptor)(realm, desc) && desc.configurable && desc.enumerable && desc.writable) {
generator.emitPropertyAssignment(O, P, descValue);
} else {
generator.emitDefineProperty(O, P, desc);
}
}
} else {
// The property is being modified
if ((0, _index2.equalDescriptors)(desc, oldDesc)) {
// only the value is being modified
if (O === realm.$GlobalObject) {
generator.emitGlobalAssignment(P, descValue, realm.getRunningContext().isStrict);
} else {
generator.emitPropertyAssignment(O, P, descValue);
}
} else {
generator.emitDefineProperty(O, P, desc, /*isDescChanged*/true);
}
}
}
}
function leakDescriptor(realm, desc) {
if (desc.value) {
(0, _invariant2.default)(desc.value instanceof _index.Value, "internal fields should not leak");
_singletons.Leak.leakValue(realm, desc.value);
}
if (desc.get) {
_singletons.Leak.leakValue(realm, desc.get);
}
if (desc.set) {
_singletons.Leak.leakValue(realm, desc.set);
}
}
// Determines if an object with parent O may create its own property P.
function parentPermitsChildPropertyCreation(realm, O, P) {
var ownDesc = O.$GetOwnProperty(P);
var ownDescValue = !ownDesc ? realm.intrinsics.undefined : ownDesc.value === undefined ? realm.intrinsics.undefined : ownDesc.value;
(0, _invariant2.default)(ownDescValue instanceof _index.Value);
if (!ownDesc || ownDescValue.mightHaveBeenDeleted()) {
// O might not object, so first ask its parent
var parent = O.$GetPrototypeOf();
parent.throwIfNotConcrete(); //TODO #1016: deal with abstract parents
if (!(parent instanceof _index.NullValue)) {
if (!parentPermitsChildPropertyCreation(realm, parent, P)) return false;
}
// Parent is OK, so if O does not object return true
if (!ownDesc) return true; // O has no opinion of its ownDesc
}
(0, _invariant2.default)(ownDesc !== undefined);
// O might have a property P and so might object
if ((0, _index2.IsDataDescriptor)(realm, ownDesc)) {
if (ownDesc.writable) {
// The grand parent does not object so it is OK that parent does not have P
// If parent does have P, it is also OK because it is a writable data property
return true;
}
}
// If parent does not have property P, this is too pessimistic, but that is
// the caller's problem.
return false;
}
var PropertiesImplementation = exports.PropertiesImplementation = function () {
function PropertiesImplementation() {
_classCallCheck(this, PropertiesImplementation);
}
_createClass(PropertiesImplementation, [{
key: "OrdinarySet",
// ECMA262 9.1.9.1
value: function OrdinarySet(realm, O, P, V, Receiver) {
if (O.isLeakedObject()) {
_singletons.Leak.leakValue(realm, V);
if (realm.generator) {
realm.generator.emitPropertyAssignment(O, StringKey(P), V);
}
return true;
}
var weakDeletion = V.mightHaveBeenDeleted();
// 1. Assert: IsPropertyKey(P) is true.
(0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P), "expected property key");
// 2. Let ownDesc be ? O.[[GetOwnProperty]](P).
var ownDesc = void 0;
var existingBinding = InternalGetPropertiesMap(O, P).get(InternalGetPropertiesKey(P));
if (existingBinding !== undefined || !(O.isPartialObject() && O.isSimpleObject())) ownDesc = O.$GetOwnProperty(P);
var ownDescValue = !ownDesc ? realm.intrinsics.undefined : ownDesc.value === undefined ? realm.intrinsics.undefined : ownDesc.value;
(0, _invariant2.default)(ownDescValue instanceof _index.Value);
// 3. If ownDesc is undefined (or might be), then
if (!ownDesc || ownDescValue.mightHaveBeenDeleted()) {
// a. Let parent be ? O.[[GetPrototypeOf]]().
var parent = O.$GetPrototypeOf();
parent.throwIfNotConcrete(); //TODO #1016: deal with abstract parents
// b. If parent is not null, then
if (!(parent instanceof _index.NullValue)) {
if (!ownDesc) {
// i. Return ? parent.[[Set]](P, V, Receiver).
return parent.$Set(P, V, Receiver);
}
// But since we don't know if O has its own property P, the parent might
// actually have a say. Give up, unless the parent would be OK with it.
if (!parentPermitsChildPropertyCreation(realm, parent, P)) {
(0, _invariant2.default)(ownDescValue instanceof _index.AbstractValue);
_index.AbstractValue.reportIntrospectionError(ownDescValue);
throw new _errors.FatalError();
}
// Since the parent is OK with us creating a local property for O
// we can carry on as if there were no parent.
}
// i. Let ownDesc be the PropertyDescriptor{[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
if (!ownDesc) ownDesc = {
value: realm.intrinsics.undefined,
writable: true,
enumerable: true,
configurable: true
};
}
// joined descriptors need special treatment
var joinCondition = ownDesc.joinCondition;
if (joinCondition !== undefined) {
var descriptor2 = ownDesc.descriptor2;
ownDesc = ownDesc.descriptor1;
var _Path$withCondition = _singletons.Path.withCondition(joinCondition, function () {
return ownDesc !== undefined ? realm.evaluateForEffects(function () {
return new _index.BooleanValue(realm, OrdinarySetHelper());
}) : (0, _realm.construct_empty_effects)(realm);
}),
_Path$withCondition2 = _slicedToArray(_Path$withCondition, 5),
compl1 = _Path$withCondition2[0],
gen1 = _Path$withCondition2[1],
bindings1 = _Path$withCondition2[2],
properties1 = _Path$withCondition2[3],
createdObj1 = _Path$withCondition2[4];
ownDesc = descriptor2;
var _Path$withInverseCond = _singletons.Path.withInverseCondition(joinCondition, function () {
return ownDesc !== undefined ? realm.evaluateForEffects(function () {
return new _index.BooleanValue(realm, OrdinarySetHelper());
}) : (0, _realm.construct_empty_effects)(realm);
}),
_Path$withInverseCond2 = _slicedToArray(_Path$withInverseCond, 5),
compl2 = _Path$withInverseCond2[0],
gen2 = _Path$withInverseCond2[1],
bindings2 = _Path$withInverseCond2[2],
properties2 = _Path$withInverseCond2[3],
createdObj2 = _Path$withInverseCond2[4];
// Join the effects, creating an abstract view of what happened, regardless
// of the actual value of ownDesc.joinCondition.
var joinedEffects = _singletons.Join.joinEffects(realm, joinCondition, [compl1, gen1, bindings1, properties1, createdObj1], [compl2, gen2, bindings2, properties2, createdObj2]);
var completion = joinedEffects[0];
if (completion instanceof _completions.PossiblyNormalCompletion) {
// in this case one of the branches may complete abruptly, which means that
// not all control flow branches join into one flow at this point.
// Consequently we have to continue tracking changes until the point where
// all the branches come together into one.
completion = realm.composeWithSavedCompletion(completion);
}
// Note that the effects of (non joining) abrupt branches are not included
// in joinedEffects, but are tracked separately inside completion.
realm.applyEffects(joinedEffects);
// return or throw completion
if (completion instanceof _completions.AbruptCompletion) throw completion;
(0, _invariant2.default)(completion instanceof _index.Value);
return _singletons.To.ToBooleanPartial(realm, completion);
}
return OrdinarySetHelper();
function OrdinarySetHelper() {
(0, _invariant2.default)(ownDesc !== undefined);
(0, _invariant2.default)(ownDescValue instanceof _index.Value);
// 4. If IsDataDescriptor(ownDesc) is true, then
if ((0, _index2.IsDataDescriptor)(realm, ownDesc)) {
// a. If ownDesc.[[Writable]] is false, return false.
if (!ownDesc.writable && !weakDeletion) {
// The write will fail if the property actually exists
if (ownDescValue.mightHaveBeenDeleted()) {
// But maybe it does not and thus would succeed.
// Since we don't know what will happen, give up for now.
(0, _invariant2.default)(ownDescValue instanceof _index.AbstractValue);
_index.AbstractValue.reportIntrospectionError(ownDescValue);
throw new _errors.FatalError();
}
return false;
}
// b. If Type(Receiver) is not Object, return false.
Receiver = Receiver.throwIfNotConcrete();
if (!(Receiver instanceof _index.ObjectValue)) return false;
// c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P).
var existingDescriptor = void 0;
var binding = InternalGetPropertiesMap(Receiver, P).get(InternalGetPropertiesKey(P));
if (binding !== undefined || !(Receiver.isPartialObject() && Receiver.isSimpleObject())) existingDescriptor = Receiver.$GetOwnProperty(P);
if (existingDescriptor !== undefined) {
if (existingDescriptor.descriptor1 === ownDesc) existingDescriptor = ownDesc;else if (existingDescriptor.descriptor2 === ownDesc) existingDescriptor = ownDesc;
}
var existingDescValue = !existingDescriptor ? realm.intrinsics.undefined : existingDescriptor.value === undefined ? realm.intrinsics.undefined : existingDescriptor.value;
(0, _invariant2.default)(existingDescValue instanceof _index.Value);
// d. If existingDescriptor is not undefined, then
if (existingDescriptor !== undefined) {
// i. If IsAccessorDescriptor(existingDescriptor) is true, return false.
if ((0, _index2.IsAccessorDescriptor)(realm, existingDescriptor)) {
(0, _invariant2.default)(!existingDescValue.mightHaveBeenDeleted(), "should not fail until weak deletes of accessors are suppported");
return false;
}
// ii. If existingDescriptor.[[Writable]] is false, return false.
if (!existingDescriptor.writable && !(weakDeletion && existingDescriptor.configurable)) {
// If we are not sure the receiver actually has a property P we can't just return false here.
if (existingDescValue.mightHaveBeenDeleted()) {
(0, _invariant2.default)(existingDescValue instanceof _index.AbstractValue);
_index.AbstractValue.reportIntrospectionError(existingDescValue);
throw new _errors.FatalError();
}
return false;
}
// iii. Let valueDesc be the PropertyDescriptor{[[Value]]: V}.
var valueDesc = { value: V };
// iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc).
if (weakDeletion || existingDescValue.mightHaveBeenDeleted()) {
// At this point we are not actually sure that Receiver actually has
// a property P, however, if it has, we are sure that its a data property,
// and that redefining the property with valueDesc will not change the
// attributes of the property, so we delete it to make things nice for $DefineOwnProperty.
Receiver.$Delete(P);
valueDesc = existingDescriptor;
valueDesc.value = V;
}
return Receiver.$DefineOwnProperty(P, valueDesc);
} else {
// e. Else Receiver does not currently have a property P,
// i. Return ? CreateDataProperty(Receiver, P, V).
return _singletons.Create.CreateDataProperty(realm, Receiver, P, V);
}
}
// 5. Assert: IsAccessorDescriptor(ownDesc) is true.
(0, _invariant2.default)((0, _index2.IsAccessorDescriptor)(realm, ownDesc), "expected accessor");
// 6. Let setter be ownDesc.[[Set]].
var setter = "set" in ownDesc ? ownDesc.set : undefined;
// 7. If setter is undefined, return false.
if (!setter || setter instanceof _index.UndefinedValue) return false;
// 8. Perform ? Call(setter, Receiver, « V »).
(0, _index2.Call)(realm, setter.throwIfNotConcrete(), Receiver, [V]);
// 9. Return true.
return true;
}
}
// ECMA262 6.2.4.4
}, {
key: "FromPropertyDescriptor",
value: function FromPropertyDescriptor(realm, Desc) {
// 1. If Desc is undefined, return undefined.
if (!Desc) return realm.intrinsics.undefined;
// 2. Let obj be ObjectCreate(%ObjectPrototype%).
var obj = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
// 3. Assert: obj is an extensible ordinary object with no own properties.
(0, _invariant2.default)(obj.getExtensible(), "expected an extensible object");
(0, _invariant2.default)(!obj.properties.size, "expected an object with no own properties");
// 4. If Desc has a [[Value]] field, then
var success = true;
if ("value" in Desc) {
(0, _invariant2.default)(Desc.value instanceof _index.Value);
// a. Perform CreateDataProperty(obj, "value", Desc.[[Value]]).
success = _singletons.Create.CreateDataProperty(realm, obj, "value", Desc.value) && success;
}
// 5. If Desc has a [[Writable]] field, then
if ("writable" in Desc) {
(0, _invariant2.default)(Desc.writable !== undefined);
// a. Perform CreateDataProperty(obj, "writable", Desc.[[Writable]]).
success = _singletons.Create.CreateDataProperty(realm, obj, "writable", new _index.BooleanValue(realm, Desc.writable)) && success;
}
// 6. If Desc has a [[Get]] field, then
if ("get" in Desc) {
(0, _invariant2.default)(Desc.get !== undefined);
// a. Perform CreateDataProperty(obj, "get", Desc.[[Get]]).
success = _singletons.Create.CreateDataProperty(realm, obj, "get", Desc.get) && success;
}
// 7. If Desc has a [[Set]] field, then
if ("set" in Desc) {
(0, _invariant2.default)(Desc.set !== undefined);
// a. Perform CreateDataProperty(obj, "set", Desc.[[Set]]).
success = _singletons.Create.CreateDataProperty(realm, obj, "set", Desc.set) && success;
}
// 8. If Desc has an [[Enumerable]] field, then
if ("enumerable" in Desc) {
(0, _invariant2.default)(Desc.enumerable !== undefined);
// a. Perform CreateDataProperty(obj, "enumerable", Desc.[[Enumerable]]).
success = _singletons.Create.CreateDataProperty(realm, obj, "enumerable", new _index.BooleanValue(realm, Desc.enumerable)) && success;
}
// 9. If Desc has a [[Configurable]] field, then
if ("configurable" in Desc) {
(0, _invariant2.default)(Desc.configurable !== undefined);
// a. Perform CreateDataProperty(obj, "configurable", Desc.[[Configurable]]).
success = _singletons.Create.CreateDataProperty(realm, obj, "configurable", new _index.BooleanValue(realm, Desc.configurable)) && success;
}
// 10. Assert: all of the above CreateDataProperty operations return true.
(0, _invariant2.default)(success, "fails to create data property");
// 11. Return obj.
return obj;
}
//
}, {
key: "OrdinaryDelete",
value: function OrdinaryDelete(realm, O, P) {
// 1. Assert: IsPropertyKey(P) is true.
(0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P), "expected a property key");
// 2. Let desc be ? O.[[GetOwnProperty]](P).
var desc = O.$GetOwnProperty(P);
// 3. If desc is undefined, return true.
if (!desc) {
if (O.isLeakedObject()) {
if (realm.generator) {
realm.generator.emitPropertyDelete(O, StringKey(P));
}
}
return true;
}
// 4. If desc.[[Configurable]] is true, then
if (desc.configurable) {
if (O.isLeakedObject()) {
if (realm.generator) {
realm.generator.emitPropertyDelete(O, StringKey(P));
}
return true;
}
// a. Remove the own property with name P from O.
var key = InternalGetPropertiesKey(P);
var map = InternalGetPropertiesMap(O, P);
var propertyBinding = map.get(key);
(0, _invariant2.default)(propertyBinding !== undefined);
realm.recordModifiedProperty(propertyBinding);
propertyBinding.descriptor = undefined;
InternalUpdatedProperty(realm, O, P, desc);
// b. Return true.
return true;
}
// 5. Return false.
return false;
}
// ECMA262 7.3.8
}, {
key: "DeletePropertyOrThrow",
value: function DeletePropertyOrThrow(realm, O, P) {
// 1. Assert: Type(O) is Object.
(0, _invariant2.default)(O instanceof _index.ObjectValue, "expected an object");
// 2. Assert: IsPropertyKey(P) is true.
(0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P), "expected a property key");
// 3. Let success be ? O.[[Delete]](P).
var success = O.$Delete(P);
// 4. If success is false, throw a TypeError exception.
if (!success) {
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "couldn't delete property");
}
// 5. Return success.
return success;
}
// ECMA262 6.2.4.6
}, {
key: "CompletePropertyDescriptor",
value: function CompletePropertyDescriptor(realm, Desc) {
// 1. Assert: Desc is a Property Descriptor.
// 2. Let like be Record{[[Value]]: undefined, [[Writable]]: false, [[Get]]: undefined, [[Set]]: undefined, [[Enumerable]]: false, [[Configurable]]: false}.
var like = {
value: realm.intrinsics.undefined,
get: realm.intrinsics.undefined,
set: realm.intrinsics.undefined,
writable: false,
enumerable: false,
configurable: false
};
// 3. If either IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then
if ((0, _index2.IsGenericDescriptor)(realm, Desc) || (0, _index2.IsDataDescriptor)(realm, Desc)) {
// a. If Desc does not have a [[Value]] field, set Desc.[[Value]] to like.[[Value]].
if (!("value" in Desc)) Desc.value = like.value;
// b. If Desc does not have a [[Writable]] field, set Desc.[[Writable]] to like.[[Writable]].
if (!("writable" in Desc)) Desc.writable = like.writable;
} else {
// 4. Else,
// a. If Desc does not have a [[Get]] field, set Desc.[[Get]] to like.[[Get]].
if (!("get" in Desc)) Desc.get = like.get;
// b. If Desc does not have a [[Set]] field, set Desc.[[Set]] to like.[[Set]].
if (!("set" in Desc)) Desc.set = like.set;
}
// 5. If Desc does not have an [[Enumerable]] field, set Desc.[[Enumerable]] to like.[[Enumerable]].
if (!("enumerable" in Desc)) Desc.enumerable = like.enumerable;
// 6. If Desc does not have a [[Configurable]] field, set Desc.[[Configurable]] to like.[[Configurable]].
if (!("configurable" in Desc)) Desc.configurable = like.configurable;
// 7. Return Desc.
return Desc;
}
// ECMA262 9.1.6.2
}, {
key: "IsCompatiblePropertyDescriptor",
value: function IsCompatiblePropertyDescriptor(realm, extensible, Desc, current) {
// 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined, Extensible, Desc, Current).
return this.ValidateAndApplyPropertyDescriptor(realm, undefined, undefined, extensible, Desc, current);
}
// ECMA262 9.1.6.3
}, {
key: "ValidateAndApplyPropertyDescriptor",
value: function ValidateAndApplyPropertyDescriptor(realm, O, P, extensible, Desc, current) {
// 1. Assert: If O is not undefined, then IsPropertyKey(P) is true.
if (O !== undefined) {
(0, _invariant2.default)(P !== undefined);
(0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P));
}
if (current && current.joinCondition !== undefined) {
var jc = current.joinCondition;
if (_singletons.Path.implies(jc)) current = current.descriptor1;else if (!_index.AbstractValue.createFromUnaryOp(realm, "!", jc, true).mightNotBeTrue()) current = current.descriptor2;
}
// 2. If current is undefined, then
if (!current) {
// a. If extensible is false, return false.
if (!extensible) return false;
// b. Assert: extensible is true.
(0, _invariant2.default)(extensible === true, "expected extensible to be true");
if (O !== undefined && O.isLeakedObject() && P !== undefined) {
leakDescriptor(realm, Desc);
if (realm.generator) {
realm.generator.emitDefineProperty(O, StringKey(P), Desc);
}
return true;
}
// c. If IsGenericDescriptor(Desc) is true or IsDataDescriptor(Desc) is true, then
if ((0, _index2.IsGenericDescriptor)(realm, Desc) || (0, _index2.IsDataDescriptor)(realm, Desc)) {
// i. If O is not undefined, create an own data property named P of object O whose [[Value]],
// [[Writable]], [[Enumerable]] and [[Configurable]] attribute values are described by Desc. If the
// value of an attribute field of Desc is absent, the attribute of the newly created property is set
// to its default value.
if (O !== undefined) {
(0, _invariant2.default)(P !== undefined);
InternalSetProperty(realm, O, P, {
value: "value" in Desc ? Desc.value : realm.intrinsics.undefined,
writable: "writable" in Desc ? Desc.writable : false,
enumerable: "enumerable" in Desc ? Desc.enumerable : false,
configurable: "configurable" in Desc ? Desc.configurable : false
});
InternalUpdatedProperty(realm, O, P, undefined);
}
} else {
// d. Else Desc must be an accessor Property Descriptor,
// i. If O is not undefined, create an own accessor property named P of object O whose [[Get]],
// [[Set]], [[Enumerable]] and [[Configurable]] attribute values are described by Desc. If the value
// of an attribute field of Desc is absent, the attribute of the newly created property is set to its
// default value.
if (O !== undefined) {
(0, _invariant2.default)(P !== undefined);
InternalSetProperty(realm, O, P, {
get: "get" in Desc ? Desc.get : realm.intrinsics.undefined,
set: "set" in Desc ? Desc.set : realm.intrinsics.undefined,
enumerable: "enumerable" in Desc ? Desc.enumerable : false,
configurable: "configurable" in Desc ? Desc.configurable : false
});
InternalUpdatedProperty(realm, O, P, undefined);
}
}
// e. Return true.
return true;
}
this.ThrowIfMightHaveBeenDeleted(current.value);
// 3. Return true, if every field in Desc is absent.
if (!Object.keys(Desc).length) return true;
// 4. Return true, if every field in Desc also occurs in current and the value of every field in Desc is the
// same value as the corresponding field in current when compared using the SameValue algorithm.
var identical = true;
for (var field in Desc) {
if (!(field in current)) {
identical = false;
} else {
var dval = InternalDescriptorPropertyToValue(realm, Desc[field]);
var cval = InternalDescriptorPropertyToValue(realm, current[field]);
if (dval instanceof _index.ConcreteValue && cval instanceof _index.ConcreteValue) identical = (0, _index2.SameValue)(realm, dval, cval);else {
identical = dval === cval;
// This might be false now but true at runtime. This does not
// matter because the logic for non identical values will still
// do the right thing in the cases below that does not blow up
// when dealing with an abstract value.
}
}
if (!identical) break;
}
if (identical) {
return true;
}
// 5. If the [[Configurable]] field of current is false, then
if (!current.configurable) {
// a. Return false, if the [[Configurable]] field of Desc is true.
if (Desc.configurable) return false;
// b. Return false, if the [[Enumerable]] field of Desc is present and the [[Enumerable]] fields of current and Desc are the Boolean negation of each other.
if ("enumerable" in Desc && Desc.enumerable !== current.enumerable) {
return false;
}
}
if (O !== undefined && O.isLeakedObject() && P !== undefined) {
leakDescriptor(realm, Desc);
if (realm.generator) {
realm.generator.emitDefineProperty(O, StringKey(P), Desc);
}
return true;
}
var oldDesc = current;
current = (0, _index2.cloneDescriptor)(current);
(0, _invariant2.default)(current !== undefined);
// 6. If IsGenericDescriptor(Desc) is true, no further validation is required.
if ((0, _index2.IsGenericDescriptor)(realm, Desc)) {} else if ((0, _index2.IsDataDescriptor)(realm, current) !== (0, _index2.IsDataDescriptor)(realm, Desc)) {
// 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have different results, then
// a. Return false, if the [[Configurable]] field of current is false.
if (!current.configurable) return false;
// b. If IsDataDescriptor(current) is true, then
if ((0, _index2.IsDataDescriptor)(realm, current)) {
// i. If O is not undefined, convert the property named P of object O from a data property to an accessor property.
// Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and set the rest of the property's attributes to their default values.
if (O !== undefined) {
(0, _invariant2.default)(P !== undefined);
var key = InternalGetPropertiesKey(P);
var propertyBinding = InternalGetPropertiesMap(O, P).get(key);
(0, _invariant2.default)(propertyBinding !== undefined);
delete current.writable;
delete current.value;
current.get = realm.intrinsics.undefined;
current.set = realm.intrinsics.undefined;
}
} else {
// c. Else,
// i. If O is not undefined, convert the property named P of object O from an accessor property to a data property. Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and set the rest of the property's attributes to their default values.
if (O !== undefined) {
(0, _invariant2.default)(P !== undefined);
var _key = InternalGetPropertiesKey(P);
var _propertyBinding = InternalGetPropertiesMap(O, P).get(_key);
(0, _invariant2.default)(_propertyBinding !== undefined);
delete current.get;
delete current.set;
current.writable = false;
current.value = realm.intrinsics.undefined;
}
}
} else if ((0, _index2.IsDataDescriptor)(realm, current) && (0, _index2.IsDataDescriptor)(realm, Desc)) {
// 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true, then
// a. If the [[Configurable]] field of current is false, then
if (!current.configurable) {
// i. Return false, if the [[Writable]] field of current is false and the [[Writable]] field of Desc is true.
if (!current.writable && Desc.writable) return false;
// ii. If the [[Writable]] field of current is false, then
if (!current.writable) {
// 1. Return false, if the [[Value]] field of Desc is present and SameValue(Desc.[[Value]], current.[[Value]]) is false.
var descValue = Desc.value || realm.intrinsics.undefined;
(0, _invariant2.default)(descValue instanceof _index.Value);
var currentValue = current.value || realm.intrinsics.undefined;
(0, _invariant2.default)(currentValue instanceof _index.Value);
if (Desc.value && !(0, _index2.SameValuePartial)(realm, descValue, currentValue)) {
return false;
}
}
} else {
// b. Else the [[Configurable]] field of current is true, so any change is acceptable.
}
} else {
// 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) are both true,
// a. If the [[Configurable]] field of current is false, then
if (!current.configurable) {
// i. Return false, if the [[Set]] field of Desc is present and SameValue(Desc.[[Set]], current.[[Set]]) is false.
if (Desc.set && !(0, _index2.SameValuePartial)(realm, Desc.set, current.set || realm.intrinsics.undefined)) return false;
// ii. Return false, if the [[Get]] field of Desc is present and SameValue(Desc.[[Get]], current.[[Get]]) is false.
if (Desc.get && !(0, _index2.SameValuePartial)(realm, Desc.get, current.get || realm.intrinsics.undefined)) return false;
}
}
// 10. If O is not undefined, then
if (O !== undefined) {
(0, _invariant2.default)(P !== undefined);
var _key2 = InternalGetPropertiesKey(P);
var map = InternalGetPropertiesMap(O, P);
var _propertyBinding2 = map.get(_key2);
if (_propertyBinding2 === undefined) {
_propertyBinding2 = { descriptor: undefined, object: O, key: _key2 };
realm.recordModifiedProperty(_propertyBinding2);
_propertyBinding2.descriptor = current;
map.set(_key2, _propertyBinding2);
} else if (_propertyBinding2.descriptor === undefined) {
realm.recordModifiedProperty(_propertyBinding2);
_propertyBinding2.descriptor = current;
} else {
realm.recordModifiedProperty(_propertyBinding2);
_propertyBinding2.descriptor = current;
}
// a. For each field of Desc that is present, set the corresponding attribute of the property named P of
// object O to the value of the field.
for (var _field in Desc) {
current[_field] = Desc[_field];
}InternalUpdatedProperty(realm, O, P, oldDesc);
}
// 11. Return true.
return true;
}
// ECMA262 9.1.6.1
}, {
key: "OrdinaryDefineOwnProperty",
value: function OrdinaryDefineOwnProperty(realm, O, P, Desc) {
(0, _invariant2.default)(O instanceof _index.ObjectValue);
// 1. Let current be ? O.[[GetOwnProperty]](P).
var current = void 0;
var binding = InternalGetPropertiesMap(O, P).get(InternalGetPropertiesKey(P));
if (binding !== undefined || !(O.isPartialObject() && O.isSimpleObject())) current = O.$GetOwnProperty(P);
// 2. Let extensible be the value of the [[Extensible]] internal slot of O.
var extensible = O.getExtensible();
// 3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current).
return this.ValidateAndApplyPropertyDescriptor(realm, O, P, extensible, Desc, current);
}
// ECMA262 19.1.2.3.1
}, {
key: "ObjectDefineProperties",
value: function ObjectDefineProperties(realm, O, Properties) {
// 1. If Type(O) is not Object, throw a TypeError exception.
if (O.mightNotBeObject()) {
if (O.mightBeObject()) O.throwIfNotConcrete();
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
}
(0, _invariant2.default)(O instanceof _index.ObjectValue || O instanceof _index.AbstractObjectValue);
// 2. Let props be ? ToObject(Properties).
var props = _singletons.To.ToObject(realm, Properties.throwIfNotConcrete());
// 3. Let keys be ? props.[[OwnPropertyKeys]]().
var keys = props.$OwnPropertyKeys();
// 4. Let descriptors be a new empty List.
var descriptors = [];
// 5. Repeat for each element nextKey of keys in List order,
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var nextKey = _step.value;
// a. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
var propDesc = props.$GetOwnProperty(nextKey);
// b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
if (propDesc && propDesc.enumerable) {
this.ThrowIfMightHaveBeenDeleted(propDesc.value);
// i. Let descObj be ? Get(props, nextKey).
var descObj = (0, _index2.Get)(realm, props, nextKey);
// ii. Let desc be ? ToPropertyDescriptor(descObj).
var desc = _singletons.To.ToPropertyDescriptor(realm, descObj);
// iii. Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
descriptors.push([nextKey, desc]);
}
}
// 6. For each pair from descriptors in list order,
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = descriptors[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var pair = _step2.value;
// a. Let P be the first element of pair.
var P = pair[0];
// b. Let desc be the second element of pair.
var desc = pair[1];
// c. Perform ? DefinePropertyOrThrow(O, P, desc).
this.DefinePropertyOrThrow(realm, O, P, desc);
}
// 7. Return O.
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return O;
}
// ECMA262 7.3.3
}, {
key: "Set",
value: function Set(realm, O, P, V, Throw) {
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
(0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P), "expected property key");
// 3. Assert: Type(Throw) is Boolean.
(0, _invariant2.default)(typeof Throw === "boolean", "expected boolean");
// 4. Let success be ? O.[[Set]](P, V, O).
var success = O.$Set(P, V, O);
// 5. If success is false and Throw is true, throw a TypeError exception.
if (success === false && Throw === true) {
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
}
// 6. Return success.
return success;
}
// ECMA262 7.3.7
}, {
key: "DefinePropertyOrThrow",
value: function DefinePropertyOrThrow(realm, O, P, desc) {
// 1. Assert: Type(O) is Object.
// 2. Assert: IsPropertyKey(P) is true.
(0, _invariant2.default)(typeof P === "string" || (0, _index2.IsPropertyKey)(realm, P), "expected property key");
// 3. Let success be ? O.[[DefineOwnProperty]](P, desc).
var success = O.$DefineOwnProperty(P, desc);
// 4. If success is false, throw a TypeError exception.
if (success === false) {
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
}
// 5. Return success.
return success;
}
// ECMA262 6.2.3.2
}, {
key: "PutValue",
value: function PutValue(realm, V, W) {
W = W.promoteEmptyToUndefined();
// The following two steps are not necessary as we propagate completions with exceptions.
// 1. ReturnIfAbrupt(V).
// 2. ReturnIfAbrupt(W).
// 3. If Type(V) is not Reference, throw a ReferenceError exception.
if (!(V instanceof _environment.Reference)) {
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError, "can't put a value to a non-reference");
}
// 4. Let base be GetBase(V).
var base = _singletons.Environment.GetBase(realm, V);
// 5. If IsUnresolvableReference(V) is true, then
if (_singletons.Environment.IsUnresolvableReference(realm, V)) {
// a. If IsStrictReference(V) is true, then
if (_singletons.Environment.IsStrictReference(realm, V)) {
// i. Throw a ReferenceError exception.
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError);
}
// b. Let globalObj be GetGlobalObject().
var globalObj = (0, _index2.GetGlobalObject)(realm);
// c. Return ? Set(globalObj, GetReferencedName(V), W, false).
return this.Set(realm, globalObj, _singletons.Environment.GetReferencedName(realm, V), W, false);
}
// 6. Else if IsPropertyReference(V) is true, then
if (_singletons.Environment.IsPropertyReference(realm, V)) {
// a. If HasPrimitiveBase(V) is true, then
if (_singletons.Environment.HasPrimitiveBase(realm, V)) {
// i. Assert: In realm case, base will never be null or undefined.
(0, _invariant2.default)(base instanceof _index.Value && !(0, _index2.HasSomeCompatibleType)(base, _index.UndefinedValue, _index.NullValue));
// ii. Set base to ToObject(base).
base = _singletons.To.ToObjectPartial(realm, base);
}
(0, _invariant2.default)(base instanceof _index.ObjectValue || base instanceof _index.AbstractObjectValue);
// b. Let succeeded be ? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).
var succeeded = base.$SetPartial(_singletons.Environment.GetReferencedNamePartial(realm, V), W, (0, _index2.GetThisValue)(realm, V));
// c. If succeeded is false and IsStrictReference(V) is true, throw a TypeError exception.
if (succeeded === false && _singletons.Environment.IsStrictReference(realm, V)) {
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError);
}
// d. Return.
return;
}
// 7. Else base must be an Environment Record,
if (base instanceof _environment.EnvironmentRecord) {
// a. Return ? base.SetMutableBinding(GetReferencedName(V), W, IsStrictReference(V)) (see 8.1.1).
var referencedName = _singletons.Environment.GetReferencedName(realm, V);
(0, _invariant2.default)(typeof referencedName === "string");
return base.SetMutableBinding(referencedName, W, _singletons.Environment.IsStrictReference(realm, V));
}
(0, _invariant2.default)(false);
}
// ECMA262 9.4.2.4
}, {
key: "ArraySetLength",
value: function ArraySetLength(realm, A, Desc) {
// 1. If the [[Value]] field of Desc is absent, then
var DescValue = Desc.value;
if (!DescValue) {
// a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
return this.OrdinaryDefineOwnProperty(realm, A, "length", Desc);
}
(0, _invariant2.default)(DescValue instanceof _index.Value);
// 2. Let newLenDesc be a copy of Desc.
var newLenDesc = Object.assign({}, Desc);
// 3. Let newLen be ? ToUint32(Desc.[[Value]]).
var newLen = _singletons.To.ToUint32(realm, DescValue);
// 4. Let numberLen be ? ToNumber(Desc.[[Value]]).
var numberLen = _singletons.To.ToNumber(realm, DescValue);
// 5. If newLen ≠ numberLen, throw a RangeError exception.
if (newLen !== numberLen) {
throw realm.createErrorThrowCompletion(realm.intrinsics.RangeError, "should be a uint");
}
// 6. Set newLenDesc.[[Value]] to newLen.
newLenDesc.value = new _index.NumberValue(realm, newLen);
// 7. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
var oldLenDesc = this.OrdinaryGetOwnProperty(realm, A, "length");
// 8. Assert: oldLenDesc will never be undefined or an accessor descriptor because Array objects are created
// with a length data property that cannot be deleted or reconfigured.
(0, _invariant2.default)(oldLenDesc !== undefined && !(0, _index2.IsAccessorDescriptor)(realm, oldLenDesc), "cannot be undefined or an accessor descriptor");
// 9. Let oldLen be oldLenDesc.[[Value]].
var oldLen = oldLenDesc.value;
(0, _invariant2.default)(oldLen instanceof _index.Value);
oldLen = oldLen.throwIfNotConcrete();
(0, _invariant2.default)(oldLen instanceof _index.NumberValue, "should be a number");
oldLen = oldLen.value;
// 10. If newLen ≥ oldLen, then
if (newLen >= oldLen) {
// a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
return this.OrdinaryDefineOwnProperty(realm, A, "length", newLenDesc);
}
// 11. If oldLenDesc.[[Writable]] is false, return false.
if (!oldLenDesc.writable) return false;
// 12. If newLenDesc.[[Writable]] is absent or has the value true, let newWritable be true.
var newWritable = void 0;
if (!("writable" in newLenDesc) || newLenDesc.writable === true) {
newWritable = true;
} else {
// 13. Else,
// a. Need to defer setting the [[Writable]] attribute to false in case any elements cannot be deleted.
// b. Let newWritable be false.
newWritable = false;
// c. Set newLenDesc.[[Writable]] to true.
newLenDesc.writable = true;
}
// 14. Let succeeded be ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
var succeeded = this.OrdinaryDefineOwnProperty(realm, A, "length", newLenDesc);
// 15. If succeeded is false, return false.
if (succeeded === false) return false;
// Here we diverge from the spec: instead of traversing all indices from
// oldLen to newLen, only the indices that are actually present are touched.
var oldLenCopy = oldLen;
var keys = Array.from(A.properties.keys()).map(function (x) {
return parseInt(x, 10);
}).filter(function (x) {
return newLen <= x && x <= oldLenCopy;
}).sort().reverse();
// 16. While newLen < oldLen repeat,
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = keys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var key = _step3.value;
// a. Set oldLen to oldLen - 1.
oldLen = key;
// b. Let deleteSucceeded be ! A.[[Delete]](! ToString(oldLen)).
var deleteSucceeded = A.$Delete(oldLen + "");
// c. If deleteSucceeded is false, then
if (deleteSucceeded === false) {
// i. Set newLenDesc.[[Value]] to oldLen + 1.
newLenDesc.value = new _index.NumberValue(realm, oldLen + 1);
// ii. If newWritable is false, set newLenDesc.[[Writable]] to false.
if (newWritable === false) newLenDesc.writable = false;
// iii. Let succeeded be ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
succeeded = this.OrdinaryDefineOwnProperty(realm, A, "length", newLenDesc);
// iv. Return false.
return false;
}
}
// 17. If newWritable is false, then
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
if (!newWritable) {
// a. Return OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor{[[Writable]]: false}). This call will always return true.
return this.OrdinaryDefineOwnProperty(realm, A, "length", {
writable: false
});
}
// 18. Return true.
return true;
}
// ECMA262 9.1.5.1
}, {
key: "OrdinaryGetOwnProperty",
value: function OrdinaryGetOwnProperty(realm, O, P) {
if (O.isLeakedObject()) {
(0, _invariant2.default)(realm.generator);
var pname = realm.generator.getAsPropertyNameExpression(StringKey(P));
var absVal = _index.AbstractValue.createTemporalFromBuildFunction(realm, _index.Value, [O], function (_ref) {
var _ref2 = _slicedToArray(_ref, 1),
node = _ref2[0];
return t.memberExpression(node, pname, !t.isIdentifier(pname));
});
// TODO: We can't be sure what the descriptor will be, but the value will be abstract.
return { configurable: true, enumerable: true, value: absVal, writable: true };
}
// 1. Assert: IsPropertyKey(P) is true.
(0, _invariant2.default)((0, _index2.IsPropertyKey)(realm, P), "expected a property key");
// 2. If O does not have an own property with key P, return undefined.
var existingBinding = InternalGetPropertiesMap(O, P).get(InternalGetPropertiesKey(P));
if (!existingBinding) {
if (O.isPartialObject()) {
(0, _invariant2.default)(realm.useAbstractInterpretation); // __makePartial will already have thrown an error if not
if (O.isSimpleObject()) {
if (P instanceof _index.StringValue) P = P.value;
if (typeof P === "string") {
// In this case it is safe to defer the property access to runtime (at this point in time)
(0, _invariant2.default)(realm.generator);
var _pname = realm.generator.getAsPropertyNameExpression(P);
var _absVal = _index.AbstractValue.createTemporalFromBuildFunction(realm, _index.Value, [O], function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 1),
node = _ref4[0];
return t.memberExpression(node, _pname, !t.isIdentifier(_pname));
});
return { configurable: true, enumerable: true, value: _absVal, writable: true };
} else {
(0, _invariant2.default)(P instanceof _index.SymbolValue);
// Simple objects don't have symbol properties
return undefined;
}
}
_index.AbstractValue.reportIntrospectionError(O, P);
throw new _errors.FatalError();
}
return undefined;
}
realm.callReportPropertyAccess(existingBinding);
if (!existingBinding.descriptor) return undefined;
// 3. Let D be a newly created Property Descriptor with no fields.
var D = {};
// 4. Let X be O's own property whose key is P.
var X = existingBinding.descriptor;
(0, _invariant2.default)(X !== undefined);
if (X.joinCondition !== undefined) {
D.joinCondition = X.joinCondition;
D.descriptor1 = X.descriptor1;
D.descriptor2 = X.descriptor2;
return D;
}
// 5. If X is a data property, then
if ((0, _index2.IsDataDescriptor)(realm, X)) {
var value = X.value;
if (O.isPartialObject() && value instanceof _index.AbstractValue && value.kind !== "resolved") {
var realmGenerator = realm.generator;
(0, _invariant2.default)(realmGenerator);
value = realmGenerator.derive(value.types, value.values, value.args, value.getBuildNode(), {
kind: "resolved"
});
InternalSetProperty(realm, O, P, {
value: value,
writable: "writable" in X ? X.writable : false,
enumerable: "enumerable" in X ? X.enumerable : false,
configurable: "configurable" in X ? X.configurable : false
});
}
// a. Set D.[[Value]] to the value of X's [[Value]] attribute.
D.value = value;
// b. Set D.[[Writable]] to the value of X's [[Writable]] attribute.
D.writable = X.writable;
} else {
// 6. Else X is an accessor property,
(0, _invariant2.default)((0, _index2.IsAccessorDescriptor)(realm, X), "expected accessor property");
// a. Set D.[[Get]] to the value of X's [[Get]] attribute.
D.get = X.get;
// b. Set D.[[Set]] to the value of X's [[Set]] attribute.
D.set = X.set;
}
// 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
D.enumerable = X.enumerable;
// 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
D.configurable = X.configurable;
// 9. Return D.
return D;
}
// ECMA262 9.1.2.1
}, {
key: "OrdinarySetPrototypeOf",
value: function OrdinarySetPrototypeOf(realm, O, V) {
if (O.isLeakedObject()) {
throw new _errors.FatalError();
}
// 1. Assert: Either Type(V) is Object or Type(V) is Null.
(0, _invariant2.default)(V instanceof _index.ObjectValue || V instanceof _index.NullValue);
// 2. Let extensible be the value of the [[Extensible]] internal slot of O.
var extensible = O.getExtensible();
// 3. Let current be the value of the [[Prototype]] internal slot of O.
var current = O.$Prototype;
// 4. If SameValue(V, current) is true, return true.
if ((0, _index2.SameValue)(realm, V, current)) return true;
// 5. If extensible is false, return false.
if (!extensible) return false;
// 6. Let p be V.
var p = V;
// 7. Let done be false.
var done = false;
// 8. Repeat while done is false,
while (!done) {
// a. If p is null, let done be true.
if (p instanceof _index.NullValue) {
done = true;
} else if ((0, _index2.SameValue)(realm, p, O)) {
// b. Else if SameValue(p, O) is true, return false.
return false;
} else {
// c. Else,
// TODO #1017 i. If the [[GetPrototypeOf]] internal method of p is not the ordinary object internal method defined in 9.1.1, let done be true.
// ii. Else, let p be the value of p's [[Prototype]] internal slot.
p = p.$Prototype;
}
}
// 9. Set the value of the [[Prototype]] internal slot of O to V.
O.$Prototype = V;
// 10. Return true.
return true;
}
// ECMA262 13.7.5.15
}, {
key: "EnumerateObjectProperties",
value: function EnumerateObjectProperties(realm, O) {
var _this = this;
/*global global*/
var visited = new global.Set();
var obj = O;
var keys = O.$OwnPropertyKeys();
var index = 0;
var iterator = new _index.ObjectValue(realm);
iterator.defineNativeMethod("next", 0, function () {
while (true) {
if (index >= keys.length) {
var proto = obj.$GetPrototypeOf();
if (proto instanceof _index.NullValue) {
return _singletons.Create.CreateIterResultObject(realm, realm.intrinsics.undefined, true);
}
obj = proto;
keys = obj.$OwnPropertyKeys();
index = 0;
}
var key = keys[index];
// Omit symbols.
if (!(key instanceof _index.StringValue)) {
index += 1;
continue;
}
// Omit non-enumerable properties.
var desc = obj.$GetOwnProperty(key);
if (desc && !desc.enumerable) {
_this.ThrowIfMightHaveBeenDeleted(desc.value);
index += 1;
visited.add(key.value);
continue;
}
// Omit duplicates.
if (visited.has(key.value)) {
index += 1;
continue;
}
visited.add(key.value);
// Yield the key.
return _singletons.Create.CreateIterResultObject(realm, key, false);
}
});
return iterator;
}
}, {
key: "ThrowIfMightHaveBeenDeleted",
value: function ThrowIfMightHaveBeenDeleted(value) {
if (!(value instanceof _index.Value)) return;
if (!value.mightHaveBeenDeleted()) return;
(0, _invariant2.default)(value instanceof _index.AbstractValue); // real empty values should never get here
_index.AbstractValue.reportIntrospectionError(value);
throw new _errors.FatalError();
}
}, {
key: "ThrowIfInternalSlotNotWritable",
value: function ThrowIfInternalSlotNotWritable(realm, object, key) {
if (!realm.isNewObject(object)) {
_index.AbstractValue.reportIntrospectionError(object, key);
throw new _errors.FatalError();
}
return object;
}
// ECMA 14.3.9
}, {
key: "PropertyDefinitionEvaluation",
value: function PropertyDefinitionEvaluation(realm, MethodDefinition, object, env, strictCode, enumerable) {
// MethodDefinition : PropertyName ( StrictFormalParameters ) { FunctionBody }
if (MethodDefinition.kind === "method") {
// 1. Let methodDef be DefineMethod of MethodDefinition with argument object.
var methodDef = _singletons.Functions.DefineMethod(realm, MethodDefinition, object, env, strictCode);
// 2. ReturnIfAbrupt(methodDef).
// 3. Perform SetFunctionName(methodDef.[[closure]], methodDef.[[key]]).
_singletons.Functions.SetFunctionName(realm, methodDef.$Closure, methodDef.$Key);
// 4. Let desc be the Property Descriptor{[[Value]]: methodDef.[[closure]], [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
var desc = { value: methodDef.$Closure, writable: true, enumerable: enumerable, configurable: true };
// 5. Return DefinePropertyOrThrow(object, methodDef.[[key]], desc).
return this.DefinePropertyOrThrow(realm, object, methodDef.$Key, desc);
} else if (MethodDefinition.kind === "generator") {
// MethodDefinition : GeneratorMethod
// See 14.4.
// ECMA 14.4.13
// 1. Let propKey be the result of evaluating PropertyName.
var propKey = (0, _ObjectExpression.EvalPropertyName)(MethodDefinition, env, realm, strictCode);
// 2. ReturnIfAbrupt(propKey).
// 3. If the function code for this GeneratorMethod is strict mode code, let strict be true. Otherwise let strict be false.
var strict = strictCode || (0, _strict4.default)(MethodDefinition.body);
// 4. Let scope be the running execution contexts LexicalEnvironment.
var scope = env;
// 5. Let closure be GeneratorFunctionCreate(Method, StrictFormalParameters, GeneratorBody, scope, strict).
var closure = _singletons.Functions.GeneratorFunctionCreate(realm, "method", MethodDefinition.params, MethodDefinition.body, scope, strict);
// 6. Perform MakeMethod(closure, object).
_singletons.Functions.MakeMethod(realm, closure, object);
// 7. Let prototype be ObjectCreate(%GeneratorPrototype%).
var prototype = _singletons.Create.ObjectCreate(realm, realm.intrinsics.GeneratorPrototype);
prototype.originalConstructor = closure;
// 8. Perform MakeConstructor(closure, true, prototype).
(0, _index2.MakeConstructor)(realm, closure, true, prototype);
// 9. Perform SetFunctionName(closure, propKey).
_singletons.Functions.SetFunctionName(realm, closure, propKey);
// 10. Let desc be the Property Descriptor{[[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
var _desc = { value: closure, writable: true, enumerable: enumerable, configurable: true };
// 11. Return DefinePropertyOrThrow(object, propKey, desc).
return this.DefinePropertyOrThrow(realm, object, propKey, _desc);
} else if (MethodDefinition.kind === "get") {
// 1. Let propKey be the result of evaluating PropertyName.
var _propKey = (0, _ObjectExpression.EvalPropertyName)(MethodDefinition, env, realm, strictCode);
// 2. ReturnIfAbrupt(propKey).
// 3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
var _strict = strictCode || (0, _strict4.default)(MethodDefinition.body);
// 4. Let scope be the running execution context's LexicalEnvironment.
var _scope = env;
// 5. Let formalParameterList be the production FormalParameters:[empty] .
var formalParameterList = [];
// 6. Let closure be FunctionCreate(Method, formalParameterList, FunctionBody, scope, strict).
var _closure = _singletons.Functions.FunctionCreate(realm, "method", formalParameterList, MethodDefinition.body, _scope, _strict);
// 7. Perform MakeMethod(closure, object).
_singletons.Functions.MakeMethod(realm, _closure, object);
// 8. Perform SetFunctionName(closure, propKey, "get").
_singletons.Functions.SetFunctionName(realm, _closure, _propKey, "get");
// 9. Let desc be the PropertyDescriptor{[[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}.
var _desc2 = {
get: _closure,
enumerable: true,
configurable: true
};
// 10. Return ? DefinePropertyOrThrow(object, propKey, desc).
return this.DefinePropertyOrThrow(realm, object, _propKey, _desc2);
} else {
(0, _invariant2.default)(MethodDefinition.kind === "set");
// 1. Let propKey be the result of evaluating PropertyName.
var _propKey2 = (0, _ObjectExpression.EvalPropertyName)(MethodDefinition, env, realm, strictCode);
// 2. ReturnIfAbrupt(propKey).
// 3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
var _strict2 = strictCode || (0, _strict4.default)(MethodDefinition.body);
// 4. Let scope be the running execution context's LexicalEnvironment.
var _scope2 = env;
// 5. Let closure be FunctionCreate(Method, PropertySetParameterList, FunctionBody, scope, strict).
var _closure2 = _singletons.Functions.FunctionCreate(realm, "method", MethodDefinition.params, MethodDefinition.body, _scope2, _strict2);
// 6. Perform MakeMethod(closure, object).
_singletons.Functions.MakeMethod(realm, _closure2, object);
// 7. Perform SetFunctionName(closure, propKey, "set").
_singletons.Functions.SetFunctionName(realm, _closure2, _propKey2, "set");
// 8. Let desc be the PropertyDescriptor{[[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}.
var _desc3 = {
set: _closure2,
enumerable: true,
configurable: true
};
// 9. Return ? DefinePropertyOrThrow(object, propKey, desc).
return this.DefinePropertyOrThrow(realm, object, _propKey2, _desc3);
}
}
}]);
return PropertiesImplementation;
}();
//# sourceMappingURL=properties.js.map