mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-08-17 10:30:32 +03:00
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:
parent
afc77da9a0
commit
5f7256f17e
@ -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;
|
||||
|
@ -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; };
|
||||
})();
|
@ -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')
|
||||
); };
|
||||
})();
|
Loading…
Reference in New Issue
Block a user