@@ -623,9 +623,12 @@ export class Compiler extends DiagnosticEmitter {
623623 break ;
624624 }
625625 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+ }
629632 }
630633 break ;
631634 }
@@ -674,48 +677,6 @@ export class Compiler extends DiagnosticEmitter {
674677 }
675678 }
676679
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-
719680 // === Elements =================================================================================
720681
721682 /** Compiles any element. */
@@ -1423,15 +1384,12 @@ export class Compiler extends DiagnosticEmitter {
14231384 }
14241385 break ;
14251386 }
1426- case ElementKind . FIELD_PROTOTYPE : {
1427- element . set ( CommonFlags . COMPILED ) ;
1387+ case ElementKind . FIELD : {
1388+ this . compileField ( < Field > element ) ;
14281389 break ;
14291390 }
14301391 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 ) ;
14351393 break ;
14361394 }
14371395 }
@@ -1440,6 +1398,94 @@ export class Compiler extends DiagnosticEmitter {
14401398 return true ;
14411399 }
14421400
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+
14431489 // === Memory ===================================================================================
14441490
14451491 /** Adds a static memory segment with the specified data. */
@@ -8290,7 +8336,6 @@ export class Compiler extends DiagnosticEmitter {
82908336 assert ( ( < Field > target ) . memoryOffset >= 0 ) ;
82918337 let thisExpression = assert ( this . resolver . currentThisExpression ) ;
82928338 let thisExpr = this . compileExpression ( thisExpression , this . options . usizeType ) ;
8293- // FIXME
82948339 let thisType = this . currentType ;
82958340 if ( thisType . is ( TypeFlags . NULLABLE ) ) {
82968341 if ( ! flow . isNonnull ( thisExpr , thisType ) ) {
0 commit comments