mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 14:25:32 +00:00
Added APIs to support conditional emscripten instantiation
This commit is contained in:
parent
3f1a6e5ac6
commit
5ad5606b39
@ -4,9 +4,11 @@ use crate::webassembly::{ImportObject, ImportValue};
|
||||
mod memory;
|
||||
mod process;
|
||||
mod io;
|
||||
mod utils;
|
||||
|
||||
// SYSCALLS
|
||||
use super::host;
|
||||
pub use self::utils::is_emscripten_module;
|
||||
|
||||
pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
let mut import_object = ImportObject::new();
|
||||
|
9
src/apis/emscripten/tests/is_emscripten_false.wast
Normal file
9
src/apis/emscripten/tests/is_emscripten_false.wast
Normal file
@ -0,0 +1,9 @@
|
||||
(module
|
||||
(table 0 anyfunc)
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $main))
|
||||
(func $main (; 1 ;) (result i32)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
17
src/apis/emscripten/tests/is_emscripten_true.wast
Normal file
17
src/apis/emscripten/tests/is_emscripten_true.wast
Normal file
@ -0,0 +1,17 @@
|
||||
(module
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(import "env" "puts" (func $puts (param i32) (result i32)))
|
||||
(table 0 anyfunc)
|
||||
(memory $0 1)
|
||||
(data (i32.const 16) "hello, world!\00")
|
||||
(export "memory" (memory $0))
|
||||
(export "main" (func $main))
|
||||
(func $main (; 1 ;) (result i32)
|
||||
(drop
|
||||
(call $puts
|
||||
(i32.const 16)
|
||||
)
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
35
src/apis/emscripten/utils.rs
Normal file
35
src/apis/emscripten/utils.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::webassembly::module::Module;
|
||||
|
||||
/// We check if a provided module is an Emscripten generated one
|
||||
pub fn is_emscripten_module(module: &Module) -> bool {
|
||||
for (module, field) in &module.info.imported_funcs {
|
||||
if module == "env" {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::webassembly::instantiate;
|
||||
use super::is_emscripten_module;
|
||||
use super::super::generate_emscripten_env;
|
||||
|
||||
#[test]
|
||||
fn should_detect_emscripten_files() {
|
||||
let wasm_bytes = include_wast2wasm_bytes!("tests/is_emscripten_true.wast");
|
||||
let import_object = generate_emscripten_env();
|
||||
let result_object = instantiate(wasm_bytes, import_object).expect("Not compiled properly");
|
||||
assert!(is_emscripten_module(&result_object.module));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_detect_non_emscripten_files() {
|
||||
let wasm_bytes = include_wast2wasm_bytes!("tests/is_emscripten_false.wast");
|
||||
let import_object = generate_emscripten_env();
|
||||
let result_object = instantiate(wasm_bytes, import_object).expect("Not compiled properly");
|
||||
assert!(!is_emscripten_module(&result_object.module));
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
pub mod emscripten;
|
||||
pub mod host;
|
||||
|
||||
pub use self::emscripten::generate_emscripten_env;
|
||||
|
||||
pub use self::emscripten::{generate_emscripten_env, is_emscripten_module};
|
||||
|
22
src/main.rs
22
src/main.rs
@ -71,22 +71,32 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> {
|
||||
wasm_binary = wabt::wat2wasm(wasm_binary)
|
||||
.map_err(|err| format!("Can't convert from wast to wasm: {:?}", err))?;
|
||||
}
|
||||
|
||||
// TODO: We should instantiate after compilation, so we provide the
|
||||
// emscripten environment conditionally based on the module
|
||||
let import_object = apis::generate_emscripten_env();
|
||||
let webassembly::ResultObject { module, instance } =
|
||||
webassembly::instantiate(wasm_binary, import_object)
|
||||
.map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err))?;
|
||||
|
||||
// webassembly::utils::print_instance_offsets(&instance);
|
||||
|
||||
if apis::is_emscripten_module(&module) {
|
||||
let func_index = match module.info.exports.get("main") {
|
||||
Some(&webassembly::Export::Function(index)) => index,
|
||||
_ => panic!("_main emscripten function not found"),
|
||||
};
|
||||
let main: extern fn(u32, u32, &webassembly::Instance) = get_instance_function!(instance, func_index);
|
||||
main(0, 0, &instance);
|
||||
}
|
||||
else {
|
||||
let func_index = instance
|
||||
.start_func
|
||||
.unwrap_or_else(|| match module.info.exports.get("main").or(module.info.exports.get("_main")) {
|
||||
.unwrap_or_else(|| match module.info.exports.get("main") {
|
||||
Some(&webassembly::Export::Function(index)) => index,
|
||||
_ => panic!("Main function not found"),
|
||||
});
|
||||
let main: extern fn(u32, u32, &webassembly::Instance) = get_instance_function!(instance, func_index);
|
||||
main(0, 0, &instance);
|
||||
let main: extern fn(&webassembly::Instance) = get_instance_function!(instance, func_index);
|
||||
main(&instance);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user