From 4962a81e97cb39f930590b4d759a4774a7450911 Mon Sep 17 00:00:00 2001 From: itsu-dev Date: Fri, 19 Dec 2025 22:31:35 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20inst=20=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bjvm-wasm/crates/inst/Cargo.toml | 8 + bjvm-wasm/crates/inst/src/ctrl.rs | 18 ++ bjvm-wasm/crates/inst/src/def.rs | 21 ++ bjvm-wasm/crates/inst/src/def/a_const_null.rs | 8 + bjvm-wasm/crates/inst/src/def/bipush.rs | 9 + bjvm-wasm/crates/inst/src/def/d_const_0.rs | 8 + bjvm-wasm/crates/inst/src/def/d_const_1.rs | 8 + bjvm-wasm/crates/inst/src/def/f_const_0.rs | 8 + bjvm-wasm/crates/inst/src/def/f_const_1.rs | 8 + bjvm-wasm/crates/inst/src/def/f_const_2.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_0.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_1.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_2.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_3.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_4.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_5.rs | 8 + bjvm-wasm/crates/inst/src/def/i_const_m1.rs | 8 + bjvm-wasm/crates/inst/src/def/l_const_0.rs | 8 + bjvm-wasm/crates/inst/src/def/l_const_1.rs | 8 + bjvm-wasm/crates/inst/src/def/ldc.rs | 8 + bjvm-wasm/crates/inst/src/def/ldc_2_w.rs | 8 + bjvm-wasm/crates/inst/src/def/ldc_w.rs | 8 + bjvm-wasm/crates/inst/src/def/nop.rs | 5 + bjvm-wasm/crates/inst/src/def/sipush.rs | 9 + bjvm-wasm/crates/inst/src/lib.rs | 211 ++++++++++++++++++ bjvm-wasm/crates/inst/tests/inst.rs | 110 +++++++++ bjvm-wasm/crates/value/Cargo.toml | 4 + bjvm-wasm/crates/value/src/lib.rs | 13 ++ 28 files changed, 552 insertions(+) create mode 100644 bjvm-wasm/crates/inst/Cargo.toml create mode 100644 bjvm-wasm/crates/inst/src/ctrl.rs create mode 100644 bjvm-wasm/crates/inst/src/def.rs create mode 100644 bjvm-wasm/crates/inst/src/def/a_const_null.rs create mode 100644 bjvm-wasm/crates/inst/src/def/bipush.rs create mode 100644 bjvm-wasm/crates/inst/src/def/d_const_0.rs create mode 100644 bjvm-wasm/crates/inst/src/def/d_const_1.rs create mode 100644 bjvm-wasm/crates/inst/src/def/f_const_0.rs create mode 100644 bjvm-wasm/crates/inst/src/def/f_const_1.rs create mode 100644 bjvm-wasm/crates/inst/src/def/f_const_2.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_0.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_1.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_2.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_3.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_4.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_5.rs create mode 100644 bjvm-wasm/crates/inst/src/def/i_const_m1.rs create mode 100644 bjvm-wasm/crates/inst/src/def/l_const_0.rs create mode 100644 bjvm-wasm/crates/inst/src/def/l_const_1.rs create mode 100644 bjvm-wasm/crates/inst/src/def/ldc.rs create mode 100644 bjvm-wasm/crates/inst/src/def/ldc_2_w.rs create mode 100644 bjvm-wasm/crates/inst/src/def/ldc_w.rs create mode 100644 bjvm-wasm/crates/inst/src/def/nop.rs create mode 100644 bjvm-wasm/crates/inst/src/def/sipush.rs create mode 100644 bjvm-wasm/crates/inst/src/lib.rs create mode 100644 bjvm-wasm/crates/inst/tests/inst.rs create mode 100644 bjvm-wasm/crates/value/Cargo.toml create mode 100644 bjvm-wasm/crates/value/src/lib.rs diff --git a/bjvm-wasm/crates/inst/Cargo.toml b/bjvm-wasm/crates/inst/Cargo.toml new file mode 100644 index 0000000..8485e85 --- /dev/null +++ b/bjvm-wasm/crates/inst/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "inst" +version = "0.1.0" +edition = "2024" + +[dependencies] +value = { path = "../value", version = "0.1.0" } +thiserror = "2.0.17" diff --git a/bjvm-wasm/crates/inst/src/ctrl.rs b/bjvm-wasm/crates/inst/src/ctrl.rs new file mode 100644 index 0000000..5b4a4d7 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/ctrl.rs @@ -0,0 +1,18 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Control { + Continue, + JumpAbsolute(usize), + JumpRelative(isize), +} + +#[derive(Debug, Clone, Copy, thiserror::Error)] +pub enum Trap { + #[error("division by zero")] + DivisionByZero, + #[error("invalid operation")] + InvalidOperation, + #[error("stack overflow")] + StackOverflow, + #[error("stack underflow")] + StackUnderflow, +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def.rs b/bjvm-wasm/crates/inst/src/def.rs new file mode 100644 index 0000000..2e36b4c --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def.rs @@ -0,0 +1,21 @@ +mod nop; pub use nop::*; +mod a_const_null; pub use a_const_null::*; +mod i_const_m1; pub use i_const_m1::*; +mod i_const_0; pub use i_const_0::*; +mod i_const_1; pub use i_const_1::*; +mod i_const_2; pub use i_const_2::*; +mod i_const_3; pub use i_const_3::*; +mod i_const_4; pub use i_const_4::*; +mod i_const_5; pub use i_const_5::*; +mod l_const_0; pub use l_const_0::*; +mod l_const_1; pub use l_const_1::*; +mod f_const_0; pub use f_const_0::*; +mod f_const_1; pub use f_const_1::*; +mod f_const_2; pub use f_const_2::*; +mod d_const_0; pub use d_const_0::*; +mod d_const_1; pub use d_const_1::*; +mod bipush; pub use bipush::*; +mod sipush; pub use sipush::*; +mod ldc; pub use ldc::*; +mod ldc_w; pub use ldc_w::*; +mod ldc_2_w; pub use ldc_2_w::*; \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/a_const_null.rs b/bjvm-wasm/crates/inst/src/def/a_const_null.rs new file mode 100644 index 0000000..7082346 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/a_const_null.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn a_const_null(stack: &mut Vec) -> Result { + stack.push(Value::Reference(None)); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/bipush.rs b/bjvm-wasm/crates/inst/src/def/bipush.rs new file mode 100644 index 0000000..daae7fc --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/bipush.rs @@ -0,0 +1,9 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn bipush(stack: &mut Vec, pc: &mut usize, arg1: u8) -> Result { + stack.push(Value::Int(arg1 as i8 as i32)); + *pc += 1; + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/d_const_0.rs b/bjvm-wasm/crates/inst/src/def/d_const_0.rs new file mode 100644 index 0000000..bbd627d --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/d_const_0.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn d_const_0(stack: &mut Vec) -> Result { + stack.push(Value::Double(0.0)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/d_const_1.rs b/bjvm-wasm/crates/inst/src/def/d_const_1.rs new file mode 100644 index 0000000..fc4df60 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/d_const_1.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn d_const_1(stack: &mut Vec) -> Result { + stack.push(Value::Double(1.0)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/f_const_0.rs b/bjvm-wasm/crates/inst/src/def/f_const_0.rs new file mode 100644 index 0000000..3350f53 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/f_const_0.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn f_const_0(stack: &mut Vec) -> Result { + stack.push(Value::Float(0.0)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/f_const_1.rs b/bjvm-wasm/crates/inst/src/def/f_const_1.rs new file mode 100644 index 0000000..7b72a0c --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/f_const_1.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn f_const_1(stack: &mut Vec) -> Result { + stack.push(Value::Float(1.0)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/f_const_2.rs b/bjvm-wasm/crates/inst/src/def/f_const_2.rs new file mode 100644 index 0000000..90e3e8e --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/f_const_2.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn f_const_2(stack: &mut Vec) -> Result { + stack.push(Value::Float(2.0)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/i_const_0.rs b/bjvm-wasm/crates/inst/src/def/i_const_0.rs new file mode 100644 index 0000000..e5a9da1 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_0.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_0(stack: &mut Vec) -> Result { + stack.push(Value::Int(0)); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/i_const_1.rs b/bjvm-wasm/crates/inst/src/def/i_const_1.rs new file mode 100644 index 0000000..562751c --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_1.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_1(stack: &mut Vec) -> Result { + stack.push(Value::Int(1)); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/i_const_2.rs b/bjvm-wasm/crates/inst/src/def/i_const_2.rs new file mode 100644 index 0000000..ff761ce --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_2.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_2(stack: &mut Vec) -> Result { + stack.push(Value::Int(2)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/i_const_3.rs b/bjvm-wasm/crates/inst/src/def/i_const_3.rs new file mode 100644 index 0000000..f8b3560 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_3.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_3(stack: &mut Vec) -> Result { + stack.push(Value::Int(3)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/i_const_4.rs b/bjvm-wasm/crates/inst/src/def/i_const_4.rs new file mode 100644 index 0000000..e924387 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_4.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_4(stack: &mut Vec) -> Result { + stack.push(Value::Int(4)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/i_const_5.rs b/bjvm-wasm/crates/inst/src/def/i_const_5.rs new file mode 100644 index 0000000..3761e33 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_5.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_5(stack: &mut Vec) -> Result { + stack.push(Value::Int(5)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/i_const_m1.rs b/bjvm-wasm/crates/inst/src/def/i_const_m1.rs new file mode 100644 index 0000000..09832f9 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/i_const_m1.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn i_const_m1(stack: &mut Vec) -> Result { + stack.push(Value::Int(-1)); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/l_const_0.rs b/bjvm-wasm/crates/inst/src/def/l_const_0.rs new file mode 100644 index 0000000..3a1344c --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/l_const_0.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn l_const_0(stack: &mut Vec) -> Result { + stack.push(Value::Long(0)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/l_const_1.rs b/bjvm-wasm/crates/inst/src/def/l_const_1.rs new file mode 100644 index 0000000..985a56c --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/l_const_1.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn l_const_1(stack: &mut Vec) -> Result { + stack.push(Value::Long(1)); + Ok(Control::Continue) +} diff --git a/bjvm-wasm/crates/inst/src/def/ldc.rs b/bjvm-wasm/crates/inst/src/def/ldc.rs new file mode 100644 index 0000000..a6b704c --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/ldc.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn ldc(stack: &mut Vec, value: Value) -> Result { + stack.push(value); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/ldc_2_w.rs b/bjvm-wasm/crates/inst/src/def/ldc_2_w.rs new file mode 100644 index 0000000..4ec2a55 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/ldc_2_w.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn ldc_2_w(stack: &mut Vec, value: Value) -> Result { + stack.push(value); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/ldc_w.rs b/bjvm-wasm/crates/inst/src/def/ldc_w.rs new file mode 100644 index 0000000..1f81817 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/ldc_w.rs @@ -0,0 +1,8 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn ldc_w(stack: &mut Vec, value: Value) -> Result { + stack.push(value); + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/nop.rs b/bjvm-wasm/crates/inst/src/def/nop.rs new file mode 100644 index 0000000..befd053 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/nop.rs @@ -0,0 +1,5 @@ +use crate::{Control, Trap}; + +pub fn nop() -> Result { + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/def/sipush.rs b/bjvm-wasm/crates/inst/src/def/sipush.rs new file mode 100644 index 0000000..6872dbc --- /dev/null +++ b/bjvm-wasm/crates/inst/src/def/sipush.rs @@ -0,0 +1,9 @@ +use value::Value; + +use crate::{Control, Trap}; + +pub fn sipush(stack: &mut Vec, pc: &mut usize, arg1: u8, arg2: u8) -> Result { + stack.push(Value::Int(((arg1 as i16) << 8 | (arg2 as i16)) as i32)); + *pc += 2; + Ok(Control::Continue) +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/src/lib.rs b/bjvm-wasm/crates/inst/src/lib.rs new file mode 100644 index 0000000..8a7a284 --- /dev/null +++ b/bjvm-wasm/crates/inst/src/lib.rs @@ -0,0 +1,211 @@ +mod def; pub use def::*; +mod ctrl; pub use ctrl::*; + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum Opcode { + Nop = 0x00, + AConstNull = 0x01, + IConstM1 = 0x02, + IConst0 = 0x03, + IConst1 = 0x04, + IConst2 = 0x05, + IConst3 = 0x06, + IConst4 = 0x07, + IConst5 = 0x08, + LConst0 = 0x09, + LConst1 = 0x0a, + FConst0 = 0x0b, + FConst1 = 0x0c, + FConst2 = 0x0d, + DConst0 = 0x0e, + DConst1 = 0x0f, + Bipush = 0x10, + Sipush = 0x11, + Ldc = 0x12, + LdcW = 0x13, + Ldc2W = 0x14, + ILoad = 0x15, + LLoad = 0x16, + FLoad = 0x17, + DLoad = 0x18, + ALoad = 0x19, + ILoad0 = 0x1a, + ILoad1 = 0x1b, + ILoad2 = 0x1c, + ILoad3 = 0x1d, + LLoad0 = 0x1e, + LLoad1 = 0x1f, + LLoad2 = 0x20, + LLoad3 = 0x21, + FLoad0 = 0x22, + FLoad1 = 0x23, + FLoad2 = 0x24, + FLoad3 = 0x25, + DLoad0 = 0x26, + DLoad1 = 0x27, + DLoad2 = 0x28, + DLoad3 = 0x29, + ALoad0 = 0x2a, + ALoad1 = 0x2b, + ALoad2 = 0x2c, + ALoad3 = 0x2d, + IALoad = 0x2e, + LALoad = 0x2f, + FALoad = 0x30, + DALoad = 0x31, + AALoad = 0x32, + BALoad = 0x33, + CALoad = 0x34, + SALoad = 0x35, + IStore = 0x36, + LStore = 0x37, + FStore = 0x38, + DStore = 0x39, + AStore = 0x3a, + IStore0 = 0x3b, + IStore1 = 0x3c, + IStore2 = 0x3d, + IStore3 = 0x3e, + LStore0 = 0x3f, + LStore1 = 0x40, + LStore2 = 0x41, + LStore3 = 0x42, + FStore0 = 0x43, + FStore1 = 0x44, + FStore2 = 0x45, + FStore3 = 0x46, + DStore0 = 0x47, + DStore1 = 0x48, + DStore2 = 0x49, + DStore3 = 0x4a, + AStore0 = 0x4b, + AStore1 = 0x4c, + AStore2 = 0x4d, + AStore3 = 0x4e, + IAStore = 0x4f, + LAStore = 0x50, + FAStore = 0x51, + DAStore = 0x52, + AAStore = 0x53, + BAStore = 0x54, + CAStore = 0x55, + SAStore = 0x56, + Pop = 0x57, + Pop2 = 0x58, + Dup = 0x59, + DupX1 = 0x5a, + DupX2 = 0x5b, + Dup2 = 0x5c, + Dup2X1 = 0x5d, + Dup2X2 = 0x5e, + Swap = 0x5f, + IAdd = 0x60, + LAdd = 0x61, + FAdd = 0x62, + DAdd = 0x63, + ISub = 0x64, + LSub = 0x65, + FSub = 0x66, + DSub = 0x67, + IMul = 0x68, + LMul = 0x69, + FMul = 0x6a, + DMul = 0x6b, + IDiv = 0x6c, + LDiv = 0x6d, + FDiv = 0x6e, + DDiv = 0x6f, + IRem = 0x70, + LRem = 0x71, + FRem = 0x72, + DRem = 0x73, + INeg = 0x74, + LNeg = 0x75, + FNeg = 0x76, + DNeg = 0x77, + IShl = 0x78, + LShl = 0x79, + IShr = 0x7a, + LShr = 0x7b, + IUShr = 0x7c, + LUShr = 0x7d, + IAnd = 0x7e, + LAnd = 0x7f, + IOr = 0x80, + LOr = 0x81, + IXor = 0x82, + LXor = 0x83, + IInc = 0x84, + I2L = 0x85, + I2F = 0x86, + I2D = 0x87, + L2I = 0x88, + L2F = 0x89, + L2D = 0x8a, + F2I = 0x8b, + F2L = 0x8c, + F2D = 0x8d, + D2I = 0x8e, + D2L = 0x8f, + D2F = 0x90, + I2B = 0x91, + I2C = 0x92, + I2S = 0x93, + LCmp = 0x94, + FCmpL = 0x95, + FCmpG = 0x96, + DCmpL = 0x97, + DCmpG = 0x98, + IfEq = 0x99, + IfNe = 0x9a, + IfLt = 0x9b, + IfGe = 0x9c, + IfGt = 0x9d, + IfLe = 0x9e, + IfICmpEq = 0x9f, + IfICmpNe = 0xa0, + IfICmpLt = 0xa1, + IfICmpGe = 0xa2, + IfICmpGt = 0xa3, + IfICmpLe = 0xa4, + IfACmpEq = 0xa5, + IfACmpNe = 0xa6, + Goto = 0xa7, + Jsr = 0xa8, + Ret = 0xa9, + TableSwitch = 0xaa, + LookupSwitch = 0xab, + IReturn = 0xac, + LReturn = 0xad, + FReturn = 0xae, + DReturn = 0xaf, + AReturn = 0xb0, + Return = 0xb1, + GetStatic = 0xb2, + PutStatic = 0xb3, + GetField = 0xb4, + PutField = 0xb5, + InvokeVirtual = 0xb6, + InvokeSpecial = 0xb7, + InvokeStatic = 0xb8, + InvokeInterface = 0xb9, + InvokeDynamic = 0xba, + New = 0xbb, + NewArray = 0xbc, + ANewArray = 0xbd, + ArrayLength = 0xbe, + AThrow = 0xbf, + CheckCast = 0xc0, + InstanceOf = 0xc1, + MonitorEnter = 0xc2, + MonitorExit = 0xc3, + Wide = 0xc4, + MultiANewArray = 0xc5, + IfNull = 0xc6, + IfNonNull = 0xc7, + GotoW = 0xc8, + JsrW = 0xc9, + // Breakpoint = 0xca, + // ImpDep1 = 0xfe, + // ImpDep2 = 0xff, +} \ No newline at end of file diff --git a/bjvm-wasm/crates/inst/tests/inst.rs b/bjvm-wasm/crates/inst/tests/inst.rs new file mode 100644 index 0000000..065b659 --- /dev/null +++ b/bjvm-wasm/crates/inst/tests/inst.rs @@ -0,0 +1,110 @@ +use inst::{ + a_const_null, bipush, d_const_0, d_const_1, f_const_0, f_const_1, f_const_2, i_const_0, + i_const_1, i_const_2, i_const_3, i_const_4, i_const_5, i_const_m1, l_const_0, l_const_1, nop, + sipush, Control, ldc, ldc_w, ldc_2_w, +}; +use value::Value; + +fn assert_const_push(instr: fn(&mut Vec) -> Result, expected: Value) { + let mut stack = Vec::new(); + let control = instr(&mut stack); + + assert!(matches!(control, Ok(Control::Continue))); + assert_eq!(stack.pop(), Some(expected)); +} + +fn assert_bipush(arg1: u8, expected: Value, expected_pc: usize) { + let mut stack = Vec::new(); + let mut pc = 0usize; + + let control = bipush(&mut stack, &mut pc, arg1); + + assert!(matches!(control, Ok(Control::Continue))); + assert_eq!(pc, expected_pc); + assert_eq!(stack.pop(), Some(expected)); +} + +fn assert_sipush(arg1: u8, arg2: u8, expected: Value, expected_pc: usize) { + let mut stack = Vec::new(); + let mut pc = 0usize; + + let control = sipush(&mut stack, &mut pc, arg1, arg2); + + assert!(matches!(control, Ok(Control::Continue))); + assert_eq!(pc, expected_pc); + assert_eq!(stack.pop(), Some(expected)); +} + +fn assert_ldc(instr: fn(&mut Vec, Value) -> Result,value: Value, expected: Value) { + let mut stack = Vec::new(); + + let control = instr(&mut stack, value.clone()); + + assert!(matches!(control, Ok(Control::Continue))); + assert_eq!(stack.pop(), Some(expected)); +} + +#[test] +fn nop_should_continue() { + assert!(matches!(nop(), Ok(Control::Continue))); +} + +#[test] +fn a_const_null_pushes_reference_none() { + assert_const_push(a_const_null, Value::Reference(None)); +} + +#[test] +fn i_const_variants_push_expected_ints() { + assert_const_push(i_const_m1, Value::Int(-1)); + assert_const_push(i_const_0, Value::Int(0)); + assert_const_push(i_const_1, Value::Int(1)); + assert_const_push(i_const_2, Value::Int(2)); + assert_const_push(i_const_3, Value::Int(3)); + assert_const_push(i_const_4, Value::Int(4)); + assert_const_push(i_const_5, Value::Int(5)); +} + +#[test] +fn l_const_variants_push_expected_longs() { + assert_const_push(l_const_0, Value::Long(0)); + assert_const_push(l_const_1, Value::Long(1)); +} + +#[test] +fn f_const_variants_push_expected_floats() { + assert_const_push(f_const_0, Value::Float(0.0)); + assert_const_push(f_const_1, Value::Float(1.0)); + assert_const_push(f_const_2, Value::Float(2.0)); +} + +#[test] +fn d_const_variants_push_expected_doubles() { + assert_const_push(d_const_0, Value::Double(0.0)); + assert_const_push(d_const_1, Value::Double(1.0)); +} + +#[test] +fn bipush_pushes_signed_byte_and_increments_pc() { + assert_bipush(0x7f, Value::Int(127), 1); + assert_bipush(0x80, Value::Int(-128), 1); + assert_bipush(0x00, Value::Int(0), 1); +} + +#[test] +fn sipush_pushes_signed_short_and_increments_pc() { + assert_sipush(0x7f, 0xff, Value::Int(32767), 2); + assert_sipush(0x80, 0x00, Value::Int(-32768), 2); +} + +#[test] +fn ldc_pushes_value_onto_stack() { + let value1 = Value::Int(42); + assert_ldc(ldc, value1.clone(), value1); + + let value2 = Value::Float(3.14); + assert_ldc(ldc_w, value2.clone(), value2); + + let value3 = Value::Long(1234567890); + assert_ldc(ldc_2_w, value3.clone(), value3); +} \ No newline at end of file diff --git a/bjvm-wasm/crates/value/Cargo.toml b/bjvm-wasm/crates/value/Cargo.toml new file mode 100644 index 0000000..02bebc1 --- /dev/null +++ b/bjvm-wasm/crates/value/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "value" +version = "0.1.0" +edition = "2024" diff --git a/bjvm-wasm/crates/value/src/lib.rs b/bjvm-wasm/crates/value/src/lib.rs new file mode 100644 index 0000000..425158a --- /dev/null +++ b/bjvm-wasm/crates/value/src/lib.rs @@ -0,0 +1,13 @@ +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum Value { + Boolean(bool), + Byte(i8), + Char(u16), + Short(i16), + Int(i32), + Long(i64), + Float(f32), + Double(f64), + Reference(Option), + ReturnAddress(usize), +} \ No newline at end of file