diff --git a/ableos/src/wasm/bin/console_out_test.wasm b/ableos/src/wasm/bin/console_out_test.wasm new file mode 100755 index 0000000..8177467 Binary files /dev/null and b/ableos/src/wasm/bin/console_out_test.wasm differ diff --git a/ableos/src/wasm/mod.rs b/ableos/src/wasm/mod.rs index 5f9105e..a0ad353 100644 --- a/ableos/src/wasm/mod.rs +++ b/ableos/src/wasm/mod.rs @@ -1,106 +1,115 @@ +use alloc::string::String; +use wasmi::TrapKind; + use { - alloc::format, - wasm_sys::SysCall, - wasmi::{ - Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, - ModuleInstance, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, - }, + alloc::format, + wasm_sys::SysCall, + wasmi::{ + Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, + ModuleInstance, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, + }, }; mod wasm_sys; struct HostFunctions; impl HostFunctions { - fn check_signature(&self, index: usize, signature: &Signature) -> bool { - let (params, ret_ty): (&[ValueType], Option) = match index.into() { - SysCall::KILL => (&[], None), - SysCall::EMPTY => (&[], None), - _ => return false, - }; - signature.params() == params && signature.return_type() == ret_ty - } + fn check_signature(&self, index: usize, signature: &Signature) -> bool { + let (params, ret_ty): (&[ValueType], Option) = match index.into() { + SysCall::KILL => (&[], None), + SysCall::EMPTY => (&[], None), + _ => return false, + }; + signature.params() == params && signature.return_type() == ret_ty + } } impl Externals for HostFunctions { - fn invoke_index( - &mut self, - index: usize, - _args: RuntimeArgs, - ) -> Result, Trap> { - match index.into() { - // Take in one arg discard the rest - SysCall::KILL => { - info!("Program run at runtime called a system call"); - debug!("Runtime arguments: {:?}", _args); - Ok(None) - } - // Do nothing - SysCall::EMPTY => Ok(None), - SysCall::EXIT => Ok(None), - SysCall::CONSOLE_RESET => Ok(None), - SysCall::CONSOLE_IN => { - info!("In"); - Ok(None) - } + fn invoke_index( + &mut self, + index: usize, + args: RuntimeArgs, + ) -> Result, Trap> { + match index.into() { + // Take in one arg discard the rest + SysCall::KILL => { + info!("Program run at runtime called a system call"); + debug!("Runtime arguments: {:?}", args); + Ok(None) + } + // Do nothing + SysCall::EMPTY => Ok(None), + SysCall::EXIT => Ok(None), + SysCall::CONSOLE_RESET => Ok(None), + SysCall::CONSOLE_IN => { + info!("In"); + Ok(None) + } - SysCall::CONSOLE_OUT => { - info!("Out"); - Ok(None) - } - SysCall::CONSOLE_GET_TITLE => Ok(None), - SysCall::CONSOLE_SET_TITLE => Ok(None), - _ => panic!("Unimplemented function at {}", index), - } - } + SysCall::CONSOLE_OUT => { + // Eventually change this to 2- ptr and len + if args.len() != 1 { + return Err(Trap::new(TrapKind::UnexpectedSignature)); + } + let arg: u64 = args.nth(0); + let buf = unsafe { String::from_utf8_unchecked(arg.to_le_bytes().to_vec()) }; + println!["{}", buf]; + Ok(None) + } + SysCall::CONSOLE_GET_TITLE => Ok(None), + SysCall::CONSOLE_SET_TITLE => Ok(None), + _ => panic!("Unimplemented function at {}", index), + } + } } impl ModuleImportResolver for HostFunctions { - fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { - let index = match field_name { - "kill" => SysCall::KILL as usize, - "empty" => SysCall::EMPTY as usize, - "exit" => SysCall::EXIT as usize, - _ => { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) - } - }; + fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { + let index = match field_name { + "kill" => SysCall::KILL as usize, + "empty" => SysCall::EMPTY as usize, + "exit" => SysCall::EXIT as usize, + _ => { + return Err(Error::Instantiation(format!( + "Export {} not found", + field_name + ))) + } + }; - if !self.check_signature(index, signature) { - return Err(Error::Instantiation(format!( - "Export {} has a bad signature", - field_name - ))); - } + if !self.check_signature(index, signature) { + return Err(Error::Instantiation(format!( + "Export {} has a bad signature", + field_name + ))); + } - Ok(FuncInstance::alloc_host( - Signature::new(&[][..], None), - index, - )) - } + Ok(FuncInstance::alloc_host( + Signature::new(&[][..], None), + index, + )) + } } pub fn evaluate() { - let wasm_binary = include_bytes!("bin/rust.wasm"); + let wasm_binary = include_bytes!("bin/rust.wasm"); - // Load wasm binary and prepare it for instantiation. - let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); + // Load wasm binary and prepare it for instantiation. + let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); - let imports = ImportsBuilder::new().with_resolver("env", &HostFunctions); + let imports = ImportsBuilder::new().with_resolver("env", &HostFunctions); - // Instantiate a module with empty imports and - // assert that there is no `start` function. - let instance = ModuleInstance::new(&module, &imports) - .expect("failed to instantiate wasm module") - .assert_no_start(); + // Instantiate a module with empty imports and + // assert that there is no `start` function. + let instance = ModuleInstance::new(&module, &imports) + .expect("failed to instantiate wasm module") + .assert_no_start(); - // Finally, invoke the exported function "test" with no parameters - // and empty external function executor. - let result: i32 = instance - .invoke_export("_start", &[], &mut HostFunctions) - .expect("failed to execute export") - .unwrap() - .try_into() - .unwrap(); + // Finally, invoke the exported function "test" with no parameters + // and empty external function executor. + let result: i32 = instance + .invoke_export("_start", &[], &mut HostFunctions) + .expect("failed to execute export") + .unwrap() + .try_into() + .unwrap(); - println!("{:?}", result); + println!("{:?}", result); } diff --git a/ableos/src/wasm/wasm_sys.rs b/ableos/src/wasm/wasm_sys.rs index 7ee8b45..900afce 100644 --- a/ableos/src/wasm/wasm_sys.rs +++ b/ableos/src/wasm/wasm_sys.rs @@ -9,6 +9,7 @@ macro_rules! syscall_enum { syscall_enum![@get_last $($VariantTail),*] }; ($($Variant:ident=$Value:expr,)*) => { + #[allow(clippy::upper_case_acronyms)] #[repr(usize)] pub enum SysCall { $($Variant = $Value),* @@ -28,64 +29,64 @@ macro_rules! syscall_enum { }; } syscall_enum! { - KILL=0, // Provide a PID - CONSOLE_RESET=1, // Reset the console - CONSOLE_IN=2, // Console Input - CONSOLE_OUT=3, // Console output - CONSOLE_GET_TITLE=4, // Get the console title - CONSOLE_SET_TITLE=5, // Set the console title - GET_PID=6, // Get the proccess ID - PROCESS_INFO=7, // Get information about the process - //scheduler Related Syscals - GET_PRIORITY=8, // Get scheduler priority - SET_PRIORITY=9, // Set scheduler priority - // - GET_HOSTNAME=10, - SET_HOSTNAME=11, + KILL=0, // Provide a PID + CONSOLE_RESET=1, // Reset the console + CONSOLE_IN=2, // Console Input + CONSOLE_OUT=3, // Console output + CONSOLE_GET_TITLE=4, // Get the console title + CONSOLE_SET_TITLE=5, // Set the console title + GET_PID=6, // Get the proccess ID + PROCESS_INFO=7, // Get information about the process + //scheduler Related Syscals + GET_PRIORITY=8, // Get scheduler priority + SET_PRIORITY=9, // Set scheduler priority + // + GET_HOSTNAME=10, + SET_HOSTNAME=11, - NEW_THREAD=12, - NEW_TASK=13, - KILL_THREAD=14, - KILL_TASK=15, - GET_THREAD=16, - GET_TASK=17, - SEND= 18, - RECEIVE = 19, - RESPOND = 20, + NEW_THREAD=12, + NEW_TASK=13, + KILL_THREAD=14, + KILL_TASK=15, + GET_THREAD=16, + GET_TASK=17, + SEND= 18, + RECEIVE = 19, + RESPOND = 20, - //File Related syscalls - // - MAKE_DIRECTORY=22, // - DELETE_DIRECTORY=23, // - RENAME_DIRECTORY=24, // - SET_DIRECTORY_ACCESS=25, // - // - MAKE_FILE=26, // - DELETE_FILE=27, // - RENAME_FILE=28, // - SET_FILE_ACCESS=29, // + //File Related syscalls + // + MAKE_DIRECTORY=22, // + DELETE_DIRECTORY=23, // + RENAME_DIRECTORY=24, // + SET_DIRECTORY_ACCESS=25, // + // + MAKE_FILE=26, // + DELETE_FILE=27, // + RENAME_FILE=28, // + SET_FILE_ACCESS=29, // - FILE_READ=30, - FILE_WRITE=31, + FILE_READ=30, + FILE_WRITE=31, - SLEEP=32, // Sleep in milliseconds - SLEEP_UNTIL=33, // Sleep until this time in milliseconds (if this is below the current time return) - NANOSLEEP=34, // Sleep in nanoseconds - NANOSLEEP_UNTIL=35, // Sleep until this time nanoseconds (if this is below the current time return) - GET_TIME=36, // Gets the system time (some derivitive of seconds) - SET_TIME=37, // Sets the system time (some derivitive of seconds) + SLEEP=32, // Sleep in milliseconds + SLEEP_UNTIL=33, // Sleep until this time in milliseconds (if this is below the current time return) + NANOSLEEP=34, // Sleep in nanoseconds + NANOSLEEP_UNTIL=35, // Sleep until this time nanoseconds (if this is below the current time return) + GET_TIME=36, // Gets the system time (some derivitive of seconds) + SET_TIME=37, // Sets the system time (some derivitive of seconds) - // Socket SysCall - SOCKET_BIND=39, // Used by servers to lock a port - SOCKET_CONNECT=40, - SOCKET_DISCONNECT=41, - SOCKET_SEND=42, - SOCKET_RECEIVE=43, + // Socket SysCall + SOCKET_BIND=39, // Used by servers to lock a port + SOCKET_CONNECT=40, + SOCKET_DISCONNECT=41, + SOCKET_SEND=42, + SOCKET_RECEIVE=43, - EXIT=50, - EMPTY=0xFFFF, + EXIT=50, + EMPTY=0xFFFF, }