@@ -1723,9 +1723,8 @@ export class Compiler extends DiagnosticEmitter {
17231723 nativeValueType , instance . memoryOffset
17241724 ) ;
17251725
1726- // We need to hardcode the local index used by makeRetain because there is no corresponding flow
17271726 if ( type . isManaged ) {
1728- valueExpr = this . makeRetain ( valueExpr , type , 1 ) ;
1727+ valueExpr = this . makeRetain ( valueExpr , type ) ;
17291728 varTypes = [ NativeType . I32 ] ;
17301729 }
17311730
@@ -1765,9 +1764,9 @@ export class Compiler extends DiagnosticEmitter {
17651764 ) ,
17661765 module . block ( null , [
17671766 module . drop (
1768- this . makeRetain ( module . local_get ( 1 , nativeValueType ) , type , 1 )
1767+ this . makeRetain ( module . local_get ( 1 , nativeValueType ) , type )
17691768 ) ,
1770- this . makeRelease ( module . local_get ( 2 , nativeValueType ) , type , 2 )
1769+ this . makeRelease ( module . local_get ( 2 , nativeValueType ) , type )
17711770 ] )
17721771 ) ,
17731772 module . local_get ( 1 , nativeValueType )
@@ -2805,24 +2804,14 @@ export class Compiler extends DiagnosticEmitter {
28052804 // Remember that this flow returns
28062805 flow . set ( FlowFlags . RETURNS | FlowFlags . TERMINATES ) ;
28072806
2808- // Prevent returning a closure in an exported function, since interop with closures is
2809- // not yet supported
2807+ // TODO: implement interop so we can return function references in exported functions
28102808 var returnSignature = returnType . signatureReference ;
28112809 if ( returnSignature !== null && flow . parentFunction . is ( CommonFlags . EXPORT ) ) {
28122810 var returnValueLocalIndex = flow . getTempLocal ( returnType ) . index ;
28132811 var nativeReturnType = returnType . toNativeType ( ) ;
2814- expr = module . flatten ( [
2815- module . local_set ( returnValueLocalIndex , expr ) ,
2816- this . ifClosure (
2817- module . local_get ( returnValueLocalIndex , nativeReturnType ) ,
2818- this . makeAbort ( null , statement ) , // TODO: throw
2819- module . nop ( )
2820- ) ,
2821- module . local_get ( returnValueLocalIndex , nativeReturnType )
2822- ] , nativeReturnType ) ;
2812+ expr = this . makeAbort ( null , statement ) ; // TODO: Use unimplemented here instead, since we know at compile time this will fail
28232813 }
28242814
2825-
28262815 // If the last statement anyway, make it the block's return value
28272816 if ( isLastInBody && expr != 0 && returnType != Type . void ) {
28282817 if ( ! stmts . length ) return expr ;
@@ -3644,7 +3633,7 @@ export class Compiler extends DiagnosticEmitter {
36443633 expr
36453634 ) ,
36463635 this . injectClosedLocals ( tempResult ) ,
3647- this . getClosureReference ( module . local_get ( tempResult . index , fromType . toNativeType ( ) ) )
3636+ module . local_get ( tempResult . index , fromType . toNativeType ( ) )
36483637 ] , toType . toNativeType ( ) ) ;
36493638
36503639 // this.currentFlow.freeTempLocal(tempResult);
@@ -6774,36 +6763,21 @@ export class Compiler extends DiagnosticEmitter {
67746763 var usize = this . options . nativeSizeType ;
67756764 return module . block ( null , [
67766765 module . local_set ( tempFunctionReferenceLocal . index , indexArg ) ,
6777- this . ifClosure (
6778- module . local_get ( tempFunctionReferenceLocal . index , usize ) ,
6779- this . compileCallIndirect ( // If this is a closure
6780- signature . toClosureSignature ( ) ,
6781- module . block ( null , [
6782- module . load (
6783- 4 ,
6784- true ,
6785- this . getClosurePtr (
6786- module . local_get ( tempFunctionReferenceLocal . index , usize ) ,
6787- ) ,
6788- usize ,
6789- 0
6790- ) ,
6791- ] , this . options . nativeSizeType ) ,
6792- expression . args ,
6793- expression ,
6794- this . getClosurePtr (
6766+ this . compileCallIndirect ( // If this is a closure
6767+ signature . toClosureSignature ( ) ,
6768+ module . block ( null , [
6769+ module . load (
6770+ 4 ,
6771+ true ,
67956772 module . local_get ( tempFunctionReferenceLocal . index , usize ) ,
6773+ usize ,
6774+ 0
67966775 ) ,
6797- contextualType == Type . void
6798- ) ,
6799- this . compileCallIndirect ( // If this function isn't a closure
6800- signature ,
6801- module . local_get ( tempFunctionReferenceLocal . index , usize ) ,
6802- expression . args ,
6803- expression ,
6804- 0 ,
6805- contextualType == Type . void
6806- )
6776+ ] , this . options . nativeSizeType ) ,
6777+ expression . args ,
6778+ expression ,
6779+ module . local_get ( tempFunctionReferenceLocal . index , usize ) ,
6780+ contextualType == Type . void
68076781 )
68086782 ] , constraints & Constraints . WILL_DROP ? contextualType . toNativeType ( ) : returnType . toNativeType ( ) ) ;
68096783 }
@@ -7458,75 +7432,20 @@ export class Compiler extends DiagnosticEmitter {
74587432 // <reference-counting>
74597433
74607434 /** Makes a retain call, retaining the expression's value. */
7461- makeRetain ( expr : ExpressionRef , type : Type , exprLocalIndex : i32 = - 1 ) : ExpressionRef {
7435+ makeRetain ( expr : ExpressionRef , type : Type ) : ExpressionRef {
74627436 var module = this . module ;
74637437 var retainInstance = this . program . retainInstance ;
74647438 this . compileFunction ( retainInstance ) ;
7465- if ( type !== null && type . isFunctionIndex ) {
7466- if ( exprLocalIndex < 0 ) {
7467- var exprLocal = this . currentFlow . getTempLocal ( type ) ;
7468- exprLocalIndex = exprLocal . index ;
7469- }
7470- var nativeType = type . toNativeType ( ) ;
7471- var usize = this . options . nativeSizeType ;
7472- var functionRetainCall = module . block ( null , [
7473- module . local_set ( exprLocalIndex , expr ) ,
7474- module . drop (
7475- module . call (
7476- retainInstance . internalName ,
7477- [
7478- this . ifClosure (
7479- module . local_get ( exprLocalIndex , nativeType ) ,
7480- this . getClosurePtr ( module . local_get ( exprLocalIndex , nativeType ) ) ,
7481- usize == NativeType . I32 ? module . i32 ( 0 ) : module . i64 ( 0 )
7482- )
7483- ] ,
7484- usize
7485- )
7486- ) ,
7487- module . local_get ( exprLocalIndex , nativeType )
7488- ] , nativeType ) ;
7489-
7490- // this.currentFlow.freeTempLocal(exprLocal);
7491-
7492- return functionRetainCall ;
7493- }
74947439
74957440 return module . call ( retainInstance . internalName , [ expr ] , this . options . nativeSizeType ) ;
74967441 }
74977442
74987443 /** Makes a release call, releasing the expression's value. Changes the current type to void.*/
7499- makeRelease ( expr : ExpressionRef , type : Type , exprLocalIndex : i32 = - 1 ) : ExpressionRef {
7444+ makeRelease ( expr : ExpressionRef , type : Type ) : ExpressionRef {
75007445 var module = this . module ;
75017446 var releaseInstance = this . program . releaseInstance ;
75027447 this . compileFunction ( releaseInstance ) ;
75037448
7504- if ( type !== null && type . isFunctionIndex ) {
7505- if ( exprLocalIndex < 0 ) {
7506- var exprLocal = this . currentFlow . getTempLocal ( type ) ;
7507- exprLocalIndex = exprLocal . index ;
7508- }
7509- var nativeType = type . toNativeType ( ) ;
7510- var functionReleaseCall = module . block ( null , [
7511- module . local_set ( exprLocalIndex , expr ) ,
7512- module . call (
7513- releaseInstance . internalName ,
7514- [
7515- this . ifClosure (
7516- module . local_get ( exprLocalIndex , nativeType ) ,
7517- this . getClosurePtr ( module . local_get ( exprLocalIndex , nativeType ) ) ,
7518- this . options . nativeSizeType == NativeType . I32 ? module . i32 ( 0 ) : module . i64 ( 0 )
7519- )
7520- ] ,
7521- NativeType . None
7522- )
7523- ] , NativeType . None ) ;
7524-
7525- // TODO: fix a bug in which this free causes some overwrites
7526- // this.currentFlow.freeTempLocal(exprLocal);
7527-
7528- return functionReleaseCall ;
7529- }
75307449 return this . module . call ( releaseInstance . internalName , [ expr ] , NativeType . None ) ;
75317450 }
75327451
@@ -8332,55 +8251,6 @@ export class Compiler extends DiagnosticEmitter {
83328251 return closureExpr ;
83338252 }
83348253
8335- private ifClosure (
8336- indexExpr : ExpressionRef ,
8337- thenExpr : ExpressionRef ,
8338- elseExpr : ExpressionRef
8339- ) : ExpressionRef {
8340- var module = this . module ;
8341- var wasm64 = this . options . nativeSizeType == NativeType . I64 ;
8342-
8343- return module . if (
8344- module . binary (
8345- wasm64 ? BinaryOp . EqI64 : BinaryOp . EqI32 ,
8346- module . binary (
8347- wasm64 ? BinaryOp . AndI64 : BinaryOp . AndI32 ,
8348- indexExpr ,
8349- wasm64 ? module . i64 ( CLOSURE_TAG ) : module . i32 ( CLOSURE_TAG )
8350- ) ,
8351- wasm64 ? module . i64 ( CLOSURE_TAG ) : module . i32 ( CLOSURE_TAG )
8352- ) ,
8353- thenExpr ,
8354- elseExpr
8355- ) ;
8356- }
8357-
8358- private getClosurePtr ( closureExpr : ExpressionRef ) : ExpressionRef {
8359- var module = this . module ;
8360- var wasm64 = this . options . nativeSizeType == NativeType . I64 ;
8361-
8362- return module . binary (
8363- wasm64 ? BinaryOp . ShlI64 : BinaryOp . ShlI32 ,
8364- closureExpr ,
8365- wasm64 ? module . i64 ( 4 ) : module . i32 ( 4 )
8366- ) ;
8367- }
8368-
8369- private getClosureReference ( closureExpr : ExpressionRef ) : ExpressionRef {
8370- var module = this . module ;
8371- var wasm64 = this . options . nativeSizeType == NativeType . I64 ;
8372-
8373- return module . binary (
8374- wasm64 ? BinaryOp . OrI64 : BinaryOp . OrI32 ,
8375- module . binary (
8376- wasm64 ? BinaryOp . ShrI64 : BinaryOp . ShrI32 ,
8377- closureExpr ,
8378- wasm64 ? module . i64 ( 4 ) : module . i32 ( 4 )
8379- ) ,
8380- wasm64 ? module . i64 ( CLOSURE_TAG ) : module . i32 ( CLOSURE_TAG )
8381- ) ;
8382- }
8383-
83848254 /** Makes sure the enclosing source file of the specified expression has been compiled. */
83858255 private maybeCompileEnclosingSource ( expression : Expression ) : void {
83868256 var internalPath = expression . range . source . internalPath ;
0 commit comments