var konst = "prop1" is compiled to:
00000: defvar "konst" #
00005: bindgname "konst" # GLOBAL
00010: string "prop1" # GLOBAL "prop1"
00015: setgname "konst" # "prop1"
00020: pop #
const konst = "prop1" is compiled to:
00000: defconst "konst" #
00005: string "prop1" # "prop1"
00010: initglexical "konst" # "prop1"
00015: pop #
JSOP_SETGNAME eventually ends up in
NativeSetExistingDataProperty, which has this nice optimization:
// Global properties declared with 'var' will be initially
// defined with an undefined value, so don't treat the initial
// assignments to such properties as overwrites.
bool overwriting = !obj->is<GlobalObject>() ||
obj->setSlotWithType(cx, shape, v, overwriting);
JSOP_INITLEXICAL ends up in
InitGlobalLexicalOperation, which calls
setSlotWithType without setting
overwriting to false:
lexicalEnv->setSlotWithType(cx, shape, value);
And that means TI treats the global lexical as an overwritten property.
Which in turn results in never taking this branch in Ion, but instead always loading global lexicals through slot loads.
We should try to mark global constant lexicals as non-overwritten properties, so that TI can treat them as constants, too.