fn main() {
#[cfg(target_arch = "x86_64")]
run();
#[cfg(not(target_arch = "x86_64"))]
println!("this example assembles x86-64 code; nothing to run on this architecture");
}
#[cfg(target_arch = "x86_64")]
fn run() {
use pager_lang::{Protection, Region};
#[cfg(any(target_os = "linux", target_os = "macos"))]
const CODE: [u8; 7] = [0x48, 0x89, 0xF8, 0x48, 0x01, 0xF0, 0xC3];
#[cfg(target_os = "windows")]
const CODE: [u8; 7] = [0x48, 0x89, 0xC8, 0x48, 0x01, 0xD0, 0xC3];
let mut region = Region::with_guard_pages(CODE.len()).expect("map code region");
println!(
"mapped {} bytes (guard pages: {})",
region.len(),
region.has_guard_pages()
);
region.write(0, &CODE).expect("write code");
region
.protect(Protection::ReadExecute)
.expect("make executable");
assert!(region.as_mut_slice().is_none());
let add: extern "C" fn(u64, u64) -> u64 = unsafe { core::mem::transmute(region.as_ptr()) };
let result = add(19, 23);
println!("jitted add(19, 23) = {result}");
assert_eq!(result, 42);
}