Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "wasmtime: debug dwarf-playground/program.wasm",
"type": "lldb",
"request": "launch",
"program": "/opt/homebrew/bin/wasmtime",
"args": [
"run",
"-D",
"debug-info=y",
"--invoke",
"compute",
"program.wasm",
"5"
],
// Deliberately no `-O opt-level=0`: at that opt level, any local
// with a multi-field (DW_OP_piece-composite) location — i.e. any
// struct local, and program.wx has one — crashes wasmtime's own
// DWARF transform (see wasmtime-dwarf-transform-bug.md, "Bug 3").
// Default opt level avoids that path; the tradeoff is some
// scalar locals show "optimized out" right at a function's
// entry (normal — becomes available a few instructions in).
"cwd": "${workspaceFolder}/dwarf-playground",
"stopOnEntry": false,
"initCommands": [
// Required on macOS for lldb to pick up the GDB/LLDB JIT
// interface that wasmtime uses to register debug info for
// the JIT-compiled module at runtime.
"settings set plugin.jit-loader.gdb.enable on",
// Our DWARF's compile-unit directory is a bare "." (see
// dwarf/mod.rs's LineProgramBuilder — there's no real
// directory/filename split to model for a single-file
// build). lldb resolves that "." against its *own* cwd,
// not the debuggee's `cwd` above, so without this it can't
// find program.wx on disk and falls back to disassembly
// view even though the line-table resolution is correct.
"settings set target.source-map . ${workspaceFolder}/dwarf-playground"
]
}
]
}
13 changes: 11 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 64 additions & 6 deletions crates/wx-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ fn main() {
for stdout (default: <input>.wasm)",
),
)
.arg(
clap::Arg::new("debug")
.long("debug")
.action(clap::ArgAction::SetTrue)
.help("Skip optimizations"),
)
.arg(message_format.clone()),
)
.subcommand(
Expand All @@ -65,7 +71,12 @@ fn main() {
let format = parse_message_format(
sub.get_one::<String>("message-format").unwrap(),
);
cmd_compile(path, output, format);
let mode = if sub.get_flag("debug") {
CompilationMode::Debug
} else {
CompilationMode::Release
};
cmd_compile(path, output, format, mode);
}
Some(("check", sub)) => {
let path = sub.get_one::<String>("path").unwrap();
Expand Down Expand Up @@ -242,7 +253,12 @@ fn abort_if_errors(count: usize) {
std::process::exit(1);
}

fn cmd_compile(file_path: &str, output: Option<&str>, format: MessageFormat) {
fn cmd_compile(
file_path: &str,
output: Option<&str>,
format: MessageFormat,
mode: CompilationMode,
) {
let mut compilation = load_compilation(file_path);

for crate_graph in &compilation.crates {
Expand All @@ -266,12 +282,26 @@ fn cmd_compile(file_path: &str, output: Option<&str>, format: MessageFormat) {
.count(),
);

let mir =
mir::MIR::build(&tir, &compilation.interner, compilation.id_generator);
let module = codegen::Builder::build(&mir, &compilation.interner).unwrap();
let bytecode = module.encode();
let mut mir = mir::MIR::build(
&tir,
&compilation.interner,
compilation.id_generator,
mode,
);
let mut graph = mir::CallGraph::build(&mir.functions, &mir.call_edges);
if mode == CompilationMode::Release {
mir.inline_calls(&mut graph);
}
mir.dead_code_eliminate(&graph);
let module =
codegen::Builder::build(&mir, &compilation.interner, mode).unwrap();

if output == Some("-") {
// No debug info for stdout output, regardless of mode — same
// reasoning as `--debug` always being self-contained for file
// output: nothing here would have anywhere to attribute embedded
// DWARF, since there's no file path to reason about.
let bytecode = module.encode();
std::io::stdout().write_all(&bytecode).unwrap();
return;
}
Expand All @@ -280,6 +310,34 @@ fn cmd_compile(file_path: &str, output: Option<&str>, format: MessageFormat) {
Some(path) => path.to_string(),
None => format!("{}.wasm", output_stem(file_path)),
};

let bytecode = match mode {
CompilationMode::Release => module.encode(),
CompilationMode::Debug => {
let (mut bytecode, debug_spans, function_debug_info) =
module.encode_with_debug_spans();
let sections = dwarf::build(
&debug_spans,
&function_debug_info,
&mir,
&compilation.interner,
&compilation.files,
);
for (name, payload) in [
(".debug_abbrev", &sections.debug_abbrev),
(".debug_info", &sections.debug_info),
(".debug_line", &sections.debug_line),
(".debug_str", &sections.debug_str),
(".debug_line_str", &sections.debug_line_str),
(".debug_aranges", &sections.debug_aranges),
] {
bytecode
.extend_from_slice(&dwarf::custom_section(name, payload));
}
bytecode
}
};

let mut file = fs::File::create(&out_path).unwrap();
file.write_all(&bytecode).unwrap();
eprintln!("Wrote {} bytes to {out_path}", bytecode.len());
Expand Down
19 changes: 15 additions & 4 deletions crates/wx-compiler-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,21 @@ pub fn compile(
.into_js());
}

let mir =
mir::MIR::build(&hir, &compilation.interner, compilation.id_generator);
let module = codegen::Builder::build(&mir, &compilation.interner)
.map_err(|_| "codegen failed".to_string())?;
let mut mir = mir::MIR::build(
&hir,
&compilation.interner,
compilation.id_generator,
CompilationMode::Release,
);
let mut graph = mir::CallGraph::build(&mir.functions, &mir.call_edges);
mir.inline_calls(&mut graph);
mir.dead_code_eliminate(&graph);
let module = codegen::Builder::build(
&mir,
&compilation.interner,
CompilationMode::Release,
)
.map_err(|_| "codegen failed".to_string())?;
let bytecode = module.encode();

Ok(CompilationResult {
Expand Down
4 changes: 4 additions & 0 deletions crates/wx-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ serde_json = { workspace = true }
insta = { version = "1.43", features = ["yaml"] }
wasmtime = "46.0.1"
wasmprinter = "0.252.0"
gimli = { version = "0.33", default-features = false, features = ["read"] }
addr2line = { version = "0.26", default-features = false, features = [
"fallible-iterator",
] }
Loading
Loading