Files
asciidisco.com/build/node_modules/prepack/lib/serializer/ResidualHeapSerializer.js
2023-08-01 13:49:46 +02:00

1924 lines
88 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ResidualHeapSerializer = 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 _realm = require("../realm.js");
var _index = require("../methods/index.js");
var _index2 = require("../values/index.js");
var _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
var _generator = require("../utils/generator.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _types = require("./types.js");
var _logger = require("./logger.js");
var _modules = require("./modules.js");
var _ResidualHeapInspector = require("./ResidualHeapInspector.js");
var _ResidualFunctions = require("./ResidualFunctions.js");
var _factorify = require("./factorify.js");
var _internalizer = require("../utils/internalizer.js");
var _Emitter = require("./Emitter.js");
var _ResidualHeapValueIdentifiers = require("./ResidualHeapValueIdentifiers.js");
var _utils = require("./utils.js");
var _hoisting = require("../react/hoisting.js");
var _singletons = require("../singletons.js");
var _ResidualReactElements = require("./ResidualReactElements.js");
var _environment = require("../environment.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function commentStatement(text) {
var s = t.emptyStatement();
s.leadingComments = [{ type: "BlockComment", value: text }];
return s;
}
var ResidualHeapSerializer = exports.ResidualHeapSerializer = function () {
function ResidualHeapSerializer(realm, logger, modules, residualHeapValueIdentifiers, residualHeapInspector, residualValues, residualFunctionInstances, residualFunctionInfos, options, referencedDeclaredValues, additionalFunctionValuesAndEffects, additionalFunctionValueInfos, declarativeEnvironmentRecordsBindings, statistics, react) {
var _this = this;
_classCallCheck(this, ResidualHeapSerializer);
this.realm = realm;
this.logger = logger;
this.modules = modules;
this.residualHeapValueIdentifiers = residualHeapValueIdentifiers;
this.statistics = statistics;
this.react = react;
var realmGenerator = this.realm.generator;
(0, _invariant2.default)(realmGenerator);
this.generator = realmGenerator;
var realmPreludeGenerator = this.realm.preludeGenerator;
(0, _invariant2.default)(realmPreludeGenerator);
this.preludeGenerator = realmPreludeGenerator;
this.prelude = [];
this._descriptors = new Map();
this.needsEmptyVar = false;
this.needsAuxiliaryConstructor = false;
this.descriptorNameGenerator = this.preludeGenerator.createNameGenerator("$$");
this.factoryNameGenerator = this.preludeGenerator.createNameGenerator("$_");
this.intrinsicNameGenerator = this.preludeGenerator.createNameGenerator("$i_");
this.functionNameGenerator = this.preludeGenerator.createNameGenerator("$f_");
this.requireReturns = new Map();
this.serializedValues = new Set();
this._serializedValueWithIdentifiers = new Set();
this.additionalFunctionValueNestedFunctions = new Set();
this.residualReactElements = new _ResidualReactElements.ResidualReactElements(this.realm, this);
this.residualFunctions = new _ResidualFunctions.ResidualFunctions(this.realm, this.statistics, options, this.modules, this.requireReturns, {
getLocation: function getLocation(value) {
return _this.getSerializeObjectIdentifier(value);
},
createLocation: function createLocation() {
var initializeConditionNameGenerator = _this.preludeGenerator.createNameGenerator("_initialized");
var location = t.identifier(initializeConditionNameGenerator.generate());
_this.currentFunctionBody.entries.push(t.variableDeclaration("var", [t.variableDeclarator(location)]));
return location;
}
}, this.prelude, this.preludeGenerator.createNameGenerator("__init_"), this.factoryNameGenerator, this.preludeGenerator.createNameGenerator("__scope_"), this.preludeGenerator.createNameGenerator("$"), residualFunctionInfos, residualFunctionInstances, additionalFunctionValueInfos, this.additionalFunctionValueNestedFunctions);
this.emitter = new _Emitter.Emitter(this.residualFunctions);
this.mainBody = this.emitter.getBody();
this.currentFunctionBody = this.mainBody;
this.residualHeapInspector = residualHeapInspector;
this.residualValues = residualValues;
this.residualFunctionInstances = residualFunctionInstances;
this.residualFunctionInfos = residualFunctionInfos;
this._options = options;
this.referencedDeclaredValues = referencedDeclaredValues;
this.activeGeneratorBodies = new Map();
this.additionalFunctionValuesAndEffects = additionalFunctionValuesAndEffects;
this.additionalFunctionValueInfos = additionalFunctionValueInfos;
this.declarativeEnvironmentRecordsBindings = declarativeEnvironmentRecordsBindings;
}
// if we're in an additional function we need to access both mainBody and the
// additional function's body which will be currentFunctionBody.
// function values nested in additional functions can't delay initializations
// TODO: revisit this and fix additional functions to be capable of delaying initializations
_createClass(ResidualHeapSerializer, [{
key: "_emitObjectProperties",
// Configures all mutable aspects of an object, in particular:
// symbols, properties, prototype.
// For every created object that corresponds to a value,
// this function should be invoked once.
// Thus, as a side effect, we gather statistics here on all emitted objects.
value: function _emitObjectProperties(obj) {
var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : obj.properties;
var _this2 = this;
var objectPrototypeAlreadyEstablished = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var cleanupDummyProperties = arguments[3];
var _loop = function _loop(symbol, propertyBinding) {
(0, _invariant2.default)(propertyBinding);
var desc = propertyBinding.descriptor;
if (desc === undefined) return "continue"; //deleted
_this2.emitter.emitNowOrAfterWaitingForDependencies(_this2._getDescriptorValues(desc).concat([symbol, obj]), function () {
(0, _invariant2.default)(desc !== undefined);
return _this2._emitProperty(obj, symbol, desc);
});
};
//inject symbols
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = obj.symbols[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = _slicedToArray(_ref, 2);
var symbol = _ref2[0];
var propertyBinding = _ref2[1];
var _ret = _loop(symbol, propertyBinding);
if (_ret === "continue") continue;
}
// inject properties
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var _loop2 = function _loop2(key, propertyBinding) {
(0, _invariant2.default)(propertyBinding);
if (propertyBinding.pathNode !== undefined) return "continue"; // Property is assigned to inside loop
var desc = propertyBinding.descriptor;
if (desc === undefined) return "continue"; //deleted
if (_this2.residualHeapInspector.canIgnoreProperty(obj, key)) return "continue";
(0, _invariant2.default)(desc !== undefined);
_this2.emitter.emitNowOrAfterWaitingForDependencies(_this2._getDescriptorValues(desc).concat(obj), function () {
(0, _invariant2.default)(desc !== undefined);
return _this2._emitProperty(obj, key, desc, cleanupDummyProperties != null && cleanupDummyProperties.has(key));
});
};
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = properties[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var _ref3 = _step2.value;
var _ref4 = _slicedToArray(_ref3, 2);
var key = _ref4[0];
var propertyBinding = _ref4[1];
var _ret2 = _loop2(key, propertyBinding);
if (_ret2 === "continue") continue;
}
// inject properties with computed names
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
if (obj.unknownProperty !== undefined) {
var _desc = obj.unknownProperty.descriptor;
if (_desc !== undefined) {
var val = _desc.value;
(0, _invariant2.default)(val instanceof _index2.AbstractValue);
this.emitter.emitNowOrAfterWaitingForDependencies(this._getNestedAbstractValues(val, [obj]), function () {
(0, _invariant2.default)(val instanceof _index2.AbstractValue);
_this2._emitPropertiesWithComputedNames(obj, val);
});
}
}
// prototype
this._emitObjectPrototype(obj, objectPrototypeAlreadyEstablished);
if (obj instanceof _index2.FunctionValue) this._emitConstructorPrototype(obj);
this.statistics.objects++;
this.statistics.objectProperties += obj.properties.size;
}
}, {
key: "_emitObjectPrototype",
value: function _emitObjectPrototype(obj, objectPrototypeAlreadyEstablished) {
var _this3 = this;
var kind = obj.getKind();
var proto = obj.$Prototype;
if (objectPrototypeAlreadyEstablished) {
// Emitting an assertion. This can be removed in the future, or put under a DEBUG flag.
this.emitter.emitNowOrAfterWaitingForDependencies([proto, obj], function () {
(0, _invariant2.default)(proto);
var serializedProto = _this3.serializeValue(proto);
var uid = _this3.getSerializeObjectIdentifier(obj);
var fetchedPrototype = _this3.realm.isCompatibleWith(_this3.realm.MOBILE_JSC_VERSION) ? t.memberExpression(uid, _internalizer.protoExpression) : t.callExpression(_this3.preludeGenerator.memoizeReference("Object.getPrototypeOf"), [uid]);
var condition = t.binaryExpression("!==", fetchedPrototype, serializedProto);
var throwblock = t.blockStatement([t.throwStatement(t.newExpression(t.identifier("Error"), [t.stringLiteral("unexpected prototype")]))]);
_this3.emitter.emit(t.ifStatement(condition, throwblock));
});
return;
}
if (proto === this.realm.intrinsics[kind + "Prototype"]) return;
this.emitter.emitNowOrAfterWaitingForDependencies([proto, obj], function () {
(0, _invariant2.default)(proto);
var serializedProto = _this3.serializeValue(proto);
var uid = _this3.getSerializeObjectIdentifier(obj);
if (!_this3.realm.isCompatibleWith(_this3.realm.MOBILE_JSC_VERSION)) _this3.emitter.emit(t.expressionStatement(t.callExpression(_this3.preludeGenerator.memoizeReference("Object.setPrototypeOf"), [uid, serializedProto])));else {
_this3.emitter.emit(t.expressionStatement(t.assignmentExpression("=", t.memberExpression(uid, _internalizer.protoExpression), serializedProto)));
}
});
}
}, {
key: "_emitConstructorPrototype",
value: function _emitConstructorPrototype(func) {
var _this4 = this;
// If the original prototype object was mutated,
// request its serialization here as this might be observable by
// residual code.
var prototype = _ResidualHeapInspector.ResidualHeapInspector.getPropertyValue(func, "prototype");
if (prototype instanceof _index2.ObjectValue && this.residualValues.has(prototype)) {
this.emitter.emitNowOrAfterWaitingForDependencies([func], function () {
(0, _invariant2.default)(prototype instanceof _index2.Value);
_this4.serializeValue(prototype);
});
}
}
}, {
key: "_getNestedAbstractValues",
value: function _getNestedAbstractValues(absVal, values) {
if (absVal.kind === "widened property") return values;
(0, _invariant2.default)(absVal.args.length === 3);
var cond = absVal.args[0];
(0, _invariant2.default)(cond instanceof _index2.AbstractValue);
if (cond.kind === "template for property name condition") {
var P = cond.args[0];
values.push(P);
var V = absVal.args[1];
values.push(V);
var W = absVal.args[2];
if (W instanceof _index2.AbstractValue) this._getNestedAbstractValues(W, values);else values.push(W);
} else {
// conditional assignment
values.push(cond);
var consequent = absVal.args[1];
(0, _invariant2.default)(consequent instanceof _index2.AbstractValue);
var alternate = absVal.args[2];
(0, _invariant2.default)(alternate instanceof _index2.AbstractValue);
this._getNestedAbstractValues(consequent, values);
this._getNestedAbstractValues(alternate, values);
}
return values;
}
}, {
key: "_emitPropertiesWithComputedNames",
value: function _emitPropertiesWithComputedNames(obj, absVal) {
if (absVal.kind === "widened property") return;
(0, _invariant2.default)(absVal.args.length === 3);
var cond = absVal.args[0];
(0, _invariant2.default)(cond instanceof _index2.AbstractValue);
if (cond.kind === "template for property name condition") {
var P = cond.args[0];
(0, _invariant2.default)(P instanceof _index2.AbstractValue);
var V = absVal.args[1];
var earlier_props = absVal.args[2];
if (earlier_props instanceof _index2.AbstractValue) this._emitPropertiesWithComputedNames(obj, earlier_props);
var uid = this.getSerializeObjectIdentifier(obj);
var serializedP = this.serializeValue(P);
var serializedV = this.serializeValue(V);
this.emitter.emit(t.expressionStatement(t.assignmentExpression("=", t.memberExpression(uid, serializedP, true), serializedV)));
} else {
// conditional assignment
var serializedCond = this.serializeValue(cond);
var consequent = absVal.args[1];
(0, _invariant2.default)(consequent instanceof _index2.AbstractValue);
var alternate = absVal.args[2];
(0, _invariant2.default)(alternate instanceof _index2.AbstractValue);
var oldBody = this.emitter.beginEmitting("consequent", {
type: "ConditionalAssignmentBranch",
parentBody: undefined,
entries: []
},
/*isChild*/true);
this._emitPropertiesWithComputedNames(obj, consequent);
var consequentBody = this.emitter.endEmitting("consequent", oldBody);
var consequentStatement = t.blockStatement(consequentBody.entries);
oldBody = this.emitter.beginEmitting("alternate", {
type: "ConditionalAssignmentBranch",
parentBody: undefined,
entries: []
},
/*isChild*/true);
this._emitPropertiesWithComputedNames(obj, alternate);
var alternateBody = this.emitter.endEmitting("alternate", oldBody);
var alternateStatement = t.blockStatement(alternateBody.entries);
this.emitter.emit(t.ifStatement(serializedCond, consequentStatement, alternateStatement));
}
}
// Overridable.
}, {
key: "getSerializeObjectIdentifier",
value: function getSerializeObjectIdentifier(val) {
return this.residualHeapValueIdentifiers.getIdentifierAndIncrementReferenceCount(val);
}
}, {
key: "_emitProperty",
value: function _emitProperty(val, key, desc) {
var _this5 = this;
var deleteIfMightHaveBeenDeleted = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
// Location for the property to be assigned to
var locationFunction = function locationFunction() {
var serializedKey = key instanceof _index2.SymbolValue ? _this5.serializeValue(key) : _this5.generator.getAsPropertyNameExpression(key);
var computed = key instanceof _index2.SymbolValue || !t.isIdentifier(serializedKey);
return t.memberExpression(_this5.getSerializeObjectIdentifier(val), serializedKey, computed);
};
if (desc === undefined) {
this._deleteProperty(locationFunction());
} else {
this.emitter.emit(this.emitDefinePropertyBody(deleteIfMightHaveBeenDeleted, locationFunction, val, key, desc));
}
}
}, {
key: "emitDefinePropertyBody",
value: function emitDefinePropertyBody(deleteIfMightHaveBeenDeleted, locationFunction, val, key, desc) {
var _this6 = this;
if (desc.joinCondition) {
var cond = this.serializeValue(desc.joinCondition);
(0, _invariant2.default)(cond !== undefined);
var trueBody = void 0;
var falseBody = void 0;
if (desc.descriptor1) trueBody = this.emitDefinePropertyBody(deleteIfMightHaveBeenDeleted, locationFunction, val, key, desc.descriptor1);
if (desc.descriptor2) falseBody = this.emitDefinePropertyBody(deleteIfMightHaveBeenDeleted, locationFunction, val, key, desc.descriptor2);
if (trueBody && falseBody) return t.ifStatement(cond, trueBody, falseBody);
if (trueBody) return t.ifStatement(cond, trueBody);
if (falseBody) return t.ifStatement(t.unaryExpression("!", cond), falseBody);
(0, _invariant2.default)(false);
}
if (locationFunction !== undefined && this._canEmbedProperty(val, key, desc)) {
var descValue = desc.value;
(0, _invariant2.default)(descValue instanceof _index2.Value);
(0, _invariant2.default)(!this.emitter.getReasonToWaitForDependencies([descValue, val]), "precondition of _emitProperty");
var mightHaveBeenDeleted = descValue.mightHaveBeenDeleted();
// The only case we do not need to remove the dummy property is array index property.
return this._getPropertyAssignment(locationFunction, function () {
(0, _invariant2.default)(descValue instanceof _index2.Value);
return _this6.serializeValue(descValue);
}, mightHaveBeenDeleted, deleteIfMightHaveBeenDeleted);
}
var body = [];
var descProps = [];
var boolKeys = ["enumerable", "configurable"];
var valKeys = [];
if (!desc.get && !desc.set) {
boolKeys.push("writable");
valKeys.push("value");
} else {
valKeys.push("set", "get");
}
var descriptorsKey = [];
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = boolKeys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var boolKey = _step3.value;
if (boolKey in desc) {
var b = desc[boolKey];
(0, _invariant2.default)(b !== undefined);
descProps.push(t.objectProperty(t.identifier(boolKey), t.booleanLiteral(b)));
descriptorsKey.push(boolKey + ":" + b.toString());
}
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
descriptorsKey = descriptorsKey.join(",");
var descriptorId = this._descriptors.get(descriptorsKey);
if (descriptorId === undefined) {
descriptorId = t.identifier(this.descriptorNameGenerator.generate(descriptorsKey));
var declar = t.variableDeclaration("var", [t.variableDeclarator(descriptorId, t.objectExpression(descProps))]);
// The descriptors are used across all scopes, and thus must be declared in the prelude.
this.prelude.push(declar);
this._descriptors.set(descriptorsKey, descriptorId);
}
(0, _invariant2.default)(descriptorId !== undefined);
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = valKeys[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var descKey = _step4.value;
if (descKey in desc) {
var _descValue = desc[descKey];
(0, _invariant2.default)(_descValue instanceof _index2.Value);
if (_descValue instanceof _index2.UndefinedValue) {
this.serializeValue(_descValue);
continue;
}
(0, _invariant2.default)(!this.emitter.getReasonToWaitForDependencies([_descValue]), "precondition of _emitProperty");
body.push(t.assignmentExpression("=", t.memberExpression(descriptorId, t.identifier(descKey)), this.serializeValue(_descValue)));
}
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
var serializedKey = key instanceof _index2.SymbolValue ? this.serializeValue(key) : this.generator.getAsPropertyNameExpression(key, /*canBeIdentifier*/false);
(0, _invariant2.default)(!this.emitter.getReasonToWaitForDependencies([val]), "precondition of _emitProperty");
body.push(t.callExpression(this.preludeGenerator.memoizeReference("Object.defineProperty"), [this.getSerializeObjectIdentifier(val), serializedKey, descriptorId]));
return t.expressionStatement(t.sequenceExpression(body));
}
}, {
key: "_serializeDeclarativeEnvironmentRecordBinding",
value: function _serializeDeclarativeEnvironmentRecordBinding(residualFunctionBinding) {
if (!residualFunctionBinding.serializedValue) {
var value = residualFunctionBinding.value;
(0, _invariant2.default)(value);
(0, _invariant2.default)(residualFunctionBinding.declarativeEnvironmentRecord);
// Set up binding identity before starting to serialize value. This is needed in case of recursive dependencies.
residualFunctionBinding.referentialized = false;
residualFunctionBinding.serializedValue = this.serializeValue(value);
if (value.mightBeObject()) {
// Increment ref count one more time to ensure that this object will be assigned a unique id.
// This ensures that only once instance is created across all possible residual function invocations.
this.residualHeapValueIdentifiers.incrementReferenceCount(value);
}
}
}
// Determine whether initialization code for a value should go into the main body, or a more specific initialization body.
}, {
key: "_getTarget",
value: function _getTarget(val) {
var _this7 = this;
var scopes = this.residualValues.get(val);
(0, _invariant2.default)(scopes !== undefined);
// All relevant values were visited in at least one scope.
(0, _invariant2.default)(scopes.size >= 1);
// First, let's figure out from which function and generator scopes this value is referenced.
var functionValues = [];
var generators = [];
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = scopes[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var scope = _step5.value;
if (scope instanceof _index2.FunctionValue) functionValues.push(scope);else {
(0, _invariant2.default)(scope instanceof _generator.Generator);
if (scope === this.realm.generator) {
// This value is used from the main generator scope. This means that we need to emit the value and its
// initialization code into the main body, and cannot delay initialization.
return {
body: this.currentFunctionBody,
description: "this.realm.generator"
};
}
generators.push(scope);
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
if (generators.length === 0) {
// This value is only referenced from residual functions.
(0, _invariant2.default)(functionValues.length > 0);
var additionalFunctionValuesAndEffects = this.additionalFunctionValuesAndEffects;
var numAdditionalFunctionReferences = 0;
// Make sure we don't delay things referenced by additional functions or nested functions
if (additionalFunctionValuesAndEffects) {
// flow forces me to do this
var additionalFuncValuesAndEffects = additionalFunctionValuesAndEffects;
numAdditionalFunctionReferences = functionValues.filter(function (funcValue) {
return additionalFuncValuesAndEffects.has(funcValue) || _this7.additionalFunctionValueNestedFunctions.has(funcValue);
}).length;
}
if (numAdditionalFunctionReferences > 0 || !this._options.delayInitializations || this._options.simpleClosures) {
// We can just emit it into the current function body.
return {
body: this.currentFunctionBody,
usedOnlyByAdditionalFunctions: numAdditionalFunctionReferences === functionValues.length,
description: "this.currentFunctionBody"
};
} else {
// We can delay the initialization, and move it into a conditional code block in the residual functions!
var _body = this.residualFunctions.residualFunctionInitializers.registerValueOnlyReferencedByResidualFunctions(functionValues, val);
return { body: _body, usedOnlyByResidualFunctions: true, description: "delay_initializer" };
}
}
// This value is referenced from more than one generator or function.
// We can emit the initialization of this value into the body associated with their common ancestor.
var commonAncestor = Array.from(scopes).reduce(function (x, y) {
return (0, _utils.commonAncestorOf)(x, y);
}, generators[0]);
(0, _invariant2.default)(commonAncestor instanceof _generator.Generator); // every scope is either the root, or a descendant
var body = void 0;
while (true) {
if (commonAncestor === this.generator) {
body = this.currentFunctionBody;
} else {
body = this.activeGeneratorBodies.get(commonAncestor);
}
if (body !== undefined) break;
commonAncestor = commonAncestor.parent;
(0, _invariant2.default)(commonAncestor !== undefined);
}
(0, _invariant2.default)(body !== undefined);
return { body: body, commonAncestor: commonAncestor };
}
}, {
key: "_getValueDebugName",
value: function _getValueDebugName(val) {
var name = void 0;
if (val instanceof _index2.FunctionValue) {
name = val.getName();
} else {
var id = this.residualHeapValueIdentifiers.getIdentifier(val);
(0, _invariant2.default)(id);
name = id.name;
}
return name;
}
}, {
key: "serializeBinding",
value: function serializeBinding(binding) {
var record = binding.environment;
(0, _invariant2.default)(record instanceof _environment.DeclarativeEnvironmentRecord, "only declarative environments has bindings");
var residualFunctionBindings = this.declarativeEnvironmentRecordsBindings.get(record);
(0, _invariant2.default)(residualFunctionBindings, "all bindings that create abstract values must have at least one call emitted to the generator so the function environment should have been visited");
var residualBinding = residualFunctionBindings.get(binding.name);
(0, _invariant2.default)(residualBinding, "any referenced residual binding should have been visited");
if (!residualBinding.referentialized) {
var additionalFunction = residualBinding.referencedOnlyFromAdditionalFunctions;
(0, _invariant2.default)(additionalFunction, "residual bindings like this are only caused by leaked bindings in pure functions");
var instance = this.residualFunctionInstances.get(additionalFunction);
(0, _invariant2.default)(instance, "any serialized function must exist in the scope");
this.residualFunctions.referentializer.referentializeBinding(residualBinding, binding.name, instance);
}
(0, _invariant2.default)(residualBinding.serializedValue);
return residualBinding.serializedValue;
}
}, {
key: "serializeValue",
value: function serializeValue(val, referenceOnly, bindingType) {
(0, _invariant2.default)(!val.refuseSerialization);
if (val instanceof _index2.AbstractValue) {
if (val.kind === "widened") {
this.serializedValues.add(val);
var name = val.intrinsicName;
(0, _invariant2.default)(name !== undefined);
return t.identifier(name);
} else if (val.kind === "widened property") {
this.serializedValues.add(val);
return this._serializeAbstractValueHelper(val);
}
}
if (this._serializedValueWithIdentifiers.has(val)) {
return this.getSerializeObjectIdentifier(val);
}
this.serializedValues.add(val);
if (!referenceOnly && _ResidualHeapInspector.ResidualHeapInspector.isLeaf(val)) {
var res = this._serializeValue(val);
(0, _invariant2.default)(res !== undefined);
return res;
}
this._serializedValueWithIdentifiers.add(val);
var target = this._getTarget(val);
var oldBody = this.emitter.beginEmitting(val, target.body);
var init = this._serializeValue(val);
var id = this.residualHeapValueIdentifiers.getIdentifier(val);
var result = id;
this.residualHeapValueIdentifiers.incrementReferenceCount(val);
if (this.residualHeapValueIdentifiers.needsIdentifier(val)) {
if (init) {
if (this._options.debugScopes) {
var scopes = this.residualValues.get(val);
(0, _invariant2.default)(scopes !== undefined);
var scopeList = Array.from(scopes).map(function (s) {
return "\"" + s.getName() + "\"";
}).join(",");
var comment = this._getValueDebugName(val) + " referenced from scopes [" + scopeList + "]";
if (target.commonAncestor !== undefined) comment = comment + " with common ancestor: " + target.commonAncestor.getName();
if (target.description !== undefined) comment = comment + " => " + target.description + " ";
this.emitter.emit(commentStatement(comment));
}
if (init !== id) {
if (target.usedOnlyByResidualFunctions) {
var declar = t.variableDeclaration(bindingType ? bindingType : "var", [t.variableDeclarator(id)]);
this.mainBody.entries.push(declar);
var assignment = t.expressionStatement(t.assignmentExpression("=", id, init));
this.emitter.emit(assignment);
} else {
var _declar = t.variableDeclaration(bindingType ? bindingType : "var", [t.variableDeclarator(id, init)]);
this.emitter.emit(_declar);
}
}
this.statistics.valueIds++;
if (target.usedOnlyByResidualFunctions) this.statistics.delayedValues++;
}
} else {
if (init) {
this.residualHeapValueIdentifiers.deleteIdentifier(val);
result = init;
this.statistics.valuesInlined++;
}
}
this.emitter.endEmitting(val, oldBody);
return result;
}
}, {
key: "_serializeValueIntrinsic",
value: function _serializeValueIntrinsic(val) {
var intrinsicName = val.intrinsicName;
(0, _invariant2.default)(intrinsicName);
if (val instanceof _index2.ObjectValue && val.intrinsicNameGenerated) {
// The intrinsic was generated at a particular point in time.
return this.preludeGenerator.convertStringToMember(intrinsicName);
} else {
// The intrinsic conceptually exists ahead of time.
(0, _invariant2.default)(this.emitter.getBody() === this.currentFunctionBody);
return this.preludeGenerator.memoizeReference(intrinsicName);
}
}
}, {
key: "_getDescriptorValues",
value: function _getDescriptorValues(desc) {
if (desc.joinCondition !== undefined) return [desc.joinCondition];
(0, _invariant2.default)(desc.value === undefined || desc.value instanceof _index2.Value);
if (desc.value !== undefined) return [desc.value];
(0, _invariant2.default)(desc.get !== undefined);
(0, _invariant2.default)(desc.set !== undefined);
return [desc.get, desc.set];
}
}, {
key: "_deleteProperty",
value: function _deleteProperty(location) {
(0, _invariant2.default)(location.type === "MemberExpression");
this.emitter.emit(t.expressionStatement(t.unaryExpression("delete", location, true)));
}
}, {
key: "_assignProperty",
value: function _assignProperty(locationFn, valueFn, mightHaveBeenDeleted) {
var deleteIfMightHaveBeenDeleted = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
this.emitter.emit(this._getPropertyAssignment(locationFn, valueFn, mightHaveBeenDeleted, deleteIfMightHaveBeenDeleted));
}
}, {
key: "_getPropertyAssignment",
value: function _getPropertyAssignment(locationFn, valueFn, mightHaveBeenDeleted) {
var deleteIfMightHaveBeenDeleted = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var location = locationFn();
var value = valueFn();
var assignment = t.expressionStatement(t.assignmentExpression("=", location, value));
if (mightHaveBeenDeleted) {
var condition = t.binaryExpression("!==", value, this.serializeValue(this.realm.intrinsics.empty));
var deletion = null;
if (deleteIfMightHaveBeenDeleted) {
(0, _invariant2.default)(location.type === "MemberExpression");
deletion = t.expressionStatement(t.unaryExpression("delete", location, true));
}
return t.ifStatement(condition, assignment, deletion);
} else {
return assignment;
}
}
}, {
key: "_serializeArrayIndexProperties",
value: function _serializeArrayIndexProperties(array, indexPropertyLength, remainingProperties) {
var elems = [];
for (var i = 0; i < indexPropertyLength; i++) {
var key = i + "";
var propertyBinding = remainingProperties.get(key);
var elem = null;
// "propertyBinding === undefined" means array has a hole in the middle.
if (propertyBinding !== undefined) {
var descriptor = propertyBinding.descriptor;
// "descriptor === undefined" means this array item has been deleted.
if (descriptor !== undefined && descriptor.value !== undefined && this._canEmbedProperty(array, key, descriptor)) {
var elemVal = descriptor.value;
(0, _invariant2.default)(elemVal instanceof _index2.Value);
var mightHaveBeenDeleted = elemVal.mightHaveBeenDeleted();
var delayReason = this.emitter.getReasonToWaitForDependencies(elemVal) || this.emitter.getReasonToWaitForActiveValue(array, mightHaveBeenDeleted);
if (!delayReason) {
elem = this.serializeValue(elemVal);
remainingProperties.delete(key);
}
}
}
elems.push(elem);
}
return elems;
}
}, {
key: "_serializeArrayLengthIfNeeded",
value: function _serializeArrayLengthIfNeeded(val, numberOfIndexProperties, remainingProperties) {
var _this8 = this;
var realm = this.realm;
var lenProperty = (0, _index.Get)(realm, val, "length");
// Need to serialize length property if:
// 1. array length is abstract.
// 2. array length is concrete, but different from number of index properties
// we put into initialization list.
if (lenProperty instanceof _index2.AbstractValue || _singletons.To.ToLength(realm, lenProperty) !== numberOfIndexProperties) {
if (!(lenProperty instanceof _index2.AbstractValue) || lenProperty.kind !== "widened property") {
this.emitter.emitNowOrAfterWaitingForDependencies([val], function () {
_this8._assignProperty(function () {
return t.memberExpression(_this8.getSerializeObjectIdentifier(val), t.identifier("length"));
}, function () {
return _this8.serializeValue(lenProperty);
}, false /*mightHaveBeenDeleted*/
);
});
}
remainingProperties.delete("length");
}
}
}, {
key: "_serializeValueArray",
value: function _serializeValueArray(val) {
var remainingProperties = new Map(val.properties);
var indexPropertyLength = (0, _utils.getSuggestedArrayLiteralLength)(this.realm, val);
// Use the serialized index properties as array initialization list.
var initProperties = this._serializeArrayIndexProperties(val, indexPropertyLength, remainingProperties);
this._serializeArrayLengthIfNeeded(val, indexPropertyLength, remainingProperties);
this._emitObjectProperties(val, remainingProperties);
return t.arrayExpression(initProperties);
}
}, {
key: "_serializeValueMap",
value: function _serializeValueMap(val) {
var _this9 = this;
var kind = val.getKind();
var elems = [];
var entries = void 0;
if (kind === "Map") {
entries = val.$MapData;
} else {
(0, _invariant2.default)(kind === "WeakMap");
entries = val.$WeakMapData;
}
(0, _invariant2.default)(entries !== undefined);
var len = entries.length;
var mapConstructorDoesntTakeArguments = this.realm.isCompatibleWith(this.realm.MOBILE_JSC_VERSION);
var _loop3 = function _loop3(i) {
var entry = entries[i];
var key = entry.$Key;
var value = entry.$Value;
if (key === undefined || value === undefined) return "continue";
var mightHaveBeenDeleted = key.mightHaveBeenDeleted();
var delayReason = _this9.emitter.getReasonToWaitForDependencies(key) || _this9.emitter.getReasonToWaitForDependencies(value) || _this9.emitter.getReasonToWaitForActiveValue(val, mightHaveBeenDeleted || mapConstructorDoesntTakeArguments);
if (delayReason) {
_this9.emitter.emitAfterWaiting(delayReason, [key, value, val], function () {
(0, _invariant2.default)(key !== undefined);
(0, _invariant2.default)(value !== undefined);
_this9.emitter.emit(t.expressionStatement(t.callExpression(t.memberExpression(_this9.residualHeapValueIdentifiers.getIdentifierAndIncrementReferenceCount(val), t.identifier("set")), [_this9.serializeValue(key), _this9.serializeValue(value)])));
});
} else {
var serializedKey = _this9.serializeValue(key);
var serializedValue = _this9.serializeValue(value);
var elem = t.arrayExpression([serializedKey, serializedValue]);
elems.push(elem);
}
};
for (var i = 0; i < len; i++) {
var _ret3 = _loop3(i);
if (_ret3 === "continue") continue;
}
this._emitObjectProperties(val);
var args = elems.length > 0 ? [t.arrayExpression(elems)] : [];
return t.newExpression(this.preludeGenerator.memoizeReference(kind), args);
}
}, {
key: "_serializeValueSet",
value: function _serializeValueSet(val) {
var _this10 = this;
var kind = val.getKind();
var elems = [];
var entries = void 0;
if (kind === "Set") {
entries = val.$SetData;
} else {
(0, _invariant2.default)(kind === "WeakSet");
entries = val.$WeakSetData;
}
(0, _invariant2.default)(entries !== undefined);
var len = entries.length;
var setConstructorDoesntTakeArguments = this.realm.isCompatibleWith(this.realm.MOBILE_JSC_VERSION);
var _loop4 = function _loop4(i) {
var entry = entries[i];
if (entry === undefined) return "continue";
var mightHaveBeenDeleted = entry.mightHaveBeenDeleted();
var delayReason = _this10.emitter.getReasonToWaitForDependencies(entry) || _this10.emitter.getReasonToWaitForActiveValue(val, mightHaveBeenDeleted || setConstructorDoesntTakeArguments);
if (delayReason) {
_this10.emitter.emitAfterWaiting(delayReason, [entry, val], function () {
(0, _invariant2.default)(entry !== undefined);
_this10.emitter.emit(t.expressionStatement(t.callExpression(t.memberExpression(_this10.residualHeapValueIdentifiers.getIdentifierAndIncrementReferenceCount(val), t.identifier("add")), [_this10.serializeValue(entry)])));
});
} else {
var elem = _this10.serializeValue(entry);
elems.push(elem);
}
};
for (var i = 0; i < len; i++) {
var _ret4 = _loop4(i);
if (_ret4 === "continue") continue;
}
this._emitObjectProperties(val);
var args = elems.length > 0 ? [t.arrayExpression(elems)] : [];
return t.newExpression(this.preludeGenerator.memoizeReference(kind), args);
}
}, {
key: "_serializeValueTypedArrayOrDataView",
value: function _serializeValueTypedArrayOrDataView(val) {
var buf = val.$ViewedArrayBuffer;
(0, _invariant2.default)(buf !== undefined);
var outlinedArrayBuffer = this.serializeValue(buf, true);
this._emitObjectProperties(val);
return t.newExpression(this.preludeGenerator.memoizeReference(val.getKind()), [outlinedArrayBuffer]);
}
}, {
key: "_serializeValueArrayBuffer",
value: function _serializeValueArrayBuffer(val) {
var elems = [];
var len = val.$ArrayBufferByteLength;
var db = val.$ArrayBufferData;
(0, _invariant2.default)(len !== undefined);
(0, _invariant2.default)(db);
var allzero = true;
for (var i = 0; i < len; i++) {
if (db[i] !== 0) {
allzero = false;
}
var elem = t.numericLiteral(db[i]);
elems.push(elem);
}
this._emitObjectProperties(val);
if (allzero) {
// if they're all zero, just emit the array buffer constructor
return t.newExpression(this.preludeGenerator.memoizeReference(val.getKind()), [t.numericLiteral(len)]);
} else {
// initialize from a byte array otherwise
var arrayValue = t.arrayExpression(elems);
var consExpr = t.newExpression(this.preludeGenerator.memoizeReference("Uint8Array"), [arrayValue]);
// access the Uint8Array.buffer property to extract the created buffer
return t.memberExpression(consExpr, t.identifier("buffer"));
}
}
}, {
key: "_serializeValueFunction",
value: function _serializeValueFunction(val) {
var _this11 = this;
if (val instanceof _index2.BoundFunctionValue) {
this._emitObjectProperties(val);
return t.callExpression(t.memberExpression(this.serializeValue(val.$BoundTargetFunction), t.identifier("bind")), [].concat(this.serializeValue(val.$BoundThis), val.$BoundArguments.map(function (boundArg, i) {
return _this11.serializeValue(boundArg);
})));
}
(0, _invariant2.default)(!(val instanceof _index2.NativeFunctionValue), "all native function values should be intrinsics");
(0, _invariant2.default)(val instanceof _index2.ECMAScriptSourceFunctionValue);
var instance = this.residualFunctionInstances.get(val);
(0, _invariant2.default)(instance);
var residualBindings = instance.residualFunctionBindings;
var inAdditionalFunction = this.currentFunctionBody !== this.mainBody;
if (inAdditionalFunction) instance.containingAdditionalFunction = this.currentAdditionalFunction;
var delayed = 1;
var undelay = function undelay() {
if (--delayed === 0) {
(0, _invariant2.default)(instance);
// hoist if we are in an additionalFunction
if (_this11.currentFunctionBody !== _this11.mainBody && (0, _hoisting.canHoistFunction)(_this11.realm, val)) {
instance.insertionPoint = new _types.BodyReference(_this11.mainBody, _this11.mainBody.entries.length);
instance.containingAdditionalFunction = undefined;
} else {
instance.insertionPoint = _this11.emitter.getBodyReference();
}
}
};
var _loop5 = function _loop5(boundName, residualBinding) {
var referencedValues = [];
var serializeBindingFunc = void 0;
if (!residualBinding.declarativeEnvironmentRecord) {
serializeBindingFunc = function serializeBindingFunc() {
return _this11._serializeGlobalBinding(boundName, residualBinding);
};
} else {
serializeBindingFunc = function serializeBindingFunc() {
return _this11._serializeDeclarativeEnvironmentRecordBinding(residualBinding);
};
var bindingValue = residualBinding.value;
(0, _invariant2.default)(bindingValue !== undefined);
referencedValues.push(bindingValue);
if (inAdditionalFunction) {
var _getTarget2 = _this11._getTarget(bindingValue),
_usedOnlyByAdditionalFunctions = _getTarget2.usedOnlyByAdditionalFunctions;
if (_usedOnlyByAdditionalFunctions) residualBinding.referencedOnlyFromAdditionalFunctions = _this11.currentAdditionalFunction;
}
}
delayed++;
_this11.emitter.emitNowOrAfterWaitingForDependencies(referencedValues, function () {
serializeBindingFunc();
undelay();
});
};
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = residualBindings[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var _ref5 = _step6.value;
var _ref6 = _slicedToArray(_ref5, 2);
var boundName = _ref6[0];
var residualBinding = _ref6[1];
_loop5(boundName, residualBinding);
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
undelay();
this._emitObjectProperties(val);
}
// Checks whether a property can be defined via simple assignment, or using object literal syntax.
}, {
key: "_canEmbedProperty",
value: function _canEmbedProperty(obj, key, prop) {
if (prop.joinCondition !== undefined) return false;
if (obj instanceof _index2.FunctionValue && key === "prototype" || obj.getKind() === "RegExp" && key === "lastIndex") return !!prop.writable && !prop.configurable && !prop.enumerable && !prop.set && !prop.get;else if (!!prop.writable && !!prop.configurable && !!prop.enumerable && !prop.set && !prop.get) {
return !(prop.value instanceof _index2.AbstractValue && prop.value.kind === "widened property");
} else {
return false;
}
}
}, {
key: "_findLastObjectPrototype",
value: function _findLastObjectPrototype(obj) {
while (obj.$Prototype instanceof _index2.ObjectValue) {
obj = obj.$Prototype;
}return obj;
}
}, {
key: "_serializeValueRegExpObject",
value: function _serializeValueRegExpObject(val) {
var source = val.$OriginalSource;
var flags = val.$OriginalFlags;
(0, _invariant2.default)(typeof source === "string");
(0, _invariant2.default)(typeof flags === "string");
this._emitObjectProperties(val);
source = new RegExp(source).source; // add escapes as per 21.2.3.2.4
return t.regExpLiteral(source, flags);
}
// Overridable.
}, {
key: "serializeValueRawObject",
value: function serializeValueRawObject(val) {
var remainingProperties = new Map(val.properties);
var dummyProperties = new Set();
var props = [];
var _iteratorNormalCompletion7 = true;
var _didIteratorError7 = false;
var _iteratorError7 = undefined;
try {
for (var _iterator7 = val.properties[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
var _ref7 = _step7.value;
var _ref8 = _slicedToArray(_ref7, 2);
var _key = _ref8[0];
var propertyBinding = _ref8[1];
if (propertyBinding.pathNode !== undefined) continue; // written to inside loop
var descriptor = propertyBinding.descriptor;
if (descriptor === undefined || descriptor.value === undefined) continue; // deleted
if (this._canEmbedProperty(val, _key, descriptor)) {
var propValue = descriptor.value;
(0, _invariant2.default)(propValue instanceof _index2.Value);
if (this.residualHeapInspector.canIgnoreProperty(val, _key)) continue;
var mightHaveBeenDeleted = propValue.mightHaveBeenDeleted();
var serializedKey = this.generator.getAsPropertyNameExpression(_key);
var _delayReason = this.emitter.getReasonToWaitForDependencies(propValue) || this.emitter.getReasonToWaitForActiveValue(val, mightHaveBeenDeleted);
// Although the property needs to be delayed, we still want to emit dummy "undefined"
// value as part of the object literal to ensure a consistent property ordering.
var serializedValue = _internalizer.voidExpression;
if (_delayReason) {
// May need to be cleaned up later.
dummyProperties.add(_key);
} else {
remainingProperties.delete(_key);
serializedValue = this.serializeValue(propValue);
}
props.push(t.objectProperty(serializedKey, serializedValue));
} else if (descriptor.value instanceof _index2.Value && descriptor.value.mightHaveBeenDeleted()) {
dummyProperties.add(_key);
var _serializedKey = this.generator.getAsPropertyNameExpression(_key);
props.push(t.objectProperty(_serializedKey, _internalizer.voidExpression));
}
}
} catch (err) {
_didIteratorError7 = true;
_iteratorError7 = err;
} finally {
try {
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
} finally {
if (_didIteratorError7) {
throw _iteratorError7;
}
}
}
this._emitObjectProperties(val, remainingProperties, /*objectPrototypeAlreadyEstablished*/false, dummyProperties);
return t.objectExpression(props);
}
}, {
key: "_serializeValueObjectViaConstructor",
value: function _serializeValueObjectViaConstructor(val) {
this._emitObjectProperties(val, val.properties, /*objectPrototypeAlreadyEstablished*/true);
this.needsAuxiliaryConstructor = true;
var serializedProto = this.serializeValue(val.$Prototype);
return t.sequenceExpression([t.assignmentExpression("=", t.memberExpression(_internalizer.constructorExpression, t.identifier("prototype")), serializedProto), t.newExpression(_internalizer.constructorExpression, [])]);
}
}, {
key: "serializeValueObject",
value: function serializeValueObject(val) {
var _this12 = this;
// If this object is a prototype object that was implicitly created by the runtime
// for a constructor, then we can obtain a reference to this object
// in a special way that's handled alongside function serialization.
var constructor = val.originalConstructor;
if (constructor !== undefined) {
var prototypeId = this.residualHeapValueIdentifiers.getIdentifier(val);
this.emitter.emitNowOrAfterWaitingForDependencies([constructor], function () {
(0, _invariant2.default)(constructor !== undefined);
(0, _invariant2.default)(prototypeId !== undefined);
_this12.serializeValue(constructor);
_this12._emitObjectProperties(val);
(0, _invariant2.default)(prototypeId.type === "Identifier");
_this12.residualFunctions.setFunctionPrototype(constructor, prototypeId);
});
return prototypeId;
}
var kind = val.getKind();
switch (kind) {
case "RegExp":
return this._serializeValueRegExpObject(val);
case "Number":
var numberData = val.$NumberData;
(0, _invariant2.default)(numberData !== undefined);
numberData.throwIfNotConcreteNumber();
(0, _invariant2.default)(numberData instanceof _index2.NumberValue, "expected number data internal slot to be a number value");
this._emitObjectProperties(val);
return t.newExpression(this.preludeGenerator.memoizeReference("Number"), [t.numericLiteral(numberData.value)]);
case "String":
var stringData = val.$StringData;
(0, _invariant2.default)(stringData !== undefined);
stringData.throwIfNotConcreteString();
(0, _invariant2.default)(stringData instanceof _index2.StringValue, "expected string data internal slot to be a string value");
this._emitObjectProperties(val);
return t.newExpression(this.preludeGenerator.memoizeReference("String"), [t.stringLiteral(stringData.value)]);
case "Boolean":
var booleanData = val.$BooleanData;
(0, _invariant2.default)(booleanData !== undefined);
booleanData.throwIfNotConcreteBoolean();
(0, _invariant2.default)(booleanData instanceof _index2.BooleanValue, "expected boolean data internal slot to be a boolean value");
this._emitObjectProperties(val);
return t.newExpression(this.preludeGenerator.memoizeReference("Boolean"), [t.booleanLiteral(booleanData.value)]);
case "Date":
var dateValue = val.$DateValue;
(0, _invariant2.default)(dateValue !== undefined);
var serializedDateValue = this.serializeValue(dateValue);
this._emitObjectProperties(val);
return t.newExpression(this.preludeGenerator.memoizeReference("Date"), [serializedDateValue]);
case "Float32Array":
case "Float64Array":
case "Int8Array":
case "Int16Array":
case "Int32Array":
case "Uint8Array":
case "Uint16Array":
case "Uint32Array":
case "Uint8ClampedArray":
case "DataView":
return this._serializeValueTypedArrayOrDataView(val);
case "ArrayBuffer":
return this._serializeValueArrayBuffer(val);
case "ReactElement":
this.residualReactElements.serializeReactElement(val);
return;
case "Map":
case "WeakMap":
return this._serializeValueMap(val);
case "Set":
case "WeakSet":
return this._serializeValueSet(val);
default:
(0, _invariant2.default)(kind === "Object", "invariant established by visitor");
(0, _invariant2.default)(this.$ParameterMap === undefined, "invariant established by visitor");
var proto = val.$Prototype;
var createViaAuxiliaryConstructor = proto !== this.realm.intrinsics.ObjectPrototype && this._findLastObjectPrototype(val) === this.realm.intrinsics.ObjectPrototype && proto instanceof _index2.ObjectValue;
return createViaAuxiliaryConstructor ? this._serializeValueObjectViaConstructor(val) : this.serializeValueRawObject(val);
}
}
}, {
key: "_serializeValueSymbol",
value: function _serializeValueSymbol(val) {
var args = [];
if (val.$Description instanceof _index2.Value) {
var serializedArg = this.serializeValue(val.$Description);
(0, _invariant2.default)(serializedArg);
args.push(serializedArg);
}
// check if symbol value exists in the global symbol map, in that case we emit an invocation of System.for
// to look it up
var globalReg = this.realm.globalSymbolRegistry.find(function (e) {
return e.$Symbol === val;
}) !== undefined;
if (globalReg) {
return t.callExpression(this.preludeGenerator.memoizeReference("Symbol.for"), args);
} else {
return t.callExpression(this.preludeGenerator.memoizeReference("Symbol"), args);
}
}
}, {
key: "_serializeValueProxy",
value: function _serializeValueProxy(val) {
return t.newExpression(this.preludeGenerator.memoizeReference("Proxy"), [this.serializeValue(val.$ProxyTarget), this.serializeValue(val.$ProxyHandler)]);
}
}, {
key: "_serializeAbstractValueHelper",
value: function _serializeAbstractValueHelper(val) {
var _this13 = this;
var serializedArgs = val.args.map(function (abstractArg, i) {
return _this13.serializeValue(abstractArg);
});
if (val.kind === "abstractConcreteUnion") {
var abstractIndex = val.args.findIndex(function (v) {
return v instanceof _index2.AbstractValue;
});
(0, _invariant2.default)(abstractIndex >= 0 && abstractIndex < val.args.length);
return serializedArgs[abstractIndex];
}
var serializedValue = val.buildNode(serializedArgs);
if (serializedValue.type === "Identifier") {
var id = serializedValue;
(0, _invariant2.default)(!this.preludeGenerator.derivedIds.has(id.name) || this.emitter.hasBeenDeclared(val));
}
return serializedValue;
}
}, {
key: "_serializeAbstractValue",
value: function _serializeAbstractValue(val) {
var _this14 = this;
(0, _invariant2.default)(val.kind !== "sentinel member expression", "invariant established by visitor");
if (val.hasIdentifier()) {
return this._serializeAbstractValueHelper(val);
} else {
// This abstract value's dependencies should all be declared
// but still need to check them again in case their serialized bodies are in different generator scope.
this.emitter.emitNowOrAfterWaitingForDependencies(val.args, function () {
var serializedValue = _this14._serializeAbstractValueHelper(val);
var uid = _this14.getSerializeObjectIdentifier(val);
var declar = t.variableDeclaration("var", [t.variableDeclarator(uid, serializedValue)]);
_this14.emitter.emit(declar);
});
}
}
}, {
key: "_serializeValue",
value: function _serializeValue(val) {
if (val instanceof _index2.AbstractValue) {
return this._serializeAbstractValue(val);
} else if (val.isIntrinsic()) {
return this._serializeValueIntrinsic(val);
} else if (val instanceof _index2.EmptyValue) {
this.needsEmptyVar = true;
return _internalizer.emptyExpression;
} else if (val instanceof _index2.UndefinedValue) {
return _internalizer.voidExpression;
} else if (_ResidualHeapInspector.ResidualHeapInspector.isLeaf(val)) {
return t.valueToNode(val.serialize());
} else if ((0, _index.IsArray)(this.realm, val)) {
(0, _invariant2.default)(val instanceof _index2.ObjectValue);
return this._serializeValueArray(val);
} else if (val instanceof _index2.ProxyValue) {
return this._serializeValueProxy(val);
} else if (val instanceof _index2.FunctionValue) {
return this._serializeValueFunction(val);
} else if (val instanceof _index2.SymbolValue) {
return this._serializeValueSymbol(val);
} else {
(0, _invariant2.default)(val instanceof _index2.ObjectValue);
return this.serializeValueObject(val);
}
}
}, {
key: "_serializeGlobalBinding",
value: function _serializeGlobalBinding(boundName, residualFunctionBinding) {
(0, _invariant2.default)(!residualFunctionBinding.declarativeEnvironmentRecord);
if (!residualFunctionBinding.serializedValue) {
residualFunctionBinding.referentialized = true;
if (boundName === "undefined") {
residualFunctionBinding.serializedValue = _internalizer.voidExpression;
} else {
var _value = this.realm.getGlobalLetBinding(boundName);
// Check for let binding vs global property
if (_value) {
var rval = residualFunctionBinding.value;
(0, _invariant2.default)(rval !== undefined && _value.equals(rval));
var id = this.serializeValue(rval, true, "let");
// increment ref count one more time as the value has been
// referentialized (stored in a variable) by serializeValue
this.residualHeapValueIdentifiers.incrementReferenceCount(rval);
residualFunctionBinding.serializedValue = id;
} else {
residualFunctionBinding.serializedValue = this.preludeGenerator.globalReference(boundName);
}
}
}
}
}, {
key: "_withGeneratorScope",
value: function _withGeneratorScope(generator, callback) {
var newBody = { type: "Generator", parentBody: undefined, entries: [] };
var oldBody = this.emitter.beginEmitting(generator, newBody, /*isChild*/true);
this.activeGeneratorBodies.set(generator, newBody);
callback(newBody);
this.activeGeneratorBodies.delete(generator);
var statements = this.emitter.endEmitting(generator, oldBody).entries;
if (this._options.debugScopes) {
var comment = "generator \"" + generator.getName() + "\"";
if (generator.parent !== undefined) {
comment = comment + " with parent \"" + generator.parent.getName() + "\"";
}
statements.unshift(commentStatement("begin " + comment));
statements.push(commentStatement("end " + comment));
}
return statements;
}
}, {
key: "_getContext",
value: function _getContext() {
var _this15 = this;
// TODO #482: Values serialized by nested generators would currently only get defined
// along the code of the nested generator; their definitions need to get hoisted
// or repeated so that they are accessible and defined from all using scopes
var context = {
serializeValue: this.serializeValue.bind(this),
serializeBinding: this.serializeBinding.bind(this),
serializeGenerator: function serializeGenerator(generator) {
return _this15._withGeneratorScope(generator, function () {
return generator.serialize(context);
});
},
emit: function emit(statement) {
_this15.emitter.emit(statement);
},
emitDefinePropertyBody: this.emitDefinePropertyBody.bind(this, false, undefined),
canOmit: function canOmit(value) {
return !_this15.referencedDeclaredValues.has(value);
},
declare: function declare(value) {
_this15.emitter.declare(value);
}
};
return context;
}
}, {
key: "_serializeAdditionalFunction",
value: function _serializeAdditionalFunction(generator, postGeneratorCallback) {
var _this16 = this;
var context = this._getContext();
return this._withGeneratorScope(generator, function (newBody) {
var oldCurBody = _this16.currentFunctionBody;
_this16.currentFunctionBody = newBody;
generator.serialize(context);
if (postGeneratorCallback) postGeneratorCallback();
_this16.currentFunctionBody = oldCurBody;
});
}
}, {
key: "_shouldBeWrapped",
value: function _shouldBeWrapped(body) {
for (var i = 0; i < body.length; i++) {
var item = body[i];
if (item.type === "ExpressionStatement") {
continue;
} else if (item.type === "VariableDeclaration" || item.type === "FunctionDeclaration") {
return true;
} else if (item.type === "BlockStatement") {
if (this._shouldBeWrapped(item.body)) {
return true;
}
} else if (item.type === "IfStatement") {
if (item.alternate) {
if (this._shouldBeWrapped(item.alternate.body)) {
return true;
}
}
if (item.consequent) {
if (this._shouldBeWrapped(item.consequent.body)) {
return true;
}
}
}
}
return false;
}
}, {
key: "processAdditionalFunctionValues",
value: function processAdditionalFunctionValues() {
var _this17 = this;
var rewrittenAdditionalFunctions = new Map();
var shouldEmitLog = !this.residualHeapValueIdentifiers.collectValToRefCountOnly;
var processAdditionalFunctionValuesFn = function processAdditionalFunctionValuesFn() {
var additionalFVEffects = _this17.additionalFunctionValuesAndEffects;
if (additionalFVEffects) {
var _loop6 = function _loop6(additionalFunctionValue, effects, transforms) {
var _effects = _slicedToArray(effects, 5),
result = _effects[0],
generator = _effects[1],
modifiedBindings = _effects[2],
modifiedProperties = _effects[3],
createdObjects = _effects[4];
var nestedFunctions = new Set([].concat(_toConsumableArray(createdObjects)).filter(function (object) {
return object instanceof _index2.FunctionValue;
}));
// result -- ignore TODO: return the result from the function somehow
// Generator -- visit all entries
// Bindings -- only need to serialize bindings if they're captured by some nested function?
// -- need to apply them and maybe need to revisit functions in ancestors to make sure
// -- we don't overwrite anything they capture
// -- TODO: deal with these properly
// PropertyBindings -- visit any property bindings that aren't to createdobjects
// CreatedObjects -- should take care of itself
_this17.realm.applyEffects([result, new _generator.Generator(_this17.realm), modifiedBindings, modifiedProperties, createdObjects]);
// Allows us to emit function declarations etc. inside of this additional
// function instead of adding them at global scope
// TODO: make sure this generator isn't getting mutated oddly
nestedFunctions.forEach(function (val) {
return _this17.additionalFunctionValueNestedFunctions.add(val);
});
var serializePropertiesAndBindings = function serializePropertiesAndBindings() {
var _iteratorNormalCompletion9 = true;
var _didIteratorError9 = false;
var _iteratorError9 = undefined;
try {
for (var _iterator9 = modifiedProperties.keys()[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
var propertyBinding = _step9.value;
var binding = propertyBinding;
var object = binding.object;
if (object instanceof _index2.ObjectValue && createdObjects.has(object)) continue;
if (object.refuseSerialization) continue;
if (object.isIntrinsic()) continue;
(0, _invariant2.default)(object instanceof _index2.ObjectValue);
_this17._emitProperty(object, binding.key, binding.descriptor, true);
}
} catch (err) {
_didIteratorError9 = true;
_iteratorError9 = err;
} finally {
try {
if (!_iteratorNormalCompletion9 && _iterator9.return) {
_iterator9.return();
}
} finally {
if (_didIteratorError9) {
throw _iteratorError9;
}
}
}
(0, _invariant2.default)(result instanceof _index2.Value);
// Handle ModifiedBindings
var additionalFunctionValueInfo = _this17.additionalFunctionValueInfos.get(additionalFunctionValue);
(0, _invariant2.default)(additionalFunctionValueInfo);
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
try {
for (var _iterator10 = additionalFunctionValueInfo.modifiedBindings[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var _ref11 = _step10.value;
var _ref12 = _slicedToArray(_ref11, 2);
var modifiedBinding = _ref12[0];
var residualBinding = _ref12[1];
var newVal = modifiedBinding.value;
(0, _invariant2.default)(newVal);
residualBinding.additionalValueSerialized = _this17.serializeValue(newVal);
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return) {
_iterator10.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
}
}
}
if (!(result instanceof _index2.UndefinedValue)) _this17.emitter.emit(t.returnStatement(_this17.serializeValue(result)));
var lazyHoistedReactNodes = _this17.residualReactElements.serializeLazyHoistedNodes();
Array.prototype.push.apply(_this17.mainBody.entries, lazyHoistedReactNodes);
};
_this17.currentAdditionalFunction = additionalFunctionValue;
var body = _this17._serializeAdditionalFunction(generator, serializePropertiesAndBindings);
(0, _invariant2.default)(additionalFunctionValue instanceof _index2.ECMAScriptSourceFunctionValue);
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;
try {
for (var _iterator11 = transforms[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var transform = _step11.value;
transform(body);
}
} catch (err) {
_didIteratorError11 = true;
_iteratorError11 = err;
} finally {
try {
if (!_iteratorNormalCompletion11 && _iterator11.return) {
_iterator11.return();
}
} finally {
if (_didIteratorError11) {
throw _iteratorError11;
}
}
}
rewrittenAdditionalFunctions.set(additionalFunctionValue, body);
// re-resolve initialized modules to include things from additional functions
_this17.modules.resolveInitializedModules();
if (shouldEmitLog && _this17.modules.moduleIds.size > 0) console.log("=== " + _this17.modules.initializedModules.size + " of " + _this17.modules.moduleIds.size + " modules initialized after additional function " + (additionalFunctionValue.intrinsicName ? additionalFunctionValue.intrinsicName : ""));
// These don't restore themselves properly otherwise.
_this17.realm.restoreBindings(modifiedBindings);
_this17.realm.restoreProperties(modifiedProperties);
};
var _iteratorNormalCompletion8 = true;
var _didIteratorError8 = false;
var _iteratorError8 = undefined;
try {
for (var _iterator8 = additionalFVEffects.entries()[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
var _ref9 = _step8.value;
var _ref10 = _slicedToArray(_ref9, 2);
var additionalFunctionValue = _ref10[0];
var _ref10$ = _ref10[1];
var effects = _ref10$.effects;
var transforms = _ref10$.transforms;
_loop6(additionalFunctionValue, effects, transforms);
}
} catch (err) {
_didIteratorError8 = true;
_iteratorError8 = err;
} finally {
try {
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
} finally {
if (_didIteratorError8) {
throw _iteratorError8;
}
}
}
}
return _this17.realm.intrinsics.undefined;
};
this.realm.evaluateAndRevertInGlobalEnv(processAdditionalFunctionValuesFn);
return rewrittenAdditionalFunctions;
}
// Hook point for any serialization needs to be done after generator serialization is complete.
}, {
key: "postGeneratorSerialization",
value: function postGeneratorSerialization() {
// For overriding only.
}
}, {
key: "serialize",
value: function serialize() {
this.generator.serialize(this._getContext());
(0, _invariant2.default)(this.emitter._declaredAbstractValues.size <= this.preludeGenerator.derivedIds.size);
this.postGeneratorSerialization();
Array.prototype.push.apply(this.prelude, this.preludeGenerator.prelude);
// TODO #20: add timers
// TODO #21: add event listeners
var _iteratorNormalCompletion12 = true;
var _didIteratorError12 = false;
var _iteratorError12 = undefined;
try {
for (var _iterator12 = this.modules.initializedModules[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
var _ref13 = _step12.value;
var _ref14 = _slicedToArray(_ref13, 2);
var moduleId = _ref14[0];
var moduleValue = _ref14[1];
this.requireReturns.set(moduleId, this.serializeValue(moduleValue));
} // Make sure additional functions get serialized.
} catch (err) {
_didIteratorError12 = true;
_iteratorError12 = err;
} finally {
try {
if (!_iteratorNormalCompletion12 && _iterator12.return) {
_iterator12.return();
}
} finally {
if (_didIteratorError12) {
throw _iteratorError12;
}
}
}
var rewrittenAdditionalFunctions = this.processAdditionalFunctionValues();
this.modules.resolveInitializedModules();
this.emitter.finalize();
this.residualFunctions.residualFunctionInitializers.factorifyInitializers(this.factoryNameGenerator);
var _residualFunctions$sp = this.residualFunctions.spliceFunctions(rewrittenAdditionalFunctions),
unstrictFunctionBodies = _residualFunctions$sp.unstrictFunctionBodies,
strictFunctionBodies = _residualFunctions$sp.strictFunctionBodies,
requireStatistics = _residualFunctions$sp.requireStatistics;
if (this.modules.moduleIds.size > 0 && !this.residualHeapValueIdentifiers.collectValToRefCountOnly) {
console.log("=== " + this.modules.initializedModules.size + " of " + this.modules.moduleIds.size + " modules initialized, " + requireStatistics.replaced + " of " + requireStatistics.count + " require calls inlined.");
}
// add strict modes
var strictDirective = t.directive(t.directiveLiteral("use strict"));
var globalDirectives = [];
if (!this.realm.isStrict && !unstrictFunctionBodies.length && strictFunctionBodies.length) {
// no unstrict functions, only strict ones
globalDirectives.push(strictDirective);
} else if (unstrictFunctionBodies.length && strictFunctionBodies.length) {
// strict and unstrict functions
var _iteratorNormalCompletion13 = true;
var _didIteratorError13 = false;
var _iteratorError13 = undefined;
try {
funcLoop: for (var _iterator13 = strictFunctionBodies[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
var func = _step13.value;
if (func.body.directives) {
var _iteratorNormalCompletion14 = true;
var _didIteratorError14 = false;
var _iteratorError14 = undefined;
try {
for (var _iterator14 = func.body.directives[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
var directive = _step14.value;
if (directive.value.value === "use strict") {
// already have a use strict directive
continue funcLoop;
}
}
} catch (err) {
_didIteratorError14 = true;
_iteratorError14 = err;
} finally {
try {
if (!_iteratorNormalCompletion14 && _iterator14.return) {
_iterator14.return();
}
} finally {
if (_didIteratorError14) {
throw _iteratorError14;
}
}
}
} else func.body.directives = [];
func.body.directives.unshift(strictDirective);
}
} catch (err) {
_didIteratorError13 = true;
_iteratorError13 = err;
} finally {
try {
if (!_iteratorNormalCompletion13 && _iterator13.return) {
_iterator13.return();
}
} finally {
if (_didIteratorError13) {
throw _iteratorError13;
}
}
}
}
// build ast
if (this.needsEmptyVar) {
this.prelude.push(t.variableDeclaration("var", [t.variableDeclarator(_internalizer.emptyExpression, t.objectExpression([]))]));
}
if (this.needsAuxiliaryConstructor) {
this.prelude.push(t.variableDeclaration("var", [t.variableDeclarator(_internalizer.constructorExpression, t.functionExpression(null, [], t.blockStatement([])))]));
}
var body = this.prelude.concat(this.emitter.getBody().entries);
(0, _factorify.factorifyObjects)(body, this.factoryNameGenerator);
var ast_body = [];
if (this.preludeGenerator.declaredGlobals.size > 0) ast_body.push(t.variableDeclaration("var", Array.from(this.preludeGenerator.declaredGlobals).map(function (key) {
return t.variableDeclarator(t.identifier(key));
})));
if (body.length) {
if (this.realm.isCompatibleWith("node-source-maps")) {
ast_body.push(t.expressionStatement(t.callExpression(t.memberExpression(t.callExpression(t.identifier("require"), [t.stringLiteral("source-map-support")]), t.identifier("install")), [])));
}
if (this._shouldBeWrapped(body)) {
var globalExpression = this.realm.isCompatibleWith("node-cli") ? t.identifier("global") : t.thisExpression();
var functionExpression = t.functionExpression(null, [], t.blockStatement(body, globalDirectives));
var callExpression = this.preludeGenerator.usesThis ? t.callExpression(t.memberExpression(functionExpression, t.identifier("call")), [globalExpression]) : t.callExpression(functionExpression, []);
ast_body.push(t.expressionStatement(callExpression));
} else {
ast_body = body;
}
}
// Make sure that the visitor visited as many values as the serializer
(0, _invariant2.default)(this.serializedValues.size === this.residualValues.size, "serialized " + this.serializedValues.size + " of " + this.residualValues.size);
// TODO: find better way to do this?
// revert changes to functionInstances in case we do multiple serialization passes
var _iteratorNormalCompletion15 = true;
var _didIteratorError15 = false;
var _iteratorError15 = undefined;
try {
for (var _iterator15 = this.residualFunctionInstances.values()[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
var instance = _step15.value;
var _iteratorNormalCompletion16 = true;
var _didIteratorError16 = false;
var _iteratorError16 = undefined;
try {
for (var _iterator16 = instance.residualFunctionBindings.values()[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {
var binding = _step16.value;
var b = binding;
delete b.serializedValue;
delete b.referentialized;
}
} catch (err) {
_didIteratorError16 = true;
_iteratorError16 = err;
} finally {
try {
if (!_iteratorNormalCompletion16 && _iterator16.return) {
_iterator16.return();
}
} finally {
if (_didIteratorError16) {
throw _iteratorError16;
}
}
}
}
} catch (err) {
_didIteratorError15 = true;
_iteratorError15 = err;
} finally {
try {
if (!_iteratorNormalCompletion15 && _iterator15.return) {
_iterator15.return();
}
} finally {
if (_didIteratorError15) {
throw _iteratorError15;
}
}
}
var program_directives = [];
if (this.realm.isStrict) program_directives.push(strictDirective);
return t.file(t.program(ast_body, program_directives));
}
}]);
return ResidualHeapSerializer;
}();
//# sourceMappingURL=ResidualHeapSerializer.js.map