Fix promotion of catch bindings w/in function expressions

One of our visitors wasn't visiting TryTerminal's handlerBinding, which meant 
that we missed renaming those identifiers in RenameVariables. I also updated the 
printers to print this binding.
This commit is contained in:
Joe Savona
2024-03-07 09:21:33 -08:00
parent 449aa70f99
commit fe91bcefd2
13 changed files with 330 additions and 29 deletions
@@ -266,8 +266,10 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
break;
}
case "try": {
value = `Try block=bb${terminal.block} catch=bb${
terminal.handler
value = `Try block=bb${terminal.block} handler=bb${terminal.handler}${
terminal.handlerBinding !== null
? ` handlerBinding=(${printPlace(terminal.handlerBinding)})`
: ""
} fallthrough=${
terminal.fallthrough != null ? `bb${terminal.fallthrough}` : ""
}`;
@@ -1126,7 +1126,12 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
yield terminal.value;
break;
}
case "try":
case "try": {
if (terminal.handlerBinding !== null) {
yield terminal.handlerBinding;
}
break;
}
case "maybe-throw":
case "sequence":
case "label":
@@ -354,7 +354,12 @@ function writeTerminal(writer: Writer, terminal: ReactiveTerminal): void {
case "try": {
writer.writeLine(`[${terminal.id}] try {`);
writeReactiveInstructions(writer, terminal.block);
writer.writeLine(`} catch {`);
writer.write(`} catch `);
if (terminal.handlerBinding !== null) {
writer.writeLine(`(${printPlace(terminal.handlerBinding)}) {`);
} else {
writer.writeLine(`{`);
}
writeReactiveInstructions(writer, terminal.handler);
writer.writeLine("}");
break;
@@ -545,6 +545,9 @@ export class ReactiveFunctionTransform<
}
case "try": {
this.visitBlock(terminal.block, state);
if (terminal.handlerBinding !== null) {
this.visitPlace(terminal.id, terminal.handlerBinding, state);
}
this.visitBlock(terminal.handler, state);
break;
}
@@ -1,25 +0,0 @@
## Input
```javascript
function Component(props) {
const callback = () => {
try {
return [];
} catch (e) {
return;
}
};
return callback();
}
```
## Error
```
[ReactForget] Invariant: Expected temporaries to be promoted to named identifiers in an earlier pass. identifier 16 is unnamed
```
@@ -0,0 +1,68 @@
## Input
```javascript
import { throwInput } from "shared-runtime";
function Component(props) {
const callback = () => {
try {
throwInput([props.value]);
} catch (e) {
return e;
}
};
return callback();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
import { throwInput } from "shared-runtime";
function Component(props) {
const $ = useMemoCache(4);
let t0;
if ($[0] !== props.value) {
t0 = () => {
try {
throwInput([props.value]);
} catch (t1) {
const e = t1;
return e;
}
};
$[0] = props.value;
$[1] = t0;
} else {
t0 = $[1];
}
const callback = t0;
let t1;
if ($[2] !== callback) {
t1 = callback();
$[2] = callback;
$[3] = t1;
} else {
t1 = $[3];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};
```
### Eval output
(kind: ok) [42]
@@ -0,0 +1,17 @@
import { throwInput } from "shared-runtime";
function Component(props) {
const callback = () => {
try {
throwInput([props.value]);
} catch (e) {
return e;
}
};
return callback();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};
@@ -0,0 +1,61 @@
## Input
```javascript
function Component(props) {
const callback = () => {
try {
return [];
} catch (e) {
return;
}
};
return callback();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{}],
};
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function Component(props) {
const $ = useMemoCache(2);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = () => {
try {
return [];
} catch (t1) {
return;
}
};
$[0] = t0;
} else {
t0 = $[0];
}
const callback = t0;
let t1;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t1 = callback();
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{}],
};
```
### Eval output
(kind: ok) []
@@ -0,0 +1,65 @@
## Input
```javascript
import { throwInput } from "shared-runtime";
function Component(props) {
const object = {
foo() {
try {
throwInput([props.value]);
} catch (e) {
return e;
}
},
};
return object.foo();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
import { throwInput } from "shared-runtime";
function Component(props) {
const $ = useMemoCache(2);
let t0;
if ($[0] !== props.value) {
const object = {
foo() {
try {
throwInput([props.value]);
} catch (t1) {
const e = t1;
return e;
}
},
};
t0 = object.foo();
$[0] = props.value;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};
```
### Eval output
(kind: ok) [42]
@@ -0,0 +1,19 @@
import { throwInput } from "shared-runtime";
function Component(props) {
const object = {
foo() {
try {
throwInput([props.value]);
} catch (e) {
return e;
}
},
};
return object.foo();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 42 }],
};
@@ -0,0 +1,59 @@
## Input
```javascript
function Component(props) {
const object = {
foo() {
try {
return [];
} catch (e) {
return;
}
},
};
return object.foo();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{}],
};
```
## Code
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function Component(props) {
const $ = useMemoCache(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
const object = {
foo() {
try {
return [];
} catch (t1) {
return;
}
},
};
t0 = object.foo();
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{}],
};
```
### Eval output
(kind: ok) []
@@ -0,0 +1,17 @@
function Component(props) {
const object = {
foo() {
try {
return [];
} catch (e) {
return;
}
},
};
return object.foo();
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{}],
};