2022-04-11 17:23:11 -05:00
|
|
|
use crate::{arch::generate_process_pass, rhai_shell::KEYBUFF};
|
2022-02-09 07:08:40 -06:00
|
|
|
use wasmi::{
|
|
|
|
Error, Externals, FuncInstance, FuncRef, ModuleImportResolver, RuntimeArgs, RuntimeValue,
|
|
|
|
Signature, Trap, ValueType,
|
|
|
|
};
|
|
|
|
|
|
|
|
const ADD_FUNC_INDEX: usize = 0;
|
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;
|
2022-04-11 13:53:33 -05:00
|
|
|
const PRINT_CLEVER_HACK: usize = 5;
|
2022-04-11 17:23:11 -05:00
|
|
|
const SEND_SIGNAL_INDEX: usize = 1;
|
2022-04-11 13:53:33 -05:00
|
|
|
|
2022-04-11 17:23:11 -05:00
|
|
|
pub struct HostExternals;
|
2022-02-09 07:08:40 -06:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 15:51:54 -05:00
|
|
|
true
|
2022-04-09 17:26:43 -05:00
|
|
|
}
|
2022-04-11 17:23:11 -05:00
|
|
|
|
2022-04-09 17:26:43 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 15:51:54 -05:00
|
|
|
true
|
2022-04-09 17:26:43 -05:00
|
|
|
}
|
2022-04-11 17:23:11 -05:00
|
|
|
|
2022-04-09 17:26:43 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 15:51:54 -05:00
|
|
|
true
|
2022-04-09 17:26:43 -05:00
|
|
|
}
|
2022-04-11 17:23:11 -05:00
|
|
|
|
2022-04-09 17:26:43 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 15:51:54 -05:00
|
|
|
true
|
2022-04-09 17:26:43 -05:00
|
|
|
}
|
2022-04-11 17:23:11 -05:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 15:51:54 -05:00
|
|
|
true
|
2022-04-09 23:49:17 -05:00
|
|
|
}
|
2022-04-11 13:53:33 -05:00
|
|
|
|
|
|
|
PRINT_CLEVER_HACK => {
|
|
|
|
let (params, ret_ty): (&[ValueType], Option<ValueType>) = (&[ValueType::I64], None);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 15:51:54 -05:00
|
|
|
true
|
2022-04-11 13:53:33 -05:00
|
|
|
}
|
2022-04-09 17:26:43 -05:00
|
|
|
_ => false,
|
|
|
|
}
|
2022-02-09 07:08:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-11 17:23:11 -05:00
|
|
|
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;
|
|
|
|
trace!("SYSCALL: {} + {} = {}", a, b, result);
|
|
|
|
Ok(Some(RuntimeValue::I32(result as i32)))
|
|
|
|
}
|
|
|
|
|
|
|
|
SEND_SIGNAL_INDEX => {
|
|
|
|
let pid: u32 = args.nth_checked(0)?;
|
|
|
|
let signal: u32 = args.nth_checked(1)?;
|
|
|
|
|
|
|
|
trace!("SYSCALL: send signal {} to pid {}", signal, pid);
|
|
|
|
let ret = RuntimeValue::I32(0);
|
|
|
|
Ok(Some(ret))
|
|
|
|
}
|
|
|
|
|
|
|
|
GET_TIME_INDEX => {
|
|
|
|
use core::sync::atomic::Ordering::*;
|
|
|
|
trace!("SYSCALL: get time");
|
2022-04-12 13:26:52 -05:00
|
|
|
|
2022-04-11 17:23:11 -05:00
|
|
|
x86_64::instructions::interrupts::disable();
|
|
|
|
let tick_time = kernel::TICK.load(Relaxed);
|
|
|
|
x86_64::instructions::interrupts::enable();
|
|
|
|
|
|
|
|
let ret = RuntimeValue::I32(tick_time.try_into().unwrap());
|
|
|
|
Ok(Some(ret))
|
|
|
|
}
|
|
|
|
|
|
|
|
GET_RANDOM_INDEX => {
|
|
|
|
trace!("SYSCALL: get random");
|
|
|
|
let rand = generate_process_pass();
|
|
|
|
|
|
|
|
let ret = RuntimeValue::I32(rand as i32);
|
|
|
|
|
|
|
|
// let ret = RuntimeValue::I32(rand.try_into().unwrap());
|
|
|
|
Ok(Some(ret))
|
|
|
|
}
|
|
|
|
|
|
|
|
GET_INPUT_INDEX => {
|
2022-04-12 13:46:50 -05:00
|
|
|
let input =
|
|
|
|
// None;
|
|
|
|
x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop());
|
2022-04-11 17:23:11 -05:00
|
|
|
if let Some(chr) = input {
|
|
|
|
trace!("SYSCALL: input: {}", chr);
|
|
|
|
}
|
|
|
|
|
|
|
|
let ret = RuntimeValue::I32(input.unwrap_or(0x00 as char) as i32);
|
|
|
|
|
|
|
|
Ok(Some(ret))
|
|
|
|
}
|
|
|
|
|
|
|
|
PRINT_CLEVER_HACK => {
|
|
|
|
// println!("SYSCALL: print clever hack");
|
|
|
|
|
|
|
|
let combinated = args.nth_checked::<u64>(0).unwrap().to_le_bytes();
|
|
|
|
|
|
|
|
for x in combinated.iter() {
|
|
|
|
let chr = *x as char;
|
|
|
|
print!("{}", chr);
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("\n");
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => {
|
|
|
|
error!("Unimplemented function at {}", index);
|
|
|
|
Err(Trap::new(wasmi::TrapKind::Unreachable))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-09 07:08:40 -06:00
|
|
|
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,
|
2022-04-11 13:53:33 -05:00
|
|
|
"print_clever_hack" => PRINT_CLEVER_HACK,
|
2022-02-09 07:08:40 -06:00
|
|
|
_ => {
|
|
|
|
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-02-09 07:08:40 -06:00
|
|
|
)));
|
|
|
|
}
|
2022-04-09 17:26:43 -05:00
|
|
|
|
2022-04-11 17:23:11 -05:00
|
|
|
trace!("Resolved export {} as func {}", field_name, index);
|
2022-04-09 17:26:43 -05:00
|
|
|
Ok(FuncInstance::alloc_host(signature.clone(), index))
|
2022-02-09 07:08:40 -06:00
|
|
|
}
|
|
|
|
}
|