mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-08-17 10:30:32 +03:00
Fix join of SimpleNormal with PossiblyNormal completions. (#2250)
Summary: Release note: none When joining a SimpleNormalCompletion with a PossiblyNormalCompletion, do not move the join condition to a leaf position. Pull Request resolved: https://github.com/facebook/prepack/pull/2250 Differential Revision: D8838821 Pulled By: hermanventer fbshipit-source-id: 6e102307af31e2ff2f3fbc7ec7f5ad516df5f7a5
This commit is contained in:
parent
912384679b
commit
cd1b752e92
@ -88,6 +88,9 @@ export class BreakCompletion extends AbruptCompletion {
|
||||
export class ReturnCompletion extends AbruptCompletion {
|
||||
constructor(value: Value, precedingEffects: void | Effects, location: ?BabelNodeSourceLocation) {
|
||||
super(value, precedingEffects, location);
|
||||
if (value instanceof EmptyValue) {
|
||||
this.value = value.$Realm.intrinsics.undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,87 +334,11 @@ export class JoinImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
updatePossiblyNormalCompletionWithConditionalSimpleNormalCompletion(
|
||||
joinNormalCompletions(
|
||||
realm: Realm,
|
||||
joinCondition: AbstractValue,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
nc: SimpleNormalCompletion
|
||||
): void {
|
||||
let v = nc.value;
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
nc.value = AbstractValue.createFromConditionalOp(realm, joinCondition, pnc.alternate.value, v);
|
||||
pnc.alternateEffects.result = nc;
|
||||
nc.effects = pnc.alternateEffects;
|
||||
pnc.alternate = nc;
|
||||
} else {
|
||||
invariant(pnc.alternate instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithConditionalSimpleNormalCompletion(
|
||||
realm,
|
||||
joinCondition,
|
||||
pnc.alternate,
|
||||
nc
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (pnc.consequent instanceof SimpleNormalCompletion) {
|
||||
nc.value = AbstractValue.createFromConditionalOp(realm, joinCondition, pnc.consequent.value, v);
|
||||
pnc.consequentEffects.result = nc;
|
||||
nc.effects = pnc.consequentEffects;
|
||||
pnc.consequent = nc;
|
||||
} else {
|
||||
invariant(pnc.consequent instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithConditionalSimpleNormalCompletion(
|
||||
realm,
|
||||
joinCondition,
|
||||
pnc.consequent,
|
||||
nc
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
realm: Realm,
|
||||
joinCondition: AbstractValue,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
nc: SimpleNormalCompletion
|
||||
): void {
|
||||
let v = nc.value;
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
nc.value = AbstractValue.createFromConditionalOp(realm, joinCondition, v, pnc.alternate.value);
|
||||
pnc = pnc.updateAlternateKeepingCurrentEffects(nc);
|
||||
} else {
|
||||
invariant(pnc.alternate instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
realm,
|
||||
joinCondition,
|
||||
pnc.alternate,
|
||||
nc
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (pnc.consequent instanceof SimpleNormalCompletion) {
|
||||
nc.value = AbstractValue.createFromConditionalOp(realm, joinCondition, v, pnc.consequent.value);
|
||||
pnc = pnc.updateConsequentKeepingCurrentEffects(nc);
|
||||
} else {
|
||||
invariant(pnc.consequent instanceof PossiblyNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
realm,
|
||||
joinCondition,
|
||||
pnc.consequent,
|
||||
nc
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
joinPossiblyNormalCompletions(
|
||||
realm: Realm,
|
||||
joinCondition: AbstractValue,
|
||||
c: PossiblyNormalCompletion,
|
||||
a: PossiblyNormalCompletion
|
||||
c: NormalCompletion,
|
||||
a: NormalCompletion
|
||||
): PossiblyNormalCompletion {
|
||||
let getAbstractValue = (v1: void | Value, v2: void | Value): Value => {
|
||||
if (v1 instanceof EmptyValue) return v2 || realm.intrinsics.undefined;
|
||||
@ -633,8 +557,8 @@ export class JoinImplementation {
|
||||
if (result1 instanceof AbruptCompletion && result2 instanceof AbruptCompletion) {
|
||||
return new ForkedAbruptCompletion(realm, joinCondition, result1, e1, result2, e2);
|
||||
}
|
||||
if (result1 instanceof PossiblyNormalCompletion && result2 instanceof PossiblyNormalCompletion) {
|
||||
return this.joinPossiblyNormalCompletions(realm, joinCondition, result1, result2);
|
||||
if (result1 instanceof NormalCompletion && result2 instanceof NormalCompletion) {
|
||||
return this.joinNormalCompletions(realm, joinCondition, result1, result2);
|
||||
}
|
||||
if (result1 instanceof AbruptCompletion) {
|
||||
let completion = result2;
|
||||
@ -678,21 +602,6 @@ export class JoinImplementation {
|
||||
savedEffects
|
||||
);
|
||||
}
|
||||
if (result1 instanceof PossiblyNormalCompletion) {
|
||||
invariant(result2 instanceof SimpleNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithConditionalSimpleNormalCompletion(realm, joinCondition, result1, result2);
|
||||
return result1;
|
||||
}
|
||||
if (result2 instanceof PossiblyNormalCompletion) {
|
||||
invariant(result1 instanceof SimpleNormalCompletion);
|
||||
this.updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
realm,
|
||||
joinCondition,
|
||||
result2,
|
||||
result1
|
||||
);
|
||||
return result2;
|
||||
}
|
||||
invariant(false);
|
||||
}
|
||||
|
||||
|
15
src/types.js
15
src/types.js
@ -32,7 +32,6 @@ import {
|
||||
AbruptCompletion,
|
||||
Completion,
|
||||
ForkedAbruptCompletion,
|
||||
SimpleNormalCompletion,
|
||||
PossiblyNormalCompletion,
|
||||
NormalCompletion,
|
||||
} from "./completions.js";
|
||||
@ -741,20 +740,6 @@ export type JoinType = {
|
||||
e: Effects
|
||||
): ForkedAbruptCompletion,
|
||||
|
||||
updatePossiblyNormalCompletionWithConditionalSimpleNormalCompletion(
|
||||
realm: Realm,
|
||||
joinCondition: AbstractValue,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
nc: SimpleNormalCompletion
|
||||
): void,
|
||||
|
||||
updatePossiblyNormalCompletionWithInverseConditionalSimpleNormalCompletion(
|
||||
realm: Realm,
|
||||
joinCondition: AbstractValue,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
nc: SimpleNormalCompletion
|
||||
): void,
|
||||
|
||||
extractAndJoinCompletionsOfType(CompletionType: typeof AbruptCompletion, realm: Realm, c: AbruptCompletion): Effects,
|
||||
|
||||
joinForkOrChoose(realm: Realm, joinCondition: Value, e1: Effects, e2: Effects): Effects,
|
||||
|
14
test/serializer/abstract/Throw10.js
Normal file
14
test/serializer/abstract/Throw10.js
Normal file
@ -0,0 +1,14 @@
|
||||
let c1 = global.__abstract ? __abstract("boolean", "true") : true;
|
||||
let c2 = global.__abstract ? __abstract("boolean", "false") : false;
|
||||
|
||||
function foo(cond) {
|
||||
if (cond) throw "I am an error too!";
|
||||
}
|
||||
|
||||
if (c2) {
|
||||
foo(c1);
|
||||
}
|
||||
|
||||
inspect = function() {
|
||||
return "success";
|
||||
};
|
Loading…
Reference in New Issue
Block a user