Should there be a constant i31ref initializer expression? #141
Description
Following up on observations in #124 (comment), I am wondering whether it'd make sense to introduce a constant initializer expression for i31ref
globals, because currently there is no trivial way to declare an i31ref
typed global, requiring workarounds like
(module
(import "env" "trivial_i31ref" (global $trivial_i31ref i31ref))
(global $global_i31ref (mut i31ref) (global.get $trivial_i31ref))
)
Suitable solutions from simplest to most general seem to be (1) the introduction of i31.zero
(module
(global $global_i31ref (mut i31ref) (i31.zero))
)
or (2) a variant of i31.new
taking an immediate instead of an expression
(module
(global $global_i31ref (mut i31ref) (i31.new_with_value value=0))
)
or, radically, (3) allowing global initializers to be defaultable and making i31ref
default to contain value 0
(module
(global $global_i31ref (mut i31ref) (default))
)
The latter is more complicated but leads to potential code size savings, e.g. in the best case
(module
(global $global_f64 (mut f64) (f64.const 0) ;; 9 bytes initializer
(global $global_f64 (mut f64) (default) ;; 1 byte initializer
)
further leading to (4) allowing to omit global initializers entirely, like on locals
(global $global_f64 (mut f64)) ;; 0 byte initializer
Given how fundamental the problem seems, I might as well be missing something?