use alloc::vec::Vec; pub fn rhai_shell() { let engine = engine_construction(); let mut scope = rhai::Scope::new(); let mut buf = String::new(); print!("> "); loop { match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) { Some('\n') => { match engine.eval_with_scope::(&mut scope, &buf) { Ok(o) => println!("{o}"), Err(e) => println!("Eval error: {e}"), }; buf.clear(); print!("> "); } Some('\u{0008}') => { buf.pop(); } Some(chr) => buf.push(chr), None => (), } } } lazy_static::lazy_static!( pub static ref KEYBUFF: spin::Mutex> = spin::Mutex::new( Vec::new()) ; ); use alloc::string::{String, ToString}; use rhai::Engine; use x86_64::instructions::interrupts::{disable, enable}; use crate::{ arch::{shutdown, sloop}, kmain::{tick, TICK}, systeminfo::{KERNEL_VERSION, RELEASE_TYPE}, KERNEL_STATE, }; pub fn afetch() { let kstate = KERNEL_STATE.lock(); use core::sync::atomic::Ordering::*; disable(); let tick_time = TICK.load(Relaxed); println!( "OS: AbleOS Host: {} Kernel: AKern-{}-v{} Uptime: {}", kstate.hostname, RELEASE_TYPE, KERNEL_VERSION, tick_time ); enable(); drop(kstate); } pub fn set_hostname(name: String) { let mut kstate = KERNEL_STATE.lock(); kstate.hostname = name; } fn engine_construction() -> Engine { let mut engine = rhai::Engine::new(); engine.on_print(|x| println!("{}", x)); engine.on_debug(|x, src, pos| { let src = src.unwrap_or("unknown"); println!("DEBUG: {} at {:?}: {}", src, pos, x); debug!("{} at {:?}: {}", src, pos, x); }); engine.register_fn("afetch", afetch); engine.register_fn("set_hostname", set_hostname); engine.register_fn("shutdown", shutdown); engine.register_fn("peek", peek_memory); engine.register_fn("poke", poke_memory); engine } /// Examine a memory pointer pub fn peek_memory(ptr: i64) -> u8 { let ptr: usize = ptr as usize; unsafe { *(ptr as *const u8) } } pub fn poke_memory(ptr: i64, val: u8) { let ptr: usize = ptr as usize; unsafe { *(ptr as *mut u8) = val } }