@@ -18,7 +18,7 @@ use crate::table::Table;
1818use crate :: thread:: Thread ;
1919use crate :: types:: {
2020 AppDataRef , AppDataRefMut , Callback , CallbackUpvalue , DestructedUserdata , Integer , LightUserData ,
21- MaybeSend , ReentrantMutex , RegistryKey , SubtypeId , ValueRef , XRc ,
21+ MaybeSend , ReentrantMutex , RegistryKey , SubtypeId , ValueRef , VmState , XRc ,
2222} ;
2323use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataRegistry , UserDataStorage } ;
2424use crate :: util:: {
@@ -356,7 +356,7 @@ impl RawLua {
356356 triggers : HookTriggers ,
357357 callback : F ,
358358 ) where
359- F : Fn ( & Lua , Debug ) -> Result < ( ) > + MaybeSend + ' static ,
359+ F : Fn ( & Lua , Debug ) -> Result < VmState > + MaybeSend + ' static ,
360360 {
361361 unsafe extern "C-unwind" fn hook_proc ( state : * mut ffi:: lua_State , ar : * mut ffi:: lua_Debug ) {
362362 let extra = ExtraData :: get ( state) ;
@@ -365,17 +365,34 @@ impl RawLua {
365365 ffi:: lua_sethook ( state, None , 0 , 0 ) ;
366366 return ;
367367 }
368- callback_error_ext ( state, extra, move |extra, _| {
368+ let result = callback_error_ext ( state, extra, move |extra, _| {
369369 let hook_cb = ( * extra) . hook_callback . clone ( ) ;
370370 let hook_cb = mlua_expect ! ( hook_cb, "no hook callback set in hook_proc" ) ;
371371 if std:: rc:: Rc :: strong_count ( & hook_cb) > 2 {
372- return Ok ( ( ) ) ; // Don't allow recursion
372+ return Ok ( VmState :: Continue ) ; // Don't allow recursion
373373 }
374374 let rawlua = ( * extra) . raw_lua ( ) ;
375375 let _guard = StateGuard :: new ( rawlua, state) ;
376376 let debug = Debug :: new ( rawlua, ar) ;
377377 hook_cb ( ( * extra) . lua ( ) , debug)
378- } )
378+ } ) ;
379+ match result {
380+ VmState :: Continue => { }
381+ VmState :: Yield => {
382+ // Only count and line events can yield
383+ if ( * ar) . event == ffi:: LUA_HOOKCOUNT || ( * ar) . event == ffi:: LUA_HOOKLINE {
384+ #[ cfg( any( feature = "lua54" , feature = "lua53" ) ) ]
385+ if ffi:: lua_isyieldable ( state) != 0 {
386+ ffi:: lua_yield ( state, 0 ) ;
387+ }
388+ #[ cfg( any( feature = "lua52" , feature = "lua51" , feature = "luajit" ) ) ]
389+ {
390+ ffi:: lua_pushliteral ( state, "attempt to yield from a hook" ) ;
391+ ffi:: lua_error ( state) ;
392+ }
393+ }
394+ }
395+ }
379396 }
380397
381398 ( * self . extra . get ( ) ) . hook_callback = Some ( std:: rc:: Rc :: new ( callback) ) ;
0 commit comments