Validator pass that terminal successors all exist

This commit is contained in:
Joe Savona
2023-04-04 13:29:02 -07:00
parent 6d62d9f505
commit d660f37bf2
6 changed files with 62 additions and 1 deletions
+3 -1
View File
@@ -11,9 +11,10 @@ import {
lower,
mergeConsecutiveBlocks,
ReactiveFunction,
validateConsistentIdentifiers,
validateTerminalSuccessors,
} from "./HIR";
import { Environment, EnvironmentConfig } from "./HIR/Environment";
import { validateConsistentIdentifiers } from "./HIR/ValidateConsistentIdentifiers";
import {
analyseFunctions,
dropMemoCalls,
@@ -61,6 +62,7 @@ export function* run(
yield log({ kind: "hir", name: "MergeConsecutiveBlocks", value: hir });
validateConsistentIdentifiers(hir);
validateTerminalSuccessors(hir);
enterSSA(hir);
yield log({ kind: "hir", name: "SSA", value: hir });
@@ -0,0 +1,27 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { CompilerError } from "../CompilerError";
import { GeneratedSource, HIRFunction } from "./HIR";
import { printTerminal } from "./PrintHIR";
import { mapTerminalSuccessors } from "./visitors";
export function validateTerminalSuccessors(fn: HIRFunction): void {
for (const [, block] of fn.body.blocks) {
mapTerminalSuccessors(block.terminal, (successor) => {
if (!fn.body.blocks.has(successor)) {
CompilerError.invariant(
`Block bb${successor} does not exist for terminal '${printTerminal(
block.terminal
)}'`,
(block.terminal as any).loc ?? GeneratedSource
);
}
return successor;
});
}
}
+2
View File
@@ -17,3 +17,5 @@ export {
} from "./HIRBuilder";
export { mergeConsecutiveBlocks } from "./MergeConsecutiveBlocks";
export { printFunction, printHIR } from "./PrintHIR";
export { validateConsistentIdentifiers } from "./ValidateConsistentIdentifiers";
export { validateTerminalSuccessors } from "./ValidateTerminalSuccessors";
@@ -21,6 +21,8 @@ import {
removeUnreachableFallthroughs,
reversePostorderBlocks,
shrink,
validateConsistentIdentifiers,
validateTerminalSuccessors,
} from "../HIR";
import { removeDeadDoWhileStatements } from "../HIR/HIRBuilder";
import { eliminateRedundantPhi } from "../SSA";
@@ -70,6 +72,9 @@ export function constantPropagation(fn: HIRFunction): void {
// Finally, merge together any blocks that are now guaranteed to execute
// consecutively
mergeConsecutiveBlocks(fn);
validateConsistentIdentifiers(fn);
validateTerminalSuccessors(fn);
}
}
@@ -0,0 +1,20 @@
## Input
```javascript
function Component(props) {
for (let i = 0; i < props.count; i++) {
return;
}
}
```
## Error
```
[ReactForget] Invariant: Block bb4 does not exist for terminal '[1] For init=bb3 test=bb1 loop=bb5 update=bb4 fallthrough=bb2' (2:4)
```
@@ -0,0 +1,5 @@
function Component(props) {
for (let i = 0; i < props.count; i++) {
return;
}
}