I sort of lost track of the discussion on non-nullable locals. Really nice to see it has been settled and there is progress on 1a.
After reading discussion on WebAssembly/function-references#44 and also discussion on implementation on bynarien (WebAssembly/binaryen#4824) I realized there might a (potentially obvious) escape hatch for toolchains:
- have a bunch of nullable globals with the right types
- initialize them as part of the start() function
- in the first few instructions of every function, set any non-nullable local like:
global.get X
ref.as_non_null
local.set Y
This explicit initialization to a dummy value allows to skip the complexities of having to deal with the validation part for 1a, allowing back things like
if (someCondition)
local = costly_initialization();
else
local = other_costly_initialization();
func(local);
or even more complex to legalize like:
const bool condition = someFunc();
if (condition)
local = costly_initialization();
//some other code
if (condition == false)
local = other_costly_initialization();
func(local);
without having to force additional restrictions on a given tool IR.
This might not be optimal (as in the added initialization costs 3 instructions per locals that might be avoided), but allows to simplify implementation and could be used either as backstop or as simple way to legalize intermediate (invalid) states.
I briefly discussed with @kripken (https://twitter.com/carlo_piovesan/status/1551834112788398080 and replies), I agree that there are potentially drawbacks / its' not optimal, but I think it might a strategy worth considering enough to be shared here.
One open question I have is whether it's always possible to generate such dummy initializes in advance (it's easy for function references, less obvious for arbitrary potentially recursive types).