summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-11-22 17:32:08 -0800
committerGitHub <noreply@github.com>2021-11-22 17:32:08 -0800
commit37999167bb333dd0b12d744af8e633897e65cff8 (patch)
tree4f70902c55b8fcd58c3793368c489111f519da30 /src
parent962ecc84cd12bce59d0b2f969aa71ecafbe38ca6 (diff)
downloadbinaryen-37999167bb333dd0b12d744af8e633897e65cff8.tar.gz
binaryen-37999167bb333dd0b12d744af8e633897e65cff8.tar.bz2
binaryen-37999167bb333dd0b12d744af8e633897e65cff8.zip
Change from storing Signature to HeapType on CallIndirect (#4352)
With nominal function types, this change makes it so that we preserve the identity of the function type used with call_indirect instructions rather than recreating a function heap type, which may or may not be the same as the originally parsed heap type, from the function signature during module writing. This will simplify the type system implementation by removing the need to store a "canonical" nominal heap type for each unique signature. We previously depended on those canonical types to avoid creating multiple duplicate function types during module writing, but now we aren't creating any new function types at all.
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp22
-rw-r--r--src/ir/ExpressionAnalyzer.cpp2
-rw-r--r--src/ir/ExpressionManipulator.cpp1
-rw-r--r--src/ir/branch-utils.h2
-rw-r--r--src/ir/iteration.h1
-rw-r--r--src/ir/module-splitting.cpp4
-rw-r--r--src/ir/module-utils.h2
-rw-r--r--src/ir/properties.h1
-rw-r--r--src/ir/type-updating.cpp2
-rw-r--r--src/passes/DeadArgumentElimination.cpp3
-rw-r--r--src/passes/Directize.cpp2
-rw-r--r--src/passes/FuncCastEmulation.cpp9
-rw-r--r--src/passes/GenerateDynCalls.cpp3
-rw-r--r--src/passes/I64ToI32Lowering.cpp4
-rw-r--r--src/passes/Inlining.cpp13
-rw-r--r--src/passes/OptimizeInstructions.cpp2
-rw-r--r--src/passes/Print.cpp2
-rw-r--r--src/shell-interface.h6
-rw-r--r--src/tools/fuzzing/fuzzing.cpp2
-rw-r--r--src/tools/wasm-ctor-eval.cpp4
-rw-r--r--src/wasm-builder.h7
-rw-r--r--src/wasm-delegations-fields.def9
-rw-r--r--src/wasm-interpreter.h4
-rw-r--r--src/wasm-traversal.h1
-rw-r--r--src/wasm.h14
-rw-r--r--src/wasm/wasm-binary.cpp5
-rw-r--r--src/wasm/wasm-s-parser.cpp2
-rw-r--r--src/wasm/wasm-stack.cpp3
-rw-r--r--src/wasm/wasm-validator.cpp14
-rw-r--r--src/wasm/wasm.cpp26
30 files changed, 65 insertions, 107 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 0a4b88a2b..6a25790ca 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -870,7 +870,7 @@ makeBinaryenCallIndirect(BinaryenModuleRef module,
for (BinaryenIndex i = 0; i < numOperands; i++) {
ret->operands.push_back((Expression*)operands[i]);
}
- ret->sig = Signature(Type(params), Type(results));
+ ret->heapType = Signature(Type(params), Type(results));
ret->type = Type(results);
ret->isReturn = isReturn;
ret->finalize();
@@ -1787,24 +1787,28 @@ void BinaryenCallIndirectSetReturn(BinaryenExpressionRef expr, bool isReturn) {
BinaryenType BinaryenCallIndirectGetParams(BinaryenExpressionRef expr) {
auto* expression = (Expression*)expr;
assert(expression->is<CallIndirect>());
- return static_cast<CallIndirect*>(expression)->sig.params.getID();
+ return static_cast<CallIndirect*>(expression)
+ ->heapType.getSignature()
+ .params.getID();
}
void BinaryenCallIndirectSetParams(BinaryenExpressionRef expr,
BinaryenType params) {
- auto* expression = (Expression*)expr;
- assert(expression->is<CallIndirect>());
- static_cast<CallIndirect*>(expression)->sig.params = Type(params);
+ auto* call = ((Expression*)expr)->cast<CallIndirect>();
+ call->heapType =
+ Signature(Type(params), call->heapType.getSignature().results);
}
BinaryenType BinaryenCallIndirectGetResults(BinaryenExpressionRef expr) {
auto* expression = (Expression*)expr;
assert(expression->is<CallIndirect>());
- return static_cast<CallIndirect*>(expression)->sig.results.getID();
+ return static_cast<CallIndirect*>(expression)
+ ->heapType.getSignature()
+ .results.getID();
}
void BinaryenCallIndirectSetResults(BinaryenExpressionRef expr,
BinaryenType results) {
- auto* expression = (Expression*)expr;
- assert(expression->is<CallIndirect>());
- static_cast<CallIndirect*>(expression)->sig.results = Type(results);
+ auto* call = ((Expression*)expr)->cast<CallIndirect>();
+ call->heapType =
+ Signature(call->heapType.getSignature().params, Type(results));
}
// LocalGet
BinaryenIndex BinaryenLocalGetGetIndex(BinaryenExpressionRef expr) {
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index c6b24beaa..a4b1efde1 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -192,7 +192,6 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
#define DELEGATE_FIELD_INT(id, field) COMPARE_FIELD(field)
#define DELEGATE_FIELD_LITERAL(id, field) COMPARE_FIELD(field)
#define DELEGATE_FIELD_NAME(id, field) COMPARE_FIELD(field)
-#define DELEGATE_FIELD_SIGNATURE(id, field) COMPARE_FIELD(field)
#define DELEGATE_FIELD_TYPE(id, field) COMPARE_FIELD(field)
#define DELEGATE_FIELD_HEAPTYPE(id, field) COMPARE_FIELD(field)
#define DELEGATE_FIELD_ADDRESS(id, field) COMPARE_FIELD(field)
@@ -314,7 +313,6 @@ struct Hasher {
#define DELEGATE_FIELD_INT(id, field) HASH_FIELD(field)
#define DELEGATE_FIELD_LITERAL(id, field) HASH_FIELD(field)
-#define DELEGATE_FIELD_SIGNATURE(id, field) HASH_FIELD(field)
#define DELEGATE_FIELD_NAME(id, field) visitNonScopeName(cast->field)
#define DELEGATE_FIELD_TYPE(id, field) visitType(cast->field);
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index e92efa925..55d170175 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -79,7 +79,6 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
#define DELEGATE_FIELD_NAME(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) COPY_FIELD(field)
-#define DELEGATE_FIELD_SIGNATURE(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_TYPE(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_HEAPTYPE(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_ADDRESS(id, field) COPY_FIELD(field)
diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h
index 25bfd9255..603b922fb 100644
--- a/src/ir/branch-utils.h
+++ b/src/ir/branch-utils.h
@@ -60,7 +60,6 @@ template<typename T> void operateOnScopeNameUses(Expression* expr, T func) {
#define DELEGATE_FIELD_NAME(id, field)
#define DELEGATE_FIELD_NAME_VECTOR(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
-#define DELEGATE_FIELD_SIGNATURE(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)
@@ -124,7 +123,6 @@ template<typename T> void operateOnScopeNameDefs(Expression* expr, T func) {
#define DELEGATE_FIELD_LITERAL(id, field)
#define DELEGATE_FIELD_NAME(id, field)
#define DELEGATE_FIELD_NAME_VECTOR(id, field)
-#define DELEGATE_FIELD_SIGNATURE(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)
diff --git a/src/ir/iteration.h b/src/ir/iteration.h
index 6574e5dff..e897c51a5 100644
--- a/src/ir/iteration.h
+++ b/src/ir/iteration.h
@@ -104,7 +104,6 @@ public:
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
-#define DELEGATE_FIELD_SIGNATURE(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index 2ef9f505d..2028db13f 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -407,7 +407,7 @@ void ModuleSplitter::thunkExportedSecondaryFunctions() {
}
auto tableSlot = tableManager.getSlot(secondaryFunc, func->type);
func->body = builder.makeCallIndirect(
- tableSlot.tableName, tableSlot.makeExpr(primary), args, func->getSig());
+ tableSlot.tableName, tableSlot.makeExpr(primary), args, func->type);
}
}
@@ -431,7 +431,7 @@ void ModuleSplitter::indirectCallsToSecondaryFunctions() {
builder.makeCallIndirect(tableSlot.tableName,
tableSlot.makeExpr(parent.primary),
curr->operands,
- func->getSig(),
+ func->type,
curr->isReturn));
}
void visitRefFunc(RefFunc* curr) {
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index 69c454410..d37457e96 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -494,7 +494,7 @@ inline void collectHeapTypes(Module& wasm,
void visitExpression(Expression* curr) {
if (auto* call = curr->dynCast<CallIndirect>()) {
- counts.note(call->getHeapType(getModule()));
+ counts.note(call->heapType);
} else if (curr->is<RefNull>()) {
counts.note(curr->type);
} else if (curr->is<RttCanon>() || curr->is<RttSub>()) {
diff --git a/src/ir/properties.h b/src/ir/properties.h
index f111d555f..92f1bda66 100644
--- a/src/ir/properties.h
+++ b/src/ir/properties.h
@@ -338,7 +338,6 @@ inline Index getNumChildren(Expression* curr) {
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
-#define DELEGATE_FIELD_SIGNATURE(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)
diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp
index 0d579367f..998e12ebb 100644
--- a/src/ir/type-updating.cpp
+++ b/src/ir/type-updating.cpp
@@ -147,8 +147,6 @@ void GlobalTypeRewriter::update() {
#define DELEGATE_FIELD_HEAPTYPE(id, field) cast->field = getNew(cast->field);
-#define DELEGATE_FIELD_SIGNATURE(id, field) cast->field = getNew(cast->field);
-
#define DELEGATE_FIELD_CHILD(id, field)
#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)
#define DELEGATE_FIELD_INT(id, field)
diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp
index b7ce5ef5f..b6694c514 100644
--- a/src/passes/DeadArgumentElimination.cpp
+++ b/src/passes/DeadArgumentElimination.cpp
@@ -669,7 +669,8 @@ private:
}
}
for (auto* call : FindAll<CallIndirect>(func->body).list) {
- if (call->isReturn && !processReturnType(call->sig.results)) {
+ if (call->isReturn &&
+ !processReturnType(call->heapType.getSignature().results)) {
return false;
}
}
diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp
index b0236e32e..1dd05e934 100644
--- a/src/passes/Directize.cpp
+++ b/src/passes/Directize.cpp
@@ -153,7 +153,7 @@ private:
return replaceWithUnreachable(operands);
}
auto* func = getModule()->getFunction(name);
- if (original->sig != func->getSig()) {
+ if (original->heapType != func->type) {
return replaceWithUnreachable(operands);
}
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index d8b9f9b1d..2d7bdad54 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -136,7 +136,7 @@ struct ParallelFuncCastEmulation
return new ParallelFuncCastEmulation(ABIType, numParams);
}
- ParallelFuncCastEmulation(Signature ABIType, Index numParams)
+ ParallelFuncCastEmulation(HeapType ABIType, Index numParams)
: ABIType(ABIType), numParams(numParams) {}
void visitCallIndirect(CallIndirect* curr) {
@@ -152,7 +152,7 @@ struct ParallelFuncCastEmulation
curr->operands.push_back(LiteralUtils::makeZero(Type::i64, *getModule()));
}
// Set the new types
- curr->sig = ABIType;
+ curr->heapType = ABIType;
auto oldType = curr->type;
curr->type = Type::i64;
curr->finalize(); // may be unreachable
@@ -162,7 +162,7 @@ struct ParallelFuncCastEmulation
private:
// The signature of a call with the right params and return
- Signature ABIType;
+ HeapType ABIType;
Index numParams;
};
@@ -171,7 +171,8 @@ struct FuncCastEmulation : public Pass {
Index numParams =
std::stoul(runner->options.getArgumentOrDefault("max-func-params", "16"));
// we just need the one ABI function type for all indirect calls
- Signature ABIType(Type(std::vector<Type>(numParams, Type::i64)), Type::i64);
+ HeapType ABIType(
+ Signature(Type(std::vector<Type>(numParams, Type::i64)), Type::i64));
// Add a thunk for each function in the table, and do the call through it.
std::unordered_map<Name, Name> funcThunks;
ElementUtils::iterAllElementFunctionNames(module, [&](Name& name) {
diff --git a/src/passes/GenerateDynCalls.cpp b/src/passes/GenerateDynCalls.cpp
index 2487085c0..5498c91e3 100644
--- a/src/passes/GenerateDynCalls.cpp
+++ b/src/passes/GenerateDynCalls.cpp
@@ -152,7 +152,8 @@ void GenerateDynCalls::generateDynCallThunk(HeapType funcType) {
table->module = ENV;
table->base = "__indirect_function_table";
}
- f->body = builder.makeCallIndirect(wasm->tables[0]->name, fptr, args, sig);
+ f->body =
+ builder.makeCallIndirect(wasm->tables[0]->name, fptr, args, funcType);
wasm->addFunction(std::move(f));
exportFunction(*wasm, name, true);
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index 9b516342d..7a07d946b 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -267,14 +267,14 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitCallIndirect(CallIndirect* curr) {
- if (curr->isReturn && curr->sig.results == Type::i64) {
+ if (curr->isReturn && curr->heapType.getSignature().results == Type::i64) {
Fatal()
<< "i64 to i32 lowering of return_call values not yet implemented";
}
visitGenericCall<CallIndirect>(
curr, [&](std::vector<Expression*>& args, Type results) {
std::vector<Type> params;
- for (const auto& param : curr->sig.params) {
+ for (const auto& param : curr->heapType.getSignature().params) {
if (param == Type::i64) {
params.push_back(Type::i32);
params.push_back(Type::i32);
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 0360974f0..a79968c92 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -255,10 +255,10 @@ struct Updater : public PostWalker<Updater> {
// achieve this, make the call a non-return call and add a break. This does
// not cause unbounded stack growth because inlining and return calling both
// avoid creating a new stack frame.
- template<typename T> void handleReturnCall(T* curr, Type targetType) {
+ template<typename T> void handleReturnCall(T* curr, HeapType targetType) {
curr->isReturn = false;
- curr->type = targetType;
- if (targetType.isConcrete()) {
+ curr->type = targetType.getSignature().results;
+ if (curr->type.isConcrete()) {
replaceCurrent(builder->makeBreak(returnName, curr));
} else {
replaceCurrent(builder->blockify(curr, builder->makeBreak(returnName)));
@@ -266,18 +266,17 @@ struct Updater : public PostWalker<Updater> {
}
void visitCall(Call* curr) {
if (curr->isReturn) {
- handleReturnCall(curr, module->getFunction(curr->target)->getResults());
+ handleReturnCall(curr, module->getFunction(curr->target)->type);
}
}
void visitCallIndirect(CallIndirect* curr) {
if (curr->isReturn) {
- handleReturnCall(curr, curr->sig.results);
+ handleReturnCall(curr, curr->heapType);
}
}
void visitCallRef(CallRef* curr) {
if (curr->isReturn) {
- handleReturnCall(curr,
- curr->target->type.getHeapType().getSignature().results);
+ handleReturnCall(curr, curr->target->type.getHeapType());
}
}
void visitLocalGet(LocalGet* curr) {
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index aa3de46e8..2cbb28c66 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1253,7 +1253,7 @@ struct OptimizeInstructions
.makeCallIndirect(get->table,
get->index,
curr->operands,
- get->type.getHeapType().getSignature(),
+ get->type.getHeapType(),
curr->isReturn));
return;
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 3476199d6..33d817326 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -436,7 +436,7 @@ struct PrintExpressionContents
o << '(';
printMinor(o, "type ");
- TypeNamePrinter(o, wasm).print(curr->getHeapType(wasm));
+ TypeNamePrinter(o, wasm).print(curr->heapType);
o << ')';
}
diff --git a/src/shell-interface.h b/src/shell-interface.h
index 6c6ddf7f2..8c3109787 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -152,7 +152,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
Literals callTable(Name tableName,
Index index,
- Signature sig,
+ HeapType sig,
LiteralList& arguments,
Type results,
ModuleInstance& instance) override {
@@ -173,8 +173,8 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
if (!func) {
trap("uninitialized table element");
}
- if (sig != func->getSig()) {
- trap("callIndirect: function signatures don't match");
+ if (sig != func->type) {
+ trap("callIndirect: function types don't match");
}
if (func->getParams().size() != arguments.size()) {
trap("callIndirect: bad # of arguments");
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 84b0e2c5c..8194c52d3 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -1260,7 +1260,7 @@ Expression* TranslateToFuzzReader::makeCallIndirect(Type type) {
}
// TODO: use a random table
return builder.makeCallIndirect(
- funcrefTableName, target, args, targetFn->getSig(), isReturn);
+ funcrefTableName, target, args, targetFn->type, isReturn);
}
Expression* TranslateToFuzzReader::makeCallRef(Type type) {
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 54324ae5a..701968dcd 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -282,7 +282,7 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
Literals callTable(Name tableName,
Index index,
- Signature sig,
+ HeapType sig,
LiteralList& arguments,
Type result,
EvallingModuleInstance& instance) override {
@@ -322,7 +322,7 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
// if this is one of our functions, we can call it; if it was
// imported, fail
auto* func = wasm->getFunction(name);
- if (func->getSig() != sig) {
+ if (func->type != sig) {
throw FailToEvalException(
std::string("callTable signature mismatch: ") + name.str);
}
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 5914a8afd..a66322eb4 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -273,12 +273,13 @@ public:
CallIndirect* makeCallIndirect(const Name table,
Expression* target,
const T& args,
- Signature sig,
+ HeapType heapType,
bool isReturn = false) {
+ assert(heapType.isSignature());
auto* call = wasm.allocator.alloc<CallIndirect>();
call->table = table;
- call->sig = sig;
- call->type = sig.results;
+ call->heapType = heapType;
+ call->type = heapType.getSignature().results;
call->target = target;
call->operands.set(args);
call->isReturn = isReturn;
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index d1a2e1b83..3d7504c60 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -72,8 +72,6 @@
// and DELEGATE_GET_FIELD is, then DELEGATE_FIELD_SCOPE_NAME_USE is called on
// them.
//
-// DELEGATE_FIELD_SIGNATURE(id, field) - called for a Signature.
-//
// DELEGATE_FIELD_TYPE(id, field) - called for a Type.
//
// DELEGATE_FIELD_HEAPTYPE(id, field) - called for a HeapType.
@@ -160,10 +158,6 @@
#endif
#endif
-#ifndef DELEGATE_FIELD_SIGNATURE
-#error please define DELEGATE_FIELD_SIGNATURE(id, field)
-#endif
-
#ifndef DELEGATE_FIELD_TYPE
#error please define DELEGATE_FIELD_TYPE(id, field)
#endif
@@ -233,7 +227,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(CallIndirect, target);
DELEGATE_FIELD_NAME(CallIndirect, table);
DELEGATE_FIELD_CHILD_VECTOR(CallIndirect, operands);
- DELEGATE_FIELD_SIGNATURE(CallIndirect, sig);
+ DELEGATE_FIELD_HEAPTYPE(CallIndirect, heapType);
DELEGATE_FIELD_INT(CallIndirect, isReturn);
DELEGATE_END(CallIndirect);
break;
@@ -733,7 +727,6 @@ switch (DELEGATE_ID) {
#undef DELEGATE_FIELD_SCOPE_NAME_DEF
#undef DELEGATE_FIELD_SCOPE_NAME_USE
#undef DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR
-#undef DELEGATE_FIELD_SIGNATURE
#undef DELEGATE_FIELD_TYPE
#undef DELEGATE_FIELD_HEAPTYPE
#undef DELEGATE_FIELD_ADDRESS
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 7eb13c002..caccef654 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -2313,7 +2313,7 @@ public:
virtual Literals callImport(Function* import, LiteralList& arguments) = 0;
virtual Literals callTable(Name tableName,
Index index,
- Signature sig,
+ HeapType sig,
LiteralList& arguments,
Type result,
SubType& instance) = 0;
@@ -2770,7 +2770,7 @@ private:
auto info = instance.getTableInterfaceInfo(curr->table);
Flow ret = info.interface->callTable(
- info.name, index, curr->sig, arguments, type, *instance.self());
+ info.name, index, curr->heapType, arguments, type, *instance.self());
// TODO: make this a proper tail call (return first)
if (curr->isReturn) {
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index 201cc95fa..7a803e2b2 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -371,7 +371,6 @@ struct PostWalker : public Walker<SubType, VisitorType> {
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
-#define DELEGATE_FIELD_SIGNATURE(id, field)
#define DELEGATE_FIELD_TYPE(id, field)
#define DELEGATE_FIELD_HEAPTYPE(id, field)
#define DELEGATE_FIELD_ADDRESS(id, field)
diff --git a/src/wasm.h b/src/wasm.h
index 4e981935e..18662ad8e 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -579,9 +579,6 @@ enum BrOnOp {
BrOnNonI31,
};
-// Forward declaration for methods that receive a Module as a parameter.
-class Module;
-
//
// Expressions
//
@@ -849,22 +846,13 @@ public:
class CallIndirect : public SpecificExpression<Expression::CallIndirectId> {
public:
CallIndirect(MixedArena& allocator) : operands(allocator) {}
- Signature sig;
+ HeapType heapType;
ExpressionList operands;
Expression* target;
Name table;
bool isReturn = false;
void finalize();
-
- // FIXME We should probably store a heap type here, and not a signature, see
- // https://github.com/WebAssembly/binaryen/issues/4220
- // For now, copy the heap type from the table if it matches - then a
- // nominal check will succeed too. If it does not match, then just
- // emit something for it like we always used to, using
- // HeapType(sig) (also do that if no module is provided).
- // FIXME When we remove this, also remove the forward decl of Module, above.
- HeapType getHeapType(Module* module = nullptr);
};
class LocalGet : public SpecificExpression<Expression::LocalGetId> {
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 0ccb9d6db..74036d748 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -4057,9 +4057,10 @@ void WasmBinaryBuilder::visitCall(Call* curr) {
void WasmBinaryBuilder::visitCallIndirect(CallIndirect* curr) {
BYN_TRACE("zz node: CallIndirect\n");
auto index = getU32LEB();
- curr->sig = getSignatureByTypeIndex(index);
+ curr->heapType = getTypeByIndex(index);
Index tableIdx = getU32LEB();
- auto num = curr->sig.params.size();
+ // TODO: Handle error cases where `heapType` is not a signature?
+ auto num = curr->heapType.getSignature().params.size();
curr->operands.resize(num);
curr->target = popNonVoidExpression();
for (size_t i = 0; i < num; i++) {
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 1e15c1faa..d9c35d97c 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2313,7 +2313,7 @@ Expression* SExpressionWasmBuilder::makeCallIndirect(Element& s,
}
HeapType callType;
i = parseTypeUse(s, i, callType);
- ret->sig = callType.getSignature();
+ ret->heapType = callType;
parseCallOperands(s, i, s.size() - 1, ret);
ret->target = parseExpression(s[s.size() - 1]);
ret->isReturn = isReturn;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 59398839e..adb9341b0 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -83,8 +83,7 @@ void BinaryInstWriter::visitCallIndirect(CallIndirect* curr) {
Index tableIdx = parent.getTableIndex(curr->table);
int8_t op =
curr->isReturn ? BinaryConsts::RetCallIndirect : BinaryConsts::CallIndirect;
- o << op << U32LEB(parent.getTypeIndex(curr->getHeapType(parent.getModule())))
- << U32LEB(tableIdx);
+ o << op << U32LEB(parent.getTypeIndex(curr->heapType)) << U32LEB(tableIdx);
}
void BinaryInstWriter::visitLocalGet(LocalGet* curr) {
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 696c50d8b..8cf456409 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -445,7 +445,12 @@ private:
}
template<typename T>
- void validateCallParamsAndResult(T* curr, Signature sig) {
+ void validateCallParamsAndResult(T* curr, HeapType sigType) {
+ if (!shouldBeTrue(
+ sigType.isSignature(), curr, "Heap type must be a signature type")) {
+ return;
+ }
+ auto sig = sigType.getSignature();
if (!shouldBeTrue(curr->operands.size() == sig.params.size(),
curr,
"call* param number must match")) {
@@ -792,7 +797,7 @@ void FunctionValidator::visitCall(Call* curr) {
if (!shouldBeTrue(!!target, curr, "call target must exist")) {
return;
}
- validateCallParamsAndResult(curr, target->getSig());
+ validateCallParamsAndResult(curr, target->type);
}
void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
@@ -812,7 +817,7 @@ void FunctionValidator::visitCallIndirect(CallIndirect* curr) {
}
}
- validateCallParamsAndResult(curr, curr->sig);
+ validateCallParamsAndResult(curr, curr->heapType);
}
void FunctionValidator::visitConst(Const* curr) {
@@ -2322,8 +2327,7 @@ void FunctionValidator::visitCallRef(CallRef* curr) {
shouldBeTrue(curr->target->type.isFunction(),
curr,
"call_ref target must be a function reference");
- validateCallParamsAndResult(
- curr, curr->target->type.getHeapType().getSignature());
+ validateCallParamsAndResult(curr, curr->target->type.getHeapType());
}
}
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index fd3cec8d8..d220b7162 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -290,7 +290,7 @@ void Call::finalize() {
}
void CallIndirect::finalize() {
- type = sig.results;
+ type = heapType.getSignature().results;
handleUnreachableOperands(this);
if (isReturn) {
type = Type::unreachable;
@@ -300,30 +300,6 @@ void CallIndirect::finalize() {
}
}
-HeapType CallIndirect::getHeapType(Module* module) {
- auto heapType = HeapType(sig);
- // See comment in wasm.h
- if (module) {
- // The table may not yet exist if the wasm module is still being
- // constructed. This should perhaps be an error, but as this is a hack for
- // the time being, handle this the same as the case where module is null.
- // Note: table_ (with underscore) is needed as |table| is a field on |this|.
- if (auto* table_ = module->getTableOrNull(table)) {
- // The wasm spec may allow more things eventually, and if so we'd need to
- // add more checking here.
- assert(table_->type.isRef());
- auto tableHeapType = table_->type.getHeapType();
- if (tableHeapType.isSignature()) {
- auto tableSig = tableHeapType.getSignature();
- if (sig == tableSig) {
- heapType = tableHeapType;
- }
- }
- }
- }
- return heapType;
-}
-
bool LocalSet::isTee() const { return type != Type::none; }
// Changes to local.tee. The type of the local should be given.