Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: refactor + tests for opcode enum #13

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/core/reader/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod function_code_header;
pub mod global;
pub mod import;
pub mod memarg;
pub mod opcode;
pub mod values;

/// https://webassembly.github.io/spec/core/binary/types.html#number-types
Expand Down
26 changes: 26 additions & 0 deletions src/core/reader/types/opcode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
pub const NOP: u8 = 0x01;
pub const END: u8 = 0x0B;
pub const LOCAL_GET: u8 = 0x20;
pub const LOCAL_SET: u8 = 0x21;
pub const GLOBAL_GET: u8 = 0x23;
pub const GLOBAL_SET: u8 = 0x24;
pub const I32_LOAD: u8 = 0x28;
pub const I32_STORE: u8 = 0x36;
pub const I32_CONST: u8 = 0x41;
pub const I32_ADD: u8 = 0x6A;
pub const I32_MUL: u8 = 0x6C;
pub const I32_DIV_S: u8 = 0x6D;
pub const I32_DIV_U: u8 = 0x6E;
pub const I32_REM_S: u8 = 0x6F;
pub const I32_CLZ: u8 = 0x67;
pub const I32_CTZ: u8 = 0x68;
pub const I32_POPCNT: u8 = 0x69;
pub const I32_REM_U: u8 = 0x70;
pub const I32_AND: u8 = 0x71;
pub const I32_OR: u8 = 0x72;
pub const I32_XOR: u8 = 0x73;
pub const I32_SHL: u8 = 0x74;
pub const I32_SHR_S: u8 = 0x75;
pub const I32_SHR_U: u8 = 0x76;
pub const I32_ROTL: u8 = 0x77;
pub const I32_ROTR: u8 = 0x78;
80 changes: 29 additions & 51 deletions src/execution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,47 +129,44 @@ where
let mut wasm = WasmReader::new(self.wasm_bytecode);
wasm.move_start_to(inst.code_expr);

