Skip to content

Commit be88c74

Browse files
committed
wip: Add vm
1 parent 3616bfd commit be88c74

21 files changed

+895
-2622
lines changed

Cargo.lock

Lines changed: 230 additions & 218 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,26 @@ anyhow = "1.0"
2020
base64 = "0.22"
2121
crc = "3.0"
2222
dyn-clone = "1.0"
23-
everscale-crypto = "0.2"
23+
everscale-crypto = "0.3.0"
2424
hex = "0.4"
2525
num-bigint = "0.4"
2626
num-integer = "0.1"
2727
num-traits = "0.2"
2828
rand = "0.8"
2929
sha2 = "0.10"
30-
thiserror = "1.0"
30+
thiserror = "2.0"
3131
unicode-segmentation = "1.0"
3232

3333
everscale-types = { version = "0.1.2", default-features = false, features = [
3434
"sync",
3535
"base64",
3636
"models",
3737
] }
38+
tycho-vm = { git = "https://github.com/broxus/tycho-vm.git", features = [
39+
"dump",
40+
], rev = "a96840aab2d481019119bcc254dba538d559780a" }
3841

3942
fift-proc = { path = "./proc", version = "=0.1.15" }
4043

4144
[patch.crates-io]
42-
everscale-types = { git = "https://github.com/broxus/everscale-types.git", rev = "6e3c289f9bbf46337b11b24656a9c87ce409323e" }
45+
everscale-types = { git = "https://github.com/broxus/everscale-types.git", rev = "3b71c951d876213ad4e03f071182be0b1711d77c" }

cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ bitflags = "2.3"
1919
console = "0.15"
2020
rustyline = { version = "15.0", default-features = false }
2121
unicode-width = "0.2"
22+
tycho-vm = { git = "https://github.com/broxus/tycho-vm.git", rev = "a96840aab2d481019119bcc254dba538d559780a" }
2223

2324
fift = { path = "..", version = "=0.1.23" }
2425
fift-libs = { path = "../libs", version = "0.1.23" }

cli/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ use std::process::ExitCode;
44
use anyhow::Result;
55
use argh::FromArgs;
66
use console::style;
7-
use unicode_width::UnicodeWidthStr;
8-
97
use fift::core::lexer::LexerPosition;
108
use fift::core::{Environment, SourceBlock};
9+
use unicode_width::UnicodeWidthStr;
1110

1211
use self::env::SystemEnvironment;
1312
use self::input::LineReader;

cli/src/modules/args.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
use std::rc::Rc;
22

33
use anyhow::Result;
4-
54
use fift::core::*;
5+
use tycho_vm::SafeRc;
66

77
pub struct CmdArgsUtils {
8-
name: Rc<dyn StackValue>,
9-
args: Vec<Rc<dyn StackValue>>,
8+
name: SafeRc<dyn StackValue>,
9+
args: Vec<SafeRc<dyn StackValue>>,
1010
}
1111

1212
impl CmdArgsUtils {
1313
pub fn new(args: Vec<String>) -> Self {
1414
let mut args = args.into_iter();
1515

16-
let name = Rc::new(args.next().unwrap_or_default()) as Rc<dyn StackValue>;
16+
let name = SafeRc::new_dyn_fift_value(args.next().unwrap_or_default());
1717

1818
let args = args
19-
.map(|value| Rc::new(value) as Rc<dyn StackValue>)
19+
.map(|value| SafeRc::new_dyn_fift_value(value))
2020
.collect::<Vec<_>>();
2121

2222
Self { name, args }
@@ -27,28 +27,42 @@ impl CmdArgsUtils {
2727
impl CmdArgsUtils {
2828
#[init]
2929
fn init(&self, d: &mut Dictionary) -> Result<()> {
30-
d.define_word("$0 ", Rc::new(cont::LitCont(self.name.clone())))?;
30+
d.define_word(
31+
"$0 ",
32+
Cont::new_dyn_fift_cont(cont::LitCont(self.name.clone())),
33+
)?;
3134

3235
let mut list = Stack::make_null();
3336
for (i, arg) in self.args.iter().enumerate().rev() {
3437
list = cons(arg.clone(), list);
35-
d.define_word(format!("${} ", i + 1), Rc::new(cont::LitCont(arg.clone())))?;
38+
d.define_word(
39+
format!("${} ", i + 1),
40+
Cont::new_dyn_fift_cont(cont::LitCont(arg.clone())),
41+
)?;
3642
}
3743

38-
d.define_word("$# ", Rc::new(cont::IntLitCont::from(self.args.len())))?;
44+
d.define_word(
45+
"$# ",
46+
Cont::new_dyn_fift_cont(cont::IntLitCont::from(self.args.len())),
47+
)?;
3948

4049
let mut all_args = Vec::with_capacity(1 + self.args.len());
4150
all_args.push(self.name.clone());
4251
all_args.extend_from_slice(&self.args);
43-
d.define_word("$() ", Rc::new(CmdArgCont(all_args)))?;
52+
d.define_word("$() ", Cont::new_dyn_fift_cont(CmdArgCont(all_args)))?;
4453

45-
d.define_word("$* ", Rc::new(cont::LitCont(Rc::new(SharedBox::new(list)))))?;
54+
d.define_word(
55+
"$* ",
56+
Cont::new_dyn_fift_cont(cont::LitCont(SafeRc::new_dyn_fift_value(SharedBox::new(
57+
list,
58+
)))),
59+
)?;
4660

4761
Ok(())
4862
}
4963
}
5064

51-
struct CmdArgCont(Vec<Rc<dyn StackValue>>);
65+
struct CmdArgCont(Vec<SafeRc<dyn StackValue>>);
5266

5367
impl ContImpl for CmdArgCont {
5468
fn run(self: Rc<Self>, ctx: &mut Context) -> Result<Option<Cont>> {
@@ -65,6 +79,6 @@ impl ContImpl for CmdArgCont {
6579
}
6680
}
6781

68-
fn cons(head: Rc<dyn StackValue>, tail: Rc<dyn StackValue>) -> Rc<dyn StackValue> {
69-
Rc::new(vec![head, tail])
82+
fn cons(head: SafeRc<dyn StackValue>, tail: SafeRc<dyn StackValue>) -> SafeRc<dyn StackValue> {
83+
SafeRc::new_dyn_fift_value(vec![head, tail])
7084
}

cli/src/modules/shell.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::process::Stdio;
33

44
use anyhow::{Context as _, Result};
55
use bitflags::bitflags;
6-
76
use fift::core::*;
87

98
pub struct ShellUtils;

rustfmt.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
format_code_in_doc_comments = true
2+
imports_granularity = "Module"
3+
normalize_comments = true
4+
overflow_delimited_expr = true
5+
group_imports = "StdExternalCrate"

src/core/cont.rs

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,46 @@ use std::rc::Rc;
33

44
use anyhow::Result;
55
use num_bigint::BigInt;
6+
use tycho_vm::{SafeDelete, SafeRc};
67

78
use super::{Context, Dictionary, Stack, StackValue, StackValueType, WordList};
9+
use crate::core::DynFiftValue;
810
use 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;
85118
impl 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

288323
impl 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> {
582617
impl<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

691726
impl 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

708743
impl 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

Comments
 (0)