first commit
This commit is contained in:
894
build/node_modules/prepack/lib/values/ObjectValue.js
generated
vendored
Normal file
894
build/node_modules/prepack/lib/values/ObjectValue.js
generated
vendored
Normal file
@@ -0,0 +1,894 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _errors = require("../errors.js");
|
||||
|
||||
var _index = require("./index.js");
|
||||
|
||||
var _utils = require("../react/utils.js");
|
||||
|
||||
var _index2 = require("../methods/index.js");
|
||||
|
||||
var _singletons = require("../singletons.js");
|
||||
|
||||
var _invariant = require("../invariant.js");
|
||||
|
||||
var _invariant2 = _interopRequireDefault(_invariant);
|
||||
|
||||
var _babelTypes = require("babel-types");
|
||||
|
||||
var t = _interopRequireWildcard(_babelTypes);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; } /**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
function isWidenedValue(v) {
|
||||
if (!(v instanceof _index.AbstractValue)) return false;
|
||||
if (v.kind === "widened" || v.kind === "widened property") return true;
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = v.args[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var a = _step.value;
|
||||
|
||||
if (isWidenedValue(a)) return true;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var ObjectValue = function (_ConcreteValue) {
|
||||
_inherits(ObjectValue, _ConcreteValue);
|
||||
|
||||
function ObjectValue(realm, proto, intrinsicName) {
|
||||
var refuseSerialization = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
||||
|
||||
_classCallCheck(this, ObjectValue);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, (ObjectValue.__proto__ || Object.getPrototypeOf(ObjectValue)).call(this, realm, intrinsicName));
|
||||
|
||||
realm.recordNewObject(_this);
|
||||
if (realm.useAbstractInterpretation) _this.setupBindings(_this.getTrackedPropertyNames());
|
||||
_this.$Prototype = proto || realm.intrinsics.null;
|
||||
_this.$Extensible = realm.intrinsics.true;
|
||||
_this._isPartial = realm.intrinsics.false;
|
||||
_this._hasLeaked = realm.intrinsics.false;
|
||||
_this._isSimple = realm.intrinsics.false;
|
||||
_this.properties = new Map();
|
||||
_this.symbols = new Map();
|
||||
_this.refuseSerialization = refuseSerialization;
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(ObjectValue, [{
|
||||
key: "getTrackedPropertyNames",
|
||||
value: function getTrackedPropertyNames() {
|
||||
return ObjectValue.trackedPropertyNames;
|
||||
}
|
||||
}, {
|
||||
key: "setupBindings",
|
||||
value: function setupBindings(propertyNames) {
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = propertyNames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var propName = _step2.value;
|
||||
|
||||
var desc = { writeable: true, value: undefined };
|
||||
this[propName + "_binding"] = {
|
||||
descriptor: desc,
|
||||
object: this,
|
||||
key: propName
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "equals",
|
||||
value: function equals(x) {
|
||||
return x instanceof ObjectValue && this.getHash() === x.getHash();
|
||||
}
|
||||
}, {
|
||||
key: "getHash",
|
||||
value: function getHash() {
|
||||
if (!this.hashValue) {
|
||||
this.hashValue = ++this.$Realm.objectCount;
|
||||
}
|
||||
return this.hashValue;
|
||||
}
|
||||
|
||||
// We track some internal state as properties on the global object, these should
|
||||
// never be serialized.
|
||||
|
||||
}, {
|
||||
key: "mightBeFalse",
|
||||
value: function mightBeFalse() {
|
||||
return false;
|
||||
}
|
||||
}, {
|
||||
key: "mightNotBeObject",
|
||||
value: function mightNotBeObject() {
|
||||
return false;
|
||||
}
|
||||
}, {
|
||||
key: "throwIfNotObject",
|
||||
value: function throwIfNotObject() {
|
||||
return this;
|
||||
}
|
||||
}, {
|
||||
key: "makeNotPartial",
|
||||
value: function makeNotPartial() {
|
||||
this._isPartial = this.$Realm.intrinsics.false;
|
||||
}
|
||||
}, {
|
||||
key: "makePartial",
|
||||
value: function makePartial() {
|
||||
this._isPartial = this.$Realm.intrinsics.true;
|
||||
}
|
||||
}, {
|
||||
key: "makeSimple",
|
||||
value: function makeSimple() {
|
||||
this._isSimple = this.$Realm.intrinsics.true;
|
||||
}
|
||||
}, {
|
||||
key: "isPartialObject",
|
||||
value: function isPartialObject() {
|
||||
return this._isPartial.value;
|
||||
}
|
||||
}, {
|
||||
key: "leak",
|
||||
value: function leak() {
|
||||
this._hasLeaked = this.$Realm.intrinsics.true;
|
||||
}
|
||||
}, {
|
||||
key: "isLeakedObject",
|
||||
value: function isLeakedObject() {
|
||||
if (this._hasLeaked instanceof _index.BooleanValue) {
|
||||
return this._hasLeaked.value;
|
||||
}
|
||||
if (this._hasLeaked === undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, {
|
||||
key: "isSimpleObject",
|
||||
value: function isSimpleObject() {
|
||||
if (this._isSimple.value) return true;
|
||||
if (this.isPartialObject()) return false;
|
||||
if (this.symbols.size > 0) return false;
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = this.properties.values()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var propertyBinding = _step3.value;
|
||||
|
||||
var desc = propertyBinding.descriptor;
|
||||
if (desc === undefined) continue; // deleted
|
||||
if (!(0, _index2.IsDataDescriptor)(this.$Realm, desc)) return false;
|
||||
if (!desc.writable) return false;
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.$Prototype instanceof _index.NullValue) return true;
|
||||
if (this.$Prototype === this.$Realm.intrinsics.ObjectPrototype) return true;
|
||||
return this.$Prototype.isSimpleObject();
|
||||
}
|
||||
}, {
|
||||
key: "getExtensible",
|
||||
value: function getExtensible() {
|
||||
return this.$Extensible.value;
|
||||
}
|
||||
}, {
|
||||
key: "setExtensible",
|
||||
value: function setExtensible(v) {
|
||||
this.$Extensible = v ? this.$Realm.intrinsics.true : this.$Realm.intrinsics.false;
|
||||
}
|
||||
}, {
|
||||
key: "getKind",
|
||||
value: function getKind() {
|
||||
// we can deduce the natural prototype by checking whether the following internal slots are present
|
||||
if (this.$SymbolData !== undefined) return "Symbol";
|
||||
if (this.$StringData !== undefined) return "String";
|
||||
if (this.$NumberData !== undefined) return "Number";
|
||||
if (this.$BooleanData !== undefined) return "Boolean";
|
||||
if (this.$DateValue !== undefined) return "Date";
|
||||
if (this.$RegExpMatcher !== undefined) return "RegExp";
|
||||
if (this.$SetData !== undefined) return "Set";
|
||||
if (this.$MapData !== undefined) return "Map";
|
||||
if (this.$DataView !== undefined) return "DataView";
|
||||
if (this.$ArrayBufferData !== undefined) return "ArrayBuffer";
|
||||
if (this.$WeakMapData !== undefined) return "WeakMap";
|
||||
if (this.$WeakSetData !== undefined) return "WeakSet";
|
||||
if ((0, _utils.isReactElement)(this) && this.$Realm.react.enabled) return "ReactElement";
|
||||
if (this.$TypedArrayName !== undefined) return this.$TypedArrayName;
|
||||
// TODO #26 #712: Promises. All kinds of iterators. Generators.
|
||||
return "Object";
|
||||
}
|
||||
}, {
|
||||
key: "defineNativeMethod",
|
||||
value: function defineNativeMethod(name, length, callback) {
|
||||
var desc = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
||||
|
||||
var intrinsicName = void 0;
|
||||
if (typeof name === "string") {
|
||||
if (this.intrinsicName) intrinsicName = this.intrinsicName + "." + name;
|
||||
} else if (name instanceof _index.SymbolValue) {
|
||||
if (this.intrinsicName && name.intrinsicName) intrinsicName = this.intrinsicName + "[" + name.intrinsicName + "]";
|
||||
} else {
|
||||
(0, _invariant2.default)(false);
|
||||
}
|
||||
this.defineNativeProperty(name, new _index.NativeFunctionValue(this.$Realm, intrinsicName, name, length, callback, false), desc);
|
||||
}
|
||||
}, {
|
||||
key: "defineNativeProperty",
|
||||
value: function defineNativeProperty(name, value) {
|
||||
var desc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
(0, _invariant2.default)(!value || value instanceof _index.Value);
|
||||
this.$DefineOwnProperty(name, _extends({
|
||||
value: value,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
}, desc));
|
||||
}
|
||||
}, {
|
||||
key: "defineNativeGetter",
|
||||
value: function defineNativeGetter(name, callback) {
|
||||
var desc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
var intrinsicName = void 0,
|
||||
funcName = void 0;
|
||||
if (typeof name === "string") {
|
||||
funcName = "get " + name;
|
||||
if (this.intrinsicName) intrinsicName = this.intrinsicName + "." + name;
|
||||
} else if (name instanceof _index.SymbolValue) {
|
||||
funcName = name.$Description instanceof _index.Value ? "get [" + name.$Description.throwIfNotConcreteString().value + "]" : "get [" + "?" + "]";
|
||||
if (this.intrinsicName && name.intrinsicName) intrinsicName = this.intrinsicName + "[" + name.intrinsicName + "]";
|
||||
} else {
|
||||
(0, _invariant2.default)(false);
|
||||
}
|
||||
|
||||
var func = new _index.NativeFunctionValue(this.$Realm, intrinsicName, funcName, 0, callback);
|
||||
this.$DefineOwnProperty(name, _extends({
|
||||
get: func,
|
||||
set: this.$Realm.intrinsics.undefined,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
}, desc));
|
||||
}
|
||||
}, {
|
||||
key: "defineNativeConstant",
|
||||
value: function defineNativeConstant(name, value) {
|
||||
var desc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
(0, _invariant2.default)(!value || value instanceof _index.Value);
|
||||
this.$DefineOwnProperty(name, _extends({
|
||||
value: value,
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false
|
||||
}, desc));
|
||||
}
|
||||
}, {
|
||||
key: "getOwnPropertyKeysArray",
|
||||
value: function getOwnPropertyKeysArray() {
|
||||
var _this2 = this;
|
||||
|
||||
if (this.isPartialObject() || this.isLeakedObject() || this.unknownProperty !== undefined) {
|
||||
_index.AbstractValue.reportIntrospectionError(this);
|
||||
throw new _errors.FatalError();
|
||||
}
|
||||
|
||||
var keyArray = Array.from(this.properties.keys());
|
||||
keyArray = keyArray.filter(function (x) {
|
||||
var pb = _this2.properties.get(x);
|
||||
if (!pb || pb.descriptor === undefined) return false;
|
||||
var pv = pb.descriptor.value;
|
||||
if (pv === undefined) return true;
|
||||
(0, _invariant2.default)(pv instanceof _index.Value);
|
||||
if (!pv.mightHaveBeenDeleted()) return true;
|
||||
// The property may or may not be there at runtime.
|
||||
// We can at best return an abstract keys array.
|
||||
// For now just terminate.
|
||||
(0, _invariant2.default)(pv instanceof _index.AbstractValue);
|
||||
_index.AbstractValue.reportIntrospectionError(pv);
|
||||
throw new _errors.FatalError();
|
||||
});
|
||||
this.$Realm.callReportObjectGetOwnProperties(this);
|
||||
return keyArray;
|
||||
}
|
||||
}, {
|
||||
key: "_serialize",
|
||||
value: function _serialize(set, stack) {
|
||||
var obj = set({});
|
||||
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator4 = this.properties[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
var _ref = _step4.value;
|
||||
|
||||
var _ref2 = _slicedToArray(_ref, 2);
|
||||
|
||||
var key = _ref2[0];
|
||||
var propertyBinding = _ref2[1];
|
||||
|
||||
var desc = propertyBinding.descriptor;
|
||||
if (desc === undefined) continue; // deleted
|
||||
_singletons.Properties.ThrowIfMightHaveBeenDeleted(desc.value);
|
||||
var serializedDesc = { enumerable: desc.enumerable, configurable: desc.configurable };
|
||||
if (desc.value) {
|
||||
serializedDesc.writable = desc.writable;
|
||||
(0, _invariant2.default)(desc.value instanceof _index.Value);
|
||||
serializedDesc.value = desc.value.serialize(stack);
|
||||
} else {
|
||||
(0, _invariant2.default)(desc.get !== undefined);
|
||||
serializedDesc.get = desc.get.serialize(stack);
|
||||
(0, _invariant2.default)(desc.set !== undefined);
|
||||
serializedDesc.set = desc.set.serialize(stack);
|
||||
}
|
||||
Object.defineProperty(obj, key, serializedDesc);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// ECMA262 9.1.1
|
||||
|
||||
}, {
|
||||
key: "$GetPrototypeOf",
|
||||
value: function $GetPrototypeOf() {
|
||||
return this.$Prototype;
|
||||
}
|
||||
|
||||
// ECMA262 9.1.2
|
||||
|
||||
}, {
|
||||
key: "$SetPrototypeOf",
|
||||
value: function $SetPrototypeOf(V) {
|
||||
// 1. Return ! OrdinarySetPrototypeOf(O, V).
|
||||
return _singletons.Properties.OrdinarySetPrototypeOf(this.$Realm, this, V);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.3
|
||||
|
||||
}, {
|
||||
key: "$IsExtensible",
|
||||
value: function $IsExtensible() {
|
||||
// 1. Return ! OrdinaryIsExtensible(O).
|
||||
return (0, _index2.OrdinaryIsExtensible)(this.$Realm, this);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.4
|
||||
|
||||
}, {
|
||||
key: "$PreventExtensions",
|
||||
value: function $PreventExtensions() {
|
||||
// 1. Return ! OrdinaryPreventExtensions(O).
|
||||
return (0, _index2.OrdinaryPreventExtensions)(this.$Realm, this);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.5
|
||||
|
||||
}, {
|
||||
key: "$GetOwnProperty",
|
||||
value: function $GetOwnProperty(P) {
|
||||
// 1. Return ! OrdinaryGetOwnProperty(O, P).
|
||||
return _singletons.Properties.OrdinaryGetOwnProperty(this.$Realm, this, P);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.6
|
||||
|
||||
}, {
|
||||
key: "$DefineOwnProperty",
|
||||
value: function $DefineOwnProperty(P, Desc) {
|
||||
// 1. Return ? OrdinaryDefineOwnProperty(O, P, Desc).
|
||||
return _singletons.Properties.OrdinaryDefineOwnProperty(this.$Realm, this, P, Desc);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.7
|
||||
|
||||
}, {
|
||||
key: "$HasProperty",
|
||||
value: function $HasProperty(P) {
|
||||
if (this.unknownProperty !== undefined && this.$GetOwnProperty(P) === undefined) {
|
||||
_index.AbstractValue.reportIntrospectionError(this, P);
|
||||
throw new _errors.FatalError();
|
||||
}
|
||||
|
||||
return (0, _index2.OrdinaryHasProperty)(this.$Realm, this, P);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.8
|
||||
|
||||
}, {
|
||||
key: "$Get",
|
||||
value: function $Get(P, Receiver) {
|
||||
var prop = this.unknownProperty;
|
||||
if (prop !== undefined && prop.descriptor !== undefined && this.$GetOwnProperty(P) === undefined) {
|
||||
var desc = prop.descriptor;
|
||||
(0, _invariant2.default)(desc !== undefined);
|
||||
var val = desc.value;
|
||||
(0, _invariant2.default)(val instanceof _index.AbstractValue);
|
||||
var propName = void 0;
|
||||
if (P instanceof _index.StringValue) {
|
||||
propName = P;
|
||||
} else if (typeof P === "string") {
|
||||
propName = new _index.StringValue(this.$Realm, P);
|
||||
} else {
|
||||
_index.AbstractValue.reportIntrospectionError(val, "abstract computed property name");
|
||||
throw new _errors.FatalError();
|
||||
}
|
||||
return this.specializeJoin(val, propName);
|
||||
}
|
||||
|
||||
// 1. Return ? OrdinaryGet(O, P, Receiver).
|
||||
return (0, _index2.OrdinaryGet)(this.$Realm, this, P, Receiver);
|
||||
}
|
||||
}, {
|
||||
key: "$GetPartial",
|
||||
value: function $GetPartial(P, Receiver) {
|
||||
if (!(P instanceof _index.AbstractValue)) return this.$Get(P, Receiver);
|
||||
// We assume that simple objects have no getter/setter properties.
|
||||
if (this !== Receiver || !this.isSimpleObject() || P.mightNotBeString() && P.mightNotBeNumber()) {
|
||||
_index.AbstractValue.reportIntrospectionError(P, "TODO: #1021");
|
||||
throw new _errors.FatalError();
|
||||
}
|
||||
// If all else fails, use this expression
|
||||
var result = void 0;
|
||||
if (this.isPartialObject()) {
|
||||
if (isWidenedValue(P)) {
|
||||
return _index.AbstractValue.createTemporalFromBuildFunction(this.$Realm, _index.Value, [this, P], function (_ref3) {
|
||||
var _ref4 = _slicedToArray(_ref3, 2),
|
||||
o = _ref4[0],
|
||||
p = _ref4[1];
|
||||
|
||||
return t.memberExpression(o, p, true);
|
||||
});
|
||||
}
|
||||
result = _index.AbstractValue.createFromType(this.$Realm, _index.Value, "sentinel member expression");
|
||||
result.args = [this, P];
|
||||
} else {
|
||||
result = this.$Realm.intrinsics.undefined;
|
||||
}
|
||||
// Get a specialization of the join of all values written to the object
|
||||
// with abstract property names.
|
||||
var prop = this.unknownProperty;
|
||||
if (prop !== undefined) {
|
||||
var desc = prop.descriptor;
|
||||
if (desc !== undefined) {
|
||||
var val = desc.value;
|
||||
(0, _invariant2.default)(val instanceof _index.AbstractValue);
|
||||
result = this.specializeJoin(val, P);
|
||||
}
|
||||
}
|
||||
// Join in all of the other values that were written to the object with
|
||||
// concrete property names.
|
||||
var _iteratorNormalCompletion5 = true;
|
||||
var _didIteratorError5 = false;
|
||||
var _iteratorError5 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator5 = this.properties[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
||||
var _ref5 = _step5.value;
|
||||
|
||||
var _ref6 = _slicedToArray(_ref5, 2);
|
||||
|
||||
var key = _ref6[0];
|
||||
var propertyBinding = _ref6[1];
|
||||
|
||||
var _desc = propertyBinding.descriptor;
|
||||
if (_desc === undefined) continue; // deleted
|
||||
(0, _invariant2.default)(_desc.value !== undefined); // otherwise this is not simple
|
||||
var _val = _desc.value;
|
||||
(0, _invariant2.default)(_val instanceof _index.Value);
|
||||
var cond = _index.AbstractValue.createFromBinaryOp(this.$Realm, "===", P, new _index.StringValue(this.$Realm, key), undefined, "check for known property");
|
||||
result = _singletons.Join.joinValuesAsConditional(this.$Realm, cond, _val, result);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError5 = true;
|
||||
_iteratorError5 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion5 && _iterator5.return) {
|
||||
_iterator5.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError5) {
|
||||
throw _iteratorError5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}, {
|
||||
key: "specializeJoin",
|
||||
value: function specializeJoin(absVal, propName) {
|
||||
if (absVal.kind === "widened property") {
|
||||
var ob = absVal.args[0];
|
||||
if (propName instanceof _index.StringValue) {
|
||||
var pName = propName.value;
|
||||
var pNumber = +pName;
|
||||
if (pName === pNumber + "") propName = new _index.NumberValue(this.$Realm, pNumber);
|
||||
}
|
||||
return _index.AbstractValue.createTemporalFromBuildFunction(this.$Realm, absVal.getType(), [ob, propName], function (_ref7) {
|
||||
var _ref8 = _slicedToArray(_ref7, 2),
|
||||
o = _ref8[0],
|
||||
p = _ref8[1];
|
||||
|
||||
return t.memberExpression(o, p, true);
|
||||
});
|
||||
}
|
||||
(0, _invariant2.default)(absVal.args.length === 3 && absVal.kind === "conditional");
|
||||
var generic_cond = absVal.args[0];
|
||||
(0, _invariant2.default)(generic_cond instanceof _index.AbstractValue);
|
||||
var cond = this.specializeCond(generic_cond, propName);
|
||||
var arg1 = absVal.args[1];
|
||||
if (arg1 instanceof _index.AbstractValue && arg1.args.length === 3) arg1 = this.specializeJoin(arg1, propName);
|
||||
var arg2 = absVal.args[2];
|
||||
if (arg2 instanceof _index.AbstractValue && arg2.args.length === 3) arg2 = this.specializeJoin(arg2, propName);
|
||||
return _index.AbstractValue.createFromConditionalOp(this.$Realm, cond, arg1, arg2, absVal.expressionLocation);
|
||||
}
|
||||
}, {
|
||||
key: "specializeCond",
|
||||
value: function specializeCond(absVal, propName) {
|
||||
if (absVal.kind === "template for property name condition") return _index.AbstractValue.createFromBinaryOp(this.$Realm, "===", absVal.args[0], propName);
|
||||
return absVal;
|
||||
}
|
||||
|
||||
// ECMA262 9.1.9
|
||||
|
||||
}, {
|
||||
key: "$Set",
|
||||
value: function $Set(P, V, Receiver) {
|
||||
// 1. Return ? OrdinarySet(O, P, V, Receiver).
|
||||
return _singletons.Properties.OrdinarySet(this.$Realm, this, P, V, Receiver);
|
||||
}
|
||||
}, {
|
||||
key: "$SetPartial",
|
||||
value: function $SetPartial(P, V, Receiver) {
|
||||
if (!(P instanceof _index.AbstractValue)) return this.$Set(P, V, Receiver);
|
||||
var pIsLoopVar = isWidenedValue(P);
|
||||
var pIsNumeric = _index.Value.isTypeCompatibleWith(P.getType(), _index.NumberValue);
|
||||
|
||||
function createTemplate(realm, propName) {
|
||||
return _index.AbstractValue.createFromBinaryOp(realm, "===", propName, new _index.StringValue(realm, ""), undefined, "template for property name condition");
|
||||
}
|
||||
|
||||
// We assume that simple objects have no getter/setter properties and
|
||||
// that all properties are writable.
|
||||
if (this !== Receiver || !this.isSimpleObject() || P.mightNotBeString() && P.mightNotBeNumber()) {
|
||||
_index.AbstractValue.reportIntrospectionError(P, "TODO #1021");
|
||||
throw new _errors.FatalError();
|
||||
}
|
||||
|
||||
var prop = void 0;
|
||||
if (this.unknownProperty === undefined) {
|
||||
prop = {
|
||||
descriptor: undefined,
|
||||
object: this,
|
||||
key: P
|
||||
};
|
||||
this.unknownProperty = prop;
|
||||
} else {
|
||||
prop = this.unknownProperty;
|
||||
}
|
||||
this.$Realm.recordModifiedProperty(prop);
|
||||
var desc = prop.descriptor;
|
||||
if (desc === undefined) {
|
||||
var newVal = V;
|
||||
if (!(V instanceof _index.UndefinedValue) && !isWidenedValue(P)) {
|
||||
// join V with undefined, using a property name test as the condition
|
||||
var cond = createTemplate(this.$Realm, P);
|
||||
newVal = _singletons.Join.joinValuesAsConditional(this.$Realm, cond, V, this.$Realm.intrinsics.undefined);
|
||||
}
|
||||
prop.descriptor = {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: newVal
|
||||
};
|
||||
} else {
|
||||
// join V with current value of this.unknownProperty. I.e. weak update.
|
||||
var oldVal = desc.value;
|
||||
(0, _invariant2.default)(oldVal instanceof _index.Value);
|
||||
var _newVal = oldVal;
|
||||
if (!(V instanceof _index.UndefinedValue)) {
|
||||
if (isWidenedValue(P)) {
|
||||
_newVal = V; // It will be widened later on
|
||||
} else {
|
||||
var _cond = createTemplate(this.$Realm, P);
|
||||
_newVal = _singletons.Join.joinValuesAsConditional(this.$Realm, _cond, V, oldVal);
|
||||
}
|
||||
}
|
||||
desc.value = _newVal;
|
||||
}
|
||||
|
||||
// Since we don't know the name of the property we are writing to, we also need
|
||||
// to perform weak updates of all of the known properties.
|
||||
// First clear out this.unknownProperty so that helper routines know its OK to update the properties
|
||||
var savedUnknownProperty = this.unknownProperty;
|
||||
this.unknownProperty = undefined;
|
||||
var _iteratorNormalCompletion6 = true;
|
||||
var _didIteratorError6 = false;
|
||||
var _iteratorError6 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator6 = this.properties[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
|
||||
var _ref9 = _step6.value;
|
||||
|
||||
var _ref10 = _slicedToArray(_ref9, 2);
|
||||
|
||||
var key = _ref10[0];
|
||||
var propertyBinding = _ref10[1];
|
||||
|
||||
if (pIsLoopVar && pIsNumeric) {
|
||||
// Delete numeric properties and don't do weak updates on other properties.
|
||||
if (key !== +key + "") continue;
|
||||
this.properties.delete(key);
|
||||
continue;
|
||||
}
|
||||
var _oldVal = this.$Realm.intrinsics.empty;
|
||||
if (propertyBinding.descriptor && propertyBinding.descriptor.value) {
|
||||
_oldVal = propertyBinding.descriptor.value;
|
||||
(0, _invariant2.default)(_oldVal instanceof _index.Value); // otherwise this is not simple
|
||||
}
|
||||
var _cond2 = _index.AbstractValue.createFromBinaryOp(this.$Realm, "===", P, new _index.StringValue(this.$Realm, key));
|
||||
var _newVal2 = _singletons.Join.joinValuesAsConditional(this.$Realm, _cond2, V, _oldVal);
|
||||
_singletons.Properties.OrdinarySet(this.$Realm, this, key, _newVal2, Receiver);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError6 = true;
|
||||
_iteratorError6 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion6 && _iterator6.return) {
|
||||
_iterator6.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError6) {
|
||||
throw _iteratorError6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.unknownProperty = savedUnknownProperty;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ECMA262 9.1.10
|
||||
|
||||
}, {
|
||||
key: "$Delete",
|
||||
value: function $Delete(P) {
|
||||
if (this.unknownProperty !== undefined) {
|
||||
// TODO #946: generate a delete from the object
|
||||
_index.AbstractValue.reportIntrospectionError(this, P);
|
||||
throw new _errors.FatalError();
|
||||
}
|
||||
|
||||
// 1. Return ? OrdinaryDelete(O, P).
|
||||
return _singletons.Properties.OrdinaryDelete(this.$Realm, this, P);
|
||||
}
|
||||
|
||||
// ECMA262 9.1.11
|
||||
|
||||
}, {
|
||||
key: "$OwnPropertyKeys",
|
||||
value: function $OwnPropertyKeys() {
|
||||
return (0, _index2.OrdinaryOwnPropertyKeys)(this.$Realm, this);
|
||||
}
|
||||
}], [{
|
||||
key: "setupTrackedPropertyAccessors",
|
||||
value: function setupTrackedPropertyAccessors(propertyNames) {
|
||||
var _loop = function _loop(propName) {
|
||||
Object.defineProperty(ObjectValue.prototype, propName, {
|
||||
configurable: true,
|
||||
get: function get() {
|
||||
var binding = this[propName + "_binding"];
|
||||
return binding.descriptor.value;
|
||||
},
|
||||
set: function set(v) {
|
||||
(0, _invariant2.default)(!this.isLeakedObject(), "cannot mutate a leaked object");
|
||||
var binding = this[propName + "_binding"];
|
||||
this.$Realm.recordModifiedProperty(binding);
|
||||
binding.descriptor.value = v;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var _iteratorNormalCompletion7 = true;
|
||||
var _didIteratorError7 = false;
|
||||
var _iteratorError7 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator7 = propertyNames[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
|
||||
var propName = _step7.value;
|
||||
|
||||
_loop(propName);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError7 = true;
|
||||
_iteratorError7 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion7 && _iterator7.return) {
|
||||
_iterator7.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError7) {
|
||||
throw _iteratorError7;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // undefined when the property is "missing"
|
||||
|
||||
|
||||
// error
|
||||
|
||||
|
||||
// function
|
||||
|
||||
|
||||
// promise
|
||||
|
||||
|
||||
// iterator
|
||||
|
||||
|
||||
// set
|
||||
|
||||
|
||||
// react
|
||||
|
||||
|
||||
// map
|
||||
|
||||
|
||||
// weak map
|
||||
|
||||
|
||||
// weak set
|
||||
|
||||
|
||||
// date
|
||||
// of type number
|
||||
|
||||
// array
|
||||
|
||||
|
||||
// regex
|
||||
|
||||
|
||||
// string
|
||||
|
||||
|
||||
// data view
|
||||
|
||||
|
||||
// array buffer
|
||||
|
||||
|
||||
// generator
|
||||
|
||||
|
||||
// typed array
|
||||
|
||||
|
||||
// backpointer to the constructor if this object was created its prototype object
|
||||
|
||||
|
||||
// partial objects
|
||||
|
||||
|
||||
// tainted objects
|
||||
|
||||
|
||||
// If true, the object has no property getters or setters and it is safe
|
||||
// to return AbstractValue for unknown properties.
|
||||
|
||||
|
||||
// An object value with an intrinsic name can either exist from the beginning of time,
|
||||
// or it can be associated with a particular point in time by being used as a template
|
||||
// when deriving an abstract value via a generator.
|
||||
|
||||
|
||||
// ReactElement
|
||||
|
||||
}]);
|
||||
|
||||
return ObjectValue;
|
||||
}(_index.ConcreteValue);
|
||||
|
||||
ObjectValue.trackedPropertyNames = ["_isPartial", "_hasLeaked", "_isSimple", "$ArrayIteratorNextIndex", "$DateValue", "$Extensible", "$IteratedList", "$IteratedObject", "$IteratedSet", "$IteratedString", "$Map", "$MapData", "$MapNextIndex", "$Prototype", "$SetData", "$SetNextIndex", "$StringIteratorNextIndex", "$WeakMapData", "$WeakSetData"];
|
||||
exports.default = ObjectValue;
|
||||
//# sourceMappingURL=ObjectValue.js.map
|
||||
Reference in New Issue
Block a user