Skip to content

Commit 0474456

Browse files
authored
fix: Fix non-usize first-class function arguments to be usize (#1669)
1 parent f95209b commit 0474456

File tree

2 files changed

+31
-32
lines changed

2 files changed

+31
-32
lines changed

src/builtins.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3277,7 +3277,7 @@ function builtin_function_call(ctx: BuiltinContext): ExpressionRef {
32773277
compiler.currentType = returnType;
32783278
return compiler.module.unreachable();
32793279
}
3280-
var indexArg = compiler.compileExpression(assert(ctx.thisOperand), ftype, Constraints.CONV_IMPLICIT);
3280+
var functionArg = compiler.compileExpression(assert(ctx.thisOperand), ftype, Constraints.CONV_IMPLICIT);
32813281
var thisOperand = assert(ctx.operands.shift());
32823282
var thisType = signature.thisType;
32833283
var thisArg: usize = 0;
@@ -3290,7 +3290,7 @@ function builtin_function_call(ctx: BuiltinContext): ExpressionRef {
32903290
);
32913291
return compiler.module.unreachable();
32923292
}
3293-
return compiler.compileCallIndirect(signature, indexArg, ctx.operands, ctx.reportNode, thisArg, ctx.contextualType == Type.void);
3293+
return compiler.compileCallIndirect(signature, functionArg, ctx.operands, ctx.reportNode, thisArg, ctx.contextualType == Type.void);
32943294
}
32953295
function_builtins.set("call", builtin_function_call);
32963296

src/compiler.ts

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)