Emscripten compiles with no errors!

This commit is contained in:
Mark McCaskey
2020-06-10 17:03:44 -07:00
parent 5a6f4f12de
commit 70e25a7396
6 changed files with 138 additions and 90 deletions

View File

@@ -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};

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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),
); );
} }

View File

@@ -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,
); );
} }
} }

View File

@@ -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());