@@ -1400,22 +1400,36 @@ export class Compiler extends DiagnosticEmitter {
14001400
14011401 /** Compiles an instance field to a getter and a setter. */
14021402 compileField ( instance : Field ) : bool {
1403- if ( instance . is ( CommonFlags . COMPILED ) ) return true ;
1404- instance . set ( CommonFlags . COMPILED ) ;
1403+ this . compileFieldGetter ( instance ) ;
1404+ this . compileFieldSetter ( instance ) ;
1405+ return instance . is ( CommonFlags . COMPILED ) ;
1406+ }
1407+
1408+ /** Compiles the getter of the specified instance field. */
1409+ compileFieldGetter ( instance : Field ) : bool {
1410+ // A getter retains, while a load, as of a field access, does not.
1411+ if ( instance . getterRef ) return true ;
14051412 var type = instance . type ;
14061413 var nativeThisType = this . options . nativeSizeType ;
14071414 var nativeValueType = type . toNativeType ( ) ;
14081415 var module = this . module ;
1409-
1410- // Make a getter
1411- var returnExpr = module . load ( type . byteSize , type . is ( TypeFlags . SIGNED ) ,
1416+ var valueExpr = module . load ( type . byteSize , type . is ( TypeFlags . SIGNED ) ,
14121417 module . local_get ( 0 , nativeThisType ) ,
14131418 nativeValueType , instance . memoryOffset
14141419 ) ;
1415- if ( type . isManaged ) returnExpr = this . makeRetain ( returnExpr ) ;
1416- module . addFunction ( instance . internalGetterName , nativeThisType , nativeValueType , null , returnExpr ) ;
1420+ if ( type . isManaged ) valueExpr = this . makeRetain ( valueExpr ) ;
1421+ instance . getterRef = module . addFunction ( instance . internalGetterName , nativeThisType , nativeValueType , null , valueExpr ) ;
1422+ if ( instance . setterRef ) instance . set ( CommonFlags . COMPILED ) ;
1423+ return true ;
1424+ }
14171425
1418- // Make a setter
1426+ /** Compiles the setter of the specified instance field. */
1427+ compileFieldSetter ( instance : Field ) : bool {
1428+ if ( instance . setterRef ) return true ;
1429+ var type = instance . type ;
1430+ var nativeThisType = this . options . nativeSizeType ;
1431+ var nativeValueType = type . toNativeType ( ) ;
1432+ var module = this . module ;
14191433 var valueExpr = module . local_get ( 1 , nativeValueType ) ;
14201434 if ( type . isManaged ) {
14211435 valueExpr = this . makeReplace (
@@ -1426,26 +1440,50 @@ export class Compiler extends DiagnosticEmitter {
14261440 valueExpr
14271441 ) ;
14281442 }
1429- module . addFunction ( instance . internalSetterName , createType ( [ nativeThisType , nativeValueType ] ) , NativeType . None , null ,
1443+ instance . setterRef = module . addFunction ( instance . internalSetterName , createType ( [ nativeThisType , nativeValueType ] ) , NativeType . None , null ,
14301444 module . store ( type . byteSize ,
14311445 module . local_get ( 0 , nativeThisType ) ,
14321446 valueExpr ,
14331447 nativeValueType , instance . memoryOffset
14341448 )
14351449 ) ;
1436-
1450+ if ( instance . getterRef ) instance . set ( CommonFlags . COMPILED ) ;
14371451 return true ;
14381452 }
14391453
14401454 /** Compiles a property to a getter and potentially a setter. */
14411455 compileProperty ( instance : Property ) : bool {
1442- if ( instance . is ( CommonFlags . COMPILED ) ) return true ;
1443- instance . set ( CommonFlags . COMPILED ) ;
1456+ this . compilePropertyGetter ( instance ) ;
1457+ this . compilePropertySetter ( instance ) ;
1458+ return instance . is ( CommonFlags . COMPILED ) ;
1459+ }
1460+
1461+ /* Compiles the getter of the specified property. */
1462+ compilePropertyGetter ( instance : Property ) : bool {
14441463 var getterInstance = instance . getterInstance ;
1445- if ( getterInstance ) this . compileFunction ( getterInstance ) ;
1464+ if ( getterInstance ) {
1465+ let ret = this . compileFunction ( getterInstance ) ;
1466+ let setterInstance = instance . setterInstance ;
1467+ if ( getterInstance . is ( CommonFlags . COMPILED ) && ( ! setterInstance || setterInstance . is ( CommonFlags . COMPILED ) ) ) {
1468+ instance . set ( CommonFlags . COMPILED ) ;
1469+ }
1470+ return ret ;
1471+ }
1472+ return false ;
1473+ }
1474+
1475+ /** Compiles the setter of the specified property. */
1476+ compilePropertySetter ( instance : Property ) : bool {
14461477 var setterInstance = instance . setterInstance ;
1447- if ( setterInstance ) this . compileFunction ( setterInstance ) ;
1448- return true ;
1478+ if ( setterInstance ) {
1479+ let ret = this . compileFunction ( setterInstance ) ;
1480+ let getterInstance = instance . getterInstance ;
1481+ if ( getterInstance !== null && getterInstance . is ( CommonFlags . COMPILED ) && setterInstance . is ( CommonFlags . COMPILED ) ) {
1482+ instance . set ( CommonFlags . COMPILED ) ;
1483+ }
1484+ return ret ;
1485+ }
1486+ return false ;
14491487 }
14501488
14511489 // === Memory ===================================================================================
@@ -8298,7 +8336,6 @@ export class Compiler extends DiagnosticEmitter {
82988336 assert ( ( < Field > target ) . memoryOffset >= 0 ) ;
82998337 let thisExpression = assert ( this . resolver . currentThisExpression ) ;
83008338 let thisExpr = this . compileExpression ( thisExpression , this . options . usizeType ) ;
8301- // FIXME
83028339 let thisType = this . currentType ;
83038340 if ( thisType . is ( TypeFlags . NULLABLE ) ) {
83048341 if ( ! flow . isNonnull ( thisExpr , thisType ) ) {
0 commit comments