Violating upvalue immutability via the debug library

  • From: Peter Cawley <corsix@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 7 Aug 2015 22:09:41 +0100

Hi all,

On the following example, LuaJIT v2.1 git head prints "xx" 60 times,
and then "yx" 60 times. On the other hand, with -joff (or with PUC-Rio
Lua), it has the expected behaviour of printing "xx" 60 times, and
then "yy" 60 times.

-----
local C = "x"
local function c() return C end

for i = 1, 2 do
for j = 1, 60 do
io.write(C, c(), "\n")
end
debug.setupvalue(c, 1, "y")
end
-----

Swapping `debug.setupvalue(c, 1, "y")` for `debug.setlocal(1, 1, "y")`
gives rise to the same effect. Using the equivalent C API debug
functions probably has a similar effect, though I've not explicitly
tested it.

One fix might be to throw a call to lj_trace_flushall into
lua_setupvalue and lua_setlocal. A more elaborate fix might be to only
call lj_trace_flushall in lua_setupvalue if the upvalue in question is
marked immutable, and to only call it in lua_setlocal if the stack
slot in question has an open upvalue pointing to it and said upvalue
is marked as immutable - but given that the debug library isn't
expected to be overly performant, the more elaborate fix doesn't seem
worthwhile. Are there other fixes worth considering?

Other related posts: