@@ -3,13 +3,46 @@ use std::rc::Rc;
33
44use anyhow:: Result ;
55use num_bigint:: BigInt ;
6+ use tycho_vm:: { SafeDelete , SafeRc } ;
67
78use super :: { Context , Dictionary , Stack , StackValue , StackValueType , WordList } ;
9+ use crate :: core:: DynFiftValue ;
810use crate :: util:: * ;
911
10- pub type Cont = Rc < dyn ContImpl > ;
12+ pub trait DynFiftCont {
13+ fn new_dyn_fift_cont < T : ContImpl + ' static > ( cont : T ) -> Cont ;
14+ }
15+
16+ impl DynFiftCont for Cont {
17+ #[ inline]
18+ fn new_dyn_fift_cont < T : ContImpl + ' static > ( cont : T ) -> Cont {
19+ let cont: Rc < dyn ContImpl > = Rc :: new ( cont) ;
20+ Cont :: from ( cont)
21+ }
22+ }
23+
24+ pub trait IntoDynFiftCont {
25+ fn into_dyn_fift_cont ( self ) -> Cont ;
26+ }
27+
28+ impl < T : ContImpl > IntoDynFiftCont for Rc < T > {
29+ #[ inline]
30+ fn into_dyn_fift_cont ( self ) -> Cont {
31+ let this: Rc < dyn ContImpl > = self ;
32+ Cont :: from ( this)
33+ }
34+ }
1135
12- pub trait ContImpl {
36+ impl < T : ContImpl > IntoDynFiftCont for SafeRc < T > {
37+ #[ inline]
38+ fn into_dyn_fift_cont ( self ) -> Cont {
39+ Rc :: < T > :: into_dyn_fift_cont ( SafeRc :: into_inner ( self ) )
40+ }
41+ }
42+
43+ pub type Cont = SafeRc < dyn ContImpl > ;
44+
45+ pub trait ContImpl : SafeDelete {
1346 fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > ;
1447
1548 fn up ( & self ) -> Option < & Cont > {
@@ -85,10 +118,12 @@ pub struct InterpreterCont;
85118impl ContImpl for InterpreterCont {
86119 fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
87120 thread_local ! {
88- static COMPILE_EXECUTE : Cont = Rc :: new ( CompileExecuteCont ) ;
121+ static COMPILE_EXECUTE : Cont = SafeRc :: new_dyn_fift_cont ( CompileExecuteCont ) ;
89122 static WORD : RefCell <String > = RefCell :: new( String :: with_capacity( 128 ) ) ;
90123 } ;
91124
125+ let this = self . into_dyn_fift_cont ( ) ;
126+
92127 ctx. stdout . flush ( ) ?;
93128
94129 let compile_exec = COMPILE_EXECUTE . with ( |c| c. clone ( ) ) ;
@@ -154,7 +189,7 @@ impl ContImpl for InterpreterCont {
154189 if entry. active {
155190 ctx. next = SeqCont :: make (
156191 Some ( compile_exec) ,
157- SeqCont :: make ( Some ( self ) , ctx. next . take ( ) ) ,
192+ SeqCont :: make ( Some ( this ) , ctx. next . take ( ) ) ,
158193 ) ;
159194 return Ok ( Some ( entry. definition . clone ( ) ) ) ;
160195 } else {
@@ -164,11 +199,11 @@ impl ContImpl for InterpreterCont {
164199 } ;
165200
166201 ctx. exit_interpret . store ( match & ctx. next {
167- Some ( next) => Rc :: new ( next. clone ( ) ) ,
202+ Some ( next) => SafeRc :: new_dyn_fift_value ( next. clone ( ) ) ,
168203 None => NopCont :: value_instance ( ) ,
169204 } ) ;
170205
171- ctx. next = SeqCont :: make ( Some ( self ) , ctx. next . take ( ) ) ;
206+ ctx. next = SeqCont :: make ( Some ( this ) , ctx. next . take ( ) ) ;
172207 break Ok ( Some ( compile_exec) ) ;
173208 }
174209 }
@@ -215,20 +250,20 @@ impl ContImpl for ListCont {
215250 ctx. next = if is_last {
216251 this. after . take ( )
217252 } else {
218- Some ( self )
253+ Some ( self . into_dyn_fift_cont ( ) )
219254 } ;
220255 }
221256 None => {
222257 if let Some ( next) = ctx. next . take ( ) {
223- ctx. next = Some ( Rc :: new ( ListCont {
258+ ctx. next = Some ( Cont :: new_dyn_fift_cont ( ListCont {
224259 after : SeqCont :: make ( self . after . clone ( ) , Some ( next) ) ,
225260 list : self . list . clone ( ) ,
226261 pos : self . pos + 1 ,
227262 } ) )
228263 } else if is_last {
229264 ctx. next = self . after . clone ( )
230265 } else {
231- ctx. next = Some ( Rc :: new ( ListCont {
266+ ctx. next = Some ( Cont :: new_dyn_fift_cont ( ListCont {
232267 after : self . after . clone ( ) ,
233268 list : self . list . clone ( ) ,
234269 pos : self . pos + 1 ,
@@ -287,9 +322,9 @@ pub struct NopCont;
287322
288323impl NopCont {
289324 thread_local ! {
290- static INSTANCE : ( Cont , Rc <dyn StackValue >) = {
291- let cont = Rc :: new ( NopCont ) ;
292- let value: Rc <dyn StackValue > = Rc :: new ( cont. clone( ) as Rc <dyn ContImpl > ) ;
325+ static INSTANCE : ( Cont , SafeRc <dyn StackValue >) = {
326+ let cont = Cont :: new_dyn_fift_cont ( NopCont ) ;
327+ let value: SafeRc <dyn StackValue > = SafeRc :: new_dyn_fift_value ( cont. clone( ) ) ;
293328 ( cont, value)
294329 } ;
295330 }
@@ -298,12 +333,12 @@ impl NopCont {
298333 Self :: INSTANCE . with ( |( c, _) | c. clone ( ) )
299334 }
300335
301- pub fn value_instance ( ) -> Rc < dyn StackValue > {
336+ pub fn value_instance ( ) -> SafeRc < dyn StackValue > {
302337 Self :: INSTANCE . with ( |( _, v) | v. clone ( ) )
303338 }
304339
305340 pub fn is_nop ( cont : & dyn ContImpl ) -> bool {
306- let left = Self :: INSTANCE . with ( |( c, _) | Rc :: as_ptr ( c) as * const ( ) ) ;
341+ let left = Self :: INSTANCE . with ( |( c, _) | SafeRc :: as_ptr ( c) as * const ( ) ) ;
307342 let right = cont as * const _ as * const ( ) ;
308343 std:: ptr:: eq ( left, right)
309344 }
@@ -329,7 +364,7 @@ impl SeqCont {
329364 if second. is_none ( ) {
330365 first
331366 } else if let Some ( first) = first {
332- Some ( Rc :: new ( Self {
367+ Some ( Cont :: new_dyn_fift_cont ( Self {
333368 first : Some ( first) ,
334369 second,
335370 } ) )
@@ -349,7 +384,7 @@ impl ContImpl for SeqCont {
349384 } else {
350385 let result = std:: mem:: replace ( & mut this. first , this. second . take ( ) ) ;
351386 this. second = ctx. next . take ( ) ;
352- ctx. next = Some ( self ) ;
387+ ctx. next = Some ( self . into_dyn_fift_cont ( ) ) ;
353388 result
354389 }
355390 }
@@ -395,7 +430,7 @@ impl ContImpl for TimesCont {
395430 if this. count > 1 {
396431 this. count -= 1 ;
397432 let body = this. body . clone ( ) ;
398- ctx. next = Some ( self ) ;
433+ ctx. next = Some ( self . into_dyn_fift_cont ( ) ) ;
399434 body
400435 } else {
401436 ctx. next = this. after . take ( ) ;
@@ -406,7 +441,7 @@ impl ContImpl for TimesCont {
406441 let next = SeqCont :: make ( self . after . clone ( ) , ctx. next . take ( ) ) ;
407442
408443 ctx. next = if self . count > 1 {
409- Some ( Rc :: new ( Self {
444+ Some ( Cont :: new_dyn_fift_cont ( Self {
410445 body : self . body . clone ( ) ,
411446 after : next,
412447 count : self . count - 1 ,
@@ -468,7 +503,7 @@ impl ContImpl for UntilCont {
468503 }
469504 }
470505 } ;
471- ctx. next = Some ( next) ;
506+ ctx. next = Some ( next. into_dyn_fift_cont ( ) ) ;
472507 Ok ( body)
473508 }
474509
@@ -535,7 +570,7 @@ impl ContImpl for WhileCont {
535570 } ) ,
536571 } ;
537572
538- ctx. next = Some ( next) ;
573+ ctx. next = Some ( next. into_dyn_fift_cont ( ) ) ;
539574 Ok ( cont)
540575 }
541576
@@ -582,7 +617,7 @@ impl<T> LoopCont<T> {
582617impl < T : LoopContImpl + ' static > ContImpl for LoopCont < T > {
583618 fn run ( mut self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
584619 let Some ( this) = Rc :: get_mut ( & mut self ) else {
585- return Ok ( Some ( Rc :: new ( Self {
620+ return Ok ( Some ( SafeRc :: new_dyn_fift_cont ( Self {
586621 inner : self . inner . clone ( ) ,
587622 state : self . state ,
588623 func : self . func . clone ( ) ,
@@ -606,7 +641,7 @@ impl<T: LoopContImpl + 'static> ContImpl for LoopCont<T> {
606641 }
607642 this. state = LoopContState :: PostExec ;
608643 let res = self . func . clone ( ) ;
609- ctx. next = Some ( self ) ;
644+ ctx. next = Some ( self . into_dyn_fift_cont ( ) ) ;
610645 break Some ( res) ;
611646 }
612647 LoopContState :: PostExec => {
@@ -615,7 +650,7 @@ impl<T: LoopContImpl + 'static> ContImpl for LoopCont<T> {
615650 continue ;
616651 }
617652 this. state = LoopContState :: PreExec ;
618- break Some ( self ) ;
653+ break Some ( self . into_dyn_fift_cont ( ) ) ;
619654 }
620655 LoopContState :: Finalize => {
621656 break if this. inner . finalize ( ctx) ? {
@@ -686,7 +721,7 @@ impl ContImpl for IntLitCont {
686721 }
687722}
688723
689- pub struct LitCont ( pub Rc < dyn StackValue > ) ;
724+ pub struct LitCont ( pub SafeRc < dyn StackValue > ) ;
690725
691726impl ContImpl for LitCont {
692727 fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
@@ -703,7 +738,7 @@ impl ContImpl for LitCont {
703738 }
704739}
705740
706- pub struct MultiLitCont ( pub Vec < Rc < dyn StackValue > > ) ;
741+ pub struct MultiLitCont ( pub Vec < SafeRc < dyn StackValue > > ) ;
707742
708743impl ContImpl for MultiLitCont {
709744 fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
@@ -778,7 +813,7 @@ impl Context<'_> {
778813 fn insert_before_next ( & mut self , cont : & mut Option < Cont > ) {
779814 if let Some ( next) = self . next . take ( ) {
780815 * cont = match cont. take ( ) {
781- Some ( prev) => Some ( Rc :: new ( SeqCont {
816+ Some ( prev) => Some ( Cont :: new_dyn_fift_cont ( SeqCont {
782817 first : Some ( prev) ,
783818 second : Some ( next) ,
784819 } ) ) ,
0 commit comments