mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
Debugging improvements
This commit is contained in:
parent
8a137126fe
commit
a08633fd36
@ -36,11 +36,6 @@ const CONST_SEGMENT_BASE_ADDR: u32 = 1024;
|
||||
/// Index of the data segment where we store constants
|
||||
const CONST_SEGMENT_INDEX: usize = 0;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
const DEBUG_BUILD: bool = true;
|
||||
#[cfg(not(debug_assertions))]
|
||||
const DEBUG_BUILD: bool = false;
|
||||
|
||||
pub struct WasmBackend<'a> {
|
||||
env: &'a Env<'a>,
|
||||
interns: &'a mut Interns,
|
||||
@ -168,16 +163,24 @@ impl<'a> WasmBackend<'a> {
|
||||
}
|
||||
|
||||
pub fn finalize_module(mut self) -> WasmModule<'a> {
|
||||
if DEBUG_BUILD {
|
||||
let module_id = self.env.module_id;
|
||||
let ident_ids = self.interns.all_ident_ids.get(&module_id).unwrap();
|
||||
self.env.module_id.register_debug_idents(ident_ids);
|
||||
}
|
||||
let symbol_table = LinkingSubSection::SymbolTable(self.linker_symbols);
|
||||
self.module.linking.subsections.push(symbol_table);
|
||||
self.module
|
||||
}
|
||||
|
||||
/// Register the debug names of Symbols in a global lookup table
|
||||
/// so that they have meaningful names when you print them.
|
||||
/// Particularly useful after generating IR for refcount procedures
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn register_symbol_debug_names(&self) {
|
||||
let module_id = self.env.module_id;
|
||||
let ident_ids = self.interns.all_ident_ids.get(&module_id).unwrap();
|
||||
self.env.module_id.register_debug_idents(ident_ids);
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn register_debug_idents(&self) {}
|
||||
|
||||
/// Reset function-level data
|
||||
fn reset(&mut self) {
|
||||
// Push the completed CodeBuilder into the module and swap it for a new empty one
|
||||
|
@ -104,6 +104,15 @@ pub fn build_module_help<'a>(
|
||||
// Generate IR for refcounting procs
|
||||
let refcount_procs = backend.generate_refcount_procs();
|
||||
|
||||
backend.register_symbol_debug_names();
|
||||
|
||||
if false {
|
||||
for proc in refcount_procs.iter() {
|
||||
println!("{}", proc.to_pretty(200));
|
||||
println!("{:#?}", proc);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate Wasm for refcounting procs
|
||||
for proc in refcount_procs.iter() {
|
||||
backend.build_proc(proc)?;
|
||||
@ -111,12 +120,6 @@ pub fn build_module_help<'a>(
|
||||
|
||||
let module = backend.finalize_module();
|
||||
|
||||
if true {
|
||||
for proc in refcount_procs.into_iter() {
|
||||
println!("{}", proc.to_pretty(200));
|
||||
}
|
||||
}
|
||||
|
||||
Ok((module, main_fn_index.unwrap()))
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,7 @@ impl StoredValue {
|
||||
|
||||
/// Helper structure for WasmBackend, to keep track of how values are stored,
|
||||
/// including the VM stack, local variables, and linear memory
|
||||
#[derive(Debug)]
|
||||
pub struct Storage<'a> {
|
||||
pub arg_types: Vec<'a, ValueType>,
|
||||
pub local_types: Vec<'a, ValueType>,
|
||||
|
@ -234,7 +234,9 @@ impl<'a> CodeBuilder<'a> {
|
||||
pub fn set_top_symbol(&mut self, sym: Symbol) -> VmSymbolState {
|
||||
let current_stack = &mut self.vm_block_stack.last_mut().unwrap().value_stack;
|
||||
let pushed_at = self.code.len();
|
||||
let top_symbol: &mut Symbol = current_stack.last_mut().unwrap();
|
||||
let top_symbol: &mut Symbol = current_stack
|
||||
.last_mut()
|
||||
.unwrap_or_else(|| unreachable!("Empty stack when trying to set Symbol {:?}", sym));
|
||||
*top_symbol = sym;
|
||||
|
||||
VmSymbolState::Pushed { pushed_at }
|
||||
|
@ -167,33 +167,42 @@ pub fn helper_wasm<'a, T: Wasm32TestResult>(
|
||||
// write the module to a file so the linker can access it
|
||||
std::fs::write(&app_o_file, &module_bytes).unwrap();
|
||||
|
||||
let _linker_output = std::process::Command::new("zig")
|
||||
.args(&[
|
||||
"wasm-ld",
|
||||
// input files
|
||||
app_o_file.to_str().unwrap(),
|
||||
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
||||
libc_a_file,
|
||||
// output
|
||||
"-o",
|
||||
final_wasm_file.to_str().unwrap(),
|
||||
// we don't define `_start`
|
||||
"--no-entry",
|
||||
// If you only specify test_wrapper, it will stop at the call to UserApp_main_1
|
||||
// But if you specify both exports, you get all the dependencies.
|
||||
//
|
||||
// It seems that it will not write out an export you didn't explicitly specify,
|
||||
// even if it's a dependency of another export!
|
||||
// In our case we always export main and test_wrapper so that's OK.
|
||||
"--export",
|
||||
"test_wrapper",
|
||||
"--export",
|
||||
"#UserApp_main_1",
|
||||
])
|
||||
let args = &[
|
||||
"wasm-ld",
|
||||
// input files
|
||||
app_o_file.to_str().unwrap(),
|
||||
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
||||
libc_a_file,
|
||||
// output
|
||||
"-o",
|
||||
final_wasm_file.to_str().unwrap(),
|
||||
// we don't define `_start`
|
||||
"--no-entry",
|
||||
// If you only specify test_wrapper, it will stop at the call to UserApp_main_1
|
||||
// But if you specify both exports, you get all the dependencies.
|
||||
//
|
||||
// It seems that it will not write out an export you didn't explicitly specify,
|
||||
// even if it's a dependency of another export!
|
||||
// In our case we always export main and test_wrapper so that's OK.
|
||||
"--export",
|
||||
"test_wrapper",
|
||||
"--export",
|
||||
"#UserApp_main_1",
|
||||
];
|
||||
|
||||
let linker_output = std::process::Command::new("zig")
|
||||
.args(args)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// dbg!(_linker_output);
|
||||
if !linker_output.status.success() {
|
||||
print!("\nLINKER FAILED\n");
|
||||
for arg in args {
|
||||
print!("{} ", arg);
|
||||
}
|
||||
println!("\n{}", std::str::from_utf8(&linker_output.stdout).unwrap());
|
||||
println!("{}", std::str::from_utf8(&linker_output.stderr).unwrap());
|
||||
}
|
||||
|
||||
Module::from_file(&store, &final_wasm_file).unwrap()
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user