@@ -683,7 +683,7 @@ sandbox = {
683
683
end
684
684
local result = getmetatable (t )
685
685
-- check if we have a wrapped __gc using mt
686
- if type (result ) == " table" and rawget (result , " __gc" ) == sgc then
686
+ if type (result ) == " table" and system . allowGC () and rawget (result , " __gc" ) == sgc then
687
687
result = rawget (result , " mt" )
688
688
end
689
689
return result
@@ -713,7 +713,11 @@ sandbox = {
713
713
if type (mt ) ~= " table" then
714
714
return setmetatable (t , mt )
715
715
end
716
- if type (rawget (mt , " __gc" )) == " function" then
716
+ if rawget (mt , " __gc" ) ~= nil then -- If __gc is set to ANYTHING not `nil`, we're gonna have issues
717
+ -- Garbage collector callbacks apparently can't be sandboxed after
718
+ -- all, because hooks are disabled while they're running. So we just
719
+ -- disable them altogether by default.
720
+ if system .allowGC () then
717
721
-- For all user __gc functions we enforce a much tighter deadline.
718
722
-- This is because these functions may be called from the main
719
723
-- thread under certain circumstanced (such as when saving the world),
@@ -723,16 +727,18 @@ sandbox = {
723
727
for k , v in pairs (mt ) do
724
728
sbmt [k ] = v
725
729
end
730
+ sbmt .__gc = sgc
726
731
sbmt .mt = mt
727
- -- Garbage collector callbacks apparently can't be sandboxed after
728
- -- all, because hooks are disabled while they're running. So we just
729
- -- disable them altogether by default.
730
- if not system .allowGC () then
731
- sbmt .__gc = nil -- Silent fail for backwards compat. TODO error in OC 1.7
732
+ mt = sbmt
732
733
else
733
- sbmt .__gc = sgc
734
+ -- Don't allow marking for finalization, but use the raw metatable.
735
+ local gc = rawget (mt , " __gc" )
736
+ rawset (mt , " __gc" , nil ) -- remove __gc
737
+ local ret = table.pack (pcall (setmetatable , t , mt ))
738
+ rawset (mt , " __gc" , gc ) -- restore __gc
739
+ if not ret [1 ] then error (ret [2 ], 0 ) end
740
+ return table.unpack (ret , 1 , ret .n )
734
741
end
735
- mt = sbmt
736
742
end
737
743
return setmetatable (t , mt )
738
744
end ,
@@ -1442,4 +1448,4 @@ end
1442
1448
1443
1449
-- JNLua converts the coroutine to a string immediately, so we can't get the
1444
1450
-- traceback later. Because of that we have to do the error handling here.
1445
- return pcall (main )
1451
+ return pcall (main )
0 commit comments