diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts index 45b2774630..c5be036759 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts @@ -341,6 +341,7 @@ export type BasicBlock = { */ export type Terminal = | UnsupportedTerminal + | UnreachableTerminal | ThrowTerminal | ReturnTerminal | GotoTerminal @@ -384,6 +385,18 @@ export type UnsupportedTerminal = { id: InstructionId; loc: SourceLocation; }; + +/** + * Terminal for an unreachable block. + * Unreachable blocks are emitted when all control flow paths of a if/switch/try block diverge + * before reaching the fallthrough. + */ +export type UnreachableTerminal = { + kind: "unreachable"; + id: InstructionId; + loc: SourceLocation; +}; + export type ThrowTerminal = { kind: "throw"; value: Place; diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/HIRBuilder.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/HIRBuilder.ts index 99cc65c81b..3c24a2bcf2 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/HIRBuilder.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/HIRBuilder.ts @@ -799,6 +799,7 @@ function getReversePostorderedBlocks(func: HIR): HIR["blocks"] { visit(terminal.block); break; } + case "unreachable": case "unsupported": { break; } diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts index 5bcf9c3997..467fd7a246 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/PrintHIR.ts @@ -121,6 +121,7 @@ export function printMixedHIR( case "throw": case "while": case "for": + case "unreachable": case "unsupported": case "goto": case "do-while": @@ -261,6 +262,10 @@ export function printTerminal(terminal: Terminal): Array | string { value = `[${terminal.id}] Sequence block=bb${terminal.block} fallthrough=bb${terminal.fallthrough}`; break; } + case "unreachable": { + value = `[${terminal.id}] Unreachable`; + break; + } case "unsupported": { value = `Unsupported`; break; diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts index 11ce4db691..e56259835c 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/visitors.ts @@ -853,6 +853,7 @@ export function mapTerminalSuccessors( loc: terminal.loc, }; } + case "unreachable": case "unsupported": { return terminal; } @@ -877,6 +878,7 @@ export function terminalFallthrough(terminal: Terminal): BlockId | null { case "goto": case "return": case "throw": + case "unreachable": case "unsupported": { return null; } @@ -915,6 +917,7 @@ export function mapOptionalFallthroughs( case "goto": case "return": case "throw": + case "unreachable": case "unsupported": { return; } @@ -1085,6 +1088,7 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable { yield terminal.block; break; } + case "unreachable": case "unsupported": break; default: { @@ -1144,6 +1148,7 @@ export function mapTerminalOperands( case "for-of": case "for-in": case "goto": + case "unreachable": case "unsupported": case "scope": { // no-op @@ -1201,6 +1206,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable { case "for-of": case "for-in": case "goto": + case "unreachable": case "unsupported": case "scope": { // no-op diff --git a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/BuildReactiveFunction.ts b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/BuildReactiveFunction.ts index 257891e1fe..fab70abed6 100644 --- a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/BuildReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/BuildReactiveFunction.ts @@ -817,6 +817,10 @@ class Driver { break; } + case "unreachable": { + // noop + break; + } case "unsupported": { CompilerError.invariant(false, { reason: "Unexpected unsupported terminal",