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 {
631
631
///
632
632
/// Any Luau code is guaranteed to call this handler "eventually"
633
633
/// (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.
634
635
///
635
636
/// The provided interrupt function can error, and this error will be propagated through
636
637
/// the Luau code that was executing at the time the interrupt was triggered.
637
638
/// 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).
641
641
///
642
642
/// # Example
643
643
///
@@ -695,7 +695,10 @@ impl Lua {
695
695
match result {
696
696
VmState :: Continue => { }
697
697
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
+ }
699
702
}
700
703
}
701
704
}
Original file line number Diff line number Diff line change @@ -330,6 +330,15 @@ fn test_interrupts() -> Result<()> {
330
330
assert_eq ! ( yield_count. load( Ordering :: Relaxed ) , 7 ) ;
331
331
assert_eq ! ( co. status( ) , ThreadStatus :: Finished ) ;
332
332
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
+
333
342
//
334
343
// Test errors in interrupts
335
344
//
You can’t perform that action at this time.
0 commit comments