Skip to content

Commit 257dc27

Browse files
committed
manual simplification
1 parent 1abce52 commit 257dc27

File tree

4 files changed

+63
-72
lines changed

4 files changed

+63
-72
lines changed

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/BuildReactiveFunction.ts

Lines changed: 47 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -925,111 +925,92 @@ class Driver {
925925
}
926926

927927
visitValueBlock(
928-
id: BlockId,
928+
blockId: BlockId,
929929
loc: SourceLocation,
930930
fallthrough: BlockId | null = null,
931931
): {block: BlockId; value: ReactiveValue; place: Place; id: InstructionId} {
932+
const block = this.cx.ir.blocks.get(blockId)!;
932933
// If we've reached the fallthrough block, stop recursing
933-
if (fallthrough !== null && id === fallthrough) {
934-
const block = this.cx.ir.blocks.get(id)!;
935-
// The fallthrough block should have instructions that we extract the value from
936-
return this.extractValueBlockResult(block.instructions, id, loc);
934+
if (fallthrough !== null && blockId === fallthrough) {
935+
CompilerError.invariant(false, {
936+
reason: 'Did not expect to reach the fallthrough of a value block',
937+
description: `Reached bb${blockId}, which is the fallthrough for this value block`,
938+
loc,
939+
});
937940
}
938-
const defaultBlock = this.cx.ir.blocks.get(id)!;
939-
if (defaultBlock.terminal.kind === 'branch') {
940-
if (defaultBlock.instructions.length === 0) {
941+
if (block.terminal.kind === 'branch') {
942+
if (block.instructions.length === 0) {
941943
return {
942-
block: defaultBlock.id,
943-
place: defaultBlock.terminal.test,
944+
block: block.id,
945+
place: block.terminal.test,
944946
value: {
945947
kind: 'LoadLocal',
946-
place: defaultBlock.terminal.test,
947-
loc: defaultBlock.terminal.test.loc,
948+
place: block.terminal.test,
949+
loc: block.terminal.test.loc,
948950
},
949-
id: defaultBlock.terminal.id,
951+
id: block.terminal.id,
950952
};
951953
}
952-
return this.extractValueBlockResult(
953-
defaultBlock.instructions,
954-
defaultBlock.id,
955-
loc,
956-
);
957-
} else if (defaultBlock.terminal.kind === 'goto') {
958-
if (defaultBlock.instructions.length === 0) {
959-
/*
960-
* Empty goto blocks just forward to the next block.
961-
* Follow the goto to get the actual value.
962-
*/
963-
return this.visitValueBlock(
964-
defaultBlock.terminal.block,
954+
return this.extractValueBlockResult(block.instructions, block.id, loc);
955+
} else if (block.terminal.kind === 'goto') {
956+
if (block.instructions.length === 0) {
957+
CompilerError.invariant(false, {
958+
reason: 'Unexpected empty block with `goto` terminal',
959+
description: `Block bb${block.id} is empty`,
965960
loc,
966-
fallthrough,
967-
);
961+
});
968962
}
969-
return this.extractValueBlockResult(
970-
defaultBlock.instructions,
971-
defaultBlock.id,
972-
loc,
973-
);
974-
} else if (defaultBlock.terminal.kind === 'maybe-throw') {
963+
return this.extractValueBlockResult(block.instructions, block.id, loc);
964+
} else if (block.terminal.kind === 'maybe-throw') {
975965
/*
976966
* ReactiveFunction does not explicitly model maybe-throw semantics,
977-
* so maybe-throw terminals in value blocks flatten away. We continue
978-
* to the continuation block if it's still part of the value block.
979-
* The fallthrough parameter tells us when to stop recursing.
967+
* so maybe-throw terminals in value blocks flatten away. In general
968+
* we recurse to the continuation block.
969+
*
970+
* However, if the last portion
971+
* of the value block is a potentially throwing expression, then the
972+
* value block could be of the form
973+
* ```
974+
* bb1:
975+
* ...StoreLocal for the value block...
976+
* maybe-throw continuation=bb2
977+
* bb2:
978+
* goto (exit the value block)
979+
* ```
980+
*
981+
* Ie what would have been a StoreLocal+goto is split up because of
982+
* the maybe-throw. We detect this case and return the value of the
983+
* current block as the result of the value block
980984
*/
981-
const continuationId = defaultBlock.terminal.continuation;
982-
983-
// If the continuation is the fallthrough, we've reached the end of the value block
984-
if (fallthrough !== null && continuationId === fallthrough) {
985-
const instructions = defaultBlock.instructions;
986-
CompilerError.invariant(instructions.length !== 0, {
987-
reason: `Unexpected empty maybe-throw block at value block boundary`,
988-
description: null,
989-
loc: defaultBlock.terminal.loc,
990-
});
991-
return this.extractValueBlockResult(instructions, defaultBlock.id, loc);
992-
}
993-
985+
const continuationId = block.terminal.continuation;
994986
const continuationBlock = this.cx.ir.blocks.get(continuationId)!;
995-
996-
/*
997-
* If the continuation block is empty with a non-maybe-throw terminal,
998-
* extract the result from this block's instructions using the continuation
999-
* block's ID so visitValueBlockTerminal can find the terminal.
1000-
*/
1001987
if (
1002988
continuationBlock.instructions.length === 0 &&
1003-
continuationBlock.terminal.kind !== 'maybe-throw'
989+
continuationBlock.terminal.kind === 'goto'
1004990
) {
1005991
return this.extractValueBlockResult(
1006-
defaultBlock.instructions,
992+
block.instructions,
1007993
continuationBlock.id,
1008994
loc,
1009995
);
1010996
}
1011997

1012-
// Recurse to the continuation, passing through the fallthrough
1013998
const continuation = this.visitValueBlock(
1014999
continuationId,
10151000
loc,
10161001
fallthrough,
10171002
);
1018-
return this.wrapWithSequence(
1019-
defaultBlock.instructions,
1020-
continuation,
1021-
loc,
1022-
);
1003+
return this.wrapWithSequence(block.instructions, continuation, loc);
10231004
} else {
10241005
/*
10251006
* The value block ended in a value terminal, recurse to get the value
10261007
* of that terminal and stitch them together in a sequence.
10271008
*/
1028-
const init = this.visitValueBlockTerminal(defaultBlock.terminal);
1009+
const init = this.visitValueBlockTerminal(block.terminal);
10291010
const final = this.visitValueBlock(init.fallthrough, loc);
10301011
return this.wrapWithSequence(
10311012
[
1032-
...defaultBlock.instructions,
1013+
...block.instructions,
10331014
{id: init.id, loc, lvalue: init.place, value: init.value},
10341015
],
10351016
final,

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-logical-expression.expect.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ function Component(props) {
3939
} catch (t0) {
4040
result = "error";
4141
}
42+
4243
return result;
4344
}
4445

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-optional-chaining.expect.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,27 @@ export const FIXTURE_ENTRYPOINT = {
3232
```javascript
3333
import { c as _c } from "react/compiler-runtime";
3434
function Foo(t0) {
35-
const $ = _c(2);
35+
const $ = _c(4);
3636
const { json } = t0;
3737
try {
38-
const foo = JSON.parse(json)?.foo;
3938
let t1;
40-
if ($[0] !== foo) {
41-
t1 = <span>{foo}</span>;
42-
$[0] = foo;
39+
if ($[0] !== json) {
40+
t1 = JSON.parse(json)?.foo;
41+
$[0] = json;
4342
$[1] = t1;
4443
} else {
4544
t1 = $[1];
4645
}
47-
return t1;
46+
const foo = t1;
47+
let t2;
48+
if ($[2] !== foo) {
49+
t2 = <span>{foo}</span>;
50+
$[2] = foo;
51+
$[3] = t2;
52+
} else {
53+
t2 = $[3];
54+
}
55+
return t2;
4856
} catch {
4957
return null;
5058
}

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-ternary-expression.expect.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ function Component(props) {
3737
} catch (t0) {
3838
result = "error";
3939
}
40+
4041
return result;
4142
}
4243

0 commit comments

Comments
 (0)