aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--examples/add.rs5
-rw-r--r--examples/fib.rs5
-rw-r--r--src/rt.rs55
3 files changed, 48 insertions, 17 deletions
diff --git a/examples/add.rs b/examples/add.rs
index 3ad8893..fee5392 100644
--- a/examples/add.rs
+++ b/examples/add.rs
@@ -30,9 +30,8 @@ fn main() {
let mut rt = Runtime::new();
let add42 = unsafe { rt.add_code::<extern "C" fn(u32) -> u32>(asm.into_code()) };
- // Write out JIT code for visualization.
- // Disassemble for example with `ndisasm -b 64 jit.asm`.
- rt.dump();
+ // Disassemble JIT code and write to stdout.
+ rt.disasm();
let res = add42(5);
assert_eq!(res, 47);
diff --git a/examples/fib.rs b/examples/fib.rs
index c38589f..573b27c 100644
--- a/examples/fib.rs
+++ b/examples/fib.rs
@@ -66,9 +66,8 @@ fn main() {
let mut rt = Runtime::new();
let fib = unsafe { rt.add_code::<extern "C" fn(u64) -> u64>(asm.into_code()) };
- // Write out JIT code for visualization.
- // Disassemble for example with `ndisasm -b 64 jit.asm`.
- rt.dump();
+ // Disassemble JIT code and write to stdout.
+ rt.disasm();
for n in 0..15 {
let fib_jit = fib(n);
diff --git a/src/rt.rs b/src/rt.rs
index 4c4309b..a47cada 100644
--- a/src/rt.rs
+++ b/src/rt.rs
@@ -156,22 +156,55 @@ impl Runtime {
unsafe { Self::as_fn::<F>(fn_start) }
}
- /// Dump the code added so far to the runtime into a file called `jit.asm` in the processes
- /// current working directory.
- ///
- /// The code can be inspected with a disassembler as for example `ndiasm` from
- /// [nasm.us](https://nasm.us/index.php).
- /// ```sh
- /// ndisasm -b 64 jit.asm
- /// ```
+ /// Disassemble the code currently added to the runtime, using
+ /// [`ndisasm`](https://nasm.us/index.php) and print it to _stdout_. If
+ /// `ndisasm` is not available on the system this prints a warning and
+ /// becomes a nop.
///
/// # Panics
///
- /// Panics if writing the file failed.
- pub fn dump(&self) {
+ /// Panics if anything goes wrong with spawning, writing to or reading from
+ /// the `ndisasm` child process.
+ pub fn disasm(&self) {
assert!(self.idx <= self.len);
let code = unsafe { core::slice::from_raw_parts(self.buf, self.idx) };
- std::fs::write("jit.asm", code).expect("Failed to write file");
+
+ // Create ndisasm process, which expects input on stdin.
+ let mut child = match std::process::Command::new("ndisasm")
+ .args(["-b64", "-"])
+ .stdin(std::process::Stdio::piped())
+ .stdout(std::process::Stdio::piped())
+ .spawn()
+ {
+ Ok(child) => child,
+ Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
+ println!("Runtime::disasm: ndisasm not found, skipping!");
+ return;
+ }
+ Err(err) => {
+ panic!("{:?}", err);
+ }
+ };
+
+ // Write code to stdin of ndisasm.
+ use std::io::Write;
+ child
+ .stdin
+ .take()
+ .expect("failed to take stdin")
+ .write_all(code)
+ .expect("failed to write bytes to stdin");
+
+ // Wait for output from ndisasm and print to stdout.
+ println!(
+ "{}",
+ String::from_utf8_lossy(
+ &child
+ .wait_with_output()
+ .expect("failed to get stdout")
+ .stdout
+ )
+ );
}
/// Reinterpret the block of code pointed to by `fn_start` as `F`.