summaryrefslogtreecommitdiff
path: root/src/passes/FuncCastEmulation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/FuncCastEmulation.cpp')
-rw-r--r--src/passes/FuncCastEmulation.cpp34
1 files changed, 18 insertions, 16 deletions
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index ba6d1d583..9d232c9eb 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -28,6 +28,8 @@
// params must be identical, i.e., the "ABI" must match.
//
+#include <string>
+
#include <ir/literal-utils.h>
#include <pass.h>
#include <wasm-builder.h>
@@ -35,11 +37,6 @@
namespace wasm {
-// This should be enough for everybody. (As described above, we need this
-// to match when dynamically linking, and also dynamic linking is why we
-// can't just detect this automatically in the module we see.)
-static const int NUM_PARAMS = 16;
-
// Converts a value to the ABI type of i64.
static Expression* toABI(Expression* value, Module* module) {
Builder builder(*module);
@@ -133,20 +130,23 @@ struct ParallelFuncCastEmulation
: public WalkerPass<PostWalker<ParallelFuncCastEmulation>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new ParallelFuncCastEmulation(ABIType); }
+ Pass* create() override {
+ return new ParallelFuncCastEmulation(ABIType, numParams);
+ }
- ParallelFuncCastEmulation(Signature ABIType) : ABIType(ABIType) {}
+ ParallelFuncCastEmulation(Signature ABIType, Index numParams)
+ : ABIType(ABIType), numParams(numParams) {}
void visitCallIndirect(CallIndirect* curr) {
- if (curr->operands.size() > NUM_PARAMS) {
- Fatal() << "FuncCastEmulation::NUM_PARAMS needs to be at least "
+ if (curr->operands.size() > numParams) {
+ Fatal() << "max-func-params needs to be at least "
<< curr->operands.size();
}
for (Expression*& operand : curr->operands) {
operand = toABI(operand, getModule());
}
// Add extra operands as needed.
- while (curr->operands.size() < NUM_PARAMS) {
+ while (curr->operands.size() < numParams) {
curr->operands.push_back(LiteralUtils::makeZero(Type::i64, *getModule()));
}
// Set the new types
@@ -161,20 +161,22 @@ struct ParallelFuncCastEmulation
private:
// The signature of a call with the right params and return
Signature ABIType;
+ Index numParams;
};
struct FuncCastEmulation : public Pass {
void run(PassRunner* runner, Module* module) override {
+ 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>(NUM_PARAMS, Type::i64)),
- Type::i64);
+ Signature ABIType(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;
for (auto& segment : module->table.segments) {
for (auto& name : segment.data) {
auto iter = funcThunks.find(name);
if (iter == funcThunks.end()) {
- auto thunk = makeThunk(name, module);
+ auto thunk = makeThunk(name, module, numParams);
funcThunks[name] = thunk;
name = thunk;
} else {
@@ -183,12 +185,12 @@ struct FuncCastEmulation : public Pass {
}
}
// update call_indirects
- ParallelFuncCastEmulation(ABIType).run(runner, module);
+ ParallelFuncCastEmulation(ABIType, numParams).run(runner, module);
}
private:
// Creates a thunk for a function, casting args and return value as needed.
- Name makeThunk(Name name, Module* module) {
+ Name makeThunk(Name name, Module* module, Index numParams) {
Name thunk = std::string("byn$fpcast-emu$") + name.str;
if (module->getFunctionOrNull(thunk)) {
Fatal() << "FuncCastEmulation::makeThunk seems a thunk name already in "
@@ -206,7 +208,7 @@ private:
}
auto* call = builder.makeCall(name, callOperands, type);
std::vector<Type> thunkParams;
- for (Index i = 0; i < NUM_PARAMS; i++) {
+ for (Index i = 0; i < numParams; i++) {
thunkParams.push_back(Type::i64);
}
auto thunkFunc =