diff options
Diffstat (limited to 'src/passes/FuncCastEmulation.cpp')
-rw-r--r-- | src/passes/FuncCastEmulation.cpp | 34 |
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 = |