1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
pub mod pwlp;
#[cfg(feature = "wasm")]
mod lib {
use super::pwlp::program::Program;
use super::pwlp::strip::DummyStrip;
use super::pwlp::vm::{Outcome, VM};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn compile(source: &str) -> Result<Vec<u8>, JsValue> {
match Program::from_source(&source) {
Ok(prg) => Ok(prg.code.to_vec()),
Err(s) => Err(JsValue::from(s)),
}
}
#[wasm_bindgen]
pub fn assemble(source: &str) -> Result<String, JsValue> {
match Program::from_source(&source) {
Ok(prg) => Ok(format!("{:?}", prg)),
Err(s) => Err(JsValue::from(s)),
}
}
#[wasm_bindgen]
pub fn run(
binary: &[u8],
length: u32,
instruction_limit: Option<usize>,
) -> Result<String, JsValue> {
let program = Program::from_binary(binary.to_vec());
let strip = DummyStrip::new(length, true);
let mut vm = VM::new(Box::new(strip));
vm.set_deterministic(true);
vm.set_trace(false);
let mut state = vm.start(program, instruction_limit);
let mut running = true;
let mut output = String::new();
while running {
match state.run(None) {
Outcome::Yielded => {}
Outcome::GlobalInstructionLimitReached
| Outcome::LocalInstructionLimitReached
| Outcome::Ended => running = false,
Outcome::Error(e) => {
return Err(JsValue::from(format!(
"Error in VM at pc={}: {:?}",
state.pc(),
e
)));
}
}
output += &state.vm.strip().to_string();
output += "\n";
}
Ok(output)
}
}
#[cfg(feature = "wasm")]
pub use lib::*;