wasm_interp: implement globals

This commit is contained in:
Brian Carroll 2022-11-21 23:47:09 +00:00
parent ff63831fd1
commit 335497c99f
No known key found for this signature in database
GPG key ID: 5C7B2EC4101703C0
2 changed files with 48 additions and 22 deletions

View file

@ -17,16 +17,23 @@ pub struct ExecutionState<'a> {
pub call_stack: CallStack<'a>,
pub value_stack: ValueStack<'a>,
pub globals: Vec<'a, Value>,
program_counter: usize,
}
impl<'a> ExecutionState<'a> {
pub fn new(arena: &'a Bump, memory_pages: u32, program_counter: usize) -> Self {
pub fn new<G>(arena: &'a Bump, memory_pages: u32, program_counter: usize, globals: G) -> Self
where
G: IntoIterator<Item = Value>,
{
let mem_bytes = memory_pages * MemorySection::PAGE_SIZE;
ExecutionState {
memory: Vec::with_capacity_in(mem_bytes as usize, arena),
call_stack: CallStack::new(arena),
value_stack: ValueStack::new(arena),
globals: Vec::from_iter_in(globals, arena),
program_counter,
}
}
@ -101,10 +108,12 @@ impl<'a> ExecutionState<'a> {
self.call_stack.set_local(index, value);
}
GETGLOBAL => {
todo!("{:?}", op_code);
let index = self.fetch_immediate_u32(module);
self.value_stack.push(self.globals[index as usize]);
}
SETGLOBAL => {
todo!("{:?}", op_code);
let index = self.fetch_immediate_u32(module);
self.globals[index as usize] = self.value_stack.pop();
}
I32LOAD => {
todo!("{:?}", op_code);

View file

@ -7,12 +7,6 @@ use roc_wasm_module::{opcodes::OpCode, SerialBuffer, ValueType, WasmModule};
const DEFAULT_MEMORY_PAGES: u32 = 1;
const DEFAULT_PROGRAM_COUNTER: usize = 0;
// #[test]
// fn test_unreachable() {}
// #[test]
// fn test_nop() {}
// #[test]
// fn test_block() {}
@ -55,7 +49,7 @@ const DEFAULT_PROGRAM_COUNTER: usize = 0;
#[test]
fn test_set_get_local() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
let local_decls = [
@ -84,7 +78,7 @@ fn test_set_get_local() {
#[test]
fn test_tee_get_local() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
let local_decls = [
@ -111,11 +105,34 @@ fn test_tee_get_local() {
assert_eq!(state.value_stack.pop(), Value::I32(12345));
}
// #[test]
// fn test_getglobal() {}
#[test]
fn test_global() {
let arena = Bump::new();
let mut state = ExecutionState::new(
&arena,
DEFAULT_MEMORY_PAGES,
DEFAULT_PROGRAM_COUNTER,
[Value::F64(1.11), Value::I32(222), Value::F64(3.33)],
);
let mut module = WasmModule::new(&arena);
// #[test]
// fn test_setglobal() {}
module.code.bytes.push(OpCode::GETGLOBAL as u8);
module.code.bytes.encode_u32(1);
module.code.bytes.push(OpCode::I32CONST as u8);
module.code.bytes.encode_i32(555);
module.code.bytes.push(OpCode::SETGLOBAL as u8);
module.code.bytes.encode_u32(1);
module.code.bytes.push(OpCode::GETGLOBAL as u8);
module.code.bytes.encode_u32(1);
state.execute_next_instruction(&module);
state.execute_next_instruction(&module);
state.execute_next_instruction(&module);
state.execute_next_instruction(&module);
assert_eq!(state.value_stack.len(), 2);
assert_eq!(state.value_stack.pop(), Value::I32(555));
assert_eq!(state.value_stack.pop(), Value::I32(222));
}
// #[test]
// fn test_i32load() {}
@ -195,7 +212,7 @@ fn test_tee_get_local() {
#[test]
fn test_i32const() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::I32CONST as u8);
@ -208,7 +225,7 @@ fn test_i32const() {
#[test]
fn test_i64const() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::I64CONST as u8);
@ -221,7 +238,7 @@ fn test_i64const() {
#[test]
fn test_f32const() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::F32CONST as u8);
@ -234,7 +251,7 @@ fn test_f32const() {
#[test]
fn test_f64const() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::F64CONST as u8);
@ -358,7 +375,7 @@ fn test_f64const() {
#[test]
fn test_i32add() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::I32CONST as u8);
@ -376,7 +393,7 @@ fn test_i32add() {
#[test]
fn test_i32sub() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::I32CONST as u8);
@ -394,7 +411,7 @@ fn test_i32sub() {
#[test]
fn test_i32mul() {
let arena = Bump::new();
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER);
let mut state = ExecutionState::new(&arena, DEFAULT_MEMORY_PAGES, DEFAULT_PROGRAM_COUNTER, []);
let mut module = WasmModule::new(&arena);
module.code.bytes.push(OpCode::I32CONST as u8);