mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
Add some debug features to gen_wasm
This commit is contained in:
parent
96380d5bfe
commit
9594b05c96
4 changed files with 62 additions and 7 deletions
|
@ -58,6 +58,8 @@ pub struct WasmBackend<'a> {
|
||||||
/// how many blocks deep are we (used for jumps)
|
/// how many blocks deep are we (used for jumps)
|
||||||
block_depth: u32,
|
block_depth: u32,
|
||||||
joinpoint_label_map: MutMap<JoinPointId, (u32, Vec<'a, StoredValue>)>,
|
joinpoint_label_map: MutMap<JoinPointId, (u32, Vec<'a, StoredValue>)>,
|
||||||
|
|
||||||
|
debug_current_proc_index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WasmBackend<'a> {
|
impl<'a> WasmBackend<'a> {
|
||||||
|
@ -149,6 +151,8 @@ impl<'a> WasmBackend<'a> {
|
||||||
code_builder: CodeBuilder::new(arena),
|
code_builder: CodeBuilder::new(arena),
|
||||||
storage: Storage::new(arena),
|
storage: Storage::new(arena),
|
||||||
symbol_layouts: MutMap::default(),
|
symbol_layouts: MutMap::default(),
|
||||||
|
|
||||||
|
debug_current_proc_index: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +207,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
|
|
||||||
pub fn build_proc(&mut self, proc: &Proc<'a>) {
|
pub fn build_proc(&mut self, proc: &Proc<'a>) {
|
||||||
// println!("\ngenerating procedure {:?}\n", proc.name);
|
// println!("\ngenerating procedure {:?}\n", proc.name);
|
||||||
|
self.debug_current_proc_index += 1;
|
||||||
|
|
||||||
self.start_proc(proc);
|
self.start_proc(proc);
|
||||||
|
|
||||||
|
@ -1246,4 +1251,18 @@ impl<'a> WasmBackend<'a> {
|
||||||
self.code_builder
|
self.code_builder
|
||||||
.call(fn_index, linker_symbol_index, num_wasm_args, has_return_val);
|
.call(fn_index, linker_symbol_index, num_wasm_args, has_return_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Debug utility
|
||||||
|
///
|
||||||
|
/// if _debug_current_proc_is("#UserApp_foo_1") {
|
||||||
|
/// self.code_builder._debug_assert_i32(0x1234);
|
||||||
|
/// }
|
||||||
|
fn _debug_current_proc_is(&self, linker_name: &'static str) -> bool {
|
||||||
|
let (_, linker_sym_index) = self.proc_symbols[self.debug_current_proc_index];
|
||||||
|
let sym_info = &self.linker_symbols[linker_sym_index as usize];
|
||||||
|
match sym_info {
|
||||||
|
SymInfo::Function(WasmObjectSymbol::Defined { name, .. }) => name == linker_name,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -901,4 +901,17 @@ impl<'a> CodeBuilder<'a> {
|
||||||
instruction_no_args!(i64_reinterpret_f64, I64REINTERPRETF64, 1, true);
|
instruction_no_args!(i64_reinterpret_f64, I64REINTERPRETF64, 1, true);
|
||||||
instruction_no_args!(f32_reinterpret_i32, F32REINTERPRETI32, 1, true);
|
instruction_no_args!(f32_reinterpret_i32, F32REINTERPRETI32, 1, true);
|
||||||
instruction_no_args!(f64_reinterpret_i64, F64REINTERPRETI64, 1, true);
|
instruction_no_args!(f64_reinterpret_i64, F64REINTERPRETI64, 1, true);
|
||||||
|
|
||||||
|
/// Generate a debug assertion for an expected i32 value
|
||||||
|
pub fn _debug_assert_i32(&mut self, expected: i32) {
|
||||||
|
self.i32_const(expected);
|
||||||
|
self.i32_eq();
|
||||||
|
self.i32_eqz();
|
||||||
|
self.if_(BlockType::NoResult);
|
||||||
|
self.unreachable_(); // Tell Wasm runtime to throw an exception
|
||||||
|
self.end();
|
||||||
|
// It matches. Restore the original value to the VM stack and continue the program.
|
||||||
|
// We know it matched the expected value, so just use that!
|
||||||
|
self.i32_const(expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,10 +247,16 @@ where
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if false {
|
if true {
|
||||||
|
println!("test_wrapper returned 0x{:x}", address);
|
||||||
|
println!("Stack:");
|
||||||
crate::helpers::wasm::debug_memory_hex(memory, address, std::mem::size_of::<T>());
|
crate::helpers::wasm::debug_memory_hex(memory, address, std::mem::size_of::<T>());
|
||||||
}
|
}
|
||||||
|
if true {
|
||||||
|
println!("Heap:");
|
||||||
|
// Manually provide address and size based on printf in test_platform.c
|
||||||
|
crate::helpers::wasm::debug_memory_hex(memory, 0x11440, 24);
|
||||||
|
}
|
||||||
let output = <T as FromWasm32Memory>::decode(memory, address as u32);
|
let output = <T as FromWasm32Memory>::decode(memory, address as u32);
|
||||||
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
|
@ -267,12 +273,17 @@ pub fn debug_memory_hex(memory: &Memory, address: i32, size: usize) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let extra_words = 2;
|
let extra_words = 2;
|
||||||
let offset = (address as usize) / 4;
|
let result_start = (address as usize) / 4;
|
||||||
let start = offset - extra_words;
|
let result_end = result_start + ((size + 3) / 4);
|
||||||
let end = offset + (size / 4) + extra_words;
|
let start = result_start - extra_words;
|
||||||
|
let end = result_end + extra_words;
|
||||||
|
|
||||||
for index in start..end {
|
for index in start..end {
|
||||||
let result_marker = if index == offset { "*" } else { " " };
|
let result_marker = if index >= result_start && index < result_end {
|
||||||
|
"|"
|
||||||
|
} else {
|
||||||
|
" "
|
||||||
|
};
|
||||||
println!(
|
println!(
|
||||||
"{:x} {} {:08x}",
|
"{:x} {} {:08x}",
|
||||||
index * 4,
|
index * 4,
|
||||||
|
@ -280,6 +291,7 @@ pub fn debug_memory_hex(memory: &Memory, address: i32, size: usize) {
|
||||||
memory_words[index]
|
memory_words[index]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
|
|
|
@ -3,7 +3,18 @@
|
||||||
// If any printf is included for compilation, even if unused, test runs take 50% longer
|
// If any printf is included for compilation, even if unused, test runs take 50% longer
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
void *roc_alloc(size_t size, unsigned int alignment) { return malloc(size); }
|
void *roc_alloc(size_t size, unsigned int alignment)
|
||||||
|
{
|
||||||
|
void *allocated = malloc(size);
|
||||||
|
if (!allocated)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "roc_alloc failed\n");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
printf("roc_alloc allocated %d bytes at %p\n", size, allocated);
|
||||||
|
}
|
||||||
|
return allocated;
|
||||||
|
}
|
||||||
|
|
||||||
void *roc_realloc(void *ptr, size_t new_size, size_t old_size,
|
void *roc_realloc(void *ptr, size_t new_size, size_t old_size,
|
||||||
unsigned int alignment)
|
unsigned int alignment)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue