diff --git a/src/heap.rs b/src/heap.rs index da13662..e9ff090 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -23,10 +23,11 @@ pub enum ObjectRef{ DoubleArray(Vec), BooleanArray(Vec), CharArray(Vec), - ObjectArray(Vec), + ObjectArray(Vec>>), Object(Object), } + unsafe impl Send for Object {} unsafe impl Sync for Object {} diff --git a/src/opcodes.rs b/src/opcodes.rs index ba9deaf..5f8e6be 100644 --- a/src/opcodes.rs +++ b/src/opcodes.rs @@ -77,13 +77,14 @@ pub const ASTORE_0: u8 = 75; // (0x4b) pub const ASTORE_1: u8 = 76; // (0x4c) pub const ASTORE_2: u8 = 77; // (0x4d) pub const ASTORE_3: u8 = 78; // (0x4e) +pub const IASTORE: u8 = 79; // (0x4f) Store into int array +pub const LASTORE: u8 = 80; // (0x50) Store into long array pub const FASTORE: u8 = 81; // (0x51) Store into float array -// pub const dastore:u8 = 82; //(0x52) store into double array -// pub const aastore: u8 = 83; // (0x53) -// -// pub const bastore:u8 = 84; // (0x54) -// -// pub const castore:u8 = 85; // (0x55) +pub const DASTORE: u8 = 82; //(0x52) store into double array +pub const AASTORE: u8 = 83; // (0x53) Store into object array +pub const BASTORE:u8 = 84; // (0x54) Store into byte or boolean array +pub const CASTORE:u8 = 85; // (0x55) Store into char array +pub const SASTORE:u8 = 86; // (0x56) Store into short array pub const POP: u8 = 87; // (0x57) Pop the top operand stack value pub const DUP: u8 = 89; // (0x59) duplicate the top operand stack value // pub const dup_x1: u8 = 90; // (0x5a) Duplicate the top operand stack value and insert two values down diff --git a/src/vm.rs b/src/vm.rs index fdf20b5..e4315b6 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -254,17 +254,7 @@ impl Vm { ISTORE_3 | LSTORE_3 | DSTORE_3 | ASTORE_3 | FSTORE_3 => { self.store(&mut local_params, 3)?; } - FASTORE => unsafe { - if let Value::F32(value) = *self.local_stack().pop()?.get() { - if let Value::I32(index) = &mut *self.local_stack().pop()?.get() { - if let Value::Ref(ref mut objectref) = &mut *self.local_stack().pop()?.get() { - if let ObjectRef::FloatArray(ref mut array) = &mut *objectref.get() { - array[*index as usize] = value; - } - } - } - } - } + BASTORE | IASTORE | LASTORE | CASTORE | SASTORE | FASTORE | DASTORE | AASTORE => unsafe { self.arraystore()? } POP => { self.local_stack().pop()?; } @@ -377,6 +367,63 @@ impl Vm { panic!("should not happen") } + unsafe fn arraystore(&mut self) -> Result<(), Error> { + let eleemnt = self.local_stack().pop()?; + + if let Value::I32(index) = &mut *self.local_stack().pop()?.get() { + if let Value::Ref(ref mut objectref) = &mut *self.local_stack().pop()?.get() { + match &mut *objectref.get() { + ObjectRef::ByteArray(ref mut array) => { + if let Value::I32(value) = *eleemnt.get() { // is i32 correct? + array[*index as usize] = value as i8; + } + } + ObjectRef::ShortArray(ref mut array) => { + if let Value::I32(value) = *eleemnt.get() { // is i32 correct? + array[*index as usize] = value as i16; + } + } + ObjectRef::IntArray(ref mut array) => { + if let Value::I32(value) = *eleemnt.get() { + array[*index as usize] = value; + } + } + ObjectRef::BooleanArray(ref mut array) => { + if let Value::I32(value) = *eleemnt.get() { + array[*index as usize] = value > 0; + } + } + ObjectRef::CharArray(ref mut array) => { + if let Value::I32(value) = *eleemnt.get() { + array[*index as usize] = char::from_u32_unchecked(value as u32); + } + } + ObjectRef::LongArray(ref mut array) => { + if let Value::I64(value) = *eleemnt.get() { + array[*index as usize] = value; + } + } + ObjectRef::FloatArray(ref mut array) => { + if let Value::F32(value) = *eleemnt.get() { + array[*index as usize] = value + } + } + ObjectRef::DoubleArray(ref mut array) => { + if let Value::F64(value) = *eleemnt.get() { + array[*index as usize] = value + } + } + ObjectRef::ObjectArray(ref mut array) => { + if let Value::Ref(ref value) = *eleemnt.get() { + array[*index as usize] = value.clone(); + } + } + } + } + } + Ok(()) + } + fn store(&mut self, local_params: &mut Vec>>>, index: usize) -> Result<(), Error> { let value = self.local_stack().pop()?; while local_params.len() < index + 1 {