@@ -3,13 +3,46 @@ use std::rc::Rc;
3
3
4
4
use anyhow:: Result ;
5
5
use num_bigint:: BigInt ;
6
+ use tycho_vm:: { SafeDelete , SafeRc } ;
6
7
7
8
use super :: { Context , Dictionary , Stack , StackValue , StackValueType , WordList } ;
9
+ use crate :: core:: DynFiftValue ;
8
10
use crate :: util:: * ;
9
11
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
+ }
11
35
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 {
13
46
fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > ;
14
47
15
48
fn up ( & self ) -> Option < & Cont > {
@@ -85,10 +118,12 @@ pub struct InterpreterCont;
85
118
impl ContImpl for InterpreterCont {
86
119
fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
87
120
thread_local ! {
88
- static COMPILE_EXECUTE : Cont = Rc :: new ( CompileExecuteCont ) ;
121
+ static COMPILE_EXECUTE : Cont = SafeRc :: new_dyn_fift_cont ( CompileExecuteCont ) ;
89
122
static WORD : RefCell <String > = RefCell :: new( String :: with_capacity( 128 ) ) ;
90
123
} ;
91
124
125
+ let this = self . into_dyn_fift_cont ( ) ;
126
+
92
127
ctx. stdout . flush ( ) ?;
93
128
94
129
let compile_exec = COMPILE_EXECUTE . with ( |c| c. clone ( ) ) ;
@@ -154,7 +189,7 @@ impl ContImpl for InterpreterCont {
154
189
if entry. active {
155
190
ctx. next = SeqCont :: make (
156
191
Some ( compile_exec) ,
157
- SeqCont :: make ( Some ( self ) , ctx. next . take ( ) ) ,
192
+ SeqCont :: make ( Some ( this ) , ctx. next . take ( ) ) ,
158
193
) ;
159
194
return Ok ( Some ( entry. definition . clone ( ) ) ) ;
160
195
} else {
@@ -164,11 +199,11 @@ impl ContImpl for InterpreterCont {
164
199
} ;
165
200
166
201
ctx. exit_interpret . store ( match & ctx. next {
167
- Some ( next) => Rc :: new ( next. clone ( ) ) ,
202
+ Some ( next) => SafeRc :: new_dyn_fift_value ( next. clone ( ) ) ,
168
203
None => NopCont :: value_instance ( ) ,
169
204
} ) ;
170
205
171
- ctx. next = SeqCont :: make ( Some ( self ) , ctx. next . take ( ) ) ;
206
+ ctx. next = SeqCont :: make ( Some ( this ) , ctx. next . take ( ) ) ;
172
207
break Ok ( Some ( compile_exec) ) ;
173
208
}
174
209
}
@@ -215,20 +250,20 @@ impl ContImpl for ListCont {
215
250
ctx. next = if is_last {
216
251
this. after . take ( )
217
252
} else {
218
- Some ( self )
253
+ Some ( self . into_dyn_fift_cont ( ) )
219
254
} ;
220
255
}
221
256
None => {
222
257
if let Some ( next) = ctx. next . take ( ) {
223
- ctx. next = Some ( Rc :: new ( ListCont {
258
+ ctx. next = Some ( Cont :: new_dyn_fift_cont ( ListCont {
224
259
after : SeqCont :: make ( self . after . clone ( ) , Some ( next) ) ,
225
260
list : self . list . clone ( ) ,
226
261
pos : self . pos + 1 ,
227
262
} ) )
228
263
} else if is_last {
229
264
ctx. next = self . after . clone ( )
230
265
} else {
231
- ctx. next = Some ( Rc :: new ( ListCont {
266
+ ctx. next = Some ( Cont :: new_dyn_fift_cont ( ListCont {
232
267
after : self . after . clone ( ) ,
233
268
list : self . list . clone ( ) ,
234
269
pos : self . pos + 1 ,
@@ -287,9 +322,9 @@ pub struct NopCont;
287
322
288
323
impl NopCont {
289
324
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( ) ) ;
293
328
( cont, value)
294
329
} ;
295
330
}
@@ -298,12 +333,12 @@ impl NopCont {
298
333
Self :: INSTANCE . with ( |( c, _) | c. clone ( ) )
299
334
}
300
335
301
- pub fn value_instance ( ) -> Rc < dyn StackValue > {
336
+ pub fn value_instance ( ) -> SafeRc < dyn StackValue > {
302
337
Self :: INSTANCE . with ( |( _, v) | v. clone ( ) )
303
338
}
304
339
305
340
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 ( ) ) ;
307
342
let right = cont as * const _ as * const ( ) ;
308
343
std:: ptr:: eq ( left, right)
309
344
}
@@ -329,7 +364,7 @@ impl SeqCont {
329
364
if second. is_none ( ) {
330
365
first
331
366
} else if let Some ( first) = first {
332
- Some ( Rc :: new ( Self {
367
+ Some ( Cont :: new_dyn_fift_cont ( Self {
333
368
first : Some ( first) ,
334
369
second,
335
370
} ) )
@@ -349,7 +384,7 @@ impl ContImpl for SeqCont {
349
384
} else {
350
385
let result = std:: mem:: replace ( & mut this. first , this. second . take ( ) ) ;
351
386
this. second = ctx. next . take ( ) ;
352
- ctx. next = Some ( self ) ;
387
+ ctx. next = Some ( self . into_dyn_fift_cont ( ) ) ;
353
388
result
354
389
}
355
390
}
@@ -395,7 +430,7 @@ impl ContImpl for TimesCont {
395
430
if this. count > 1 {
396
431
this. count -= 1 ;
397
432
let body = this. body . clone ( ) ;
398
- ctx. next = Some ( self ) ;
433
+ ctx. next = Some ( self . into_dyn_fift_cont ( ) ) ;
399
434
body
400
435
} else {
401
436
ctx. next = this. after . take ( ) ;
@@ -406,7 +441,7 @@ impl ContImpl for TimesCont {
406
441
let next = SeqCont :: make ( self . after . clone ( ) , ctx. next . take ( ) ) ;
407
442
408
443
ctx. next = if self . count > 1 {
409
- Some ( Rc :: new ( Self {
444
+ Some ( Cont :: new_dyn_fift_cont ( Self {
410
445
body : self . body . clone ( ) ,
411
446
after : next,
412
447
count : self . count - 1 ,
@@ -468,7 +503,7 @@ impl ContImpl for UntilCont {
468
503
}
469
504
}
470
505
} ;
471
- ctx. next = Some ( next) ;
506
+ ctx. next = Some ( next. into_dyn_fift_cont ( ) ) ;
472
507
Ok ( body)
473
508
}
474
509
@@ -535,7 +570,7 @@ impl ContImpl for WhileCont {
535
570
} ) ,
536
571
} ;
537
572
538
- ctx. next = Some ( next) ;
573
+ ctx. next = Some ( next. into_dyn_fift_cont ( ) ) ;
539
574
Ok ( cont)
540
575
}
541
576
@@ -582,7 +617,7 @@ impl<T> LoopCont<T> {
582
617
impl < T : LoopContImpl + ' static > ContImpl for LoopCont < T > {
583
618
fn run ( mut self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
584
619
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 {
586
621
inner : self . inner . clone ( ) ,
587
622
state : self . state ,
588
623
func : self . func . clone ( ) ,
@@ -606,7 +641,7 @@ impl<T: LoopContImpl + 'static> ContImpl for LoopCont<T> {
606
641
}
607
642
this. state = LoopContState :: PostExec ;
608
643
let res = self . func . clone ( ) ;
609
- ctx. next = Some ( self ) ;
644
+ ctx. next = Some ( self . into_dyn_fift_cont ( ) ) ;
610
645
break Some ( res) ;
611
646
}
612
647
LoopContState :: PostExec => {
@@ -615,7 +650,7 @@ impl<T: LoopContImpl + 'static> ContImpl for LoopCont<T> {
615
650
continue ;
616
651
}
617
652
this. state = LoopContState :: PreExec ;
618
- break Some ( self ) ;
653
+ break Some ( self . into_dyn_fift_cont ( ) ) ;
619
654
}
620
655
LoopContState :: Finalize => {
621
656
break if this. inner . finalize ( ctx) ? {
@@ -686,7 +721,7 @@ impl ContImpl for IntLitCont {
686
721
}
687
722
}
688
723
689
- pub struct LitCont ( pub Rc < dyn StackValue > ) ;
724
+ pub struct LitCont ( pub SafeRc < dyn StackValue > ) ;
690
725
691
726
impl ContImpl for LitCont {
692
727
fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
@@ -703,7 +738,7 @@ impl ContImpl for LitCont {
703
738
}
704
739
}
705
740
706
- pub struct MultiLitCont ( pub Vec < Rc < dyn StackValue > > ) ;
741
+ pub struct MultiLitCont ( pub Vec < SafeRc < dyn StackValue > > ) ;
707
742
708
743
impl ContImpl for MultiLitCont {
709
744
fn run ( self : Rc < Self > , ctx : & mut Context ) -> Result < Option < Cont > > {
@@ -778,7 +813,7 @@ impl Context<'_> {
778
813
fn insert_before_next ( & mut self , cont : & mut Option < Cont > ) {
779
814
if let Some ( next) = self . next . take ( ) {
780
815
* cont = match cont. take ( ) {
781
- Some ( prev) => Some ( Rc :: new ( SeqCont {
816
+ Some ( prev) => Some ( Cont :: new_dyn_fift_cont ( SeqCont {
782
817
first : Some ( prev) ,
783
818
second : Some ( next) ,
784
819
} ) ) ,
0 commit comments