It would be useful to allow const global variables in asm.js that could be used in place of numeric literals. This would allow Emscripten to reduce code size by factoring out frequent long numeric literals, replacing them with a short identifier. This could be done with a normal global var but, without the const-ness, a single-pass AOT compiler will not know if the var is const or not which makes it hard to avoid emitting a global load instead of a immediate.
One motivation for this is factoring out common float32 constants (e.g. fround(0)
). Another is a possible heap-access optimization: if Emscripten explicitly masks heap indices (e.g., HEAP32[(i&0xfffffff)>>2]
), then the compiler can see that the access must in-bounds (by comparing the mask with the minimum heap size) and avoid bounds checks. However, heap masks take a lot of characters, so consts allow a significant size reduction.
The extension is pretty simple:
- Literal-initialized global variables can be declared with
const
instead ofvar
. - The Global Environment already records mutability of global variables which is checked by assignment, so
const
globals are recorded asimm
. - The type of a const global is the precise type of the numeric literal (float, double, signed, fixnum, unsigned), so they can be used exactly where a numeric literal could be used without explicit coercion.
- In addition to being used by Identifier expressions, const globals can be used in place of numeric literals in variable type annotations and return type annotations.
This is in release Firefox along with the heap-masking optimization. Emscripten doesn’t emit heap-masked code, though, so this is all considered experimental and feedback is welcome.