@@ -6190,7 +6190,7 @@ export class Compiler extends DiagnosticEmitter {
61906190 var thisExpression = this . resolver . currentThisExpression ;
61916191
61926192 var signature : Signature | null ;
6193- var indexArg : ExpressionRef ;
6193+ var functionArg : ExpressionRef ;
61946194 switch ( target . kind ) {
61956195
61966196 // direct call: concrete function
@@ -6224,15 +6224,21 @@ export class Compiler extends DiagnosticEmitter {
62246224 ) ;
62256225 }
62266226
6227- // indirect call: index argument with signature (non-generic, can't be inlined)
6227+ // indirect call: first-class function (non-generic, can't be inlined)
62286228 case ElementKind . LOCAL : {
62296229 let local = < Local > target ;
62306230 signature = local . type . signatureReference ;
62316231 if ( signature ) {
62326232 if ( local . is ( CommonFlags . INLINED ) ) {
6233- indexArg = module . i32 ( i64_low ( local . constantIntegerValue ) ) ;
6233+ let inlinedValue = local . constantIntegerValue ;
6234+ if ( this . options . isWasm64 ) {
6235+ functionArg = module . i64 ( i64_low ( inlinedValue ) , i64_high ( inlinedValue ) ) ;
6236+ } else {
6237+ assert ( ! i64_high ( inlinedValue ) ) ;
6238+ functionArg = module . i32 ( i64_low ( inlinedValue ) ) ;
6239+ }
62346240 } else {
6235- indexArg = module . local_get ( local . index , NativeType . I32 ) ;
6241+ functionArg = module . local_get ( local . index , this . options . nativeSizeType ) ;
62366242 }
62376243 break ;
62386244 }
@@ -6246,7 +6252,7 @@ export class Compiler extends DiagnosticEmitter {
62466252 let global = < Global > target ;
62476253 signature = global . type . signatureReference ;
62486254 if ( signature ) {
6249- indexArg = module . global_get ( global . internalName , global . type . toNativeType ( ) ) ;
6255+ functionArg = module . global_get ( global . internalName , global . type . toNativeType ( ) ) ;
62506256 break ;
62516257 }
62526258 this . error (
@@ -6262,13 +6268,14 @@ export class Compiler extends DiagnosticEmitter {
62626268 if ( signature ) {
62636269 let fieldParent = fieldInstance . parent ;
62646270 assert ( fieldParent . kind == ElementKind . CLASS ) ;
6265- indexArg = module . load ( 4 , false ,
6271+ let usizeType = this . options . usizeType ;
6272+ functionArg = module . load ( usizeType . byteSize , false ,
62666273 this . compileExpression (
62676274 assert ( thisExpression ) ,
62686275 ( < Class > fieldParent ) . type ,
62696276 Constraints . CONV_IMPLICIT | Constraints . IS_THIS
62706277 ) ,
6271- NativeType . I32 ,
6278+ usizeType . toNativeType ( ) ,
62726279 fieldInstance . memoryOffset
62736280 ) ;
62746281 break ;
@@ -6297,7 +6304,7 @@ export class Compiler extends DiagnosticEmitter {
62976304 Constraints . CONV_IMPLICIT | Constraints . IS_THIS
62986305 ) ;
62996306 }
6300- indexArg = this . compileCallDirect ( getterInstance , [ ] , expression . expression , thisArg ) ;
6307+ functionArg = this . compileCallDirect ( getterInstance , [ ] , expression . expression , thisArg ) ;
63016308 signature = this . currentType . signatureReference ;
63026309 if ( ! signature ) {
63036310 this . error (
@@ -6314,7 +6321,7 @@ export class Compiler extends DiagnosticEmitter {
63146321 if ( typeArguments !== null && typeArguments . length > 0 ) {
63156322 let ftype = typeArguments [ 0 ] ;
63166323 signature = ftype . getSignature ( ) ;
6317- indexArg = this . compileExpression ( expression . expression , ftype , Constraints . CONV_IMPLICIT ) ;
6324+ functionArg = this . compileExpression ( expression . expression , ftype , Constraints . CONV_IMPLICIT ) ;
63186325 break ;
63196326 }
63206327 // fall-through
@@ -6339,7 +6346,7 @@ export class Compiler extends DiagnosticEmitter {
63396346 }
63406347 return this . compileCallIndirect (
63416348 assert ( signature ) , // FIXME: bootstrap can't see this yet
6342- indexArg ,
6349+ functionArg ,
63436350 expression . args ,
63446351 expression ,
63456352 0 ,
@@ -7143,10 +7150,10 @@ export class Compiler extends DiagnosticEmitter {
71437150 return expr ;
71447151 }
71457152
7146- /** Compiles an indirect call using an index argument and a signature . */
7153+ /** Compiles an indirect call to a first-class function . */
71477154 compileCallIndirect (
71487155 signature : Signature ,
7149- indexArg : ExpressionRef ,
7156+ functionArg : ExpressionRef ,
71507157 argumentExpressions : Expression [ ] ,
71517158 reportNode : Node ,
71527159 thisArg : ExpressionRef = 0 ,
@@ -7177,13 +7184,13 @@ export class Compiler extends DiagnosticEmitter {
71777184 ) ;
71787185 }
71797186 assert ( index == numArgumentsInclThis ) ;
7180- return this . makeCallIndirect ( signature , indexArg , reportNode , operands , immediatelyDropped ) ;
7187+ return this . makeCallIndirect ( signature , functionArg , reportNode , operands , immediatelyDropped ) ;
71817188 }
71827189
7183- /** Creates an indirect call to the function at `indexArg` in the function table . */
7190+ /** Creates an indirect call to a first-class function. */
71847191 makeCallIndirect (
71857192 signature : Signature ,
7186- indexArg : ExpressionRef ,
7193+ functionArg : ExpressionRef ,
71877194 reportNode : Node ,
71887195 operands : ExpressionRef [ ] | null = null ,
71897196 immediatelyDropped : bool = false ,
@@ -7216,37 +7223,29 @@ export class Compiler extends DiagnosticEmitter {
72167223 }
72177224 }
72187225
7219- if ( this . options . isWasm64 ) {
7220- indexArg = module . unary ( UnaryOp . WrapI64 , indexArg ) ;
7221- }
7222-
72237226 // We might be calling a varargs stub here, even if all operands have been
72247227 // provided, so we must set `argumentsLength` in any case. Inject setting it
72257228 // into the index argument, which becomes executed last after any operands.
72267229 this . ensureArgumentsLength ( ) ;
72277230 var nativeSizeType = this . options . nativeSizeType ;
7228- if ( getSideEffects ( indexArg ) & SideEffects . WritesGlobal ) {
7231+ if ( getSideEffects ( functionArg ) & SideEffects . WritesGlobal ) {
72297232 let flow = this . currentFlow ;
7230- let temp = flow . getTempLocal ( this . options . usizeType , findUsedLocals ( indexArg ) ) ;
7231- indexArg = module . block ( null , [
7232- module . local_set ( temp . index , indexArg , true ) , // Function
7233+ let temp = flow . getTempLocal ( this . options . usizeType , findUsedLocals ( functionArg ) ) ;
7234+ functionArg = module . block ( null , [
7235+ module . local_set ( temp . index , functionArg , true ) , // Function
72337236 module . global_set ( BuiltinNames . argumentsLength , module . i32 ( numArguments ) ) ,
72347237 module . local_get ( temp . index , nativeSizeType )
72357238 ] , nativeSizeType ) ;
72367239 flow . freeTempLocal ( temp ) ;
72377240 } else { // simplify
7238- indexArg = module . block ( null , [
7241+ functionArg = module . block ( null , [
72397242 module . global_set ( BuiltinNames . argumentsLength , module . i32 ( numArguments ) ) ,
7240- indexArg
7243+ functionArg
72417244 ] , nativeSizeType ) ;
72427245 }
72437246 if ( operands ) this . operandsTostack ( signature , operands ) ;
72447247 var expr = module . call_indirect (
7245- nativeSizeType == NativeType . I64
7246- ? module . unary ( UnaryOp . WrapI64 ,
7247- module . load ( 8 , false , indexArg , NativeType . I64 )
7248- )
7249- : module . load ( 4 , false , indexArg , NativeType . I32 ) ,
7248+ module . load ( 4 , false , functionArg , NativeType . I32 ) , // ._index
72507249 operands ,
72517250 signature . nativeParams ,
72527251 signature . nativeResults
0 commit comments