Skip to content

Commit c73529a

Browse files
committed
[compiler] Prepare HIRBuilder to be used by later passes
1 parent 0d325f1 commit c73529a

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
@@ -124,6 +124,7 @@ function run(
124124
fnType,
125125
config,
126126
contextIdentifiers,
127+
func,
127128
logger,
128129
filename,
129130
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
@@ -68,12 +68,14 @@ import {BuiltInArrayId} from './ObjectShape';
6868
export function lower(
6969
func: NodePath<t.Function>,
7070
env: Environment,
71+
// Bindings captured from the outer function, in case lower() is called recursively (for lambdas)
7172
bindings: Bindings | null = null,
7273
capturedRefs: Array<t.Identifier> = [],
73-
// the outermost function being compiled, in case lower() is called recursively (for lambdas)
74-
parent: NodePath<t.Function> | null = null,
7574
): Result<HIRFunction, CompilerError> {
76-
const builder = new HIRBuilder(env, parent ?? func, bindings, capturedRefs);
75+
const builder = new HIRBuilder(env, {
76+
bindings,
77+
context: capturedRefs,
78+
});
7779
const context: HIRFunction['context'] = [];
7880

7981
for (const ref of capturedRefs ?? []) {
@@ -213,7 +215,7 @@ export function lower(
213215
return Ok({
214216
id,
215217
params,
216-
fnType: parent == null ? env.fnType : 'Other',
218+
fnType: bindings == null ? env.fnType : 'Other',
217219
returnTypeAnnotation: null, // TODO: extract the actual return type node if present
218220
returnType: makeType(),
219221
body: builder.build(),
@@ -3376,7 +3378,7 @@ function lowerFunction(
33763378
| t.ObjectMethod
33773379
>,
33783380
): LoweredFunction | null {
3379-
const componentScope: Scope = builder.parentFunction.scope;
3381+
const componentScope: Scope = builder.environment.parentFunction.scope;
33803382
const capturedContext = gatherCapturedContext(expr, componentScope);
33813383

33823384
/*
@@ -3387,13 +3389,10 @@ function lowerFunction(
33873389
* This isn't a problem in practice because use Babel's scope analysis to
33883390
* identify the correct references.
33893391
*/
3390-
const lowering = lower(
3391-
expr,
3392-
builder.environment,
3393-
builder.bindings,
3394-
[...builder.context, ...capturedContext],
3395-
builder.parentFunction,
3396-
);
3392+
const lowering = lower(expr, builder.environment, builder.bindings, [
3393+
...builder.context,
3394+
...capturedContext,
3395+
]);
33973396
let loweredFunc: HIRFunction;
33983397
if (lowering.isErr()) {
33993398
lowering
@@ -3415,7 +3414,7 @@ function lowerExpressionToTemporary(
34153414
return lowerValueToTemporary(builder, value);
34163415
}
34173416

3418-
function lowerValueToTemporary(
3417+
export function lowerValueToTemporary(
34193418
builder: HIRBuilder,
34203419
value: InstructionValue,
34213420
): 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
@@ -53,7 +53,7 @@ import {
5353
ShapeRegistry,
5454
addHook,
5555
} from './ObjectShape';
56-
import {Scope as BabelScope} from '@babel/traverse';
56+
import {Scope as BabelScope, NodePath} from '@babel/traverse';
5757
import {TypeSchema} from './TypeSchema';
5858

5959
export const ReactElementSymbolSchema = z.object({
@@ -857,12 +857,14 @@ export class Environment {
857857

858858
#contextIdentifiers: Set<t.Identifier>;
859859
#hoistedIdentifiers: Set<t.Identifier>;
860+
parentFunction: NodePath<t.Function>;
860861

861862
constructor(
862863
scope: BabelScope,
863864
fnType: ReactFunctionType,
864865
config: EnvironmentConfig,
865866
contextIdentifiers: Set<t.Identifier>,
867+
parentFunction: NodePath<t.Function>, // the outermost function being compiled
866868
logger: Logger | null,
867869
filename: string | null,
868870
code: string | null,
@@ -920,6 +922,7 @@ export class Environment {
920922
this.#moduleTypes.set(REANIMATED_MODULE_NAME, reanimatedModuleType);
921923
}
922924

925+
this.parentFunction = parentFunction;
923926
this.#contextIdentifiers = contextIdentifiers;
924927
this.#hoistedIdentifiers = new Set();
925928
}

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) {
@@ -375,7 +375,7 @@ export default class HIRBuilder {
375375
}
376376

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

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

0 commit comments

Comments
 (0)