Special case conditionals for $Set operations on abstract object (#2219)

Summary:
This lets the simplifier do it work and allows intermediate objects to be dead code eliminated.

If this looks good, I'll do $SetPartial and $Delete too.
Pull Request resolved: https://github.com/facebook/prepack/pull/2219

Differential Revision: D8809146

Pulled By: sebmarkbage

fbshipit-source-id: 9fbfa87f5079b60f234ce4c1b2c745ac72a6b2af
This commit is contained in:
Sebastian Markbage 2018-07-11 12:43:08 -07:00 committed by Facebook Github Bot
parent afc77da9a0
commit 5f7256f17e
3 changed files with 56 additions and 0 deletions

View File

@ -681,6 +681,34 @@ export default class AbstractObjectValue extends AbstractValue {
return cv.$Set(P, V, Receiver === this ? cv : Receiver);
}
invariant(false);
} else if (this.kind === "conditional") {
// this is the join of two concrete/abstract objects
// use this join condition for the join of the two property values
let [cond, ob1, ob2] = this.args;
invariant(cond instanceof AbstractValue);
invariant(ob1 instanceof ObjectValue || ob1 instanceof AbstractObjectValue);
invariant(ob2 instanceof ObjectValue || ob2 instanceof AbstractObjectValue);
let d1 = ob1.$GetOwnProperty(P);
let d2 = ob2.$GetOwnProperty(P);
let oldVal1 =
d1 === undefined ? this.$Realm.intrinsics.empty : IsDataDescriptor(this.$Realm, d1) ? d1.value : undefined;
let oldVal2 =
d2 === undefined ? this.$Realm.intrinsics.empty : IsDataDescriptor(this.$Realm, d2) ? d2.value : undefined;
if (oldVal1 === undefined || oldVal2 === undefined) {
AbstractValue.reportIntrospectionError(this, P);
throw new FatalError();
}
invariant(oldVal1 instanceof Value);
invariant(oldVal2 instanceof Value);
let newVal1 = AbstractValue.createFromConditionalOp(this.$Realm, cond, V, oldVal1);
let newVal2 = AbstractValue.createFromConditionalOp(this.$Realm, cond, oldVal2, V);
let result1 = ob1.$Set(P, newVal1, ob1);
let result2 = ob2.$Set(P, newVal2, ob2);
if (result1 !== result2) {
AbstractValue.reportIntrospectionError(this, P);
throw new FatalError();
}
return result1;
} else {
let sawTrue = false;
let sawFalse = false;

View File

@ -0,0 +1,13 @@
// does not contain:unnecessaryIndirection
(function () {
let c1 = global.__abstract ? __abstract("boolean", "(true)") : true;
let c2 = global.__abstract ? __abstract("boolean", "(!false)") : true;
var a = {unnecessaryIndirection:1};
var b = {unnecessaryIndirection:2};
var c = {unnecessaryIndirection:3};
var obj1 = c1 ? a : b;
var obj2 = c2 ? obj1 : c;
obj2.unnecessaryIndirection = 5;
global.result = a.unnecessaryIndirection;
inspect = function() { return global.result; };
})();

View File

@ -0,0 +1,15 @@
(function () {
let c = global.__abstract ? __abstract("boolean", "(true)") : true;
var a = {x:1};
var b = {};
var obj = c ? a : b;
obj.x = 2;
global.result = a.x;
global.residualObject = b;
inspect = function() {
return (
global.result + ' ' +
global.residualObject.x + ' ' +
global.residualObject.hasOwnProperty('x')
); };
})();