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:

§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