Search code examples
webassembly

Does Wasm require validation of locals set before accessed?


From a famous Wasm article WebAssembly Troubles part 1: WebAssembly Is Not a Stack Machine, it wrote that

In WebAssembly as it exists now, you have to zero locals when entering a function unless you can statically prove that the local is always set before it is accessed.

This article was written in 2019, and for now, I wonder if this still holds. So I write a WASM file:

(module
    (func (export "get_before_set") (result i32)
        (local $dummy i32)
        local.get $dummy
    )
)

I run this WASM file with wasmer, and it turns out that this function just returns 0.

Does this mean that, WebAssembly require engine (instead of manually) to zero locals unless engine can statically prove that local is set before accessed?

I went through the WASM specification, and didn't find record about this requirement. Does this behavior a standard, or just implementation-defined?


Solution

  • Semantically, yes. Though of course, in practice, if an engine sees that a local's initialisation value is never read before being overwritten, it is totally free to optimise away the default initialisation.

    As for where this is specified, it's here, when constructing the function frame.

    That being said, the upcoming function references proposal introduces the notion of uninitialised locals and validates that they are not read. But that only applies to locals of types that do not have a default value, like non-null references.