From 550a1794e9460467c474d56554b62942bf911a9c Mon Sep 17 00:00:00 2001 From: johannst Date: Fri, 13 Dec 2024 22:47:47 +0000 Subject: deploy: 869761849ff64669244b6cbb79cac41f66654041 --- src/bf/bf.rs.html | 44 +++++++++++++++++++++++++++++--------------- src/juicebox_asm/rt.rs.html | 42 ++++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/bf/bf.rs.html b/src/bf/bf.rs.html index 556b131..8efe643 100644 --- a/src/bf/bf.rs.html +++ b/src/bf/bf.rs.html @@ -402,10 +402,16 @@ 401 402 403 -404
//! Brainfuck VM.
+404
+405
+406
+407
+408
+409
+410
+411
//! Brainfuck VM.
 //!
-//! This example implements a simple
-//! [brainfuck](https://en.wikipedia.org/wiki/Brainfuck) interpreter
+//! This example implements a simple [brainfuck][bf] interpreter
 //! [`BrainfuckInterp`] and a jit compiler [`BrainfuckJit`].
 //!
 //! Brainfuck is an esoteric programming languge existing of 8 commands.
@@ -415,8 +421,16 @@
 //! - `-` decrement data at current data pointer.
 //! - `.` output data at current data pointer.
 //! - `,` read input and store at current data pointer.
-//! - `[` jump behind matching ']' if data at data pointer is zero.
-//! - `]` jump behind matching '[' if data at data pointer is non-zero.
+//! - `[` jump behind matching `]` if data at data pointer is zero.
+//! - `]` jump behind matching `[` if data at data pointer is non-zero.
+//!
+//! The following is the `hello-world` program from [wikipedia][hw].
+//! ```
+//! ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
+//! ```
+//!
+//! [bf]: https://en.wikipedia.org/wiki/Brainfuck
+//! [hw]: https://en.wikipedia.org/wiki/Brainfuck#Hello_World!
 
 use std::collections::HashMap;
 use std::io::Write;
