@samitouri / QOS-React / commits / 24b28ae257

[λ] Remove broken support for identifiers defined after use

This also adds some book keeping to throw if ever define identifiers after use to make sure we don't generate incorrect code.

Sathya Gunasekaran committed Feb 7, 2023 at 18:25 UTC 24b28ae25748098f025892cdd23c776203f73367
4 files changed +39 -46
compiler/forget/src/SSA/EnterSSA.ts
+13 -8
@@ -1,4 +1,5 @@
1 import invariant from "invariant";
2 +import { CompilerError } from "../CompilerError";
3 import {
4 BasicBlock,
5 BlockId,
@@ -18,6 +19,7 @@ import {
19 mapInstructionOperands,
20 mapTerminalOperands,
21 } from "../HIR/visitors";
22 +import { todoInvariant } from "../Utils/todo";
23
24 type IncompletePhi = {
25 oldId: Identifier;
@@ -35,6 +37,7 @@ class SSABuilder {
37 unsealedPreds: Map<BasicBlock, number> = new Map();
38 #blocks: Map<BlockId, BasicBlock>;
39 #env: Environment;
40 + #unknown: Set<Identifier> = new Set();
41
42 constructor(env: Environment, blocks: Map<BlockId, BasicBlock>) {
43 this.#blocks = blocks;
@@ -68,6 +71,15 @@ class SSABuilder {
71
72 definePlace(oldPlace: Place): Place {
73 const oldId = oldPlace.identifier;
74 + if (this.#unknown.has(oldId)) {
75 + CompilerError.invariant(
76 + `identifier ${printIdentifier(
77 + oldId
78 + )} should have been defined before use`,
79 + oldPlace.loc
80 + );
81 + }
82 +
83 const newId = this.makeId(oldId);
84 this.state().defs.set(oldId, newId);
85 return {
@@ -98,6 +110,7 @@ class SSABuilder {
110 // console.log(
111 // `Unable to find "${printIdentifier(oldId)}", assuming it's a global`
112 // );
113 + this.#unknown.add(oldId);
114 return oldId;
115 }
116
@@ -224,12 +237,4 @@ export default function enterSSA(func: HIRFunction) {
237 }
238 }
239 }
227 -
228 - for (const [_, block] of func.body.blocks) {
229 - for (const instr of block.instructions) {
230 - if (instr.value.kind === "FunctionExpression") {
231 - mapInstructionOperands(instr, (place) => builder.getPlace(place));
232 - }
233 - }
234 - }
240 }
compiler/forget/src/__tests__/fixtures/hir/error.mutate-captured-arg-separately.expect.md new
+25
@@ -0,0 +1,25 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// Let's not support identifiers defined after use for now.
6 +function component(a) {
7 + let y = function () {
8 + m(x);
9 + };
10 +
11 + let x = { a };
12 + m(x);
13 + return y;
14 +}
15 +
16 +```
17 +
18 +
19 +## Error
20 +
21 +```
22 +[ReactForget] Invariant: identifier x$2 should have been defined before use (7:7)
23 +```
24 +
25 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/error.mutate-captured-arg-separately.js renamed
+1
@@ -1,3 +1,4 @@
1 +// Let's not support identifiers defined after use for now.
2 function component(a) {
3 let y = function () {
4 m(x);
compiler/forget/src/__tests__/fixtures/hir/mutate-captured-arg-separately.expect.md deleted
-38
@@ -1,38 +0,0 @@
1 -
2 -## Input
3 -
4 -```javascript
5 -function component(a) {
6 - let y = function () {
7 - m(x);
8 - };
9 -
10 - let x = { a };
11 - m(x);
12 - return y;
13 -}
14 -
15 -```
16 -
17 -## Code
18 -
19 -```javascript
20 -function component(a) {
21 - const $ = React.unstable_useMemoCache();
22 - let y;
23 - if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
24 - y = function () {
25 - m(x);
26 - };
27 - $[0] = y;
28 - } else {
29 - y = $[0];
30 - }
31 -
32 - const x = { a: a };
33 - m(x);
34 - return y;
35 -}
36 -
37 -```
38 -
\ No newline at end of file