mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
wasm_interp: implement globals
This commit is contained in:
parent
ff63831fd1
commit
335497c99f
2 changed files with 48 additions and 22 deletions
|
@ -17,16 +17,23 @@ pub struct ExecutionState<'a> {
|
||||||
pub call_stack: CallStack<'a>,
|
pub call_stack: CallStack<'a>,
|
||||||
|
|
||||||
pub value_stack: ValueStack<'a>,
|
pub value_stack: ValueStack<'a>,
|
||||||
|
|
||||||
|
pub globals: Vec<'a, Value>,
|
||||||
|
|
||||||
program_counter: usize,
|
program_counter: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ExecutionState<'a> {
|
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;
|
let mem_bytes = memory_pages * MemorySection::PAGE_SIZE;
|
||||||
ExecutionState {
|
ExecutionState {
|
||||||
memory: Vec::with_capacity_in(mem_bytes as usize, arena),
|
memory: Vec::with_capacity_in(mem_bytes as usize, arena),
|
||||||
call_stack: CallStack::new(arena),
|
call_stack: CallStack::new(arena),
|
||||||
value_stack: ValueStack::new(arena),
|
value_stack: ValueStack::new(arena),
|
||||||
|
globals: Vec::from_iter_in(globals, arena),
|
||||||
program_counter,
|
program_counter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,10 +108,12 @@ impl<'a> ExecutionState<'a> {
|
||||||
self.call_stack.set_local(index, value);
|
self.call_stack.set_local(index, value);
|
||||||
}
|
}
|
||||||
GETGLOBAL => {
|
GETGLOBAL => {
|
||||||
todo!("{:?}", op_code);
|
let index = self.fetch_immediate_u32(module);
|
||||||
|
self.value_stack.push(self.globals[index as usize]);
|
||||||
}
|
}
|
||||||
SETGLOBAL => {
|
SETGLOBAL => {
|
||||||
todo!("{:?}", op_code);
|
let index = self.fetch_immediate_u32(module);
|
||||||
|
self.globals[index as usize] = self.value_stack.pop();
|
||||||
}
|
}
|
||||||
I32LOAD => {
|
I32LOAD => {
|
||||||
todo!("{:?}", op_code);
|
todo!("{:?}", op_code);
|
||||||
|
|
|
@ -7,12 +7,6 @@ use roc_wasm_module::{opcodes::OpCode, SerialBuffer, ValueType, WasmModule};
|
||||||
const DEFAULT_MEMORY_PAGES: u32 = 1;
|
const DEFAULT_MEMORY_PAGES: u32 = 1;
|
||||||
const DEFAULT_PROGRAM_COUNTER: usize = 0;
|
const DEFAULT_PROGRAM_COUNTER: usize = 0;
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_unreachable() {}
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn test_nop() {}
|
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn test_block() {}
|
// fn test_block() {}
|
||||||
|
|
||||||
|
@ -55,7 +49,7 @@ const DEFAULT_PROGRAM_COUNTER: usize = 0;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_get_local() {
|
fn test_set_get_local() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
let local_decls = [
|
let local_decls = [
|
||||||
|
@ -84,7 +78,7 @@ fn test_set_get_local() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tee_get_local() {
|
fn test_tee_get_local() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
let local_decls = [
|
let local_decls = [
|
||||||
|
@ -111,11 +105,34 @@ fn test_tee_get_local() {
|
||||||
assert_eq!(state.value_stack.pop(), Value::I32(12345));
|
assert_eq!(state.value_stack.pop(), Value::I32(12345));
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn test_getglobal() {}
|
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]
|
module.code.bytes.push(OpCode::GETGLOBAL as u8);
|
||||||
// fn test_setglobal() {}
|
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]
|
// #[test]
|
||||||
// fn test_i32load() {}
|
// fn test_i32load() {}
|
||||||
|
@ -195,7 +212,7 @@ fn test_tee_get_local() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i32const() {
|
fn test_i32const() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::I32CONST as u8);
|
module.code.bytes.push(OpCode::I32CONST as u8);
|
||||||
|
@ -208,7 +225,7 @@ fn test_i32const() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64const() {
|
fn test_i64const() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::I64CONST as u8);
|
module.code.bytes.push(OpCode::I64CONST as u8);
|
||||||
|
@ -221,7 +238,7 @@ fn test_i64const() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_f32const() {
|
fn test_f32const() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::F32CONST as u8);
|
module.code.bytes.push(OpCode::F32CONST as u8);
|
||||||
|
@ -234,7 +251,7 @@ fn test_f32const() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_f64const() {
|
fn test_f64const() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::F64CONST as u8);
|
module.code.bytes.push(OpCode::F64CONST as u8);
|
||||||
|
@ -358,7 +375,7 @@ fn test_f64const() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i32add() {
|
fn test_i32add() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::I32CONST as u8);
|
module.code.bytes.push(OpCode::I32CONST as u8);
|
||||||
|
@ -376,7 +393,7 @@ fn test_i32add() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i32sub() {
|
fn test_i32sub() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::I32CONST as u8);
|
module.code.bytes.push(OpCode::I32CONST as u8);
|
||||||
|
@ -394,7 +411,7 @@ fn test_i32sub() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i32mul() {
|
fn test_i32mul() {
|
||||||
let arena = Bump::new();
|
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 mut module = WasmModule::new(&arena);
|
||||||
|
|
||||||
module.code.bytes.push(OpCode::I32CONST as u8);
|
module.code.bytes.push(OpCode::I32CONST as u8);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue