77 Set_union ,
88 getOrInsertDefault ,
99} from '../Utils/utils' ;
10+ import { collectOptionalChainSidemap } from './CollectOptionalChainDependencies' ;
1011import {
1112 BasicBlock ,
1213 BlockId ,
@@ -19,6 +20,7 @@ import {
1920 ReactiveScopeDependency ,
2021 ScopeId ,
2122} from './HIR' ;
23+ import { collectTemporariesSidemap } from './PropagateScopeDependenciesHIR' ;
2224
2325/**
2426 * Helper function for `PropagateScopeDependencies`.
@@ -73,23 +75,38 @@ export function collectHoistablePropertyLoads(
7375 fn : HIRFunction ,
7476 temporaries : ReadonlyMap < IdentifierId , ReactiveScopeDependency > ,
7577 optionals : ReadonlyMap < BlockId , ReactiveScopeDependency > ,
76- ) : ReadonlyMap < ScopeId , BlockInfo > {
78+ ) : ReadonlyMap < BlockId , BlockInfo > {
7779 const registry = new PropertyPathRegistry ( ) ;
7880
79- const nodes = collectNonNullsInBlocks ( fn , temporaries , optionals , registry ) ;
81+ const functionExpressionReferences = collectFunctionExpressionRValues ( fn ) ;
82+ const reallyAccessedTemporaries = new Map (
83+ [ ...temporaries ] . filter ( ( [ id ] ) => ! functionExpressionReferences . has ( id ) ) ,
84+ ) ;
85+ const nodes = collectNonNullsInBlocks (
86+ fn ,
87+ reallyAccessedTemporaries ,
88+ optionals ,
89+ registry ,
90+ ) ;
8091 propagateNonNull ( fn , nodes , registry ) ;
8192
82- const nodesKeyedByScopeId = new Map < ScopeId , BlockInfo > ( ) ;
93+ return nodes ;
94+ }
95+
96+ export function keyByScopeId < T > (
97+ fn : HIRFunction ,
98+ source : ReadonlyMap < BlockId , T > ,
99+ ) : ReadonlyMap < ScopeId , T > {
100+ const keyedByScopeId = new Map < ScopeId , T > ( ) ;
83101 for ( const [ _ , block ] of fn . body . blocks ) {
84102 if ( block . terminal . kind === 'scope' ) {
85- nodesKeyedByScopeId . set (
103+ keyedByScopeId . set (
86104 block . terminal . scope . id ,
87- nodes . get ( block . terminal . block ) ! ,
105+ source . get ( block . terminal . block ) ! ,
88106 ) ;
89107 }
90108 }
91-
92- return nodesKeyedByScopeId ;
109+ return keyedByScopeId ;
93110}
94111
95112export type BlockInfo = {
@@ -319,6 +336,27 @@ function collectNonNullsInBlocks(
319336 assumedNonNullObjects ,
320337 ) ;
321338 }
339+ } else if (
340+ instr . value . kind === 'FunctionExpression' &&
341+ ! fn . env . config . enableTreatFunctionDepsAsConditional
342+ ) {
343+ const innerFn = instr . value . loweredFunc ;
344+ const innerTemporaries = collectTemporariesSidemap (
345+ innerFn . func ,
346+ new Set ( ) ,
347+ ) ;
348+ const optionals = collectOptionalChainSidemap ( innerFn . func ) ;
349+ const innerHoistableMap = collectHoistablePropertyLoads (
350+ innerFn . func ,
351+ innerTemporaries ,
352+ optionals . hoistableObjects ,
353+ ) ;
354+ const innerHoistables = assertNonNull (
355+ innerHoistableMap . get ( innerFn . func . body . entry ) ,
356+ ) ;
357+ for ( const entry of innerHoistables . assumedNonNullObjects ) {
358+ assumedNonNullObjects . add ( entry ) ;
359+ }
322360 }
323361 }
324362 }
@@ -520,3 +558,25 @@ function reduceMaybeOptionalChains(
520558 }
521559 } while ( changed ) ;
522560}
561+
562+ function collectFunctionExpressionRValues ( fn : HIRFunction ) : Set < IdentifierId > {
563+ const sources = new Map < IdentifierId , IdentifierId > ( ) ;
564+ const functionExpressionReferences = new Set < IdentifierId > ( ) ;
565+
566+ for ( const [ _ , block ] of fn . body . blocks ) {
567+ for ( const { lvalue, value} of block . instructions ) {
568+ if ( value . kind === 'FunctionExpression' ) {
569+ for ( const reference of value . loweredFunc . dependencies ) {
570+ let curr : IdentifierId | undefined = reference . identifier . id ;
571+ while ( curr != null ) {
572+ functionExpressionReferences . add ( curr ) ;
573+ curr = sources . get ( curr ) ;
574+ }
575+ }
576+ } else if ( value . kind === 'PropertyLoad' ) {
577+ sources . set ( lvalue . identifier . id , value . object . identifier . id ) ;
578+ }
579+ }
580+ }
581+ return functionExpressionReferences ;
582+ }
0 commit comments