@@ -764,6 +764,34 @@ int lua_metaipair(lua_State* L)
764
764
765
765
} // anonymous namespace
766
766
767
+ bool 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 false ;
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 false ;
789
+ }
790
+ // ditch "debug"
791
+ lua_remove (mState , -2 );
792
+ return true ;
793
+ }
794
+
767
795
LuaState::~LuaState ()
768
796
{
769
797
// If we're unwinding the stack due to an exception, don't bother trying
@@ -793,45 +821,35 @@ LuaState::~LuaState()
793
821
LL_DEBUGS (" Lua" ) << LLCoros::getName () << " : Registry.atexit is a table with "
794
822
<< len << " entries" << LL_ENDL;
795
823
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
-
809
- for (int i (len); i >= 1 ; --i)
824
+ // TODO: 'debug' global shouldn't be overwritten and should be accessible at this stage
825
+ if (push_debug_traceback ())
810
826
{
811
- 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]
815
- // Call atexit[i](), no args, no return values.
816
- // Use lua_pcall() because errors in any one atexit() function
817
- // shouldn't cancel the rest of them. Pass debug.traceback() as
818
- // 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)
827
+ // stack now contains atexit, debug.traceback()
828
+ for (int i (len); i >= 1 ; --i)
822
829
{
823
- auto error{ lua_tostdstring (mState , -1 ) };
824
- LL_WARNS (" Lua" ) << LLCoros::getName ()
825
- << " : atexit(" << i << " ) error: " << error << LL_ENDL;
826
- // pop error message
827
- lua_pop (mState , 1 );
830
+ lua_pushinteger (mState , i);
831
+ // stack contains Registry.atexit, debug.traceback(), i
832
+ lua_gettable (mState , -3 );
833
+ // stack contains Registry.atexit, debug.traceback(), atexit[i]
834
+ // Call atexit[i](), no args, no return values.
835
+ // Use lua_pcall() because errors in any one atexit() function
836
+ // shouldn't cancel the rest of them. Pass debug.traceback() as
837
+ // the error handler function.
838
+ LL_DEBUGS (" Lua" ) << LLCoros::getName () << " : calling atexit(" << i << " )" << LL_ENDL;
839
+ if (lua_pcall (mState , 0 , 0 , -2 ) != LUA_OK)
840
+ {
841
+ auto error{ lua_tostdstring (mState , -1 ) };
842
+ LL_WARNS (" Lua" ) << LLCoros::getName () << " : atexit(" << i << " ) error: " << error << LL_ENDL;
843
+ // pop error message
844
+ lua_pop (mState , 1 );
845
+ }
846
+ LL_DEBUGS (" Lua" ) << LLCoros::getName () << " : atexit(" << i << " ) done" << LL_ENDL;
847
+ // lua_pcall() has already popped atexit[i]:
848
+ // stack contains atexit, debug.traceback()
828
849
}
829
- LL_DEBUGS (" Lua" ) << LLCoros::getName () << " : atexit(" << i << " ) done" << LL_ENDL;
830
- // lua_pcall() has already popped atexit[i]:
831
- // stack contains atexit, debug.traceback()
850
+ // pop debug.traceback()
851
+ lua_pop (mState , 1 );
832
852
}
833
- // pop debug.traceback()
834
- lua_pop (mState , 1 );
835
853
}
836
854
// pop Registry.atexit (either table or nil)
837
855
lua_pop (mState , 1 );
0 commit comments