mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 13:48:26 +00:00
Clean up and port various parts of emscripten
This commit is contained in:
@@ -32,7 +32,7 @@ pub use crate::types::{
|
|||||||
pub use crate::types::{Val as Value, ValType as Type};
|
pub use crate::types::{Val as Value, ValType as Type};
|
||||||
|
|
||||||
pub use target_lexicon::{Architecture, CallingConvention, OperatingSystem, Triple, HOST};
|
pub use target_lexicon::{Architecture, CallingConvention, OperatingSystem, Triple, HOST};
|
||||||
pub use wasm_common::{Bytes, Pages, ValueType, WasmExternType, WasmTypeList};
|
pub use wasm_common::{Bytes, GlobalInit, Pages, ValueType, WasmExternType, WasmTypeList};
|
||||||
#[cfg(feature = "compiler")]
|
#[cfg(feature = "compiler")]
|
||||||
pub use wasmer_compiler::CompilerConfig;
|
pub use wasmer_compiler::CompilerConfig;
|
||||||
pub use wasmer_compiler::{CpuFeature, Features, Target};
|
pub use wasmer_compiler::{CpuFeature, Features, Target};
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ lazy_static = "1.4"
|
|||||||
libc = "0.2.60"
|
libc = "0.2.60"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
#wasmer-runtime-core = { path = "../runtime-core", version = "0.16.2" }
|
|
||||||
wasmer = { path = "../api", version = "0.16.2" }
|
wasmer = { path = "../api", version = "0.16.2" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
|||||||
@@ -20,18 +20,10 @@ use std::collections::HashMap;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{f64, ffi::c_void};
|
use std::{f64, ffi::c_void};
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
imports, Exportable, Function, FunctionType, Global, ImportObject, Instance, Memory,
|
imports, AnyRef, Exportable, Function, FunctionType, Global, ImportObject, ImportType,
|
||||||
MemoryType, Module, NativeFunc, Pages, RuntimeError, Store, Table, TableType, Val, ValType,
|
Instance, Memory, MemoryType, Module, NativeFunc, Pages, RuntimeError, Store, Table, TableType,
|
||||||
|
Val, ValType,
|
||||||
};
|
};
|
||||||
/*use wasmer_runtime_core::{
|
|
||||||
error::{CallError, CallResult, ResolveError},
|
|
||||||
export::Export,
|
|
||||||
func,
|
|
||||||
module::ImportName,
|
|
||||||
types::ElementType,
|
|
||||||
vm::Ctx,
|
|
||||||
DynFunc, IsExport,
|
|
||||||
};*/
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use ::libc::DIR as LibcDir;
|
use ::libc::DIR as LibcDir;
|
||||||
@@ -84,7 +76,7 @@ pub struct EmEnv<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EmEnv<'a> {
|
impl<'a> EmEnv<'a> {
|
||||||
pub fn new(memory: Memory, data: &'a mut EmscriptenData) -> Self {
|
pub fn new(memory: Memory, data: &'a mut EmscriptenData<'a>) -> Self {
|
||||||
Self { memory, data }
|
Self { memory, data }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,87 +192,120 @@ impl<'a> EmscriptenData<'a> {
|
|||||||
) -> EmscriptenData<'a> {
|
) -> EmscriptenData<'a> {
|
||||||
let malloc = instance
|
let malloc = instance
|
||||||
.exports
|
.exports
|
||||||
.get("_malloc")
|
.get_native_function("_malloc")
|
||||||
.or(instance.exports.get("malloc"))
|
.or_else(|_| instance.exports.get_native_function("malloc"))
|
||||||
.ok();
|
.ok();
|
||||||
let free = instance
|
let free = instance
|
||||||
.exports
|
.exports
|
||||||
.get("_free")
|
.get_native_function("_free")
|
||||||
.or(instance.exports.get("free"))
|
.or_else(|_| instance.exports.get_native_function("free"))
|
||||||
.ok();
|
.ok();
|
||||||
let memalign = instance
|
let memalign = instance
|
||||||
.exports
|
.exports
|
||||||
.get("_memalign")
|
.get_native_function("_memalign")
|
||||||
.or(instance.exports.get("memalign"))
|
.or_else(|_| instance.exports.get_native_function("memalign"))
|
||||||
.ok();
|
.ok();
|
||||||
let memset = instance
|
let memset = instance
|
||||||
.exports
|
.exports
|
||||||
.get("_memset")
|
.get_native_function("_memset")
|
||||||
.or(instance.exports.get("memset"))
|
.or_else(|_| instance.exports.get_native_function("memset"))
|
||||||
.ok();
|
.ok();
|
||||||
let stack_alloc = instance.exports.get("stackAlloc").ok();
|
let stack_alloc = instance.exports.get_native_function("stackAlloc").ok();
|
||||||
|
|
||||||
let dyn_call_i = instance.exports.get("dynCall_i").ok();
|
let dyn_call_i = instance.exports.get_native_function("dynCall_i").ok();
|
||||||
let dyn_call_ii = instance.exports.get("dynCall_ii").ok();
|
let dyn_call_ii = instance.exports.get_native_function("dynCall_ii").ok();
|
||||||
let dyn_call_iii = instance.exports.get("dynCall_iii").ok();
|
let dyn_call_iii = instance.exports.get_native_function("dynCall_iii").ok();
|
||||||
let dyn_call_iiii = instance.exports.get("dynCall_iiii").ok();
|
let dyn_call_iiii = instance.exports.get_native_function("dynCall_iiii").ok();
|
||||||
let dyn_call_iifi = instance.exports.get("dynCall_iifi").ok();
|
let dyn_call_iifi = instance.exports.get_native_function("dynCall_iifi").ok();
|
||||||
let dyn_call_v = instance.exports.get("dynCall_v").ok();
|
let dyn_call_v = instance.exports.get_native_function("dynCall_v").ok();
|
||||||
let dyn_call_vi = instance.exports.get("dynCall_vi").ok();
|
let dyn_call_vi = instance.exports.get_native_function("dynCall_vi").ok();
|
||||||
let dyn_call_vii = instance.exports.get("dynCall_vii").ok();
|
let dyn_call_vii = instance.exports.get_native_function("dynCall_vii").ok();
|
||||||
let dyn_call_viii = instance.exports.get("dynCall_viii").ok();
|
let dyn_call_viii = instance.exports.get_native_function("dynCall_viii").ok();
|
||||||
let dyn_call_viiii = instance.exports.get("dynCall_viiii").ok();
|
let dyn_call_viiii = instance.exports.get_native_function("dynCall_viiii").ok();
|
||||||
|
|
||||||
// round 2
|
// round 2
|
||||||
let dyn_call_dii = instance.exports.get("dynCall_dii").ok();
|
let dyn_call_dii = instance.exports.get_native_function("dynCall_dii").ok();
|
||||||
let dyn_call_diiii = instance.exports.get("dynCall_diiii").ok();
|
let dyn_call_diiii = instance.exports.get_native_function("dynCall_diiii").ok();
|
||||||
let dyn_call_iiiii = instance.exports.get("dynCall_iiiii").ok();
|
let dyn_call_iiiii = instance.exports.get_native_function("dynCall_iiiii").ok();
|
||||||
let dyn_call_iiiiii = instance.exports.get("dynCall_iiiiii").ok();
|
let dyn_call_iiiiii = instance.exports.get_native_function("dynCall_iiiiii").ok();
|
||||||
let dyn_call_iiiiiii = instance.exports.get("dynCall_iiiiiii").ok();
|
let dyn_call_iiiiiii = instance.exports.get_native_function("dynCall_iiiiiii").ok();
|
||||||
let dyn_call_iiiiiiii = instance.exports.get("dynCall_iiiiiiii").ok();
|
let dyn_call_iiiiiiii = instance
|
||||||
let dyn_call_iiiiiiiii = instance.exports.get("dynCall_iiiiiiiii").ok();
|
.exports
|
||||||
let dyn_call_iiiiiiiiii = instance.exports.get("dynCall_iiiiiiiiii").ok();
|
.get_native_function("dynCall_iiiiiiii")
|
||||||
let dyn_call_iiiiiiiiiii = instance.exports.get("dynCall_iiiiiiiiiii").ok();
|
.ok();
|
||||||
let dyn_call_vd = instance.exports.get("dynCall_vd").ok();
|
let dyn_call_iiiiiiiii = instance
|
||||||
let dyn_call_viiiii = instance.exports.get("dynCall_viiiii").ok();
|
.exports
|
||||||
let dyn_call_viiiiii = instance.exports.get("dynCall_viiiiii").ok();
|
.get_native_function("dynCall_iiiiiiiii")
|
||||||
let dyn_call_viiiiiii = instance.exports.get("dynCall_viiiiiii").ok();
|
.ok();
|
||||||
let dyn_call_viiiiiiii = instance.exports.get("dynCall_viiiiiiii").ok();
|
let dyn_call_iiiiiiiiii = instance
|
||||||
let dyn_call_viiiiiiiii = instance.exports.get("dynCall_viiiiiiiii").ok();
|
.exports
|
||||||
let dyn_call_viiiiiiiiii = instance.exports.get("dynCall_viiiiiiiiii").ok();
|
.get_native_function("dynCall_iiiiiiiiii")
|
||||||
let dyn_call_iij = instance.exports.get("dynCall_iij").ok();
|
.ok();
|
||||||
let dyn_call_iji = instance.exports.get("dynCall_iji").ok();
|
let dyn_call_iiiiiiiiiii = instance
|
||||||
let dyn_call_iiji = instance.exports.get("dynCall_iiji").ok();
|
.exports
|
||||||
let dyn_call_iiijj = instance.exports.get("dynCall_iiijj").ok();
|
.get_native_function("dynCall_iiiiiiiiiii")
|
||||||
let dyn_call_j = instance.exports.get("dynCall_j").ok();
|
.ok();
|
||||||
let dyn_call_ji = instance.exports.get("dynCall_ji").ok();
|
let dyn_call_vd = instance.exports.get_native_function("dynCall_vd").ok();
|
||||||
let dyn_call_jii = instance.exports.get("dynCall_jii").ok();
|
let dyn_call_viiiii = instance.exports.get_native_function("dynCall_viiiii").ok();
|
||||||
let dyn_call_jij = instance.exports.get("dynCall_jij").ok();
|
let dyn_call_viiiiii = instance.exports.get_native_function("dynCall_viiiiii").ok();
|
||||||
let dyn_call_jjj = instance.exports.get("dynCall_jjj").ok();
|
let dyn_call_viiiiiii = instance
|
||||||
let dyn_call_viiij = instance.exports.get("dynCall_viiij").ok();
|
.exports
|
||||||
let dyn_call_viiijiiii = instance.exports.get("dynCall_viiijiiii").ok();
|
.get_native_function("dynCall_viiiiiii")
|
||||||
let dyn_call_viiijiiiiii = instance.exports.get("dynCall_viiijiiiiii").ok();
|
.ok();
|
||||||
let dyn_call_viij = instance.exports.get("dynCall_viij").ok();
|
let dyn_call_viiiiiiii = instance
|
||||||
let dyn_call_viiji = instance.exports.get("dynCall_viiji").ok();
|
.exports
|
||||||
let dyn_call_viijiii = instance.exports.get("dynCall_viijiii").ok();
|
.get_native_function("dynCall_viiiiiiii")
|
||||||
let dyn_call_viijj = instance.exports.get("dynCall_viijj").ok();
|
.ok();
|
||||||
let dyn_call_vj = instance.exports.get("dynCall_vj").ok();
|
let dyn_call_viiiiiiiii = instance
|
||||||
let dyn_call_vjji = instance.exports.get("dynCall_vjji").ok();
|
.exports
|
||||||
let dyn_call_vij = instance.exports.get("dynCall_vij").ok();
|
.get_native_function("dynCall_viiiiiiiii")
|
||||||
let dyn_call_viji = instance.exports.get("dynCall_viji").ok();
|
.ok();
|
||||||
let dyn_call_vijiii = instance.exports.get("dynCall_vijiii").ok();
|
let dyn_call_viiiiiiiiii = instance
|
||||||
let dyn_call_vijj = instance.exports.get("dynCall_vijj").ok();
|
.exports
|
||||||
let dyn_call_viid = instance.exports.get("dynCall_viid").ok();
|
.get_native_function("dynCall_viiiiiiiiii")
|
||||||
let dyn_call_vidd = instance.exports.get("dynCall_vidd").ok();
|
.ok();
|
||||||
let dyn_call_viidii = instance.exports.get("dynCall_viidii").ok();
|
let dyn_call_iij = instance.exports.get_native_function("dynCall_iij").ok();
|
||||||
let dyn_call_viidddddddd = instance.exports.get("dynCall_viidddddddd").ok();
|
let dyn_call_iji = instance.exports.get_native_function("dynCall_iji").ok();
|
||||||
|
let dyn_call_iiji = instance.exports.get_native_function("dynCall_iiji").ok();
|
||||||
|
let dyn_call_iiijj = instance.exports.get_native_function("dynCall_iiijj").ok();
|
||||||
|
let dyn_call_j = instance.exports.get_native_function("dynCall_j").ok();
|
||||||
|
let dyn_call_ji = instance.exports.get_native_function("dynCall_ji").ok();
|
||||||
|
let dyn_call_jii = instance.exports.get_native_function("dynCall_jii").ok();
|
||||||
|
let dyn_call_jij = instance.exports.get_native_function("dynCall_jij").ok();
|
||||||
|
let dyn_call_jjj = instance.exports.get_native_function("dynCall_jjj").ok();
|
||||||
|
let dyn_call_viiij = instance.exports.get_native_function("dynCall_viiij").ok();
|
||||||
|
let dyn_call_viiijiiii = instance
|
||||||
|
.exports
|
||||||
|
.get_native_function("dynCall_viiijiiii")
|
||||||
|
.ok();
|
||||||
|
let dyn_call_viiijiiiiii = instance
|
||||||
|
.exports
|
||||||
|
.get_native_function("dynCall_viiijiiiiii")
|
||||||
|
.ok();
|
||||||
|
let dyn_call_viij = instance.exports.get_native_function("dynCall_viij").ok();
|
||||||
|
let dyn_call_viiji = instance.exports.get_native_function("dynCall_viiji").ok();
|
||||||
|
let dyn_call_viijiii = instance.exports.get_native_function("dynCall_viijiii").ok();
|
||||||
|
let dyn_call_viijj = instance.exports.get_native_function("dynCall_viijj").ok();
|
||||||
|
let dyn_call_vj = instance.exports.get_native_function("dynCall_vj").ok();
|
||||||
|
let dyn_call_vjji = instance.exports.get_native_function("dynCall_vjji").ok();
|
||||||
|
let dyn_call_vij = instance.exports.get_native_function("dynCall_vij").ok();
|
||||||
|
let dyn_call_viji = instance.exports.get_native_function("dynCall_viji").ok();
|
||||||
|
let dyn_call_vijiii = instance.exports.get_native_function("dynCall_vijiii").ok();
|
||||||
|
let dyn_call_vijj = instance.exports.get_native_function("dynCall_vijj").ok();
|
||||||
|
let dyn_call_viid = instance.exports.get_native_function("dynCall_viid").ok();
|
||||||
|
let dyn_call_vidd = instance.exports.get_native_function("dynCall_vidd").ok();
|
||||||
|
let dyn_call_viidii = instance.exports.get_native_function("dynCall_viidii").ok();
|
||||||
|
let dyn_call_viidddddddd = instance
|
||||||
|
.exports
|
||||||
|
.get_native_function("dynCall_viidddddddd")
|
||||||
|
.ok();
|
||||||
|
|
||||||
let stack_save = instance.exports.get("stackSave").ok();
|
let stack_save = instance.exports.get_native_function("stackSave").ok();
|
||||||
let stack_restore = instance.exports.get("stackRestore").ok();
|
let stack_restore = instance.exports.get_native_function("stackRestore").ok();
|
||||||
let set_threw = instance
|
let set_threw = instance
|
||||||
.exports
|
.exports
|
||||||
.get("_setThrew")
|
.get_native_function("_setThrew")
|
||||||
.or(instance.exports.get("setThrew"))
|
.or_else(|_| instance.exports.get_native_function("setThrew"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
EmscriptenData {
|
EmscriptenData {
|
||||||
@@ -385,6 +410,7 @@ pub fn set_up_emscripten(instance: &mut Instance) -> Result<(), RuntimeError> {
|
|||||||
/// If you don't want to set it up yourself, consider using [`run_emscripten_instance`].
|
/// If you don't want to set it up yourself, consider using [`run_emscripten_instance`].
|
||||||
pub fn emscripten_call_main(
|
pub fn emscripten_call_main(
|
||||||
instance: &mut Instance,
|
instance: &mut Instance,
|
||||||
|
env: &mut EmEnv,
|
||||||
path: &str,
|
path: &str,
|
||||||
args: &[&str],
|
args: &[&str],
|
||||||
) -> Result<(), RuntimeError> {
|
) -> Result<(), RuntimeError> {
|
||||||
@@ -395,17 +421,17 @@ pub fn emscripten_call_main(
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
}?;
|
}?;
|
||||||
let num_params = main_func.signature().params().len();
|
let num_params = main_func.ty().params().len();
|
||||||
let _result = match num_params {
|
let _result = match num_params {
|
||||||
2 => {
|
2 => {
|
||||||
let mut new_args = vec![path];
|
let mut new_args = vec![path];
|
||||||
new_args.extend(args);
|
new_args.extend(args);
|
||||||
let (argc, argv) = store_module_arguments(instance.context_mut(), new_args);
|
let (argc, argv) = store_module_arguments(env, new_args);
|
||||||
let func: Function = instance.exports.get(func_name)?;
|
let func: &Function = instance.exports.get(func_name)?;
|
||||||
func.call(&[Val::I32(argc as i32), Val::I32(argv as i32)])?;
|
func.call(&[Val::I32(argc as i32), Val::I32(argv as i32)])?;
|
||||||
}
|
}
|
||||||
0 => {
|
0 => {
|
||||||
let func: Function = instance.exports.get(func_name)?;
|
let func: &Function = instance.exports.get(func_name)?;
|
||||||
func.call(&[])?;
|
func.call(&[])?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -430,7 +456,7 @@ pub fn run_emscripten_instance(
|
|||||||
mapped_dirs: Vec<(String, PathBuf)>,
|
mapped_dirs: Vec<(String, PathBuf)>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> Result<(), RuntimeError> {
|
||||||
let mut data = EmscriptenData::new(instance, &globals.data, mapped_dirs.into_iter().collect());
|
let mut data = EmscriptenData::new(instance, &globals.data, mapped_dirs.into_iter().collect());
|
||||||
let env = EmEnv::new(globals.memory, &mut data);
|
let mut env = EmEnv::new(globals.memory, &mut data);
|
||||||
|
|
||||||
set_up_emscripten(instance)?;
|
set_up_emscripten(instance)?;
|
||||||
|
|
||||||
@@ -438,12 +464,12 @@ pub fn run_emscripten_instance(
|
|||||||
|
|
||||||
if let Some(ep) = entrypoint {
|
if let Some(ep) = entrypoint {
|
||||||
debug!("Running entry point: {}", &ep);
|
debug!("Running entry point: {}", &ep);
|
||||||
let arg = unsafe { allocate_cstr_on_stack(instance.context_mut(), args[0]).0 };
|
let arg = unsafe { allocate_cstr_on_stack(&mut env, args[0]).0 };
|
||||||
//let (argc, argv) = store_module_arguments(instance.context_mut(), args);
|
//let (argc, argv) = store_module_arguments(instance.context_mut(), args);
|
||||||
let func: Function = instance.exports.get(&ep)?;
|
let func: &Function = instance.exports.get(&ep)?;
|
||||||
func.call(&[Val::I32(arg as i32)])?;
|
func.call(&[Val::I32(arg as i32)])?;
|
||||||
} else {
|
} else {
|
||||||
emscripten_call_main(instance, path, &args)?;
|
emscripten_call_main(instance, &mut env, path, &args)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO atexit for emscripten
|
// TODO atexit for emscripten
|
||||||
@@ -514,20 +540,9 @@ impl EmscriptenGlobals {
|
|||||||
module: &Module, /*, static_bump: u32 */
|
module: &Module, /*, static_bump: u32 */
|
||||||
) -> Result<Self, String> {
|
) -> Result<Self, String> {
|
||||||
let mut use_old_abort_on_cannot_grow_memory = false;
|
let mut use_old_abort_on_cannot_grow_memory = false;
|
||||||
for (
|
for ImportType { module, name, ty } in module.imports().functions() {
|
||||||
index,
|
if name == "abortOnCannotGrowMemory" && module == "env" {
|
||||||
ImportName {
|
if ty == *OLD_ABORT_ON_CANNOT_GROW_MEMORY_SIG {
|
||||||
namespace_index,
|
|
||||||
name_index,
|
|
||||||
},
|
|
||||||
) in &module.info().imported_functions
|
|
||||||
{
|
|
||||||
let namespace = module.info().namespace_table.get(*namespace_index);
|
|
||||||
let name = module.info().name_table.get(*name_index);
|
|
||||||
if name == "abortOnCannotGrowMemory" && namespace == "env" {
|
|
||||||
let sig_index = module.info().func_assoc[index.convert_up(module.info())];
|
|
||||||
let expected_sig = &module.info().signatures[sig_index];
|
|
||||||
if *expected_sig == *OLD_ABORT_ON_CANNOT_GROW_MEMORY_SIG {
|
|
||||||
use_old_abort_on_cannot_grow_memory = true;
|
use_old_abort_on_cannot_grow_memory = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -542,11 +557,12 @@ impl EmscriptenGlobals {
|
|||||||
let memory = Memory::new(store, memory_type).unwrap();
|
let memory = Memory::new(store, memory_type).unwrap();
|
||||||
|
|
||||||
let table_type = TableType {
|
let table_type = TableType {
|
||||||
element: ElementType::Anyfunc,
|
ty: ValType::FuncRef,
|
||||||
minimum: table_min,
|
minimum: table_min,
|
||||||
maximum: table_max,
|
maximum: table_max,
|
||||||
};
|
};
|
||||||
let table = Table::new(table_type).unwrap();
|
// TODO: review init value
|
||||||
|
let table = Table::new(store, table_type, Val::AnyRef(AnyRef::null())).unwrap();
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
let static_bump = STATIC_BUMP;
|
let static_bump = STATIC_BUMP;
|
||||||
@@ -587,17 +603,8 @@ impl EmscriptenGlobals {
|
|||||||
emscripten_set_up_memory(&memory, &data)?;
|
emscripten_set_up_memory(&memory, &data)?;
|
||||||
|
|
||||||
let mut null_func_names = vec![];
|
let mut null_func_names = vec![];
|
||||||
for (
|
for ImportType { module, name, .. } in module.imports().functions() {
|
||||||
_,
|
if module == "env" && name.starts_with("nullFunction_") {
|
||||||
ImportName {
|
|
||||||
namespace_index,
|
|
||||||
name_index,
|
|
||||||
},
|
|
||||||
) in &module.info().imported_functions
|
|
||||||
{
|
|
||||||
let namespace = module.info().namespace_table.get(*namespace_index);
|
|
||||||
let name = module.info().name_table.get(*name_index);
|
|
||||||
if namespace == "env" && name.starts_with("nullFunction_") {
|
|
||||||
null_func_names.push(name.to_string())
|
null_func_names.push(name.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1066,7 +1073,6 @@ pub fn generate_emscripten_env(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Compatibility with newer versions of Emscripten
|
// Compatibility with newer versions of Emscripten
|
||||||
use crate::wasmer_runtime_core::import::LikeNamespace;
|
|
||||||
for (k, v) in env_ns.get_exports() {
|
for (k, v) in env_ns.get_exports() {
|
||||||
if k.starts_with("_") {
|
if k.starts_with("_") {
|
||||||
let k = &k[1..];
|
let k = &k[1..];
|
||||||
@@ -1077,23 +1083,26 @@ pub fn generate_emscripten_env(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for null_func_name in globals.null_func_names.iter() {
|
for null_func_name in globals.null_func_names.iter() {
|
||||||
env_ns.insert(null_func_name.as_str(), Function::new(nullfunc).to_export());
|
env_ns.insert(
|
||||||
|
null_func_name.as_str(),
|
||||||
|
Function::new_env(store, env, nullfunc).to_export(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let import_object: ImportObject = imports! {
|
let import_object: ImportObject = imports! {
|
||||||
"env" => env_ns,
|
"env" => env_ns,
|
||||||
"global" => {
|
"global" => {
|
||||||
"NaN" => Global::new(Val::F64(f64::NAN)),
|
"NaN" => Global::new(store, Val::F64(f64::NAN)),
|
||||||
"Infinity" => Global::new(Val::F64(f64::INFINITY)),
|
"Infinity" => Global::new(store, Val::F64(f64::INFINITY)),
|
||||||
},
|
},
|
||||||
"global.Math" => {
|
"global.Math" => {
|
||||||
"pow" => Function::new(store, crate::math::pow),
|
"pow" => Function::new(store, crate::math::pow),
|
||||||
"exp" => Function::new(store, crate::math::exp),
|
"exp" => Function::new(store, crate::math::exp),
|
||||||
"log" => Function::new(store, env, crate::math::log),
|
"log" => Function::new(store, crate::math::log),
|
||||||
},
|
},
|
||||||
"asm2wasm" => {
|
"asm2wasm" => {
|
||||||
"f64-rem" => Function::new_env(store, env, crate::math::f64_rem),
|
"f64-rem" => Function::new(store, crate::math::f64_rem),
|
||||||
"f64-to-int" => Function::new_env(store, env, crate::math::f64_to_int),
|
"f64-to-int" => Function::new(store, crate::math::f64_to_int),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,24 +8,15 @@ use std::mem::size_of;
|
|||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use wasmer::{Memory, Module, Pages};
|
use wasmer::{GlobalInit, ImportType, Memory, Module, Pages};
|
||||||
use wasmer_runtime_core::{
|
|
||||||
structures::TypedIndex,
|
|
||||||
types::{ImportedMemoryIndex, ImportedTableIndex},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// We check if a provided module is an Emscripten generated one
|
/// We check if a provided module is an Emscripten generated one
|
||||||
pub fn is_emscripten_module(module: &Module) -> bool {
|
pub fn is_emscripten_module(module: &Module) -> bool {
|
||||||
for (_, import_name) in &module.info().imported_functions {
|
for ImportType { module, name, .. } in module.imports().functions() {
|
||||||
let namespace = module
|
if (name == "_emscripten_memcpy_big"
|
||||||
.info()
|
|| name == "emscripten_memcpy_big"
|
||||||
.namespace_table
|
|| name == "__map_file")
|
||||||
.get(import_name.namespace_index);
|
&& module == "env"
|
||||||
let field = module.info().name_table.get(import_name.name_index);
|
|
||||||
if (field == "_emscripten_memcpy_big"
|
|
||||||
|| field == "emscripten_memcpy_big"
|
|
||||||
|| field == "__map_file")
|
|
||||||
&& namespace == "env"
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -34,19 +25,19 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_emscripten_table_size(module: &Module) -> Result<(u32, Option<u32>), String> {
|
pub fn get_emscripten_table_size(module: &Module) -> Result<(u32, Option<u32>), String> {
|
||||||
if module.info().imported_tables.len() == 0 {
|
if let Some(ImportType { ty, .. }) = module.imports().tables().next() {
|
||||||
|
Ok((ty.minimum, ty.maximum))
|
||||||
|
} else {
|
||||||
return Err("Emscripten requires at least one imported table".to_string());
|
return Err("Emscripten requires at least one imported table".to_string());
|
||||||
}
|
}
|
||||||
let (_, table) = &module.info().imported_tables[ImportedTableIndex::new(0)];
|
|
||||||
Ok((table.minimum, table.maximum))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_emscripten_memory_size(module: &Module) -> Result<(Pages, Option<Pages>, bool), String> {
|
pub fn get_emscripten_memory_size(module: &Module) -> Result<(Pages, Option<Pages>, bool), String> {
|
||||||
if module.info().imported_memories.len() == 0 {
|
if let Some(ImportType { ty, .. }) = module.imports().memories().next() {
|
||||||
|
Ok((ty.minimum, ty.maximum, ty.shared))
|
||||||
|
} else {
|
||||||
return Err("Emscripten requires at least one imported memory".to_string());
|
return Err("Emscripten requires at least one imported memory".to_string());
|
||||||
}
|
}
|
||||||
let (_, memory) = &module.info().imported_memories[ImportedMemoryIndex::new(0)];
|
|
||||||
Ok((memory.minimum, memory.maximum, memory.shared))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads values written by `-s EMIT_EMSCRIPTEN_METADATA=1`
|
/// Reads values written by `-s EMIT_EMSCRIPTEN_METADATA=1`
|
||||||
@@ -54,14 +45,20 @@ pub fn get_emscripten_memory_size(module: &Module) -> Result<(Pages, Option<Page
|
|||||||
/// Last export: Dynamic Base
|
/// Last export: Dynamic Base
|
||||||
/// Second-to-Last export: Dynamic top pointer
|
/// Second-to-Last export: Dynamic top pointer
|
||||||
pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, String> {
|
pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, String> {
|
||||||
let max_idx = match module.info().globals.iter().map(|(k, _)| k).max() {
|
let max_idx = match module
|
||||||
|
.info()
|
||||||
|
.global_initializers
|
||||||
|
.iter()
|
||||||
|
.map(|(k, _)| k)
|
||||||
|
.max()
|
||||||
|
{
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let snd_max_idx = match module
|
let snd_max_idx = match module
|
||||||
.info()
|
.info()
|
||||||
.globals
|
.global_initializers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, _)| k)
|
.map(|(k, _)| k)
|
||||||
.filter(|k| *k != max_idx)
|
.filter(|k| *k != max_idx)
|
||||||
@@ -71,19 +68,9 @@ pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, St
|
|||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
use wasmer_runtime_core::types::{GlobalInit, Initializer::Const, Value::I32};
|
if let (GlobalInit::I32Const(dynamic_base), GlobalInit::I32Const(dynamictop_ptr)) = (
|
||||||
if let (
|
&module.info().global_initializers[max_idx],
|
||||||
GlobalInit {
|
&module.info().global_initializers[snd_max_idx],
|
||||||
init: Const(I32(dynamic_base)),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
GlobalInit {
|
|
||||||
init: Const(I32(dynamictop_ptr)),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
) = (
|
|
||||||
&module.info().globals[max_idx],
|
|
||||||
&module.info().globals[snd_max_idx],
|
|
||||||
) {
|
) {
|
||||||
let dynamic_base = (*dynamic_base as u32).checked_sub(32).ok_or(format!(
|
let dynamic_base = (*dynamic_base as u32).checked_sub(32).ok_or(format!(
|
||||||
"emscripten unexpected dynamic_base {}",
|
"emscripten unexpected dynamic_base {}",
|
||||||
|
|||||||
Reference in New Issue
Block a user