use crate::core::reader::types::opcode::*;
loop {
// call the instruction hook
#[cfg(feature = "hooks")]
H::instruction_hook(self);

match wasm.read_u8().unwrap_validated() {
// end
0x0B => {
let first_instr_byte = wasm.read_u8().unwrap_validated();

match first_instr_byte {
END => {
break;
}
// local.get: [] -> [t]
0x20 => {
LOCAL_GET => {
let local_idx = wasm.read_var_u32().unwrap_validated() as LocalIdx;
let local = locals.get(local_idx);
trace!("Instruction: local.get [] -> [{local:?}]");
stack.push_value(local.clone());
}
// local.set [t] -> []
0x21 => {
LOCAL_SET => {
let local_idx = wasm.read_var_u32().unwrap_validated() as LocalIdx;
let local = locals.get_mut(local_idx);
let value = stack.pop_value(local.to_ty());
trace!("Instruction: local.set [{local:?}] -> []");
*local = value;
}
// global.get [] -> [t]
0x23 => {
GLOBAL_GET => {
let global_idx = wasm.read_var_u32().unwrap_validated() as GlobalIdx;
let global = self.store.globals.get(global_idx).unwrap_validated();

stack.push_value(global.value.clone());
}
// global.set [t] -> []
0x24 => {
GLOBAL_SET => {
let global_idx = wasm.read_var_u32().unwrap_validated() as GlobalIdx;
let global = self.store.globals.get_mut(global_idx).unwrap_validated();

global.value = stack.pop_value(global.global.ty.ty)
}
// i32.load [i32] -> [i32]
0x28 => {
I32_LOAD => {
let memarg = MemArg::read_unvalidated(&mut wasm);
let relative_address: u32 =
stack.pop_value(ValType::NumType(NumType::I32)).into();
Expand All @@ -196,8 +193,7 @@ where
stack.push_value(Value::I32(data));
trace!("Instruction: i32.load [{relative_address}] -> [{data}]");
}
// i32.store [i32] -> [i32]
0x36 => {
I32_STORE => {
let memarg = MemArg::read_unvalidated(&mut wasm);

let data_to_store: u32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
Expand All @@ -219,56 +215,49 @@ where
memory_location.copy_from_slice(&data_to_store.to_le_bytes());
trace!("Instruction: i32.store [{relative_address} {data_to_store}] -> []");
}
// i32.const: [] -> [i32]
0x41 => {
I32_CONST => {
let constant = wasm.read_var_i32().unwrap_validated();
trace!("Instruction: i32.const [] -> [{constant}]");
stack.push_value(constant.into());
}
// i32.clz: [i32] -> [i32]
0x67 => {
I32_CLZ => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.leading_zeros() as i32;

trace!("Instruction: i32.clz [{v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.ctz: [i32] -> [i32]
0x68 => {
I32_CTZ => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.trailing_zeros() as i32;

trace!("Instruction: i32.ctz [{v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.popcnt: [i32] -> [i32]
0x69 => {
I32_POPCNT => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.count_ones() as i32;

trace!("Instruction: i32.popcnt [{v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.add: [i32 i32] -> [i32]
0x6A => {
I32_ADD => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.wrapping_add(v2);

trace!("Instruction: i32.add [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.mul: [i32 i32] -> [i32]
0x6C => {
I32_MUL => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1.wrapping_mul(v2);

trace!("Instruction: i32.mul [{v1} {v2}] -> [{res}]");
nerodesu017 marked this conversation as resolved.
Show resolved Hide resolved
stack.push_value(res.into());
}
// i32.div_s: [i32 i32] -> [i32]
0x6D => {
I32_DIV_S => {
let dividend: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let divisor: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -284,8 +273,7 @@ where
trace!("Instruction: i32.div_s [{divisor} {dividend}] -> [{res}]");
stack.push_value(res.into());
}
// i32.div_u: [i32 i32] -> [i32]
0x6E => {
I32_DIV_U => {
let dividend: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let divisor: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -301,8 +289,7 @@ where
trace!("Instruction: i32.div_u [{divisor} {dividend}] -> [{res}]");
stack.push_value(res.into());
}
// i32.rem_s: [i32 i32] -> [i32]
0x6F => {
I32_REM_S => {
let dividend: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let divisor: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -316,8 +303,7 @@ where
trace!("Instruction: i32.rem_s [{divisor} {dividend}] -> [{res}]");
stack.push_value(res.into());
}
// i32.rem_u: [i32 i32] -> [i32]
0x70 => {
I32_REM_U => {
let dividend: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let divisor: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -334,44 +320,39 @@ where
trace!("Instruction: i32.rem_u [{divisor} {dividend}] -> [{res}]");
stack.push_value(res.into());
}
// i32.and: [i32 i32] -> [i32]
0x71 => {
I32_AND => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1 & v2;

trace!("Instruction: i32.and [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.or: [i32 i32] -> [i32]
0x72 => {
I32_OR => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1 | v2;

trace!("Instruction: i32.or [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.xor: [i32 i32] -> [i32]
0x73 => {
I32_XOR => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v1 ^ v2;

trace!("Instruction: i32.xor [{v1} {v2}] -> [{res}]");
stack.push_value(res.into());
}
// i32.shl: [i32 i32] -> [i32]
0x74 => {
I32_SHL => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let res = v2.wrapping_shl(v1 as u32);

trace!("Instruction: i32.shl [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.shr_s: [i32 i32] -> [i32]
0x75 => {
I32_SHR_S => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -380,8 +361,7 @@ where
trace!("Instruction: i32.shr_s [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.shr_u: [i32 i32] -> [i32]
0x76 => {
I32_SHR_U => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -390,8 +370,7 @@ where
trace!("Instruction: i32.shr_u [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.rotl: [i32 i32] -> [i32]
0x77 => {
I32_ROTL => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand All @@ -400,8 +379,7 @@ where
trace!("Instruction: i32.rotl [{v2} {v1}] -> [{res}]");
stack.push_value(res.into());
}
// i32.rotr: [i32 i32] -> [i32]
0x78 => {
I32_ROTR => {
let v1: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();
let v2: i32 = stack.pop_value(ValType::NumType(NumType::I32)).into();

Expand Down
Loading