separate the context intialization from the function execution (#21)
the start function is called from the initialization phase
This commit is contained in:
committed by
Dan Gohman
parent
95fba6a9de
commit
bf5a06bc95
@@ -11,7 +11,7 @@ use std::ptr::{self, write_unaligned};
|
||||
use std::string::String;
|
||||
use std::vec::Vec;
|
||||
use wasmtime_environ::{
|
||||
compile_module, Compilation, Module, ModuleTranslation, Relocation, RelocationTarget,
|
||||
compile_module, Compilation, Export, Module, ModuleTranslation, Relocation, RelocationTarget,
|
||||
};
|
||||
|
||||
/// Executes a module that has been translated with the `wasmtime-environ` environment
|
||||
@@ -132,16 +132,13 @@ fn make_vmctx(instance: &mut Instance, mem_base_addrs: &mut [*mut u8]) -> Vec<*m
|
||||
vmctx
|
||||
}
|
||||
|
||||
/// Jumps to the code region of memory and execute the start function of the module.
|
||||
pub fn execute(
|
||||
/// prepares the execution context
|
||||
pub fn finish_instantiation(
|
||||
module: &Module,
|
||||
compilation: &Compilation,
|
||||
instance: &mut Instance,
|
||||
) -> Result<(), String> {
|
||||
let start_index = module
|
||||
.start_func
|
||||
.ok_or_else(|| String::from("No start function defined, aborting execution"))?;
|
||||
// FIXME: Put all the function bodies into a page-aligned memory region, and
|
||||
) -> Result<Vec<*mut u8>, String> {
|
||||
// TODO: Put all the function bodies into a page-aligned memory region, and
|
||||
// then make them ReadExecute rather than ReadWriteExecute.
|
||||
for code_buf in compilation.functions.values() {
|
||||
match unsafe {
|
||||
@@ -161,26 +158,59 @@ pub fn execute(
|
||||
}
|
||||
}
|
||||
|
||||
let code_buf =
|
||||
&compilation.functions[module
|
||||
.defined_func_index(start_index)
|
||||
.expect("imported start functions not supported yet")];
|
||||
|
||||
// Collect all memory base addresses and Vec.
|
||||
let mut mem_base_addrs = instance
|
||||
.memories
|
||||
.values_mut()
|
||||
.map(LinearMemory::base_addr)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let vmctx = make_vmctx(instance, &mut mem_base_addrs);
|
||||
|
||||
if let Some(start_index) = module.start_func {
|
||||
let code_buf =
|
||||
&compilation.functions[module
|
||||
.defined_func_index(start_index)
|
||||
.expect("imported start functions not supported yet")];
|
||||
|
||||
// Rather than writing inline assembly to jump to the code region, we use the fact that
|
||||
// the Rust ABI for calling a function with no arguments and no return matches the one of
|
||||
// the generated code. Thanks to this, we can transmute the code region into a first-class
|
||||
// Rust function and call it.
|
||||
unsafe {
|
||||
let start_func = transmute::<_, fn(*const *mut u8)>(code_buf.as_ptr());
|
||||
start_func(vmctx.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(vmctx)
|
||||
}
|
||||
|
||||
/// Jumps to the code region of memory and execute the exported function
|
||||
pub fn execute(
|
||||
module: &Module,
|
||||
compilation: &Compilation,
|
||||
vmctx: &mut Vec<*mut u8>,
|
||||
function: &str,
|
||||
) -> Result<(), String> {
|
||||
let fn_index = match module.exports.get(function) {
|
||||
Some(Export::Function(index)) => *index,
|
||||
Some(_) => return Err(format!("exported item \"{}\" is not a function", function)),
|
||||
None => return Err(format!("no export named \"{}\"", function)),
|
||||
};
|
||||
|
||||
let code_buf =
|
||||
&compilation.functions[module
|
||||
.defined_func_index(fn_index)
|
||||
.expect("imported start functions not supported yet")];
|
||||
|
||||
// Rather than writing inline assembly to jump to the code region, we use the fact that
|
||||
// the Rust ABI for calling a function with no arguments and no return matches the one of
|
||||
// the generated code. Thanks to this, we can transmute the code region into a first-class
|
||||
// Rust function and call it.
|
||||
unsafe {
|
||||
let start_func = transmute::<_, fn(*const *mut u8)>(code_buf.as_ptr());
|
||||
start_func(vmctx.as_ptr());
|
||||
let func = transmute::<_, fn(*const *mut u8)>(code_buf.as_ptr());
|
||||
func(vmctx.as_ptr());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ mod execute;
|
||||
mod instance;
|
||||
mod memory;
|
||||
|
||||
pub use execute::{compile_and_link_module, execute};
|
||||
pub use execute::{compile_and_link_module, execute, finish_instantiation};
|
||||
pub use instance::Instance;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
|
||||
Reference in New Issue
Block a user