1
0
Fork 0
forked from AbleOS/ableos
ableOS_v1Change/ableos/src/wasm_jumploader/host_functions.rs

203 lines
6.8 KiB
Rust
Raw Normal View History

2022-04-09 17:26:43 -05:00
use core::arch;
use wasmi::{
Error, Externals, FuncInstance, FuncRef, ModuleImportResolver, RuntimeArgs, RuntimeValue,
Signature, Trap, ValueType,
};
2022-02-12 03:25:02 -06:00
pub struct HostExternals {}
const ADD_FUNC_INDEX: usize = 0;
2022-02-26 07:35:36 -06:00
const SEND_SIGNAL_INDEX: usize = 1;
2022-02-26 07:47:44 -06:00
const GET_TIME_INDEX: usize = 2;
2022-04-09 17:26:43 -05:00
const GET_RANDOM_INDEX: usize = 3;
2022-04-09 23:49:17 -05:00
const GET_INPUT_INDEX: usize = 4;
impl Externals for HostExternals {
fn invoke_index(
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index {
ADD_FUNC_INDEX => {
let a: u32 = args.nth_checked(0)?;
let b: u32 = args.nth_checked(1)?;
let result = a + b;
2022-02-12 03:25:02 -06:00
println!("SYSCALL: {} + {} = {}", a, b, result);
Ok(Some(RuntimeValue::I32(result as i32)))
}
2022-02-26 07:35:36 -06:00
SEND_SIGNAL_INDEX => {
let pid: u32 = args.nth_checked(0)?;
let signal: u32 = args.nth_checked(1)?;
println!("SYSCALL: send signal {} to pid {}", signal, pid);
let ret = RuntimeValue::I32(0);
Ok(Some(ret))
}
2022-02-26 07:47:44 -06:00
GET_TIME_INDEX => {
use core::sync::atomic::Ordering::*;
2022-04-09 17:26:43 -05:00
println!("SYSCALL: get time");
x86_64::instructions::interrupts::disable();
let tick_time = kernel::TICK.load(Relaxed);
2022-04-09 17:26:43 -05:00
x86_64::instructions::interrupts::enable();
let ret = RuntimeValue::I32(tick_time.try_into().unwrap());
Ok(Some(ret))
}
GET_RANDOM_INDEX => {
println!("SYSCALL: get random");
let rand = generate_process_pass();
2022-02-26 07:47:44 -06:00
2022-04-09 17:26:43 -05:00
let ret = RuntimeValue::I32(rand as i32);
// let ret = RuntimeValue::I32(rand.try_into().unwrap());
2022-02-26 07:47:44 -06:00
Ok(Some(ret))
}
2022-04-09 23:49:17 -05:00
GET_INPUT_INDEX => {
// println!("SYSCALL: get input");
let input =
x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop());
if let Some(chr) = input {
println!("SYSCALL: input: {}", chr);
}
let ret = RuntimeValue::I32(input.unwrap_or(0x00 as char) as i32);
Ok(Some(ret))
}
_ => panic!("Unimplemented function at {}", index),
}
}
}
2022-04-09 23:49:17 -05:00
use crate::rhai_shell::KEYBUFF;
2022-04-09 17:26:43 -05:00
use crate::arch::generate_process_pass;
impl HostExternals {
fn check_signature(&self, index: usize, signature: &Signature) -> bool {
2022-04-09 17:26:43 -05:00
match index {
ADD_FUNC_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[ValueType::I32, ValueType::I32], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
return true;
}
SEND_SIGNAL_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[ValueType::I32, ValueType::I32], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
return true;
}
GET_TIME_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
return true;
}
GET_RANDOM_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
return true;
}
2022-04-09 23:49:17 -05:00
GET_INPUT_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
return true;
}
2022-04-09 17:26:43 -05:00
_ => false,
}
}
}
impl ModuleImportResolver for HostExternals {
fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
let index = match field_name {
"add" => ADD_FUNC_INDEX,
2022-02-26 07:35:36 -06:00
"send_signal" => SEND_SIGNAL_INDEX,
2022-04-09 17:26:43 -05:00
"get_time" => GET_TIME_INDEX,
"get_random" => GET_RANDOM_INDEX,
2022-04-09 23:49:17 -05:00
"get_input" => GET_INPUT_INDEX,
_ => {
return Err(Error::Instantiation(format!(
"Export {} not found",
field_name
)))
}
};
if !self.check_signature(index, signature) {
return Err(Error::Instantiation(format!(
2022-04-09 17:26:43 -05:00
"Export {} has a bad signature {:?}",
field_name, signature
)));
}
2022-04-09 17:26:43 -05:00
trace!("Resolved export {} as func {}", field_name, index);
Ok(FuncInstance::alloc_host(signature.clone(), index))
2022-04-09 17:26:43 -05:00
/*Ok(FuncInstance::alloc_host(
Signature::new(&[ValueType::I32, ValueType::I32][..], Some(ValueType::I32)),
index,
2022-04-09 17:26:43 -05:00
))*/
}
}
2022-04-09 17:26:43 -05:00
use crate::wasm_jumploader::host_functions::ValueType::I32;