Open TerrorJack opened 6 years ago
The i64
to i32
lowering hacks which either passes two parameters or uses a global for higher 32-bits are overly complicated for our use cases. Simpler solution: pass raw bit patterns in f64
instead, so we won't lose higher 32 bits, nor do we need to rely on any global state for function calls.
We now pass i64
as f64
for FFI. Closing this issue for now, since fully transparent handling based on a Module -> Module
rewriting is another pile of work and should be scheduled later.
https://bugs.chromium.org/p/v8/issues/detail?id=7741#c8
Finally, V8 guys have made the move!
We won't remove the current hacks immediately since it takes some time for V8's changes to propagate to node.js/chrome, but still worth celebrating.
Revisiting this issue after one year:
--experimental-wasm-bigint
landed in V8 but is still off by default. For SpiderMonkey it seems to be a work in progress. So other than "debug mode" we still need to assume the absence of wasm bigint integration for now.
We need this asap for #358. The i64
hash values aren't safe to be assumed to stay within Number.MAX_SAFE_INTEGER
range. While we can risk a reinterpret cast or use a global buffer for casting, the real solution IMO is fixing this old issue, and use vanilla i64 parameters & return values in our imported & exported functions.
Reopening this issue since it's relevant again today.
The C
/C++
and Rust
folks should face a similar challenge. The existing solution seems to be:
emscripten
: the parameters are turned to a pair of i32
s, the result to a temporary i32
which is a handle to extract the higher/lower 32-bits, see https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-pass-int64-t-and-uint64-t-values-from-js-into-wasm-functionswasm-bindgen
: parameters are passed on a "global stack" which is a fixed-length static memory region, see https://rustwasm.github.io/docs/wasm-bindgen/contributing/design/rust-type-conversions.html#global-stackI have yet to find some clang
compiled wasi
target executables for further investigation. Anyway we should make our solution close to the existing ABIs, to prepare for future introduction of the clang
toolchain and cbits
support.
Currently, WebAssembly as in spec/V8 doesn't support passing
i64
across WebAssembly/JavaScript boundary, and thei64
viaBigInt
proposal isn't landing anytime soon. Before we properly generate 32-bit code (which is going to be a standalone issue later), we still need to polyfill this feature.Previously, there are multiple different workarounds co-existing in asterius:
i64
from wasm to js. SeeAsterius.JSFFI
Asterius.Builtins
)i64
from wasm to js, we pass the higher/lower 32-bits as two parameters, and re-assemble at the other end. SeeAsterius.Builtins.cutI64
.For more reliable code generation, i64 FFI should be handled in a transparent & uniform manner:
__asterius_*_wrapper
function exist here.i64
viaBigInt
proposal, we can remove the wrappers and behavior of generated code shouldn't change.