@@ -4,13 +4,14 @@ use crate::frame::{ExecutionResult, FrameRef};
4
4
use crate :: pyobject:: { PyObjectRef , PyResult } ;
5
5
use crate :: vm:: VirtualMachine ;
6
6
7
- use std:: cell:: Cell ;
7
+ use std:: cell:: { Cell , RefCell } ;
8
8
9
9
#[ derive( Debug ) ]
10
10
pub struct Coro {
11
11
frame : FrameRef ,
12
12
closed : Cell < bool > ,
13
13
running : Cell < bool > ,
14
+ exceptions : RefCell < Vec < PyBaseExceptionRef > > ,
14
15
}
15
16
16
17
impl Coro {
@@ -19,6 +20,7 @@ impl Coro {
19
20
frame,
20
21
closed : Cell :: new ( false ) ,
21
22
running : Cell :: new ( false ) ,
23
+ exceptions : RefCell :: new ( vec ! [ ] ) ,
22
24
}
23
25
}
24
26
@@ -29,15 +31,32 @@ impl Coro {
29
31
}
30
32
}
31
33
34
+ fn run_with_context < F > ( & self , func : F , vm : & VirtualMachine ) -> PyResult < ExecutionResult >
35
+ where
36
+ F : FnOnce ( ) -> PyResult < ExecutionResult > ,
37
+ {
38
+ self . running . set ( true ) ;
39
+ let curr_exception_stack_len = vm. exceptions . borrow ( ) . len ( ) ;
40
+ vm. exceptions
41
+ . borrow_mut ( )
42
+ . append ( & mut self . exceptions . borrow_mut ( ) ) ;
43
+ let result = func ( ) ;
44
+ self . exceptions . replace (
45
+ vm. exceptions
46
+ . borrow_mut ( )
47
+ . split_off ( curr_exception_stack_len) ,
48
+ ) ;
49
+ self . running . set ( false ) ;
50
+ result
51
+ }
52
+
32
53
pub fn send ( & self , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
33
54
if self . closed . get ( ) {
34
55
return Err ( objiter:: new_stop_iteration ( vm) ) ;
35
56
}
36
57
37
58
self . frame . push_value ( value. clone ( ) ) ;
38
- self . running . set ( true ) ;
39
- let result = vm. run_frame ( self . frame . clone ( ) ) ;
40
- self . running . set ( false ) ;
59
+ let result = self . run_with_context ( || vm. run_frame ( self . frame . clone ( ) ) , vm) ;
41
60
self . maybe_close ( & result) ;
42
61
result?. into_result ( vm)
43
62
}
@@ -53,9 +72,9 @@ impl Coro {
53
72
return Err ( exceptions:: normalize ( exc_type, exc_val, exc_tb, vm) ?) ;
54
73
}
55
74
vm. frames . borrow_mut ( ) . push ( self . frame . clone ( ) ) ;
75
+ let result =
76
+ self . run_with_context ( || self . frame . gen_throw ( vm, exc_type, exc_val, exc_tb) , vm) ;
56
77
self . running . set ( true ) ;
57
- let result = self . frame . gen_throw ( vm, exc_type, exc_val, exc_tb) ;
58
- self . running . set ( false ) ;
59
78
self . maybe_close ( & result) ;
60
79
vm. frames . borrow_mut ( ) . pop ( ) ;
61
80
result?. into_result ( vm)
@@ -67,13 +86,17 @@ impl Coro {
67
86
}
68
87
vm. frames . borrow_mut ( ) . push ( self . frame . clone ( ) ) ;
69
88
self . running . set ( true ) ;
70
- let result = self . frame . gen_throw (
89
+ let result = self . run_with_context (
90
+ || {
91
+ self . frame . gen_throw (
92
+ vm,
93
+ vm. ctx . exceptions . generator_exit . clone ( ) . into_object ( ) ,
94
+ vm. get_none ( ) ,
95
+ vm. get_none ( ) ,
96
+ )
97
+ } ,
71
98
vm,
72
- vm. ctx . exceptions . generator_exit . clone ( ) . into_object ( ) ,
73
- vm. get_none ( ) ,
74
- vm. get_none ( ) ,
75
99
) ;
76
- self . running . set ( false ) ;
77
100
vm. frames . borrow_mut ( ) . pop ( ) ;
78
101
self . closed . set ( true ) ;
79
102
match result {
0 commit comments