@@ -1400,22 +1400,36 @@ export class Compiler extends DiagnosticEmitter {
1400
1400
1401
1401
/** Compiles an instance field to a getter and a setter. */
1402
1402
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 ;
1405
1412
var type = instance . type ;
1406
1413
var nativeThisType = this . options . nativeSizeType ;
1407
1414
var nativeValueType = type . toNativeType ( ) ;
1408
1415
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 ) ,
1412
1417
module . local_get ( 0 , nativeThisType ) ,
1413
1418
nativeValueType , instance . memoryOffset
1414
1419
) ;
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
+ }
1417
1425
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 ;
1419
1433
var valueExpr = module . local_get ( 1 , nativeValueType ) ;
1420
1434
if ( type . isManaged ) {
1421
1435
valueExpr = this . makeReplace (
@@ -1426,26 +1440,50 @@ export class Compiler extends DiagnosticEmitter {
1426
1440
valueExpr
1427
1441
) ;
1428
1442
}
1429
- module . addFunction ( instance . internalSetterName , createType ( [ nativeThisType , nativeValueType ] ) , NativeType . None , null ,
1443
+ instance . setterRef = module . addFunction ( instance . internalSetterName , createType ( [ nativeThisType , nativeValueType ] ) , NativeType . None , null ,
1430
1444
module . store ( type . byteSize ,
1431
1445
module . local_get ( 0 , nativeThisType ) ,
1432
1446
valueExpr ,
1433
1447
nativeValueType , instance . memoryOffset
1434
1448
)
1435
1449
) ;
1436
-
1450
+ if ( instance . getterRef ) instance . set ( CommonFlags . COMPILED ) ;
1437
1451
return true ;
1438
1452
}
1439
1453
1440
1454
/** Compiles a property to a getter and potentially a setter. */
1441
1455
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 {
1444
1463
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 {
1446
1477
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 ;
1449
1487
}
1450
1488
1451
1489
// === Memory ===================================================================================
@@ -8298,7 +8336,6 @@ export class Compiler extends DiagnosticEmitter {
8298
8336
assert ( ( < Field > target ) . memoryOffset >= 0 ) ;
8299
8337
let thisExpression = assert ( this . resolver . currentThisExpression ) ;
8300
8338
let thisExpr = this . compileExpression ( thisExpression , this . options . usizeType ) ;
8301
- // FIXME
8302
8339
let thisType = this . currentType ;
8303
8340
if ( thisType . is ( TypeFlags . NULLABLE ) ) {
8304
8341
if ( ! flow . isNonnull ( thisExpr , thisType ) ) {
0 commit comments