Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ import {retainWhere} from '../Utils/utils';
export function flattenScopesWithHooksOrUseHIR(fn: HIRFunction): void {
const activeScopes: Array<{block: BlockId; fallthrough: BlockId}> = [];
const prune: Array<BlockId> = [];
const blocksWithHooks = new Set<BlockId>();

// First pass: identify blocks that contain hooks
for (const [, block] of fn.body.blocks) {
retainWhere(activeScopes, current => current.fallthrough !== block.id);

for (const instr of block.instructions) {
const {value} = instr;
switch (value.kind) {
Expand All @@ -55,17 +55,34 @@ export function flattenScopesWithHooksOrUseHIR(fn: HIRFunction): void {
getHookKind(fn.env, callee.identifier) != null ||
isUseOperator(callee.identifier)
) {
prune.push(...activeScopes.map(entry => entry.block));
activeScopes.length = 0;
blocksWithHooks.add(block.id);
}
}
}
}
}

// Helper function to check if a scope's body block contains hooks
function scopeContainsHook(scopeBlockId: BlockId): boolean {
return blocksWithHooks.has(scopeBlockId);
}

// Second pass: prune only scopes that contain hooks
for (const [, block] of fn.body.blocks) {
retainWhere(activeScopes, current => current.fallthrough !== block.id);

if (block.terminal.kind === 'scope') {
activeScopes.push({
block: block.id,
fallthrough: block.terminal.fallthrough,
});
const scopeBodyBlockId = block.terminal.block;
// Only prune scopes whose body blocks contain hooks
if (scopeContainsHook(scopeBodyBlockId)) {
prune.push(block.id);
} else {
// Scope doesn't contain hooks, so track it (it can be memoized)
activeScopes.push({
block: block.id,
fallthrough: block.terminal.fallthrough,
});
}
}
}

Expand Down