pub fn read_constant_instructions(
wasm: &mut WasmReader<'_>,
this_global_valtype: Option<ValType>,
_globals_ty: Option<&[GlobalType]>
) -> Result<Span>
Expand description
Read and validate constant expressions.
This function is used to validate that a constant expression produces the expected result. The main use case for this is to validate that an initialization expression for a global returns the correct value.
Note: to be valid, constant expressions may not leave garbage data on the stack. It may leave only what is expected and nothing more.
Valid constant instructions are:
- Core: https://webassembly.github.io/spec/core/valid/instructions.html#valid-constant
- Extended Proposal: https://webassembly.github.io/extended-const/core/valid/instructions.html#valid-constant
§The Wonders of global.get
The global.get
instruction is quite picky by nature. To make a long story short, there are two rules to follow to
be able to use this expression.
§1. The referenced global must be imported
Take the example code:
(module
(global (export "g") (mut i32) (
i32.add (i32.const 1) (i32.const 2)
))
(global (export "h1") i32 (
i32.const 1
))
(global (export "h2") i32 (
global.get 1
))
(func (export "f")
i32.const 100
global.set 0))
When compiling with wat2wasm, the following error is thrown:
Error: validate failed:
test.wast:11:24: error: initializer expression can only reference an imported global
global.get 1
^
When compiling the code with the latest dev build of wasmtime, the following error is thrown:
failed to parse WebAssembly module
Caused by:
constant expression required: global.get of locally defined global (at offset 0x24)
§2. The referenced global must be immutable
(module
(import "env" "g" (global (mut i32)))
(global (export "h") (mut i32) (
i32.add (i32.const 1) (global.get 0)
))
)
When compiling with wat2wasm, the following error is thrown:
Error: validate failed:
test.wast:4:27: error: initializer expression cannot reference a mutable global
i32.add (i32.const 1) (global.get 0)
§Note
The following instructions are not yet supported:
ref.null
ref.func
global.get