Skip to content

Commit

Permalink
[compiler] Prepare HIRBuilder to be used by later passes
Browse files Browse the repository at this point in the history
  • Loading branch information
mofeiZ committed Feb 1, 2025
1 parent 556cf07 commit 0b6247f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ function run(
fnType,
config,
contextIdentifiers,
func,
logger,
filename,
code,
Expand Down
25 changes: 12 additions & 13 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ import {BuiltInArrayId} from './ObjectShape';
export function lower(
func: NodePath<t.Function>,
env: Environment,
// Bindings captured from the outer function, in case lower() is called recursively (for lambdas)
bindings: Bindings | null = null,
capturedRefs: Array<t.Identifier> = [],
// the outermost function being compiled, in case lower() is called recursively (for lambdas)
parent: NodePath<t.Function> | null = null,
): Result<HIRFunction, CompilerError> {
const builder = new HIRBuilder(env, parent ?? func, bindings, capturedRefs);
const builder = new HIRBuilder(env, {
bindings,
context: capturedRefs,
});
const context: HIRFunction['context'] = [];

for (const ref of capturedRefs ?? []) {
Expand Down Expand Up @@ -213,7 +215,7 @@ export function lower(
return Ok({
id,
params,
fnType: parent == null ? env.fnType : 'Other',
fnType: bindings == null ? env.fnType : 'Other',
returnTypeAnnotation: null, // TODO: extract the actual return type node if present
returnType: makeType(),
body: builder.build(),
Expand Down Expand Up @@ -3375,7 +3377,7 @@ function lowerFunction(
| t.ObjectMethod
>,
): LoweredFunction | null {
const componentScope: Scope = builder.parentFunction.scope;
const componentScope: Scope = builder.environment.parentFunction.scope;
const capturedContext = gatherCapturedContext(expr, componentScope);

/*
Expand All @@ -3386,13 +3388,10 @@ function lowerFunction(
* This isn't a problem in practice because use Babel's scope analysis to
* identify the correct references.
*/
const lowering = lower(
expr,
builder.environment,
builder.bindings,
[...builder.context, ...capturedContext],
builder.parentFunction,
);
const lowering = lower(expr, builder.environment, builder.bindings, [
...builder.context,
...capturedContext,
]);
let loweredFunc: HIRFunction;
if (lowering.isErr()) {
lowering
Expand All @@ -3414,7 +3413,7 @@ function lowerExpressionToTemporary(
return lowerValueToTemporary(builder, value);
}

function lowerValueToTemporary(
export function lowerValueToTemporary(
builder: HIRBuilder,
value: InstructionValue,
): Place {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
ShapeRegistry,
addHook,
} from './ObjectShape';
import {Scope as BabelScope} from '@babel/traverse';
import {Scope as BabelScope, NodePath} from '@babel/traverse';
import {TypeSchema} from './TypeSchema';

export const ReactElementSymbolSchema = z.object({
Expand Down Expand Up @@ -844,12 +844,14 @@ export class Environment {

#contextIdentifiers: Set<t.Identifier>;
#hoistedIdentifiers: Set<t.Identifier>;
parentFunction: NodePath<t.Function>;

constructor(
scope: BabelScope,
fnType: ReactFunctionType,
config: EnvironmentConfig,
contextIdentifiers: Set<t.Identifier>,
parentFunction: NodePath<t.Function>, // the outermost function being compiled
logger: Logger | null,
filename: string | null,
code: string | null,
Expand Down Expand Up @@ -907,6 +909,7 @@ export class Environment {
this.#moduleTypes.set(REANIMATED_MODULE_NAME, reanimatedModuleType);
}

this.parentFunction = parentFunction;
this.#contextIdentifiers = contextIdentifiers;
this.#hoistedIdentifiers = new Set();
}
Expand Down
28 changes: 17 additions & 11 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIRBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ export default class HIRBuilder {
#bindings: Bindings;
#env: Environment;
#exceptionHandlerStack: Array<BlockId> = [];
parentFunction: NodePath<t.Function>;
errors: CompilerError = new CompilerError();
/**
* Traversal context: counts the number of `fbt` tag parents
Expand All @@ -136,16 +135,17 @@ export default class HIRBuilder {

constructor(
env: Environment,
parentFunction: NodePath<t.Function>, // the outermost function being compiled
bindings: Bindings | null = null,
context: Array<t.Identifier> | null = null,
options?: {
bindings?: Bindings | null;
context?: Array<t.Identifier>;
entryBlockKind?: BlockKind;
},
) {
this.#env = env;
this.#bindings = bindings ?? new Map();
this.parentFunction = parentFunction;
this.#context = context ?? [];
this.#bindings = options?.bindings ?? new Map();
this.#context = options?.context ?? [];
this.#entry = makeBlockId(env.nextBlockId);
this.#current = newBlock(this.#entry, 'block');
this.#current = newBlock(this.#entry, options?.entryBlockKind ?? 'block');
}

currentBlockKind(): BlockKind {
Expand Down Expand Up @@ -239,7 +239,7 @@ export default class HIRBuilder {

// Check if the binding is from module scope
const outerBinding =
this.parentFunction.scope.parent.getBinding(originalName);
this.#env.parentFunction.scope.parent.getBinding(originalName);
if (babelBinding === outerBinding) {
const path = babelBinding.path;
if (path.isImportDefaultSpecifier()) {
Expand Down Expand Up @@ -293,7 +293,7 @@ export default class HIRBuilder {
const binding = this.#resolveBabelBinding(path);
if (binding) {
// Check if the binding is from module scope, if so return null
const outerBinding = this.parentFunction.scope.parent.getBinding(
const outerBinding = this.#env.parentFunction.scope.parent.getBinding(
path.node.name,
);
if (binding === outerBinding) {
Expand Down Expand Up @@ -375,7 +375,7 @@ export default class HIRBuilder {
}

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

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

Expand Down

0 comments on commit 0b6247f

Please sign in to comment.