Skip to content
8 changes: 4 additions & 4 deletions src/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2898,7 +2898,7 @@ function builtin_call_indirect(ctx: BuiltinContext): ExpressionRef {
} else {
returnType = ctx.contextualType;
}
var indexArg = compiler.compileExpression(operands[0], Type.u32, Constraints.CONV_IMPLICIT);
var tableIndexExpr = compiler.compileExpression(operands[0], Type.u32, Constraints.CONV_IMPLICIT);
var numOperands = operands.length - 1;
var operandExprs = new Array<ExpressionRef>(numOperands);
var nativeParamTypes = new Array<NativeType>(numOperands);
Expand All @@ -2907,7 +2907,7 @@ function builtin_call_indirect(ctx: BuiltinContext): ExpressionRef {
nativeParamTypes[i] = compiler.currentType.toNativeType();
}
compiler.currentType = returnType;
return module.call_indirect(indexArg, operandExprs, createType(nativeParamTypes), returnType.toNativeType());
return module.call_indirect(tableIndexExpr, operandExprs, createType(nativeParamTypes), returnType.toNativeType());
}
builtins.set(BuiltinNames.call_indirect, builtin_call_indirect);

Expand Down Expand Up @@ -2997,7 +2997,7 @@ function builtin_function_call(ctx: BuiltinContext): ExpressionRef {
compiler.currentType = returnType;
return compiler.module.unreachable();
}
var indexArg = compiler.compileExpression(assert(ctx.thisOperand), ftype, Constraints.CONV_IMPLICIT);
var functionPointer = compiler.compileExpression(assert(ctx.thisOperand), ftype, Constraints.CONV_IMPLICIT);
var thisOperand = assert(ctx.operands.shift());
var thisType = signature.thisType;
var thisArg: usize = 0;
Expand All @@ -3010,7 +3010,7 @@ function builtin_function_call(ctx: BuiltinContext): ExpressionRef {
);
return compiler.module.unreachable();
}
return compiler.compileCallIndirect(signature, indexArg, ctx.operands, ctx.reportNode, thisArg, ctx.contextualType == Type.void);
return compiler.compileCallIndirect(signature, functionPointer, ctx.operands, ctx.reportNode, thisArg, ctx.contextualType == Type.void);
}
function_builtins.set("call", builtin_function_call);

