mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 22:58:18 +00:00
Emscripten compiles with no errors!
This commit is contained in:
@@ -26,13 +26,16 @@ pub use crate::ptr::{Array, Item, WasmPtr};
|
|||||||
pub use crate::store::{Store, StoreObject};
|
pub use crate::store::{Store, StoreObject};
|
||||||
pub use crate::tunables::Tunables;
|
pub use crate::tunables::Tunables;
|
||||||
pub use crate::types::{
|
pub use crate::types::{
|
||||||
AnyRef, ExportType, ExternType, FunctionType, GlobalType, HostInfo, HostRef, ImportType,
|
xternType, AnyRef, ExportType, FunctionType, GlobalType, HostInfo, HostRef, ImportType,
|
||||||
MemoryType, Mutability, TableType, Val, ValType,
|
MemoryType, Mutability, TableType, Val, ValType,
|
||||||
};
|
};
|
||||||
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, GlobalInit, Pages, ValueType, WasmExternType, WasmTypeList};
|
pub use wasm_common::{
|
||||||
|
Bytes, GlobalInit, Pages, ValueType, WasmExternType, WasmTypeList, WASM_MAX_PAGES,
|
||||||
|
WASM_MIN_PAGES, WASM_PAGE_SIZE,
|
||||||
|
};
|
||||||
#[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};
|
||||||
|
|||||||
@@ -81,12 +81,32 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Marker trait to make Rust happy: required to allow `NativeFunc<i32>` work.
|
||||||
|
/// without this trait, the singleton case looks like a generic impl in the macro
|
||||||
|
/// expansion and Rust will not compile this code because it's a potential duplicate
|
||||||
|
/// with all the existing tuples for which this is also being implemented.
|
||||||
|
pub unsafe trait WasmExternTypeInner: Copy + WasmExternType
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unsafe impl WasmExternTypeInner for i8 {}
|
||||||
|
unsafe impl WasmExternTypeInner for u8 {}
|
||||||
|
unsafe impl WasmExternTypeInner for i16 {}
|
||||||
|
unsafe impl WasmExternTypeInner for u16 {}
|
||||||
|
unsafe impl WasmExternTypeInner for i32 {}
|
||||||
|
unsafe impl WasmExternTypeInner for u32 {}
|
||||||
|
unsafe impl WasmExternTypeInner for i64 {}
|
||||||
|
unsafe impl WasmExternTypeInner for u64 {}
|
||||||
|
unsafe impl WasmExternTypeInner for f32 {}
|
||||||
|
unsafe impl WasmExternTypeInner for f64 {}
|
||||||
|
|
||||||
macro_rules! impl_native_traits {
|
macro_rules! impl_native_traits {
|
||||||
( $( $x:ident ),* ) => {
|
( $( $x:ident ),* ) => {
|
||||||
#[allow(unused_parens, non_snake_case)]
|
#[allow(unused_parens, non_snake_case)]
|
||||||
impl<'a $( , $x )*, Rets> NativeFunc<'a, ( $( $x, )* ), Rets>
|
impl<'a $( , $x )*, Rets> NativeFunc<'a, ( $( $x ),* ), Rets>
|
||||||
where
|
where
|
||||||
$( $x: WasmExternType, )*
|
$( $x: WasmExternType + WasmExternTypeInner, )*
|
||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
/// Call the typed func and return results.
|
/// Call the typed func and return results.
|
||||||
|
|||||||
4
lib/emscripten/src/env/mod.rs
vendored
4
lib/emscripten/src/env/mod.rs
vendored
@@ -54,8 +54,8 @@ pub fn call_memset(ctx: &mut EmEnv, pointer: u32, value: u32, size: u32) -> u32
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_emscripten_data<'a, 'b>(ctx: &'a mut EmEnv<'b>) -> &'a mut EmscriptenData<'b> {
|
pub(crate) fn get_emscripten_data<'a>(ctx: &'a mut EmEnv) -> &'a mut EmscriptenData<'static> {
|
||||||
ctx.data
|
unsafe { &mut *ctx.data }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _getpagesize(_ctx: &mut EmEnv) -> u32 {
|
pub fn _getpagesize(_ctx: &mut EmEnv) -> u32 {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*#![deny(
|
#![deny(
|
||||||
dead_code,
|
dead_code,
|
||||||
nonstandard_style,
|
nonstandard_style,
|
||||||
unused_imports,
|
unused_imports,
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
unused_unsafe,
|
unused_unsafe,
|
||||||
unreachable_patterns
|
unreachable_patterns
|
||||||
)]
|
)]
|
||||||
*/
|
|
||||||
#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
|
#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")]
|
||||||
#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
|
#![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")]
|
||||||
|
|
||||||
@@ -20,9 +19,9 @@ 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, AnyRef, Exportable, Function, FunctionType, Global, ImportObject, ImportType,
|
imports, namespace, AnyRef, Exports, Function, FunctionType, Global, ImportObject, Instance,
|
||||||
Instance, Memory, MemoryType, Module, NativeFunc, Pages, RuntimeError, Store, Table, TableType,
|
Memory, MemoryType, Module, NativeFunc, Pages, RuntimeError, Store, Table, TableType, Val,
|
||||||
Val, ValType,
|
ValType,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@@ -70,14 +69,17 @@ pub use self::utils::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// The environment provided to the Emscripten imports.
|
/// The environment provided to the Emscripten imports.
|
||||||
pub struct EmEnv<'a> {
|
pub struct EmEnv {
|
||||||
memory: Memory,
|
memory: Memory,
|
||||||
data: &'a mut EmscriptenData<'a>,
|
data: *mut EmscriptenData<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EmEnv<'a> {
|
impl EmEnv {
|
||||||
pub fn new(memory: Memory, data: &'a mut EmscriptenData<'a>) -> Self {
|
pub fn new(memory: Memory, data: *mut c_void) -> Self {
|
||||||
Self { memory, data }
|
Self {
|
||||||
|
memory,
|
||||||
|
data: data as *mut _,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the memory
|
/// Get a reference to the memory
|
||||||
@@ -193,22 +195,22 @@ impl<'a> EmscriptenData<'a> {
|
|||||||
let malloc = instance
|
let malloc = instance
|
||||||
.exports
|
.exports
|
||||||
.get_native_function("_malloc")
|
.get_native_function("_malloc")
|
||||||
.or_else(|_| instance.exports.get_native_function("malloc"))
|
.or(instance.exports.get_native_function("malloc"))
|
||||||
.ok();
|
.ok();
|
||||||
let free = instance
|
let free = instance
|
||||||
.exports
|
.exports
|
||||||
.get_native_function("_free")
|
.get_native_function("_free")
|
||||||
.or_else(|_| instance.exports.get_native_function("free"))
|
.or(instance.exports.get_native_function("free"))
|
||||||
.ok();
|
.ok();
|
||||||
let memalign = instance
|
let memalign = instance
|
||||||
.exports
|
.exports
|
||||||
.get_native_function("_memalign")
|
.get_native_function("_memalign")
|
||||||
.or_else(|_| instance.exports.get_native_function("memalign"))
|
.or(instance.exports.get_native_function("memalign"))
|
||||||
.ok();
|
.ok();
|
||||||
let memset = instance
|
let memset = instance
|
||||||
.exports
|
.exports
|
||||||
.get_native_function("_memset")
|
.get_native_function("_memset")
|
||||||
.or_else(|_| instance.exports.get_native_function("memset"))
|
.or(instance.exports.get_native_function("memset"))
|
||||||
.ok();
|
.ok();
|
||||||
let stack_alloc = instance.exports.get_native_function("stackAlloc").ok();
|
let stack_alloc = instance.exports.get_native_function("stackAlloc").ok();
|
||||||
|
|
||||||
@@ -305,7 +307,7 @@ impl<'a> EmscriptenData<'a> {
|
|||||||
let set_threw = instance
|
let set_threw = instance
|
||||||
.exports
|
.exports
|
||||||
.get_native_function("_setThrew")
|
.get_native_function("_setThrew")
|
||||||
.or_else(|_| instance.exports.get_native_function("setThrew"))
|
.or(instance.exports.get_native_function("setThrew"))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
EmscriptenData {
|
EmscriptenData {
|
||||||
@@ -420,18 +422,25 @@ pub fn emscripten_call_main(
|
|||||||
Ok(func) => Ok(("main", func)),
|
Ok(func) => Ok(("main", func)),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
},
|
},
|
||||||
}?;
|
}
|
||||||
|
.map_err(|e| RuntimeError::new(e.to_string()))?;
|
||||||
let num_params = main_func.ty().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(env, 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)
|
||||||
|
.map_err(|e| RuntimeError::new(e.to_string()))?;
|
||||||
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)
|
||||||
|
.map_err(|e| RuntimeError::new(e.to_string()))?;
|
||||||
func.call(&[])?;
|
func.call(&[])?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -456,8 +465,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 mut env = EmEnv::new(globals.memory, &mut data);
|
let mut env = EmEnv::new(globals.memory.clone(), &mut data as *mut _ as *mut c_void);
|
||||||
|
|
||||||
set_up_emscripten(instance)?;
|
set_up_emscripten(instance)?;
|
||||||
|
|
||||||
// println!("running emscripten instance");
|
// println!("running emscripten instance");
|
||||||
@@ -466,7 +474,10 @@ pub fn run_emscripten_instance(
|
|||||||
debug!("Running entry point: {}", &ep);
|
debug!("Running entry point: {}", &ep);
|
||||||
let arg = unsafe { allocate_cstr_on_stack(&mut env, 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)
|
||||||
|
.map_err(|e| RuntimeError::new(e.to_string()))?;
|
||||||
func.call(&[Val::I32(arg as i32)])?;
|
func.call(&[Val::I32(arg as i32)])?;
|
||||||
} else {
|
} else {
|
||||||
emscripten_call_main(instance, &mut env, path, &args)?;
|
emscripten_call_main(instance, &mut env, path, &args)?;
|
||||||
@@ -540,9 +551,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 ImportType { module, name, ty } in module.imports().functions() {
|
for import in module.imports().functions() {
|
||||||
if name == "abortOnCannotGrowMemory" && module == "env" {
|
if import.name() == "abortOnCannotGrowMemory" && import.module() == "env" {
|
||||||
if ty == *OLD_ABORT_ON_CANNOT_GROW_MEMORY_SIG {
|
if import.ty() == &*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;
|
||||||
@@ -603,9 +614,9 @@ 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 ImportType { module, name, .. } in module.imports().functions() {
|
for import in module.imports().functions() {
|
||||||
if module == "env" && name.starts_with("nullFunction_") {
|
if import.module() == "env" && import.name().starts_with("nullFunction_") {
|
||||||
null_func_names.push(name.to_string())
|
null_func_names.push(import.name().to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,27 +637,27 @@ pub fn generate_emscripten_env(
|
|||||||
env: &mut EmEnv,
|
env: &mut EmEnv,
|
||||||
) -> ImportObject {
|
) -> ImportObject {
|
||||||
let abort_on_cannot_grow_memory_export = if globals.data.use_old_abort_on_cannot_grow_memory {
|
let abort_on_cannot_grow_memory_export = if globals.data.use_old_abort_on_cannot_grow_memory {
|
||||||
Function::new_env(store, env, crate::memory::abort_on_cannot_grow_memory_old).to_export()
|
Function::new_env(store, env, crate::memory::abort_on_cannot_grow_memory_old)
|
||||||
} else {
|
} else {
|
||||||
Function::new_env(store, env, crate::memory::abort_on_cannot_grow_memory).to_export()
|
Function::new_env(store, env, crate::memory::abort_on_cannot_grow_memory)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut env_ns = namespace! {
|
let mut env_ns: Exports = namespace! {
|
||||||
"memory" => Export::Memory(globals.memory.clone()),
|
//"memory" => globals.memory.clone(),
|
||||||
"table" => Export::Table(globals.table.clone()),
|
//"table" => globals.table.clone(),
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
"STACKTOP" => Global::new(Value::I32(globals.data.stacktop as i32)),
|
"STACKTOP" => Global::new(store, Val::I32(globals.data.stacktop as i32)),
|
||||||
"STACK_MAX" => Global::new(Value::I32(globals.data.stack_max as i32)),
|
"STACK_MAX" => Global::new(store, Val::I32(globals.data.stack_max as i32)),
|
||||||
"DYNAMICTOP_PTR" => Global::new(Value::I32(globals.data.dynamictop_ptr as i32)),
|
"DYNAMICTOP_PTR" => Global::new(store, Val::I32(globals.data.dynamictop_ptr as i32)),
|
||||||
"fb" => Global::new(Value::I32(globals.data.table_base as i32)),
|
"fb" => Global::new(store, Val::I32(globals.data.table_base as i32)),
|
||||||
"tableBase" => Global::new(Value::I32(globals.data.table_base as i32)),
|
"tableBase" => Global::new(store, Val::I32(globals.data.table_base as i32)),
|
||||||
"__table_base" => Global::new(Value::I32(globals.data.table_base as i32)),
|
"__table_base" => Global::new(store, Val::I32(globals.data.table_base as i32)),
|
||||||
"ABORT" => Global::new(Value::I32(globals.data.abort as i32)),
|
"ABORT" => Global::new(store, Val::I32(globals.data.abort as i32)),
|
||||||
"gb" => Global::new(Value::I32(globals.data.memory_base as i32)),
|
"gb" => Global::new(store, Val::I32(globals.data.memory_base as i32)),
|
||||||
"memoryBase" => Global::new(Value::I32(globals.data.memory_base as i32)),
|
"memoryBase" => Global::new(store, Val::I32(globals.data.memory_base as i32)),
|
||||||
"__memory_base" => Global::new(Value::I32(globals.data.memory_base as i32)),
|
"__memory_base" => Global::new(store, Val::I32(globals.data.memory_base as i32)),
|
||||||
"tempDoublePtr" => Global::new(Value::I32(globals.data.temp_double_ptr as i32)),
|
"tempDoublePtr" => Global::new(store, Val::I32(globals.data.temp_double_ptr as i32)),
|
||||||
|
|
||||||
// inet
|
// inet
|
||||||
"_inet_addr" => Function::new_env(store, env, crate::inet::addr),
|
"_inet_addr" => Function::new_env(store, env, crate::inet::addr),
|
||||||
@@ -901,48 +912,50 @@ pub fn generate_emscripten_env(
|
|||||||
"_gmtime" => Function::new_env(store, env, crate::time::_gmtime),
|
"_gmtime" => Function::new_env(store, env, crate::time::_gmtime),
|
||||||
|
|
||||||
// Math
|
// Math
|
||||||
"sqrt" => Function::new_env(store, env, crate::math::sqrt),
|
"sqrt" => Function::new(store, crate::math::sqrt),
|
||||||
"floor" => Function::new_env(store, env, crate::math::floor),
|
"floor" => Function::new(store, crate::math::floor),
|
||||||
"fabs" => Function::new_env(store, env, crate::math::fabs),
|
"fabs" => Function::new(store, crate::math::fabs),
|
||||||
"f64-rem" => Function::new_env(store, env, crate::math::f64_rem),
|
"f64-rem" => Function::new(store, crate::math::f64_rem),
|
||||||
"_llvm_copysign_f32" => Function::new_env(store, env, crate::math::_llvm_copysign_f32),
|
"_llvm_copysign_f32" => Function::new(store, crate::math::_llvm_copysign_f32),
|
||||||
"_llvm_copysign_f64" => Function::new_env(store, env, crate::math::_llvm_copysign_f64),
|
"_llvm_copysign_f64" => Function::new(store, crate::math::_llvm_copysign_f64),
|
||||||
"_llvm_log10_f64" => Function::new_env(store, env, crate::math::_llvm_log10_f64),
|
"_llvm_log10_f64" => Function::new(store, crate::math::_llvm_log10_f64),
|
||||||
"_llvm_log2_f64" => Function::new_env(store, env, crate::math::_llvm_log2_f64),
|
"_llvm_log2_f64" => Function::new(store, crate::math::_llvm_log2_f64),
|
||||||
"_llvm_log10_f32" => Function::new_env(store, env, crate::math::_llvm_log10_f32),
|
"_llvm_log10_f32" => Function::new(store, crate::math::_llvm_log10_f32),
|
||||||
"_llvm_log2_f32" => Function::new_env(store, env, crate::math::_llvm_log2_f64),
|
"_llvm_log2_f32" => Function::new(store, crate::math::_llvm_log2_f64),
|
||||||
"_llvm_sin_f64" => Function::new_env(store, env, crate::math::_llvm_sin_f64),
|
"_llvm_sin_f64" => Function::new(store, crate::math::_llvm_sin_f64),
|
||||||
"_llvm_cos_f64" => Function::new_env(store, env, crate::math::_llvm_cos_f64),
|
"_llvm_cos_f64" => Function::new(store, crate::math::_llvm_cos_f64),
|
||||||
"_llvm_exp2_f32" => Function::new_env(store, env, crate::math::_llvm_exp2_f32),
|
"_llvm_exp2_f32" => Function::new(store, crate::math::_llvm_exp2_f32),
|
||||||
"_llvm_exp2_f64" => Function::new_env(store, env, crate::math::_llvm_exp2_f64),
|
"_llvm_exp2_f64" => Function::new(store, crate::math::_llvm_exp2_f64),
|
||||||
"_llvm_trunc_f64" => Function::new_env(store, env, crate::math::_llvm_trunc_f64),
|
"_llvm_trunc_f64" => Function::new(store, crate::math::_llvm_trunc_f64),
|
||||||
"_llvm_fma_f64" => Function::new_env(store, env, crate::math::_llvm_fma_f64),
|
"_llvm_fma_f64" => Function::new(store, crate::math::_llvm_fma_f64),
|
||||||
"_emscripten_random" => Function::new_env(store, env, crate::math::_emscripten_random),
|
"_emscripten_random" => Function::new_env(store, env, crate::math::_emscripten_random),
|
||||||
|
|
||||||
// Jump
|
// Jump
|
||||||
"__setjmp" => Function::new_env(store, env, crate::jmp::__setjmp),
|
"__setjmp" => Function::new_env(store, env, crate::jmp::__setjmp),
|
||||||
"__longjmp" => Function::new_env(store, env, crate::jmp::__longjmp),
|
// TODO: reenable these. they're using `()` as trap return value, probably need
|
||||||
"_longjmp" => Function::new_env(store, env, crate::jmp::_longjmp),
|
// to use soemthing else that impls Error
|
||||||
"_emscripten_longjmp" => Function::new_env(store, env, crate::jmp::_longjmp),
|
//"__longjmp" => Function::new_env(store, env, crate::jmp::__longjmp),
|
||||||
|
//"_longjmp" => Function::new_env(store, env, crate::jmp::_longjmp),
|
||||||
|
//"_emscripten_longjmp" => Function::new_env(store, env, crate::jmp::_longjmp),
|
||||||
|
|
||||||
// Bitwise
|
// Bitwise
|
||||||
"_llvm_bswap_i64" => Function::new_env(store, env, crate::bitwise::_llvm_bswap_i64),
|
"_llvm_bswap_i64" => Function::new_env(store, env, crate::bitwise::_llvm_bswap_i64),
|
||||||
|
|
||||||
// libc
|
// libc
|
||||||
"_execv" => Function::new_env(store, env, crate::libc::execv),
|
"_execv" => Function::new(store, crate::libc::execv),
|
||||||
"_endpwent" => Function::new_env(store, env, crate::libc::endpwent),
|
"_endpwent" => Function::new(store, crate::libc::endpwent),
|
||||||
"_fexecve" => Function::new_env(store, env, crate::libc::fexecve),
|
"_fexecve" => Function::new(store, crate::libc::fexecve),
|
||||||
"_fpathconf" => Function::new_env(store, env, crate::libc::fpathconf),
|
"_fpathconf" => Function::new(store, crate::libc::fpathconf),
|
||||||
"_getitimer" => Function::new_env(store, env, crate::libc::getitimer),
|
"_getitimer" => Function::new(store, crate::libc::getitimer),
|
||||||
"_getpwent" => Function::new_env(store, env, crate::libc::getpwent),
|
"_getpwent" => Function::new(store, crate::libc::getpwent),
|
||||||
"_killpg" => Function::new_env(store, env, crate::libc::killpg),
|
"_killpg" => Function::new(store, crate::libc::killpg),
|
||||||
"_pathconf" => Function::new_env(store, env, crate::libc::pathconf),
|
"_pathconf" => Function::new_env(store, env, crate::libc::pathconf),
|
||||||
"_siginterrupt" => Function::new_env(store, env, crate::signal::_siginterrupt),
|
"_siginterrupt" => Function::new_env(store, env, crate::signal::_siginterrupt),
|
||||||
"_setpwent" => Function::new_env(store, env, crate::libc::setpwent),
|
"_setpwent" => Function::new(store, crate::libc::setpwent),
|
||||||
"_sigismember" => Function::new_env(store, env, crate::libc::sigismember),
|
"_sigismember" => Function::new(store, crate::libc::sigismember),
|
||||||
"_sigpending" => Function::new_env(store, env, crate::libc::sigpending),
|
"_sigpending" => Function::new(store, crate::libc::sigpending),
|
||||||
"___libc_current_sigrtmax" => Function::new_env(store, env, crate::libc::current_sigrtmax),
|
"___libc_current_sigrtmax" => Function::new(store, crate::libc::current_sigrtmax),
|
||||||
"___libc_current_sigrtmin" => Function::new_env(store, env, crate::libc::current_sigrtmin),
|
"___libc_current_sigrtmin" => Function::new(store, crate::libc::current_sigrtmin),
|
||||||
|
|
||||||
// Linking
|
// Linking
|
||||||
"_dlclose" => Function::new_env(store, env, crate::linking::_dlclose),
|
"_dlclose" => Function::new_env(store, env, crate::linking::_dlclose),
|
||||||
@@ -1073,19 +1086,24 @@ pub fn generate_emscripten_env(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Compatibility with newer versions of Emscripten
|
// Compatibility with newer versions of Emscripten
|
||||||
for (k, v) in env_ns.get_exports() {
|
let mut to_insert: Vec<(String, _)> = vec![];
|
||||||
|
for (k, v) in env_ns.iter() {
|
||||||
if k.starts_with("_") {
|
if k.starts_with("_") {
|
||||||
let k = &k[1..];
|
let k = &k[1..];
|
||||||
if !env_ns.contains_key(k) {
|
if !env_ns.contains(k) {
|
||||||
env_ns.insert(k, v.to_export());
|
to_insert.push((k.to_string(), v.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (k, v) in to_insert {
|
||||||
|
env_ns.insert(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
for null_func_name in globals.null_func_names.iter() {
|
for null_func_name in globals.null_func_names.iter() {
|
||||||
env_ns.insert(
|
env_ns.insert(
|
||||||
null_func_name.as_str(),
|
null_func_name.as_str(),
|
||||||
Function::new_env(store, env, nullfunc).to_export(),
|
Function::new_env(store, env, nullfunc),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,17 @@ pub fn _emscripten_resize_heap(ctx: &mut EmEnv, requested_size: u32) -> u32 {
|
|||||||
let current_memory = current_memory_pages.bytes().0 as u32;
|
let current_memory = current_memory_pages.bytes().0 as u32;
|
||||||
|
|
||||||
// implementation from emscripten
|
// implementation from emscripten
|
||||||
let mut new_size = usize::max(current_memory as usize, WASM_MIN_PAGES * WASM_PAGE_SIZE);
|
let mut new_size = usize::max(
|
||||||
|
current_memory as usize,
|
||||||
|
WASM_MIN_PAGES as usize * WASM_PAGE_SIZE,
|
||||||
|
);
|
||||||
while new_size < requested_size as usize {
|
while new_size < requested_size as usize {
|
||||||
if new_size <= 0x2000_0000 {
|
if new_size <= 0x2000_0000 {
|
||||||
new_size = align_up(new_size * 2, WASM_PAGE_SIZE);
|
new_size = align_up(new_size * 2, WASM_PAGE_SIZE);
|
||||||
} else {
|
} else {
|
||||||
new_size = usize::min(
|
new_size = usize::min(
|
||||||
align_up((3 * new_size + 0x8000_0000) / 4, WASM_PAGE_SIZE),
|
align_up((3 * new_size + 0x8000_0000) / 4, WASM_PAGE_SIZE),
|
||||||
WASM_PAGE_SIZE * WASM_MAX_PAGES,
|
WASM_PAGE_SIZE * WASM_MAX_PAGES as usize,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ 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::{GlobalInit, ImportType, Memory, Module, Pages};
|
use wasmer::{GlobalInit, Memory, Module, Pages};
|
||||||
|
|
||||||
/// 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 ImportType { module, name, .. } in module.imports().functions() {
|
for import in module.imports().functions() {
|
||||||
|
let name = import.name();
|
||||||
|
let module = import.module();
|
||||||
if (name == "_emscripten_memcpy_big"
|
if (name == "_emscripten_memcpy_big"
|
||||||
|| name == "emscripten_memcpy_big"
|
|| name == "emscripten_memcpy_big"
|
||||||
|| name == "__map_file")
|
|| name == "__map_file")
|
||||||
@@ -25,7 +27,8 @@ 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 let Some(ImportType { ty, .. }) = module.imports().tables().next() {
|
if let Some(import) = module.imports().tables().next() {
|
||||||
|
let ty = import.ty();
|
||||||
Ok((ty.minimum, ty.maximum))
|
Ok((ty.minimum, ty.maximum))
|
||||||
} else {
|
} else {
|
||||||
return Err("Emscripten requires at least one imported table".to_string());
|
return Err("Emscripten requires at least one imported table".to_string());
|
||||||
@@ -33,7 +36,8 @@ pub fn get_emscripten_table_size(module: &Module) -> Result<(u32, Option<u32>),
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 let Some(ImportType { ty, .. }) = module.imports().memories().next() {
|
if let Some(import) = module.imports().memories().next() {
|
||||||
|
let ty = import.ty();
|
||||||
Ok((ty.minimum, ty.maximum, ty.shared))
|
Ok((ty.minimum, ty.maximum, ty.shared))
|
||||||
} else {
|
} else {
|
||||||
return Err("Emscripten requires at least one imported memory".to_string());
|
return Err("Emscripten requires at least one imported memory".to_string());
|
||||||
|
|||||||
Reference in New Issue
Block a user