diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index 5cf90daf3..fff3e36cc 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -683,7 +683,7 @@ sandbox = { end local result = getmetatable(t) -- check if we have a wrapped __gc using mt - if type(result) == "table" and rawget(result, "__gc") == sgc then + if type(result) == "table" and system.allowGC() and rawget(result, "__gc") == sgc then result = rawget(result, "mt") end return result @@ -713,7 +713,11 @@ sandbox = { if type(mt) ~= "table" then return setmetatable(t, mt) end - if type(rawget(mt, "__gc")) == "function" then + if rawget(mt, "__gc") ~= nil then -- If __gc is set to ANYTHING not `nil`, we're gonna have issues + -- Garbage collector callbacks apparently can't be sandboxed after + -- all, because hooks are disabled while they're running. So we just + -- disable them altogether by default. + if system.allowGC() then -- For all user __gc functions we enforce a much tighter deadline. -- This is because these functions may be called from the main -- thread under certain circumstanced (such as when saving the world), @@ -723,16 +727,18 @@ sandbox = { for k, v in pairs(mt) do sbmt[k] = v end - sbmt.mt = mt - -- Garbage collector callbacks apparently can't be sandboxed after - -- all, because hooks are disabled while they're running. So we just - -- disable them altogether by default. - if not system.allowGC() then - sbmt.__gc = nil -- Silent fail for backwards compat. TODO error in OC 1.7 - else sbmt.__gc = sgc + sbmt.mt = mt + mt = sbmt + else + -- Don't allow marking for finalization, but use the raw metatable. + local gc = rawget(mt, "__gc") + rawset(mt, "__gc", nil) -- remove __gc + local ret = table.pack(pcall(setmetatable, t, mt)) + rawset(mt, "__gc", gc) -- restore __gc + if not ret[1] then error(ret[2], 0) end + return table.unpack(ret, 1, ret.n) end - mt = sbmt end return setmetatable(t, mt) end, @@ -1442,4 +1448,4 @@ end -- JNLua converts the coroutine to a string immediately, so we can't get the -- traceback later. Because of that we have to do the error handling here. -return pcall(main) \ No newline at end of file +return pcall(main)