Skip to content

Commit 64b555c

Browse files
committed
[compiler] Prepare HIRBuilder to be used by later passes
1 parent 8ce15b0 commit 64b555c

File tree

4 files changed

+34
-25
lines changed

4 files changed

+34
-25
lines changed

compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ function run(
130130
mode,
131131
config,
132132
contextIdentifiers,
133+
func,
133134
logger,
134135
filename,
135136
code,

compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,14 @@ import {BuiltInArrayId} from './ObjectShape';
7070
export function lower(
7171
func: NodePath<t.Function>,
7272
env: Environment,
73+
// Bindings captured from the outer function, in case lower() is called recursively (for lambdas)
7374
bindings: Bindings | null = null,
7475
capturedRefs: Array<t.Identifier> = [],
75-
// the outermost function being compiled, in case lower() is called recursively (for lambdas)
76-
parent: NodePath<t.Function> | null = null,
7776
): Result<HIRFunction, CompilerError> {
78-
const builder = new HIRBuilder(env, parent ?? func, bindings, capturedRefs);
77+
const builder = new HIRBuilder(env, {
78+
bindings,
79+
context: capturedRefs,
80+
});
7981
const context: HIRFunction['context'] = [];
8082

8183
for (const ref of capturedRefs ?? []) {
@@ -215,7 +217,7 @@ export function lower(
215217
return Ok({
216218
id,
217219
params,
218-
fnType: parent == null ? env.fnType : 'Other',
220+
fnType: bindings == null ? env.fnType : 'Other',
219221
returnTypeAnnotation: null, // TODO: extract the actual return type node if present
220222
returnType: makeType(),
221223
body: builder.build(),
@@ -3417,7 +3419,7 @@ function lowerFunction(
34173419
| t.ObjectMethod
34183420
>,
34193421
): LoweredFunction | null {
3420-
const componentScope: Scope = builder.parentFunction.scope;
3422+
const componentScope: Scope = builder.environment.parentFunction.scope;
34213423
const capturedContext = gatherCapturedContext(expr, componentScope);
34223424

34233425
/*
@@ -3428,13 +3430,10 @@ function lowerFunction(
34283430
* This isn't a problem in practice because use Babel's scope analysis to
34293431
* identify the correct references.
34303432
*/
3431-
const lowering = lower(
3432-
expr,
3433-
builder.environment,
3434-
builder.bindings,
3435-
[...builder.context, ...capturedContext],
3436-
builder.parentFunction,
3437-
);
3433+
const lowering = lower(expr, builder.environment, builder.bindings, [
3434+
...builder.context,
3435+
...capturedContext,
3436+
]);
34383437
let loweredFunc: HIRFunction;
34393438
if (lowering.isErr()) {
34403439
lowering
@@ -3456,7 +3455,7 @@ function lowerExpressionToTemporary(
34563455
return lowerValueToTemporary(builder, value);
34573456
}
34583457

3459-
function lowerValueToTemporary(
3458+
export function lowerValueToTemporary(
34603459
builder: HIRBuilder,
34613460
value: InstructionValue,
34623461
): Place {

compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import {
4747
ShapeRegistry,
4848
addHook,
4949
} from './ObjectShape';
50-
import {Scope as BabelScope} from '@babel/traverse';
50+
import {Scope as BabelScope, NodePath} from '@babel/traverse';
5151
import {TypeSchema} from './TypeSchema';
5252

5353
export const ReactElementSymbolSchema = z.object({
@@ -675,13 +675,15 @@ export class Environment {
675675

676676
#contextIdentifiers: Set<t.Identifier>;
677677
#hoistedIdentifiers: Set<t.Identifier>;
678+
parentFunction: NodePath<t.Function>;
678679

679680
constructor(
680681
scope: BabelScope,
681682
fnType: ReactFunctionType,
682683
compilerMode: CompilerMode,
683684
config: EnvironmentConfig,
684685
contextIdentifiers: Set<t.Identifier>,
686+
parentFunction: NodePath<t.Function>, // the outermost function being compiled
685687
logger: Logger | null,
686688
filename: string | null,
687689
code: string | null,
@@ -740,6 +742,7 @@ export class Environment {
740742
this.#moduleTypes.set(REANIMATED_MODULE_NAME, reanimatedModuleType);
741743
}
742744

745+
this.parentFunction = parentFunction;
743746
this.#contextIdentifiers = contextIdentifiers;
744747
this.#hoistedIdentifiers = new Set();
745748
}

compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ export default class HIRBuilder {
110110
#bindings: Bindings;
111111
#env: Environment;
112112
#exceptionHandlerStack: Array<BlockId> = [];
113-
parentFunction: NodePath<t.Function>;
114113
errors: CompilerError = new CompilerError();
115114
/**
116115
* Traversal context: counts the number of `fbt` tag parents
@@ -136,16 +135,17 @@ export default class HIRBuilder {
136135

137136
constructor(
138137
env: Environment,
139-
parentFunction: NodePath<t.Function>, // the outermost function being compiled
140-
bindings: Bindings | null = null,
141-
context: Array<t.Identifier> | null = null,
138+
options?: {
139+
bindings?: Bindings | null;
140+
context?: Array<t.Identifier>;
141+
entryBlockKind?: BlockKind;
142+
},
142143
) {
143144
this.#env = env;
144-
this.#bindings = bindings ?? new Map();
145-
this.parentFunction = parentFunction;
146-
this.#context = context ?? [];
145+
this.#bindings = options?.bindings ?? new Map();
146+
this.#context = options?.context ?? [];
147147
this.#entry = makeBlockId(env.nextBlockId);
148-
this.#current = newBlock(this.#entry, 'block');
148+
this.#current = newBlock(this.#entry, options?.entryBlockKind ?? 'block');
149149
}
150150

151151
currentBlockKind(): BlockKind {
@@ -239,7 +239,7 @@ export default class HIRBuilder {
239239

240240
// Check if the binding is from module scope
241241
const outerBinding =
242-
this.parentFunction.scope.parent.getBinding(originalName);
242+
this.#env.parentFunction.scope.parent.getBinding(originalName);
243243
if (babelBinding === outerBinding) {
244244
const path = babelBinding.path;
245245
if (path.isImportDefaultSpecifier()) {
@@ -293,7 +293,7 @@ export default class HIRBuilder {
293293
const binding = this.#resolveBabelBinding(path);
294294
if (binding) {
295295
// Check if the binding is from module scope, if so return null
296-
const outerBinding = this.parentFunction.scope.parent.getBinding(
296+
const outerBinding = this.#env.parentFunction.scope.parent.getBinding(
297297
path.node.name,
298298
);
299299
if (binding === outerBinding) {
@@ -376,7 +376,7 @@ export default class HIRBuilder {
376376
}
377377

378378
// Terminate the current block w the given terminal, and start a new block
379-
terminate(terminal: Terminal, nextBlockKind: BlockKind | null): void {
379+
terminate(terminal: Terminal, nextBlockKind: BlockKind | null): BlockId {
380380
const {id: blockId, kind, instructions} = this.#current;
381381
this.#completed.set(blockId, {
382382
kind,
@@ -390,6 +390,7 @@ export default class HIRBuilder {
390390
const nextId = this.#env.nextBlockId;
391391
this.#current = newBlock(nextId, nextBlockKind);
392392
}
393+
return blockId;
393394
}
394395

395396
/*
@@ -746,6 +747,11 @@ function getReversePostorderedBlocks(func: HIR): HIR['blocks'] {
746747
* (eg bb2 then bb1), we ensure that they get reversed back to the correct order.
747748
*/
748749
const block = func.blocks.get(blockId)!;
750+
CompilerError.invariant(block != null, {
751+
reason: '[HIRBuilder] Unexpected null block',
752+
description: `expected block ${blockId} to exist`,
753+
loc: GeneratedSource,
754+
});
749755
const successors = [...eachTerminalSuccessor(block.terminal)].reverse();
750756
const fallthrough = terminalFallthrough(block.terminal);
751757

0 commit comments

Comments
 (0)