diff --git a/crates/wasm_interp/src/lib.rs b/crates/wasm_interp/src/lib.rs index dbd01480ea..fd6f2fe500 100644 --- a/crates/wasm_interp/src/lib.rs +++ b/crates/wasm_interp/src/lib.rs @@ -1,5 +1,6 @@ mod call_stack; mod execute; +pub mod test_utils; mod value_stack; // Exposed for testing only. Should eventually become private. diff --git a/crates/wasm_interp/src/test_utils.rs b/crates/wasm_interp/src/test_utils.rs new file mode 100644 index 0000000000..35d4e8f018 --- /dev/null +++ b/crates/wasm_interp/src/test_utils.rs @@ -0,0 +1,64 @@ +use crate::{Action, ExecutionState}; +use bumpalo::{collections::Vec, Bump}; +use roc_wasm_module::{opcodes::OpCode, SerialBuffer, Value, WasmModule}; + +pub fn default_state(arena: &Bump) -> ExecutionState { + let pages = 1; + let program_counter = 0; + let globals = []; + ExecutionState::new(arena, pages, program_counter, globals) +} + +pub fn const_value(buf: &mut Vec<'_, u8>, value: Value) { + use Value::*; + match value { + I32(x) => { + buf.push(OpCode::I32CONST as u8); + buf.encode_i32(x); + } + I64(x) => { + buf.push(OpCode::I64CONST as u8); + buf.encode_i64(x); + } + F32(x) => { + buf.push(OpCode::F32CONST as u8); + buf.encode_f32(x); + } + F64(x) => { + buf.push(OpCode::F64CONST as u8); + buf.encode_f64(x); + } + } +} + +pub fn test_op_example(op: OpCode, args: A, expected: Value) +where + A: IntoIterator, +{ + let arena = Bump::new(); + let mut module = WasmModule::new(&arena); + + { + let buf = &mut module.code.bytes; + buf.push(0); // no locals + for arg in args { + const_value(buf, arg); + } + buf.push(op as u8); + buf.push(OpCode::END as u8); // end function + } + + let mut state = default_state(&arena); + state.call_stack.push_frame( + 0, + 0, + &[], + &mut state.value_stack, + &module.code.bytes, + &mut state.program_counter, + ); + + while let Action::Continue = state.execute_next_instruction(&module) {} + + assert_eq!(state.value_stack.pop(), expected); +} diff --git a/crates/wasm_interp/tests/test_opcodes.rs b/crates/wasm_interp/tests/test_opcodes.rs index 9a26dcd735..2378c7356b 100644 --- a/crates/wasm_interp/tests/test_opcodes.rs +++ b/crates/wasm_interp/tests/test_opcodes.rs @@ -1,6 +1,7 @@ #![cfg(test)] use bumpalo::{collections::Vec, Bump}; +use roc_wasm_interp::test_utils::{const_value, default_state}; use roc_wasm_interp::{Action, ExecutionState, ValueStack}; use roc_wasm_module::{ opcodes::OpCode, @@ -9,35 +10,6 @@ use roc_wasm_module::{ WasmModule, }; -fn default_state(arena: &Bump) -> ExecutionState { - let pages = 1; - let program_counter = 0; - let globals = []; - ExecutionState::new(arena, pages, program_counter, globals) -} - -fn const_value(buf: &mut Vec<'_, u8>, value: Value) { - use Value::*; - match value { - I32(x) => { - buf.push(OpCode::I32CONST as u8); - buf.encode_i32(x); - } - I64(x) => { - buf.push(OpCode::I64CONST as u8); - buf.encode_i64(x); - } - F32(x) => { - buf.push(OpCode::F32CONST as u8); - buf.encode_f32(x); - } - F64(x) => { - buf.push(OpCode::F64CONST as u8); - buf.encode_f64(x); - } - } -} - #[test] fn test_loop() { test_loop_help(10, 55);