"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JoinImplementation = 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 _errors = require("../errors.js"); var _completions = require("../completions.js"); var _environment = require("../environment.js"); var _index = require("../methods/index.js"); var _realm = require("../realm.js"); var _generator = require("../utils/generator.js"); var _index2 = require("../values/index.js"); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); 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 joinGenerators(realm, joinCondition, generator1, generator2) { var result = new _generator.Generator(realm); if (!generator1.empty() || !generator2.empty()) { result.joinGenerators(joinCondition, generator1, generator2); } return result; } function joinArrays(realm, v1, v2, getAbstractValue) { var e = v1 && v1[0] || v2 && v2[0]; if (e instanceof _index2.Value) return joinArraysOfValues(realm, v1, v2, getAbstractValue);else return joinArrayOfsMapEntries(realm, v1, v2, getAbstractValue); } function joinArrayOfsMapEntries(realm, a1, a2, getAbstractValue) { var empty = realm.intrinsics.empty; var n = Math.max(a1 && a1.length || 0, a2 && a2.length || 0); var result = []; for (var i = 0; i < n; i++) { var _ref = a1 && a1[i] || { $Key: empty, $Value: empty }, key1 = _ref.$Key, val1 = _ref.$Value; var _ref2 = a2 && a2[i] || { $Key: empty, $Value: empty }, key2 = _ref2.$Key, val2 = _ref2.$Value; if (key1 === undefined && key2 === undefined) { result[i] = { $Key: undefined, $Value: undefined }; } else { var key3 = getAbstractValue(key1, key2); var val3 = getAbstractValue(val1, val2); result[i] = { $Key: key3, $Value: val3 }; } } return result; } function joinArraysOfValues(realm, a1, a2, getAbstractValue) { var n = Math.max(a1 && a1.length || 0, a2 && a2.length || 0); var result = []; for (var i = 0; i < n; i++) { result[i] = getAbstractValue(a1 && a1[i] || undefined, a2 && a2[i] || undefined); } return result; } var JoinImplementation = exports.JoinImplementation = function () { function JoinImplementation() { _classCallCheck(this, JoinImplementation); } _createClass(JoinImplementation, [{ key: "stopEffectCaptureJoinApplyAndReturnCompletion", value: function stopEffectCaptureJoinApplyAndReturnCompletion(c1, c2, realm) { var e = realm.getCapturedEffects(c1); (0, _invariant2.default)(e !== undefined); realm.stopEffectCaptureAndUndoEffects(c1); var joined_effects = this.joinPossiblyNormalCompletionWithAbruptCompletion(realm, c1, c2, e); realm.applyEffects(joined_effects); var result = joined_effects[0]; (0, _invariant2.default)(result instanceof _completions.AbruptCompletion); return result; } }, { key: "unbundleNormalCompletion", value: function unbundleNormalCompletion(completionOrValue) { var completion = void 0, value = void 0; if (completionOrValue instanceof _completions.PossiblyNormalCompletion) { completion = completionOrValue; value = completionOrValue.value; } else { (0, _invariant2.default)(completionOrValue instanceof _index2.Value || completionOrValue instanceof _environment.Reference); value = completionOrValue; } return [completion, value]; } }, { key: "composeNormalCompletions", value: function composeNormalCompletions(leftCompletion, rightCompletion, resultValue, realm) { if (leftCompletion instanceof _completions.PossiblyNormalCompletion) { if (rightCompletion instanceof _completions.PossiblyNormalCompletion) { this.updatePossiblyNormalCompletionWithValue(realm, rightCompletion, resultValue); return this.composePossiblyNormalCompletions(realm, leftCompletion, rightCompletion); } this.updatePossiblyNormalCompletionWithValue(realm, leftCompletion, resultValue); return leftCompletion; } else if (rightCompletion instanceof _completions.PossiblyNormalCompletion) { this.updatePossiblyNormalCompletionWithValue(realm, rightCompletion, resultValue); return rightCompletion; } else { (0, _invariant2.default)(leftCompletion === undefined && rightCompletion === undefined); return resultValue; } } }, { key: "composePossiblyNormalCompletions", value: function composePossiblyNormalCompletions(realm, pnc, c) { //merge the two pathConditions var composedPath = []; composedPath = pnc.pathConditions.concat(c.pathConditions); var savedPathConditions = pnc.savedPathConditions; if (pnc.consequent instanceof _completions.AbruptCompletion) { if (pnc.alternate instanceof _index2.Value) { var _pnc$alternateEffects = _slicedToArray(pnc.alternateEffects, 5), _g = _pnc$alternateEffects[1], _b = _pnc$alternateEffects[2], _p = _pnc$alternateEffects[3], _o = _pnc$alternateEffects[4]; var _newAlternateEffects = [c, _g, _b, _p, _o]; return new _completions.PossiblyNormalCompletion(c.value, pnc.joinCondition, pnc.consequent, pnc.consequentEffects, c, _newAlternateEffects, composedPath, savedPathConditions, pnc.savedEffects); } (0, _invariant2.default)(pnc.alternate instanceof _completions.PossiblyNormalCompletion); var new_alternate = this.composePossiblyNormalCompletions(realm, pnc.alternate, c); var _pnc$alternateEffects2 = _slicedToArray(pnc.alternateEffects, 5), g = _pnc$alternateEffects2[1], b = _pnc$alternateEffects2[2], p = _pnc$alternateEffects2[3], o = _pnc$alternateEffects2[4]; var newAlternateEffects = [new_alternate, g, b, p, o]; return new _completions.PossiblyNormalCompletion(new_alternate.value, pnc.joinCondition, pnc.consequent, pnc.consequentEffects, new_alternate, newAlternateEffects, composedPath, savedPathConditions, pnc.savedEffects); } else { (0, _invariant2.default)(pnc.alternate instanceof _completions.AbruptCompletion); if (pnc.consequent instanceof _index2.Value) { var _pnc$consequentEffect = _slicedToArray(pnc.consequentEffects, 5), _g3 = _pnc$consequentEffect[1], _b3 = _pnc$consequentEffect[2], _p3 = _pnc$consequentEffect[3], _o3 = _pnc$consequentEffect[4]; var _newConsequentEffects = [c, _g3, _b3, _p3, _o3]; return new _completions.PossiblyNormalCompletion(c.value, pnc.joinCondition, c, _newConsequentEffects, pnc.alternate, pnc.alternateEffects, composedPath, savedPathConditions, pnc.savedEffects); } (0, _invariant2.default)(pnc.consequent instanceof _completions.PossiblyNormalCompletion); var new_consequent = this.composePossiblyNormalCompletions(realm, pnc.consequent, c); var _pnc$consequentEffect2 = _slicedToArray(pnc.consequentEffects, 5), _g2 = _pnc$consequentEffect2[1], _b2 = _pnc$consequentEffect2[2], _p2 = _pnc$consequentEffect2[3], _o2 = _pnc$consequentEffect2[4]; var newConsequentEffects = [new_consequent, _g2, _b2, _p2, _o2]; return new _completions.PossiblyNormalCompletion(new_consequent.value, pnc.joinCondition, new_consequent, newConsequentEffects, pnc.alternate, pnc.alternateEffects, composedPath, savedPathConditions, pnc.savedEffects); } } }, { key: "updatePossiblyNormalCompletionWithSubsequentEffects", value: function updatePossiblyNormalCompletionWithSubsequentEffects(realm, pnc, subsequentEffects) { var v = subsequentEffects[0]; (0, _invariant2.default)(v instanceof _index2.Value); pnc.value = v; if (pnc.consequent instanceof _completions.AbruptCompletion) { if (pnc.alternate instanceof _index2.Value) { pnc.alternate = v; pnc.alternateEffects = realm.composeEffects(pnc.alternateEffects, subsequentEffects); } else { (0, _invariant2.default)(pnc.alternate instanceof _completions.PossiblyNormalCompletion); this.updatePossiblyNormalCompletionWithSubsequentEffects(realm, pnc.alternate, subsequentEffects); } } else { if (pnc.consequent instanceof _index2.Value) { pnc.consequent = v; pnc.consequentEffects = realm.composeEffects(pnc.consequentEffects, subsequentEffects); } else { (0, _invariant2.default)(pnc.consequent instanceof _completions.PossiblyNormalCompletion); this.updatePossiblyNormalCompletionWithSubsequentEffects(realm, pnc.consequent, subsequentEffects); } } } }, { key: "updatePossiblyNormalCompletionWithValue", value: function updatePossiblyNormalCompletionWithValue(realm, pnc, v) { pnc.value = v; if (pnc.consequent instanceof _completions.AbruptCompletion) { if (pnc.alternate instanceof _index2.Value) { pnc.alternate = v; pnc.alternateEffects[0] = v; } else { (0, _invariant2.default)(pnc.alternate instanceof _completions.PossiblyNormalCompletion); this.updatePossiblyNormalCompletionWithValue(realm, pnc.alternate, v); } } else { if (pnc.consequent instanceof _index2.Value) { pnc.consequent = v; pnc.consequentEffects[0] = v; } else { (0, _invariant2.default)(pnc.consequent instanceof _completions.PossiblyNormalCompletion); this.updatePossiblyNormalCompletionWithValue(realm, pnc.consequent, v); } } } // Returns the joined effects of all of the paths in pnc. // The normal path in pnc is modified to become terminated by ac, // so the overall completion will always be an instance of JoinedAbruptCompletions }, { key: "joinPossiblyNormalCompletionWithAbruptCompletion", value: function joinPossiblyNormalCompletionWithAbruptCompletion(realm, // a forked path with a non abrupt (normal) component pnc, // an abrupt completion that completes the normal path ac, // effects collected after pnc was constructed e) { // set up e with ac as the completion. It's OK to do this repeatedly since ac is not changed by recursive calls. e[0] = ac; if (pnc.consequent instanceof _completions.AbruptCompletion) { if (pnc.alternate instanceof _index2.Value) { return this.joinEffects(realm, pnc.joinCondition, pnc.consequentEffects, realm.composeEffects(pnc.alternateEffects, e)); } (0, _invariant2.default)(pnc.alternate instanceof _completions.PossiblyNormalCompletion); var alternate_effects = this.joinPossiblyNormalCompletionWithAbruptCompletion(realm, pnc.alternate, ac, e); (0, _invariant2.default)(pnc.consequent instanceof _completions.AbruptCompletion); return this.joinEffects(realm, pnc.joinCondition, pnc.consequentEffects, alternate_effects); } else { (0, _invariant2.default)(pnc.alternate instanceof _completions.AbruptCompletion); if (pnc.consequent instanceof _index2.Value) { return this.joinEffects(realm, pnc.joinCondition, realm.composeEffects(pnc.consequentEffects, e), pnc.alternateEffects); } (0, _invariant2.default)(pnc.consequent instanceof _completions.PossiblyNormalCompletion); var consequent_effects = this.joinPossiblyNormalCompletionWithAbruptCompletion(realm, pnc.consequent, ac, e); (0, _invariant2.default)(pnc.alternate instanceof _completions.AbruptCompletion); return this.joinEffects(realm, pnc.joinCondition, consequent_effects, pnc.alternateEffects); } } }, { key: "joinPossiblyNormalCompletionWithValue", value: function joinPossiblyNormalCompletionWithValue(realm, joinCondition, pnc, v) { if (pnc.consequent instanceof _completions.AbruptCompletion) { if (pnc.alternate instanceof _index2.Value) { pnc.alternate = this.joinValuesAsConditional(realm, joinCondition, pnc.alternate, v); } else { (0, _invariant2.default)(pnc.alternate instanceof _completions.PossiblyNormalCompletion); this.joinPossiblyNormalCompletionWithValue(realm, joinCondition, pnc.alternate, v); } } else { if (pnc.consequent instanceof _index2.Value) { pnc.consequent = this.joinValuesAsConditional(realm, joinCondition, pnc.consequent, v); } else { (0, _invariant2.default)(pnc.consequent instanceof _completions.PossiblyNormalCompletion); this.joinPossiblyNormalCompletionWithValue(realm, joinCondition, pnc.consequent, v); } } } }, { key: "joinValueWithPossiblyNormalCompletion", value: function joinValueWithPossiblyNormalCompletion(realm, joinCondition, pnc, v) { if (pnc.consequent instanceof _completions.AbruptCompletion) { if (pnc.alternate instanceof _index2.Value) { pnc.alternate = this.joinValuesAsConditional(realm, joinCondition, v, pnc.alternate); } else { (0, _invariant2.default)(pnc.alternate instanceof _completions.PossiblyNormalCompletion); this.joinValueWithPossiblyNormalCompletion(realm, joinCondition, pnc.alternate, v); } } else { if (pnc.consequent instanceof _index2.Value) { pnc.consequent = this.joinValuesAsConditional(realm, joinCondition, v, pnc.consequent); } else { (0, _invariant2.default)(pnc.consequent instanceof _completions.PossiblyNormalCompletion); this.joinValueWithPossiblyNormalCompletion(realm, joinCondition, pnc.consequent, v); } } } }, { key: "joinAndRemoveNestedReturnCompletions", value: function joinAndRemoveNestedReturnCompletions(realm, c) { if (c instanceof _completions.ReturnCompletion) { return c.value; } if (c instanceof _completions.JoinedAbruptCompletions) { var c1 = this.joinAndRemoveNestedReturnCompletions(realm, c.consequent); var c2 = this.joinAndRemoveNestedReturnCompletions(realm, c.alternate); c.consequentEffects[0] = c1; c.alternateEffects[0] = c2; return this.joinResults(realm, c.joinCondition, c1, c2, c.consequentEffects, c.alternateEffects); } return c; } }, { key: "joinEffectsAndPromoteNestedReturnCompletions", value: function joinEffectsAndPromoteNestedReturnCompletions(realm, c, e, nested_effects) { if (c instanceof _index2.Value) { // If not undefined, the nested effects were captured when evaluating a conditional code block that ended normally. // e represent effects that were captured since reaching the join point where the normal and abrupt // completions came together into the completion supplied to the outermost call to this recursive function. if (nested_effects !== undefined) e = realm.composeEffects(nested_effects, e); return e; } if (c instanceof _completions.AbruptCompletion && !(c instanceof _completions.JoinedAbruptCompletions)) { // The nested effects were captured when evaluating a conditional code block that ended abruptly. // An abrupt completion does not care about the effects that were collected since the join point. (0, _invariant2.default)(nested_effects !== undefined); return nested_effects; } if (c instanceof _completions.PossiblyNormalCompletion) { var _e = this.joinEffectsAndPromoteNestedReturnCompletions(realm, c.consequent, e, c.consequentEffects); var _e2 = this.joinEffectsAndPromoteNestedReturnCompletions(realm, c.alternate, e, c.alternateEffects); if (_e[0] instanceof _completions.AbruptCompletion) { if (_e2[0] instanceof _index2.Value) _e2[0] = new _completions.ReturnCompletion(realm.intrinsics.undefined, realm.currentLocation); return this.joinEffects(realm, c.joinCondition, _e, _e2); } else if (_e2[0] instanceof _completions.AbruptCompletion) { if (_e[0] instanceof _index2.Value) _e[0] = new _completions.ReturnCompletion(realm.intrinsics.undefined, realm.currentLocation); return this.joinEffects(realm, c.joinCondition, _e, _e2); } } (0, _invariant2.default)(c instanceof _completions.JoinedAbruptCompletions); // e will be ignored in the calls below since the branches are all abrupt. var e1 = this.joinEffectsAndPromoteNestedReturnCompletions(realm, c.consequent, e, c.consequentEffects); var e2 = this.joinEffectsAndPromoteNestedReturnCompletions(realm, c.alternate, e, c.alternateEffects); var _ref3 = [e1[0], e2[0]], r1 = _ref3[0], r2 = _ref3[1]; if (r1 instanceof _completions.ReturnCompletion) { (0, _invariant2.default)(!(r2 instanceof _completions.ReturnCompletion)); // Otherwise their values should have been joined if (r2 instanceof _completions.JoinedAbruptCompletions) { if (r2.consequent instanceof _completions.ReturnCompletion) { var r1jr2c = this.joinEffects(realm, c.joinCondition, e1, r2.consequentEffects); (0, _invariant2.default)(r1jr2c[0] instanceof _completions.ReturnCompletion); var or = _index2.AbstractValue.createFromLogicalOp(realm, "||", c.joinCondition, r2.joinCondition); (0, _invariant2.default)(or instanceof _index2.AbstractValue); return this.joinEffects(realm, or, r1jr2c, r2.alternateEffects); } if (r2.alternate instanceof _completions.ReturnCompletion) { var r1jr2a = this.joinEffects(realm, c.joinCondition, e1, r2.alternateEffects); (0, _invariant2.default)(r1jr2a[0] instanceof _completions.ReturnCompletion); var notR2jc = _index2.AbstractValue.createFromUnaryOp(realm, "!", r2.joinCondition); var _or = _index2.AbstractValue.createFromLogicalOp(realm, "||", c.joinCondition, notR2jc); (0, _invariant2.default)(_or instanceof _index2.AbstractValue); return this.joinEffects(realm, _or, r1jr2a, r2.consequentEffects); } } } else if (r2 instanceof _completions.ReturnCompletion) { (0, _invariant2.default)(!(r1 instanceof _completions.ReturnCompletion)); // Otherwise their values should have been joined if (r1 instanceof _completions.JoinedAbruptCompletions) { if (r1.consequent instanceof _completions.ReturnCompletion) { var r2jr1c = this.joinEffects(realm, c.joinCondition, r1.consequentEffects, e2); (0, _invariant2.default)(r2jr1c[0] instanceof _completions.ReturnCompletion); var _or2 = _index2.AbstractValue.createFromLogicalOp(realm, "||", c.joinCondition, r1.joinCondition); (0, _invariant2.default)(_or2 instanceof _index2.AbstractValue); return this.joinEffects(realm, _or2, r2jr1c, r1.alternateEffects); } if (r1.alternate instanceof _completions.ReturnCompletion) { var r2jr1a = this.joinEffects(realm, c.joinCondition, r1.alternateEffects, e2); var notR1jc = _index2.AbstractValue.createFromUnaryOp(realm, "!", r1.joinCondition); (0, _invariant2.default)(r2jr1a[0] instanceof _completions.ReturnCompletion); var _or3 = _index2.AbstractValue.createFromLogicalOp(realm, "||", c.joinCondition, notR1jc); (0, _invariant2.default)(_or3 instanceof _index2.AbstractValue); return this.joinEffects(realm, _or3, r2jr1a, r1.consequentEffects); } } } return this.joinEffects(realm, c.joinCondition, e1, e2); } }, { key: "unbundleReturnCompletion", value: function unbundleReturnCompletion(realm, c) { var empty_effects = (0, _realm.construct_empty_effects)(realm); var v = realm.intrinsics.empty; if (c.consequent instanceof _completions.ReturnCompletion) { var negation = _index2.AbstractValue.createFromUnaryOp(realm, "!", c.joinCondition); // Simply negating the (known to be abstract) join condition should // not become a concrete value (0, _invariant2.default)(negation instanceof _index2.AbstractValue); var pathConditions = [negation]; var pnc = new _completions.PossiblyNormalCompletion(v, c.joinCondition, v, empty_effects, c.alternate, c.alternateEffects, pathConditions, []); return [c.consequentEffects, pnc]; } else if (c.alternate instanceof _completions.ReturnCompletion) { var _pnc = new _completions.PossiblyNormalCompletion(v, c.joinCondition, c.consequent, c.consequentEffects, v, empty_effects, [c.joinCondition], []); return [c.alternateEffects, _pnc]; } else { (0, _invariant2.default)(false, "unbundleReturnCompletion needs an argument that contains a non nested return completion"); } } }, { key: "removeNormalEffects", value: function removeNormalEffects(realm, c) { if (c.consequent instanceof _completions.AbruptCompletion) { if (c.alternate instanceof _index2.Value) { var result = c.alternateEffects; c.alternateEffects = (0, _realm.construct_empty_effects)(realm); return result; } else { (0, _invariant2.default)(c.alternate instanceof _completions.PossiblyNormalCompletion); var _result = realm.composeEffects(c.alternateEffects, this.removeNormalEffects(realm, c.alternate)); c.alternateEffects = (0, _realm.construct_empty_effects)(realm); return _result; } } else { if (c.consequent instanceof _index2.Value) { var _result2 = c.consequentEffects; c.consequentEffects = (0, _realm.construct_empty_effects)(realm); return _result2; } else { (0, _invariant2.default)(c.consequent instanceof _completions.PossiblyNormalCompletion); var _result3 = realm.composeEffects(c.consequentEffects, this.removeNormalEffects(realm, c.consequent)); c.consequentEffects = (0, _realm.construct_empty_effects)(realm); return _result3; } } } }, { key: "joinEffects", value: function joinEffects(realm, joinCondition, e1, e2) { var _e3 = _slicedToArray(e1, 5), result1 = _e3[0], gen1 = _e3[1], bindings1 = _e3[2], properties1 = _e3[3], createdObj1 = _e3[4]; var _e4 = _slicedToArray(e2, 5), result2 = _e4[0], gen2 = _e4[1], bindings2 = _e4[2], properties2 = _e4[3], createdObj2 = _e4[4]; var result = this.joinResults(realm, joinCondition, result1, result2, e1, e2); if (result1 instanceof _completions.AbruptCompletion) { if (!(result2 instanceof _completions.AbruptCompletion)) { (0, _invariant2.default)(result instanceof _completions.PossiblyNormalCompletion); return [result, gen2, bindings2, properties2, createdObj2]; } } else if (result2 instanceof _completions.AbruptCompletion) { (0, _invariant2.default)(result instanceof _completions.PossiblyNormalCompletion); return [result, gen1, bindings1, properties1, createdObj1]; } var bindings = this.joinBindings(realm, joinCondition, bindings1, bindings2); var properties = this.joinPropertyBindings(realm, joinCondition, properties1, properties2, createdObj1, createdObj2); var createdObjects = new Set(); createdObj1.forEach(function (o) { createdObjects.add(o); }); createdObj2.forEach(function (o) { createdObjects.add(o); }); var generator = joinGenerators(realm, joinCondition, gen1, gen2); return [result, generator, bindings, properties, createdObjects]; } }, { key: "joinResults", value: function joinResults(realm, joinCondition, result1, result2, e1, e2) { var _this = this; var getAbstractValue = function getAbstractValue(v1, v2) { return _this.joinValuesAsConditional(realm, joinCondition, v1, v2); }; if (result1 instanceof _environment.Reference || result2 instanceof _environment.Reference) { _index2.AbstractValue.reportIntrospectionError(joinCondition); throw new _errors.FatalError(); } if (result1 instanceof _completions.BreakCompletion && result2 instanceof _completions.BreakCompletion && result1.target === result2.target) { return new _completions.BreakCompletion(realm.intrinsics.empty, joinCondition.expressionLocation, result1.target); } if (result1 instanceof _completions.ContinueCompletion && result2 instanceof _completions.ContinueCompletion && result1.target === result2.target) { return new _completions.ContinueCompletion(realm.intrinsics.empty, joinCondition.expressionLocation, result1.target); } if (result1 instanceof _completions.ReturnCompletion && result2 instanceof _completions.ReturnCompletion) { var val = this.joinValues(realm, result1.value, result2.value, getAbstractValue); (0, _invariant2.default)(val instanceof _index2.Value); return new _completions.ReturnCompletion(val, joinCondition.expressionLocation); } if (result1 instanceof _completions.ThrowCompletion && result2 instanceof _completions.ThrowCompletion) { var _val = this.joinValues(realm, result1.value, result2.value, getAbstractValue); (0, _invariant2.default)(_val instanceof _index2.Value); return new _completions.ThrowCompletion(_val, result1.location); } if (result1 instanceof _completions.AbruptCompletion && result2 instanceof _completions.AbruptCompletion) { return new _completions.JoinedAbruptCompletions(realm, joinCondition, result1, e1, result2, e2); } if (result1 instanceof _index2.Value && result2 instanceof _index2.Value) { var _val2 = this.joinValues(realm, result1, result2, getAbstractValue); (0, _invariant2.default)(_val2 instanceof _index2.Value); return _val2; } if (result1 instanceof _completions.PossiblyNormalCompletion && result2 instanceof _completions.PossiblyNormalCompletion) { return this.composePossiblyNormalCompletions(realm, result1, result2); } if (result1 instanceof _completions.AbruptCompletion) { var value = result2; var savedEffects = void 0; var pathConditions = void 0; var savedPathConditions = []; if (result2 instanceof _completions.PossiblyNormalCompletion) { value = result2.value; savedEffects = result2.savedEffects; pathConditions = [joinCondition].concat(result2.pathConditions); savedPathConditions = result2.savedPathConditions; } else { pathConditions = [joinCondition]; } (0, _invariant2.default)(value instanceof _index2.Value); return new _completions.PossiblyNormalCompletion(value, joinCondition, result1, e1, result2, e2, pathConditions, savedPathConditions, savedEffects); } if (result2 instanceof _completions.AbruptCompletion) { var _value = result1; var _savedEffects = void 0; var _pathConditions = void 0; var _savedPathConditions = []; if (result1 instanceof _completions.PossiblyNormalCompletion) { _value = result1.value; _savedEffects = result1.savedEffects; _pathConditions = [joinCondition].concat(result1.pathConditions); _savedPathConditions = result1.savedPathConditions; } else { _pathConditions = [joinCondition]; } (0, _invariant2.default)(_value instanceof _index2.Value); return new _completions.PossiblyNormalCompletion(_value, joinCondition, result1, e1, result2, e2, _pathConditions, _savedPathConditions, _savedEffects); } if (result1 instanceof _completions.PossiblyNormalCompletion) { (0, _invariant2.default)(result2 instanceof _index2.Value); this.joinPossiblyNormalCompletionWithValue(realm, joinCondition, result1, result2); return result1; } if (result2 instanceof _completions.PossiblyNormalCompletion) { (0, _invariant2.default)(result1 instanceof _index2.Value); this.joinValueWithPossiblyNormalCompletion(realm, joinCondition, result2, result1); return result2; } (0, _invariant2.default)(false); } }, { key: "composeGenerators", value: function composeGenerators(realm, generator1, generator2) { var result = new _generator.Generator(realm); if (!generator1.empty() || !generator2.empty()) { result.composeGenerators(generator1, generator2); } return result; } // Creates a single map that joins together maps m1 and m2 using the given join // operator. If an entry is present in one map but not the other, the missing // entry is treated as if it were there and its value were undefined. }, { key: "joinMaps", value: function joinMaps(m1, m2, join) { var m3 = new Map(); m1.forEach(function (val1, key, map1) { var val2 = m2.get(key); var val3 = join(key, val1, val2); m3.set(key, val3); }); m2.forEach(function (val2, key, map2) { if (!m1.has(key)) { m3.set(key, join(key, undefined, val2)); } }); return m3; } // Creates a single map that has an key, value pair for the union of the key // sets of m1 and m2. The value of a pair is the join of m1[key] and m2[key] // where the join is defined to be just m1[key] if m1[key] === m2[key] and // and abstract value with expression "joinCondition ? m1[key] : m2[key]" if not. }, { key: "joinBindings", value: function joinBindings(realm, joinCondition, m1, m2) { var _this2 = this; var getAbstractValue = function getAbstractValue(v1, v2) { return _this2.joinValuesAsConditional(realm, joinCondition, v1, v2); }; var join = function join(b, b1, b2) { var l1 = b1 === undefined ? b.hasLeaked : b1.hasLeaked; var l2 = b2 === undefined ? b.hasLeaked : b2.hasLeaked; var v1 = b1 === undefined ? b.value : b1.value; var v2 = b2 === undefined ? b.value : b2.value; var hasLeaked = l1 || l2; // If either has leaked, then this binding has leaked. var value = _this2.joinValues(realm, v1, v2, getAbstractValue); (0, _invariant2.default)(value instanceof _index2.Value); return { hasLeaked: hasLeaked, value: value }; }; return this.joinMaps(m1, m2, join); } // If v1 is known and defined and v1 === v2 return v1, // otherwise return getAbstractValue(v1, v2) }, { key: "joinValues", value: function joinValues(realm, v1, v2, getAbstractValue) { if (Array.isArray(v1) || Array.isArray(v2)) { (0, _invariant2.default)(v1 === undefined || Array.isArray(v1)); (0, _invariant2.default)(v2 === undefined || Array.isArray(v2)); return joinArrays(realm, v1, v2, getAbstractValue); } (0, _invariant2.default)(v1 === undefined || v1 instanceof _index2.Value); (0, _invariant2.default)(v2 === undefined || v2 instanceof _index2.Value); if (v1 !== undefined && v2 !== undefined && !(v1 instanceof _index2.AbstractValue) && !(v2 instanceof _index2.AbstractValue) && (0, _index.StrictEqualityComparison)(realm, v1.throwIfNotConcrete(), v2.throwIfNotConcrete())) { return v1; } else { return getAbstractValue(v1, v2); } } }, { key: "joinValuesAsConditional", value: function joinValuesAsConditional(realm, condition, v1, v2) { return _index2.AbstractValue.createFromConditionalOp(realm, condition, v1, v2); } }, { key: "joinPropertyBindings", value: function joinPropertyBindings(realm, joinCondition, m1, m2, c1, c2) { var _this3 = this; var join = function join(b, d1, d2) { // If the PropertyBinding object has been freshly allocated do not join if (d1 === undefined) { if (b.object instanceof _index2.ObjectValue && c2.has(b.object)) return d2; // no join if (b.descriptor !== undefined && m1.has(b)) { // property was deleted d1 = (0, _index.cloneDescriptor)(b.descriptor); (0, _invariant2.default)(d1 !== undefined); d1.value = realm.intrinsics.empty; } else { // no write to property d1 = b.descriptor; //Get value of property before the split } } if (d2 === undefined) { if (b.object instanceof _index2.ObjectValue && c1.has(b.object)) return d1; // no join if (b.descriptor !== undefined && m2.has(b)) { // property was deleted d2 = (0, _index.cloneDescriptor)(b.descriptor); (0, _invariant2.default)(d2 !== undefined); d2.value = realm.intrinsics.empty; } else { // no write to property d2 = b.descriptor; //Get value of property before the split } } return _this3.joinDescriptors(realm, joinCondition, d1, d2); }; return this.joinMaps(m1, m2, join); } }, { key: "joinDescriptors", value: function joinDescriptors(realm, joinCondition, d1, d2) { var _this4 = this; var getAbstractValue = function getAbstractValue(v1, v2) { return _this4.joinValuesAsConditional(realm, joinCondition, v1, v2); }; var clone_with_abstract_value = function clone_with_abstract_value(d) { if (!(0, _index.IsDataDescriptor)(realm, d)) { var d3 = {}; d3.joinCondition = joinCondition; return d3; } var dc = (0, _index.cloneDescriptor)(d); (0, _invariant2.default)(dc !== undefined); var dcValue = dc.value; if (Array.isArray(dcValue)) { (0, _invariant2.default)(dcValue.length > 0); var elem0 = dcValue[0]; if (elem0 instanceof _index2.Value) { dc.value = dcValue.map(function (e) { return getAbstractValue(e, realm.intrinsics.empty); }); } else { dc.value = dcValue.map(function (e) { var _ref4 = e, key1 = _ref4.$Key, val1 = _ref4.$Value; var key3 = getAbstractValue(key1, realm.intrinsics.empty); var val3 = getAbstractValue(val1, realm.intrinsics.empty); return { $Key: key3, $Value: val3 }; }); } } else { (0, _invariant2.default)(dcValue === undefined || dcValue instanceof _index2.Value); dc.value = getAbstractValue(dcValue, realm.intrinsics.empty); } return dc; }; if (d1 === undefined) { if (d2 === undefined) return undefined; // d2 is a new property created in only one branch, join with empty var d3 = clone_with_abstract_value(d2); if (!(0, _index.IsDataDescriptor)(realm, d2)) d3.descriptor2 = d2; return d3; } else if (d2 === undefined) { (0, _invariant2.default)(d1 !== undefined); // d1 is a new property created in only one branch, join with empty var _d = clone_with_abstract_value(d1); if (!(0, _index.IsDataDescriptor)(realm, d1)) _d.descriptor1 = d1; return _d; } else { if ((0, _index.equalDescriptors)(d1, d2) && (0, _index.IsDataDescriptor)(realm, d1)) { var dc = (0, _index.cloneDescriptor)(d1); (0, _invariant2.default)(dc !== undefined); dc.value = this.joinValues(realm, d1.value, d2.value, getAbstractValue); return dc; } var _d2 = {}; _d2.joinCondition = joinCondition; _d2.descriptor1 = d1; _d2.descriptor2 = d2; return _d2; } } }]); return JoinImplementation; }(); //# sourceMappingURL=join.js.map