mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
wasm_interp: create execute
module
This commit is contained in:
parent
ae4131d3ac
commit
45556b95bd
544
crates/wasm_interp/src/execute.rs
Normal file
544
crates/wasm_interp/src/execute.rs
Normal file
@ -0,0 +1,544 @@
|
||||
use bumpalo::{collections::Vec, Bump};
|
||||
use roc_wasm_module::opcodes::OpCode;
|
||||
use roc_wasm_module::WasmModule;
|
||||
|
||||
use crate::call_stack::CallStack;
|
||||
use crate::value_stack::ValueStack;
|
||||
|
||||
pub struct ExecutionState<'a> {
|
||||
memory: Vec<'a, u8>,
|
||||
call_stack: CallStack<'a>,
|
||||
value_stack: ValueStack<'a>,
|
||||
program_counter: usize,
|
||||
}
|
||||
|
||||
impl<'a> ExecutionState<'a> {
|
||||
fn next(&mut self, module: WasmModule<'a>) {
|
||||
use OpCode::*;
|
||||
|
||||
let op_code = OpCode::from(module.code.bytes[self.program_counter]);
|
||||
self.program_counter += 1;
|
||||
match op_code {
|
||||
UNREACHABLE => {
|
||||
unreachable!("WebAssembly tried to execute an `unreachable` instruction.");
|
||||
}
|
||||
NOP => {}
|
||||
BLOCK => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
LOOP => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
IF => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
ELSE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
END => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
BR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
BRIF => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
BRTABLE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
RETURN => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
CALL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
CALLINDIRECT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
DROP => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
SELECT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
GETLOCAL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
SETLOCAL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
TEELOCAL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
GETGLOBAL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
SETGLOBAL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LOAD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32LOAD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64LOAD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LOAD8S => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LOAD8U => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LOAD16S => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LOAD16U => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD8S => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD8U => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD16S => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD16U => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD32S => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LOAD32U => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32STORE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64STORE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32STORE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64STORE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32STORE8 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32STORE16 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64STORE8 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64STORE16 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64STORE32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
CURRENTMEMORY => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
GROWMEMORY => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32CONST => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64CONST => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32CONST => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64CONST => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32EQZ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32EQ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32NE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LTS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LTU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32GTS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32GTU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LES => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32LEU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32GES => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32GEU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64EQZ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64EQ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64NE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LTS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LTU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64GTS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64GTU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LES => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64LEU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64GES => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64GEU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
|
||||
F32EQ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32NE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32LT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32GT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32LE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32GE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
|
||||
F64EQ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64NE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64LT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64GT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64LE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64GE => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
|
||||
I32CLZ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32CTZ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32POPCNT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32ADD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32SUB => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32MUL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32DIVS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32DIVU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32REMS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32REMU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32AND => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32OR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32XOR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32SHL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32SHRS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32SHRU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32ROTL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32ROTR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
|
||||
I64CLZ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64CTZ => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64POPCNT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64ADD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64SUB => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64MUL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64DIVS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64DIVU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64REMS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64REMU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64AND => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64OR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64XOR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64SHL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64SHRS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64SHRU => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64ROTL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64ROTR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32ABS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32NEG => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32CEIL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32FLOOR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32TRUNC => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32NEAREST => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32SQRT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32ADD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32SUB => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32MUL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32DIV => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32MIN => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32MAX => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32COPYSIGN => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64ABS => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64NEG => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64CEIL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64FLOOR => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64TRUNC => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64NEAREST => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64SQRT => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64ADD => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64SUB => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64MUL => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64DIV => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64MIN => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64MAX => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64COPYSIGN => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
|
||||
I32WRAPI64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32TRUNCSF32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32TRUNCUF32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32TRUNCSF64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I32TRUNCUF64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64EXTENDSI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64EXTENDUI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64TRUNCSF32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64TRUNCUF32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64TRUNCSF64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64TRUNCUF64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32CONVERTSI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32CONVERTUI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32CONVERTSI64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32CONVERTUI64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32DEMOTEF64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64CONVERTSI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64CONVERTUI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64CONVERTSI64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64CONVERTUI64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64PROMOTEF32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
|
||||
I32REINTERPRETF32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
I64REINTERPRETF64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F32REINTERPRETI32 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
F64REINTERPRETI64 => {
|
||||
todo!("{:?}", op_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
mod call_stack;
|
||||
mod execute;
|
||||
mod value_stack;
|
||||
|
||||
// Exposed for testing only. Should eventually become private.
|
||||
pub use call_stack::CallStack;
|
||||
pub use value_stack::ValueStack;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Value {
|
||||
I32(i32),
|
||||
|
@ -7,7 +7,7 @@ use crate::Value;
|
||||
/// Memory-efficient Struct-of-Arrays storage for the value stack.
|
||||
/// Pack the values and their types as densely as possible,
|
||||
/// to get better cache usage, at the expense of some extra logic.
|
||||
struct ValueStack<'a> {
|
||||
pub struct ValueStack<'a> {
|
||||
bytes: Vec<'a, u8>,
|
||||
is_float: BitVec,
|
||||
is_64: BitVec,
|
||||
|
@ -183,6 +183,12 @@ pub enum OpCode {
|
||||
F64REINTERPRETI64 = 0xbf,
|
||||
}
|
||||
|
||||
impl From<u8> for OpCode {
|
||||
fn from(x: u8) -> Self {
|
||||
unsafe { std::mem::transmute(x) }
|
||||
}
|
||||
}
|
||||
|
||||
/// The format of the *immediate* operands of an operator
|
||||
/// Immediates appear directly in the byte stream after the opcode,
|
||||
/// rather than being popped off the value stack. These are the possible forms.
|
||||
@ -264,7 +270,7 @@ impl SkipBytes for OpCode {
|
||||
|
||||
let opcode_byte: u8 = bytes[*cursor];
|
||||
|
||||
let opcode: OpCode = unsafe { std::mem::transmute(opcode_byte) };
|
||||
let opcode: OpCode = OpCode::from(opcode_byte);
|
||||
// will return Err if transmute was invalid
|
||||
let immediates = immediates_for(opcode).map_err(|message| ParseError {
|
||||
message,
|
||||
|
Loading…
Reference in New Issue
Block a user