diff --git a/lib/emscripten/src/env.rs b/lib/emscripten/src/env.rs index df1c624eb..d686ddcce 100644 --- a/lib/emscripten/src/env.rs +++ b/lib/emscripten/src/env.rs @@ -39,7 +39,7 @@ pub extern "C" fn _getenv(name: c_int, vmctx: &mut Ctx) -> u32 { } /// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int); -pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, vmctx: &mut Ctx) { +pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, vmctx: &mut Ctx) -> c_int { debug!("emscripten::_setenv"); let name_addr = vmctx.memory(0)[name as usize] as *const c_char; @@ -48,29 +48,29 @@ pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, vmctx: &m debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) }); - unsafe { setenv(name_addr, value_addr, overwrite) }; + unsafe { setenv(name_addr, value_addr, overwrite) } } /// emscripten: _putenv // (name: *const char); -pub extern "C" fn _putenv(name: c_int, vmctx: &mut Ctx) { +pub extern "C" fn _putenv(name: c_int, vmctx: &mut Ctx) -> c_int { debug!("emscripten::_putenv"); let name_addr = vmctx.memory(0)[name as usize] as *const c_char; debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); - unsafe { putenv(name_addr as _) }; + unsafe { putenv(name_addr as _) } } /// emscripten: _unsetenv // (name: *const char); -pub extern "C" fn _unsetenv(name: c_int, vmctx: &mut Ctx) { +pub extern "C" fn _unsetenv(name: c_int, vmctx: &mut Ctx) -> c_int { debug!("emscripten::_unsetenv"); let name_addr = vmctx.memory(0)[name as usize] as *const c_char; debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); - unsafe { unsetenv(name_addr) }; + unsafe { unsetenv(name_addr) } } #[allow(clippy::cast_ptr_alignment)] @@ -221,3 +221,9 @@ pub extern "C" fn _sysconf(name: c_int, _vmctx: &mut Ctx) -> c_long { // TODO: Implement like emscripten expects regarding memory/page size unsafe { sysconf(name) } } + +pub extern "C" fn ___assert_fail(a: c_int, b: c_int, c: c_int, d: c_int, _vmctx: &mut Ctx) { + debug!("emscripten::___assert_fail {} {} {} {}", a, b, c, d); + // TODO: Implement like emscripten expects regarding memory/page size + unimplemented!() +} diff --git a/lib/emscripten/src/errno.rs b/lib/emscripten/src/errno.rs index 9787ea85b..9c2bb309e 100644 --- a/lib/emscripten/src/errno.rs +++ b/lib/emscripten/src/errno.rs @@ -1,10 +1,10 @@ // use std::collections::HashMap; -pub extern "C" fn ___seterrno(value: i32) -> i32 { +pub extern "C" fn ___seterrno(value: i32) { debug!("emscripten::___seterrno {}", value); // TODO: Incomplete impl eprintln!("failed to set errno!"); - value + // value } // pub enum ErrnoCodes { diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 9ffd8676d..f0b019479 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -160,6 +160,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { let mut env_namespace = Namespace::new(); let mut asm_namespace = Namespace::new(); let mut global_namespace = Namespace::new(); + let mut global_math_namespace = Namespace::new(); // Add globals. // NOTE: There is really no need for checks, these globals should always be available. @@ -238,6 +239,19 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { }, ); + // Global Math + global_math_namespace.insert( + "pow", + Export::Function { + func: func!(math, pow), + ctx: Context::Internal, + signature: FuncSig { + params: vec![F64, F64], + returns: vec![F64], + }, + }, + ); + // Print function env_namespace.insert( "printf", @@ -263,6 +277,19 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { }, ); + // Assert + env_namespace.insert( + "___assert_fail", + Export::Function { + func: func!(env, ___assert_fail), + ctx: Context::Internal, + signature: FuncSig { + params: vec![I32, I32, I32, I32], + returns: vec![], + }, + }, + ); + // Lock env_namespace.insert( "___lock", @@ -270,7 +297,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { func: func!(lock, ___lock), ctx: Context::Internal, signature: FuncSig { - params: vec![I32, I32], + params: vec![I32], returns: vec![], }, }, @@ -282,7 +309,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { func: func!(lock, ___unlock), ctx: Context::Internal, signature: FuncSig { - params: vec![I32, I32], + params: vec![I32], returns: vec![], }, }, @@ -319,7 +346,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { ctx: Context::Internal, signature: FuncSig { params: vec![I32, I32, I32], - returns: vec![], + returns: vec![I32], }, }, ); @@ -331,7 +358,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { ctx: Context::Internal, signature: FuncSig { params: vec![I32], - returns: vec![], + returns: vec![I32], }, }, ); @@ -343,7 +370,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { ctx: Context::Internal, signature: FuncSig { params: vec![I32], - returns: vec![], + returns: vec![I32], }, }, ); @@ -391,7 +418,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { ctx: Context::Internal, signature: FuncSig { params: vec![I32], - returns: vec![I32], + returns: vec![], }, }, ); @@ -798,7 +825,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { func: func!(process, abort_stack_overflow), ctx: Context::Internal, signature: FuncSig { - params: vec![], + params: vec![I32], returns: vec![], }, }, @@ -931,7 +958,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { ctx: Context::Internal, signature: FuncSig { params: vec![], - returns: vec![], + returns: vec![I32], }, }, ); @@ -955,7 +982,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { ctx: Context::Internal, signature: FuncSig { params: vec![], - returns: vec![], + returns: vec![I32], }, }, ); @@ -1020,6 +1047,18 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { }, ); // NullFuncs + env_namespace.insert( + "nullFunc_i", + Export::Function { + func: func!(nullfunc, nullfunc_i), + ctx: Context::Internal, + signature: FuncSig { + params: vec![I32], + returns: vec![], + }, + }, + ); + env_namespace.insert( "nullFunc_ii", Export::Function { @@ -1450,7 +1489,7 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { // mock_external!(env_namespace, ___syscall146); // mock_external!(env_namespace, ___syscall145); // mock_external!(env_namespace, ___syscall142); - mock_external!(env_namespace, ___syscall140); + // mock_external!(env_namespace, ___syscall140); // mock_external!(env_namespace, ___syscall122); // mock_external!(env_namespace, ___syscall102); // mock_external!(env_namespace, ___syscall20); @@ -1463,6 +1502,8 @@ pub fn generate_emscripten_env(globals: &EmscriptenGlobals) -> ImportObject { imports.register("env", env_namespace); imports.register("asm2wasm", asm_namespace); + imports.register("global", global_namespace); + imports.register("global.Math", global_math_namespace); imports } diff --git a/lib/emscripten/src/lock.rs b/lib/emscripten/src/lock.rs index 17073b591..355fed803 100644 --- a/lib/emscripten/src/lock.rs +++ b/lib/emscripten/src/lock.rs @@ -2,13 +2,13 @@ use libc::c_int; use wasmer_runtime_core::vm::Ctx; // NOTE: Not implemented by Emscripten -pub extern "C" fn ___lock(which: c_int, varargs: c_int, _vmctx: &mut Ctx) { - debug!("emscripten::___lock {}, {}", which, varargs); +pub extern "C" fn ___lock(what: c_int, _vmctx: &mut Ctx) { + debug!("emscripten::___lock {}", what); } // NOTE: Not implemented by Emscripten -pub extern "C" fn ___unlock(which: c_int, varargs: c_int, _vmctx: &mut Ctx) { - debug!("emscripten::___unlock {}, {}", which, varargs); +pub extern "C" fn ___unlock(what: c_int, _vmctx: &mut Ctx) { + debug!("emscripten::___unlock {}", what); } // NOTE: Not implemented by Emscripten diff --git a/lib/emscripten/src/math.rs b/lib/emscripten/src/math.rs index c39f3028c..367807dbb 100644 --- a/lib/emscripten/src/math.rs +++ b/lib/emscripten/src/math.rs @@ -15,3 +15,8 @@ pub extern "C" fn f64_rem(x: f64, y: f64) -> f64 { debug!("emscripten::f64-rem"); x % y } + +// emscripten: global.Math pow +pub extern "C" fn pow(x: f64, y: f64) -> f64 { + x.powf(y) +} diff --git a/lib/emscripten/src/memory.rs b/lib/emscripten/src/memory.rs index 7e48e0144..0789de870 100644 --- a/lib/emscripten/src/memory.rs +++ b/lib/emscripten/src/memory.rs @@ -25,16 +25,18 @@ pub extern "C" fn get_total_memory(_vmctx: &mut Ctx) -> u32 { } /// emscripten: enlargeMemory -pub extern "C" fn enlarge_memory(_vmctx: &mut Ctx) { +pub extern "C" fn enlarge_memory(_vmctx: &mut Ctx) -> u32 { debug!("emscripten::enlarge_memory"); // instance.memories[0].grow(100); // TODO: Fix implementation + 0 } /// emscripten: abortOnCannotGrowMemory -pub extern "C" fn abort_on_cannot_grow_memory() { +pub extern "C" fn abort_on_cannot_grow_memory() -> u32 { debug!("emscripten::abort_on_cannot_grow_memory"); abort_with_message("Cannot enlarge memory arrays!"); + 0 } /// emscripten: ___map_file diff --git a/lib/emscripten/src/nullfunc.rs b/lib/emscripten/src/nullfunc.rs index 3121b094a..37530e8cd 100644 --- a/lib/emscripten/src/nullfunc.rs +++ b/lib/emscripten/src/nullfunc.rs @@ -1,6 +1,11 @@ use super::process::abort_with_message; use wasmer_runtime_core::vm::Ctx; +pub extern "C" fn nullfunc_i(x: u32, _vmctx: &mut Ctx) { + debug!("emscripten::nullfunc_i {}", x); + abort_with_message("Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); +} + pub extern "C" fn nullfunc_ii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_ii {}", x); abort_with_message("Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); diff --git a/lib/emscripten/src/process.rs b/lib/emscripten/src/process.rs index ae48bdff8..11f045a99 100644 --- a/lib/emscripten/src/process.rs +++ b/lib/emscripten/src/process.rs @@ -41,7 +41,7 @@ pub extern "C" fn em_abort(message: u32, vmctx: &mut Ctx) { } } -pub extern "C" fn abort_stack_overflow() { +pub extern "C" fn abort_stack_overflow(what: c_int) { debug!("emscripten::abort_stack_overflow"); // TODO: Message incomplete. Need to finish em runtime data first abort_with_message("Stack overflow! Attempted to allocate some bytes on the stack");