mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Refactored emscripten logic out of Instance
This commit is contained in:
parent
93f8cdfc81
commit
3f27610459
@ -74,6 +74,81 @@ pub struct EmscriptenData {
|
|||||||
pub stack_alloc: extern "C" fn(u32, &Instance) -> u32,
|
pub stack_alloc: extern "C" fn(u32, &Instance) -> u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EmscriptenData {
|
||||||
|
pub fn new(module: &Module, instance: &Instance) -> Self {
|
||||||
|
unsafe {
|
||||||
|
debug!("emscripten::new");
|
||||||
|
let malloc_export = module.info.exports.get("_malloc");
|
||||||
|
let free_export = module.info.exports.get("_free");
|
||||||
|
let memalign_export = module.info.exports.get("_memalign");
|
||||||
|
let memset_export = module.info.exports.get("_memset");
|
||||||
|
let stack_alloc_export = module.info.exports.get("stackAlloc");
|
||||||
|
|
||||||
|
let mut malloc_addr = 0 as *const u8;
|
||||||
|
let mut free_addr = 0 as *const u8;
|
||||||
|
let mut memalign_addr = 0 as *const u8;
|
||||||
|
let mut memset_addr = 0 as *const u8;
|
||||||
|
let mut stack_alloc_addr = 0 as _;
|
||||||
|
|
||||||
|
if let Some(Export::Function(malloc_index)) = malloc_export {
|
||||||
|
malloc_addr = instance.get_function_pointer(*malloc_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Export::Function(free_index)) = free_export {
|
||||||
|
free_addr = instance.get_function_pointer(*free_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Export::Function(memalign_index)) = memalign_export {
|
||||||
|
memalign_addr = instance.get_function_pointer(*memalign_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Export::Function(memset_index)) = memset_export {
|
||||||
|
memset_addr = instance.get_function_pointer(*memset_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Export::Function(stack_alloc_index)) = stack_alloc_export {
|
||||||
|
stack_alloc_addr = instance.get_function_pointer(*stack_alloc_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmscriptenData {
|
||||||
|
malloc: mem::transmute(malloc_addr),
|
||||||
|
free: mem::transmute(free_addr),
|
||||||
|
memalign: mem::transmute(memalign_addr),
|
||||||
|
memset: mem::transmute(memset_addr),
|
||||||
|
stack_alloc: mem::transmute(stack_alloc_addr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emscripten __ATINIT__
|
||||||
|
pub fn atinit(&self, module: &Module, instance: &Instance) -> Result<(), String> {
|
||||||
|
debug!("emscripten::atinit");
|
||||||
|
if let Some(&Export::Function(environ_constructor_index)) =
|
||||||
|
module.info.exports.get("___emscripten_environ_constructor")
|
||||||
|
{
|
||||||
|
debug!("emscripten::___emscripten_environ_constructor");
|
||||||
|
let ___emscripten_environ_constructor: extern "C" fn(&Instance) =
|
||||||
|
get_instance_function!(instance, environ_constructor_index);
|
||||||
|
call_protected!(___emscripten_environ_constructor(&instance))
|
||||||
|
.map_err(|err| format!("{}", err))?;
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
// TODO: We also need to handle TTY.init() and SOCKFS.root = FS.mount(SOCKFS, {}, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emscripten __ATEXIT__
|
||||||
|
pub fn atexit(&self, module: &Module, instance: &Instance) -> Result<(), String> {
|
||||||
|
debug!("emscripten::atexit");
|
||||||
|
use libc::fflush;
|
||||||
|
use std::ptr;
|
||||||
|
// Flush all open streams
|
||||||
|
unsafe {
|
||||||
|
fflush(ptr::null_mut());
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for EmscriptenData {
|
impl fmt::Debug for EmscriptenData {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("EmscriptenData")
|
f.debug_struct("EmscriptenData")
|
||||||
@ -554,66 +629,7 @@ impl Instance {
|
|||||||
tables: tables_pointer[..].into(),
|
tables: tables_pointer[..].into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let emscripten_data = if options.abi == InstanceABI::Emscripten {
|
let mut instance = Instance {
|
||||||
unsafe {
|
|
||||||
debug!("emscripten::initiating data");
|
|
||||||
let malloc_export = module.info.exports.get("_malloc");
|
|
||||||
let free_export = module.info.exports.get("_free");
|
|
||||||
let memalign_export = module.info.exports.get("_memalign");
|
|
||||||
let memset_export = module.info.exports.get("_memset");
|
|
||||||
let stack_alloc_export = module.info.exports.get("stackAlloc");
|
|
||||||
|
|
||||||
let mut malloc_addr = 0 as *const u8;
|
|
||||||
let mut free_addr = 0 as *const u8;
|
|
||||||
let mut memalign_addr = 0 as *const u8;
|
|
||||||
let mut memset_addr = 0 as *const u8;
|
|
||||||
let mut stack_alloc_addr = 0 as _;
|
|
||||||
|
|
||||||
if malloc_export.is_none()
|
|
||||||
&& free_export.is_none()
|
|
||||||
&& memalign_export.is_none()
|
|
||||||
&& memset_export.is_none()
|
|
||||||
{
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
if let Some(Export::Function(malloc_index)) = malloc_export {
|
|
||||||
malloc_addr =
|
|
||||||
get_function_addr(&malloc_index, &import_functions, &functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Export::Function(free_index)) = free_export {
|
|
||||||
free_addr = get_function_addr(&free_index, &import_functions, &functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Export::Function(memalign_index)) = memalign_export {
|
|
||||||
memalign_addr =
|
|
||||||
get_function_addr(&memalign_index, &import_functions, &functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Export::Function(memset_index)) = memset_export {
|
|
||||||
memset_addr =
|
|
||||||
get_function_addr(&memset_index, &import_functions, &functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Export::Function(stack_alloc_index)) = stack_alloc_export {
|
|
||||||
stack_alloc_addr =
|
|
||||||
get_function_addr(&stack_alloc_index, &import_functions, &functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(EmscriptenData {
|
|
||||||
malloc: mem::transmute(malloc_addr),
|
|
||||||
free: mem::transmute(free_addr),
|
|
||||||
memalign: mem::transmute(memalign_addr),
|
|
||||||
memset: mem::transmute(memset_addr),
|
|
||||||
stack_alloc: mem::transmute(stack_alloc_addr),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Instance {
|
|
||||||
data_pointers,
|
data_pointers,
|
||||||
tables: Arc::new(tables.into_iter().collect()), // tables.into_iter().map(|table| RwLock::new(table)).collect()),
|
tables: Arc::new(tables.into_iter().collect()), // tables.into_iter().map(|table| RwLock::new(table)).collect()),
|
||||||
memories: Arc::new(memories.into_iter().collect()),
|
memories: Arc::new(memories.into_iter().collect()),
|
||||||
@ -621,8 +637,14 @@ impl Instance {
|
|||||||
functions,
|
functions,
|
||||||
import_functions,
|
import_functions,
|
||||||
start_func,
|
start_func,
|
||||||
emscripten_data,
|
emscripten_data: None,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
if options.abi == InstanceABI::Emscripten {
|
||||||
|
instance.emscripten_data = Some(EmscriptenData::new(module, &instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memory_mut(&mut self, memory_index: usize) -> &mut LinearMemory {
|
pub fn memory_mut(&mut self, memory_index: usize) -> &mut LinearMemory {
|
||||||
|
@ -14,6 +14,7 @@ use cranelift_codegen::{
|
|||||||
settings::{self, Configurable},
|
settings::{self, Configurable},
|
||||||
};
|
};
|
||||||
use cranelift_wasm::ModuleEnvironment;
|
use cranelift_wasm::ModuleEnvironment;
|
||||||
|
use std::io::{self, Write};
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use target_lexicon;
|
use target_lexicon;
|
||||||
@ -153,7 +154,7 @@ pub fn get_isa() -> Box<isa::TargetIsa> {
|
|||||||
isa::lookup(triple!("x86_64")).unwrap().finish(flags)
|
isa::lookup(triple!("x86_64")).unwrap().finish(flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_module_arguments(path: &str, args: Vec<&str>, instance: &mut Instance) -> (u32, u32) {
|
fn store_module_arguments(path: &str, args: Vec<&str>, instance: &Instance) -> (u32, u32) {
|
||||||
let argc = args.len() + 1;
|
let argc = args.len() + 1;
|
||||||
|
|
||||||
let (argv_offset, argv_slice): (_, &mut [u32]) =
|
let (argv_offset, argv_slice): (_, &mut [u32]) =
|
||||||
@ -211,19 +212,9 @@ pub fn start_instance(
|
|||||||
path: &str,
|
path: &str,
|
||||||
args: Vec<&str>,
|
args: Vec<&str>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if is_emscripten_module(&module) {
|
if let Some(ref emscripten_data) = &instance.emscripten_data {
|
||||||
// Emscripten __ATINIT__
|
emscripten_data.atinit(module, instance)?;
|
||||||
if let Some(&Export::Function(environ_constructor_index)) =
|
|
||||||
module.info.exports.get("___emscripten_environ_constructor")
|
|
||||||
{
|
|
||||||
debug!("emscripten::___emscripten_environ_constructor");
|
|
||||||
let ___emscripten_environ_constructor: extern "C" fn(&Instance) =
|
|
||||||
get_instance_function!(instance, environ_constructor_index);
|
|
||||||
call_protected!(___emscripten_environ_constructor(&instance))
|
|
||||||
.map_err(|err| format!("{}", err))?;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: We also need to handle TTY.init() and SOCKFS.root = FS.mount(SOCKFS, {}, null)
|
|
||||||
let func_index = match module.info.exports.get("_main") {
|
let func_index = match module.info.exports.get("_main") {
|
||||||
Some(&Export::Function(index)) => index,
|
Some(&Export::Function(index)) => index,
|
||||||
_ => panic!("_main emscripten function not found"),
|
_ => panic!("_main emscripten function not found"),
|
||||||
@ -232,7 +223,7 @@ pub fn start_instance(
|
|||||||
let sig_index = module.get_func_type(func_index);
|
let sig_index = module.get_func_type(func_index);
|
||||||
let signature = module.get_signature(sig_index);
|
let signature = module.get_signature(sig_index);
|
||||||
let num_params = signature.params.len();
|
let num_params = signature.params.len();
|
||||||
match num_params {
|
let result = match num_params {
|
||||||
2 => {
|
2 => {
|
||||||
let main: extern "C" fn(u32, u32, &Instance) =
|
let main: extern "C" fn(u32, u32, &Instance) =
|
||||||
get_instance_function!(instance, func_index);
|
get_instance_function!(instance, func_index);
|
||||||
@ -248,8 +239,11 @@ pub fn start_instance(
|
|||||||
num_params
|
num_params
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
.map_err(|err| format!("{}", err))
|
.map_err(|err| format!("{}", err));
|
||||||
// TODO: We should implement emscripten __ATEXIT__
|
|
||||||
|
emscripten_data.atexit(module, instance)?;
|
||||||
|
|
||||||
|
result
|
||||||
} else {
|
} else {
|
||||||
let func_index =
|
let func_index =
|
||||||
instance
|
instance
|
||||||
|
Loading…
Reference in New Issue
Block a user