More error checking in invokestatic

This commit is contained in:
VegOwOtenks 2024-09-02 12:02:19 +02:00
parent 2042007242
commit fb29955f7d
3 changed files with 41 additions and 2 deletions

View file

@ -1,4 +1,5 @@
use core::fmt::{Formatter, Debug};
use core::ops::BitAnd;
#[derive(Debug, Copy, Clone)]
#[repr(u16)]
@ -36,10 +37,18 @@ impl MethodAccessFlag {
}
}
#[derive(Copy, Clone)]
pub struct MethodAccessFlagMask {
pub mask: u16,
}
impl BitAnd<MethodAccessFlag> for MethodAccessFlagMask {
type Output=bool;
fn bitand(self, f: MethodAccessFlag) -> bool {
return (self.mask & f.discriminant()) != 0;
}
}
impl Debug for MethodAccessFlagMask {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
let mut flag_vec = Vec::new();

View file

@ -130,6 +130,11 @@ impl ClassStore {
return Some(was_init);
}
pub fn set_init(&mut self, class_idx: usize, was_init: bool) {
let pair = self.classes.get_mut(class_idx).unwrap();
pair.0 = was_init;
}
}

View file

@ -17,6 +17,7 @@ pub enum Error {
ClassFileError(classfile::Error),
BadNameError(String),
RunTimeError(String),
OpcodeError(String),
}
impl From<classfile::Error> for Error {
@ -151,6 +152,7 @@ impl JVM {
// TODO: ConstantValue Attributes (final)
// TODO: Static Stuff
self.class_store.set_init(class_idx, true);
}
fn prepare_invoke_static(&mut self, class_index: usize, method_name: &String, arguments: &[Value]) -> Result<(), Error> {
@ -210,6 +212,17 @@ impl JVM {
// TODO: Throw exception on fail
let callee_method_info = &callee_class_file.methods[callee_method_index];
if ! (callee_method_info.access_flags & MethodAccessFlag::Static) {
// TODO: Throw IncompatibleClassChangeError
return Err(Error::RunTimeError(format!(
"Invoked method '{}' in class '{}' does not have Access::Static (from invokestatic from '{}' in class '{}')",
method.name,
class.get_classname().unwrap(),
supplied_method_name,
supplied_class_name,
)));
}
let supplied_descriptor: MethodDescriptor = supplied_descriptor_string.try_into()?;
// TODO: Throw exception on fail
@ -225,6 +238,7 @@ impl JVM {
}
let arguments = Vec::new();
// TODO: Pass arguments
let new_frame = StackFrame::new(
callee_class_file,
@ -233,11 +247,22 @@ impl JVM {
&arguments.into_boxed_slice(),
);
//println!("{} {} {}", class_name, method_name, method_descriptor);
return Ok(JVMCallbackOperation::PushFrame(new_frame));
},
Instruction::ReturnVoid() => {
let expected_type = AbstractTypeDescription {
array_level: 0,
kind: AbstractTypeKind::Void(),
};
if method.descriptor.return_type != expected_type {
return Err(Error::OpcodeError(format!("Found opcode '{:?}' on method returning '{:?}'", instruction, method.descriptor.return_type)))
}
return Ok(JVMCallbackOperation::PopFrame());
},
_ => {
return Err(Error::RunTimeError(format!("Opcode not implemented yet: {:?}", instruction)))
},