Ported Emscripten to new Context API

This commit is contained in:
ptitSeb
2022-05-31 17:23:51 +02:00
committed by Manos Pitsidianakis
parent d3d363bab2
commit cf85615e55
31 changed files with 2038 additions and 1386 deletions

1
Cargo.lock generated
View File

@@ -3018,6 +3018,7 @@ dependencies = [
"log", "log",
"time", "time",
"wasmer", "wasmer",
"wasmer-types",
] ]
[[package]] [[package]]

View File

@@ -16,7 +16,8 @@ lazy_static = "1.4"
libc = "^0.2" libc = "^0.2"
log = "0.4" log = "0.4"
time = { version = "0.2", features = ["std"] } time = { version = "0.2", features = ["std"] }
wasmer = { path = "../api", version = "=2.3.0", default-features = false, features = ["sys"] } wasmer = { path = "../api", version = "=2.3.0", default-features = false, features = ["sys", "compiler"] }
wasmer-types = { path = "../types", version = "=2.3.0" }
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
getrandom = "0.2" getrandom = "0.2"

View File

@@ -1,8 +1,9 @@
use crate::emscripten_target; use crate::emscripten_target;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
///emscripten: _llvm_bswap_i64 ///emscripten: _llvm_bswap_i64
pub fn _llvm_bswap_i64(ctx: &EmEnv, _low: i32, high: i32) -> i32 { pub fn _llvm_bswap_i64(ctx: ContextMut<'_, EmEnv>, _low: i32, high: i32) -> i32 {
debug!("emscripten::_llvm_bswap_i64"); debug!("emscripten::_llvm_bswap_i64");
emscripten_target::setTempRet0(ctx, _low.swap_bytes()); emscripten_target::setTempRet0(ctx, _low.swap_bytes());
high.swap_bytes() high.swap_bytes()

View File

@@ -1,35 +1,36 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::env::get_emscripten_data; use crate::env::{get_emscripten_data, get_emscripten_funcs};
use crate::EmEnv; use crate::EmEnv;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
use libc::getdtablesize; use libc::getdtablesize;
use wasmer::{AsContextMut, ContextMut};
pub fn asm_const_i(_ctx: &EmEnv, _val: i32) -> i32 { pub fn asm_const_i(_ctx: ContextMut<'_, EmEnv>, _val: i32) -> i32 {
debug!("emscripten::asm_const_i: {}", _val); debug!("emscripten::asm_const_i: {}", _val);
0 0
} }
pub fn exit_with_live_runtime(_ctx: &EmEnv) { pub fn exit_with_live_runtime(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::exit_with_live_runtime"); debug!("emscripten::exit_with_live_runtime");
} }
pub fn setTempRet0(ctx: &EmEnv, val: i32) { pub fn setTempRet0(ctx: ContextMut<'_, EmEnv>, val: i32) {
trace!("emscripten::setTempRet0: {}", val); trace!("emscripten::setTempRet0: {}", val);
get_emscripten_data(ctx).temp_ret_0 = val; get_emscripten_data(&ctx).temp_ret_0 = val;
} }
pub fn getTempRet0(ctx: &EmEnv) -> i32 { pub fn getTempRet0(ctx: ContextMut<'_, EmEnv>) -> i32 {
trace!("emscripten::getTempRet0"); trace!("emscripten::getTempRet0");
get_emscripten_data(ctx).temp_ret_0 get_emscripten_data(&ctx).temp_ret_0
} }
pub fn _alarm(_ctx: &EmEnv, _seconds: u32) -> i32 { pub fn _alarm(_ctx: ContextMut<'_, EmEnv>, _seconds: u32) -> i32 {
debug!("emscripten::_alarm({})", _seconds); debug!("emscripten::_alarm({})", _seconds);
0 0
} }
pub fn _atexit(_ctx: &EmEnv, _func: i32) -> i32 { pub fn _atexit(_ctx: ContextMut<'_, EmEnv>, _func: i32) -> i32 {
debug!("emscripten::_atexit"); debug!("emscripten::_atexit");
// TODO: implement atexit properly // TODO: implement atexit properly
// __ATEXIT__.unshift({ // __ATEXIT__.unshift({
@@ -38,38 +39,38 @@ pub fn _atexit(_ctx: &EmEnv, _func: i32) -> i32 {
// }); // });
0 0
} }
pub fn __Unwind_Backtrace(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn __Unwind_Backtrace(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::__Unwind_Backtrace"); debug!("emscripten::__Unwind_Backtrace");
0 0
} }
pub fn __Unwind_FindEnclosingFunction(_ctx: &EmEnv, _a: i32) -> i32 { pub fn __Unwind_FindEnclosingFunction(_ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
debug!("emscripten::__Unwind_FindEnclosingFunction"); debug!("emscripten::__Unwind_FindEnclosingFunction");
0 0
} }
pub fn __Unwind_GetIPInfo(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn __Unwind_GetIPInfo(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::__Unwind_GetIPInfo"); debug!("emscripten::__Unwind_GetIPInfo");
0 0
} }
pub fn ___cxa_find_matching_catch_2(_ctx: &EmEnv) -> i32 { pub fn ___cxa_find_matching_catch_2(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::___cxa_find_matching_catch_2"); debug!("emscripten::___cxa_find_matching_catch_2");
0 0
} }
pub fn ___cxa_find_matching_catch_3(_ctx: &EmEnv, _a: i32) -> i32 { pub fn ___cxa_find_matching_catch_3(_ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
debug!("emscripten::___cxa_find_matching_catch_3"); debug!("emscripten::___cxa_find_matching_catch_3");
0 0
} }
pub fn ___cxa_free_exception(_ctx: &EmEnv, _a: i32) { pub fn ___cxa_free_exception(_ctx: ContextMut<'_, EmEnv>, _a: i32) {
debug!("emscripten::___cxa_free_exception"); debug!("emscripten::___cxa_free_exception");
} }
pub fn ___resumeException(_ctx: &EmEnv, _a: i32) { pub fn ___resumeException(_ctx: ContextMut<'_, EmEnv>, _a: i32) {
debug!("emscripten::___resumeException"); debug!("emscripten::___resumeException");
} }
pub fn _dladdr(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _dladdr(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::_dladdr"); debug!("emscripten::_dladdr");
0 0
} }
pub fn ___gxx_personality_v0( pub fn ___gxx_personality_v0(
_ctx: &EmEnv, _ctx: ContextMut<'_, EmEnv>,
_a: i32, _a: i32,
_b: i32, _b: i32,
_c: i32, _c: i32,
@@ -82,25 +83,25 @@ pub fn ___gxx_personality_v0(
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub fn _getdtablesize(_ctx: &EmEnv) -> i32 { pub fn _getdtablesize(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::getdtablesize"); debug!("emscripten::getdtablesize");
unsafe { getdtablesize() } unsafe { getdtablesize() }
} }
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
pub fn _getdtablesize(_ctx: &EmEnv) -> i32 { pub fn _getdtablesize(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::getdtablesize"); debug!("emscripten::getdtablesize");
-1 -1
} }
pub fn _gethostbyaddr(_ctx: &EmEnv, _addr: i32, _addrlen: i32, _atype: i32) -> i32 { pub fn _gethostbyaddr(_ctx: ContextMut<'_, EmEnv>, _addr: i32, _addrlen: i32, _atype: i32) -> i32 {
debug!("emscripten::gethostbyaddr"); debug!("emscripten::gethostbyaddr");
0 0
} }
pub fn _gethostbyname(_ctx: &EmEnv, _name: i32) -> i32 { pub fn _gethostbyname(_ctx: ContextMut<'_, EmEnv>, _name: i32) -> i32 {
debug!("emscripten::gethostbyname_r"); debug!("emscripten::gethostbyname_r");
0 0
} }
pub fn _gethostbyname_r( pub fn _gethostbyname_r(
_ctx: &EmEnv, _ctx: ContextMut<'_, EmEnv>,
_name: i32, _name: i32,
_ret: i32, _ret: i32,
_buf: i32, _buf: i32,
@@ -112,13 +113,13 @@ pub fn _gethostbyname_r(
0 0
} }
// NOTE: php.js has proper impl; libc has proper impl for linux // NOTE: php.js has proper impl; libc has proper impl for linux
pub fn _getloadavg(_ctx: &EmEnv, _loadavg: i32, _nelem: i32) -> i32 { pub fn _getloadavg(_ctx: ContextMut<'_, EmEnv>, _loadavg: i32, _nelem: i32) -> i32 {
debug!("emscripten::getloadavg"); debug!("emscripten::getloadavg");
0 0
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn _getnameinfo( pub fn _getnameinfo(
_ctx: &EmEnv, _ctx: ContextMut<'_, EmEnv>,
_addr: i32, _addr: i32,
_addrlen: i32, _addrlen: i32,
_host: i32, _host: i32,
@@ -140,15 +141,18 @@ pub fn _getnameinfo(
// Macro definitions // Macro definitions
macro_rules! invoke { macro_rules! invoke {
($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{ ($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{
let sp = get_emscripten_data($ctx).stack_save_ref().expect("stack_save is None").call().expect("stack_save call failed"); let funcs = get_emscripten_funcs(&$ctx).clone();
let call = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone(); let sp = funcs.stack_save_ref().expect("stack_save is None").call(&mut $ctx.as_context_mut()).expect("stack_save call failed");
match call.call($($arg),*) { let call = funcs.$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone();
match call.call(&mut $ctx, $($arg),*) {
Ok(v) => v, Ok(v) => v,
Err(_e) => { Err(_e) => {
get_emscripten_data($ctx).stack_restore_ref().expect("stack_restore is None").call(sp).expect("stack_restore call failed"); let stack = funcs.stack_restore_ref().expect("stack_restore is None");
stack.call(&mut $ctx, sp).expect("stack_restore call failed");
// TODO: We should check if _e != "longjmp" and if that's the case, re-throw the error // TODO: We should check if _e != "longjmp" and if that's the case, re-throw the error
// JS version is: if (e !== e+0 && e !== 'longjmp') throw e; // JS version is: if (e !== e+0 && e !== 'longjmp') throw e;
get_emscripten_data($ctx).set_threw_ref().expect("set_threw is None").call(1, 0).expect("set_threw call failed"); let threw = funcs.set_threw_ref().expect("set_threw is None");
threw.call(&mut $ctx, 1, 0).expect("set_threw call failed");
0 as _ 0 as _
} }
} }
@@ -156,15 +160,19 @@ macro_rules! invoke {
} }
macro_rules! invoke_no_return { macro_rules! invoke_no_return {
($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{ ($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{
let sp = get_emscripten_data($ctx).stack_save_ref().expect("stack_save is None").call().expect("stack_save call failed"); let funcs = get_emscripten_funcs(&$ctx).clone();
let call = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone(); let stack = funcs.stack_save_ref().expect("stack_save is None");
match call.call($($arg),*) { let sp = stack.call(&mut $ctx).expect("stack_save call failed");
let call = funcs.$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone();
match call.call(&mut $ctx, $($arg),*) {
Ok(v) => v, Ok(v) => v,
Err(_e) => { Err(_e) => {
get_emscripten_data($ctx).stack_restore_ref().expect("stack_restore is None").call(sp).expect("stack_restore call failed"); let stack = funcs.stack_restore_ref().expect("stack_restore is None");
stack.call(&mut $ctx, sp).expect("stack_restore call failed");
// TODO: We should check if _e != "longjmp" and if that's the case, re-throw the error // TODO: We should check if _e != "longjmp" and if that's the case, re-throw the error
// JS version is: if (e !== e+0 && e !== 'longjmp') throw e; // JS version is: if (e !== e+0 && e !== 'longjmp') throw e;
get_emscripten_data($ctx).set_threw_ref().expect("set_threw is None").call(1, 0).expect("set_threw call failed"); let threw = funcs.set_threw_ref().expect("set_threw is None");
threw.call(&mut $ctx, 1, 0).expect("set_threw call failed");
} }
} }
}}; }};
@@ -172,51 +180,59 @@ macro_rules! invoke_no_return {
// The invoke_j functions do not save the stack // The invoke_j functions do not save the stack
macro_rules! invoke_no_stack_save { macro_rules! invoke_no_stack_save {
($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{ ($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{
let call = get_emscripten_data($ctx).$name_ref().expect(concat!(stringify!($name), " is set to None")).clone(); let funcs = get_emscripten_funcs(&$ctx).clone();
let call = funcs.$name_ref().expect(concat!(stringify!($name), " is set to None")).clone();
call.call($($arg),*).unwrap() call.call(&mut $ctx.as_context_mut(), $($arg),*).unwrap()
}} }}
} }
// Invoke functions // Invoke functions
pub fn invoke_i(ctx: &EmEnv, index: i32) -> i32 { pub fn invoke_i(mut ctx: ContextMut<'_, EmEnv>, index: i32) -> i32 {
debug!("emscripten::invoke_i"); debug!("emscripten::invoke_i");
invoke!(ctx, dyn_call_i, dyn_call_i_ref, index) invoke!(ctx, dyn_call_i, dyn_call_i_ref, index)
} }
pub fn invoke_ii(ctx: &EmEnv, index: i32, a1: i32) -> i32 { pub fn invoke_ii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32) -> i32 {
debug!("emscripten::invoke_ii"); debug!("emscripten::invoke_ii");
invoke!(ctx, dyn_call_ii, dyn_call_ii_ref, index, a1) invoke!(ctx, dyn_call_ii, dyn_call_ii_ref, index, a1)
} }
pub fn invoke_iii(ctx: &EmEnv, index: i32, a1: i32, a2: i32) -> i32 { pub fn invoke_iii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32) -> i32 {
debug!("emscripten::invoke_iii"); debug!("emscripten::invoke_iii");
invoke!(ctx, dyn_call_iii, dyn_call_iii_ref, index, a1, a2) invoke!(ctx, dyn_call_iii, dyn_call_iii_ref, index, a1, a2)
} }
pub fn invoke_iiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { pub fn invoke_iiii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32) -> i32 {
debug!("emscripten::invoke_iiii"); debug!("emscripten::invoke_iiii");
invoke!(ctx, dyn_call_iiii, dyn_call_iiii_ref, index, a1, a2, a3) invoke!(ctx, dyn_call_iiii, dyn_call_iiii_ref, index, a1, a2, a3)
} }
pub fn invoke_iifi(ctx: &EmEnv, index: i32, a1: i32, a2: f64, a3: i32) -> i32 { pub fn invoke_iifi(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: f64, a3: i32) -> i32 {
debug!("emscripten::invoke_iifi"); debug!("emscripten::invoke_iifi");
invoke!(ctx, dyn_call_iifi, dyn_call_iifi_ref, index, a1, a2, a3) invoke!(ctx, dyn_call_iifi, dyn_call_iifi_ref, index, a1, a2, a3)
} }
pub fn invoke_v(ctx: &EmEnv, index: i32) { pub fn invoke_v(mut ctx: ContextMut<'_, EmEnv>, index: i32) {
debug!("emscripten::invoke_v"); debug!("emscripten::invoke_v");
invoke_no_return!(ctx, dyn_call_v, dyn_call_v_ref, index); invoke_no_return!(ctx, dyn_call_v, dyn_call_v_ref, index);
} }
pub fn invoke_vi(ctx: &EmEnv, index: i32, a1: i32) { pub fn invoke_vi(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32) {
debug!("emscripten::invoke_vi"); debug!("emscripten::invoke_vi");
invoke_no_return!(ctx, dyn_call_vi, dyn_call_vi_ref, index, a1); invoke_no_return!(ctx, dyn_call_vi, dyn_call_vi_ref, index, a1);
} }
pub fn invoke_vii(ctx: &EmEnv, index: i32, a1: i32, a2: i32) { pub fn invoke_vii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32) {
debug!("emscripten::invoke_vii"); debug!("emscripten::invoke_vii");
invoke_no_return!(ctx, dyn_call_vii, dyn_call_vii_ref, index, a1, a2); invoke_no_return!(ctx, dyn_call_vii, dyn_call_vii_ref, index, a1, a2);
} }
pub fn invoke_viii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32) { pub fn invoke_viii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32) {
debug!("emscripten::invoke_viii"); debug!("emscripten::invoke_viii");
invoke_no_return!(ctx, dyn_call_viii, dyn_call_viii_ref, index, a1, a2, a3); invoke_no_return!(ctx, dyn_call_viii, dyn_call_viii_ref, index, a1, a2, a3);
} }
pub fn invoke_viiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) { pub fn invoke_viiii(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
) {
debug!("emscripten::invoke_viiii"); debug!("emscripten::invoke_viiii");
invoke_no_return!( invoke_no_return!(
ctx, ctx,
@@ -229,11 +245,18 @@ pub fn invoke_viiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32)
a4 a4
); );
} }
pub fn invoke_dii(ctx: &EmEnv, index: i32, a1: i32, a2: i32) -> f64 { pub fn invoke_dii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32) -> f64 {
debug!("emscripten::invoke_dii"); debug!("emscripten::invoke_dii");
invoke!(ctx, dyn_call_dii, dyn_call_dii_ref, index, a1, a2) invoke!(ctx, dyn_call_dii, dyn_call_dii_ref, index, a1, a2)
} }
pub fn invoke_diiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> f64 { pub fn invoke_diiii(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
) -> f64 {
debug!("emscripten::invoke_diiii"); debug!("emscripten::invoke_diiii");
invoke!( invoke!(
ctx, ctx,
@@ -246,7 +269,14 @@ pub fn invoke_diiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32)
a4 a4
) )
} }
pub fn invoke_iiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> i32 { pub fn invoke_iiiii(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
) -> i32 {
debug!("emscripten::invoke_iiiii"); debug!("emscripten::invoke_iiiii");
invoke!( invoke!(
ctx, ctx,
@@ -259,7 +289,15 @@ pub fn invoke_iiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32)
a4 a4
) )
} }
pub fn invoke_iiiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) -> i32 { pub fn invoke_iiiiii(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
) -> i32 {
debug!("emscripten::invoke_iiiiii"); debug!("emscripten::invoke_iiiiii");
invoke!( invoke!(
ctx, ctx,
@@ -275,7 +313,7 @@ pub fn invoke_iiiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiii( pub fn invoke_iiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -300,7 +338,7 @@ pub fn invoke_iiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiii( pub fn invoke_iiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -327,7 +365,7 @@ pub fn invoke_iiiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiiii( pub fn invoke_iiiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -356,7 +394,7 @@ pub fn invoke_iiiiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiiiii( pub fn invoke_iiiiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -387,7 +425,7 @@ pub fn invoke_iiiiiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiiiiii( pub fn invoke_iiiiiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -418,11 +456,19 @@ pub fn invoke_iiiiiiiiiii(
a10 a10
) )
} }
pub fn invoke_vd(ctx: &EmEnv, index: i32, a1: f64) { pub fn invoke_vd(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: f64) {
debug!("emscripten::invoke_vd"); debug!("emscripten::invoke_vd");
invoke_no_return!(ctx, dyn_call_vd, dyn_call_vd_ref, index, a1) invoke_no_return!(ctx, dyn_call_vd, dyn_call_vd_ref, index, a1)
} }
pub fn invoke_viiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) { pub fn invoke_viiiii(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
) {
debug!("emscripten::invoke_viiiii"); debug!("emscripten::invoke_viiiii");
invoke_no_return!( invoke_no_return!(
ctx, ctx,
@@ -438,7 +484,7 @@ pub fn invoke_viiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiii( pub fn invoke_viiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -463,7 +509,7 @@ pub fn invoke_viiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiii( pub fn invoke_viiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -490,7 +536,7 @@ pub fn invoke_viiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiiii( pub fn invoke_viiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -519,7 +565,7 @@ pub fn invoke_viiiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiiiii( pub fn invoke_viiiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -550,7 +596,7 @@ pub fn invoke_viiiiiiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiiiiii( pub fn invoke_viiiiiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -582,24 +628,31 @@ pub fn invoke_viiiiiiiiii(
) )
} }
pub fn invoke_iij(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { pub fn invoke_iij(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32) -> i32 {
debug!("emscripten::invoke_iij"); debug!("emscripten::invoke_iij");
invoke!(ctx, dyn_call_iij, dyn_call_iij_ref, index, a1, a2, a3) invoke!(ctx, dyn_call_iij, dyn_call_iij_ref, index, a1, a2, a3)
} }
pub fn invoke_iji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { pub fn invoke_iji(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32) -> i32 {
debug!("emscripten::invoke_iji"); debug!("emscripten::invoke_iji");
invoke!(ctx, dyn_call_iji, dyn_call_iji_ref, index, a1, a2, a3) invoke!(ctx, dyn_call_iji, dyn_call_iji_ref, index, a1, a2, a3)
} }
pub fn invoke_iiji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> i32 { pub fn invoke_iiji(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
) -> i32 {
debug!("emscripten::invoke_iiji"); debug!("emscripten::invoke_iiji");
invoke!(ctx, dyn_call_iiji, dyn_call_iiji_ref, index, a1, a2, a3, a4) invoke!(ctx, dyn_call_iiji, dyn_call_iiji_ref, index, a1, a2, a3, a4)
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_iiijj( pub fn invoke_iiijj(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -622,28 +675,43 @@ pub fn invoke_iiijj(
a6 a6
) )
} }
pub fn invoke_j(ctx: &EmEnv, index: i32) -> i32 { pub fn invoke_j(mut ctx: ContextMut<'_, EmEnv>, index: i32) -> i32 {
debug!("emscripten::invoke_j"); debug!("emscripten::invoke_j");
invoke_no_stack_save!(ctx, dyn_call_j, dyn_call_j_ref, index) invoke_no_stack_save!(ctx, dyn_call_j, dyn_call_j_ref, index)
} }
pub fn invoke_ji(ctx: &EmEnv, index: i32, a1: i32) -> i32 { pub fn invoke_ji(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32) -> i32 {
debug!("emscripten::invoke_ji"); debug!("emscripten::invoke_ji");
invoke_no_stack_save!(ctx, dyn_call_ji, dyn_call_ji_ref, index, a1) invoke_no_stack_save!(ctx, dyn_call_ji, dyn_call_ji_ref, index, a1)
} }
pub fn invoke_jii(ctx: &EmEnv, index: i32, a1: i32, a2: i32) -> i32 { pub fn invoke_jii(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32) -> i32 {
debug!("emscripten::invoke_jii"); debug!("emscripten::invoke_jii");
invoke_no_stack_save!(ctx, dyn_call_jii, dyn_call_jii_ref, index, a1, a2) invoke_no_stack_save!(ctx, dyn_call_jii, dyn_call_jii_ref, index, a1, a2)
} }
pub fn invoke_jij(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { pub fn invoke_jij(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32) -> i32 {
debug!("emscripten::invoke_jij"); debug!("emscripten::invoke_jij");
invoke_no_stack_save!(ctx, dyn_call_jij, dyn_call_jij_ref, index, a1, a2, a3) invoke_no_stack_save!(ctx, dyn_call_jij, dyn_call_jij_ref, index, a1, a2, a3)
} }
pub fn invoke_jjj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> i32 { pub fn invoke_jjj(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
) -> i32 {
debug!("emscripten::invoke_jjj"); debug!("emscripten::invoke_jjj");
invoke_no_stack_save!(ctx, dyn_call_jjj, dyn_call_jjj_ref, index, a1, a2, a3, a4) invoke_no_stack_save!(ctx, dyn_call_jjj, dyn_call_jjj_ref, index, a1, a2, a3, a4)
} }
pub fn invoke_viiij(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) { pub fn invoke_viiij(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
) {
debug!("emscripten::invoke_viiij"); debug!("emscripten::invoke_viiij");
invoke_no_stack_save!( invoke_no_stack_save!(
ctx, ctx,
@@ -659,7 +727,7 @@ pub fn invoke_viiij(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiijiiii( pub fn invoke_viiijiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -690,7 +758,7 @@ pub fn invoke_viiijiiii(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viiijiiiiii( pub fn invoke_viiijiiiiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -723,11 +791,19 @@ pub fn invoke_viiijiiiiii(
a11 a11
) )
} }
pub fn invoke_viij(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) { pub fn invoke_viij(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) {
debug!("emscripten::invoke_viij"); debug!("emscripten::invoke_viij");
invoke_no_stack_save!(ctx, dyn_call_viij, dyn_call_viij_ref, index, a1, a2, a3, a4) invoke_no_stack_save!(ctx, dyn_call_viij, dyn_call_viij_ref, index, a1, a2, a3, a4)
} }
pub fn invoke_viiji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) { pub fn invoke_viiji(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
) {
debug!("emscripten::invoke_viiji"); debug!("emscripten::invoke_viiji");
invoke_no_stack_save!( invoke_no_stack_save!(
ctx, ctx,
@@ -743,7 +819,7 @@ pub fn invoke_viiji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viijiii( pub fn invoke_viijiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -769,7 +845,16 @@ pub fn invoke_viijiii(
) )
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viijj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32, a6: i32) { pub fn invoke_viijj(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
a6: i32,
) {
debug!("emscripten::invoke_viijj"); debug!("emscripten::invoke_viijj");
invoke_no_stack_save!( invoke_no_stack_save!(
ctx, ctx,
@@ -784,11 +869,19 @@ pub fn invoke_viijj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
a6 a6
) )
} }
pub fn invoke_vj(ctx: &EmEnv, index: i32, a1: i32, a2: i32) { pub fn invoke_vj(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32) {
debug!("emscripten::invoke_vj"); debug!("emscripten::invoke_vj");
invoke_no_stack_save!(ctx, dyn_call_vj, dyn_call_vj_ref, index, a1, a2) invoke_no_stack_save!(ctx, dyn_call_vj, dyn_call_vj_ref, index, a1, a2)
} }
pub fn invoke_vjji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) { pub fn invoke_vjji(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
) {
debug!("emscripten::invoke_vjji"); debug!("emscripten::invoke_vjji");
invoke_no_return!( invoke_no_return!(
ctx, ctx,
@@ -802,17 +895,17 @@ pub fn invoke_vjji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
a5 a5
) )
} }
pub fn invoke_vij(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32) { pub fn invoke_vij(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32) {
debug!("emscripten::invoke_vij"); debug!("emscripten::invoke_vij");
invoke_no_stack_save!(ctx, dyn_call_vij, dyn_call_vij_ref, index, a1, a2, a3) invoke_no_stack_save!(ctx, dyn_call_vij, dyn_call_vij_ref, index, a1, a2, a3)
} }
pub fn invoke_viji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) { pub fn invoke_viji(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) {
debug!("emscripten::invoke_viji"); debug!("emscripten::invoke_viji");
invoke_no_stack_save!(ctx, dyn_call_viji, dyn_call_viji_ref, index, a1, a2, a3, a4) invoke_no_stack_save!(ctx, dyn_call_viji, dyn_call_viji_ref, index, a1, a2, a3, a4)
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_vijiii( pub fn invoke_vijiii(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,
@@ -835,7 +928,15 @@ pub fn invoke_vijiii(
a6 a6
) )
} }
pub fn invoke_vijj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32, a5: i32) { pub fn invoke_vijj(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: i32,
a4: i32,
a5: i32,
) {
debug!("emscripten::invoke_vijj"); debug!("emscripten::invoke_vijj");
invoke_no_stack_save!( invoke_no_stack_save!(
ctx, ctx,
@@ -849,15 +950,23 @@ pub fn invoke_vijj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
a5 a5
) )
} }
pub fn invoke_vidd(ctx: &EmEnv, index: i32, a1: i32, a2: f64, a3: f64) { pub fn invoke_vidd(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: f64, a3: f64) {
debug!("emscripten::invoke_viid"); debug!("emscripten::invoke_viid");
invoke_no_return!(ctx, dyn_call_vidd, dyn_call_vidd_ref, index, a1, a2, a3); invoke_no_return!(ctx, dyn_call_vidd, dyn_call_vidd_ref, index, a1, a2, a3);
} }
pub fn invoke_viid(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: f64) { pub fn invoke_viid(mut ctx: ContextMut<'_, EmEnv>, index: i32, a1: i32, a2: i32, a3: f64) {
debug!("emscripten::invoke_viid"); debug!("emscripten::invoke_viid");
invoke_no_return!(ctx, dyn_call_viid, dyn_call_viid_ref, index, a1, a2, a3); invoke_no_return!(ctx, dyn_call_viid, dyn_call_viid_ref, index, a1, a2, a3);
} }
pub fn invoke_viidii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: f64, a4: i32, a5: i32) { pub fn invoke_viidii(
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
a3: f64,
a4: i32,
a5: i32,
) {
debug!("emscripten::invoke_viidii"); debug!("emscripten::invoke_viidii");
invoke_no_return!( invoke_no_return!(
ctx, ctx,
@@ -873,7 +982,7 @@ pub fn invoke_viidii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: f64, a4: i32
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn invoke_viidddddddd( pub fn invoke_viidddddddd(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
index: i32, index: i32,
a1: i32, a1: i32,
a2: i32, a2: i32,

View File

@@ -12,54 +12,55 @@ pub use self::windows::*;
use libc::c_char; use libc::c_char;
use crate::{allocate_on_stack, EmscriptenData}; use crate::{allocate_on_stack, EmscriptenData, EmscriptenFunctions};
use std::os::raw::c_int; use std::os::raw::c_int;
use std::sync::MutexGuard; use std::sync::MutexGuard;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ValueType; use wasmer::ValueType;
use wasmer::WasmPtr; use wasmer::{AsContextMut, ContextMut, WasmPtr};
pub fn call_malloc(ctx: &EmEnv, size: u32) -> u32 { pub fn call_malloc(mut ctx: ContextMut<'_, EmEnv>, size: u32) -> u32 {
get_emscripten_data(ctx) let malloc_ref = get_emscripten_funcs(&ctx).malloc_ref().unwrap().clone();
.malloc_ref() malloc_ref.call(&mut ctx.as_context_mut(), size).unwrap()
.unwrap()
.call(size)
.unwrap()
} }
#[warn(dead_code)] #[warn(dead_code)]
pub fn call_malloc_with_cast<T: Copy>(ctx: &EmEnv, size: u32) -> WasmPtr<T> { pub fn call_malloc_with_cast<T: Copy>(ctx: ContextMut<'_, EmEnv>, size: u32) -> WasmPtr<T> {
WasmPtr::new(call_malloc(ctx, size)) WasmPtr::new(call_malloc(ctx, size))
} }
pub fn call_memalign(ctx: &EmEnv, alignment: u32, size: u32) -> u32 { pub fn call_memalign(mut ctx: ContextMut<'_, EmEnv>, alignment: u32, size: u32) -> u32 {
if let Some(memalign) = &get_emscripten_data(ctx).memalign_ref() { let memalign_ref = get_emscripten_funcs(&ctx).memalign_ref().unwrap().clone();
memalign.call(alignment, size).unwrap() memalign_ref.call(&mut ctx, alignment, size).unwrap()
} else {
panic!("Memalign is set to None");
}
} }
pub fn call_memset(ctx: &EmEnv, pointer: u32, value: u32, size: u32) -> u32 { pub fn call_memset(mut ctx: ContextMut<'_, EmEnv>, pointer: u32, value: u32, size: u32) -> u32 {
get_emscripten_data(ctx) let memset_ref = get_emscripten_funcs(&ctx).memset_ref().unwrap().clone();
.memset_ref() memset_ref
.unwrap() .call(&mut ctx.as_context_mut(), pointer, value, size)
.call(pointer, value, size)
.unwrap() .unwrap()
} }
pub(crate) fn get_emscripten_data(ctx: &EmEnv) -> MutexGuard<EmscriptenData> { pub(crate) fn get_emscripten_data<'a>(
ctx.data.lock().unwrap() ctx: &'a ContextMut<'_, EmEnv>,
) -> MutexGuard<'a, EmscriptenData> {
ctx.data().data.lock().unwrap()
} }
pub fn _getpagesize(_ctx: &EmEnv) -> u32 { pub(crate) fn get_emscripten_funcs<'a>(
ctx: &'a ContextMut<'_, EmEnv>,
) -> MutexGuard<'a, EmscriptenFunctions> {
ctx.data().funcs.lock().unwrap()
}
pub fn _getpagesize(_ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::_getpagesize"); debug!("emscripten::_getpagesize");
16384 16384
} }
pub fn _times(ctx: &EmEnv, buffer: u32) -> u32 { pub fn _times(ctx: ContextMut<'_, EmEnv>, buffer: u32) -> u32 {
if buffer != 0 { if buffer != 0 {
call_memset(ctx, buffer, 0, 16); call_memset(ctx, buffer, 0, 16);
} }
@@ -67,18 +68,20 @@ pub fn _times(ctx: &EmEnv, buffer: u32) -> u32 {
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn ___build_environment(ctx: &EmEnv, environ: c_int) { pub fn ___build_environment(mut ctx: ContextMut<'_, EmEnv>, environ: c_int) {
debug!("emscripten::___build_environment {}", environ); debug!("emscripten::___build_environment {}", environ);
const MAX_ENV_VALUES: u32 = 64; const MAX_ENV_VALUES: u32 = 64;
const TOTAL_ENV_SIZE: u32 = 1024; const TOTAL_ENV_SIZE: u32 = 1024;
let environment = emscripten_memory_pointer!(ctx.memory(0), environ) as *mut c_int; let environment = emscripten_memory_pointer!(ctx, ctx.data().memory(0), environ) as *mut c_int;
let (mut pool_offset, env_ptr, mut pool_ptr) = unsafe { let (mut pool_offset, env_ptr, mut pool_ptr) = unsafe {
let (pool_offset, _pool_slice): (u32, &mut [u8]) = let (pool_offset, _pool_slice): (u32, &mut [u8]) =
allocate_on_stack(ctx, TOTAL_ENV_SIZE as u32); allocate_on_stack(&mut ctx.as_context_mut(), TOTAL_ENV_SIZE as u32);
let (env_offset, _env_slice): (u32, &mut [u8]) = let (env_offset, _env_slice): (u32, &mut [u8]) =
allocate_on_stack(ctx, (MAX_ENV_VALUES * 4) as u32); allocate_on_stack(&mut ctx.as_context_mut(), (MAX_ENV_VALUES * 4) as u32);
let env_ptr = emscripten_memory_pointer!(ctx.memory(0), env_offset) as *mut c_int; let env_ptr =
let pool_ptr = emscripten_memory_pointer!(ctx.memory(0), pool_offset) as *mut u8; emscripten_memory_pointer!(ctx, ctx.data().memory(0), env_offset) as *mut c_int;
let pool_ptr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), pool_offset) as *mut u8;
*env_ptr = pool_offset as i32; *env_ptr = pool_offset as i32;
*environment = env_offset as i32; *environment = env_offset as i32;
@@ -119,18 +122,18 @@ pub fn ___build_environment(ctx: &EmEnv, environ: c_int) {
} }
} }
pub fn ___assert_fail(_ctx: &EmEnv, _a: c_int, _b: c_int, _c: c_int, _d: c_int) { pub fn ___assert_fail(_ctx: ContextMut<'_, EmEnv>, _a: c_int, _b: c_int, _c: c_int, _d: c_int) {
debug!("emscripten::___assert_fail {} {} {} {}", _a, _b, _c, _d); debug!("emscripten::___assert_fail {} {} {} {}", _a, _b, _c, _d);
// TODO: Implement like emscripten expects regarding memory/page size // TODO: Implement like emscripten expects regarding memory/page size
// TODO raise an error // TODO raise an error
} }
pub fn _pathconf(ctx: &EmEnv, path_addr: c_int, name: c_int) -> c_int { pub fn _pathconf(ctx: ContextMut<'_, EmEnv>, path_addr: c_int, name: c_int) -> c_int {
debug!( debug!(
"emscripten::_pathconf {} {} - UNIMPLEMENTED", "emscripten::_pathconf {} {} - UNIMPLEMENTED",
path_addr, name path_addr, name
); );
let _path = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const c_char; let _path = emscripten_memory_pointer!(ctx, ctx.data().memory(0), path_addr) as *const c_char;
match name { match name {
0 => 32000, 0 => 32000,
1 | 2 | 3 => 255, 1 | 2 | 3 => 255,
@@ -146,7 +149,7 @@ pub fn _pathconf(ctx: &EmEnv, path_addr: c_int, name: c_int) -> c_int {
} }
} }
pub fn _fpathconf(_ctx: &EmEnv, _fildes: c_int, name: c_int) -> c_int { pub fn _fpathconf(_ctx: ContextMut<'_, EmEnv>, _fildes: c_int, name: c_int) -> c_int {
debug!("emscripten::_fpathconf {} {}", _fildes, name); debug!("emscripten::_fpathconf {} {}", _fildes, name);
match name { match name {
0 => 32000, 0 => 32000,

View File

@@ -10,14 +10,14 @@ use std::os::raw::c_char;
use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr}; use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr};
use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
use crate::EmEnv; use crate::EmEnv;
use wasmer::WasmPtr; use wasmer::{AsContextMut, ContextMut, WasmPtr};
// #[no_mangle] // #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char; /// emscripten: _getenv // (name: *const char) -> *const c_char;
pub fn _getenv(ctx: &EmEnv, name: i32) -> u32 { pub fn _getenv(ctx: ContextMut<'_, EmEnv>, name: i32) -> u32 {
debug!("emscripten::_getenv"); debug!("emscripten::_getenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), name) as *const c_char;
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
@@ -30,11 +30,11 @@ pub fn _getenv(ctx: &EmEnv, name: i32) -> u32 {
} }
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int); /// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int);
pub fn _setenv(ctx: &EmEnv, name: c_int, value: c_int, overwrite: c_int) -> c_int { pub fn _setenv(ctx: ContextMut<'_, EmEnv>, name: c_int, value: c_int, overwrite: c_int) -> c_int {
debug!("emscripten::_setenv"); debug!("emscripten::_setenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), name) as *const c_char;
let value_addr = emscripten_memory_pointer!(ctx.memory(0), value) as *const c_char; let value_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), value) as *const c_char;
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) }); debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) });
@@ -43,10 +43,10 @@ pub fn _setenv(ctx: &EmEnv, name: c_int, value: c_int, overwrite: c_int) -> c_in
} }
/// emscripten: _putenv // (name: *const char); /// emscripten: _putenv // (name: *const char);
pub fn _putenv(ctx: &EmEnv, name: c_int) -> c_int { pub fn _putenv(ctx: ContextMut<'_, EmEnv>, name: c_int) -> c_int {
debug!("emscripten::_putenv"); debug!("emscripten::_putenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), name) as *const c_char;
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
@@ -54,10 +54,10 @@ pub fn _putenv(ctx: &EmEnv, name: c_int) -> c_int {
} }
/// emscripten: _unsetenv // (name: *const char); /// emscripten: _unsetenv // (name: *const char);
pub fn _unsetenv(ctx: &EmEnv, name: c_int) -> c_int { pub fn _unsetenv(ctx: ContextMut<'_, EmEnv>, name: c_int) -> c_int {
debug!("emscripten::_unsetenv"); debug!("emscripten::_unsetenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), name) as *const c_char;
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
@@ -65,7 +65,7 @@ pub fn _unsetenv(ctx: &EmEnv, name: c_int) -> c_int {
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _getpwnam(ctx: &EmEnv, name_ptr: c_int) -> c_int { pub fn _getpwnam(mut ctx: ContextMut<'_, EmEnv>, name_ptr: c_int) -> c_int {
debug!("emscripten::_getpwnam {}", name_ptr); debug!("emscripten::_getpwnam {}", name_ptr);
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
let _ = name_ptr; let _ = name_ptr;
@@ -82,21 +82,25 @@ pub fn _getpwnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
} }
let name = unsafe { let name = unsafe {
let memory_name_ptr = emscripten_memory_pointer!(ctx.memory(0), name_ptr) as *const c_char; let memory = ctx.data().memory(0);
let memory_name_ptr = emscripten_memory_pointer!(ctx, memory, name_ptr) as *const c_char;
CStr::from_ptr(memory_name_ptr) CStr::from_ptr(memory_name_ptr)
}; };
unsafe { unsafe {
let passwd = &*libc_getpwnam(name.as_ptr()); let passwd = &*libc_getpwnam(name.as_ptr());
let passwd_struct_offset = call_malloc(ctx, mem::size_of::<GuestPasswd>() as _); let passwd_struct_offset =
call_malloc(ctx.as_context_mut(), mem::size_of::<GuestPasswd>() as _);
let memory = ctx.data().memory(0);
let passwd_struct_ptr = let passwd_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd; emscripten_memory_pointer!(ctx, memory, passwd_struct_offset) as *mut GuestPasswd;
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx, passwd.pw_name); (*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_name);
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(ctx, passwd.pw_passwd); (*passwd_struct_ptr).pw_passwd =
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx, passwd.pw_gecos); copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_passwd);
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx, passwd.pw_dir); (*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_gecos);
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx, passwd.pw_shell); (*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_dir);
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_shell);
(*passwd_struct_ptr).pw_uid = passwd.pw_uid; (*passwd_struct_ptr).pw_uid = passwd.pw_uid;
(*passwd_struct_ptr).pw_gid = passwd.pw_gid; (*passwd_struct_ptr).pw_gid = passwd.pw_gid;
@@ -105,7 +109,7 @@ pub fn _getpwnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _getgrnam(ctx: &EmEnv, name_ptr: c_int) -> c_int { pub fn _getgrnam(mut ctx: ContextMut<'_, EmEnv>, name_ptr: c_int) -> c_int {
debug!("emscripten::_getgrnam {}", name_ptr); debug!("emscripten::_getgrnam {}", name_ptr);
#[repr(C)] #[repr(C)]
@@ -117,18 +121,21 @@ pub fn _getgrnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
} }
let name = unsafe { let name = unsafe {
let memory_name_ptr = emscripten_memory_pointer!(ctx.memory(0), name_ptr) as *const c_char; let memory_name_ptr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), name_ptr) as *const c_char;
CStr::from_ptr(memory_name_ptr) CStr::from_ptr(memory_name_ptr)
}; };
unsafe { unsafe {
let group = &*libc_getgrnam(name.as_ptr()); let group = &*libc_getgrnam(name.as_ptr());
let group_struct_offset = call_malloc(ctx, mem::size_of::<GuestGroup>() as _); let group_struct_offset =
call_malloc(ctx.as_context_mut(), mem::size_of::<GuestGroup>() as _);
let group_struct_ptr = let group_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup; emscripten_memory_pointer!(ctx, ctx.data().memory(0), group_struct_offset)
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(ctx, group.gr_name); as *mut GuestGroup;
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(ctx, group.gr_passwd); (*group_struct_ptr).gr_name = copy_cstr_into_wasm(ctx.as_context_mut(), group.gr_name);
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(ctx.as_context_mut(), group.gr_passwd);
(*group_struct_ptr).gr_gid = group.gr_gid; (*group_struct_ptr).gr_gid = group.gr_gid;
(*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(ctx, group.gr_mem); (*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(ctx, group.gr_mem);
@@ -136,22 +143,25 @@ pub fn _getgrnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
} }
} }
pub fn _sysconf(_ctx: &EmEnv, name: c_int) -> i32 { pub fn _sysconf(_ctx: ContextMut<'_, EmEnv>, name: c_int) -> i32 {
debug!("emscripten::_sysconf {}", name); debug!("emscripten::_sysconf {}", name);
// TODO: Implement like emscripten expects regarding memory/page size // TODO: Implement like emscripten expects regarding memory/page size
unsafe { sysconf(name) as i32 } // TODO review i64 unsafe { sysconf(name) as i32 } // TODO review i64
} }
// this may be a memory leak, probably not though because emscripten does the same thing // this may be a memory leak, probably not though because emscripten does the same thing
pub fn _gai_strerror(ctx: &EmEnv, ecode: i32) -> i32 { pub fn _gai_strerror(mut ctx: ContextMut<'_, EmEnv>, ecode: i32) -> i32 {
debug!("emscripten::_gai_strerror({})", ecode); debug!("emscripten::_gai_strerror({})", ecode);
let cstr = unsafe { std::ffi::CStr::from_ptr(libc::gai_strerror(ecode)) }; let cstr = unsafe { std::ffi::CStr::from_ptr(libc::gai_strerror(ecode)) };
let bytes = cstr.to_bytes_with_nul(); let bytes = cstr.to_bytes_with_nul();
let string_on_guest: WasmPtr<c_char> = call_malloc_with_cast(ctx, bytes.len() as _); let string_on_guest: WasmPtr<c_char> =
let memory = ctx.memory(0); call_malloc_with_cast(ctx.as_context_mut(), bytes.len() as _);
let memory = ctx.data().memory(0);
let writer = string_on_guest.slice(&memory, bytes.len() as _).unwrap(); let writer = string_on_guest
.slice(&ctx, &memory, bytes.len() as _)
.unwrap();
for (i, byte) in bytes.iter().enumerate() { for (i, byte) in bytes.iter().enumerate() {
writer.index(i as u64).write(*byte as _).unwrap(); writer.index(i as u64).write(*byte as _).unwrap();
} }
@@ -160,7 +170,7 @@ pub fn _gai_strerror(ctx: &EmEnv, ecode: i32) -> i32 {
} }
pub fn _getaddrinfo( pub fn _getaddrinfo(
ctx: &EmEnv, mut ctx: ContextMut<'_, EmEnv>,
node_ptr: WasmPtr<c_char>, node_ptr: WasmPtr<c_char>,
service_str_ptr: WasmPtr<c_char>, service_str_ptr: WasmPtr<c_char>,
hints_ptr: WasmPtr<EmAddrInfo>, hints_ptr: WasmPtr<EmAddrInfo>,
@@ -168,7 +178,7 @@ pub fn _getaddrinfo(
) -> i32 { ) -> i32 {
use libc::{addrinfo, freeaddrinfo}; use libc::{addrinfo, freeaddrinfo};
debug!("emscripten::_getaddrinfo"); debug!("emscripten::_getaddrinfo");
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
debug!(" => node = {}", { debug!(" => node = {}", {
if node_ptr.is_null() { if node_ptr.is_null() {
std::borrow::Cow::Borrowed("null") std::borrow::Cow::Borrowed("null")
@@ -187,7 +197,7 @@ pub fn _getaddrinfo(
let hints = if hints_ptr.is_null() { let hints = if hints_ptr.is_null() {
None None
} else { } else {
let hints_guest = hints_ptr.deref(&memory).read().unwrap(); let hints_guest = hints_ptr.deref(&ctx, &memory).read().unwrap();
Some(addrinfo { Some(addrinfo {
ai_flags: hints_guest.ai_flags, ai_flags: hints_guest.ai_flags,
ai_family: hints_guest.ai_family, ai_family: hints_guest.ai_family,
@@ -234,14 +244,14 @@ pub fn _getaddrinfo(
while !current_host_node.is_null() { while !current_host_node.is_null() {
let current_guest_node_ptr: WasmPtr<EmAddrInfo> = let current_guest_node_ptr: WasmPtr<EmAddrInfo> =
call_malloc_with_cast(ctx, std::mem::size_of::<EmAddrInfo>() as _); call_malloc_with_cast(ctx.as_context_mut(), std::mem::size_of::<EmAddrInfo>() as _);
if head_of_list.is_none() { if head_of_list.is_none() {
head_of_list = Some(current_guest_node_ptr); head_of_list = Some(current_guest_node_ptr);
} }
// connect list // connect list
if let Some(prev_guest) = previous_guest_node { if let Some(prev_guest) = previous_guest_node {
let derefed_prev_guest = prev_guest.deref(&memory); let derefed_prev_guest = prev_guest.deref(&ctx, &memory);
let mut pg = derefed_prev_guest.read().unwrap(); let mut pg = derefed_prev_guest.read().unwrap();
pg.ai_next = current_guest_node_ptr; pg.ai_next = current_guest_node_ptr;
derefed_prev_guest.write(pg).unwrap(); derefed_prev_guest.write(pg).unwrap();
@@ -254,9 +264,9 @@ pub fn _getaddrinfo(
let guest_sockaddr_ptr = { let guest_sockaddr_ptr = {
let host_sockaddr_ptr = (*current_host_node).ai_addr; let host_sockaddr_ptr = (*current_host_node).ai_addr;
let guest_sockaddr_ptr: WasmPtr<EmSockAddr> = let guest_sockaddr_ptr: WasmPtr<EmSockAddr> =
call_malloc_with_cast(ctx, host_addrlen as _); call_malloc_with_cast(ctx.as_context_mut(), host_addrlen as _);
let derefed_guest_sockaddr = guest_sockaddr_ptr.deref(&memory); let derefed_guest_sockaddr = guest_sockaddr_ptr.deref(&ctx, &memory);
let mut gs = derefed_guest_sockaddr.read().unwrap(); let mut gs = derefed_guest_sockaddr.read().unwrap();
gs.sa_family = (*host_sockaddr_ptr).sa_family as i16; gs.sa_family = (*host_sockaddr_ptr).sa_family as i16;
gs.sa_data = (*host_sockaddr_ptr).sa_data; gs.sa_data = (*host_sockaddr_ptr).sa_data;
@@ -273,10 +283,10 @@ pub fn _getaddrinfo(
let canonname_bytes = canonname_cstr.to_bytes_with_nul(); let canonname_bytes = canonname_cstr.to_bytes_with_nul();
let str_size = canonname_bytes.len(); let str_size = canonname_bytes.len();
let guest_canonname: WasmPtr<c_char> = let guest_canonname: WasmPtr<c_char> =
call_malloc_with_cast(ctx, str_size as _); call_malloc_with_cast(ctx.as_context_mut(), str_size as _);
let guest_canonname_writer = let guest_canonname_writer =
guest_canonname.slice(&memory, str_size as _).unwrap(); guest_canonname.slice(&ctx, &memory, str_size as _).unwrap();
for (i, b) in canonname_bytes.iter().enumerate() { for (i, b) in canonname_bytes.iter().enumerate() {
guest_canonname_writer guest_canonname_writer
.index(i as u64) .index(i as u64)
@@ -290,7 +300,7 @@ pub fn _getaddrinfo(
} }
}; };
let derefed_current_guest_node = current_guest_node_ptr.deref(&memory); let derefed_current_guest_node = current_guest_node_ptr.deref(&ctx, &memory);
let mut cgn = derefed_current_guest_node.read().unwrap(); let mut cgn = derefed_current_guest_node.read().unwrap();
cgn.ai_flags = (*current_host_node).ai_flags; cgn.ai_flags = (*current_host_node).ai_flags;
cgn.ai_family = (*current_host_node).ai_family; cgn.ai_family = (*current_host_node).ai_family;
@@ -310,7 +320,10 @@ pub fn _getaddrinfo(
head_of_list.unwrap_or_else(|| WasmPtr::new(0)) head_of_list.unwrap_or_else(|| WasmPtr::new(0))
}; };
res_val_ptr.deref(&memory).write(head_of_list).unwrap(); res_val_ptr
.deref(&ctx, &memory)
.write(head_of_list)
.unwrap();
0 0
} }

View File

@@ -1,7 +1,8 @@
// use std::collections::HashMap; // use std::collections::HashMap;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn ___seterrno(_ctx: &EmEnv, _value: i32) { pub fn ___seterrno(mut _ctx: ContextMut<'_, EmEnv>, _value: i32) {
debug!("emscripten::___seterrno {}", _value); debug!("emscripten::___seterrno {}", _value);
// TODO: Incomplete impl // TODO: Incomplete impl
eprintln!("failed to set errno!"); eprintln!("failed to set errno!");

View File

@@ -1,56 +1,57 @@
use super::env; use super::env;
use super::process::_abort; use super::process::_abort;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
/// emscripten: ___cxa_allocate_exception /// emscripten: ___cxa_allocate_exception
pub fn ___cxa_allocate_exception(ctx: &EmEnv, size: u32) -> u32 { pub fn ___cxa_allocate_exception(ctx: ContextMut<'_, EmEnv>, size: u32) -> u32 {
debug!("emscripten::___cxa_allocate_exception"); debug!("emscripten::___cxa_allocate_exception");
env::call_malloc(ctx, size as _) env::call_malloc(ctx, size as _)
} }
pub fn ___cxa_current_primary_exception(_ctx: &EmEnv) -> u32 { pub fn ___cxa_current_primary_exception(_ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::___cxa_current_primary_exception"); debug!("emscripten::___cxa_current_primary_exception");
unimplemented!("emscripten::___cxa_current_primary_exception") unimplemented!("emscripten::___cxa_current_primary_exception")
} }
pub fn ___cxa_decrement_exception_refcount(_ctx: &EmEnv, _a: u32) { pub fn ___cxa_decrement_exception_refcount(_ctx: ContextMut<'_, EmEnv>, _a: u32) {
debug!("emscripten::___cxa_decrement_exception_refcount({})", _a); debug!("emscripten::___cxa_decrement_exception_refcount({})", _a);
unimplemented!("emscripten::___cxa_decrement_exception_refcount({})", _a) unimplemented!("emscripten::___cxa_decrement_exception_refcount({})", _a)
} }
pub fn ___cxa_increment_exception_refcount(_ctx: &EmEnv, _a: u32) { pub fn ___cxa_increment_exception_refcount(_ctx: ContextMut<'_, EmEnv>, _a: u32) {
debug!("emscripten::___cxa_increment_exception_refcount({})", _a); debug!("emscripten::___cxa_increment_exception_refcount({})", _a);
unimplemented!("emscripten::___cxa_increment_exception_refcount({})", _a) unimplemented!("emscripten::___cxa_increment_exception_refcount({})", _a)
} }
pub fn ___cxa_rethrow_primary_exception(_ctx: &EmEnv, _a: u32) { pub fn ___cxa_rethrow_primary_exception(_ctx: ContextMut<'_, EmEnv>, _a: u32) {
debug!("emscripten::___cxa_rethrow_primary_exception({})", _a); debug!("emscripten::___cxa_rethrow_primary_exception({})", _a);
unimplemented!("emscripten::___cxa_rethrow_primary_exception({})", _a) unimplemented!("emscripten::___cxa_rethrow_primary_exception({})", _a)
} }
/// emscripten: ___cxa_throw /// emscripten: ___cxa_throw
/// TODO: We don't have support for exceptions yet /// TODO: We don't have support for exceptions yet
pub fn ___cxa_throw(ctx: &EmEnv, _ptr: u32, _ty: u32, _destructor: u32) { pub fn ___cxa_throw(ctx: ContextMut<'_, EmEnv>, _ptr: u32, _ty: u32, _destructor: u32) {
debug!("emscripten::___cxa_throw"); debug!("emscripten::___cxa_throw");
eprintln!("Throwing exceptions not yet implemented: aborting!"); eprintln!("Throwing exceptions not yet implemented: aborting!");
_abort(ctx); _abort(ctx);
} }
pub fn ___cxa_begin_catch(_ctx: &EmEnv, _exception_object_ptr: u32) -> i32 { pub fn ___cxa_begin_catch(_ctx: ContextMut<'_, EmEnv>, _exception_object_ptr: u32) -> i32 {
debug!("emscripten::___cxa_begin_catch"); debug!("emscripten::___cxa_begin_catch");
-1 -1
} }
pub fn ___cxa_end_catch(_ctx: &EmEnv) { pub fn ___cxa_end_catch(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::___cxa_end_catch"); debug!("emscripten::___cxa_end_catch");
} }
pub fn ___cxa_uncaught_exception(_ctx: &EmEnv) -> i32 { pub fn ___cxa_uncaught_exception(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::___cxa_uncaught_exception"); debug!("emscripten::___cxa_uncaught_exception");
-1 -1
} }
pub fn ___cxa_pure_virtual(_ctx: &EmEnv) { pub fn ___cxa_pure_virtual(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::___cxa_pure_virtual"); debug!("emscripten::___cxa_pure_virtual");
// ABORT = true // ABORT = true
panic!("Pure virtual function called!"); panic!("Pure virtual function called!");

View File

@@ -3,27 +3,27 @@ use crate::EmEnv;
use libc::c_char; use libc::c_char;
use libc::execvp as libc_execvp; use libc::execvp as libc_execvp;
use std::ffi::CString; use std::ffi::CString;
use wasmer::WasmPtr; use wasmer::{ContextMut, WasmPtr};
pub fn execvp(ctx: &EmEnv, command_name_offset: u32, argv_offset: u32) -> i32 { pub fn execvp(ctx: ContextMut<'_, EmEnv>, command_name_offset: u32, argv_offset: u32) -> i32 {
// a single reference to re-use // a single reference to re-use
let emscripten_memory = ctx.memory(0); let emscripten_memory = ctx.data().memory(0);
// read command name as string // read command name as string
let command_name_string_vec = WasmPtr::<u8>::new(command_name_offset) let command_name_string_vec = WasmPtr::<u8>::new(command_name_offset)
.read_until(&emscripten_memory, |&byte| byte == 0) .read_until(&ctx, &emscripten_memory, |&byte| byte == 0)
.unwrap(); .unwrap();
let command_name_string = CString::new(command_name_string_vec).unwrap(); let command_name_string = CString::new(command_name_string_vec).unwrap();
// get the array of args // get the array of args
let argv = WasmPtr::<WasmPtr<u8>>::new(argv_offset) let argv = WasmPtr::<WasmPtr<u8>>::new(argv_offset)
.read_until(&emscripten_memory, |&ptr| ptr.is_null()) .read_until(&ctx, &emscripten_memory, |&ptr| ptr.is_null())
.unwrap(); .unwrap();
let arg_strings: Vec<CString> = argv let arg_strings: Vec<CString> = argv
.into_iter() .into_iter()
.map(|ptr| { .map(|ptr| {
let vec = ptr let vec = ptr
.read_until(&emscripten_memory, |&byte| byte == 0) .read_until(&ctx, &emscripten_memory, |&byte| byte == 0)
.unwrap(); .unwrap();
CString::new(vec).unwrap() CString::new(vec).unwrap()
}) })
@@ -40,13 +40,23 @@ pub fn execvp(ctx: &EmEnv, command_name_offset: u32, argv_offset: u32) -> i32 {
} }
/// execl /// execl
pub fn execl(_ctx: &EmEnv, _path_ptr: i32, _arg0_ptr: i32, _varargs: VarArgs) -> i32 { pub fn execl(
_ctx: ContextMut<'_, EmEnv>,
_path_ptr: i32,
_arg0_ptr: i32,
_varargs: VarArgs,
) -> i32 {
debug!("emscripten::execl"); debug!("emscripten::execl");
-1 -1
} }
/// execle /// execle
pub fn execle(_ctx: &EmEnv, _path_ptr: i32, _arg0_ptr: i32, _varargs: VarArgs) -> i32 { pub fn execle(
_ctx: ContextMut<'_, EmEnv>,
_path_ptr: i32,
_arg0_ptr: i32,
_varargs: VarArgs,
) -> i32 {
debug!("emscripten::execle"); debug!("emscripten::execle");
-1 -1
} }

View File

@@ -1,7 +1,8 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
// __exit // __exit
pub fn exit(_ctx: &EmEnv, value: i32) { pub fn exit(mut _ctx: ContextMut<'_, EmEnv>, value: i32) {
debug!("emscripten::exit {}", value); debug!("emscripten::exit {}", value);
::std::process::exit(value); ::std::process::exit(value);
} }

View File

@@ -1,6 +1,7 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn addr(_ctx: &EmEnv, _cp: i32) -> i32 { pub fn addr(mut _ctx: ContextMut<'_, EmEnv>, _cp: i32) -> i32 {
debug!("inet::addr({})", _cp); debug!("inet::addr({})", _cp);
0 0
} }

View File

@@ -11,25 +11,26 @@ pub use self::unix::*;
pub use self::windows::*; pub use self::windows::*;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
/// getprotobyname /// getprotobyname
pub fn getprotobyname(_ctx: &EmEnv, _name_ptr: i32) -> i32 { pub fn getprotobyname(_ctx: ContextMut<'_, EmEnv>, _name_ptr: i32) -> i32 {
debug!("emscripten::getprotobyname"); debug!("emscripten::getprotobyname");
unimplemented!("emscripten::getprotobyname") unimplemented!("emscripten::getprotobyname")
} }
/// getprotobynumber /// getprotobynumber
pub fn getprotobynumber(_ctx: &EmEnv, _one: i32) -> i32 { pub fn getprotobynumber(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::getprotobynumber"); debug!("emscripten::getprotobynumber");
unimplemented!("emscripten::getprotobynumber") unimplemented!("emscripten::getprotobynumber")
} }
/// sigdelset /// sigdelset
pub fn sigdelset(ctx: &EmEnv, set: i32, signum: i32) -> i32 { pub fn sigdelset(ctx: ContextMut<'_, EmEnv>, set: i32, signum: i32) -> i32 {
debug!("emscripten::sigdelset"); debug!("emscripten::sigdelset");
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let ptr = emscripten_memory_pointer!(memory, set) as *mut i32; let ptr = emscripten_memory_pointer!(ctx, memory, set) as *mut i32;
unsafe { *ptr &= !(1 << (signum - 1)) } unsafe { *ptr &= !(1 << (signum - 1)) }
@@ -37,11 +38,11 @@ pub fn sigdelset(ctx: &EmEnv, set: i32, signum: i32) -> i32 {
} }
/// sigfillset /// sigfillset
pub fn sigfillset(ctx: &EmEnv, set: i32) -> i32 { pub fn sigfillset(ctx: ContextMut<'_, EmEnv>, set: i32) -> i32 {
debug!("emscripten::sigfillset"); debug!("emscripten::sigfillset");
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let ptr = emscripten_memory_pointer!(memory, set) as *mut i32; let ptr = emscripten_memory_pointer!(ctx, memory, set) as *mut i32;
unsafe { unsafe {
*ptr = -1; *ptr = -1;
@@ -51,13 +52,13 @@ pub fn sigfillset(ctx: &EmEnv, set: i32) -> i32 {
} }
/// tzset /// tzset
pub fn tzset(_ctx: &EmEnv) { pub fn tzset(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::tzset - stub"); debug!("emscripten::tzset - stub");
//unimplemented!("emscripten::tzset - stub") //unimplemented!("emscripten::tzset - stub")
} }
/// strptime /// strptime
pub fn strptime(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn strptime(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::strptime"); debug!("emscripten::strptime");
unimplemented!("emscripten::strptime") unimplemented!("emscripten::strptime")
} }

View File

@@ -4,31 +4,32 @@ use libc::{chroot as _chroot, getpwuid as _getpwuid, printf as _printf};
use std::mem; use std::mem;
use crate::EmEnv; use crate::EmEnv;
use wasmer::{AsContextMut, ContextMut};
/// putchar /// putchar
pub fn putchar(_ctx: &EmEnv, chr: i32) { pub fn putchar(_ctx: ContextMut<'_, EmEnv>, chr: i32) {
unsafe { libc::putchar(chr) }; unsafe { libc::putchar(chr) };
} }
/// printf /// printf
pub fn printf(ctx: &EmEnv, memory_offset: i32, extra: i32) -> i32 { pub fn printf(ctx: ContextMut<'_, EmEnv>, memory_offset: i32, extra: i32) -> i32 {
debug!("emscripten::printf {}, {}", memory_offset, extra); debug!("emscripten::printf {}, {}", memory_offset, extra);
unsafe { unsafe {
let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; let addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), memory_offset) as _;
_printf(addr, extra) _printf(addr, extra)
} }
} }
/// chroot /// chroot
pub fn chroot(ctx: &EmEnv, name_ptr: i32) -> i32 { pub fn chroot(ctx: ContextMut<'_, EmEnv>, name_ptr: i32) -> i32 {
debug!("emscripten::chroot"); debug!("emscripten::chroot");
let name = emscripten_memory_pointer!(ctx.memory(0), name_ptr) as *const i8; let name = emscripten_memory_pointer!(ctx, ctx.data().memory(0), name_ptr) as *const i8;
unsafe { _chroot(name as *const _) } unsafe { _chroot(name as *const _) }
} }
/// getpwuid /// getpwuid
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn getpwuid(ctx: &EmEnv, uid: i32) -> i32 { pub fn getpwuid(mut ctx: ContextMut<'_, EmEnv>, uid: i32) -> i32 {
debug!("emscripten::getpwuid {}", uid); debug!("emscripten::getpwuid {}", uid);
#[repr(C)] #[repr(C)]
@@ -44,18 +45,21 @@ pub fn getpwuid(ctx: &EmEnv, uid: i32) -> i32 {
unsafe { unsafe {
let passwd = &*_getpwuid(uid as _); let passwd = &*_getpwuid(uid as _);
let passwd_struct_offset = call_malloc(ctx, mem::size_of::<GuestPasswd>() as _); let passwd_struct_offset =
call_malloc(ctx.as_context_mut(), mem::size_of::<GuestPasswd>() as _);
let passwd_struct_ptr = let passwd_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd; emscripten_memory_pointer!(ctx, ctx.data().memory(0), passwd_struct_offset)
as *mut GuestPasswd;
assert_eq!( assert_eq!(
passwd_struct_ptr as usize % std::mem::align_of::<GuestPasswd>(), passwd_struct_ptr as usize % std::mem::align_of::<GuestPasswd>(),
0 0
); );
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx, passwd.pw_name); (*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_name);
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(ctx, passwd.pw_passwd); (*passwd_struct_ptr).pw_passwd =
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx, passwd.pw_gecos); copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_passwd);
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx, passwd.pw_dir); (*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_gecos);
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx, passwd.pw_shell); (*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_dir);
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_shell);
(*passwd_struct_ptr).pw_uid = passwd.pw_uid; (*passwd_struct_ptr).pw_uid = passwd.pw_uid;
(*passwd_struct_ptr).pw_gid = passwd.pw_gid; (*passwd_struct_ptr).pw_gid = passwd.pw_gid;

View File

@@ -1,13 +1,14 @@
use super::env::get_emscripten_data; use super::env::get_emscripten_funcs;
use super::process::abort_with_message; use super::process::abort_with_message;
use libc::c_int; use libc::c_int;
// use std::cell::UnsafeCell; // use std::cell::UnsafeCell;
use crate::EmEnv; use crate::EmEnv;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use wasmer::{AsContextMut, ContextMut};
/// setjmp /// setjmp
pub fn __setjmp(ctx: &EmEnv, _env_addr: u32) -> c_int { pub fn __setjmp(ctx: ContextMut<'_, EmEnv>, _env_addr: u32) -> c_int {
debug!("emscripten::__setjmp (setjmp)"); debug!("emscripten::__setjmp (setjmp)");
abort_with_message(ctx, "missing function: _setjmp"); abort_with_message(ctx, "missing function: _setjmp");
unreachable!() unreachable!()
@@ -18,7 +19,7 @@ pub fn __setjmp(ctx: &EmEnv, _env_addr: u32) -> c_int {
// let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8; // let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8;
// // We create the jump buffer outside of the wasm memory // // We create the jump buffer outside of the wasm memory
// let jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]); // let jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]);
// let jumps = &mut get_emscripten_data(ctx).jumps; // let jumps = &mut get_emscripten_data(&ctx).jumps;
// let result = setjmp(jump_buf.get() as _); // let result = setjmp(jump_buf.get() as _);
// // We set the jump index to be the last 3value of jumps // // We set the jump index to be the last 3value of jumps
// *jump_index = jumps.len() as _; // *jump_index = jumps.len() as _;
@@ -30,13 +31,13 @@ pub fn __setjmp(ctx: &EmEnv, _env_addr: u32) -> c_int {
/// longjmp /// longjmp
#[allow(unreachable_code)] #[allow(unreachable_code)]
pub fn __longjmp(ctx: &EmEnv, _env_addr: u32, _val: c_int) { pub fn __longjmp(ctx: ContextMut<'_, EmEnv>, _env_addr: u32, _val: c_int) {
debug!("emscripten::__longjmp (longmp)"); debug!("emscripten::__longjmp (longmp)");
abort_with_message(ctx, "missing function: _longjmp"); abort_with_message(ctx, "missing function: _longjmp");
// unsafe { // unsafe {
// // We retrieve the jump index from the env address // // We retrieve the jump index from the env address
// let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8; // let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8;
// let jumps = &mut get_emscripten_data(ctx).jumps; // let jumps = &mut get_emscripten_data(&ctx).jumps;
// // We get the real jump buffer from the jumps vector, using the retrieved index // // We get the real jump buffer from the jumps vector, using the retrieved index
// let jump_buf = &jumps[*jump_index as usize]; // let jump_buf = &jumps[*jump_index as usize];
// longjmp(jump_buf.get() as _, val) // longjmp(jump_buf.get() as _, val)
@@ -57,12 +58,18 @@ impl Error for LongJumpRet {}
/// _longjmp /// _longjmp
// This function differs from the js implementation, it should return Result<(), &'static str> // This function differs from the js implementation, it should return Result<(), &'static str>
#[allow(unreachable_code)] #[allow(unreachable_code)]
pub fn _longjmp(ctx: &EmEnv, env_addr: i32, val: c_int) -> Result<(), LongJumpRet> { pub fn _longjmp(
mut ctx: ContextMut<'_, EmEnv>,
env_addr: i32,
val: c_int,
) -> Result<(), LongJumpRet> {
let val = if val == 0 { 1 } else { val }; let val = if val == 0 { 1 } else { val };
get_emscripten_data(ctx) let threw = get_emscripten_funcs(&ctx)
.set_threw_ref() .set_threw_ref()
.expect("set_threw is None") .expect("set_threw is None")
.call(env_addr, val) .clone();
threw
.call(&mut ctx.as_context_mut(), env_addr, val)
.expect("set_threw failed to call"); .expect("set_threw failed to call");
Err(LongJumpRet) Err(LongJumpRet)
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +1,77 @@
extern crate libc; extern crate libc;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
#[cfg(unix)] #[cfg(unix)]
use std::convert::TryInto; use std::convert::TryInto;
pub fn current_sigrtmax() -> i32 { pub fn current_sigrtmax(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::current_sigrtmax"); debug!("emscripten::current_sigrtmax");
0 0
} }
pub fn current_sigrtmin() -> i32 { pub fn current_sigrtmin(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::current_sigrtmin"); debug!("emscripten::current_sigrtmin");
0 0
} }
pub fn endpwent() { pub fn endpwent(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::endpwent"); debug!("emscripten::endpwent");
} }
pub fn execv(_a: i32, _b: i32) -> i32 { pub fn execv(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::execv"); debug!("emscripten::execv");
0 0
} }
pub fn fexecve(_a: i32, _b: i32, _c: i32) -> i32 { pub fn fexecve(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32, _c: i32) -> i32 {
debug!("emscripten::fexecve"); debug!("emscripten::fexecve");
0 0
} }
pub fn fpathconf(_a: i32, _b: i32) -> i32 { pub fn fpathconf(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::fpathconf"); debug!("emscripten::fpathconf");
0 0
} }
pub fn getitimer(_a: i32, _b: i32) -> i32 { pub fn getitimer(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::getitimer"); debug!("emscripten::getitimer");
0 0
} }
pub fn getpwent() -> i32 { pub fn getpwent(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::getpwent"); debug!("emscripten::getpwent");
0 0
} }
pub fn killpg(_a: i32, _b: i32) -> i32 { pub fn killpg(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::killpg"); debug!("emscripten::killpg");
0 0
} }
#[cfg(unix)] #[cfg(unix)]
pub fn pathconf(ctx: &EmEnv, path_ptr: i32, name: i32) -> i32 { pub fn pathconf(ctx: ContextMut<'_, EmEnv>, path_ptr: i32, name: i32) -> i32 {
debug!("emscripten::pathconf"); debug!("emscripten::pathconf");
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8; let path = emscripten_memory_pointer!(ctx, ctx.data().memory(0), path_ptr) as *const i8;
unsafe { libc::pathconf(path as *const _, name).try_into().unwrap() } unsafe { libc::pathconf(path as *const _, name).try_into().unwrap() }
} }
#[cfg(not(unix))] #[cfg(not(unix))]
pub fn pathconf(_ctx: &EmEnv, _path_ptr: i32, _name: i32) -> i32 { pub fn pathconf(_ctx: ContextMut<'_, EmEnv>, _path_ptr: i32, _name: i32) -> i32 {
debug!("emscripten::pathconf"); debug!("emscripten::pathconf");
0 0
} }
pub fn setpwent() { pub fn setpwent(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::setpwent"); debug!("emscripten::setpwent");
} }
pub fn sigismember(_a: i32, _b: i32) -> i32 { pub fn sigismember(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::sigismember"); debug!("emscripten::sigismember");
0 0
} }
pub fn sigpending(_a: i32) -> i32 { pub fn sigpending(_ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
debug!("emscripten::sigpending"); debug!("emscripten::sigpending");
0 0
} }

View File

@@ -1,27 +1,28 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
// TODO: Need to implement. // TODO: Need to implement.
/// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void /// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void
pub fn _dlopen(_ctx: &EmEnv, _filename: u32, _flag: u32) -> i32 { pub fn _dlopen(mut _ctx: ContextMut<'_, EmEnv>, _filename: u32, _flag: u32) -> i32 {
debug!("emscripten::_dlopen"); debug!("emscripten::_dlopen");
-1 -1
} }
/// emscripten: dlclose(handle: *mut c_void) -> c_int /// emscripten: dlclose(handle: *mut c_void) -> c_int
pub fn _dlclose(_ctx: &EmEnv, _filename: u32) -> i32 { pub fn _dlclose(mut _ctx: ContextMut<'_, EmEnv>, _filename: u32) -> i32 {
debug!("emscripten::_dlclose"); debug!("emscripten::_dlclose");
-1 -1
} }
/// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void /// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void
pub fn _dlsym(_ctx: &EmEnv, _filepath: u32, _symbol: u32) -> i32 { pub fn _dlsym(mut _ctx: ContextMut<'_, EmEnv>, _filepath: u32, _symbol: u32) -> i32 {
debug!("emscripten::_dlsym"); debug!("emscripten::_dlsym");
-1 -1
} }
/// emscripten: dlerror() -> *mut c_char /// emscripten: dlerror() -> *mut c_char
pub fn _dlerror(_ctx: &EmEnv) -> i32 { pub fn _dlerror(mut _ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::_dlerror"); debug!("emscripten::_dlerror");
-1 -1
} }

View File

@@ -1,22 +1,29 @@
use crate::EmEnv; use crate::EmEnv;
use libc::c_int; use libc::c_int;
use wasmer::ContextMut;
// NOTE: Not implemented by Emscripten // NOTE: Not implemented by Emscripten
pub fn ___lock(_ctx: &EmEnv, _what: c_int) { pub fn ___lock(mut _ctx: ContextMut<'_, EmEnv>, _what: c_int) {
debug!("emscripten::___lock {}", _what); debug!("emscripten::___lock {}", _what);
} }
// NOTE: Not implemented by Emscripten // NOTE: Not implemented by Emscripten
pub fn ___unlock(_ctx: &EmEnv, _what: c_int) { pub fn ___unlock(mut _ctx: ContextMut<'_, EmEnv>, _what: c_int) {
debug!("emscripten::___unlock {}", _what); debug!("emscripten::___unlock {}", _what);
} }
// NOTE: Not implemented by Emscripten // NOTE: Not implemented by Emscripten
pub fn ___wait(_ctx: &EmEnv, _which: u32, _varargs: u32, _three: u32, _four: u32) { pub fn ___wait(
mut _ctx: ContextMut<'_, EmEnv>,
_which: u32,
_varargs: u32,
_three: u32,
_four: u32,
) {
debug!("emscripten::___wait"); debug!("emscripten::___wait");
} }
pub fn _flock(_ctx: &EmEnv, _fd: u32, _op: u32) -> u32 { pub fn _flock(mut _ctx: ContextMut<'_, EmEnv>, _fd: u32, _op: u32) -> u32 {
debug!("emscripten::_flock"); debug!("emscripten::_flock");
0 0
} }

View File

@@ -1,5 +1,5 @@
macro_rules! emscripten_memory_pointer { macro_rules! emscripten_memory_pointer {
($memory:expr, $pointer:expr) => { ($ctx:expr, $memory:expr, $pointer:expr) => {
$memory.data_ptr().wrapping_add($pointer as usize) $memory.data_ptr(&$ctx).wrapping_add($pointer as usize)
}; };
} }

View File

@@ -1,110 +1,111 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn _llvm_copysign_f32(x: f64, y: f64) -> f64 { pub fn _llvm_copysign_f32(mut _ctx: ContextMut<'_, EmEnv>, x: f64, y: f64) -> f64 {
x.copysign(y) x.copysign(y)
} }
pub fn _llvm_copysign_f64(x: f64, y: f64) -> f64 { pub fn _llvm_copysign_f64(mut _ctx: ContextMut<'_, EmEnv>, x: f64, y: f64) -> f64 {
x.copysign(y) x.copysign(y)
} }
/// emscripten: _llvm_log10_f64 /// emscripten: _llvm_log10_f64
pub fn _llvm_log10_f64(value: f64) -> f64 { pub fn _llvm_log10_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
debug!("emscripten::_llvm_log10_f64"); debug!("emscripten::_llvm_log10_f64");
value.log10() value.log10()
} }
/// emscripten: _llvm_log2_f64 /// emscripten: _llvm_log2_f64
pub fn _llvm_log2_f64(value: f64) -> f64 { pub fn _llvm_log2_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
debug!("emscripten::_llvm_log2_f64"); debug!("emscripten::_llvm_log2_f64");
value.log2() value.log2()
} }
/// emscripten: _llvm_sin_f64 /// emscripten: _llvm_sin_f64
pub fn _llvm_sin_f64(value: f64) -> f64 { pub fn _llvm_sin_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
debug!("emscripten::_llvm_sin_f64"); debug!("emscripten::_llvm_sin_f64");
value.sin() value.sin()
} }
/// emscripten: _llvm_cos_f64 /// emscripten: _llvm_cos_f64
pub fn _llvm_cos_f64(value: f64) -> f64 { pub fn _llvm_cos_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
debug!("emscripten::_llvm_cos_f64"); debug!("emscripten::_llvm_cos_f64");
value.cos() value.cos()
} }
pub fn _llvm_log10_f32(_value: f64) -> f64 { pub fn _llvm_log10_f32(mut _ctx: ContextMut<'_, EmEnv>, _value: f64) -> f64 {
debug!("emscripten::_llvm_log10_f32"); debug!("emscripten::_llvm_log10_f32");
-1.0 -1.0
} }
pub fn _llvm_log2_f32(_value: f64) -> f64 { pub fn _llvm_log2_f32(mut _ctx: ContextMut<'_, EmEnv>, _value: f64) -> f64 {
debug!("emscripten::_llvm_log10_f32"); debug!("emscripten::_llvm_log10_f32");
-1.0 -1.0
} }
pub fn _llvm_exp2_f32(value: f32) -> f32 { pub fn _llvm_exp2_f32(mut _ctx: ContextMut<'_, EmEnv>, value: f32) -> f32 {
debug!("emscripten::_llvm_exp2_f32"); debug!("emscripten::_llvm_exp2_f32");
2f32.powf(value) 2f32.powf(value)
} }
pub fn _llvm_exp2_f64(value: f64) -> f64 { pub fn _llvm_exp2_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
debug!("emscripten::_llvm_exp2_f64"); debug!("emscripten::_llvm_exp2_f64");
2f64.powf(value) 2f64.powf(value)
} }
pub fn _llvm_trunc_f64(value: f64) -> f64 { pub fn _llvm_trunc_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
debug!("emscripten::_llvm_trunc_f64"); debug!("emscripten::_llvm_trunc_f64");
value.trunc() value.trunc()
} }
pub fn _llvm_fma_f64(value: f64, a: f64, b: f64) -> f64 { pub fn _llvm_fma_f64(mut _ctx: ContextMut<'_, EmEnv>, value: f64, a: f64, b: f64) -> f64 {
debug!("emscripten::_llvm_fma_f64"); debug!("emscripten::_llvm_fma_f64");
value.mul_add(a, b) value.mul_add(a, b)
} }
pub fn _emscripten_random(_ctx: &EmEnv) -> f64 { pub fn _emscripten_random(mut _ctx: ContextMut<'_, EmEnv>) -> f64 {
debug!("emscripten::_emscripten_random"); debug!("emscripten::_emscripten_random");
-1.0 -1.0
} }
// emscripten: asm2wasm.f64-rem // emscripten: asm2wasm.f64-rem
pub fn f64_rem(x: f64, y: f64) -> f64 { pub fn f64_rem(mut _ctx: ContextMut<'_, EmEnv>, x: f64, y: f64) -> f64 {
debug!("emscripten::f64-rem"); debug!("emscripten::f64-rem");
x % y x % y
} }
// emscripten: global.Math pow // emscripten: global.Math pow
pub fn pow(x: f64, y: f64) -> f64 { pub fn pow(mut _ctx: ContextMut<'_, EmEnv>, x: f64, y: f64) -> f64 {
x.powf(y) x.powf(y)
} }
// emscripten: global.Math exp // emscripten: global.Math exp
pub fn exp(value: f64) -> f64 { pub fn exp(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.exp() value.exp()
} }
// emscripten: global.Math log // emscripten: global.Math log
pub fn log(value: f64) -> f64 { pub fn log(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.ln() value.ln()
} }
// emscripten: global.Math sqrt // emscripten: global.Math sqrt
pub fn sqrt(value: f64) -> f64 { pub fn sqrt(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.sqrt() value.sqrt()
} }
// emscripten: global.Math floor // emscripten: global.Math floor
pub fn floor(value: f64) -> f64 { pub fn floor(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.floor() value.floor()
} }
// emscripten: global.Math fabs // emscripten: global.Math fabs
pub fn fabs(value: f64) -> f64 { pub fn fabs(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.abs() value.abs()
} }
// emscripten: asm2wasm.f64-to-int // emscripten: asm2wasm.f64-to-int
pub fn f64_to_int(value: f64) -> i32 { pub fn f64_to_int(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> i32 {
debug!("emscripten::f64_to_int {}", value); debug!("emscripten::f64_to_int {}", value);
value as i32 value as i32
} }

View File

@@ -3,26 +3,32 @@ use super::process::abort_with_message;
use crate::EmEnv; use crate::EmEnv;
use libc::{c_int, c_void, memcpy, size_t}; use libc::{c_int, c_void, memcpy, size_t};
// TODO: investigate max pages etc. probably in Wasm Common, maybe reexport // TODO: investigate max pages etc. probably in Wasm Common, maybe reexport
use wasmer::{Pages, WasmPtr, WASM_MAX_PAGES, WASM_MIN_PAGES, WASM_PAGE_SIZE}; use wasmer::{
AsContextMut, ContextMut, Pages, WasmPtr, WASM_MAX_PAGES, WASM_MIN_PAGES, WASM_PAGE_SIZE,
};
/// emscripten: _emscripten_memcpy_big /// emscripten: _emscripten_memcpy_big
pub fn _emscripten_memcpy_big(ctx: &EmEnv, dest: u32, src: u32, len: u32) -> u32 { pub fn _emscripten_memcpy_big(ctx: ContextMut<'_, EmEnv>, dest: u32, src: u32, len: u32) -> u32 {
debug!( debug!(
"emscripten::_emscripten_memcpy_big {}, {}, {}", "emscripten::_emscripten_memcpy_big {}, {}, {}",
dest, src, len dest, src, len
); );
let dest_addr = emscripten_memory_pointer!(ctx.memory(0), dest) as *mut c_void; let dest_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), dest) as *mut c_void;
let src_addr = emscripten_memory_pointer!(ctx.memory(0), src) as *mut c_void; let src_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), src) as *mut c_void;
unsafe { unsafe {
memcpy(dest_addr, src_addr, len as size_t); memcpy(dest_addr, src_addr, len as size_t);
} }
dest dest
} }
fn get_heap_size(ctx: &ContextMut<'_, EmEnv>) -> u32 {
ctx.data().memory(0).size(&ctx).bytes().0 as u32
}
/// emscripten: _emscripten_get_heap_size /// emscripten: _emscripten_get_heap_size
pub fn _emscripten_get_heap_size(ctx: &EmEnv) -> u32 { pub fn _emscripten_get_heap_size(ctx: ContextMut<'_, EmEnv>) -> u32 {
trace!("emscripten::_emscripten_get_heap_size"); trace!("emscripten::_emscripten_get_heap_size");
let result = ctx.memory(0).size().bytes().0 as u32; let result = get_heap_size(&ctx);
trace!("=> {}", result); trace!("=> {}", result);
result result
@@ -36,11 +42,9 @@ fn align_up(mut val: usize, multiple: usize) -> usize {
val val
} }
/// emscripten: _emscripten_resize_heap fn resize_heap(ctx: &mut ContextMut<'_, EmEnv>, requested_size: u32) -> u32 {
/// Note: this function only allows growing the size of heap
pub fn _emscripten_resize_heap(ctx: &EmEnv, requested_size: u32) -> u32 {
debug!("emscripten::_emscripten_resize_heap {}", requested_size); debug!("emscripten::_emscripten_resize_heap {}", requested_size);
let current_memory_pages = ctx.memory(0).size(); let current_memory_pages = ctx.data().memory(0).size(&ctx);
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
@@ -60,7 +64,11 @@ pub fn _emscripten_resize_heap(ctx: &EmEnv, requested_size: u32) -> u32 {
} }
let amount_to_grow = (new_size - current_memory as usize) / WASM_PAGE_SIZE; let amount_to_grow = (new_size - current_memory as usize) / WASM_PAGE_SIZE;
if let Ok(_pages_allocated) = ctx.memory(0).grow(Pages(amount_to_grow as u32)) { if let Ok(_pages_allocated) = ctx
.data()
.memory(0)
.grow(&mut ctx.as_context_mut(), Pages(amount_to_grow as u32))
{
debug!("{} pages allocated", _pages_allocated.0); debug!("{} pages allocated", _pages_allocated.0);
1 1
} else { } else {
@@ -68,19 +76,23 @@ pub fn _emscripten_resize_heap(ctx: &EmEnv, requested_size: u32) -> u32 {
} }
} }
/// emscripten: _emscripten_resize_heap
/// Note: this function only allows growing the size of heap
pub fn _emscripten_resize_heap(mut ctx: ContextMut<'_, EmEnv>, requested_size: u32) -> u32 {
resize_heap(&mut ctx, requested_size)
}
/// emscripten: sbrk /// emscripten: sbrk
pub fn sbrk(ctx: &EmEnv, increment: i32) -> i32 { pub fn sbrk(mut ctx: ContextMut<'_, EmEnv>, increment: i32) -> i32 {
debug!("emscripten::sbrk"); debug!("emscripten::sbrk");
// let old_dynamic_top = 0; // let old_dynamic_top = 0;
// let new_dynamic_top = 0; // let new_dynamic_top = 0;
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
let dynamictop_ptr = { let top_ptr = get_emscripten_data(&ctx).globals.dynamictop_ptr;
let globals = &get_emscripten_data(ctx).globals; let dynamictop_ptr = WasmPtr::<i32>::new(top_ptr).deref(&ctx, &memory);
WasmPtr::<i32>::new(globals.dynamictop_ptr).deref(&memory)
};
let old_dynamic_top = dynamictop_ptr.read().unwrap(); let old_dynamic_top = dynamictop_ptr.read().unwrap();
let new_dynamic_top: i32 = old_dynamic_top + increment; let new_dynamic_top: i32 = old_dynamic_top + increment;
let total_memory = _emscripten_get_heap_size(ctx) as i32; let total_memory = get_heap_size(&ctx) as i32;
debug!( debug!(
" => PTR {}, old: {}, new: {}, increment: {}, total: {}", " => PTR {}, old: {}, new: {}, increment: {}, total: {}",
dynamictop_ptr.offset(), dynamictop_ptr.offset(),
@@ -94,25 +106,27 @@ pub fn sbrk(ctx: &EmEnv, increment: i32) -> i32 {
return -1; return -1;
} }
if new_dynamic_top > total_memory { if new_dynamic_top > total_memory {
let resized = _emscripten_resize_heap(ctx, new_dynamic_top as u32); let resized = resize_heap(&mut ctx, new_dynamic_top as u32);
if resized == 0 { if resized == 0 {
return -1; return -1;
} }
} }
// re-borrow the top ptr
let dynamictop_ptr = WasmPtr::<i32>::new(top_ptr).deref(&ctx, &memory);
dynamictop_ptr.write(new_dynamic_top).unwrap(); dynamictop_ptr.write(new_dynamic_top).unwrap();
old_dynamic_top as _ old_dynamic_top as _
} }
/// emscripten: getTotalMemory /// emscripten: getTotalMemory
pub fn get_total_memory(_ctx: &EmEnv) -> u32 { pub fn get_total_memory(ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::get_total_memory"); debug!("emscripten::get_total_memory");
// instance.memories[0].current_pages() // instance.memories[0].current_pages()
// TODO: Fix implementation // TODO: Fix implementation
_ctx.memory(0).size().bytes().0 as u32 ctx.data().memory(0).size(&ctx).bytes().0 as u32
} }
/// emscripten: enlargeMemory /// emscripten: enlargeMemory
pub fn enlarge_memory(_ctx: &EmEnv) -> u32 { pub fn enlarge_memory(_ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::enlarge_memory"); debug!("emscripten::enlarge_memory");
// instance.memories[0].grow(100); // instance.memories[0].grow(100);
// TODO: Fix implementation // TODO: Fix implementation
@@ -120,7 +134,7 @@ pub fn enlarge_memory(_ctx: &EmEnv) -> u32 {
} }
/// emscripten: abortOnCannotGrowMemory /// emscripten: abortOnCannotGrowMemory
pub fn abort_on_cannot_grow_memory(ctx: &EmEnv, _requested_size: u32) -> u32 { pub fn abort_on_cannot_grow_memory(ctx: ContextMut<'_, EmEnv>, _requested_size: u32) -> u32 {
debug!( debug!(
"emscripten::abort_on_cannot_grow_memory {}", "emscripten::abort_on_cannot_grow_memory {}",
_requested_size _requested_size
@@ -130,32 +144,32 @@ pub fn abort_on_cannot_grow_memory(ctx: &EmEnv, _requested_size: u32) -> u32 {
} }
/// emscripten: abortOnCannotGrowMemory /// emscripten: abortOnCannotGrowMemory
pub fn abort_on_cannot_grow_memory_old(ctx: &EmEnv) -> u32 { pub fn abort_on_cannot_grow_memory_old(ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::abort_on_cannot_grow_memory"); debug!("emscripten::abort_on_cannot_grow_memory");
abort_with_message(ctx, "Cannot enlarge memory arrays!"); abort_with_message(ctx, "Cannot enlarge memory arrays!");
0 0
} }
/// emscripten: segfault /// emscripten: segfault
pub fn segfault(ctx: &EmEnv) { pub fn segfault(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::segfault"); debug!("emscripten::segfault");
abort_with_message(ctx, "segmentation fault"); abort_with_message(ctx, "segmentation fault");
} }
/// emscripten: alignfault /// emscripten: alignfault
pub fn alignfault(ctx: &EmEnv) { pub fn alignfault(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::alignfault"); debug!("emscripten::alignfault");
abort_with_message(ctx, "alignment fault"); abort_with_message(ctx, "alignment fault");
} }
/// emscripten: ftfault /// emscripten: ftfault
pub fn ftfault(ctx: &EmEnv) { pub fn ftfault(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::ftfault"); debug!("emscripten::ftfault");
abort_with_message(ctx, "Function table mask error"); abort_with_message(ctx, "Function table mask error");
} }
/// emscripten: ___map_file /// emscripten: ___map_file
pub fn ___map_file(_ctx: &EmEnv, _one: u32, _two: u32) -> c_int { pub fn ___map_file(_ctx: ContextMut<'_, EmEnv>, _one: u32, _two: u32) -> c_int {
debug!("emscripten::___map_file"); debug!("emscripten::___map_file");
// NOTE: TODO: Em returns -1 here as well. May need to implement properly // NOTE: TODO: Em returns -1 here as well. May need to implement properly
-1 -1

View File

@@ -6,34 +6,35 @@ type PidT = libc::pid_t;
type PidT = c_int; type PidT = c_int;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn abort_with_message(ctx: &EmEnv, message: &str) { pub fn abort_with_message(ctx: ContextMut<'_, EmEnv>, message: &str) {
debug!("emscripten::abort_with_message"); debug!("emscripten::abort_with_message");
println!("{}", message); println!("{}", message);
_abort(ctx); _abort(ctx);
} }
/// The name of this call is `abort` but we want to avoid conflicts with libc::abort /// The name of this call is `abort` but we want to avoid conflicts with libc::abort
pub fn em_abort(ctx: &EmEnv, arg: u32) { pub fn em_abort(ctx: ContextMut<'_, EmEnv>, arg: u32) {
debug!("emscripten::abort"); debug!("emscripten::abort");
eprintln!("Program aborted with value {}", arg); eprintln!("Program aborted with value {}", arg);
_abort(ctx); _abort(ctx);
} }
pub fn _abort(_ctx: &EmEnv) { pub fn _abort(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_abort"); debug!("emscripten::_abort");
unsafe { unsafe {
abort(); abort();
} }
} }
pub fn _prctl(ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _prctl(ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::_prctl"); debug!("emscripten::_prctl");
abort_with_message(ctx, "missing function: prctl"); abort_with_message(ctx, "missing function: prctl");
-1 -1
} }
pub fn _fork(_ctx: &EmEnv) -> PidT { pub fn _fork(_ctx: ContextMut<'_, EmEnv>) -> PidT {
debug!("emscripten::_fork"); debug!("emscripten::_fork");
// unsafe { // unsafe {
// fork() // fork()
@@ -41,132 +42,132 @@ pub fn _fork(_ctx: &EmEnv) -> PidT {
-1 -1
} }
pub fn _endgrent(_ctx: &EmEnv) { pub fn _endgrent(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_endgrent"); debug!("emscripten::_endgrent");
} }
pub fn _execve(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn _execve(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_execve"); debug!("emscripten::_execve");
-1 -1
} }
#[allow(unreachable_code)] #[allow(unreachable_code)]
pub fn _exit(_ctx: &EmEnv, status: c_int) { pub fn _exit(_ctx: ContextMut<'_, EmEnv>, status: c_int) {
// -> ! // -> !
debug!("emscripten::_exit {}", status); debug!("emscripten::_exit {}", status);
unsafe { exit(status) } unsafe { exit(status) }
} }
pub fn _kill(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn _kill(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_kill"); debug!("emscripten::_kill");
-1 -1
} }
pub fn _sched_yield(_ctx: &EmEnv) -> i32 { pub fn _sched_yield(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::_sched_yield"); debug!("emscripten::_sched_yield");
-1 -1
} }
pub fn _llvm_stacksave(_ctx: &EmEnv) -> i32 { pub fn _llvm_stacksave(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::_llvm_stacksave"); debug!("emscripten::_llvm_stacksave");
-1 -1
} }
pub fn _llvm_stackrestore(_ctx: &EmEnv, _one: i32) { pub fn _llvm_stackrestore(_ctx: ContextMut<'_, EmEnv>, _one: i32) {
debug!("emscripten::_llvm_stackrestore"); debug!("emscripten::_llvm_stackrestore");
} }
pub fn _raise(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _raise(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_raise"); debug!("emscripten::_raise");
-1 -1
} }
pub fn _sem_init(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn _sem_init(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_sem_init: {}, {}, {}", _one, _two, _three); debug!("emscripten::_sem_init: {}, {}, {}", _one, _two, _three);
0 0
} }
pub fn _sem_destroy(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _sem_destroy(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sem_destroy"); debug!("emscripten::_sem_destroy");
0 0
} }
pub fn _sem_post(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _sem_post(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sem_post"); debug!("emscripten::_sem_post");
-1 -1
} }
pub fn _sem_wait(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _sem_wait(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sem_post"); debug!("emscripten::_sem_post");
-1 -1
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _getgrent(_ctx: &EmEnv) -> c_int { pub fn _getgrent(_ctx: ContextMut<'_, EmEnv>) -> c_int {
debug!("emscripten::_getgrent"); debug!("emscripten::_getgrent");
-1 -1
} }
pub fn _setgrent(_ctx: &EmEnv) { pub fn _setgrent(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_setgrent"); debug!("emscripten::_setgrent");
} }
pub fn _setgroups(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn _setgroups(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_setgroups"); debug!("emscripten::_setgroups");
-1 -1
} }
pub fn _setitimer(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn _setitimer(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_setitimer"); debug!("emscripten::_setitimer");
-1 -1
} }
pub fn _usleep(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _usleep(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_usleep"); debug!("emscripten::_usleep");
-1 -1
} }
pub fn _nanosleep(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn _nanosleep(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_nanosleep"); debug!("emscripten::_nanosleep");
-1 -1
} }
pub fn _utime(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn _utime(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_utime"); debug!("emscripten::_utime");
-1 -1
} }
pub fn _utimes(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn _utimes(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_utimes"); debug!("emscripten::_utimes");
-1 -1
} }
pub fn _wait(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _wait(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_wait"); debug!("emscripten::_wait");
-1 -1
} }
pub fn _wait3(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn _wait3(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_wait3"); debug!("emscripten::_wait3");
-1 -1
} }
pub fn _wait4(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32, _d: i32) -> i32 { pub fn _wait4(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32, _d: i32) -> i32 {
debug!("emscripten::_wait4"); debug!("emscripten::_wait4");
-1 -1
} }
pub fn _waitid(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32, _d: i32) -> i32 { pub fn _waitid(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32, _d: i32) -> i32 {
debug!("emscripten::_waitid"); debug!("emscripten::_waitid");
-1 -1
} }
pub fn _waitpid(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn _waitpid(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_waitpid"); debug!("emscripten::_waitpid");
-1 -1
} }
pub fn abort_stack_overflow(ctx: &EmEnv, _what: c_int) { pub fn abort_stack_overflow(ctx: ContextMut<'_, EmEnv>, _what: c_int) {
debug!("emscripten::abort_stack_overflow"); debug!("emscripten::abort_stack_overflow");
// TODO: Message incomplete. Need to finish em runtime data first // TODO: Message incomplete. Need to finish em runtime data first
abort_with_message( abort_with_message(
@@ -175,24 +176,24 @@ pub fn abort_stack_overflow(ctx: &EmEnv, _what: c_int) {
); );
} }
pub fn _llvm_trap(ctx: &EmEnv) { pub fn _llvm_trap(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_llvm_trap"); debug!("emscripten::_llvm_trap");
abort_with_message(ctx, "abort!"); abort_with_message(ctx, "abort!");
} }
pub fn _llvm_eh_typeid_for(_ctx: &EmEnv, _type_info_addr: u32) -> i32 { pub fn _llvm_eh_typeid_for(_ctx: ContextMut<'_, EmEnv>, _type_info_addr: u32) -> i32 {
debug!("emscripten::_llvm_eh_typeid_for"); debug!("emscripten::_llvm_eh_typeid_for");
-1 -1
} }
pub fn _system(_ctx: &EmEnv, _one: i32) -> c_int { pub fn _system(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> c_int {
debug!("emscripten::_system"); debug!("emscripten::_system");
// TODO: May need to change this Em impl to a working version // TODO: May need to change this Em impl to a working version
eprintln!("Can't call external programs"); eprintln!("Can't call external programs");
EAGAIN EAGAIN
} }
pub fn _popen(_ctx: &EmEnv, _one: i32, _two: i32) -> c_int { pub fn _popen(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> c_int {
debug!("emscripten::_popen"); debug!("emscripten::_popen");
// TODO: May need to change this Em impl to a working version // TODO: May need to change this Em impl to a working version
eprintln!("Missing function: popen"); eprintln!("Missing function: popen");

View File

@@ -1,11 +1,17 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn _pthread_attr_destroy(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_attr_destroy(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_attr_destroy"); trace!("emscripten::_pthread_attr_destroy");
0 0
} }
pub fn _pthread_attr_getstack(_ctx: &EmEnv, _stackaddr: i32, _stacksize: i32, _other: i32) -> i32 { pub fn _pthread_attr_getstack(
mut _ctx: ContextMut<'_, EmEnv>,
_stackaddr: i32,
_stacksize: i32,
_other: i32,
) -> i32 {
trace!( trace!(
"emscripten::_pthread_attr_getstack({}, {}, {})", "emscripten::_pthread_attr_getstack({}, {}, {})",
_stackaddr, _stackaddr,
@@ -18,175 +24,175 @@ pub fn _pthread_attr_getstack(_ctx: &EmEnv, _stackaddr: i32, _stacksize: i32, _o
0 0
} }
pub fn _pthread_attr_init(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_attr_init(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_attr_init({})", _a); trace!("emscripten::_pthread_attr_init({})", _a);
0 0
} }
pub fn _pthread_attr_setstacksize(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_attr_setstacksize(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_attr_setstacksize"); trace!("emscripten::_pthread_attr_setstacksize");
0 0
} }
pub fn _pthread_cleanup_pop(_ctx: &EmEnv, _a: i32) { pub fn _pthread_cleanup_pop(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) {
trace!("emscripten::_pthread_cleanup_pop"); trace!("emscripten::_pthread_cleanup_pop");
} }
pub fn _pthread_cleanup_push(_ctx: &EmEnv, _a: i32, _b: i32) { pub fn _pthread_cleanup_push(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) {
trace!("emscripten::_pthread_cleanup_push"); trace!("emscripten::_pthread_cleanup_push");
} }
pub fn _pthread_cond_destroy(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_cond_destroy(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_cond_destroy"); trace!("emscripten::_pthread_cond_destroy");
0 0
} }
pub fn _pthread_cond_init(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_cond_init(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_cond_init"); trace!("emscripten::_pthread_cond_init");
0 0
} }
pub fn _pthread_cond_signal(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_cond_signal(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_cond_signal"); trace!("emscripten::_pthread_cond_signal");
0 0
} }
pub fn _pthread_cond_timedwait(_ctx: &EmEnv, _a: i32, _b: i32, _c: i32) -> i32 { pub fn _pthread_cond_timedwait(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32, _c: i32) -> i32 {
trace!("emscripten::_pthread_cond_timedwait"); trace!("emscripten::_pthread_cond_timedwait");
0 0
} }
pub fn _pthread_cond_wait(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_cond_wait(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_cond_wait"); trace!("emscripten::_pthread_cond_wait");
0 0
} }
pub fn _pthread_condattr_destroy(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_condattr_destroy(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_condattr_destroy"); trace!("emscripten::_pthread_condattr_destroy");
0 0
} }
pub fn _pthread_condattr_init(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_condattr_init(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_condattr_init"); trace!("emscripten::_pthread_condattr_init");
0 0
} }
pub fn _pthread_condattr_setclock(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_condattr_setclock(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_condattr_setclock"); trace!("emscripten::_pthread_condattr_setclock");
0 0
} }
pub fn _pthread_create(_ctx: &EmEnv, _a: i32, _b: i32, _c: i32, _d: i32) -> i32 { pub fn _pthread_create(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32, _c: i32, _d: i32) -> i32 {
trace!("emscripten::_pthread_create"); trace!("emscripten::_pthread_create");
// 11 seems to mean "no" // 11 seems to mean "no"
11 11
} }
pub fn _pthread_detach(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_detach(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_detach"); trace!("emscripten::_pthread_detach");
0 0
} }
pub fn _pthread_equal(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_equal(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_equal"); trace!("emscripten::_pthread_equal");
0 0
} }
pub fn _pthread_exit(_ctx: &EmEnv, _a: i32) { pub fn _pthread_exit(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) {
trace!("emscripten::_pthread_exit"); trace!("emscripten::_pthread_exit");
} }
pub fn _pthread_getattr_np(_ctx: &EmEnv, _thread: i32, _attr: i32) -> i32 { pub fn _pthread_getattr_np(mut _ctx: ContextMut<'_, EmEnv>, _thread: i32, _attr: i32) -> i32 {
trace!("emscripten::_pthread_getattr_np({}, {})", _thread, _attr); trace!("emscripten::_pthread_getattr_np({}, {})", _thread, _attr);
0 0
} }
pub fn _pthread_getspecific(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_getspecific(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_getspecific"); trace!("emscripten::_pthread_getspecific");
0 0
} }
pub fn _pthread_join(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_join(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_join"); trace!("emscripten::_pthread_join");
0 0
} }
pub fn _pthread_self(_ctx: &EmEnv) -> i32 { pub fn _pthread_self(mut _ctx: ContextMut<'_, EmEnv>) -> i32 {
trace!("emscripten::_pthread_self"); trace!("emscripten::_pthread_self");
0 0
} }
pub fn _pthread_key_create(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_key_create(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_key_create"); trace!("emscripten::_pthread_key_create");
0 0
} }
pub fn _pthread_mutex_destroy(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_mutex_destroy(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_mutex_destroy"); trace!("emscripten::_pthread_mutex_destroy");
0 0
} }
pub fn _pthread_mutex_init(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_mutex_init(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_mutex_init"); trace!("emscripten::_pthread_mutex_init");
0 0
} }
pub fn _pthread_mutexattr_destroy(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_mutexattr_destroy(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_mutexattr_destroy"); trace!("emscripten::_pthread_mutexattr_destroy");
0 0
} }
pub fn _pthread_mutexattr_init(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_mutexattr_init(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_mutexattr_init"); trace!("emscripten::_pthread_mutexattr_init");
0 0
} }
pub fn _pthread_mutexattr_settype(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_mutexattr_settype(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_mutexattr_settype"); trace!("emscripten::_pthread_mutexattr_settype");
0 0
} }
pub fn _pthread_once(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_once(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_once"); trace!("emscripten::_pthread_once");
0 0
} }
pub fn _pthread_rwlock_destroy(_ctx: &EmEnv, _rwlock: i32) -> i32 { pub fn _pthread_rwlock_destroy(mut _ctx: ContextMut<'_, EmEnv>, _rwlock: i32) -> i32 {
trace!("emscripten::_pthread_rwlock_destroy({})", _rwlock); trace!("emscripten::_pthread_rwlock_destroy({})", _rwlock);
0 0
} }
pub fn _pthread_rwlock_init(_ctx: &EmEnv, _rwlock: i32, _attr: i32) -> i32 { pub fn _pthread_rwlock_init(mut _ctx: ContextMut<'_, EmEnv>, _rwlock: i32, _attr: i32) -> i32 {
trace!("emscripten::_pthread_rwlock_init({}, {})", _rwlock, _attr); trace!("emscripten::_pthread_rwlock_init({}, {})", _rwlock, _attr);
0 0
} }
pub fn _pthread_rwlock_rdlock(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_rwlock_rdlock(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_rwlock_rdlock"); trace!("emscripten::_pthread_rwlock_rdlock");
0 0
} }
pub fn _pthread_rwlock_unlock(_ctx: &EmEnv, _a: i32) -> i32 { pub fn _pthread_rwlock_unlock(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
trace!("emscripten::_pthread_rwlock_unlock"); trace!("emscripten::_pthread_rwlock_unlock");
0 0
} }
pub fn _pthread_rwlock_wrlock(_ctx: &EmEnv, _rwlock: i32) -> i32 { pub fn _pthread_rwlock_wrlock(mut _ctx: ContextMut<'_, EmEnv>, _rwlock: i32) -> i32 {
trace!("emscripten::_pthread_rwlock_wrlock({})", _rwlock); trace!("emscripten::_pthread_rwlock_wrlock({})", _rwlock);
0 0
} }
pub fn _pthread_setcancelstate(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_setcancelstate(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_setcancelstate"); trace!("emscripten::_pthread_setcancelstate");
0 0
} }
pub fn _pthread_setspecific(_ctx: &EmEnv, _a: i32, _b: i32) -> i32 { pub fn _pthread_setspecific(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
trace!("emscripten::_pthread_setspecific"); trace!("emscripten::_pthread_setspecific");
0 0
} }
pub fn _pthread_sigmask(_ctx: &EmEnv, _a: i32, _b: i32, _c: i32) -> i32 { pub fn _pthread_sigmask(mut _ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32, _c: i32) -> i32 {
trace!("emscripten::_pthread_sigmask"); trace!("emscripten::_pthread_sigmask");
0 0
} }

View File

@@ -1,47 +1,48 @@
// use super::varargs::VarArgs; // use super::varargs::VarArgs;
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _sigemptyset(ctx: &EmEnv, set: u32) -> i32 { pub fn _sigemptyset(ctx: ContextMut<'_, EmEnv>, set: u32) -> i32 {
debug!("emscripten::_sigemptyset"); debug!("emscripten::_sigemptyset");
let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32; let set_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), set) as *mut u32;
unsafe { unsafe {
*set_addr = 0; *set_addr = 0;
} }
0 0
} }
pub fn _sigaction(_ctx: &EmEnv, _signum: u32, _act: u32, _oldact: u32) -> i32 { pub fn _sigaction(_ctx: ContextMut<'_, EmEnv>, _signum: u32, _act: u32, _oldact: u32) -> i32 {
debug!("emscripten::_sigaction {}, {}, {}", _signum, _act, _oldact); debug!("emscripten::_sigaction {}, {}, {}", _signum, _act, _oldact);
0 0
} }
pub fn _siginterrupt(_ctx: &EmEnv, _a: u32, _b: u32) -> i32 { pub fn _siginterrupt(_ctx: ContextMut<'_, EmEnv>, _a: u32, _b: u32) -> i32 {
debug!("emscripten::_siginterrupt {}, {}", _a, _b); debug!("emscripten::_siginterrupt {}, {}", _a, _b);
0 0
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _sigaddset(ctx: &EmEnv, set: u32, signum: u32) -> i32 { pub fn _sigaddset(ctx: ContextMut<'_, EmEnv>, set: u32, signum: u32) -> i32 {
debug!("emscripten::_sigaddset {}, {}", set, signum); debug!("emscripten::_sigaddset {}, {}", set, signum);
let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32; let set_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), set) as *mut u32;
unsafe { unsafe {
*set_addr |= 1 << (signum - 1); *set_addr |= 1 << (signum - 1);
} }
0 0
} }
pub fn _sigsuspend(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _sigsuspend(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sigsuspend"); debug!("emscripten::_sigsuspend");
-1 -1
} }
pub fn _sigprocmask(_ctx: &EmEnv, _one: i32, _two: i32, _three: i32) -> i32 { pub fn _sigprocmask(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_sigprocmask"); debug!("emscripten::_sigprocmask");
0 0
} }
pub fn _signal(_ctx: &EmEnv, _sig: u32, _two: i32) -> i32 { pub fn _signal(_ctx: ContextMut<'_, EmEnv>, _sig: u32, _two: i32) -> i32 {
debug!("emscripten::_signal ({})", _sig); debug!("emscripten::_signal ({})", _sig);
0 0
} }

View File

@@ -48,54 +48,54 @@ use super::env;
#[allow(unused_imports)] #[allow(unused_imports)]
use std::io::Error; use std::io::Error;
use std::slice; use std::slice;
use wasmer::WasmPtr; use wasmer::{AsContextMut, ContextMut, WasmPtr};
/// exit /// exit
pub fn ___syscall1(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) { pub fn ___syscall1(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) {
debug!("emscripten::___syscall1 (exit) {}", _which); debug!("emscripten::___syscall1 (exit) {}", _which);
let status: i32 = varargs.get(ctx); let status: i32 = varargs.get(&ctx);
unsafe { unsafe {
exit(status); exit(status);
} }
} }
/// read /// read
pub fn ___syscall3(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall3(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
// -> ssize_t // -> ssize_t
debug!("emscripten::___syscall3 (read) {}", _which); debug!("emscripten::___syscall3 (read) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(&ctx);
let count: i32 = varargs.get(ctx); let count: i32 = varargs.get(&ctx);
debug!("=> fd: {}, buf_offset: {}, count: {}", fd, buf, count); debug!("=> fd: {}, buf_offset: {}, count: {}", fd, buf, count);
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_void; let buf_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *mut c_void;
let ret = unsafe { read(fd, buf_addr, count as _) }; let ret = unsafe { read(fd, buf_addr, count as _) };
debug!("=> ret: {}", ret); debug!("=> ret: {}", ret);
ret as _ ret as _
} }
/// write /// write
pub fn ___syscall4(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall4(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall4 (write) {}", _which); debug!("emscripten::___syscall4 (write) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let buf: i32 = varargs.get(ctx); let buf: i32 = varargs.get(&ctx);
let count: i32 = varargs.get(ctx); let count: i32 = varargs.get(&ctx);
debug!("=> fd: {}, buf: {}, count: {}", fd, buf, count); debug!("=> fd: {}, buf: {}, count: {}", fd, buf, count);
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *const c_void; let buf_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *const c_void;
unsafe { write(fd, buf_addr, count as _) as i32 } unsafe { write(fd, buf_addr, count as _) as i32 }
} }
/// close /// close
pub fn ___syscall6(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall6(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall6 (close) {}", _which); debug!("emscripten::___syscall6 (close) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
debug!("fd: {}", fd); debug!("fd: {}", fd);
unsafe { close(fd) } unsafe { close(fd) }
} }
// chdir // chdir
pub fn ___syscall12(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall12(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall12 (chdir) {}", _which); debug!("emscripten::___syscall12 (chdir) {}", _which);
let path_ptr = varargs.get_str(ctx); let path_ptr = varargs.get_str(&ctx);
let real_path_owned = get_cstr_path(ctx, path_ptr as *const _); let real_path_owned = get_cstr_path(ctx, path_ptr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
@@ -111,63 +111,63 @@ pub fn ___syscall12(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
ret ret
} }
pub fn ___syscall10(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall10(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall10"); debug!("emscripten::___syscall10");
-1 -1
} }
pub fn ___syscall14(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall14(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall14"); debug!("emscripten::___syscall14");
-1 -1
} }
pub fn ___syscall15(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall15(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall15"); debug!("emscripten::___syscall15");
-1 -1
} }
// getpid // getpid
pub fn ___syscall20(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall20(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall20 (getpid)"); debug!("emscripten::___syscall20 (getpid)");
unsafe { getpid() } unsafe { getpid() }
} }
pub fn ___syscall21(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall21(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall21"); debug!("emscripten::___syscall21");
-1 -1
} }
pub fn ___syscall25(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall25(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall25"); debug!("emscripten::___syscall25");
-1 -1
} }
pub fn ___syscall29(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall29(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall29"); debug!("emscripten::___syscall29");
-1 -1
} }
pub fn ___syscall32(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall32(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall32"); debug!("emscripten::___syscall32");
-1 -1
} }
pub fn ___syscall33(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall33(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall33"); debug!("emscripten::___syscall33");
-1 -1
} }
pub fn ___syscall36(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall36(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall36"); debug!("emscripten::___syscall36");
-1 -1
} }
// rename // rename
pub fn ___syscall38(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 { pub fn ___syscall38(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall38 (rename)"); debug!("emscripten::___syscall38 (rename)");
let old_path = varargs.get_str(ctx); let old_path = varargs.get_str(&ctx);
let new_path = varargs.get_str(ctx); let new_path = varargs.get_str(&ctx);
let real_old_path_owned = get_cstr_path(ctx, old_path as *const _); let real_old_path_owned = get_cstr_path(ctx.as_context_mut(), old_path as *const _);
let real_old_path = if let Some(ref rp) = real_old_path_owned { let real_old_path = if let Some(ref rp) = real_old_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
@@ -190,9 +190,9 @@ pub fn ___syscall38(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
} }
// rmdir // rmdir
pub fn ___syscall40(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall40(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall40 (rmdir)"); debug!("emscripten::___syscall40 (rmdir)");
let pathname_addr = varargs.get_str(ctx); let pathname_addr = varargs.get_str(&ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _); let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
@@ -203,16 +203,16 @@ pub fn ___syscall40(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
} }
// pipe // pipe
pub fn ___syscall42(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall42(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall42 (pipe)"); debug!("emscripten::___syscall42 (pipe)");
// offset to a file descriptor, which contains a read end and write end, 2 integers // offset to a file descriptor, which contains a read end and write end, 2 integers
let fd_offset: u32 = varargs.get(ctx); let fd_offset: u32 = varargs.get(&ctx);
let emscripten_memory = ctx.memory(0); let emscripten_memory = ctx.data().memory(0);
// convert the file descriptor into a vec with two slots // convert the file descriptor into a vec with two slots
let mut fd_vec: [c_int; 2] = WasmPtr::<[c_int; 2]>::new(fd_offset) let mut fd_vec: [c_int; 2] = WasmPtr::<[c_int; 2]>::new(fd_offset)
.deref(&emscripten_memory) .deref(&ctx, &emscripten_memory)
.read() .read()
.unwrap(); .unwrap();
@@ -230,133 +230,133 @@ pub fn ___syscall42(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
result result
} }
pub fn ___syscall51(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall51(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall51"); debug!("emscripten::___syscall51");
-1 -1
} }
pub fn ___syscall52(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall52(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall52"); debug!("emscripten::___syscall52");
-1 -1
} }
pub fn ___syscall53(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall53(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall53"); debug!("emscripten::___syscall53");
-1 -1
} }
pub fn ___syscall60(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall60(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall60"); debug!("emscripten::___syscall60");
-1 -1
} }
// dup2 // dup2
pub fn ___syscall63(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall63(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall63 (dup2) {}", _which); debug!("emscripten::___syscall63 (dup2) {}", _which);
let src: i32 = varargs.get(ctx); let src: i32 = varargs.get(&ctx);
let dst: i32 = varargs.get(ctx); let dst: i32 = varargs.get(&ctx);
unsafe { dup2(src, dst) } unsafe { dup2(src, dst) }
} }
// getppid // getppid
pub fn ___syscall64(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall64(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall64 (getppid)"); debug!("emscripten::___syscall64 (getppid)");
unsafe { getpid() } unsafe { getpid() }
} }
pub fn ___syscall66(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall66(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall66"); debug!("emscripten::___syscall66");
-1 -1
} }
pub fn ___syscall75(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall75(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall75"); debug!("emscripten::___syscall75");
-1 -1
} }
pub fn ___syscall91(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall91(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall91 - stub"); debug!("emscripten::___syscall91 - stub");
0 0
} }
pub fn ___syscall96(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall96(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall96"); debug!("emscripten::___syscall96");
-1 -1
} }
pub fn ___syscall97(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall97(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall97"); debug!("emscripten::___syscall97");
-1 -1
} }
pub fn ___syscall110(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall110(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall110"); debug!("emscripten::___syscall110");
-1 -1
} }
pub fn ___syscall121(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall121(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall121"); debug!("emscripten::___syscall121");
-1 -1
} }
pub fn ___syscall125(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall125(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall125"); debug!("emscripten::___syscall125");
-1 -1
} }
pub fn ___syscall133(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall133(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall133"); debug!("emscripten::___syscall133");
-1 -1
} }
pub fn ___syscall144(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall144(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall144"); debug!("emscripten::___syscall144");
-1 -1
} }
pub fn ___syscall147(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall147(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall147"); debug!("emscripten::___syscall147");
-1 -1
} }
pub fn ___syscall150(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall150(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall150"); debug!("emscripten::___syscall150");
-1 -1
} }
pub fn ___syscall151(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall151(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall151"); debug!("emscripten::___syscall151");
-1 -1
} }
pub fn ___syscall152(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall152(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall152"); debug!("emscripten::___syscall152");
-1 -1
} }
pub fn ___syscall153(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall153(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall153"); debug!("emscripten::___syscall153");
-1 -1
} }
pub fn ___syscall163(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall163(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall163"); debug!("emscripten::___syscall163");
-1 -1
} }
// getcwd // getcwd
pub fn ___syscall183(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 { pub fn ___syscall183(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall183"); debug!("emscripten::___syscall183");
let buf_offset: WasmPtr<libc::c_char> = varargs.get(ctx); let buf_offset: WasmPtr<libc::c_char> = varargs.get(&ctx);
let _size: c_int = varargs.get(ctx); let _size: c_int = varargs.get(&ctx);
let path = get_current_directory(ctx); let path = get_current_directory(ctx.as_context_mut());
let path_string = path.unwrap().display().to_string(); let path_string = path.unwrap().display().to_string();
let len = path_string.len(); let len = path_string.len();
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
let buf_writer = buf_offset.slice(&memory, len as u32 + 1).unwrap(); let buf_writer = buf_offset.slice(&ctx, &memory, len as u32 + 1).unwrap();
for (i, byte) in path_string.bytes().enumerate() { for (i, byte) in path_string.bytes().enumerate() {
buf_writer.index(i as u64).write(byte as _).unwrap(); buf_writer.index(i as u64).write(byte as _).unwrap();
} }
@@ -365,26 +365,26 @@ pub fn ___syscall183(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
} }
// mmap2 // mmap2
pub fn ___syscall192(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall192(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall192 (mmap2) {}", _which); debug!("emscripten::___syscall192 (mmap2) {}", _which);
let _addr: i32 = varargs.get(ctx); let _addr: i32 = varargs.get(&ctx);
let len: u32 = varargs.get(ctx); let len: u32 = varargs.get(&ctx);
let _prot: i32 = varargs.get(ctx); let _prot: i32 = varargs.get(&ctx);
let _flags: i32 = varargs.get(ctx); let _flags: i32 = varargs.get(&ctx);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let _off: i32 = varargs.get(ctx); let _off: i32 = varargs.get(&ctx);
debug!( debug!(
"=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}", "=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}",
_addr, len, _prot, _flags, fd, _off _addr, len, _prot, _flags, fd, _off
); );
if fd == -1 { if fd == -1 {
let ptr = env::call_memalign(ctx, 16384, len); let ptr = env::call_memalign(ctx.as_context_mut(), 16384, len);
if ptr == 0 { if ptr == 0 {
// ENOMEM // ENOMEM
return -12; return -12;
} }
let real_ptr = emscripten_memory_pointer!(ctx.memory(0), ptr) as *const u8; let real_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), ptr) as *const u8;
env::call_memset(ctx, ptr, 0, len); env::call_memset(ctx, ptr, 0, len);
for i in 0..(len as usize) { for i in 0..(len as usize) {
unsafe { unsafe {
@@ -400,19 +400,19 @@ pub fn ___syscall192(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
/// lseek /// lseek
pub fn ___syscall140(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall140(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
// -> c_int // -> c_int
debug!("emscripten::___syscall140 (lseek) {}", _which); debug!("emscripten::___syscall140 (lseek) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let _offset_high: u32 = varargs.get(ctx); // We don't use the offset high as emscripten skips it let _offset_high: u32 = varargs.get(&ctx); // We don't use the offset high as emscripten skips it
let offset_low: u32 = varargs.get(ctx); let offset_low: u32 = varargs.get(&ctx);
let result_ptr_value: WasmPtr<i64> = varargs.get(ctx); let result_ptr_value: WasmPtr<i64> = varargs.get(&ctx);
let whence: i32 = varargs.get(ctx); let whence: i32 = varargs.get(&ctx);
let offset = offset_low; let offset = offset_low;
let ret = unsafe { lseek(fd, offset as _, whence) as i64 }; let ret = unsafe { lseek(fd, offset as _, whence) as i64 };
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
let result_ptr = result_ptr_value.deref(&memory); let result_ptr = result_ptr_value.deref(&ctx, &memory);
result_ptr.write(ret).unwrap(); result_ptr.write(ret).unwrap();
debug!( debug!(
@@ -429,13 +429,13 @@ pub fn ___syscall140(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
/// readv /// readv
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn ___syscall145(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 { pub fn ___syscall145(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> i32 {
// -> ssize_t // -> ssize_t
debug!("emscripten::___syscall145 (readv) {}", _which); debug!("emscripten::___syscall145 (readv) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let iov: i32 = varargs.get(ctx); let iov: i32 = varargs.get(&ctx);
let iovcnt: i32 = varargs.get(ctx); let iovcnt: i32 = varargs.get(&ctx);
#[repr(C)] #[repr(C)]
struct GuestIovec { struct GuestIovec {
@@ -448,9 +448,11 @@ pub fn ___syscall145(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
unsafe { unsafe {
for i in 0..iovcnt { for i in 0..iovcnt {
let guest_iov_addr = let guest_iov_addr =
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec; emscripten_memory_pointer!(ctx, ctx.data().memory(0), (iov + i * 8))
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base) as *mut GuestIovec;
as *mut c_void; let iov_base =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), (*guest_iov_addr).iov_base)
as *mut c_void;
let iov_len = (*guest_iov_addr).iov_len as _; let iov_len = (*guest_iov_addr).iov_len as _;
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len); // debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
let curr = read(fd, iov_base, iov_len); let curr = read(fd, iov_base, iov_len);
@@ -466,12 +468,12 @@ pub fn ___syscall145(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
// writev // writev
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn ___syscall146(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall146(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
// -> ssize_t // -> ssize_t
debug!("emscripten::___syscall146 (writev) {}", _which); debug!("emscripten::___syscall146 (writev) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let iov: i32 = varargs.get(ctx); let iov: i32 = varargs.get(&ctx);
let iovcnt: i32 = varargs.get(ctx); let iovcnt: i32 = varargs.get(&ctx);
#[repr(C)] #[repr(C)]
struct GuestIovec { struct GuestIovec {
@@ -484,9 +486,11 @@ pub fn ___syscall146(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
for i in 0..iovcnt { for i in 0..iovcnt {
unsafe { unsafe {
let guest_iov_addr = let guest_iov_addr =
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec; emscripten_memory_pointer!(ctx, ctx.data().memory(0), (iov + i * 8))
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base) as *mut GuestIovec;
as *const c_void; let iov_base =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), (*guest_iov_addr).iov_base)
as *const c_void;
let iov_len = (*guest_iov_addr).iov_len as _; let iov_len = (*guest_iov_addr).iov_len as _;
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len); // debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
let curr = write(fd, iov_base, iov_len); let curr = write(fd, iov_base, iov_len);
@@ -507,14 +511,14 @@ pub fn ___syscall146(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
ret as _ ret as _
} }
pub fn ___syscall191(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall191(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
let _resource: i32 = varargs.get(ctx); let _resource: i32 = varargs.get(&ctx);
debug!( debug!(
"emscripten::___syscall191 - mostly stub, resource: {}", "emscripten::___syscall191 - mostly stub, resource: {}",
_resource _resource
); );
let rlim_emptr: i32 = varargs.get(ctx); let rlim_emptr: i32 = varargs.get(&ctx);
let rlim_ptr = emscripten_memory_pointer!(ctx.memory(0), rlim_emptr) as *mut u8; let rlim_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), rlim_emptr) as *mut u8;
let rlim = unsafe { slice::from_raw_parts_mut(rlim_ptr, 16) }; let rlim = unsafe { slice::from_raw_parts_mut(rlim_ptr, 16) };
// set all to RLIM_INIFINTY // set all to RLIM_INIFINTY
@@ -524,18 +528,18 @@ pub fn ___syscall191(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
0 0
} }
pub fn ___syscall193(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall193(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall193"); debug!("emscripten::___syscall193");
-1 -1
} }
// stat64 // stat64
pub fn ___syscall195(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall195(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall195 (stat64) {}", _which); debug!("emscripten::___syscall195 (stat64) {}", _which);
let pathname_addr = varargs.get_str(ctx); let pathname_addr = varargs.get_str(&ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(&ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _); let real_path_owned = get_cstr_path(ctx.as_context_mut(), pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
@@ -561,11 +565,11 @@ pub fn ___syscall195(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
// fstat64 // fstat64
pub fn ___syscall197(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall197(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall197 (fstat64) {}", _which); debug!("emscripten::___syscall197 (fstat64) {}", _which);
let fd: c_int = varargs.get(ctx); let fd: c_int = varargs.get(&ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(&ctx);
unsafe { unsafe {
let mut stat = std::mem::zeroed(); let mut stat = std::mem::zeroed();
@@ -580,135 +584,135 @@ pub fn ___syscall197(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
0 0
} }
pub fn ___syscall209(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall209(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall209"); debug!("emscripten::___syscall209");
-1 -1
} }
pub fn ___syscall211(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall211(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall211"); debug!("emscripten::___syscall211");
-1 -1
} }
pub fn ___syscall218(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall218(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall218"); debug!("emscripten::___syscall218");
-1 -1
} }
pub fn ___syscall268(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall268(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall268"); debug!("emscripten::___syscall268");
-1 -1
} }
pub fn ___syscall269(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall269(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall269"); debug!("emscripten::___syscall269");
-1 -1
} }
pub fn ___syscall272(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall272(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall272"); debug!("emscripten::___syscall272");
-1 -1
} }
pub fn ___syscall295(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall295(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall295"); debug!("emscripten::___syscall295");
-1 -1
} }
pub fn ___syscall296(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall296(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall296"); debug!("emscripten::___syscall296");
-1 -1
} }
pub fn ___syscall297(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall297(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall297"); debug!("emscripten::___syscall297");
-1 -1
} }
pub fn ___syscall298(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall298(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall298"); debug!("emscripten::___syscall298");
-1 -1
} }
pub fn ___syscall300(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall300(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall300"); debug!("emscripten::___syscall300");
-1 -1
} }
pub fn ___syscall301(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall301(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall301"); debug!("emscripten::___syscall301");
-1 -1
} }
pub fn ___syscall302(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall302(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall302"); debug!("emscripten::___syscall302");
-1 -1
} }
pub fn ___syscall303(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall303(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall303"); debug!("emscripten::___syscall303");
-1 -1
} }
pub fn ___syscall304(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall304(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall304"); debug!("emscripten::___syscall304");
-1 -1
} }
pub fn ___syscall305(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall305(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall305"); debug!("emscripten::___syscall305");
-1 -1
} }
pub fn ___syscall306(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall306(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall306"); debug!("emscripten::___syscall306");
-1 -1
} }
pub fn ___syscall307(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall307(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall307"); debug!("emscripten::___syscall307");
-1 -1
} }
pub fn ___syscall308(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall308(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall308"); debug!("emscripten::___syscall308");
-1 -1
} }
// utimensat // utimensat
pub fn ___syscall320(_ctx: &EmEnv, _which: c_int, mut _varargs: VarArgs) -> c_int { pub fn ___syscall320(_ctx: ContextMut<'_, EmEnv>, _which: c_int, mut _varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall320 (utimensat), {}", _which); debug!("emscripten::___syscall320 (utimensat), {}", _which);
0 0
} }
pub fn ___syscall331(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall331(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall331"); debug!("emscripten::___syscall331");
-1 -1
} }
pub fn ___syscall333(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall333(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall333"); debug!("emscripten::___syscall333");
-1 -1
} }
pub fn ___syscall334(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall334(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall334"); debug!("emscripten::___syscall334");
-1 -1
} }
pub fn ___syscall337(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall337(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall337"); debug!("emscripten::___syscall337");
-1 -1
} }
// prlimit64 // prlimit64
pub fn ___syscall340(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall340(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall340 (prlimit64), {}", _which); debug!("emscripten::___syscall340 (prlimit64), {}", _which);
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway. // NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway.
let _pid: i32 = varargs.get(ctx); let _pid: i32 = varargs.get(&ctx);
let resource: i32 = varargs.get(ctx); let resource: i32 = varargs.get(&ctx);
let _new_limit: u32 = varargs.get(ctx); let _new_limit: u32 = varargs.get(&ctx);
let old_limit: u32 = varargs.get(ctx); let old_limit: u32 = varargs.get(&ctx);
let val = match resource { let val = match resource {
// RLIMIT_NOFILE // RLIMIT_NOFILE
@@ -718,7 +722,7 @@ pub fn ___syscall340(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
if old_limit != 0 { if old_limit != 0 {
// just report no limits // just report no limits
let buf_ptr = emscripten_memory_pointer!(ctx.memory(0), old_limit) as *mut u8; let buf_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), old_limit) as *mut u8;
let buf = unsafe { slice::from_raw_parts_mut(buf_ptr, 16) }; let buf = unsafe { slice::from_raw_parts_mut(buf_ptr, 16) };
LittleEndian::write_i64(&mut *buf, val); LittleEndian::write_i64(&mut *buf, val);
@@ -728,7 +732,7 @@ pub fn ___syscall340(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
0 0
} }
pub fn ___syscall345(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall345(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall345"); debug!("emscripten::___syscall345");
-1 -1
} }

View File

@@ -81,7 +81,7 @@ use libc::{
// TCGETS, // TCGETS,
// TCSETSW, // TCSETSW,
}; };
use wasmer::{ValueType, WasmPtr}; use wasmer::{AsContextMut, ContextMut, ValueType, WasmPtr};
// They are not exposed in in Rust libc in macOS // They are not exposed in in Rust libc in macOS
const TCGETS: u64 = 0x5401; const TCGETS: u64 = 0x5401;
@@ -157,12 +157,12 @@ use libc::SO_NOSIGPIPE;
const SO_NOSIGPIPE: c_int = 0; const SO_NOSIGPIPE: c_int = 0;
/// open /// open
pub fn ___syscall5(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall5(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall5 (open) {}", _which); debug!("emscripten::___syscall5 (open) {}", _which);
let pathname_addr = varargs.get_str(ctx); let pathname_addr = varargs.get_str(&ctx);
let flags: i32 = varargs.get(ctx); let flags: i32 = varargs.get(&ctx);
let mode: u32 = varargs.get(ctx); let mode: u32 = varargs.get(&ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _); let real_path_owned = utils::get_cstr_path(ctx.as_context_mut(), pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
@@ -181,11 +181,11 @@ pub fn ___syscall5(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
} }
/// link /// link
pub fn ___syscall9(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall9(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall9 (link) {}", _which); debug!("emscripten::___syscall9 (link) {}", _which);
let oldname_ptr = varargs.get_str(ctx); let oldname_ptr = varargs.get_str(&ctx);
let newname_ptr = varargs.get_str(ctx); let newname_ptr = varargs.get_str(&ctx);
let result = unsafe { link(oldname_ptr, newname_ptr) }; let result = unsafe { link(oldname_ptr, newname_ptr) };
debug!( debug!(
"=> oldname: {}, newname: {}, result: {}", "=> oldname: {}, newname: {}, result: {}",
@@ -197,30 +197,30 @@ pub fn ___syscall9(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
} }
/// getrusage /// getrusage
pub fn ___syscall77(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall77(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall77 (getrusage) {}", _which); debug!("emscripten::___syscall77 (getrusage) {}", _which);
let resource: c_int = varargs.get(ctx); let resource: c_int = varargs.get(&ctx);
let rusage_ptr: c_int = varargs.get(ctx); let rusage_ptr: c_int = varargs.get(&ctx);
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let rusage = emscripten_memory_pointer!(ctx.memory(0), rusage_ptr) as *mut rusage; let rusage = emscripten_memory_pointer!(ctx, ctx.data().memory(0), rusage_ptr) as *mut rusage;
assert_eq!(8, mem::align_of_val(&rusage)); assert_eq!(8, mem::align_of_val(&rusage));
unsafe { getrusage(resource, rusage) } unsafe { getrusage(resource, rusage) }
} }
/// symlink /// symlink
pub fn ___syscall83(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall83(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall83 (symlink) {}", _which); debug!("emscripten::___syscall83 (symlink) {}", _which);
let path1 = varargs.get_str(ctx); let path1 = varargs.get_str(&ctx);
let path2 = varargs.get_str(ctx); let path2 = varargs.get_str(&ctx);
let real_path1_owned = utils::get_cstr_path(ctx, path1 as *const _); let real_path1_owned = utils::get_cstr_path(ctx.as_context_mut(), path1 as *const _);
let real_path1 = if let Some(ref rp) = real_path1_owned { let real_path1 = if let Some(ref rp) = real_path1_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
path1 path1
}; };
let real_path2_owned = utils::get_cstr_path(ctx, path2 as *const _); let real_path2_owned = utils::get_cstr_path(ctx.as_context_mut(), path2 as *const _);
let real_path2 = if let Some(ref rp) = real_path2_owned { let real_path2 = if let Some(ref rp) = real_path2_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
@@ -237,13 +237,13 @@ pub fn ___syscall83(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
} }
/// readlink /// readlink
pub fn ___syscall85(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 { pub fn ___syscall85(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall85 (readlink)"); debug!("emscripten::___syscall85 (readlink)");
let pathname_addr = varargs.get_str(ctx); let pathname_addr = varargs.get_str(&ctx);
let buf = varargs.get_str(ctx); let buf = varargs.get_str(&ctx);
// let buf_addr: i32 = varargs.get(ctx); // let buf_addr: i32 = varargs.get(&ctx);
let buf_size: i32 = varargs.get(ctx); let buf_size: i32 = varargs.get(&ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _); let real_path_owned = get_cstr_path(ctx.as_context_mut(), pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
@@ -266,10 +266,10 @@ pub fn ___syscall85(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
} }
/// ftruncate64 /// ftruncate64
pub fn ___syscall194(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall194(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall194 (ftruncate64) {}", _which); debug!("emscripten::___syscall194 (ftruncate64) {}", _which);
let _fd: c_int = varargs.get(ctx); let _fd: c_int = varargs.get(&ctx);
let _length: i64 = varargs.get(ctx); let _length: i64 = varargs.get(&ctx);
#[cfg(not(any(target_os = "freebsd", target_vendor = "apple")))] #[cfg(not(any(target_os = "freebsd", target_vendor = "apple")))]
unsafe { unsafe {
ftruncate64(_fd, _length) ftruncate64(_fd, _length)
@@ -283,17 +283,17 @@ pub fn ___syscall194(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
/// lchown /// lchown
pub fn ___syscall198(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall198(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall198 (lchown) {}", _which); debug!("emscripten::___syscall198 (lchown) {}", _which);
let path_ptr = varargs.get_str(ctx); let path_ptr = varargs.get_str(&ctx);
let real_path_owned = utils::get_cstr_path(ctx, path_ptr as *const _); let real_path_owned = utils::get_cstr_path(ctx.as_context_mut(), path_ptr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
path_ptr path_ptr
}; };
let uid: uid_t = varargs.get(ctx); let uid: uid_t = varargs.get(&ctx);
let gid: gid_t = varargs.get(ctx); let gid: gid_t = varargs.get(&ctx);
let result = unsafe { lchown(real_path, uid, gid) }; let result = unsafe { lchown(real_path, uid, gid) };
debug!( debug!(
"=> path: {}, uid: {}, gid: {}, result: {}", "=> path: {}, uid: {}, gid: {}, result: {}",
@@ -306,13 +306,13 @@ pub fn ___syscall198(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
/// getgroups /// getgroups
pub fn ___syscall205(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall205(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall205 (getgroups) {}", _which); debug!("emscripten::___syscall205 (getgroups) {}", _which);
let ngroups_max: c_int = varargs.get(ctx); let ngroups_max: c_int = varargs.get(&ctx);
let groups: c_int = varargs.get(ctx); let groups: c_int = varargs.get(&ctx);
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let gid_ptr = emscripten_memory_pointer!(ctx.memory(0), groups) as *mut gid_t; let gid_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), groups) as *mut gid_t;
assert_eq!(4, mem::align_of_val(&gid_ptr)); assert_eq!(4, mem::align_of_val(&gid_ptr));
let result = unsafe { getgroups(ngroups_max, gid_ptr) }; let result = unsafe { getgroups(ngroups_max, gid_ptr) };
debug!( debug!(
@@ -323,46 +323,46 @@ pub fn ___syscall205(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
// chown // chown
pub fn ___syscall212(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall212(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall212 (chown) {}", _which); debug!("emscripten::___syscall212 (chown) {}", _which);
let pathname_addr = varargs.get_str(ctx); let pathname_addr = varargs.get_str(&ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _); let real_path_owned = utils::get_cstr_path(ctx.as_context_mut(), pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
pathname_addr pathname_addr
}; };
let owner: u32 = varargs.get(ctx); let owner: u32 = varargs.get(&ctx);
let group: u32 = varargs.get(ctx); let group: u32 = varargs.get(&ctx);
unsafe { chown(real_path, owner, group) } unsafe { chown(real_path, owner, group) }
} }
/// madvise /// madvise
pub fn ___syscall219(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall219(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall212 (chown) {}", _which); debug!("emscripten::___syscall212 (chown) {}", _which);
let addr_ptr: c_int = varargs.get(ctx); let addr_ptr: c_int = varargs.get(&ctx);
let len: usize = varargs.get(ctx); let len: usize = varargs.get(&ctx);
let advice: c_int = varargs.get(ctx); let advice: c_int = varargs.get(&ctx);
let addr = emscripten_memory_pointer!(ctx.memory(0), addr_ptr) as *mut c_void; let addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), addr_ptr) as *mut c_void;
unsafe { madvise(addr, len, advice) } unsafe { madvise(addr, len, advice) }
} }
/// access /// access
pub fn ___syscall33(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall33(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall33 (access) {}", _which); debug!("emscripten::___syscall33 (access) {}", _which);
let path = varargs.get_str(ctx); let path = varargs.get_str(&ctx);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _); let real_path_owned = utils::get_cstr_path(ctx.as_context_mut(), path as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
path path
}; };
let amode: c_int = varargs.get(ctx); let amode: c_int = varargs.get(&ctx);
let result = unsafe { access(real_path, amode) }; let result = unsafe { access(real_path, amode) };
debug!( debug!(
"=> path: {}, amode: {}, result: {}", "=> path: {}, amode: {}, result: {}",
@@ -374,41 +374,41 @@ pub fn ___syscall33(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
} }
/// nice /// nice
pub fn ___syscall34(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall34(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall34 (nice) {}", _which); debug!("emscripten::___syscall34 (nice) {}", _which);
let inc_r: c_int = varargs.get(ctx); let inc_r: c_int = varargs.get(&ctx);
unsafe { nice(inc_r) } unsafe { nice(inc_r) }
} }
// mkdir // mkdir
pub fn ___syscall39(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall39(mut ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall39 (mkdir) {}", _which); debug!("emscripten::___syscall39 (mkdir) {}", _which);
let pathname_addr = varargs.get_str(ctx); let pathname_addr = varargs.get_str(&ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _); let real_path_owned = utils::get_cstr_path(ctx.as_context_mut(), pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
pathname_addr pathname_addr
}; };
let mode: u32 = varargs.get(ctx); let mode: u32 = varargs.get(&ctx);
unsafe { mkdir(real_path, mode as _) } unsafe { mkdir(real_path, mode as _) }
} }
/// dup /// dup
pub fn ___syscall41(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall41(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall41 (dup) {}", _which); debug!("emscripten::___syscall41 (dup) {}", _which);
let fd: c_int = varargs.get(ctx); let fd: c_int = varargs.get(&ctx);
unsafe { dup(fd) } unsafe { dup(fd) }
} }
/// getgid32 /// getgid32
pub fn ___syscall200(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall200(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall200 (getgid32)"); debug!("emscripten::___syscall200 (getgid32)");
unsafe { getgid() as i32 } unsafe { getgid() as i32 }
} }
// geteuid32 // geteuid32
pub fn ___syscall201(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall201(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall201 (geteuid32)"); debug!("emscripten::___syscall201 (geteuid32)");
unsafe { unsafe {
// Maybe fix: Emscripten returns 0 always // Maybe fix: Emscripten returns 0 always
@@ -417,7 +417,7 @@ pub fn ___syscall201(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
} }
// getegid32 // getegid32
pub fn ___syscall202(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall202(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
// gid_t // gid_t
debug!("emscripten::___syscall202 (getegid32)"); debug!("emscripten::___syscall202 (getegid32)");
unsafe { unsafe {
@@ -427,21 +427,21 @@ pub fn ___syscall202(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
} }
/// fchown /// fchown
pub fn ___syscall207(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall207(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall207 (fchown) {}", _which); debug!("emscripten::___syscall207 (fchown) {}", _which);
let fd: c_int = varargs.get(ctx); let fd: c_int = varargs.get(&ctx);
let owner: uid_t = varargs.get(ctx); let owner: uid_t = varargs.get(&ctx);
let group: gid_t = varargs.get(ctx); let group: gid_t = varargs.get(&ctx);
unsafe { fchown(fd, owner, group) } unsafe { fchown(fd, owner, group) }
} }
/// dup3 /// dup3
pub fn ___syscall330(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> pid_t { pub fn ___syscall330(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> pid_t {
// Implementation based on description at https://linux.die.net/man/2/dup3 // Implementation based on description at https://linux.die.net/man/2/dup3
debug!("emscripten::___syscall330 (dup3)"); debug!("emscripten::___syscall330 (dup3)");
let oldfd: c_int = varargs.get(ctx); let oldfd: c_int = varargs.get(&ctx);
let newfd: c_int = varargs.get(ctx); let newfd: c_int = varargs.get(&ctx);
let flags: c_int = varargs.get(ctx); let flags: c_int = varargs.get(&ctx);
if oldfd == newfd { if oldfd == newfd {
return EINVAL; return EINVAL;
@@ -474,19 +474,20 @@ pub fn ___syscall330(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> pid_t
} }
/// ioctl /// ioctl
pub fn ___syscall54(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall54(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall54 (ioctl) {}", _which); debug!("emscripten::___syscall54 (ioctl) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let request: u32 = varargs.get(ctx); let request: u32 = varargs.get(&ctx);
debug!("=> fd: {}, op: {}", fd, request); debug!("=> fd: {}, op: {}", fd, request);
// Got the equivalents here: https://code.woboq.org/linux/linux/include/uapi/asm-generic/ioctls.h.html // Got the equivalents here: https://code.woboq.org/linux/linux/include/uapi/asm-generic/ioctls.h.html
match request { match request {
WASM_FIOCLEX | WASM_FIONBIO | WASM_TIOCGWINSZ | WASM_TIOCSPGRP | WASM_TCGETS WASM_FIOCLEX | WASM_FIONBIO | WASM_TIOCGWINSZ | WASM_TIOCSPGRP | WASM_TCGETS
| WASM_TCSETSW => { | WASM_TCSETSW => {
let argp: u32 = varargs.get(ctx); let argp: u32 = varargs.get(&ctx);
let argp_ptr = emscripten_memory_pointer!(ctx.memory(0), argp) as *mut c_void; let argp_ptr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), argp) as *mut c_void;
let translated_request = translate_ioctl(request); let translated_request = translate_ioctl(request);
let ret = unsafe { ioctl(fd, translated_request as _, argp_ptr) }; let ret = unsafe { ioctl(fd, translated_request as _, argp_ptr) };
debug!( debug!(
@@ -516,11 +517,11 @@ const SOCK_CLOEXC: i32 = 0x80000;
// socketcall // socketcall
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall102(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall102 (socketcall) {}", _which); debug!("emscripten::___syscall102 (socketcall) {}", _which);
let call: u32 = varargs.get(ctx); let call: u32 = varargs.get(&ctx);
let mut socket_varargs: VarArgs = varargs.get(ctx); let mut socket_varargs: VarArgs = varargs.get(&ctx);
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
// migrating to EmSockAddr, port being separate here is nice, should update that too // migrating to EmSockAddr, port being separate here is nice, should update that too
#[repr(C)] #[repr(C)]
@@ -541,9 +542,9 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
1 => { 1 => {
debug!("socket: socket"); debug!("socket: socket");
// socket (domain: c_int, ty: c_int, protocol: c_int) -> c_int // socket (domain: c_int, ty: c_int, protocol: c_int) -> c_int
let domain: i32 = socket_varargs.get(ctx); let domain: i32 = socket_varargs.get(&ctx);
let ty_and_flags: i32 = socket_varargs.get(ctx); let ty_and_flags: i32 = socket_varargs.get(&ctx);
let protocol: i32 = socket_varargs.get(ctx); let protocol: i32 = socket_varargs.get(&ctx);
let ty = ty_and_flags & (!SOCK_NON_BLOCK) & (!SOCK_CLOEXC); let ty = ty_and_flags & (!SOCK_NON_BLOCK) & (!SOCK_CLOEXC);
let fd = unsafe { socket(domain, ty, protocol) }; let fd = unsafe { socket(domain, ty, protocol) };
@@ -582,10 +583,10 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
debug!("socket: bind"); debug!("socket: bind");
// bind (socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int // bind (socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int
// TODO: Emscripten has a different signature. // TODO: Emscripten has a different signature.
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(ctx); let address: u32 = socket_varargs.get(&ctx);
let address_len = socket_varargs.get(ctx); let address_len = socket_varargs.get(&ctx);
let address = emscripten_memory_pointer!(&memory, address) as *mut sockaddr; let address = emscripten_memory_pointer!(ctx, &memory, address) as *mut sockaddr;
// Debug received address // Debug received address
let _proper_address = address as *const GuestSockaddrIn; let _proper_address = address as *const GuestSockaddrIn;
@@ -607,17 +608,17 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
debug!("socket: connect"); debug!("socket: connect");
// connect (socket: c_int, address: *const sockaddr, len: socklen_t) -> c_int // connect (socket: c_int, address: *const sockaddr, len: socklen_t) -> c_int
// TODO: Emscripten has a different signature. // TODO: Emscripten has a different signature.
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(ctx); let address: u32 = socket_varargs.get(&ctx);
let address_len = socket_varargs.get(ctx); let address_len = socket_varargs.get(&ctx);
let address = emscripten_memory_pointer!(&memory, address) as *mut sockaddr; let address = emscripten_memory_pointer!(ctx, &memory, address) as *mut sockaddr;
unsafe { connect(socket, address, address_len) } unsafe { connect(socket, address, address_len) }
} }
4 => { 4 => {
debug!("socket: listen"); debug!("socket: listen");
// listen (socket: c_int, backlog: c_int) -> c_int // listen (socket: c_int, backlog: c_int) -> c_int
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let backlog: i32 = socket_varargs.get(ctx); let backlog: i32 = socket_varargs.get(&ctx);
let status = unsafe { listen(socket, backlog) }; let status = unsafe { listen(socket, backlog) };
debug!( debug!(
"=> socketfd: {}, backlog: {} = status: {}", "=> socketfd: {}, backlog: {} = status: {}",
@@ -628,17 +629,17 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
5 => { 5 => {
debug!("socket: accept"); debug!("socket: accept");
// accept (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int // accept (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
let socket: i32 = socket_varargs.get(ctx); let socket: i32 = socket_varargs.get(&ctx);
let address: WasmPtr<EmSockAddr> = socket_varargs.get(ctx); let address: WasmPtr<EmSockAddr> = socket_varargs.get(&ctx);
let address_len: WasmPtr<u32> = socket_varargs.get(ctx); let address_len: WasmPtr<u32> = socket_varargs.get(&ctx);
debug!( debug!(
"=> socket: {}, address: {:?}, address_len: {}", "=> socket: {}, address: {:?}, address_len: {}",
socket, socket,
address.deref(&memory).read().unwrap(), address.deref(&ctx, &memory).read().unwrap(),
address_len.deref(&memory).read().unwrap() address_len.deref(&ctx, &memory).read().unwrap()
); );
let mut address_len_addr = address_len.deref(&memory).read().unwrap(); let mut address_len_addr = address_len.deref(&ctx, &memory).read().unwrap();
// let mut address_len_addr: socklen_t = 0; // let mut address_len_addr: socklen_t = 0;
let mut host_address: sockaddr = sockaddr { let mut host_address: sockaddr = sockaddr {
@@ -648,7 +649,7 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
sa_len: Default::default(), sa_len: Default::default(),
}; };
let fd = unsafe { accept(socket, &mut host_address, &mut address_len_addr) }; let fd = unsafe { accept(socket, &mut host_address, &mut address_len_addr) };
let mut address_addr = address.deref(&memory).read().unwrap(); let mut address_addr = address.deref(&ctx, &memory).read().unwrap();
address_addr.sa_family = host_address.sa_family as _; address_addr.sa_family = host_address.sa_family as _;
address_addr.sa_data = host_address.sa_data; address_addr.sa_data = host_address.sa_data;
@@ -669,10 +670,10 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
6 => { 6 => {
debug!("socket: getsockname"); debug!("socket: getsockname");
// getsockname (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int // getsockname (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
let socket: i32 = socket_varargs.get(ctx); let socket: i32 = socket_varargs.get(&ctx);
let address: WasmPtr<EmSockAddr> = socket_varargs.get(ctx); let address: WasmPtr<EmSockAddr> = socket_varargs.get(&ctx);
let address_len: WasmPtr<u32> = socket_varargs.get(ctx); let address_len: WasmPtr<u32> = socket_varargs.get(&ctx);
let address_len_addr = address_len.deref(&memory).read().unwrap(); let address_len_addr = address_len.deref(&ctx, &memory).read().unwrap();
let mut sock_addr_host: sockaddr = sockaddr { let mut sock_addr_host: sockaddr = sockaddr {
sa_family: Default::default(), sa_family: Default::default(),
@@ -688,7 +689,7 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
) )
}; };
// translate from host data into emscripten data // translate from host data into emscripten data
let mut address_mut = address.deref(&memory).read().unwrap(); let mut address_mut = address.deref(&ctx, &memory).read().unwrap();
address_mut.sa_family = sock_addr_host.sa_family as _; address_mut.sa_family = sock_addr_host.sa_family as _;
address_mut.sa_data = sock_addr_host.sa_data; address_mut.sa_data = sock_addr_host.sa_data;
@@ -702,40 +703,40 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
7 => { 7 => {
debug!("socket: getpeername"); debug!("socket: getpeername");
// getpeername (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int // getpeername (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(ctx); let address: u32 = socket_varargs.get(&ctx);
let address_len: u32 = socket_varargs.get(ctx); let address_len: u32 = socket_varargs.get(&ctx);
let address = emscripten_memory_pointer!(memory, address) as *mut sockaddr; let address = emscripten_memory_pointer!(ctx, memory, address) as *mut sockaddr;
let address_len_addr = let address_len_addr =
emscripten_memory_pointer!(memory, address_len) as *mut socklen_t; emscripten_memory_pointer!(ctx, memory, address_len) as *mut socklen_t;
unsafe { getpeername(socket, address, address_len_addr) } unsafe { getpeername(socket, address, address_len_addr) }
} }
11 => { 11 => {
debug!("socket: sendto"); debug!("socket: sendto");
// sendto (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t // sendto (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let buf: u32 = socket_varargs.get(ctx); let buf: u32 = socket_varargs.get(&ctx);
let flags = socket_varargs.get(ctx); let flags = socket_varargs.get(&ctx);
let len: i32 = socket_varargs.get(ctx); let len: i32 = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(ctx); let address: u32 = socket_varargs.get(&ctx);
let address_len = socket_varargs.get(ctx); let address_len = socket_varargs.get(&ctx);
let buf_addr = emscripten_memory_pointer!(memory, buf) as _; let buf_addr = emscripten_memory_pointer!(ctx, memory, buf) as _;
let address = emscripten_memory_pointer!(memory, address) as *mut sockaddr; let address = emscripten_memory_pointer!(ctx, memory, address) as *mut sockaddr;
unsafe { sendto(socket, buf_addr, flags, len, address, address_len) as i32 } unsafe { sendto(socket, buf_addr, flags, len, address, address_len) as i32 }
} }
12 => { 12 => {
debug!("socket: recvfrom"); debug!("socket: recvfrom");
// recvfrom (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t // recvfrom (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let buf: u32 = socket_varargs.get(ctx); let buf: u32 = socket_varargs.get(&ctx);
let len: i32 = socket_varargs.get(ctx); let len: i32 = socket_varargs.get(&ctx);
let flags: i32 = socket_varargs.get(ctx); let flags: i32 = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(ctx); let address: u32 = socket_varargs.get(&ctx);
let address_len: u32 = socket_varargs.get(ctx); let address_len: u32 = socket_varargs.get(&ctx);
let buf_addr = emscripten_memory_pointer!(memory, buf) as _; let buf_addr = emscripten_memory_pointer!(ctx, memory, buf) as _;
let address = emscripten_memory_pointer!(memory, address) as *mut sockaddr; let address = emscripten_memory_pointer!(ctx, memory, address) as *mut sockaddr;
let address_len_addr = let address_len_addr =
emscripten_memory_pointer!(memory, address_len) as *mut socklen_t; emscripten_memory_pointer!(ctx, memory, address_len) as *mut socklen_t;
unsafe { unsafe {
recvfrom( recvfrom(
socket, socket,
@@ -753,13 +754,13 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
// https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L156 // https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L156
// setsockopt (socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int // setsockopt (socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let level: i32 = socket_varargs.get(ctx); let level: i32 = socket_varargs.get(&ctx);
let level = if level == 1 { SOL_SOCKET } else { level }; let level = if level == 1 { SOL_SOCKET } else { level };
let untranslated_name: i32 = socket_varargs.get(ctx); let untranslated_name: i32 = socket_varargs.get(&ctx);
let value: u32 = socket_varargs.get(ctx); let value: u32 = socket_varargs.get(&ctx);
let option_len: u32 = socket_varargs.get(ctx); let option_len: u32 = socket_varargs.get(&ctx);
let value_addr = emscripten_memory_pointer!(memory, value) as *const libc::c_void; let value_addr = emscripten_memory_pointer!(ctx, memory, value) as *const libc::c_void;
let name: i32 = translate_socket_name_flag(untranslated_name); let name: i32 = translate_socket_name_flag(untranslated_name);
let ret = unsafe { setsockopt(socket, level, name, value_addr, option_len) }; let ret = unsafe { setsockopt(socket, level, name, value_addr, option_len) };
@@ -770,33 +771,34 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
15 => { 15 => {
debug!("socket: getsockopt"); debug!("socket: getsockopt");
// getsockopt (sockfd: c_int, level: c_int, optname: c_int, optval: *mut c_void, optlen: *mut socklen_t) -> c_int // getsockopt (sockfd: c_int, level: c_int, optname: c_int, optval: *mut c_void, optlen: *mut socklen_t) -> c_int
let socket = socket_varargs.get(ctx); let socket = socket_varargs.get(&ctx);
let level: i32 = socket_varargs.get(ctx); let level: i32 = socket_varargs.get(&ctx);
let level = if level == 1 { SOL_SOCKET } else { level }; let level = if level == 1 { SOL_SOCKET } else { level };
let untranslated_name: i32 = socket_varargs.get(ctx); let untranslated_name: i32 = socket_varargs.get(&ctx);
let name: i32 = translate_socket_name_flag(untranslated_name); let name: i32 = translate_socket_name_flag(untranslated_name);
let value: u32 = socket_varargs.get(ctx); let value: u32 = socket_varargs.get(&ctx);
let option_len: u32 = socket_varargs.get(ctx); let option_len: u32 = socket_varargs.get(&ctx);
let value_addr = emscripten_memory_pointer!(memory, value) as _; let value_addr = emscripten_memory_pointer!(ctx, memory, value) as _;
let option_len_addr = emscripten_memory_pointer!(memory, option_len) as *mut socklen_t; let option_len_addr =
emscripten_memory_pointer!(ctx, memory, option_len) as *mut socklen_t;
unsafe { getsockopt(socket, level, name, value_addr, option_len_addr) } unsafe { getsockopt(socket, level, name, value_addr, option_len_addr) }
} }
16 => { 16 => {
debug!("socket: sendmsg"); debug!("socket: sendmsg");
// sendmsg (fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t // sendmsg (fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t
let socket: i32 = socket_varargs.get(ctx); let socket: i32 = socket_varargs.get(&ctx);
let msg: u32 = socket_varargs.get(ctx); let msg: u32 = socket_varargs.get(&ctx);
let flags: i32 = socket_varargs.get(ctx); let flags: i32 = socket_varargs.get(&ctx);
let msg_addr = emscripten_memory_pointer!(memory, msg) as *const msghdr; let msg_addr = emscripten_memory_pointer!(ctx, memory, msg) as *const msghdr;
unsafe { sendmsg(socket, msg_addr, flags) as i32 } unsafe { sendmsg(socket, msg_addr, flags) as i32 }
} }
17 => { 17 => {
debug!("socket: recvmsg"); debug!("socket: recvmsg");
// recvmsg (fd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t // recvmsg (fd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t
let socket: i32 = socket_varargs.get(ctx); let socket: i32 = socket_varargs.get(&ctx);
let msg: u32 = socket_varargs.get(ctx); let msg: u32 = socket_varargs.get(&ctx);
let flags: i32 = socket_varargs.get(ctx); let flags: i32 = socket_varargs.get(&ctx);
let msg_addr = emscripten_memory_pointer!(memory, msg) as *mut msghdr; let msg_addr = emscripten_memory_pointer!(ctx, memory, msg) as *mut msghdr;
unsafe { recvmsg(socket, msg_addr, flags) as i32 } unsafe { recvmsg(socket, msg_addr, flags) as i32 }
} }
_ => { _ => {
@@ -831,10 +833,10 @@ fn translate_socket_name_flag(name: i32) -> i32 {
} }
/// getpgid /// getpgid
pub fn ___syscall132(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall132(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall132 (getpgid)"); debug!("emscripten::___syscall132 (getpgid)");
let pid: pid_t = varargs.get(ctx); let pid: pid_t = varargs.get(&ctx);
let ret = unsafe { getpgid(pid) }; let ret = unsafe { getpgid(pid) };
debug!("=> pid: {} = {}", pid, ret); debug!("=> pid: {} = {}", pid, ret);
@@ -853,14 +855,14 @@ pub struct EmPollFd {
} }
/// poll /// poll
pub fn ___syscall168(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall168(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall168(poll)"); debug!("emscripten::___syscall168(poll)");
let fds: WasmPtr<EmPollFd> = varargs.get(ctx); let fds: WasmPtr<EmPollFd> = varargs.get(&ctx);
let nfds: u32 = varargs.get(ctx); let nfds: u32 = varargs.get(&ctx);
let timeout: i32 = varargs.get(ctx); let timeout: i32 = varargs.get(&ctx);
let memory = ctx.memory(0); let memory = ctx.data().memory(0);
let mut fds_mut = fds.deref(&memory).read().unwrap(); let mut fds_mut = fds.deref(&ctx, &memory).read().unwrap();
unsafe { unsafe {
libc::poll( libc::poll(
@@ -872,35 +874,35 @@ pub fn ___syscall168(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
} }
// pread // pread
pub fn ___syscall180(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall180(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall180 (pread) {}", _which); debug!("emscripten::___syscall180 (pread) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(&ctx);
let count: u32 = varargs.get(ctx); let count: u32 = varargs.get(&ctx);
{ {
let zero: u32 = varargs.get(ctx); let zero: u32 = varargs.get(&ctx);
assert_eq!(zero, 0); assert_eq!(zero, 0);
} }
let offset: i64 = varargs.get(ctx); let offset: i64 = varargs.get(&ctx);
let buf_ptr = emscripten_memory_pointer!(ctx.memory(0), buf) as _; let buf_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as _;
unsafe { pread(fd, buf_ptr, count as _, offset) as _ } unsafe { pread(fd, buf_ptr, count as _, offset) as _ }
} }
// pwrite // pwrite
pub fn ___syscall181(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall181(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall181 (pwrite) {}", _which); debug!("emscripten::___syscall181 (pwrite) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(&ctx);
let count: u32 = varargs.get(ctx); let count: u32 = varargs.get(&ctx);
{ {
let zero: u32 = varargs.get(ctx); let zero: u32 = varargs.get(&ctx);
assert_eq!(zero, 0); assert_eq!(zero, 0);
} }
let offset: i64 = varargs.get(ctx); let offset: i64 = varargs.get(&ctx);
let buf_ptr = emscripten_memory_pointer!(ctx.memory(0), buf) as _; let buf_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as _;
let status = unsafe { pwrite(fd, buf_ptr, count as _, offset) as _ }; let status = unsafe { pwrite(fd, buf_ptr, count as _, offset) as _ };
debug!( debug!(
"=> fd: {}, buf: {}, count: {}, offset: {} = status:{}", "=> fd: {}, buf: {}, count: {}, offset: {} = status:{}",
@@ -910,24 +912,24 @@ pub fn ___syscall181(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
/// fchmod /// fchmod
pub fn ___syscall94(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall94(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall118 (fchmod) {}", _which); debug!("emscripten::___syscall118 (fchmod) {}", _which);
let fd: c_int = varargs.get(ctx); let fd: c_int = varargs.get(&ctx);
let mode: mode_t = varargs.get(ctx); let mode: mode_t = varargs.get(&ctx);
unsafe { fchmod(fd, mode) } unsafe { fchmod(fd, mode) }
} }
/// wait4 /// wait4
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn ___syscall114(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> pid_t { pub fn ___syscall114(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> pid_t {
debug!("emscripten::___syscall114 (wait4)"); debug!("emscripten::___syscall114 (wait4)");
let pid: pid_t = varargs.get(ctx); let pid: pid_t = varargs.get(&ctx);
let status: u32 = varargs.get(ctx); let status: u32 = varargs.get(&ctx);
let options: c_int = varargs.get(ctx); let options: c_int = varargs.get(&ctx);
let rusage: u32 = varargs.get(ctx); let rusage: u32 = varargs.get(&ctx);
let status_addr = emscripten_memory_pointer!(ctx.memory(0), status) as *mut c_int; let status_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), status) as *mut c_int;
let rusage_addr = emscripten_memory_pointer!(ctx.memory(0), rusage) as *mut rusage; let rusage_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), rusage) as *mut rusage;
let res = unsafe { wait4(pid, status_addr, options, rusage_addr) }; let res = unsafe { wait4(pid, status_addr, options, rusage_addr) };
debug!( debug!(
"=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}", "=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}",
@@ -937,22 +939,22 @@ pub fn ___syscall114(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> pid_t
} }
/// fsync /// fsync
pub fn ___syscall118(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall118(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall118 (fsync) {}", _which); debug!("emscripten::___syscall118 (fsync) {}", _which);
let fd: c_int = varargs.get(ctx); let fd: c_int = varargs.get(&ctx);
unsafe { fsync(fd) } unsafe { fsync(fd) }
} }
// select // select
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn ___syscall142(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall142(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall142 (newselect) {}", _which); debug!("emscripten::___syscall142 (newselect) {}", _which);
let nfds: i32 = varargs.get(ctx); let nfds: i32 = varargs.get(&ctx);
let readfds: u32 = varargs.get(ctx); let readfds: u32 = varargs.get(&ctx);
let writefds: u32 = varargs.get(ctx); let writefds: u32 = varargs.get(&ctx);
let exceptfds: u32 = varargs.get(ctx); let exceptfds: u32 = varargs.get(&ctx);
let _timeout: i32 = varargs.get(ctx); let _timeout: i32 = varargs.get(&ctx);
if nfds > 1024 { if nfds > 1024 {
// EINVAL // EINVAL
@@ -960,27 +962,27 @@ pub fn ___syscall142(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
assert!(exceptfds == 0, "`exceptfds` is not supporrted"); assert!(exceptfds == 0, "`exceptfds` is not supporrted");
let readfds_ptr = emscripten_memory_pointer!(ctx.memory(0), readfds) as _; let readfds_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), readfds) as _;
let writefds_ptr = emscripten_memory_pointer!(ctx.memory(0), writefds) as _; let writefds_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), writefds) as _;
unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) } unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) }
} }
/// fdatasync /// fdatasync
pub fn ___syscall148(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall148(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall148 (fdatasync) {}", _which); debug!("emscripten::___syscall148 (fdatasync) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
unsafe { fdatasync(fd) } unsafe { fdatasync(fd) }
} }
// setpgid // setpgid
pub fn ___syscall57(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall57(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall57 (setpgid) {}", _which); debug!("emscripten::___syscall57 (setpgid) {}", _which);
let pid: i32 = varargs.get(ctx); let pid: i32 = varargs.get(&ctx);
let pgid: i32 = varargs.get(ctx); let pgid: i32 = varargs.get(&ctx);
let ret = unsafe { setpgid(pid, pgid) }; let ret = unsafe { setpgid(pid, pgid) };
debug!("=> pid: {}, pgid: {} = {}", pid, pgid, ret); debug!("=> pid: {}, pgid: {} = {}", pid, pgid, ret);
@@ -992,25 +994,25 @@ pub fn ___syscall57(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
/// uname /// uname
// NOTE: Wondering if we should return custom utsname, like Emscripten. // NOTE: Wondering if we should return custom utsname, like Emscripten.
pub fn ___syscall122(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall122(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall122 (uname) {}", _which); debug!("emscripten::___syscall122 (uname) {}", _which);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(&ctx);
debug!("=> buf: {}", buf); debug!("=> buf: {}", buf);
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut utsname; let buf_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *mut utsname;
unsafe { uname(buf_addr) } unsafe { uname(buf_addr) }
} }
/// lstat64 /// lstat64
pub fn ___syscall196(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall196(mut ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall196 (lstat64) {}", _which); debug!("emscripten::___syscall196 (lstat64) {}", _which);
let path = varargs.get_str(ctx); let path = varargs.get_str(&ctx);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _); let real_path_owned = utils::get_cstr_path(ctx.as_context_mut(), path as *const _);
let real_path = if let Some(ref rp) = real_path_owned { let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr() rp.as_c_str().as_ptr()
} else { } else {
path path
}; };
let buf_ptr: u32 = varargs.get(ctx); let buf_ptr: u32 = varargs.get(&ctx);
unsafe { unsafe {
let mut stat: stat = std::mem::zeroed(); let mut stat: stat = std::mem::zeroed();
@@ -1034,7 +1036,7 @@ pub fn ___syscall196(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
} }
// getuid // getuid
pub fn ___syscall199(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn ___syscall199(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall199 (getuid)"); debug!("emscripten::___syscall199 (getuid)");
let uid = unsafe { getuid() as _ }; let uid = unsafe { getuid() as _ };
debug!(" => {}", uid); debug!(" => {}", uid);
@@ -1044,20 +1046,20 @@ pub fn ___syscall199(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
// getdents // getdents
// dirent structure is // dirent structure is
// i64, i64, u16 (280), i8, [i8; 256] // i64, i64, u16 (280), i8, [i8; 256]
pub fn ___syscall220(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 { pub fn ___syscall220(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
use super::super::env::get_emscripten_data; use super::super::env::get_emscripten_data;
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let dirp_addr: i32 = varargs.get(ctx); let dirp_addr: i32 = varargs.get(&ctx);
let count: u32 = varargs.get(ctx); let count: u32 = varargs.get(&ctx);
debug!( debug!(
"emscripten::___syscall220 (getdents) {} {} {}", "emscripten::___syscall220 (getdents) {} {} {}",
fd, dirp_addr, count fd, dirp_addr, count
); );
let dirp = emscripten_memory_pointer!(ctx.memory(0), dirp_addr) as *mut u8; let dirp = emscripten_memory_pointer!(ctx, ctx.data().memory(0), dirp_addr) as *mut u8;
let opened_dirs = &mut get_emscripten_data(ctx).opened_dirs; let opened_dirs = &mut get_emscripten_data(&ctx).opened_dirs;
// need to persist stream across calls? // need to persist stream across calls?
// let dir: *mut libc::DIR = unsafe { libc::fdopendir(fd) }; // let dir: *mut libc::DIR = unsafe { libc::fdopendir(fd) };
@@ -1108,11 +1110,11 @@ pub fn ___syscall220(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
} }
// fcntl64 // fcntl64
pub fn ___syscall221(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall221(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall221 (fcntl64) {}", _which); debug!("emscripten::___syscall221 (fcntl64) {}", _which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(&ctx);
let cmd: i32 = varargs.get(ctx); let cmd: i32 = varargs.get(&ctx);
let arg: i32 = varargs.get(ctx); let arg: i32 = varargs.get(&ctx);
// (FAPPEND - 0x08 // (FAPPEND - 0x08
// |FASYNC - 0x40 // |FASYNC - 0x40
// |FFSYNC - 0x80 // |FFSYNC - 0x80
@@ -1126,12 +1128,12 @@ pub fn ___syscall221(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
} }
/// fallocate /// fallocate
pub fn ___syscall324(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int { pub fn ___syscall324(ctx: ContextMut<'_, EmEnv>, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall324 (fallocate) {}", _which); debug!("emscripten::___syscall324 (fallocate) {}", _which);
let _fd: c_int = varargs.get(ctx); let _fd: c_int = varargs.get(&ctx);
let _mode: c_int = varargs.get(ctx); let _mode: c_int = varargs.get(&ctx);
let _offset: off_t = varargs.get(ctx); let _offset: off_t = varargs.get(&ctx);
let _len: off_t = varargs.get(ctx); let _len: off_t = varargs.get(&ctx);
#[cfg(not(any(target_os = "freebsd", target_vendor = "apple", target_os = "android")))] #[cfg(not(any(target_os = "freebsd", target_vendor = "apple", target_os = "android")))]
unsafe { unsafe {
fallocate(_fd, _mode, _offset, _len) fallocate(_fd, _mode, _offset, _len)

View File

@@ -13,6 +13,8 @@ use std::ffi::CString;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use libc::time_t; use libc::time_t;
use wasmer::{AsContextMut, ContextMut};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
type clockid_t = c_int; type clockid_t = c_int;
@@ -50,7 +52,7 @@ const CLOCK_MONOTONIC_COARSE: clockid_t = 6;
/// emscripten: _gettimeofday /// emscripten: _gettimeofday
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _gettimeofday(ctx: &EmEnv, tp: c_int, tz: c_int) -> c_int { pub fn _gettimeofday(ctx: ContextMut<'_, EmEnv>, tp: c_int, tz: c_int) -> c_int {
debug!("emscripten::_gettimeofday {} {}", tp, tz); debug!("emscripten::_gettimeofday {} {}", tp, tz);
#[repr(C)] #[repr(C)]
struct GuestTimeVal { struct GuestTimeVal {
@@ -65,7 +67,8 @@ pub fn _gettimeofday(ctx: &EmEnv, tp: c_int, tz: c_int) -> c_int {
unsafe { unsafe {
let now = SystemTime::now(); let now = SystemTime::now();
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap();
let timeval_struct_ptr = emscripten_memory_pointer!(ctx.memory(0), tp) as *mut GuestTimeVal; let timeval_struct_ptr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), tp) as *mut GuestTimeVal;
(*timeval_struct_ptr).tv_sec = since_epoch.as_secs() as _; (*timeval_struct_ptr).tv_sec = since_epoch.as_secs() as _;
(*timeval_struct_ptr).tv_usec = since_epoch.subsec_nanos() as _; (*timeval_struct_ptr).tv_usec = since_epoch.subsec_nanos() as _;
@@ -73,7 +76,7 @@ pub fn _gettimeofday(ctx: &EmEnv, tp: c_int, tz: c_int) -> c_int {
0 0
} }
pub fn _clock_getres(_ctx: &EmEnv, _clk_id: i32, _tp: i32) -> i32 { pub fn _clock_getres(mut _ctx: ContextMut<'_, EmEnv>, _clk_id: i32, _tp: i32) -> i32 {
debug!("emscripten::_clock_getres"); debug!("emscripten::_clock_getres");
// clock_getres(clk_id, tp) // clock_getres(clk_id, tp)
0 0
@@ -81,7 +84,7 @@ pub fn _clock_getres(_ctx: &EmEnv, _clk_id: i32, _tp: i32) -> i32 {
/// emscripten: _clock_gettime /// emscripten: _clock_gettime
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _clock_gettime(ctx: &EmEnv, clk_id: clockid_t, tp: c_int) -> c_int { pub fn _clock_gettime(ctx: ContextMut<'_, EmEnv>, clk_id: clockid_t, tp: c_int) -> c_int {
debug!("emscripten::_clock_gettime {} {}", clk_id, tp); debug!("emscripten::_clock_gettime {} {}", clk_id, tp);
// debug!("Memory {:?}", ctx.memory(0)[..]); // debug!("Memory {:?}", ctx.memory(0)[..]);
#[repr(C)] #[repr(C)]
@@ -106,48 +109,48 @@ pub fn _clock_gettime(ctx: &EmEnv, clk_id: clockid_t, tp: c_int) -> c_int {
unsafe { unsafe {
let timespec_struct_ptr = let timespec_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), tp) as *mut GuestTimeSpec; emscripten_memory_pointer!(ctx, ctx.data().memory(0), tp) as *mut GuestTimeSpec;
(*timespec_struct_ptr).tv_sec = (duration / 1_000_000_000) as _; (*timespec_struct_ptr).tv_sec = (duration / 1_000_000_000) as _;
(*timespec_struct_ptr).tv_nsec = (duration % 1_000_000_000) as _; (*timespec_struct_ptr).tv_nsec = (duration % 1_000_000_000) as _;
} }
0 0
} }
pub fn _clock_settime(_ctx: &EmEnv, _clk_id: i32, _tp: i32) -> i32 { pub fn _clock_settime(mut _ctx: ContextMut<'_, EmEnv>, _clk_id: i32, _tp: i32) -> i32 {
debug!("emscripten::_clock_settime"); debug!("emscripten::_clock_settime");
// clock_settime(clk_id, tp) // clock_settime(clk_id, tp)
0 0
} }
/// emscripten: ___clock_gettime /// emscripten: ___clock_gettime
pub fn ___clock_gettime(ctx: &EmEnv, clk_id: clockid_t, tp: c_int) -> c_int { pub fn ___clock_gettime(ctx: ContextMut<'_, EmEnv>, clk_id: clockid_t, tp: c_int) -> c_int {
debug!("emscripten::___clock_gettime {} {}", clk_id, tp); debug!("emscripten::___clock_gettime {} {}", clk_id, tp);
_clock_gettime(ctx, clk_id, tp) _clock_gettime(ctx, clk_id, tp)
} }
/// emscripten: _clock /// emscripten: _clock
pub fn _clock(_ctx: &EmEnv) -> c_int { pub fn _clock(mut _ctx: ContextMut<'_, EmEnv>) -> c_int {
debug!("emscripten::_clock"); debug!("emscripten::_clock");
0 // TODO: unimplemented 0 // TODO: unimplemented
} }
/// emscripten: _difftime /// emscripten: _difftime
pub fn _difftime(_ctx: &EmEnv, t0: u32, t1: u32) -> f64 { pub fn _difftime(mut _ctx: ContextMut<'_, EmEnv>, t0: u32, t1: u32) -> f64 {
debug!("emscripten::_difftime"); debug!("emscripten::_difftime");
(t0 - t1) as _ (t0 - t1) as _
} }
pub fn _gmtime_r(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 { pub fn _gmtime_r(mut _ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_gmtime_r"); debug!("emscripten::_gmtime_r");
-1 -1
} }
pub fn _mktime(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _mktime(mut _ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_mktime"); debug!("emscripten::_mktime");
-1 -1
} }
pub fn _gmtime(_ctx: &EmEnv, _one: i32) -> i32 { pub fn _gmtime(mut _ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_gmtime"); debug!("emscripten::_gmtime");
-1 -1
} }
@@ -168,14 +171,14 @@ struct guest_tm {
} }
/// emscripten: _tvset /// emscripten: _tvset
pub fn _tvset(_ctx: &EmEnv) { pub fn _tvset(mut _ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_tvset UNIMPLEMENTED"); debug!("emscripten::_tvset UNIMPLEMENTED");
} }
/// formats time as a C string /// formats time as a C string
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
unsafe fn fmt_time(ctx: &EmEnv, time: u32) -> *const c_char { unsafe fn fmt_time(ctx: ContextMut<'_, EmEnv>, time: u32) -> *const c_char {
let date = &*(emscripten_memory_pointer!(ctx.memory(0), time) as *mut guest_tm); let date = &*(emscripten_memory_pointer!(ctx, ctx.data().memory(0), time) as *mut guest_tm);
let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
let months = vec![ let months = vec![
@@ -199,21 +202,21 @@ unsafe fn fmt_time(ctx: &EmEnv, time: u32) -> *const c_char {
} }
/// emscripten: _asctime /// emscripten: _asctime
pub fn _asctime(ctx: &EmEnv, time: u32) -> u32 { pub fn _asctime(mut ctx: ContextMut<'_, EmEnv>, time: u32) -> u32 {
debug!("emscripten::_asctime {}", time); debug!("emscripten::_asctime {}", time);
unsafe { unsafe {
let time_str_ptr = fmt_time(ctx, time); let time_str_ptr = fmt_time(ctx.as_context_mut(), time);
copy_cstr_into_wasm(ctx, time_str_ptr) copy_cstr_into_wasm(ctx, time_str_ptr)
// let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8; // let c_str = emscripten_memory_pointer!(ctx, ctx.data().memory(0), res) as *mut i8;
// use std::ffi::CStr; // use std::ffi::CStr;
// debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); // debug!("#### cstr = {:?}", CStr::from_ptr(c_str));
} }
} }
/// emscripten: _asctime_r /// emscripten: _asctime_r
pub fn _asctime_r(ctx: &EmEnv, time: u32, buf: u32) -> u32 { pub fn _asctime_r(mut ctx: ContextMut<'_, EmEnv>, time: u32, buf: u32) -> u32 {
debug!("emscripten::_asctime_r {}, {}", time, buf); debug!("emscripten::_asctime_r {}, {}", time, buf);
unsafe { unsafe {
@@ -221,10 +224,10 @@ pub fn _asctime_r(ctx: &EmEnv, time: u32, buf: u32) -> u32 {
// to write out more than 26 bytes (including the null terminator). // to write out more than 26 bytes (including the null terminator).
// See http://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html // See http://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html
// Our undefined behavior is to truncate the write to at most 26 bytes, including null terminator. // Our undefined behavior is to truncate the write to at most 26 bytes, including null terminator.
let time_str_ptr = fmt_time(ctx, time); let time_str_ptr = fmt_time(ctx.as_context_mut(), time);
write_to_buf(ctx, time_str_ptr, buf, 26) write_to_buf(ctx, time_str_ptr, buf, 26)
// let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8; // let c_str = emscripten_memory_pointer!(ctx, ctx.data().memory(0), res) as *mut i8;
// use std::ffi::CStr; // use std::ffi::CStr;
// debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); // debug!("#### cstr = {:?}", CStr::from_ptr(c_str));
} }
@@ -232,21 +235,22 @@ pub fn _asctime_r(ctx: &EmEnv, time: u32, buf: u32) -> u32 {
/// emscripten: _localtime /// emscripten: _localtime
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _localtime(ctx: &EmEnv, time_p: u32) -> c_int { pub fn _localtime(mut ctx: ContextMut<'_, EmEnv>, time_p: u32) -> c_int {
debug!("emscripten::_localtime {}", time_p); debug!("emscripten::_localtime {}", time_p);
// NOTE: emscripten seems to want tzset() called in this function // NOTE: emscripten seems to want tzset() called in this function
// https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r // https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r
let timespec = unsafe { let timespec = unsafe {
let time_p_addr = emscripten_memory_pointer!(ctx.memory(0), time_p) as *mut i64; let time_p_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), time_p) as *mut i64;
let seconds = *time_p_addr; let seconds = *time_p_addr;
time::OffsetDateTime::from_unix_timestamp(seconds) time::OffsetDateTime::from_unix_timestamp(seconds)
}; };
unsafe { unsafe {
let tm_struct_offset = env::call_malloc(ctx, mem::size_of::<guest_tm>() as _); let tm_struct_offset =
let tm_struct_ptr = env::call_malloc(ctx.as_context_mut(), mem::size_of::<guest_tm>() as _);
emscripten_memory_pointer!(ctx.memory(0), tm_struct_offset) as *mut guest_tm; let tm_struct_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), tm_struct_offset)
as *mut guest_tm;
// debug!( // debug!(
// ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}", // ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}",
// result_tm.tm_sec, result_tm.tm_min, result_tm.tm_hour, result_tm.tm_mday, // result_tm.tm_sec, result_tm.tm_min, result_tm.tm_hour, result_tm.tm_mday,
@@ -269,14 +273,14 @@ pub fn _localtime(ctx: &EmEnv, time_p: u32) -> c_int {
} }
/// emscripten: _localtime_r /// emscripten: _localtime_r
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _localtime_r(ctx: &EmEnv, time_p: u32, result: u32) -> c_int { pub fn _localtime_r(ctx: ContextMut<'_, EmEnv>, time_p: u32, result: u32) -> c_int {
debug!("emscripten::_localtime_r {}", time_p); debug!("emscripten::_localtime_r {}", time_p);
// NOTE: emscripten seems to want tzset() called in this function // NOTE: emscripten seems to want tzset() called in this function
// https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r // https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r
unsafe { unsafe {
let seconds = emscripten_memory_pointer!(ctx.memory(0), time_p) as *const i32; let seconds = emscripten_memory_pointer!(ctx, ctx.data().memory(0), time_p) as *const i32;
let timespec = time::OffsetDateTime::from_unix_timestamp_nanos(*seconds as _); let timespec = time::OffsetDateTime::from_unix_timestamp_nanos(*seconds as _);
// debug!( // debug!(
@@ -285,7 +289,8 @@ pub fn _localtime_r(ctx: &EmEnv, time_p: u32, result: u32) -> c_int {
// result_tm.tm_mon, result_tm.tm_year, result_tm.tm_wday, result_tm.tm_yday, // result_tm.tm_mon, result_tm.tm_year, result_tm.tm_wday, result_tm.tm_yday,
// ); // );
let result_addr = emscripten_memory_pointer!(ctx.memory(0), result) as *mut guest_tm; let result_addr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), result) as *mut guest_tm;
(*result_addr).tm_sec = timespec.second() as _; (*result_addr).tm_sec = timespec.second() as _;
(*result_addr).tm_min = timespec.minute() as _; (*result_addr).tm_min = timespec.minute() as _;
@@ -305,24 +310,27 @@ pub fn _localtime_r(ctx: &EmEnv, time_p: u32, result: u32) -> c_int {
/// emscripten: _time /// emscripten: _time
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _time(ctx: &EmEnv, time_p: u32) -> i32 { pub fn _time(ctx: ContextMut<'_, EmEnv>, time_p: u32) -> i32 {
debug!("emscripten::_time {}", time_p); debug!("emscripten::_time {}", time_p);
unsafe { unsafe {
let time_p_addr = emscripten_memory_pointer!(ctx.memory(0), time_p) as *mut i64; let time_p_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), time_p) as *mut i64;
libc_time(time_p_addr) as i32 // TODO review i64 libc_time(time_p_addr) as i32 // TODO review i64
} }
} }
pub fn _ctime_r(ctx: &EmEnv, time_p: u32, buf: u32) -> u32 { pub fn _ctime_r(mut ctx: ContextMut<'_, EmEnv>, time_p: u32, buf: u32) -> u32 {
debug!("emscripten::_ctime_r {} {}", time_p, buf); debug!("emscripten::_ctime_r {} {}", time_p, buf);
let (result_offset, _result_slice): (u32, &mut [u8]) = unsafe { allocate_on_stack(ctx, 44) }; // var stack = stackSave();
let time = _localtime_r(ctx, time_p, result_offset) as u32; let (result_offset, _result_slice): (u32, &mut [u8]) =
unsafe { allocate_on_stack(&mut ctx.as_context_mut(), 44) };
let time = _localtime_r(ctx.as_context_mut(), time_p, result_offset) as u32;
_asctime_r(ctx, time, buf) _asctime_r(ctx, time, buf)
// stackRestore(stack);
} }
pub fn _ctime(ctx: &EmEnv, time_p: u32) -> u32 { pub fn _ctime(ctx: ContextMut<'_, EmEnv>, time_p: u32) -> u32 {
debug!("emscripten::_ctime {}", time_p); debug!("emscripten::_ctime {}", time_p);
let tm_current = 2414544; let tm_current = 2414544;
_ctime_r(ctx, time_p, tm_current) _ctime_r(ctx, time_p, tm_current)
@@ -331,11 +339,12 @@ pub fn _ctime(ctx: &EmEnv, time_p: u32) -> u32 {
/// emscripten: _timegm /// emscripten: _timegm
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub fn _timegm(ctx: &EmEnv, time_ptr: u32) -> i32 { pub fn _timegm(ctx: ContextMut<'_, EmEnv>, time_ptr: u32) -> i32 {
debug!("emscripten::_timegm {}", time_ptr); debug!("emscripten::_timegm {}", time_ptr);
unsafe { unsafe {
let time_p_addr = emscripten_memory_pointer!(ctx.memory(0), time_ptr) as *mut guest_tm; let time_p_addr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), time_ptr) as *mut guest_tm;
let x: *mut c_char = CString::new("").expect("CString::new failed").into_raw(); let x: *mut c_char = CString::new("").expect("CString::new failed").into_raw();
let mut rust_tm = libc_tm { let mut rust_tm = libc_tm {
@@ -371,7 +380,7 @@ pub fn _timegm(ctx: &EmEnv, time_ptr: u32) -> i32 {
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub fn _timegm(_ctx: &EmEnv, _time_ptr: c_int) -> i32 { pub fn _timegm(mut _ctx: ContextMut<'_, EmEnv>, _time_ptr: c_int) -> i32 {
debug!( debug!(
"emscripten::_timegm - UNIMPLEMENTED IN WINDOWS {}", "emscripten::_timegm - UNIMPLEMENTED IN WINDOWS {}",
_time_ptr _time_ptr
@@ -380,18 +389,24 @@ pub fn _timegm(_ctx: &EmEnv, _time_ptr: c_int) -> i32 {
} }
/// emscripten: _strftime /// emscripten: _strftime
pub fn _strftime(ctx: &EmEnv, s_ptr: c_int, maxsize: u32, format_ptr: c_int, tm_ptr: c_int) -> i32 { pub fn _strftime(
ctx: ContextMut<'_, EmEnv>,
s_ptr: c_int,
maxsize: u32,
format_ptr: c_int,
tm_ptr: c_int,
) -> i32 {
debug!( debug!(
"emscripten::_strftime {} {} {} {}", "emscripten::_strftime {} {} {} {}",
s_ptr, maxsize, format_ptr, tm_ptr s_ptr, maxsize, format_ptr, tm_ptr
); );
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let s = emscripten_memory_pointer!(ctx.memory(0), s_ptr) as *mut c_char; let s = emscripten_memory_pointer!(ctx, ctx.data().memory(0), s_ptr) as *mut c_char;
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let format = emscripten_memory_pointer!(ctx.memory(0), format_ptr) as *const c_char; let format = emscripten_memory_pointer!(ctx, ctx.data().memory(0), format_ptr) as *const c_char;
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let tm = emscripten_memory_pointer!(ctx.memory(0), tm_ptr) as *const guest_tm; let tm = emscripten_memory_pointer!(ctx, ctx.data().memory(0), tm_ptr) as *const guest_tm;
let format_string = unsafe { std::ffi::CStr::from_ptr(format).to_str().unwrap() }; let format_string = unsafe { std::ffi::CStr::from_ptr(format).to_str().unwrap() };
@@ -428,7 +443,7 @@ pub fn _strftime(ctx: &EmEnv, s_ptr: c_int, maxsize: u32, format_ptr: c_int, tm_
/// emscripten: _strftime_l /// emscripten: _strftime_l
pub fn _strftime_l( pub fn _strftime_l(
ctx: &EmEnv, ctx: ContextMut<'_, EmEnv>,
s_ptr: c_int, s_ptr: c_int,
maxsize: u32, maxsize: u32,
format_ptr: c_int, format_ptr: c_int,

View File

@@ -1,20 +1,27 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn _getcontext(_ctx: &EmEnv, _ucp: i32) -> i32 { pub fn _getcontext(mut _ctx: ContextMut<'_, EmEnv>, _ucp: i32) -> i32 {
debug!("emscripten::_getcontext({})", _ucp); debug!("emscripten::_getcontext({})", _ucp);
0 0
} }
pub fn _makecontext(_ctx: &EmEnv, _ucp: i32, _func: i32, _argc: i32, _argv: i32) { pub fn _makecontext(
mut _ctx: ContextMut<'_, EmEnv>,
_ucp: i32,
_func: i32,
_argc: i32,
_argv: i32,
) {
debug!( debug!(
"emscripten::_makecontext({}, {}, {}, {})", "emscripten::_makecontext({}, {}, {}, {})",
_ucp, _func, _argc, _argv _ucp, _func, _argc, _argv
); );
} }
pub fn _setcontext(_ctx: &EmEnv, _ucp: i32) -> i32 { pub fn _setcontext(mut _ctx: ContextMut<'_, EmEnv>, _ucp: i32) -> i32 {
debug!("emscripten::_setcontext({})", _ucp); debug!("emscripten::_setcontext({})", _ucp);
0 0
} }
pub fn _swapcontext(_ctx: &EmEnv, _oucp: i32, _ucp: i32) -> i32 { pub fn _swapcontext(mut _ctx: ContextMut<'_, EmEnv>, _oucp: i32, _ucp: i32) -> i32 {
debug!("emscripten::_swapcontext({}, {})", _oucp, _ucp); debug!("emscripten::_swapcontext({}, {})", _oucp, _ucp);
0 0
} }

View File

@@ -1,6 +1,7 @@
use crate::EmEnv; use crate::EmEnv;
use wasmer::ContextMut;
pub fn confstr(_ctx: &EmEnv, _name: i32, _buf_pointer: i32, _len: i32) -> i32 { pub fn confstr(mut _ctx: ContextMut<'_, EmEnv>, _name: i32, _buf_pointer: i32, _len: i32) -> i32 {
debug!("unistd::confstr({}, {}, {})", _name, _buf_pointer, _len); debug!("unistd::confstr({}, {}, {})", _name, _buf_pointer, _len);
0 0
} }

View File

@@ -1,5 +1,5 @@
use super::env; use super::env;
use super::env::get_emscripten_data; use super::env::{get_emscripten_data, get_emscripten_funcs};
use crate::storage::align_memory; use crate::storage::align_memory;
use crate::EmEnv; use crate::EmEnv;
use libc::stat; use libc::stat;
@@ -8,7 +8,7 @@ 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, Memory, Module, Pages, WasmPtr}; use wasmer::{AsContextMut, ContextMut, GlobalInit, Memory, Module, Pages, WasmPtr};
/// 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 {
@@ -93,8 +93,13 @@ pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, St
} }
} }
pub unsafe fn write_to_buf(ctx: &EmEnv, string: *const c_char, buf: u32, max: u32) -> u32 { pub unsafe fn write_to_buf(
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_char; ctx: ContextMut<'_, EmEnv>,
string: *const c_char,
buf: u32,
max: u32,
) -> u32 {
let buf_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *mut c_char;
for i in 0..max { for i in 0..max {
*buf_addr.add(i as _) = *string.add(i as _); *buf_addr.add(i as _) = *string.add(i as _);
@@ -104,11 +109,12 @@ pub unsafe fn write_to_buf(ctx: &EmEnv, string: *const c_char, buf: u32, max: u3
} }
/// This function expects nullbyte to be appended. /// This function expects nullbyte to be appended.
pub unsafe fn copy_cstr_into_wasm(ctx: &EmEnv, cstr: *const c_char) -> u32 { pub unsafe fn copy_cstr_into_wasm(mut ctx: ContextMut<'_, EmEnv>, cstr: *const c_char) -> u32 {
let s = CStr::from_ptr(cstr).to_str().unwrap(); let s = CStr::from_ptr(cstr).to_str().unwrap();
let cstr_len = s.len(); let cstr_len = s.len();
let space_offset = env::call_malloc(ctx, (cstr_len as u32) + 1); let space_offset = env::call_malloc(ctx.as_context_mut(), (cstr_len as u32) + 1);
let raw_memory = emscripten_memory_pointer!(ctx.memory(0), space_offset) as *mut c_char; let raw_memory =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), space_offset) as *mut c_char;
let slice = slice::from_raw_parts_mut(raw_memory, cstr_len); let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
for (byte, loc) in s.bytes().zip(slice.iter_mut()) { for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
@@ -124,14 +130,16 @@ pub unsafe fn copy_cstr_into_wasm(ctx: &EmEnv, cstr: *const c_char) -> u32 {
/// # Safety /// # Safety
/// This method is unsafe because it operates directly with the slice of memory represented by the address /// This method is unsafe because it operates directly with the slice of memory represented by the address
pub unsafe fn allocate_on_stack<T: Copy>(ctx: &EmEnv, count: u32) -> (u32, &mut [T]) { pub unsafe fn allocate_on_stack<'a, T: Copy>(
let offset = get_emscripten_data(ctx) ctx: &mut ContextMut<'a, EmEnv>,
.stack_alloc_ref() count: u32,
.unwrap() ) -> (u32, &'a mut [T]) {
.call(count * (size_of::<T>() as u32)) let stack_alloc_ref = get_emscripten_funcs(ctx).stack_alloc_ref().unwrap().clone();
let offset = stack_alloc_ref
.call(&mut ctx.as_context_mut(), count * (size_of::<T>() as u32))
.unwrap(); .unwrap();
let addr = emscripten_memory_pointer!(ctx.memory(0), offset) as *mut T; let addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), offset) as *mut T;
let slice = slice::from_raw_parts_mut(addr, count as usize); let slice = slice::from_raw_parts_mut(addr, count as usize);
(offset, slice) (offset, slice)
@@ -139,7 +147,10 @@ pub unsafe fn allocate_on_stack<T: Copy>(ctx: &EmEnv, count: u32) -> (u32, &mut
/// # Safety /// # Safety
/// This method is unsafe because it uses `allocate_on_stack` which is unsafe /// This method is unsafe because it uses `allocate_on_stack` which is unsafe
pub unsafe fn allocate_cstr_on_stack<'a>(ctx: &'a EmEnv, s: &str) -> (u32, &'a [u8]) { pub unsafe fn allocate_cstr_on_stack<'a>(
ctx: &'a mut ContextMut<'a, EmEnv>,
s: &str,
) -> (u32, &'a [u8]) {
let (offset, slice) = allocate_on_stack(ctx, (s.len() + 1) as u32); let (offset, slice) = allocate_on_stack(ctx, (s.len() + 1) as u32);
use std::iter; use std::iter;
@@ -151,7 +162,10 @@ pub unsafe fn allocate_cstr_on_stack<'a>(ctx: &'a EmEnv, s: &str) -> (u32, &'a [
} }
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
pub unsafe fn copy_terminated_array_of_cstrs(_ctx: &EmEnv, cstrs: *mut *mut c_char) -> u32 { pub unsafe fn copy_terminated_array_of_cstrs(
mut _ctx: ContextMut<'_, EmEnv>,
cstrs: *mut *mut c_char,
) -> u32 {
let _total_num = { let _total_num = {
let mut ptr = cstrs; let mut ptr = cstrs;
let mut counter = 0; let mut counter = 0;
@@ -189,8 +203,8 @@ pub struct GuestStat {
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub unsafe fn copy_stat_into_wasm(ctx: &EmEnv, buf: u32, stat: &stat) { pub unsafe fn copy_stat_into_wasm(ctx: ContextMut<'_, EmEnv>, buf: u32, stat: &stat) {
let stat_ptr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut GuestStat; let stat_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *mut GuestStat;
(*stat_ptr).st_dev = stat.st_dev as _; (*stat_ptr).st_dev = stat.st_dev as _;
(*stat_ptr).__st_dev_padding = 0; (*stat_ptr).__st_dev_padding = 0;
(*stat_ptr).__st_ino_truncated = stat.st_ino as _; (*stat_ptr).__st_ino_truncated = stat.st_ino as _;
@@ -217,20 +231,20 @@ pub unsafe fn copy_stat_into_wasm(ctx: &EmEnv, buf: u32, stat: &stat) {
} }
#[allow(dead_code)] // it's used in `env/windows/mod.rs`. #[allow(dead_code)] // it's used in `env/windows/mod.rs`.
pub fn read_string_from_wasm(memory: &Memory, offset: u32) -> String { pub fn read_string_from_wasm(ctx: ContextMut<'_, EmEnv>, memory: &Memory, offset: u32) -> String {
WasmPtr::<u8>::new(offset) WasmPtr::<u8>::new(offset)
.read_utf8_string_with_nul(memory) .read_utf8_string_with_nul(&ctx, memory)
.unwrap() .unwrap()
} }
/// This function trys to find an entry in mapdir /// This function trys to find an entry in mapdir
/// translating paths into their correct value /// translating paths into their correct value
pub fn get_cstr_path(ctx: &EmEnv, path: *const i8) -> Option<std::ffi::CString> { pub fn get_cstr_path(ctx: ContextMut<'_, EmEnv>, path: *const i8) -> Option<std::ffi::CString> {
use std::collections::VecDeque; use std::collections::VecDeque;
let path_str = let path_str =
unsafe { std::ffi::CStr::from_ptr(path as *const _).to_str().unwrap() }.to_string(); unsafe { std::ffi::CStr::from_ptr(path as *const _).to_str().unwrap() }.to_string();
let data = get_emscripten_data(ctx); let data = get_emscripten_data(&ctx);
let path = PathBuf::from(path_str); let path = PathBuf::from(path_str);
let mut prefix_added = false; let mut prefix_added = false;
let mut components = path.components().collect::<VecDeque<_>>(); let mut components = path.components().collect::<VecDeque<_>>();
@@ -261,13 +275,13 @@ pub fn get_cstr_path(ctx: &EmEnv, path: *const i8) -> Option<std::ffi::CString>
/// gets the current directory /// gets the current directory
/// handles mapdir logic /// handles mapdir logic
pub fn get_current_directory(ctx: &EmEnv) -> Option<PathBuf> { pub fn get_current_directory(ctx: ContextMut<'_, EmEnv>) -> Option<PathBuf> {
if let Some(val) = get_emscripten_data(ctx).mapped_dirs.get(".") { if let Some(val) = get_emscripten_data(&ctx).mapped_dirs.get(".") {
return Some(val.clone()); return Some(val.clone());
} }
std::env::current_dir() std::env::current_dir()
.map(|cwd| { .map(|cwd| {
if let Some(val) = get_emscripten_data(ctx) if let Some(val) = get_emscripten_data(&ctx)
.mapped_dirs .mapped_dirs
.get(&cwd.to_string_lossy().to_string()) .get(&cwd.to_string_lossy().to_string())
{ {

View File

@@ -3,6 +3,7 @@ use std::mem;
use wasmer::FromToNativeWasmType; use wasmer::FromToNativeWasmType;
// use std::ffi::CStr; // use std::ffi::CStr;
use std::os::raw::c_char; use std::os::raw::c_char;
use wasmer::ContextMut;
#[repr(transparent)] #[repr(transparent)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@@ -11,15 +12,18 @@ pub struct VarArgs {
} }
impl VarArgs { impl VarArgs {
pub fn get<T: Sized>(&mut self, ctx: &EmEnv) -> T { pub fn get<T: Sized>(&mut self, ctx: &ContextMut<'_, EmEnv>) -> T {
let ptr = emscripten_memory_pointer!(ctx.memory(0), self.pointer); let ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), self.pointer);
self.pointer += mem::size_of::<T>() as u32; self.pointer += mem::size_of::<T>() as u32;
unsafe { (ptr as *const T).read() } unsafe { (ptr as *const T).read() }
} }
pub fn get_str(&mut self, ctx: &EmEnv) -> *const c_char { // pub fn getStr<'a>(&mut self, ctx: &mut Ctx) -> &'a CStr {
pub fn get_str(&mut self, ctx: &ContextMut<'_, EmEnv>) -> *const c_char {
let ptr_addr: u32 = self.get(ctx); let ptr_addr: u32 = self.get(ctx);
emscripten_memory_pointer!(ctx.memory(0), ptr_addr) as *const c_char let ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), ptr_addr) as *const c_char;
ptr
// unsafe { CStr::from_ptr(ptr) }
} }
} }