Working interpreter
This commit is contained in:
parent
58c89bbbb6
commit
49a907da25
|
@ -121,12 +121,9 @@ impl InterpContext {
|
|||
multivalue[0]
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let idx = match args[0] {
|
||||
ConstVal::I32(x) => x,
|
||||
_ => panic!(),
|
||||
};
|
||||
let func = self.tables[table_index].elements[idx as usize];
|
||||
self.call(module, func, &args[1..])?
|
||||
let idx = args.last().unwrap().as_u32().unwrap() as usize;
|
||||
let func = self.tables[table_index].elements[idx];
|
||||
self.call(module, func, &args[..args.len() - 1])?
|
||||
}
|
||||
&ValueDef::Operator(ref op, ref args, _) => {
|
||||
let args = args
|
||||
|
@ -167,10 +164,7 @@ impl InterpContext {
|
|||
} => {
|
||||
let cond = body.resolve_alias(cond);
|
||||
let cond = frame.values.get(&cond).unwrap();
|
||||
let cond = match cond[0] {
|
||||
ConstVal::I32(x) => x != 0,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let cond = cond[0].as_u32().unwrap() != 0;
|
||||
if cond {
|
||||
frame.apply_target(body, if_true);
|
||||
} else {
|
||||
|
@ -184,10 +178,7 @@ impl InterpContext {
|
|||
} => {
|
||||
let value = body.resolve_alias(value);
|
||||
let value = frame.values.get(&value).unwrap();
|
||||
let value = match value[0] {
|
||||
ConstVal::I32(x) => x,
|
||||
_ => unreachable!(),
|
||||
} as usize;
|
||||
let value = value[0].as_u32().unwrap() as usize;
|
||||
if value < targets.len() {
|
||||
frame.apply_target(body, &targets[value]);
|
||||
} else {
|
||||
|
@ -209,8 +200,60 @@ impl InterpContext {
|
|||
}
|
||||
}
|
||||
|
||||
fn call_import(&mut self, name: &str, _args: &[ConstVal]) -> Option<SmallVec<[ConstVal; 2]>> {
|
||||
todo!("call_import: {}", name);
|
||||
fn call_import(&mut self, name: &str, args: &[ConstVal]) -> Option<SmallVec<[ConstVal; 2]>> {
|
||||
let mem = &mut self.memories[Memory::from(0)];
|
||||
match name {
|
||||
"__wasi_fd_prestat_get" => {
|
||||
Some(smallvec![ConstVal::I32(8)]) // BADF
|
||||
}
|
||||
"__wasi_args_sizes_get" => {
|
||||
let p_argc = args[0].as_u32().unwrap();
|
||||
let p_argv_size = args[1].as_u32().unwrap();
|
||||
write_u32(mem, p_argc, 0);
|
||||
write_u32(mem, p_argv_size, 0);
|
||||
Some(smallvec![ConstVal::I32(0)])
|
||||
}
|
||||
"__wasi_args_get" => Some(smallvec![ConstVal::I32(0)]),
|
||||
"__wasi_fd_fdstat_get" => {
|
||||
let fd = args[0].as_u32().unwrap();
|
||||
let p_fdstat_t = args[1].as_u32().unwrap();
|
||||
if fd == 1 {
|
||||
write_u32(mem, p_fdstat_t + 0, 2); // filetype = CHAR
|
||||
write_u32(mem, p_fdstat_t + 4, 0); // flags = 0
|
||||
write_u32(mem, p_fdstat_t + 8, 0x40); // rights_base = WRITE
|
||||
write_u32(mem, p_fdstat_t + 12, 0); // rights_inheriting = 0
|
||||
Some(smallvec![ConstVal::I32(0)])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
"__wasi_fd_write" => {
|
||||
let fd = args[0].as_u32().unwrap();
|
||||
let p_iovs = args[1].as_u32().unwrap();
|
||||
let iovs_len = args[2].as_u32().unwrap();
|
||||
let p_nwritten = args[3].as_u32().unwrap();
|
||||
if fd == 1 {
|
||||
let mut written = 0;
|
||||
for i in 0..iovs_len {
|
||||
let iov_entry = p_iovs + 8 * i;
|
||||
let base = read_u32(mem, iov_entry) as usize;
|
||||
let len = read_u32(mem, iov_entry + 4) as usize;
|
||||
let data = &mem.data[base..(base + len)];
|
||||
print!("{}", std::str::from_utf8(data).unwrap());
|
||||
written += len;
|
||||
}
|
||||
write_u32(mem, p_nwritten, written as u32);
|
||||
Some(smallvec![ConstVal::I32(0)])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
"__wasi_proc_exit" => {
|
||||
eprintln!("WASI exit: {:?}", args[0]);
|
||||
None
|
||||
}
|
||||
_ => panic!("Unknown import: {} with args: {:?}", name, args),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +310,15 @@ pub enum ConstVal {
|
|||
None,
|
||||
}
|
||||
|
||||
impl ConstVal {
|
||||
pub fn as_u32(self) -> Option<u32> {
|
||||
match self {
|
||||
Self::I32(x) => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn const_eval(
|
||||
op: &Operator,
|
||||
vals: &[ConstVal],
|
||||
|
|
Loading…
Reference in a new issue