Skip to content

Commit 86021d8

Browse files
author
Adel Prokurov
committed
Read bytecode files and execute em
1 parent 85151b2 commit 86021d8

File tree

8 files changed

+374
-84
lines changed

8 files changed

+374
-84
lines changed

examples/switch.jazz

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
var b = 4
1+
var b = "hello,world"
22

3-
switch b {
4-
0 -> $print(0)
5-
1 -> $print(1)
6-
2 -> $print(2)
7-
_ -> $print(b)
3+
switch B {
4+
"hello,world" -> $print("Hello!")
85
}

jazz-vm/Cargo.lock

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

jazz-vm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ fnv = "1.0"
1111
libloading = "0.5.0"
1212
libc = "0.2"
1313
borrowed-thread = "0.1"
14+
byteorder = "1.3"

jazz-vm/src/main.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
2+
extern crate jazzvm;
3+
4+
use jazzvm::vm::*;
5+
use jazzvm::module::*;
6+
use jazzvm::builtins::*;
7+
use jazzvm::fields::*;
8+
9+
use std::env::args;
10+
111
fn main() {
12+
let args = args().collect::<Vec<String>>();
13+
14+
let mut vm = VM::new();
15+
init_fields();
16+
register_builtins(&mut vm);
217

18+
use std::io::Read;
19+
let mut f = std::fs::File::open(&args[1]).unwrap();
20+
let mut buf = vec![];
21+
f.read_to_end(&mut buf).unwrap();
22+
let reader = Reader {
23+
code: buf,
24+
pc: 0,
25+
};
26+
use std::path::Path;
27+
let p = Path::new(&args[1]);
28+
let f = p.file_stem().unwrap().to_str().unwrap().to_owned();
29+
30+
let mut module = read_module(reader, &f);
31+
32+
vm.code = module.code.clone();
33+
*VM_THREAD.borrow_mut() = vm;
34+
VM_THREAD.borrow_mut().interp(&mut module);
335
}

jazz-vm/src/module.rs

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,247 @@ impl Module {
2222
}
2323
}
2424
}
25+
26+
use byteorder::{ByteOrder, LittleEndian};
27+
28+
pub struct Reader {
29+
pub code: Vec<u8>,
30+
pub pc: usize,
31+
}
32+
33+
impl Reader {
34+
pub fn read_u8(&mut self) -> u8 {
35+
let b = self.code[self.pc];
36+
self.pc += 1;
37+
b
38+
}
39+
pub fn read_u16(&mut self) -> u16 {
40+
let short: [u8; 2] = [self.read_u8(), self.read_u8()];
41+
unsafe { std::mem::transmute(short) }
42+
}
43+
pub fn read_u32(&mut self) -> u32 {
44+
let int: [u16; 2] = [self.read_u16(), self.read_u16()];
45+
unsafe { std::mem::transmute(int) }
46+
}
47+
48+
pub fn read_u64(&mut self) -> u64 {
49+
let long: [u32; 2] = [self.read_u32(), self.read_u32()];
50+
unsafe { std::mem::transmute(long) }
51+
}
52+
}
53+
54+
use crate::opcode::Opcode;
55+
use crate::value::*;
56+
pub fn read_module(mut reader: Reader, name: &str) -> P<Module> {
57+
let nglobals = reader.read_u32();
58+
let nfields = reader.read_u32();
59+
let ncodesize = reader.read_u32();
60+
61+
let module = P(Module::new(name));
62+
for _ in 0..nglobals {
63+
let b = reader.read_u8();
64+
match b {
65+
1 => {
66+
let off = reader.read_u32() as usize;
67+
let nargs = reader.read_u16() as i32;
68+
let f = Function {
69+
var: FuncVar::Offset(off),
70+
nargs: nargs,
71+
env: P(Value::Array(P(vec![]))),
72+
module: module.clone(),
73+
jit: false,
74+
yield_point: 0,
75+
};
76+
module.borrow_mut().globals.push(P(Value::Func(P(f))));
77+
}
78+
_ => unimplemented!(),
79+
}
80+
}
81+
82+
for _ in 0..nfields {
83+
let key = reader.read_u64();
84+
let len = reader.read_u16();
85+
let mut buf = vec![];
86+
for _ in 0..len {
87+
buf.push(reader.read_u8());
88+
}
89+
let s = String::from_utf8(buf).unwrap();
90+
module.borrow_mut().fields.insert(key, s);
91+
}
92+
let mut code = vec![];
93+
for _ in 0..ncodesize {
94+
let op = reader.read_u8();
95+
match op {
96+
0 => {
97+
let int = reader.read_u64();
98+
code.push(Opcode::LdInt(int as i64));
99+
}
100+
1 => {
101+
let float = reader.read_u64();
102+
code.push(Opcode::LdFloat(f64::from_bits(float)));
103+
}
104+
2 => {
105+
let len = reader.read_u16();
106+
let mut buf = vec![];
107+
for _ in 0..len {
108+
buf.push(reader.read_u8());
109+
}
110+
let s = String::from_utf8(buf).unwrap();
111+
code.push(Opcode::LdStr(s));
112+
}
113+
3 => {
114+
let b2 = reader.read_u8();
115+
let op = match b2 {
116+
0 => Opcode::LdFalse,
117+
1 => Opcode::LdTrue,
118+
2 => Opcode::LdNull,
119+
3 => Opcode::LdThis,
120+
4 => {
121+
let h = reader.read_u64();
122+
Opcode::LdField(h)
123+
}
124+
5 => {
125+
let id = reader.read_u32();
126+
Opcode::LdLocal(id)
127+
}
128+
6 => {
129+
let id = reader.read_u32();
130+
Opcode::LdGlobal(id)
131+
}
132+
7 => {
133+
let id = reader.read_u32();
134+
Opcode::LdEnv(id)
135+
}
136+
8 => {
137+
let id = reader.read_u32();
138+
Opcode::LdBuiltin(id)
139+
}
140+
9 => {
141+
let id = reader.read_u32();
142+
Opcode::LdIndex(id)
143+
}
144+
10 => Opcode::LdArray,
145+
_ => unreachable!(),
146+
};
147+
code.push(op);
148+
}
149+
4 => {
150+
let b2 = reader.read_u8();
151+
let op = match b2 {
152+
0 => {
153+
let id = reader.read_u32();
154+
Opcode::SetLocal(id)
155+
}
156+
1 => {
157+
let id = reader.read_u32();
158+
Opcode::SetGlobal(id)
159+
}
160+
2 => {
161+
let id = reader.read_u32();
162+
Opcode::SetEnv(id)
163+
}
164+
3 => {
165+
let id = reader.read_u64();
166+
Opcode::SetField(id)
167+
}
168+
4 => Opcode::SetArray,
169+
5 => {
170+
let idx = reader.read_u32();
171+
Opcode::SetIndex(idx)
172+
}
173+
6 => Opcode::SetThis,
174+
_ => unreachable!(),
175+
};
176+
code.push(op);
177+
}
178+
5 => {
179+
let count = reader.read_u16();
180+
code.push(Opcode::Pop(count as u32));
181+
}
182+
6 => {
183+
let count = reader.read_u16();
184+
code.push(Opcode::Apply(count as _));
185+
}
186+
7 => {
187+
let count = reader.read_u16();
188+
code.push(Opcode::Call(count as _));
189+
}
190+
8 => {
191+
let count = reader.read_u16();
192+
code.push(Opcode::TailCall(count as _));
193+
}
194+
9 => {
195+
let count = reader.read_u16();
196+
code.push(Opcode::ObjCall(count as _));
197+
}
198+
10 => {
199+
let b2 = reader.read_u8();
200+
match b2 {
201+
0 => {
202+
let dest = reader.read_u32();
203+
code.push(Opcode::Jump(dest));
204+
}
205+
1 => {
206+
let dest = reader.read_u32();
207+
code.push(Opcode::JumpIf(dest));
208+
}
209+
2 => {
210+
let dest = reader.read_u32();
211+
code.push(Opcode::JumpIfNot(dest));
212+
}
213+
_ => unreachable!(),
214+
}
215+
}
216+
11 => code.push(Opcode::Ret),
217+
12 => {
218+
let c = reader.read_u32();
219+
code.push(Opcode::MakeEnv(c));
220+
}
221+
13 => {
222+
let c = reader.read_u32();
223+
code.push(Opcode::MakeArray(c));
224+
}
225+
14 => {
226+
code.push(Opcode::Neg);
227+
}
228+
15 => code.push(Opcode::Bool),
229+
16 => code.push(Opcode::Not),
230+
17 => code.push(Opcode::IsNull),
231+
18 => code.push(Opcode::IsNotNull),
232+
19 => {
233+
let b2 = reader.read_u8();
234+
use Opcode::*;
235+
let op = match b2 {
236+
0 => Add,
237+
1 => Sub,
238+
2 => Mul,
239+
3 => Div,
240+
4 => Rem,
241+
5 => Shl,
242+
6 => Shr,
243+
7 => UShr,
244+
8 => Or,
245+
9 => And,
246+
10 => Xor,
247+
11 => Eq,
248+
12 => Neq,
249+
13 => Lt,
250+
14 => Lte,
251+
15 => Gt,
252+
16 => Gte,
253+
_ => unreachable!(),
254+
};
255+
code.push(op);
256+
}
257+
20 => code.push(Opcode::Nop),
258+
21 => code.push(Opcode::TypeOf),
259+
22 => code.push(Opcode::Hash),
260+
23 => code.push(Opcode::New),
261+
24 => code.push(Opcode::Yield),
262+
25 => code.push(Opcode::Last),
263+
_ => unimplemented!(),
264+
}
265+
}
266+
module.borrow_mut().code = code;
267+
module
268+
}

0 commit comments

Comments
 (0)