[dart2wasm] Add function type immediate to call_ref

The encoding uses the 0x17 opcode temporarily assigned to `call_ref`
with immediate in V8 and Binaryen for transitioning from `call_ref`
without immediate. After V8 and Binaryen change the proper 0x14
encoding to accepting an immediate, we can switch back to 0x14.

Change-Id: Ib84c62068e73a101d23a1bbd7eb3b893ef7a1493
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258802
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
Aske Simon Christensen 2022-10-28 16:25:58 +00:00 committed by Commit Queue
parent 982fe25bfa
commit c975c5c713
4 changed files with 15 additions and 23 deletions

View file

@ -435,7 +435,7 @@ class ClosureLayouter extends RecursiveVisitor {
b.struct_get(contextStruct, FieldIndex.instantiationContextInner);
b.struct_get(genericClosureStruct, FieldIndex.closureVtable);
b.struct_get(genericVtableStruct, genericVtableFieldIndex);
b.call_ref();
b.call_ref(genericFunctionType);
b.end();
return trampoline;

View file

@ -2136,10 +2136,13 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
// Call entry point in vtable
int vtableIndex =
representation.fieldIndexForSignature(posArgCount, argNames);
w.FunctionType functionType =
(representation.vtableStruct.fields[vtableIndex].type as w.RefType)
.heapType as w.FunctionType;
b.local_get(temp);
b.struct_get(struct, FieldIndex.closureVtable);
b.struct_get(representation.vtableStruct, vtableIndex);
b.call_ref();
b.call_ref(functionType);
return translator.topInfo.nullableType;
}
@ -2187,7 +2190,7 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
representation.vtableStruct, FieldIndex.vtableInstantiationFunction);
// Call instantiation function
b.call_ref();
b.call_ref(representation.instantiationFunctionType);
return representation.instantiationFunctionType.outputs.single;
} else {
// Only other alternative is `NeverType`.

View file

@ -1140,7 +1140,7 @@ class Intrinsifier {
codeGen.wrap(node.arguments.positional[i], functionType.inputs[i]);
}
b.local_get(temp);
b.call_ref();
b.call_ref(functionType);
return translator.outputOrVoid(functionType.outputs);
}
@ -1435,7 +1435,7 @@ class Intrinsifier {
b.local_get(args);
b.ref_cast(translator.functions.asyncStubBaseStruct);
b.struct_get(translator.functions.asyncStubBaseStruct, stubFieldIndex);
b.call_ref();
b.call_ref(translator.functions.asyncStubFunctionType);
return true;
}

View file

@ -533,25 +533,14 @@ class Instructions with SerializerMixin {
writeUnsigned(table?.index ?? 0);
}
bool _verifyCallRef() {
if (!reachable) {
return _debugTrace(const ['call_ref'], reachableAfter: false);
}
ValueType fun = _topOfStack;
if (fun is RefType) {
var heapType = fun.heapType;
if (heapType is FunctionType) {
return _verifyTypes([...heapType.inputs, fun], heapType.outputs,
trace: const ['call_ref']);
}
}
_reportError("Expected function type, got $fun");
}
/// Emit a `call_ref` instruction.
void call_ref() {
assert(_verifyCallRef());
writeByte(0x14);
void call_ref(FunctionType type) {
assert(_verifyTypes(
[...type.inputs, RefType.def(type, nullable: true)], type.outputs,
trace: ['call_ref', type]));
// TODO(askesc): Change to 0x14 when supported by both V8 and Binaryen.
writeByte(0x17);
writeUnsigned(type.index);
}
// Parametric instructions