1# Deterministic Wasm Execution 2 3The WebAssembly language is *mostly* deterministic, but there are a few places 4where non-determinism slips in. This page documents how to use Wasmtime to 5execute Wasm programs fully deterministically, even when the Wasm language spec 6allows for non-determinism. 7 8## Make Sure All Imports are Deterministic 9 10Do not give Wasm programs access to non-deterministic host functions. 11 12When using WASI, use 13[`wasi-virt`](https://github.com/bytecodealliance/WASI-Virt) to virtualize 14non-deterministic APIs like clocks and file systems. 15 16## Enable IEEE-754 `NaN` canonicalization 17 18Some Wasm opcodes can result in `NaN` (not-a-number) values. The IEEE-754 spec 19defines a whole range of `NaN` values and the Wasm spec does not require that 20Wasm always generates any particular `NaN` value, it could be any one of 21them. This non-determinism can then be observed by the Wasm program by storing 22the `NaN` value to memory or bitcasting it to an integer. Therefore, Wasmtime 23can be configured to canonicalize all `NaN`s into a particular, canonical `NaN` 24value. The downside is that this adds overhead to Wasm's floating-point 25instructions. 26 27See 28[wasmtime::Config::cranelift_nan_canonicalization](https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.cranelift_nan_canonicalization) 29for more details. 30 31## Make the Relaxed SIMD Proposal Deterministic 32 33The relaxed SIMD proposal gives Wasm programs access to SIMD operations that 34cannot be made to execute both identically and performantly across different 35architectures. The proposal gave up determinism across different architectures in 36order to maintain portable performance. 37 38At the cost of worse runtime performance, Wasmtime can deterministically execute 39this proposal's instructions. See 40[wasmtime::Config::relaxed_simd_deterministic](https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.relaxed_simd_deterministic) 41for more details. 42 43Alternatively, you can simply disable the proposal completely. See 44[`wasmtime::Config::wasm_relaxed_simd`](https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.wasm_relaxed_simd) 45for more details. 46 47## Handling Non-Deterministic Memory and Table Growth 48 49All WebAssembly memories and tables have an associated minimum, or initial, size 50and an optional maximum size. When the maximum size is not present, that means 51"unlimited". If a memory or table is already at its maximum size, then attempts 52to grow them will always fail. If they are below their maximum size, however, 53then the `memory.grow` and `table.grow` instructions are allowed to 54non-deterministicaly succeed or fail (for example, when the host system does not 55have enough memory available to satisfy that growth). 56 57You can make this deterministic in a variety of ways: 58 59* Disallow Wasm programs that use memories and tables via a 60 [limiter](https://docs.rs/wasmtime/latest/wasmtime/struct.Store.html#method.limiter) 61 that rejects non-zero-sized memories and tables. 62 63* Use a [custom memory 64 creator](https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.with_host_memory) 65 that allocates the maximum size up front so that growth will either always 66 succeed or fail before the program has begun execution. 67 68* Use [the `wasmparser` crate](https://crates.io/crates/wasmparser) to write a 69 little validator program that rejects Wasm modules that use 70 `{memory,table}.grow` instructions or alternatively rejects memories and 71 tables that do not have a maximum size equal to their minimum size (which, 72 again, means that their allocation must happen completely up front, and if 73 allocation fails, it will have failed before the Wasm program began 74 executing). 75 76## Use Deterministic Interruption, If Any 77 78If you are making Wasm execution interruptible, use [deterministic fuel-based 79interruption](./examples-interrupting-wasm.md#deterministic-fuel) rather than 80non-deterministic epoch-based interruption. 81