2022-02-09 07:08:40 -06:00
|
|
|
pub mod host_functions;
|
|
|
|
|
2022-04-11 17:23:11 -05:00
|
|
|
use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::host_functions::HostExternals};
|
2022-02-09 07:08:40 -06:00
|
|
|
use genfs::{Fs, OpenOptions};
|
2022-02-12 03:25:02 -06:00
|
|
|
use wasmi::{ImportsBuilder, ModuleInstance};
|
2022-02-09 07:08:40 -06:00
|
|
|
|
|
|
|
pub fn interp() {
|
2022-02-26 07:35:36 -06:00
|
|
|
trace!("Interpreting...");
|
2022-02-09 07:08:40 -06:00
|
|
|
let fs = &*FILE_SYSTEM.lock();
|
2022-02-26 07:35:36 -06:00
|
|
|
trace!("Got filesystem");
|
2022-02-09 07:08:40 -06:00
|
|
|
let file = fs
|
2022-02-26 07:35:36 -06:00
|
|
|
.open(
|
2022-04-19 02:15:45 -05:00
|
|
|
b"/home/able/bins/aos_test.wasm",
|
2022-02-26 07:35:36 -06:00
|
|
|
OpenOptions::new().read(true),
|
|
|
|
)
|
2022-02-09 07:08:40 -06:00
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let mut wasm_binary = Vec::new();
|
|
|
|
|
|
|
|
let ret = file.read_to_end(&mut wasm_binary).unwrap();
|
2022-02-26 07:35:36 -06:00
|
|
|
trace!("Binary size {}", ret);
|
2022-02-09 07:08:40 -06:00
|
|
|
// Load wasm binary and prepare it for instantiation.
|
|
|
|
let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
|
2022-04-09 17:26:43 -05:00
|
|
|
trace!("Loaded wasm binary");
|
2022-02-09 07:08:40 -06:00
|
|
|
let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
|
2022-04-09 17:26:43 -05:00
|
|
|
trace!("Created imports");
|
2022-02-09 07:08:40 -06:00
|
|
|
|
|
|
|
// Instantiate a module with empty imports and
|
|
|
|
// assert that there is no `start` function.
|
2022-04-09 17:26:43 -05:00
|
|
|
let instance = ModuleInstance::new(&module, &imports); // .expect("failed to instantiate wasm module")
|
|
|
|
|
|
|
|
match instance {
|
|
|
|
Ok(inst) => {
|
2022-04-11 15:51:54 -05:00
|
|
|
let instance = inst.assert_no_start();
|
2022-04-09 17:26:43 -05:00
|
|
|
let mut is_driver = false;
|
2022-04-11 15:51:54 -05:00
|
|
|
let _is_program = false;
|
2022-04-09 17:26:43 -05:00
|
|
|
let mut has_driver_entry = false;
|
|
|
|
let mut has_driver_exit = false;
|
|
|
|
let mut has_start = false;
|
|
|
|
|
2022-04-11 15:51:54 -05:00
|
|
|
if let Some(_val) = instance.export_by_name("driver_entry") {
|
2022-04-09 17:26:43 -05:00
|
|
|
has_driver_entry = true;
|
|
|
|
}
|
|
|
|
|
2022-04-11 15:51:54 -05:00
|
|
|
if let Some(_val) = instance.export_by_name("driver_exit") {
|
2022-04-09 17:26:43 -05:00
|
|
|
has_driver_exit = true;
|
|
|
|
}
|
2022-02-09 07:08:40 -06:00
|
|
|
|
2022-04-09 17:26:43 -05:00
|
|
|
match instance.export_by_name("start") {
|
2022-04-11 15:51:54 -05:00
|
|
|
Some(_val) => {
|
2022-04-09 17:26:43 -05:00
|
|
|
trace!("Program start function found");
|
|
|
|
has_start = true;
|
|
|
|
}
|
|
|
|
None => debug!("No start function found"),
|
|
|
|
}
|
2022-02-09 07:08:40 -06:00
|
|
|
|
2022-04-19 02:15:45 -05:00
|
|
|
match instance.export_by_name("main") {
|
|
|
|
Some(_val) => {
|
|
|
|
trace!("Program main function found");
|
|
|
|
has_start = true;
|
|
|
|
}
|
|
|
|
None => debug!("No main function found"),
|
|
|
|
}
|
|
|
|
|
2022-04-09 17:26:43 -05:00
|
|
|
match (has_driver_entry, has_driver_exit) {
|
|
|
|
(true, true) => {
|
|
|
|
trace!("Valid driver entry and exit functions found");
|
|
|
|
is_driver = true;
|
|
|
|
}
|
|
|
|
(true, false) => error!("Driver entry function found but no driver exit function"),
|
|
|
|
(false, true) => error!("Driver exit function found but no driver entry function"),
|
|
|
|
(false, false) => {
|
|
|
|
trace!("No driver entry or exit functions found");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if has_start && has_driver_entry {
|
2022-04-09 22:04:16 -05:00
|
|
|
error!(
|
|
|
|
"A program should not have both a start function and a driver entry function. It Will be treated as a program."
|
|
|
|
);
|
2022-04-09 17:26:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if has_start {
|
|
|
|
let ret = instance
|
|
|
|
.invoke_export("start", &[], &mut HostExternals {})
|
|
|
|
.expect("failed to execute export");
|
|
|
|
|
|
|
|
println!("collected wasm return value: {:?}", ret);
|
|
|
|
} else if is_driver {
|
|
|
|
let ret = instance
|
|
|
|
.invoke_export("driver_entry", &[], &mut HostExternals {})
|
|
|
|
.expect("failed to execute export");
|
|
|
|
|
|
|
|
println!("collected wasm return value: {:?}", ret);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => error!("{}", err),
|
|
|
|
}
|
2022-02-09 07:08:40 -06:00
|
|
|
}
|
2022-04-09 17:26:43 -05:00
|
|
|
|
2022-04-25 04:56:01 -05:00
|
|
|
pub fn run_program(program: Vec<u8>) {
|
|
|
|
// Load wasm binary and prepare it for instantiation.
|
|
|
|
let module = wasmi::Module::from_buffer(&program).expect("failed to load wasm");
|
|
|
|
trace!("Loaded wasm binary");
|
|
|
|
let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
|
|
|
|
trace!("Created imports");
|
|
|
|
|
|
|
|
// 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")
|
|
|
|
|
|
|
|
match instance {
|
|
|
|
Ok(inst) => {
|
|
|
|
let instance = inst.assert_no_start();
|
|
|
|
let mut is_driver = false;
|
|
|
|
let _is_program = false;
|
|
|
|
let mut has_driver_entry = false;
|
|
|
|
let mut has_driver_exit = false;
|
|
|
|
let mut has_start = false;
|
|
|
|
|
|
|
|
if let Some(_val) = instance.export_by_name("driver_entry") {
|
|
|
|
has_driver_entry = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(_val) = instance.export_by_name("driver_exit") {
|
|
|
|
has_driver_exit = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
match instance.export_by_name("start") {
|
|
|
|
Some(_val) => {
|
|
|
|
trace!("Program start function found");
|
|
|
|
has_start = true;
|
|
|
|
}
|
|
|
|
None => debug!("No start function found"),
|
|
|
|
}
|
|
|
|
|
|
|
|
match instance.export_by_name("main") {
|
|
|
|
Some(_val) => {
|
|
|
|
trace!("Program main function found");
|
|
|
|
has_start = false;
|
|
|
|
}
|
|
|
|
None => debug!("No main function found"),
|
|
|
|
}
|
|
|
|
|
|
|
|
match (has_driver_entry, has_driver_exit) {
|
|
|
|
(true, true) => {
|
|
|
|
trace!("Valid driver entry and exit functions found");
|
|
|
|
is_driver = true;
|
|
|
|
}
|
|
|
|
(true, false) => error!("Driver entry function found but no driver exit function"),
|
|
|
|
(false, true) => error!("Driver exit function found but no driver entry function"),
|
|
|
|
(false, false) => {
|
|
|
|
trace!("No driver entry or exit functions found");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if has_start && has_driver_entry {
|
|
|
|
error!(
|
|
|
|
"A program should not have both a start function and a driver entry function. It Will be treated as a program."
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if has_start {
|
|
|
|
let ret = instance
|
|
|
|
.invoke_export("start", &[], &mut HostExternals {})
|
|
|
|
.expect("failed to execute export");
|
|
|
|
|
|
|
|
println!("collected wasm return value: {:?}", ret);
|
|
|
|
} else if is_driver {
|
|
|
|
let ret = instance
|
|
|
|
.invoke_export("driver_entry", &[], &mut HostExternals {})
|
|
|
|
.expect("failed to execute export");
|
|
|
|
|
|
|
|
println!("collected wasm return value: {:?}", ret);
|
|
|
|
} else {
|
|
|
|
println!("ERROR: No start or driver entry function found, invalid program");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => error!("{}", err),
|
|
|
|
}
|
|
|
|
}
|