@@ -764,6 +764,34 @@ int lua_metaipair(lua_State* L)
764
764
765
765
} // anonymous namespace
766
766
767
+ int LuaState::push_debug_traceback ()
768
+ {
769
+ // Push debug.traceback() onto the stack as lua_pcall()'s error
770
+ // handler function. On error, lua_pcall() calls the specified error
771
+ // handler function with the original error message; the message
772
+ // returned by the error handler is then returned by lua_pcall().
773
+ // Luau's debug.traceback() is called with a message to prepend to the
774
+ // returned traceback string. Almost as if they'd been designed to
775
+ // work together...
776
+ lua_getglobal (mState , " debug" );
777
+ if (!lua_istable (mState , -1 ))
778
+ {
779
+ lua_pop (mState , 1 );
780
+ LL_WARNS (" Lua" ) << " 'debug' table not found" << LL_ENDL;
781
+ return 0 ;
782
+ }
783
+ lua_getfield (mState , -1 , " traceback" );
784
+ if (!lua_isfunction (mState , -1 ))
785
+ {
786
+ lua_pop (mState , 2 );
787
+ LL_WARNS (" Lua" ) << " 'traceback' func not found" << LL_ENDL;
788
+ return 0 ;
789
+ }
790
+ // ditch "debug"
791
+ lua_remove (mState , -2 );
792
+ return lua_gettop (mState );
793
+ }
794
+
767
795
LuaState::~LuaState ()
768
796
{
769
797
// If we're unwinding the stack due to an exception, don't bother trying
@@ -784,6 +812,8 @@ LuaState::~LuaState()
784
812
// stack contains Registry.atexit
785
813
if (lua_istable (mState , -1 ))
786
814
{
815
+ int atexit = lua_gettop (mState );
816
+
787
817
// We happen to know that Registry.atexit is built by appending array
788
818
// entries using table.insert(). That's important because it means
789
819
// there are no holes, and therefore lua_objlen() should be correct.
@@ -793,36 +823,25 @@ LuaState::~LuaState()
793
823
LL_DEBUGS (" Lua" ) << LLCoros::getName () << " : Registry.atexit is a table with "
794
824
<< len << " entries" << LL_ENDL;
795
825
796
- // Push debug.traceback() onto the stack as lua_pcall()'s error
797
- // handler function. On error, lua_pcall() calls the specified error
798
- // handler function with the original error message; the message
799
- // returned by the error handler is then returned by lua_pcall().
800
- // Luau's debug.traceback() is called with a message to prepend to the
801
- // returned traceback string. Almost as if they'd been designed to
802
- // work together...
803
- lua_getglobal (mState , " debug" );
804
- lua_getfield (mState , -1 , " traceback" );
805
- // ditch "debug"
806
- lua_remove (mState , -2 );
807
- // stack now contains atexit, debug.traceback()
808
-
826
+ // TODO: 'debug' global shouldn't be overwritten and should be accessible at this stage
827
+ S32 debug_traceback_idx = push_debug_traceback ();
828
+ // if debug_traceback is true, stack now contains atexit, /debug.traceback()/
829
+ // otherwise just atexit
809
830
for (int i (len); i >= 1 ; --i)
810
831
{
811
832
lua_pushinteger (mState , i);
812
- // stack contains Registry.atexit, debug.traceback(), i
813
- lua_gettable (mState , - 3 );
814
- // stack contains Registry.atexit, debug.traceback(), atexit[i]
833
+ // stack contains Registry.atexit, / debug.traceback()/ , i
834
+ lua_gettable (mState , atexit );
835
+ // stack contains Registry.atexit, / debug.traceback()/ , atexit[i]
815
836
// Call atexit[i](), no args, no return values.
816
837
// Use lua_pcall() because errors in any one atexit() function
817
838
// shouldn't cancel the rest of them. Pass debug.traceback() as
818
839
// the error handler function.
819
- LL_DEBUGS (" Lua" ) << LLCoros::getName ()
820
- << " : calling atexit(" << i << " )" << LL_ENDL;
821
- if (lua_pcall (mState , 0 , 0 , -2 ) != LUA_OK)
840
+ LL_DEBUGS (" Lua" ) << LLCoros::getName () << " : calling atexit(" << i << " )" << LL_ENDL;
841
+ if (lua_pcall (mState , 0 , 0 , debug_traceback_idx) != LUA_OK)
822
842
{
823
843
auto error{ lua_tostdstring (mState , -1 ) };
824
- LL_WARNS (" Lua" ) << LLCoros::getName ()
825
- << " : atexit(" << i << " ) error: " << error << LL_ENDL;
844
+ LL_WARNS (" Lua" ) << LLCoros::getName () << " : atexit(" << i << " ) error: " << error << LL_ENDL;
826
845
// pop error message
827
846
lua_pop (mState , 1 );
828
847
}
@@ -831,7 +850,8 @@ LuaState::~LuaState()
831
850
// stack contains atexit, debug.traceback()
832
851
}
833
852
// pop debug.traceback()
834
- lua_pop (mState , 1 );
853
+ if (debug_traceback_idx)
854
+ lua_remove (mState , debug_traceback_idx);
835
855
}
836
856
// pop Registry.atexit (either table or nil)
837
857
lua_pop (mState , 1 );
0 commit comments