mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Store consequentEffects and alternateEffects in consequent and alternate (#2134)
Summary: Release Notes: None Follow up on #2110, this PR makes progress towards unifying PossiblyNormalCompletion and ForkedAbruptCompletion as well as unifying completion and effects. Introduces `updateConsequentKeepingCurrentEffects` for a common pattern of updating one of the completions for a PNC/FAC and fixing up the effects. Closes https://github.com/facebook/prepack/pull/2134 Differential Revision: D8525738 Pulled By: cblappert fbshipit-source-id: c415eea47cd786e39820138f84213c2cc9d5e891
This commit is contained in:
parent
b59e918fd6
commit
891a4c6ea6
@ -25,6 +25,8 @@ export class Completion {
|
||||
target: ?string;
|
||||
location: ?BabelNodeSourceLocation;
|
||||
|
||||
effects: ?Effects;
|
||||
|
||||
toDisplayString(): string {
|
||||
return "[" + this.constructor.name + " value " + (this.value ? this.value.toDisplayString() : "undefined") + "]";
|
||||
}
|
||||
@ -81,18 +83,48 @@ export class ForkedAbruptCompletion extends AbruptCompletion {
|
||||
alternateEffects: Effects
|
||||
) {
|
||||
super(realm.intrinsics.empty, consequent.location);
|
||||
invariant(consequentEffects);
|
||||
invariant(alternateEffects);
|
||||
this.joinCondition = joinCondition;
|
||||
consequent.effects = consequentEffects;
|
||||
this.consequent = consequent;
|
||||
this.consequentEffects = consequentEffects;
|
||||
alternate.effects = alternateEffects;
|
||||
this.alternate = alternate;
|
||||
this.alternateEffects = alternateEffects;
|
||||
}
|
||||
|
||||
joinCondition: AbstractValue;
|
||||
consequent: AbruptCompletion;
|
||||
consequentEffects: Effects;
|
||||
alternate: AbruptCompletion;
|
||||
alternateEffects: Effects;
|
||||
|
||||
// For convenience, this.consequent.effects should always be defined, but accessing it directly requires
|
||||
// verifying that with an invariant.
|
||||
get consequentEffects(): Effects {
|
||||
invariant(this.consequent.effects);
|
||||
return this.consequent.effects;
|
||||
}
|
||||
|
||||
get alternateEffects(): Effects {
|
||||
invariant(this.alternate.effects);
|
||||
return this.alternate.effects;
|
||||
}
|
||||
|
||||
updateConsequentKeepingCurrentEffects(newConsequent: AbruptCompletion) {
|
||||
let effects = this.consequent.effects;
|
||||
invariant(effects);
|
||||
newConsequent.effects = effects;
|
||||
newConsequent.effects.result = newConsequent;
|
||||
this.consequent = newConsequent;
|
||||
return newConsequent;
|
||||
}
|
||||
|
||||
updateAlternateKeepingCurrentEffects(newAlternate: AbruptCompletion) {
|
||||
let effects = this.alternate.effects;
|
||||
invariant(effects);
|
||||
newAlternate.effects = effects;
|
||||
newAlternate.effects.result = newAlternate;
|
||||
this.alternate = newAlternate;
|
||||
return newAlternate;
|
||||
}
|
||||
|
||||
toDisplayString(): string {
|
||||
let superString = super.toDisplayString().slice(0, -1);
|
||||
@ -170,23 +202,51 @@ export class PossiblyNormalCompletion extends NormalCompletion {
|
||||
: alternate.expressionLocation;
|
||||
super(value, loc);
|
||||
this.joinCondition = joinCondition;
|
||||
consequent.effects = consequentEffects;
|
||||
alternate.effects = alternateEffects;
|
||||
this.consequent = consequent;
|
||||
this.consequentEffects = consequentEffects;
|
||||
this.alternate = alternate;
|
||||
this.alternateEffects = alternateEffects;
|
||||
this.savedEffects = savedEffects;
|
||||
this.savedPathConditions = savedPathConditions;
|
||||
}
|
||||
|
||||
joinCondition: AbstractValue;
|
||||
consequent: Completion;
|
||||
consequentEffects: Effects;
|
||||
alternate: Completion;
|
||||
alternateEffects: Effects;
|
||||
savedEffects: void | Effects;
|
||||
// The path conditions that applied at the time of the oldest fork that caused this completion to arise.
|
||||
savedPathConditions: Array<AbstractValue>;
|
||||
|
||||
// For convenience, this.consequent.effects should always be defined, but accessing it directly requires
|
||||
// verifying that with an invariant.
|
||||
get consequentEffects(): Effects {
|
||||
invariant(this.consequent.effects);
|
||||
return this.consequent.effects;
|
||||
}
|
||||
|
||||
get alternateEffects(): Effects {
|
||||
invariant(this.alternate.effects);
|
||||
return this.alternate.effects;
|
||||
}
|
||||
|
||||
// TODO blappert: these functions are a copy of those in ForkedAbruptCompletion, but the two classes will be unified
|
||||
// soon
|
||||
updateConsequentKeepingCurrentEffects(newConsequent: Completion) {
|
||||
let effects = this.consequentEffects;
|
||||
newConsequent.effects = effects;
|
||||
newConsequent.effects.result = newConsequent;
|
||||
this.consequent = newConsequent;
|
||||
return newConsequent;
|
||||
}
|
||||
|
||||
updateAlternateKeepingCurrentEffects(newAlternate: Completion) {
|
||||
let effects = this.alternateEffects;
|
||||
newAlternate.effects = effects;
|
||||
newAlternate.effects.result = newAlternate;
|
||||
this.alternate = newAlternate;
|
||||
return newAlternate;
|
||||
}
|
||||
|
||||
toDisplayString(): string {
|
||||
let superString = super.toDisplayString().slice(0, -1);
|
||||
return (
|
||||
|
@ -112,7 +112,7 @@ export default function(ast: BabelNodeTryStatement, strictCode: boolean, env: Le
|
||||
},
|
||||
"composeNestedThrowEffectsWithHandler/1"
|
||||
);
|
||||
c.consequentEffects.result = c.consequent = new AbruptCompletion(realm.intrinsics.empty);
|
||||
c.updateConsequentKeepingCurrentEffects(new AbruptCompletion(realm.intrinsics.empty));
|
||||
}
|
||||
priorEffects.pop();
|
||||
let alternate = c.alternate;
|
||||
@ -129,7 +129,7 @@ export default function(ast: BabelNodeTryStatement, strictCode: boolean, env: Le
|
||||
},
|
||||
"composeNestedThrowEffectsWithHandler/2"
|
||||
);
|
||||
c.alternateEffects.result = c.alternate = new AbruptCompletion(realm.intrinsics.empty);
|
||||
c.updateAlternateKeepingCurrentEffects(new AbruptCompletion(realm.intrinsics.empty));
|
||||
}
|
||||
priorEffects.pop();
|
||||
return Join.joinForkOrChoose(realm, c.joinCondition, consequentEffects, alternateEffects);
|
||||
|
@ -224,18 +224,18 @@ export class JoinImplementation {
|
||||
pnc.value = v.value;
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
pnc.alternate = v;
|
||||
pnc.alternateEffects.result = v;
|
||||
pnc.alternateEffects = realm.composeEffects(pnc.alternateEffects, subsequentEffects);
|
||||
v.effects = realm.composeEffects(pnc.alternateEffects, subsequentEffects);
|
||||
pnc.alternate = v;
|
||||
} else {
|
||||
invariant(pnc.alternate instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithSubsequentEffects(realm, pnc.alternate, subsequentEffects);
|
||||
}
|
||||
} else {
|
||||
if (pnc.consequent instanceof SimpleNormalCompletion) {
|
||||
pnc.consequent = v;
|
||||
pnc.consequentEffects.result = v;
|
||||
pnc.consequentEffects = realm.composeEffects(pnc.consequentEffects, subsequentEffects);
|
||||
v.effects = realm.composeEffects(pnc.consequentEffects, subsequentEffects);
|
||||
pnc.consequent = v;
|
||||
} else {
|
||||
invariant(pnc.consequent instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithSubsequentEffects(realm, pnc.consequent, subsequentEffects);
|
||||
@ -251,8 +251,7 @@ export class JoinImplementation {
|
||||
if (v instanceof AbstractValue) v = realm.simplifyAndRefineAbstractValue(v);
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
nc.value = v;
|
||||
pnc.alternate = nc;
|
||||
pnc.alternateEffects.result = nc;
|
||||
pnc.updateAlternateKeepingCurrentEffects(nc);
|
||||
pnc.value = v;
|
||||
} else {
|
||||
invariant(pnc.alternate instanceof PossiblyNormalCompletion);
|
||||
@ -266,8 +265,7 @@ export class JoinImplementation {
|
||||
if (v instanceof AbstractValue) v = realm.simplifyAndRefineAbstractValue(v);
|
||||
if (pnc.consequent instanceof SimpleNormalCompletion) {
|
||||
nc.value = v;
|
||||
pnc.consequent = nc;
|
||||
pnc.consequentEffects.result = nc;
|
||||
pnc.updateConsequentKeepingCurrentEffects(nc);
|
||||
pnc.value = v;
|
||||
} else {
|
||||
invariant(pnc.consequent instanceof PossiblyNormalCompletion);
|
||||
@ -364,8 +362,7 @@ export class JoinImplementation {
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
nc.value = AbstractValue.createFromConditionalOp(realm, joinCondition, v, pnc.alternate.value);
|
||||
pnc.alternate = nc;
|
||||
pnc.alternateEffects.result = pnc.alternate;
|
||||
pnc.updateAlternateKeepingCurrentEffects(nc);
|
||||
} else {
|
||||
invariant(pnc.alternate instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
@ -378,8 +375,7 @@ export class JoinImplementation {
|
||||
} else {
|
||||
if (pnc.consequent instanceof SimpleNormalCompletion) {
|
||||
nc.value = AbstractValue.createFromConditionalOp(realm, joinCondition, v, pnc.consequent.value);
|
||||
pnc.consequent = nc;
|
||||
pnc.consequentEffects.result = pnc.consequent;
|
||||
pnc.updateConsequentKeepingCurrentEffects(nc);
|
||||
} else {
|
||||
invariant(pnc.consequent instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
@ -444,12 +440,12 @@ export class JoinImplementation {
|
||||
if (ce.result instanceof CompletionType) {
|
||||
// Erase completions of type CompletionType and prepare for transformation of c to a possibly normal completion
|
||||
if (c.consequent instanceof CompletionType) {
|
||||
c.consequentEffects.result = c.consequent = convertToPNC
|
||||
? new SimpleNormalCompletion(realm.intrinsics.empty)
|
||||
: dummyCompletion;
|
||||
c.updateConsequentKeepingCurrentEffects(
|
||||
convertToPNC ? new SimpleNormalCompletion(realm.intrinsics.empty) : dummyCompletion
|
||||
);
|
||||
convertToPNC = false;
|
||||
} else if (convertToPNC && c.consequent instanceof ForkedAbruptCompletion) {
|
||||
c.consequentEffects.result = c.consequent = (c.consequent.transferChildrenToPossiblyNormalCompletion(): any);
|
||||
c.updateConsequentKeepingCurrentEffects((c.consequent.transferChildrenToPossiblyNormalCompletion(): any));
|
||||
convertToPNC = false;
|
||||
}
|
||||
} else {
|
||||
@ -464,11 +460,11 @@ export class JoinImplementation {
|
||||
if (ae.result instanceof CompletionType) {
|
||||
// Erase completions of type CompletionType and prepare for transformation of c to a possibly normal completion
|
||||
if (c.alternate instanceof CompletionType) {
|
||||
c.alternateEffects.result = c.alternate = convertToPNC
|
||||
? new SimpleNormalCompletion(realm.intrinsics.empty)
|
||||
: dummyCompletion;
|
||||
c.updateAlternateKeepingCurrentEffects(
|
||||
convertToPNC ? new SimpleNormalCompletion(realm.intrinsics.empty) : dummyCompletion
|
||||
);
|
||||
} else if (convertToPNC && c.alternate instanceof ForkedAbruptCompletion) {
|
||||
c.alternateEffects.result = c.alternate = (c.alternate.transferChildrenToPossiblyNormalCompletion(): any);
|
||||
c.updateAlternateKeepingCurrentEffects((c.alternate.transferChildrenToPossiblyNormalCompletion(): any));
|
||||
}
|
||||
} else {
|
||||
ae.result = new CompletionType(realm.intrinsics.empty);
|
||||
|
@ -1178,12 +1178,12 @@ export class Realm {
|
||||
|
||||
updateAbruptCompletions(priorEffects: Effects, c: PossiblyNormalCompletion) {
|
||||
if (c.consequent instanceof AbruptCompletion) {
|
||||
c.consequentEffects = this.composeEffects(priorEffects, c.consequentEffects);
|
||||
c.consequent.effects = this.composeEffects(priorEffects, c.consequentEffects);
|
||||
let alternate = c.alternate;
|
||||
if (alternate instanceof PossiblyNormalCompletion) this.updateAbruptCompletions(priorEffects, alternate);
|
||||
} else {
|
||||
invariant(c.alternate instanceof AbruptCompletion);
|
||||
c.alternateEffects = this.composeEffects(priorEffects, c.alternateEffects);
|
||||
c.alternate.effects = this.composeEffects(priorEffects, c.alternateEffects);
|
||||
let consequent = c.consequent;
|
||||
if (consequent instanceof PossiblyNormalCompletion) this.updateAbruptCompletions(priorEffects, consequent);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user