mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Scaffold for sequence terminal
I realized that we can use our value block system to fix _most_ of the remaining order-of-evaluation issues we had with sequence expressions. This PR adds a new SequenceTerminal to HIR; there is already a ReactiveFunction equivalent (ReactiveSequenceValue) that the next PR will convert this terminal into.
This commit is contained in:
@@ -279,7 +279,8 @@ export type Terminal =
|
||||
| LogicalTerminal
|
||||
| TernaryTerminal
|
||||
| OptionalTerminal
|
||||
| LabelTerminal;
|
||||
| LabelTerminal
|
||||
| SequenceTerminal;
|
||||
|
||||
function _staticInvariantTerminalHasLocation(
|
||||
terminal: Terminal
|
||||
@@ -298,7 +299,6 @@ function _staticInvariantTerminalHasInstructionId(
|
||||
/**
|
||||
* Terminal nodes allowed for a value block
|
||||
*/
|
||||
export type ValueTerminal = IfTerminal | GotoTerminal;
|
||||
// A terminal that couldn't be lowered correctly.
|
||||
export type UnsupportedTerminal = {
|
||||
kind: "unsupported";
|
||||
@@ -437,6 +437,14 @@ export type OptionalTerminal = {
|
||||
loc: SourceLocation;
|
||||
};
|
||||
|
||||
export type SequenceTerminal = {
|
||||
kind: "sequence";
|
||||
block: BlockId;
|
||||
fallthrough: BlockId;
|
||||
id: InstructionId;
|
||||
loc: SourceLocation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instructions generally represent expressions but with all nesting flattened away,
|
||||
* such that all operands to each instruction are either primitive values OR are
|
||||
|
||||
@@ -697,6 +697,10 @@ export function reversePostorderBlocks(func: HIR): void {
|
||||
visit(terminal.block);
|
||||
break;
|
||||
}
|
||||
case "sequence": {
|
||||
visit(terminal.block);
|
||||
break;
|
||||
}
|
||||
case "unsupported": {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ export function printMixedHIR(
|
||||
return printInstruction(value);
|
||||
}
|
||||
switch (value.kind) {
|
||||
case "sequence":
|
||||
case "label":
|
||||
case "optional":
|
||||
case "branch":
|
||||
@@ -220,6 +221,10 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
|
||||
}`;
|
||||
break;
|
||||
}
|
||||
case "sequence": {
|
||||
value = `[${terminal.id}] Sequence block=bb${terminal.block} fallthrough=bb${terminal.fallthrough}`;
|
||||
break;
|
||||
}
|
||||
case "unsupported": {
|
||||
value = `Unsupported`;
|
||||
break;
|
||||
|
||||
@@ -704,6 +704,17 @@ export function mapTerminalSuccessors(
|
||||
loc: terminal.loc,
|
||||
};
|
||||
}
|
||||
case "sequence": {
|
||||
const block = fn(terminal.block);
|
||||
const fallthrough = fn(terminal.fallthrough);
|
||||
return {
|
||||
kind: "sequence",
|
||||
block,
|
||||
fallthrough,
|
||||
id: makeInstructionId(0),
|
||||
loc: terminal.loc,
|
||||
};
|
||||
}
|
||||
case "unsupported": {
|
||||
return terminal;
|
||||
}
|
||||
@@ -737,6 +748,7 @@ export function terminalFallthrough(terminal: Terminal): BlockId | null {
|
||||
case "label":
|
||||
case "logical":
|
||||
case "optional":
|
||||
case "sequence":
|
||||
case "switch":
|
||||
case "ternary":
|
||||
case "while": {
|
||||
@@ -813,6 +825,10 @@ export function mapOptionalFallthroughs(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "sequence": {
|
||||
const _: BlockId = terminal.fallthrough;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assertExhaustive(
|
||||
terminal,
|
||||
@@ -881,6 +897,10 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
|
||||
yield terminal.block;
|
||||
break;
|
||||
}
|
||||
case "sequence": {
|
||||
yield terminal.block;
|
||||
break;
|
||||
}
|
||||
case "unsupported":
|
||||
break;
|
||||
default: {
|
||||
@@ -920,6 +940,7 @@ export function mapTerminalOperands(
|
||||
terminal.value = fn(terminal.value);
|
||||
break;
|
||||
}
|
||||
case "sequence":
|
||||
case "label":
|
||||
case "optional":
|
||||
case "ternary":
|
||||
@@ -967,6 +988,7 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
|
||||
yield terminal.value;
|
||||
break;
|
||||
}
|
||||
case "sequence":
|
||||
case "label":
|
||||
case "optional":
|
||||
case "ternary":
|
||||
|
||||
@@ -570,6 +570,7 @@ class Driver {
|
||||
|
||||
break;
|
||||
}
|
||||
case "sequence":
|
||||
case "optional":
|
||||
case "ternary":
|
||||
case "logical": {
|
||||
|
||||
@@ -135,6 +135,10 @@ function printTerminalLabel(terminal: Terminal): string {
|
||||
buffer.push("Label");
|
||||
break;
|
||||
}
|
||||
case "sequence": {
|
||||
buffer.push("Sequence");
|
||||
break;
|
||||
}
|
||||
case "unsupported": {
|
||||
break;
|
||||
}
|
||||
@@ -237,6 +241,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "sequence": {
|
||||
buffer.push(printJumpArrow(blockId, terminal.block, "block"));
|
||||
buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
|
||||
break;
|
||||
}
|
||||
case "throw":
|
||||
case "return":
|
||||
case "unsupported": {
|
||||
|
||||
Reference in New Issue
Block a user