@@ -1819,6 +1819,36 @@ export class Compiler extends DiagnosticEmitter {
18191819 }
18201820 }
18211821 }
1822+
1823+ // Also check if 'this' is captured (for methods)
1824+ if ( preCapturedNames . has ( CommonNames . this_ ) ) {
1825+ let thisLocal = flow . lookupLocal ( CommonNames . this_ ) ;
1826+ if ( thisLocal && ! thisLocal . isCaptured ) {
1827+ thisLocal . isCaptured = true ;
1828+ if ( ! instance . capturedLocals ) {
1829+ instance . capturedLocals = new Map ( ) ;
1830+ }
1831+ if ( ! instance . capturedLocals . has ( thisLocal ) ) {
1832+ let ptrSize = this . options . usizeType . byteSize ;
1833+ let currentOffset = ptrSize ;
1834+ for ( let _keys = Map_keys ( instance . capturedLocals ) , j = 0 , m = _keys . length ; j < m ; ++ j ) {
1835+ let existingLocal = _keys [ j ] ;
1836+ let endOfSlot = existingLocal . envSlotIndex + existingLocal . type . byteSize ;
1837+ if ( endOfSlot > currentOffset ) currentOffset = endOfSlot ;
1838+ }
1839+ let typeSize = thisLocal . type . byteSize ;
1840+ let align = typeSize ;
1841+ currentOffset = ( currentOffset + align - 1 ) & ~ ( align - 1 ) ;
1842+ thisLocal . envSlotIndex = currentOffset ;
1843+ thisLocal . envOwner = instance ;
1844+ instance . capturedLocals . set ( thisLocal , thisLocal . envSlotIndex ) ;
1845+ }
1846+ if ( ! instance . envLocal ) {
1847+ let envLocal = flow . addScopedLocal ( "$env" , this . options . usizeType ) ;
1848+ instance . envLocal = envLocal ;
1849+ }
1850+ }
1851+ }
18221852 }
18231853
18241854 // For closures (functions that capture from outer scope), create a local to cache
@@ -7655,6 +7685,36 @@ export class Compiler extends DiagnosticEmitter {
76557685 }
76567686 break ;
76577687 }
7688+ case NodeKind . This : {
7689+ // Handle 'this' capture - look it up in outer flow
7690+ let local = outerFlow . lookupLocal ( CommonNames . this_ ) ;
7691+ if ( ! local ) {
7692+ local = outerFlow . lookupLocalInOuter ( CommonNames . this_ ) ;
7693+ }
7694+ if ( local && ! captures . has ( local ) ) {
7695+ local . isCaptured = true ;
7696+ if ( ! local . envOwner ) {
7697+ local . envOwner = < Function > local . parent ;
7698+ }
7699+ if ( local . envSlotIndex >= 0 ) {
7700+ captures . set ( local , local . envSlotIndex ) ;
7701+ } else {
7702+ let ptrSize = this . options . usizeType . byteSize ;
7703+ let currentOffset = ptrSize ;
7704+ for ( let _keys = Map_keys ( captures ) , idx = 0 , cnt = _keys . length ; idx < cnt ; ++ idx ) {
7705+ let existingLocal = _keys [ idx ] ;
7706+ let endOfSlot = existingLocal . envSlotIndex + existingLocal . type . byteSize ;
7707+ if ( endOfSlot > currentOffset ) currentOffset = endOfSlot ;
7708+ }
7709+ let typeSize = local . type . byteSize ;
7710+ let align = typeSize ;
7711+ currentOffset = ( currentOffset + align - 1 ) & ~ ( align - 1 ) ;
7712+ local . envSlotIndex = currentOffset ;
7713+ captures . set ( local , local . envSlotIndex ) ;
7714+ }
7715+ }
7716+ break ;
7717+ }
76587718 case NodeKind . Function : {
76597719 // For nested function expressions, scan their body but add their params to inner names
76607720 let funcExpr = < FunctionExpression > node ;
@@ -8166,6 +8226,17 @@ export class Compiler extends DiagnosticEmitter {
81668226 }
81678227 break ;
81688228 }
8229+ case NodeKind . This : {
8230+ // Handle 'this' capture - check if outer function has a 'this' local
8231+ let thisLocal = outerFlow . lookupLocal ( CommonNames . this_ ) ;
8232+ if ( ! thisLocal ) {
8233+ thisLocal = outerFlow . lookupLocalInOuter ( CommonNames . this_ ) ;
8234+ }
8235+ if ( thisLocal ) {
8236+ capturedNames . set ( CommonNames . this_ , null ) ;
8237+ }
8238+ break ;
8239+ }
81698240 case NodeKind . Block : {
81708241 let block = < BlockStatement > node ;
81718242 for ( let i = 0 , k = block . statements . length ; i < k ; i ++ ) {
@@ -8602,9 +8673,11 @@ export class Compiler extends DiagnosticEmitter {
86028673 let slotOffset = local . envSlotIndex ;
86038674 let localType = local . type ;
86048675
8605- // Only copy if this is a parameter (index in parameter range)
8606- // Local variables will be initialized when their declaration is compiled
8607- if ( local . index >= paramStartIndex && local . index < paramEndIndex ) {
8676+ // Copy parameters and 'this' to the environment
8677+ // Local variables (var/let) will be initialized later when their declaration is compiled
8678+ let isParameter = local . index >= paramStartIndex && local . index < paramEndIndex ;
8679+ let isThis = hasThis && local . index == 0 ; // 'this' is at index 0 in methods
8680+ if ( isParameter || isThis ) {
86088681 stmts . push (
86098682 module . store (
86108683 localType . byteSize ,
@@ -8679,6 +8752,22 @@ export class Compiler extends DiagnosticEmitter {
86798752 }
86808753 case NodeKind . This : {
86818754 let thisType = sourceFunction . signature . thisType ;
8755+
8756+ // Check if 'this' is captured from an outer scope (closure case)
8757+ if ( ! thisType && this . options . hasFeature ( Feature . Closures ) ) {
8758+ // Look for 'this' in outer flow - it might be captured
8759+ let thisLocal = flow . lookupLocal ( CommonNames . this_ ) ;
8760+ if ( ! thisLocal ) {
8761+ thisLocal = flow . lookupLocalInOuter ( CommonNames . this_ ) ;
8762+ }
8763+ if ( thisLocal && thisLocal . isCaptured && thisLocal . envSlotIndex >= 0 ) {
8764+ // 'this' is captured - load from closure environment
8765+ flow . set ( FlowFlags . AccessesThis ) ;
8766+ this . currentType = thisLocal . type ;
8767+ return this . compileClosureLoad ( thisLocal , expression ) ;
8768+ }
8769+ }
8770+
86828771 if ( ! thisType ) {
86838772 this . error (
86848773 DiagnosticCode . _this_cannot_be_referenced_in_current_location ,
0 commit comments