@@ -623,9 +623,12 @@ export class Compiler extends DiagnosticEmitter {
623
623
break ;
624
624
}
625
625
case ElementKind . FIELD : {
626
- this . makeExportedFieldGetter ( prefix + GETTER_PREFIX + name , < Field > element ) ;
627
- if ( ! element . is ( CommonFlags . READONLY ) ) {
628
- this . makeExportedFieldSetter ( prefix + SETTER_PREFIX + name , < Field > element ) ;
626
+ if ( element . is ( CommonFlags . COMPILED ) ) {
627
+ let module = this . module ;
628
+ module . addFunctionExport ( ( < Field > element ) . internalGetterName , prefix + GETTER_PREFIX + name ) ;
629
+ if ( ! element . is ( CommonFlags . READONLY ) ) {
630
+ module . addFunctionExport ( ( < Field > element ) . internalSetterName , prefix + SETTER_PREFIX + name ) ;
631
+ }
629
632
}
630
633
break ;
631
634
}
@@ -674,48 +677,6 @@ export class Compiler extends DiagnosticEmitter {
674
677
}
675
678
}
676
679
677
- /** Makes an exported function to get the value of an instance field. */
678
- private makeExportedFieldGetter ( name : string , field : Field ) : void {
679
- var type = field . type ;
680
- var nativeThisType = this . options . nativeSizeType ;
681
- var nativeValueType = type . toNativeType ( ) ;
682
- var module = this . module ;
683
- var returnExpr = module . load ( type . byteSize , type . is ( TypeFlags . SIGNED ) ,
684
- module . local_get ( 0 , nativeThisType ) ,
685
- nativeValueType , field . memoryOffset
686
- ) ;
687
- // functions retain the return value for the caller
688
- if ( type . isManaged ) returnExpr = this . makeRetain ( returnExpr ) ;
689
- module . addFunction ( name , nativeThisType , nativeValueType , null , returnExpr ) ;
690
- module . addFunctionExport ( name , name ) ;
691
- }
692
-
693
- /** Makes an exported function to set the value of an instance field. */
694
- private makeExportedFieldSetter ( name : string , field : Field ) : void {
695
- var type = field . type ;
696
- var nativeThisType = this . options . nativeSizeType ;
697
- var nativeValueType = type . toNativeType ( ) ;
698
- var module = this . module ;
699
- var valueExpr = module . local_get ( 1 , nativeValueType ) ;
700
- if ( type . isManaged ) {
701
- valueExpr = this . makeReplace (
702
- module . load ( type . byteSize , false ,
703
- module . local_get ( 0 , nativeThisType ) ,
704
- nativeValueType , field . memoryOffset
705
- ) ,
706
- valueExpr
707
- ) ;
708
- }
709
- module . addFunction ( name , createType ( [ nativeThisType , nativeValueType ] ) , NativeType . None , null ,
710
- module . store ( type . byteSize ,
711
- module . local_get ( 0 , nativeThisType ) ,
712
- valueExpr ,
713
- nativeValueType , field . memoryOffset
714
- )
715
- ) ;
716
- module . addFunctionExport ( name , name ) ;
717
- }
718
-
719
680
// === Elements =================================================================================
720
681
721
682
/** Compiles any element. */
@@ -1423,15 +1384,12 @@ export class Compiler extends DiagnosticEmitter {
1423
1384
}
1424
1385
break ;
1425
1386
}
1426
- case ElementKind . FIELD_PROTOTYPE : {
1427
- element . set ( CommonFlags . COMPILED ) ;
1387
+ case ElementKind . FIELD : {
1388
+ this . compileField ( < Field > element ) ;
1428
1389
break ;
1429
1390
}
1430
1391
case ElementKind . PROPERTY : {
1431
- let getterInstance = ( < Property > element ) . getterInstance ;
1432
- if ( getterInstance ) this . compileFunction ( getterInstance ) ;
1433
- let setterInstance = ( < Property > element ) . setterInstance ;
1434
- if ( setterInstance ) this . compileFunction ( setterInstance ) ;
1392
+ this . compileProperty ( < Property > element ) ;
1435
1393
break ;
1436
1394
}
1437
1395
}
@@ -1440,6 +1398,94 @@ export class Compiler extends DiagnosticEmitter {
1440
1398
return true ;
1441
1399
}
1442
1400
1401
+ /** Compiles an instance field to a getter and a setter. */
1402
+ compileField ( instance : Field ) : bool {
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 ;
1412
+ var type = instance . type ;
1413
+ var nativeThisType = this . options . nativeSizeType ;
1414
+ var nativeValueType = type . toNativeType ( ) ;
1415
+ var module = this . module ;
1416
+ var valueExpr = module . load ( type . byteSize , type . is ( TypeFlags . SIGNED ) ,
1417
+ module . local_get ( 0 , nativeThisType ) ,
1418
+ nativeValueType , instance . memoryOffset
1419
+ ) ;
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
+ }
1425
+
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 ;
1433
+ var valueExpr = module . local_get ( 1 , nativeValueType ) ;
1434
+ if ( type . isManaged ) {
1435
+ valueExpr = this . makeReplace (
1436
+ module . load ( type . byteSize , false ,
1437
+ module . local_get ( 0 , nativeThisType ) ,
1438
+ nativeValueType , instance . memoryOffset
1439
+ ) ,
1440
+ valueExpr
1441
+ ) ;
1442
+ }
1443
+ instance . setterRef = module . addFunction ( instance . internalSetterName , createType ( [ nativeThisType , nativeValueType ] ) , NativeType . None , null ,
1444
+ module . store ( type . byteSize ,
1445
+ module . local_get ( 0 , nativeThisType ) ,
1446
+ valueExpr ,
1447
+ nativeValueType , instance . memoryOffset
1448
+ )
1449
+ ) ;
1450
+ if ( instance . getterRef ) instance . set ( CommonFlags . COMPILED ) ;
1451
+ return true ;
1452
+ }
1453
+
1454
+ /** Compiles a property to a getter and potentially a setter. */
1455
+ compileProperty ( instance : Property ) : bool {
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 {
1463
+ var getterInstance = instance . 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 {
1477
+ var setterInstance = instance . setterInstance ;
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 ;
1487
+ }
1488
+
1443
1489
// === Memory ===================================================================================
1444
1490
1445
1491
/** Adds a static memory segment with the specified data. */
@@ -8290,7 +8336,6 @@ export class Compiler extends DiagnosticEmitter {
8290
8336
assert ( ( < Field > target ) . memoryOffset >= 0 ) ;
8291
8337
let thisExpression = assert ( this . resolver . currentThisExpression ) ;
8292
8338
let thisExpr = this . compileExpression ( thisExpression , this . options . usizeType ) ;
8293
- // FIXME
8294
8339
let thisType = this . currentType ;
8295
8340
if ( thisType . is ( TypeFlags . NULLABLE ) ) {
8296
8341
if ( ! flow . isNonnull ( thisExpr , thisType ) ) {
0 commit comments