Add dvm_panic macro for dumping state before panic call.

This commit is contained in:
Jesse Brault 2024-12-29 10:36:15 -06:00
parent 5322e441c5
commit 258fe824bd

View File

@ -119,10 +119,11 @@ impl DvmState {
} }
macro_rules! dump_state { macro_rules! dump_state {
( $message: expr, $state: expr ) => { ( $state: expr ) => {
println!("----"); println!("Registers: ");
println!("{}", $message); for (i, register) in $state.registers.iter().enumerate() {
println!("----"); println!(" r{}: {:?}", i, register);
}
println!("Call stack:"); println!("Call stack:");
for call_frame in &$state.call_stack { for call_frame in &$state.call_stack {
@ -135,13 +136,19 @@ macro_rules! dump_state {
} }
} }
} }
println!("Registers: ");
for (i, register) in $state.registers.iter().enumerate() {
println!(" r{}: {:?}", i, register);
}
}; };
} }
macro_rules! dvm_panic {
( $message: expr, $state: expr ) => {{
println!("----");
println!("Dvm panic: {}", $message);
println!("----");
dump_state!($state);
panic!();
}};
}
pub fn call_fn( pub fn call_fn(
state: &mut DvmState, state: &mut DvmState,
context: &DvmContext, context: &DvmContext,
@ -250,26 +257,6 @@ macro_rules! read_string {
}}; }};
} }
macro_rules! write_string {
( $raw_ptr: expr, $s: expr ) => {
for (i, b) in $s.bytes().enumerate() {
unsafe {
$raw_ptr.add(i).write(b);
}
}
};
}
macro_rules! write_bytes {
( $ptr: expr, $offset: expr, $src: expr ) => {
for (i, &b) in $src.iter().enumerate() {
unsafe {
$ptr.add($offset + i).write(b);
}
}
};
}
pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8]) { pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8]) {
let mut iter = byte_code.iter().cloned(); let mut iter = byte_code.iter().cloned();
while let Some(op_code) = iter.next() { while let Some(op_code) = iter.next() {
@ -339,7 +326,9 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
.iter() .iter()
.find(|implementation| implementation.fqn == impl_name) .find(|implementation| implementation.fqn == impl_name)
}) })
.expect(&format!("Implementation not found: {}", impl_name)); .unwrap_or_else(|| {
dvm_panic!(&format!("Implementation not found: {}", impl_name), state)
});
let dm_alloc_object = DvmObject::new(implementation.clone()); let dm_alloc_object = DvmObject::new(implementation.clone());
state.registers[target_register] = DvmValue::Object(Rc::new(dm_alloc_object)); state.registers[target_register] = DvmValue::Object(Rc::new(dm_alloc_object));
@ -363,7 +352,10 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
// Get constant // Get constant
let Some(lib) = context.libs.iter().find(|lib| lib.name == lib_name) else { let Some(lib) = context.libs.iter().find(|lib| lib.name == lib_name) else {
panic!("Could not find lib with name: {}", lib_name); dvm_panic!(
&format!("Could not find lib with name: {}", lib_name),
state
);
}; };
let constant = lib.constants.get(const_id).unwrap(); let constant = lib.constants.get(const_id).unwrap();
let DmConstant::String(s) = constant; let DmConstant::String(s) = constant;
@ -455,7 +447,12 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
let method = self_obj let method = self_obj
.implementation() .implementation()
.get_method(&symbol_name, &self_obj) .get_method(&symbol_name, &self_obj)
.expect(&format!("Could not find method: {}", symbol_name)); .unwrap_or_else(|| {
dvm_panic!(
&format!("Could not find method with name: {}", symbol_name),
state
);
});
let dm_fn = method.dm_fn(); let dm_fn = method.dm_fn();
let call_result = call_fn(state, context, &dm_fn, args); let call_result = call_fn(state, context, &dm_fn, args);
@ -468,7 +465,10 @@ pub fn run_byte_code(state: &mut DvmState, context: &DvmContext, byte_code: &[u8
todo!() todo!()
} }
op_code => { op_code => {
panic!("Invalid op_code: {}", op_code); dvm_panic!(
&format!("Unimplemented or unknown op code: {}", op_code),
state
);
} }
} }
} }