@@ -439,7 +453,7 @@
     fn new(prog: &str) -> Result<Self, String> {
         // Do a first pass over the bf program to filter whitespace and detect
         // invalid tokens. Additionally validate all conditional branches, and
-        // compute their branch target.
+        // compute their branch targets.
         let (imem, branches) = {
             // Instruction memory holding the final bf program.
             let mut imem = Vec::new();
@@ -591,8 +605,8 @@
 
     // Move data memory pointer (argument on jit entry) into correct register.
     asm.mov(dmem_base, Reg64::rdi);
-    // Move data memory size into correct register.
-    asm.mov(dmem_size, Reg64::rsi);
+    // Move data memory size (compile time constant) into correct register.
+    asm.mov(dmem_size, Imm64::from(vm.dmem.len()));
     // Clear data memory index.
     asm.xor(dmem_idx, dmem_idx);
 
@@ -720,11 +734,11 @@
         pc += 1;
     }
 
-    let mut ret_epilogue = Label::new();
+    let mut epilogue = Label::new();
 
     // Successful return from bf program.
     asm.xor(Reg64::rax, Reg64::rax);
-    asm.bind(&mut ret_epilogue);
+    asm.bind(&mut epilogue);
     // Restore callee saved registers before returning from jit.
     asm.pop(dmem_idx);
     asm.pop(dmem_size);
@@ -734,12 +748,12 @@
     // Return because of data pointer overflow.
     asm.bind(&mut oob_ov);
     asm.mov(Reg64::rax, Imm64::from(1));
-    asm.jmp(&mut ret_epilogue);
+    asm.jmp(&mut epilogue);
 
     // Return because of data pointer underflow.
     asm.bind(&mut oob_uv);
     asm.mov(Reg64::rax, Imm64::from(2));
-    asm.jmp(&mut ret_epilogue);
+    asm.jmp(&mut epilogue);
 
     if !label_stack.is_empty() {
         panic!("encountered un-balanced brackets, left-over '[' after jitting bf program")
@@ -747,11 +761,11 @@
 
     // Get function pointer to jitted bf program.
     let mut rt = Runtime::new();
-    let bf_entry = unsafe { rt.add_code::<extern "C" fn(*mut u8, usize) -> u64>(asm.into_code()) };
+    let bf_entry = unsafe { rt.add_code::<extern "C" fn(*mut u8) -> u64>(asm.into_code()) };
 
     // Execute jitted bf program.
-    match bf_entry(&mut vm.dmem as *mut u8, vm.dmem.len()) {
-        0 => {}
+    match bf_entry(&mut vm.dmem as *mut u8) {
+        0 => { /* success */ }
         1 => panic!("oob: data pointer overflow"),
         2 => panic!("oob: data pointer underflow"),
         _ => unreachable!(),
diff --git a/src/juicebox_asm/rt.rs.html b/src/juicebox_asm/rt.rs.html
index 039fa77..b0fad10 100644
--- a/src/juicebox_asm/rt.rs.html
+++ b/src/juicebox_asm/rt.rs.html
@@ -266,8 +266,7 @@
 265
 266
 267
-268
-269
//! Simple `mmap`ed runtime.
+268
//! Simple `mmap`ed runtime.
 //!
 //! This runtime supports adding code to executable pages and turn the added code into user
 //! specified function pointer.
@@ -275,8 +274,6 @@
 #[cfg(not(target_os = "linux"))]
 compile_error!("This runtime is only supported on linux");
 
-use nix::sys::mman::{mmap, mprotect, munmap, MapFlags, ProtFlags};
-
 mod perf {
     use std::fs;
     use std::io::Write;
@@ -298,7 +295,7 @@
     impl PerfMap {
         /// Create an empty perf map file.
         pub(super) fn new() -> Self {
-            let name = format!("/tmp/perf-{}.map", nix::unistd::getpid());
+            let name = format!("/tmp/perf-{}.map", unsafe { libc::getpid() });
             let file = fs::OpenOptions::new()
                 .truncate(true)
                 .create(true)
@@ -338,22 +335,26 @@
     /// Panics if the `mmap` call fails.
     pub fn new() -> Runtime {
         // Allocate a single page.
-        let len = core::num::NonZeroUsize::new(4096).expect("Value is non zero");
+        let len = 4096;
         let buf = unsafe {
-            mmap(
-                None,
+            libc::mmap(
+                std::ptr::null_mut(),
                 len,
-                ProtFlags::PROT_NONE,
-                MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
+                libc::PROT_NONE,
+                libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
                 0, /* fd */
                 0, /* off */
-            )
-            .expect("Failed to mmap runtime code page") as *mut u8
+            ) as *mut u8
         };
+        assert_ne!(
+            buf.cast(),
+            libc::MAP_FAILED,
+            "Failed to mmap runtime code page"
+        );
 
         Runtime {
             buf,
-            len: len.get(),
+            len,
             idx: 0,
             perf: None,
         }
@@ -455,12 +456,8 @@
     fn protect(&mut self) {
         unsafe {
             // Remove write permissions from code page and allow to read-execute from it.
-            mprotect(
-                self.buf.cast(),
-                self.len,
-                ProtFlags::PROT_READ | ProtFlags::PROT_EXEC,
-            )
-            .expect("Failed to RX mprotect runtime code page");
+            let ret = libc::mprotect(self.buf.cast(), self.len, libc::PROT_READ | libc::PROT_EXEC);
+            assert_eq!(ret, 0, "Failed to RX mprotect runtime code page");
         }
     }
 
@@ -472,8 +469,8 @@
     fn unprotect(&mut self) {
         unsafe {
             // Add write permissions to code page.
-            mprotect(self.buf.cast(), self.len, ProtFlags::PROT_WRITE)
-                .expect("Failed to W mprotect runtime code page");
+            let ret = libc::mprotect(self.buf.cast(), self.len, libc::PROT_WRITE);
+            assert_eq!(ret, 0, "Failed to W mprotect runtime code page");
         }
     }
 }
@@ -483,7 +480,8 @@
     /// [`Runtime::add_code`].
     fn drop(&mut self) {
         unsafe {
-            munmap(self.buf.cast(), self.len).expect("Failed to munmap runtime");
+            let ret = libc::munmap(self.buf.cast(), self.len);
+            assert_eq!(ret, 0, "Failed to munmap runtime");
         }
     }
 }
-- 
cgit v1.2.3