@@ -18,7 +18,7 @@ use crate::table::Table;
18
18
use crate :: thread:: Thread ;
19
19
use crate :: types:: {
20
20
AppDataRef , AppDataRefMut , Callback , CallbackUpvalue , DestructedUserdata , Integer , LightUserData ,
21
- MaybeSend , ReentrantMutex , RegistryKey , SubtypeId , ValueRef , XRc ,
21
+ MaybeSend , ReentrantMutex , RegistryKey , SubtypeId , ValueRef , VmState , XRc ,
22
22
} ;
23
23
use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataRegistry , UserDataStorage } ;
24
24
use crate :: util:: {
@@ -356,7 +356,7 @@ impl RawLua {
356
356
triggers : HookTriggers ,
357
357
callback : F ,
358
358
) where
359
- F : Fn ( & Lua , Debug ) -> Result < ( ) > + MaybeSend + ' static ,
359
+ F : Fn ( & Lua , Debug ) -> Result < VmState > + MaybeSend + ' static ,
360
360
{
361
361
unsafe extern "C-unwind" fn hook_proc ( state : * mut ffi:: lua_State , ar : * mut ffi:: lua_Debug ) {
362
362
let extra = ExtraData :: get ( state) ;
@@ -365,17 +365,34 @@ impl RawLua {
365
365
ffi:: lua_sethook ( state, None , 0 , 0 ) ;
366
366
return ;
367
367
}
368
- callback_error_ext ( state, extra, move |extra, _| {
368
+ let result = callback_error_ext ( state, extra, move |extra, _| {
369
369
let hook_cb = ( * extra) . hook_callback . clone ( ) ;
370
370
let hook_cb = mlua_expect ! ( hook_cb, "no hook callback set in hook_proc" ) ;
371
371
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
373
373
}
374
374
let rawlua = ( * extra) . raw_lua ( ) ;
375
375
let _guard = StateGuard :: new ( rawlua, state) ;
376
376
let debug = Debug :: new ( rawlua, ar) ;
377
377
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
+ }
379
396
}
380
397
381
398
( * self . extra . get ( ) ) . hook_callback = Some ( std:: rc:: Rc :: new ( callback) ) ;
0 commit comments