File tree Expand file tree Collapse file tree 2 files changed +16
-4
lines changed Expand file tree Collapse file tree 2 files changed +16
-4
lines changed Original file line number Diff line number Diff line change @@ -631,13 +631,13 @@ impl Lua {
631631 ///
632632 /// Any Luau code is guaranteed to call this handler "eventually"
633633 /// (in practice this can happen at any function call or at any loop iteration).
634+ /// This is similar to `Lua::set_hook` but in more simplified form.
634635 ///
635636 /// The provided interrupt function can error, and this error will be propagated through
636637 /// the Luau code that was executing at the time the interrupt was triggered.
637638 /// Also this can be used to implement continuous execution limits by instructing Luau VM to
638- /// yield by returning [`VmState::Yield`].
639- ///
640- /// This is similar to `Lua::set_hook` but in more simplified form.
639+ /// yield by returning [`VmState::Yield`]. The yield will happen only at yieldable points
640+ /// of execution (not across metamethod/C-call boundaries).
641641 ///
642642 /// # Example
643643 ///
@@ -695,7 +695,10 @@ impl Lua {
695695 match result {
696696 VmState :: Continue => { }
697697 VmState :: Yield => {
698- ffi:: lua_yield ( state, 0 ) ;
698+ // We can yield only at yieldable points, otherwise ignore and continue
699+ if ffi:: lua_isyieldable ( state) != 0 {
700+ ffi:: lua_yield ( state, 0 ) ;
701+ }
699702 }
700703 }
701704 }
Original file line number Diff line number Diff line change @@ -330,6 +330,15 @@ fn test_interrupts() -> Result<()> {
330330 assert_eq ! ( yield_count. load( Ordering :: Relaxed ) , 7 ) ;
331331 assert_eq ! ( co. status( ) , ThreadStatus :: Finished ) ;
332332
333+ // Test no yielding at non-yieldable points
334+ yield_count. store ( 0 , Ordering :: Relaxed ) ;
335+ let co = lua. create_thread ( lua. create_function ( |lua, arg : Value | {
336+ ( lua. load ( "return (function(x) return x end)(...)" ) ) . call :: < Value > ( arg)
337+ } ) ?) ?;
338+ let res = co. resume :: < String > ( "abc" ) ?;
339+ assert_eq ! ( res, "abc" . to_string( ) ) ;
340+ assert_eq ! ( yield_count. load( Ordering :: Relaxed ) , 3 ) ;
341+
333342 //
334343 // Test errors in interrupts
335344 //
You can’t perform that action at this time.
0 commit comments