arraylength

This commit is contained in:
Shautvast 2023-10-27 21:58:28 +02:00
parent eba8dcfe05
commit c5d573c698
3 changed files with 33 additions and 6 deletions

View file

@ -20,7 +20,25 @@ pub enum ObjectRef {
StringArray(Vec<String>),
ObjectArray(Type, Vec<Arc<UnsafeCell<ObjectRef>>>),
Object(Box<Object>),
Class(Arc<RefCell<Class>>)
Class(Arc<RefCell<Class>>),
}
impl ObjectRef {
pub fn get_array_length(&self) -> usize {
match self {
ByteArray(d) => d.len(),
ShortArray(d) => d.len(),
IntArray(d) => d.len(),
LongArray(d) => d.len(),
FloatArray(d) => d.len(),
DoubleArray(d) => d.len(),
BooleanArray(d) => d.len(),
CharArray(d) => d.len(),
StringArray(d) => d.len(),
ObjectArray(_, d) => d.len(),
_ => unreachable!("not an array")
}
}
}
fn into_vec_i8(v: Vec<u8>) -> Vec<i8> {

View file

@ -286,7 +286,7 @@ pub const NEW: u8 = 187;
// (0xbb) Create new object
pub const ANEWARRAY: u8 = 189;
// (0xbd)
pub const _ARRAYLENGTH: u8 = 190;
pub const ARRAYLENGTH: u8 = 190;
// (0xbe)
pub const _ATHROW: u8 = 191;
// (0xbf)
@ -440,7 +440,7 @@ pub const OPCODES:Lazy<Vec<&str>> = Lazy::new(|| {
opcodes[INVOKESTATIC as usize] = "INVOKESTATIC" ;
opcodes[NEW as usize] = "NEW" ;
opcodes[ANEWARRAY as usize] = "ANEWARRAY" ;
opcodes[_ARRAYLENGTH as usize] = "_ARRAYLENGTH" ;
opcodes[ARRAYLENGTH as usize] = "ARRAYLENGTH" ;
opcodes[_ATHROW as usize] = "_ATHROW" ;
opcodes[_CHECKCAST as usize] = "_CHECKCAST" ;
opcodes[MONITORENTER as usize] = "MONITORENTER" ;

View file

@ -671,6 +671,15 @@ impl Vm {
panic!();
}
},
ARRAYLENGTH => {
let val = self.current_frame().pop()?;
unsafe {
if let Ref(val) = &*val.get() {
let o = &*val.get();
self.current_frame().push(I32(o.get_array_length() as i32));
}
}
}
MONITORENTER => {
self.current_frame().pop()?;
} //TODO implement
@ -734,10 +743,10 @@ impl Vm {
if let I32(index) = &*value.get() {
let index = *index as usize;
let arrayref = self.current_frame().pop()?;
if let Value::Null = &*arrayref.get() {
if let Null = &*arrayref.get() {
return Err(anyhow!("NullpointerException"));
}
if let Value::Ref(objectref) = &*arrayref.get() {
if let Ref(objectref) = &*arrayref.get() {
match &*objectref.get() {
ObjectRef::ByteArray(array) => {
self.current_frame().push(I32(array[index] as i32));