binaryen
binaryen copied to clipboard
Extra pass for v128 operands in exported functions and globals?
At current moment, we can produce such code:
(func (export "a") $a (param $0 v128) (result v128) ;; [v128] -> [v128]
local.get $0
local.get $0
i32x4.mul
)
But web engines can't call functions with such signature. I'm not sure about standalone runtimes like wasmtime / wasmer, but web engines definitely not.
So I propose to add a new separate pass (at the end of pass pipeline) that would modify the code and the signature as follows:
(module
(memory $0 1)
;; reserve temp data for return value of $a
(data (i32.const 16) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
(func (export "a") $a (param $0 i32) (result i32) ;; [i32] -> [i32]
(local $1 v128)
i32.const 16
local.get $0
v128.load
local.tee $1
local.get $1
i32x4.mul
v128.store
i32.const 16
)
)
That is, now v128 values are stored and loaded from linear memory. WDYT?
This sounds like the issue we have with i64s. For them we have the legalization pass, LegalizeJSInterface
. Extending that for v128 would make sense.
Good idea. But it's probably better to isolate the common infra and move it to a separate header file, and utilize it by the two separate passes afterwards. As for me the most difficult part is the strategy for memory reservation, because the input and output v128 arguments can be up to 65k in theory and will probably need or reserve memory for the maximum number of v128 args in the signatures