Expand Down
56 changes: 28 additions & 28 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6668,7 +6668,7 @@ export class Compiler extends DiagnosticEmitter {
var thisExpression = this.resolver.currentThisExpression;

var signature: Signature | null;
var indexArg: ExpressionRef;
var functionPointerExpr: ExpressionRef;
switch (target.kind) {

// direct call: concrete function
Expand All @@ -6678,23 +6678,23 @@ export class Compiler extends DiagnosticEmitter {
// builtins handle present respectively omitted type arguments on their own
return this.compileCallExpressionBuiltin(functionPrototype, expression, contextualType);
}
let functionInstance = this.resolver.maybeInferCall(expression, functionPrototype, flow);
if (!functionInstance) return this.module.unreachable();
target = functionInstance;
let functionPointerExpr = this.resolver.maybeInferCall(expression, functionPrototype, flow);
if (!functionPointerExpr) return this.module.unreachable();
target = functionPointerExpr;
// fall-through
}
case ElementKind.FUNCTION: {
let functionInstance = <Function>target;
let functionPointerExpr = <Function>target;
let thisArg: ExpressionRef = 0;
if (functionInstance.is(CommonFlags.INSTANCE)) {
if (functionPointerExpr.is(CommonFlags.INSTANCE)) {
thisArg = this.compileExpression(
assert(thisExpression),
assert(functionInstance.signature.thisType),
assert(functionPointerExpr.signature.thisType),
Constraints.CONV_IMPLICIT | Constraints.IS_THIS
);
}
return this.compileCallDirect(
functionInstance,
functionPointerExpr,
expression.args,
expression,
thisArg,
Expand All @@ -6708,9 +6708,9 @@ export class Compiler extends DiagnosticEmitter {
signature = local.type.signatureReference;
if (signature) {
if (local.is(CommonFlags.INLINED)) {
indexArg = module.i32(i64_low(local.constantIntegerValue));
functionPointerExpr = module.i32(i64_low(local.constantIntegerValue));
} else {
indexArg = module.local_get(local.index, NativeType.I32);
functionPointerExpr = module.local_get(local.index, NativeType.I32);
}
break;
}
Expand All @@ -6724,7 +6724,7 @@ export class Compiler extends DiagnosticEmitter {
let global = <Global>target;
signature = global.type.signatureReference;
if (signature) {
indexArg = module.global_get(global.internalName, global.type.toNativeType());
functionPointerExpr = module.global_get(global.internalName, global.type.toNativeType());
break;
}
this.error(
Expand All @@ -6740,7 +6740,7 @@ export class Compiler extends DiagnosticEmitter {
if (signature) {
let fieldParent = fieldInstance.parent;
assert(fieldParent.kind == ElementKind.CLASS);
indexArg = module.load(4, false,
functionPointerExpr = module.load(4, false,
this.compileExpression(
assert(thisExpression),
(<Class>fieldParent).type,
Expand Down Expand Up @@ -6775,7 +6775,7 @@ export class Compiler extends DiagnosticEmitter {
Constraints.CONV_IMPLICIT | Constraints.IS_THIS
);
}
indexArg = this.compileCallDirect(getterInstance, [], expression.expression, thisArg);
functionPointerExpr = this.compileCallDirect(getterInstance, [], expression.expression, thisArg);
signature = this.currentType.signatureReference;
if (!signature) {
this.error(
Expand All @@ -6792,7 +6792,7 @@ export class Compiler extends DiagnosticEmitter {
if (typeArguments !== null && typeArguments.length > 0) {
let ftype = typeArguments[0];
signature = ftype.getSignature();
indexArg = this.compileExpression(expression.expression, ftype, Constraints.CONV_IMPLICIT);
functionPointerExpr = this.compileExpression(expression.expression, ftype, Constraints.CONV_IMPLICIT);
break;
}
// fall-through
Expand All @@ -6817,7 +6817,7 @@ export class Compiler extends DiagnosticEmitter {
}
return this.compileCallIndirect(
assert(signature), // FIXME: bootstrap can't see this yet
indexArg,
functionPointerExpr,
expression.args,
expression,
0,
Expand Down Expand Up @@ -7973,7 +7973,7 @@ export class Compiler extends DiagnosticEmitter {
/** Compiles an indirect call using an index argument and a signature. */
compileCallIndirect(
signature: Signature,
indexArg: ExpressionRef,
functionPointerExpr: ExpressionRef,
argumentExpressions: Expression[],
reportNode: Node,
thisArg: ExpressionRef = 0,
Expand Down Expand Up @@ -8004,13 +8004,13 @@ export class Compiler extends DiagnosticEmitter {
);
}
assert(index == numArgumentsInclThis);
return this.makeCallIndirect(signature, indexArg, reportNode, operands, immediatelyDropped);
return this.makeCallIndirect(signature, functionPointerExpr, reportNode, operands, immediatelyDropped);
}

/** Creates an indirect call to the function at `indexArg` in the function table. */
/** Creates an indirect call to the first class function pointed to by `functionPointer`. */
makeCallIndirect(
signature: Signature,
indexArg: ExpressionRef,
functionPointerExpr: ExpressionRef,
reportNode: Node,
operands: ExpressionRef[] | null = null,
immediatelyDropped: bool = false,
Expand Down Expand Up @@ -8044,35 +8044,35 @@ export class Compiler extends DiagnosticEmitter {
}

if (this.options.isWasm64) {
indexArg = module.unary(UnaryOp.WrapI64, indexArg);
functionPointerExpr = module.unary(UnaryOp.WrapI64, functionPointerExpr);
}

// We might be calling a varargs stub here, even if all operands have been
// provided, so we must set `argumentsLength` in any case. Inject setting it
// into the index argument, which becomes executed last after any operands.
this.ensureArgumentsLength();
var nativeSizeType = this.options.nativeSizeType;
if (getSideEffects(indexArg) & SideEffects.WritesGlobal) {
if (getSideEffects(functionPointerExpr) & SideEffects.WritesGlobal) {
let flow = this.currentFlow;
let temp = flow.getTempLocal(this.options.usizeType, findUsedLocals(indexArg));
indexArg = module.block(null, [
module.local_set(temp.index, indexArg),
let temp = flow.getTempLocal(this.options.usizeType, findUsedLocals(functionPointerExpr));
functionPointerExpr = module.block(null, [
module.local_set(temp.index, functionPointerExpr),
module.global_set(BuiltinNames.argumentsLength, module.i32(numArguments)),
module.local_get(temp.index, nativeSizeType)
], nativeSizeType);
flow.freeTempLocal(temp);
} else { // simplify
indexArg = module.block(null, [
functionPointerExpr = module.block(null, [
module.global_set(BuiltinNames.argumentsLength, module.i32(numArguments)),
indexArg
functionPointerExpr
], nativeSizeType);
}
var expr = module.call_indirect(
nativeSizeType == NativeType.I64
? module.unary(UnaryOp.WrapI64,
module.load(8, false, indexArg, NativeType.I64)
module.load(8, false, functionPointerExpr, NativeType.I64)
)
: module.load(4, false, indexArg, NativeType.I32),
: module.load(4, false, functionPointerExpr, NativeType.I32),
operands,
signature.nativeParams,
signature.nativeResults
Expand Down