@@ -1779,6 +1779,40 @@ export class Compiler extends DiagnosticEmitter {
17791779 // This ensures we know which locals need to be stored in the environment
17801780 this . prescanForClosures ( bodyNode , instance , flow ) ;
17811781
1782+ // Mark captured parameters and set up environment if needed
1783+ let preCapturedNames = instance . preCapturedNames ;
1784+ if ( preCapturedNames && preCapturedNames . size > 0 ) {
1785+ // Check if any parameters are captured
1786+ let parameterTypes = instance . signature . parameterTypes ;
1787+ for ( let i = 0 , k = parameterTypes . length ; i < k ; i ++ ) {
1788+ let paramName = instance . getParameterName ( i ) ;
1789+ if ( preCapturedNames . has ( paramName ) ) {
1790+ let local = flow . lookupLocal ( paramName ) ;
1791+ if ( local && ! local . isCaptured ) {
1792+ local . isCaptured = true ;
1793+ // Ensure environment structures are set up
1794+ if ( ! instance . capturedLocals ) {
1795+ instance . capturedLocals = new Map ( ) ;
1796+ }
1797+ if ( ! instance . capturedLocals . has ( local ) ) {
1798+ // Calculate proper byte offset
1799+ let currentOffset = 0 ;
1800+ for ( let _keys = Map_keys ( instance . capturedLocals ) , j = 0 , m = _keys . length ; j < m ; ++ j ) {
1801+ let existingLocal = _keys [ j ] ;
1802+ currentOffset += existingLocal . type . byteSize ;
1803+ }
1804+ local . envSlotIndex = currentOffset ;
1805+ instance . capturedLocals . set ( local , local . envSlotIndex ) ;
1806+ }
1807+ if ( ! instance . envLocal ) {
1808+ let envLocal = flow . addScopedLocal ( "$env" , this . options . usizeType ) ;
1809+ instance . envLocal = envLocal ;
1810+ }
1811+ }
1812+ }
1813+ }
1814+ }
1815+
17821816 // compile statements
17831817 if ( bodyNode . kind == NodeKind . Block ) {
17841818 stmts = this . compileStatements ( ( < BlockStatement > bodyNode ) . statements , stmts ) ;
@@ -3239,12 +3273,12 @@ export class Compiler extends DiagnosticEmitter {
32393273 if ( ! sourceFunc . capturedLocals . has ( local ) ) {
32403274 // Calculate proper byte offset based on current environment size
32413275 let currentOffset = 0 ;
3242- for ( let _values = Map_values ( sourceFunc . capturedLocals ) , i = 0 , k = _values . length ; i < k ; ++ i ) {
3243- let existingLocal = _values [ i ] ;
3276+ for ( let _keys = Map_keys ( sourceFunc . capturedLocals ) , i = 0 , k = _keys . length ; i < k ; ++ i ) {
3277+ let existingLocal = _keys [ i ] ;
32443278 currentOffset += existingLocal . type . byteSize ;
32453279 }
32463280 local . envSlotIndex = currentOffset ;
3247- sourceFunc . capturedLocals . set ( local , local ) ;
3281+ sourceFunc . capturedLocals . set ( local , local . envSlotIndex ) ;
32483282 }
32493283 // Ensure we have an environment local
32503284 if ( ! sourceFunc . envLocal ) {
@@ -7507,7 +7541,13 @@ export class Compiler extends DiagnosticEmitter {
75077541 }
75087542 if ( local && ! captures . has ( local ) ) {
75097543 local . isCaptured = true ;
7510- local . envSlotIndex = captures . size ;
7544+ // Calculate proper byte offset based on existing captures
7545+ let currentOffset = 0 ;
7546+ for ( let _keys = Map_keys ( captures ) , idx = 0 , cnt = _keys . length ; idx < cnt ; ++ idx ) {
7547+ let existingLocal = _keys [ idx ] ;
7548+ currentOffset += existingLocal . type . byteSize ;
7549+ }
7550+ local . envSlotIndex = currentOffset ;
75117551 captures . set ( local , local . envSlotIndex ) ;
75127552 }
75137553 break ;
@@ -7810,7 +7850,10 @@ export class Compiler extends DiagnosticEmitter {
78107850 this . collectDeclaredVariables ( forStmt . body , vars ) ;
78117851 break ;
78127852 }
7813- // Function expressions don't add to outer scope
7853+ case NodeKind . FunctionDeclaration :
7854+ case NodeKind . Function :
7855+ // Function declarations and expressions don't add their variables to outer scope
7856+ break ;
78147857 }
78157858 }
78167859
@@ -8022,6 +8065,19 @@ export class Compiler extends DiagnosticEmitter {
80228065 }
80238066 break ;
80248067 }
8068+ case NodeKind . Variable : {
8069+ // Add declared variables to inner names so they're not considered captures
8070+ let varStmt = < VariableStatement > node ;
8071+ for ( let i = 0 , k = varStmt . declarations . length ; i < k ; i ++ ) {
8072+ let decl = varStmt . declarations [ i ] ;
8073+ innerFunctionNames . add ( decl . name . text ) ;
8074+ // Scan initializers for captures
8075+ if ( decl . initializer ) {
8076+ this . collectCapturedNames ( decl . initializer , innerFunctionNames , outerFlow , declaredVars , capturedNames ) ;
8077+ }
8078+ }
8079+ break ;
8080+ }
80258081 case NodeKind . Binary : {
80268082 let binary = < BinaryExpression > node ;
80278083 this . collectCapturedNames ( binary . left , innerFunctionNames , outerFlow , declaredVars , capturedNames ) ;
0 commit comments