summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/passes/FuncCastEmulation.cpp34
-rw-r--r--test/passes/fpcast-emu_pass-arg=max-func-params@5.txt43
-rw-r--r--test/passes/fpcast-emu_pass-arg=max-func-params@5.wast14
4 files changed, 77 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1d6edfac3..27a097a76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,8 @@ Current Trunk
- Remove old/broken SpollPointers pass. This pass: Spills values that might be
pointers to the C stack. This allows Boehm-style GC to see them properly.
This can be revived if needed from git history (#3261).
+- Make `NUM_PARAMS` in `FuncCastEmulation` a runtime configuration option named
+ `max-func-params`. This defaults to the original value of 16.
v98
---
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 =
diff --git a/test/passes/fpcast-emu_pass-arg=max-func-params@5.txt b/test/passes/fpcast-emu_pass-arg=max-func-params@5.txt
new file mode 100644
index 000000000..4382aaca0
--- /dev/null
+++ b/test/passes/fpcast-emu_pass-arg=max-func-params@5.txt
@@ -0,0 +1,43 @@
+(module
+ (type $i64_i64_i64_i64_i64_=>_i64 (func (param i64 i64 i64 i64 i64) (result i64)))
+ (type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64)))
+ (table $0 10 10 funcref)
+ (elem (i32.const 0) $byn$fpcast-emu$a)
+ (func $a (param $x i32) (param $y i64) (param $z f32) (param $w f64)
+ (drop
+ (call_indirect (type $i64_i64_i64_i64_i64_=>_i64)
+ (i64.extend_i32_u
+ (i32.const 1)
+ )
+ (i64.const 2)
+ (i64.extend_i32_u
+ (i32.reinterpret_f32
+ (f32.const 3)
+ )
+ )
+ (i64.reinterpret_f64
+ (f64.const 4)
+ )
+ (i64.const 0)
+ (i32.const 1337)
+ )
+ )
+ )
+ (func $byn$fpcast-emu$a (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (result i64)
+ (call $a
+ (i32.wrap_i64
+ (local.get $0)
+ )
+ (local.get $1)
+ (f32.reinterpret_i32
+ (i32.wrap_i64
+ (local.get $2)
+ )
+ )
+ (f64.reinterpret_i64
+ (local.get $3)
+ )
+ )
+ (i64.const 0)
+ )
+)
diff --git a/test/passes/fpcast-emu_pass-arg=max-func-params@5.wast b/test/passes/fpcast-emu_pass-arg=max-func-params@5.wast
new file mode 100644
index 000000000..b1b0369c4
--- /dev/null
+++ b/test/passes/fpcast-emu_pass-arg=max-func-params@5.wast
@@ -0,0 +1,14 @@
+(module
+ (type $vijfd (func (param i32) (param i64) (param f32) (param f64)))
+ (table 10 10 funcref)
+ (elem (i32.const 0) $a)
+ (func $a (param $x i32) (param $y i64) (param $z f32) (param $w f64)
+ (call_indirect (type $vijfd)
+ (i32.const 1)
+ (i64.const 2)
+ (f32.const 3)
+ (f64.const 4)
+ (i32.const 1337)
+ )
+ )
+)