@@ -6190,7 +6190,7 @@ export class Compiler extends DiagnosticEmitter {
6190
6190
var thisExpression = this . resolver . currentThisExpression ;
6191
6191
6192
6192
var signature : Signature | null ;
6193
- var indexArg : ExpressionRef ;
6193
+ var functionArg : ExpressionRef ;
6194
6194
switch ( target . kind ) {
6195
6195
6196
6196
// direct call: concrete function
@@ -6224,15 +6224,21 @@ export class Compiler extends DiagnosticEmitter {
6224
6224
) ;
6225
6225
}
6226
6226
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)
6228
6228
case ElementKind . LOCAL : {
6229
6229
let local = < Local > target ;
6230
6230
signature = local . type . signatureReference ;
6231
6231
if ( signature ) {
6232
6232
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
+ }
6234
6240
} else {
6235
- indexArg = module . local_get ( local . index , NativeType . I32 ) ;
6241
+ functionArg = module . local_get ( local . index , this . options . nativeSizeType ) ;
6236
6242
}
6237
6243
break ;
6238
6244
}
@@ -6246,7 +6252,7 @@ export class Compiler extends DiagnosticEmitter {
6246
6252
let global = < Global > target ;
6247
6253
signature = global . type . signatureReference ;
6248
6254
if ( signature ) {
6249
- indexArg = module . global_get ( global . internalName , global . type . toNativeType ( ) ) ;
6255
+ functionArg = module . global_get ( global . internalName , global . type . toNativeType ( ) ) ;
6250
6256
break ;
6251
6257
}
6252
6258
this . error (
@@ -6262,13 +6268,14 @@ export class Compiler extends DiagnosticEmitter {
6262
6268
if ( signature ) {
6263
6269
let fieldParent = fieldInstance . parent ;
6264
6270
assert ( fieldParent . kind == ElementKind . CLASS ) ;
6265
- indexArg = module . load ( 4 , false ,
6271
+ let usizeType = this . options . usizeType ;
6272
+ functionArg = module . load ( usizeType . byteSize , false ,
6266
6273
this . compileExpression (
6267
6274
assert ( thisExpression ) ,
6268
6275
( < Class > fieldParent ) . type ,
6269
6276
Constraints . CONV_IMPLICIT | Constraints . IS_THIS
6270
6277
) ,
6271
- NativeType . I32 ,
6278
+ usizeType . toNativeType ( ) ,
6272
6279
fieldInstance . memoryOffset
6273
6280
) ;
6274
6281
break ;
@@ -6297,7 +6304,7 @@ export class Compiler extends DiagnosticEmitter {
6297
6304
Constraints . CONV_IMPLICIT | Constraints . IS_THIS
6298
6305
) ;
6299
6306
}
6300
- indexArg = this . compileCallDirect ( getterInstance , [ ] , expression . expression , thisArg ) ;
6307
+ functionArg = this . compileCallDirect ( getterInstance , [ ] , expression . expression , thisArg ) ;
6301
6308
signature = this . currentType . signatureReference ;
6302
6309
if ( ! signature ) {
6303
6310
this . error (
@@ -6314,7 +6321,7 @@ export class Compiler extends DiagnosticEmitter {
6314
6321
if ( typeArguments !== null && typeArguments . length > 0 ) {
6315
6322
let ftype = typeArguments [ 0 ] ;
6316
6323
signature = ftype . getSignature ( ) ;
6317
- indexArg = this . compileExpression ( expression . expression , ftype , Constraints . CONV_IMPLICIT ) ;
6324
+ functionArg = this . compileExpression ( expression . expression , ftype , Constraints . CONV_IMPLICIT ) ;
6318
6325
break ;
6319
6326
}
6320
6327
// fall-through
@@ -6339,7 +6346,7 @@ export class Compiler extends DiagnosticEmitter {
6339
6346
}
6340
6347
return this . compileCallIndirect (
6341
6348
assert ( signature ) , // FIXME: bootstrap can't see this yet
6342
- indexArg ,
6349
+ functionArg ,
6343
6350
expression . args ,
6344
6351
expression ,
6345
6352
0 ,
@@ -7143,10 +7150,10 @@ export class Compiler extends DiagnosticEmitter {
7143
7150
return expr ;
7144
7151
}
7145
7152
7146
- /** Compiles an indirect call using an index argument and a signature . */
7153
+ /** Compiles an indirect call to a first-class function . */
7147
7154
compileCallIndirect (
7148
7155
signature : Signature ,
7149
- indexArg : ExpressionRef ,
7156
+ functionArg : ExpressionRef ,
7150
7157
argumentExpressions : Expression [ ] ,
7151
7158
reportNode : Node ,
7152
7159
thisArg : ExpressionRef = 0 ,
@@ -7177,13 +7184,13 @@ export class Compiler extends DiagnosticEmitter {
7177
7184
) ;
7178
7185
}
7179
7186
assert ( index == numArgumentsInclThis ) ;
7180
- return this . makeCallIndirect ( signature , indexArg , reportNode , operands , immediatelyDropped ) ;
7187
+ return this . makeCallIndirect ( signature , functionArg , reportNode , operands , immediatelyDropped ) ;
7181
7188
}
7182
7189
7183
- /** Creates an indirect call to the function at `indexArg` in the function table . */
7190
+ /** Creates an indirect call to a first-class function. */
7184
7191
makeCallIndirect (
7185
7192
signature : Signature ,
7186
- indexArg : ExpressionRef ,
7193
+ functionArg : ExpressionRef ,
7187
7194
reportNode : Node ,
7188
7195
operands : ExpressionRef [ ] | null = null ,
7189
7196
immediatelyDropped : bool = false ,
@@ -7216,37 +7223,29 @@ export class Compiler extends DiagnosticEmitter {
7216
7223
}
7217
7224
}
7218
7225
7219
- if ( this . options . isWasm64 ) {
7220
- indexArg = module . unary ( UnaryOp . WrapI64 , indexArg ) ;
7221
- }
7222
-
7223
7226
// We might be calling a varargs stub here, even if all operands have been
7224
7227
// provided, so we must set `argumentsLength` in any case. Inject setting it
7225
7228
// into the index argument, which becomes executed last after any operands.
7226
7229
this . ensureArgumentsLength ( ) ;
7227
7230
var nativeSizeType = this . options . nativeSizeType ;
7228
- if ( getSideEffects ( indexArg ) & SideEffects . WritesGlobal ) {
7231
+ if ( getSideEffects ( functionArg ) & SideEffects . WritesGlobal ) {
7229
7232
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
7233
7236
module . global_set ( BuiltinNames . argumentsLength , module . i32 ( numArguments ) ) ,
7234
7237
module . local_get ( temp . index , nativeSizeType )
7235
7238
] , nativeSizeType ) ;
7236
7239
flow . freeTempLocal ( temp ) ;
7237
7240
} else { // simplify
7238
- indexArg = module . block ( null , [
7241
+ functionArg = module . block ( null , [
7239
7242
module . global_set ( BuiltinNames . argumentsLength , module . i32 ( numArguments ) ) ,
7240
- indexArg
7243
+ functionArg
7241
7244
] , nativeSizeType ) ;
7242
7245
}
7243
7246
if ( operands ) this . operandsTostack ( signature , operands ) ;
7244
7247
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
7250
7249
operands ,
7251
7250
signature . nativeParams ,
7252
7251
signature . nativeResults
0 commit comments