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",
"time",
"wasmer",
"wasmer-types",
]
[[package]]

View File

@@ -16,7 +16,8 @@ lazy_static = "1.4"
libc = "^0.2"
log = "0.4"
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]
getrandom = "0.2"

View File

@@ -1,8 +1,9 @@
use crate::emscripten_target;
use crate::EmEnv;
use wasmer::ContextMut;
///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");
emscripten_target::setTempRet0(ctx, _low.swap_bytes());
high.swap_bytes()

View File

@@ -1,35 +1,36 @@
#![allow(non_snake_case)]
use crate::env::get_emscripten_data;
use crate::env::{get_emscripten_data, get_emscripten_funcs};
use crate::EmEnv;
#[cfg(target_os = "linux")]
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);
0
}
pub fn exit_with_live_runtime(_ctx: &EmEnv) {
pub fn exit_with_live_runtime(_ctx: ContextMut<'_, EmEnv>) {
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);
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");
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);
0
}
pub fn _atexit(_ctx: &EmEnv, _func: i32) -> i32 {
pub fn _atexit(_ctx: ContextMut<'_, EmEnv>, _func: i32) -> i32 {
debug!("emscripten::_atexit");
// TODO: implement atexit properly
// __ATEXIT__.unshift({
@@ -38,38 +39,38 @@ pub fn _atexit(_ctx: &EmEnv, _func: i32) -> i32 {
// });
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");
0
}
pub fn __Unwind_FindEnclosingFunction(_ctx: &EmEnv, _a: i32) -> i32 {
pub fn __Unwind_FindEnclosingFunction(_ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
debug!("emscripten::__Unwind_FindEnclosingFunction");
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");
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");
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");
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");
}
pub fn ___resumeException(_ctx: &EmEnv, _a: i32) {
pub fn ___resumeException(_ctx: ContextMut<'_, EmEnv>, _a: i32) {
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");
0
}
pub fn ___gxx_personality_v0(
_ctx: &EmEnv,
_ctx: ContextMut<'_, EmEnv>,
_a: i32,
_b: i32,
_c: i32,
@@ -82,25 +83,25 @@ pub fn ___gxx_personality_v0(
}
#[cfg(target_os = "linux")]
pub fn _getdtablesize(_ctx: &EmEnv) -> i32 {
pub fn _getdtablesize(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::getdtablesize");
unsafe { getdtablesize() }
}
#[cfg(not(target_os = "linux"))]
pub fn _getdtablesize(_ctx: &EmEnv) -> i32 {
pub fn _getdtablesize(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::getdtablesize");
-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");
0
}
pub fn _gethostbyname(_ctx: &EmEnv, _name: i32) -> i32 {
pub fn _gethostbyname(_ctx: ContextMut<'_, EmEnv>, _name: i32) -> i32 {
debug!("emscripten::gethostbyname_r");
0
}
pub fn _gethostbyname_r(
_ctx: &EmEnv,
_ctx: ContextMut<'_, EmEnv>,
_name: i32,
_ret: i32,
_buf: i32,
@@ -112,13 +113,13 @@ pub fn _gethostbyname_r(
0
}
// 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");
0
}
#[allow(clippy::too_many_arguments)]
pub fn _getnameinfo(
_ctx: &EmEnv,
_ctx: ContextMut<'_, EmEnv>,
_addr: i32,
_addrlen: i32,
_host: i32,
@@ -140,15 +141,18 @@ pub fn _getnameinfo(
// Macro definitions
macro_rules! invoke {
($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 call = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone();
match call.call($($arg),*) {
let funcs = get_emscripten_funcs(&$ctx).clone();
let sp = funcs.stack_save_ref().expect("stack_save is None").call(&mut $ctx.as_context_mut()).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,
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
// 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 _
}
}
@@ -156,15 +160,19 @@ macro_rules! invoke {
}
macro_rules! invoke_no_return {
($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 call = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone();
match call.call($($arg),*) {
let funcs = get_emscripten_funcs(&$ctx).clone();
let stack = funcs.stack_save_ref().expect("stack_save is None");
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,
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
// 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
macro_rules! invoke_no_stack_save {
($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
pub fn invoke_i(ctx: &EmEnv, index: i32) -> i32 {
pub fn invoke_i(mut ctx: ContextMut<'_, EmEnv>, index: i32) -> i32 {
debug!("emscripten::invoke_i");
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");
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");
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");
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");
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");
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");
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");
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");
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");
invoke_no_return!(
ctx,
@@ -229,11 +245,18 @@ pub fn invoke_viiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32)
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");
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");
invoke!(
ctx,
@@ -246,7 +269,14 @@ pub fn invoke_diiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32)
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");
invoke!(
ctx,
@@ -259,7 +289,15 @@ pub fn invoke_iiiii(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32)
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");
invoke!(
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)]
pub fn invoke_iiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -300,7 +338,7 @@ pub fn invoke_iiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -327,7 +365,7 @@ pub fn invoke_iiiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -356,7 +394,7 @@ pub fn invoke_iiiiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -387,7 +425,7 @@ pub fn invoke_iiiiiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_iiiiiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -418,11 +456,19 @@ pub fn invoke_iiiiiiiiiii(
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");
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");
invoke_no_return!(
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)]
pub fn invoke_viiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -463,7 +509,7 @@ pub fn invoke_viiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -490,7 +536,7 @@ pub fn invoke_viiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -519,7 +565,7 @@ pub fn invoke_viiiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -550,7 +596,7 @@ pub fn invoke_viiiiiiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_viiiiiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: 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");
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");
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");
invoke!(ctx, dyn_call_iiji, dyn_call_iiji_ref, index, a1, a2, a3, a4)
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_iiijj(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -622,28 +675,43 @@ pub fn invoke_iiijj(
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");
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");
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");
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");
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");
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");
invoke_no_stack_save!(
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)]
pub fn invoke_viiijiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -690,7 +758,7 @@ pub fn invoke_viiijiiii(
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_viiijiiiiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -723,11 +791,19 @@ pub fn invoke_viiijiiiiii(
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");
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");
invoke_no_stack_save!(
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)]
pub fn invoke_viijiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -769,7 +845,16 @@ pub fn invoke_viijiii(
)
}
#[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");
invoke_no_stack_save!(
ctx,
@@ -784,11 +869,19 @@ pub fn invoke_viijj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
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");
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");
invoke_no_return!(
ctx,
@@ -802,17 +895,17 @@ pub fn invoke_vjji(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
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");
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");
invoke_no_stack_save!(ctx, dyn_call_viji, dyn_call_viji_ref, index, a1, a2, a3, a4)
}
#[allow(clippy::too_many_arguments)]
pub fn invoke_vijiii(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,
@@ -835,7 +928,15 @@ pub fn invoke_vijiii(
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");
invoke_no_stack_save!(
ctx,
@@ -849,15 +950,23 @@ pub fn invoke_vijj(ctx: &EmEnv, index: i32, a1: i32, a2: i32, a3: i32, a4: i32,
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");
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");
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");
invoke_no_return!(
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)]
pub fn invoke_viidddddddd(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
index: i32,
a1: i32,
a2: i32,

View File

@@ -12,54 +12,55 @@ pub use self::windows::*;
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::sync::MutexGuard;
use crate::EmEnv;
use wasmer::ValueType;
use wasmer::WasmPtr;
use wasmer::{AsContextMut, ContextMut, WasmPtr};
pub fn call_malloc(ctx: &EmEnv, size: u32) -> u32 {
get_emscripten_data(ctx)
.malloc_ref()
.unwrap()
.call(size)
.unwrap()
pub fn call_malloc(mut ctx: ContextMut<'_, EmEnv>, size: u32) -> u32 {
let malloc_ref = get_emscripten_funcs(&ctx).malloc_ref().unwrap().clone();
malloc_ref.call(&mut ctx.as_context_mut(), size).unwrap()
}
#[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))
}
pub fn call_memalign(ctx: &EmEnv, alignment: u32, size: u32) -> u32 {
if let Some(memalign) = &get_emscripten_data(ctx).memalign_ref() {
memalign.call(alignment, size).unwrap()
} else {
panic!("Memalign is set to None");
}
pub fn call_memalign(mut ctx: ContextMut<'_, EmEnv>, alignment: u32, size: u32) -> u32 {
let memalign_ref = get_emscripten_funcs(&ctx).memalign_ref().unwrap().clone();
memalign_ref.call(&mut ctx, alignment, size).unwrap()
}
pub fn call_memset(ctx: &EmEnv, pointer: u32, value: u32, size: u32) -> u32 {
get_emscripten_data(ctx)
.memset_ref()
.unwrap()
.call(pointer, value, size)
pub fn call_memset(mut ctx: ContextMut<'_, EmEnv>, pointer: u32, value: u32, size: u32) -> u32 {
let memset_ref = get_emscripten_funcs(&ctx).memset_ref().unwrap().clone();
memset_ref
.call(&mut ctx.as_context_mut(), pointer, value, size)
.unwrap()
}
pub(crate) fn get_emscripten_data(ctx: &EmEnv) -> MutexGuard<EmscriptenData> {
ctx.data.lock().unwrap()
pub(crate) fn get_emscripten_data<'a>(
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");
16384
}
pub fn _times(ctx: &EmEnv, buffer: u32) -> u32 {
pub fn _times(ctx: ContextMut<'_, EmEnv>, buffer: u32) -> u32 {
if buffer != 0 {
call_memset(ctx, buffer, 0, 16);
}
@@ -67,18 +68,20 @@ pub fn _times(ctx: &EmEnv, buffer: u32) -> u32 {
}
#[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);
const MAX_ENV_VALUES: u32 = 64;
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 (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]) =
allocate_on_stack(ctx, (MAX_ENV_VALUES * 4) as u32);
let env_ptr = emscripten_memory_pointer!(ctx.memory(0), env_offset) as *mut c_int;
let pool_ptr = emscripten_memory_pointer!(ctx.memory(0), pool_offset) as *mut u8;
allocate_on_stack(&mut ctx.as_context_mut(), (MAX_ENV_VALUES * 4) as u32);
let env_ptr =
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;
*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);
// TODO: Implement like emscripten expects regarding memory/page size
// 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!(
"emscripten::_pathconf {} {} - UNIMPLEMENTED",
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 {
0 => 32000,
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);
match name {
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::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
use crate::EmEnv;
use wasmer::WasmPtr;
use wasmer::{AsContextMut, ContextMut, WasmPtr};
// #[no_mangle]
/// 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");
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) });
@@ -30,11 +30,11 @@ pub fn _getenv(ctx: &EmEnv, name: i32) -> u32 {
}
/// 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");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char;
let value_addr = emscripten_memory_pointer!(ctx.memory(0), value) 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, ctx.data().memory(0), value) as *const c_char;
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_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);
pub fn _putenv(ctx: &EmEnv, name: c_int) -> c_int {
pub fn _putenv(ctx: ContextMut<'_, EmEnv>, name: c_int) -> c_int {
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) });
@@ -54,10 +54,10 @@ pub fn _putenv(ctx: &EmEnv, name: c_int) -> c_int {
}
/// 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");
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) });
@@ -65,7 +65,7 @@ pub fn _unsetenv(ctx: &EmEnv, name: c_int) -> c_int {
}
#[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);
#[cfg(feature = "debug")]
let _ = name_ptr;
@@ -82,21 +82,25 @@ pub fn _getpwnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
}
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)
};
unsafe {
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 =
emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd;
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx, passwd.pw_name);
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(ctx, passwd.pw_passwd);
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx, passwd.pw_gecos);
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx, passwd.pw_dir);
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx, passwd.pw_shell);
emscripten_memory_pointer!(ctx, memory, passwd_struct_offset) as *mut GuestPasswd;
(*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.as_context_mut(), passwd.pw_passwd);
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_gecos);
(*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_gid = passwd.pw_gid;
@@ -105,7 +109,7 @@ pub fn _getpwnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
}
#[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);
#[repr(C)]
@@ -117,18 +121,21 @@ pub fn _getgrnam(ctx: &EmEnv, name_ptr: c_int) -> c_int {
}
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)
};
unsafe {
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 =
emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup;
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(ctx, group.gr_name);
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(ctx, group.gr_passwd);
emscripten_memory_pointer!(ctx, ctx.data().memory(0), group_struct_offset)
as *mut GuestGroup;
(*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_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);
// TODO: Implement like emscripten expects regarding memory/page size
unsafe { sysconf(name) as i32 } // TODO review i64
}
// 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);
let cstr = unsafe { std::ffi::CStr::from_ptr(libc::gai_strerror(ecode)) };
let bytes = cstr.to_bytes_with_nul();
let string_on_guest: WasmPtr<c_char> = call_malloc_with_cast(ctx, bytes.len() as _);
let memory = ctx.memory(0);
let string_on_guest: WasmPtr<c_char> =
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() {
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(
ctx: &EmEnv,
mut ctx: ContextMut<'_, EmEnv>,
node_ptr: WasmPtr<c_char>,
service_str_ptr: WasmPtr<c_char>,
hints_ptr: WasmPtr<EmAddrInfo>,
@@ -168,7 +178,7 @@ pub fn _getaddrinfo(
) -> i32 {
use libc::{addrinfo, freeaddrinfo};
debug!("emscripten::_getaddrinfo");
let memory = ctx.memory(0);
let memory = ctx.data().memory(0);
debug!(" => node = {}", {
if node_ptr.is_null() {
std::borrow::Cow::Borrowed("null")
@@ -187,7 +197,7 @@ pub fn _getaddrinfo(
let hints = if hints_ptr.is_null() {
None
} else {
let hints_guest = hints_ptr.deref(&memory).read().unwrap();
let hints_guest = hints_ptr.deref(&ctx, &memory).read().unwrap();
Some(addrinfo {
ai_flags: hints_guest.ai_flags,
ai_family: hints_guest.ai_family,
@@ -234,14 +244,14 @@ pub fn _getaddrinfo(
while !current_host_node.is_null() {
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() {
head_of_list = Some(current_guest_node_ptr);
}
// connect list
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();
pg.ai_next = current_guest_node_ptr;
derefed_prev_guest.write(pg).unwrap();
@@ -254,9 +264,9 @@ pub fn _getaddrinfo(
let guest_sockaddr_ptr = {
let host_sockaddr_ptr = (*current_host_node).ai_addr;
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();
gs.sa_family = (*host_sockaddr_ptr).sa_family as i16;
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 str_size = canonname_bytes.len();
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 =
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() {
guest_canonname_writer
.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();
cgn.ai_flags = (*current_host_node).ai_flags;
cgn.ai_family = (*current_host_node).ai_family;
@@ -310,7 +320,10 @@ pub fn _getaddrinfo(
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
}

View File

@@ -1,7 +1,8 @@
// use std::collections::HashMap;
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);
// TODO: Incomplete impl
eprintln!("failed to set errno!");

View File

@@ -1,56 +1,57 @@
use super::env;
use super::process::_abort;
use crate::EmEnv;
use wasmer::ContextMut;
/// 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");
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");
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);
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);
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);
unimplemented!("emscripten::___cxa_rethrow_primary_exception({})", _a)
}
/// emscripten: ___cxa_throw
/// 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");
eprintln!("Throwing exceptions not yet implemented: aborting!");
_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");
-1
}
pub fn ___cxa_end_catch(_ctx: &EmEnv) {
pub fn ___cxa_end_catch(_ctx: ContextMut<'_, EmEnv>) {
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");
-1
}
pub fn ___cxa_pure_virtual(_ctx: &EmEnv) {
pub fn ___cxa_pure_virtual(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::___cxa_pure_virtual");
// ABORT = true
panic!("Pure virtual function called!");

View File

@@ -3,27 +3,27 @@ use crate::EmEnv;
use libc::c_char;
use libc::execvp as libc_execvp;
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
let emscripten_memory = ctx.memory(0);
let emscripten_memory = ctx.data().memory(0);
// read command name as string
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();
let command_name_string = CString::new(command_name_string_vec).unwrap();
// get the array of args
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();
let arg_strings: Vec<CString> = argv
.into_iter()
.map(|ptr| {
let vec = ptr
.read_until(&emscripten_memory, |&byte| byte == 0)
.read_until(&ctx, &emscripten_memory, |&byte| byte == 0)
.unwrap();
CString::new(vec).unwrap()
})
@@ -40,13 +40,23 @@ pub fn execvp(ctx: &EmEnv, command_name_offset: u32, argv_offset: u32) -> i32 {
}
/// 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");
-1
}
/// 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");
-1
}

View File

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

View File

@@ -1,6 +1,7 @@
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);
0
}

View File

@@ -11,25 +11,26 @@ pub use self::unix::*;
pub use self::windows::*;
use crate::EmEnv;
use wasmer::ContextMut;
/// getprotobyname
pub fn getprotobyname(_ctx: &EmEnv, _name_ptr: i32) -> i32 {
pub fn getprotobyname(_ctx: ContextMut<'_, EmEnv>, _name_ptr: i32) -> i32 {
debug!("emscripten::getprotobyname");
unimplemented!("emscripten::getprotobyname")
}
/// getprotobynumber
pub fn getprotobynumber(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn getprotobynumber(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::getprotobynumber");
unimplemented!("emscripten::getprotobynumber")
}
/// 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");
let memory = ctx.memory(0);
let memory = ctx.data().memory(0);
#[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)) }
@@ -37,11 +38,11 @@ pub fn sigdelset(ctx: &EmEnv, set: i32, signum: i32) -> i32 {
}
/// sigfillset
pub fn sigfillset(ctx: &EmEnv, set: i32) -> i32 {
pub fn sigfillset(ctx: ContextMut<'_, EmEnv>, set: i32) -> i32 {
debug!("emscripten::sigfillset");
let memory = ctx.memory(0);
let memory = ctx.data().memory(0);
#[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;
@@ -51,13 +52,13 @@ pub fn sigfillset(ctx: &EmEnv, set: i32) -> i32 {
}
/// tzset
pub fn tzset(_ctx: &EmEnv) {
pub fn tzset(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::tzset - stub");
//unimplemented!("emscripten::tzset - stub")
}
/// 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");
unimplemented!("emscripten::strptime")
}

View File

@@ -4,31 +4,32 @@ use libc::{chroot as _chroot, getpwuid as _getpwuid, printf as _printf};
use std::mem;
use crate::EmEnv;
use wasmer::{AsContextMut, ContextMut};
/// putchar
pub fn putchar(_ctx: &EmEnv, chr: i32) {
pub fn putchar(_ctx: ContextMut<'_, EmEnv>, chr: i32) {
unsafe { libc::putchar(chr) };
}
/// 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);
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)
}
}
/// chroot
pub fn chroot(ctx: &EmEnv, name_ptr: i32) -> i32 {
pub fn chroot(ctx: ContextMut<'_, EmEnv>, name_ptr: i32) -> i32 {
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 _) }
}
/// getpwuid
#[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);
#[repr(C)]
@@ -44,18 +45,21 @@ pub fn getpwuid(ctx: &EmEnv, uid: i32) -> i32 {
unsafe {
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 =
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!(
passwd_struct_ptr as usize % std::mem::align_of::<GuestPasswd>(),
0
);
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx, passwd.pw_name);
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(ctx, passwd.pw_passwd);
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx, passwd.pw_gecos);
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx, passwd.pw_dir);
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx, passwd.pw_shell);
(*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.as_context_mut(), passwd.pw_passwd);
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx.as_context_mut(), passwd.pw_gecos);
(*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_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 libc::c_int;
// use std::cell::UnsafeCell;
use crate::EmEnv;
use std::error::Error;
use std::fmt;
use wasmer::{AsContextMut, ContextMut};
/// 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)");
abort_with_message(ctx, "missing function: _setjmp");
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;
// // We create the jump buffer outside of the wasm memory
// 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 _);
// // We set the jump index to be the last 3value of jumps
// *jump_index = jumps.len() as _;
@@ -30,13 +31,13 @@ pub fn __setjmp(ctx: &EmEnv, _env_addr: u32) -> c_int {
/// longjmp
#[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)");
abort_with_message(ctx, "missing function: _longjmp");
// unsafe {
// // We retrieve the jump index from the env address
// 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
// let jump_buf = &jumps[*jump_index as usize];
// longjmp(jump_buf.get() as _, val)
@@ -57,12 +58,18 @@ impl Error for LongJumpRet {}
/// _longjmp
// This function differs from the js implementation, it should return Result<(), &'static str>
#[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 };
get_emscripten_data(ctx)
let threw = get_emscripten_funcs(&ctx)
.set_threw_ref()
.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");
Err(LongJumpRet)
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +1,77 @@
extern crate libc;
use crate::EmEnv;
use wasmer::ContextMut;
#[cfg(unix)]
use std::convert::TryInto;
pub fn current_sigrtmax() -> i32 {
pub fn current_sigrtmax(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::current_sigrtmax");
0
}
pub fn current_sigrtmin() -> i32 {
pub fn current_sigrtmin(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::current_sigrtmin");
0
}
pub fn endpwent() {
pub fn endpwent(_ctx: ContextMut<'_, EmEnv>) {
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");
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");
0
}
pub fn fpathconf(_a: i32, _b: i32) -> i32 {
pub fn fpathconf(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::fpathconf");
0
}
pub fn getitimer(_a: i32, _b: i32) -> i32 {
pub fn getitimer(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::getitimer");
0
}
pub fn getpwent() -> i32 {
pub fn getpwent(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::getpwent");
0
}
pub fn killpg(_a: i32, _b: i32) -> i32 {
pub fn killpg(_ctx: ContextMut<'_, EmEnv>, _a: i32, _b: i32) -> i32 {
debug!("emscripten::killpg");
0
}
#[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");
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() }
}
#[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");
0
}
pub fn setpwent() {
pub fn setpwent(_ctx: ContextMut<'_, EmEnv>) {
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");
0
}
pub fn sigpending(_a: i32) -> i32 {
pub fn sigpending(_ctx: ContextMut<'_, EmEnv>, _a: i32) -> i32 {
debug!("emscripten::sigpending");
0
}

View File

@@ -1,27 +1,28 @@
use crate::EmEnv;
use wasmer::ContextMut;
// TODO: Need to implement.
/// 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");
-1
}
/// 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");
-1
}
/// 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");
-1
}
/// emscripten: dlerror() -> *mut c_char
pub fn _dlerror(_ctx: &EmEnv) -> i32 {
pub fn _dlerror(mut _ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::_dlerror");
-1
}

View File

@@ -1,22 +1,29 @@
use crate::EmEnv;
use libc::c_int;
use wasmer::ContextMut;
// 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);
}
// 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);
}
// 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");
}
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");
0
}

View File

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

View File

@@ -1,110 +1,111 @@
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)
}
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)
}
/// 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");
value.log10()
}
/// 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");
value.log2()
}
/// 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");
value.sin()
}
/// 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");
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");
-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");
-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");
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");
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");
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");
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");
-1.0
}
// 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");
x % y
}
// 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)
}
// emscripten: global.Math exp
pub fn exp(value: f64) -> f64 {
pub fn exp(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.exp()
}
// emscripten: global.Math log
pub fn log(value: f64) -> f64 {
pub fn log(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.ln()
}
// emscripten: global.Math sqrt
pub fn sqrt(value: f64) -> f64 {
pub fn sqrt(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.sqrt()
}
// emscripten: global.Math floor
pub fn floor(value: f64) -> f64 {
pub fn floor(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.floor()
}
// emscripten: global.Math fabs
pub fn fabs(value: f64) -> f64 {
pub fn fabs(mut _ctx: ContextMut<'_, EmEnv>, value: f64) -> f64 {
value.abs()
}
// 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);
value as i32
}

View File

@@ -3,26 +3,32 @@ use super::process::abort_with_message;
use crate::EmEnv;
use libc::{c_int, c_void, memcpy, size_t};
// 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
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!(
"emscripten::_emscripten_memcpy_big {}, {}, {}",
dest, src, len
);
let dest_addr = emscripten_memory_pointer!(ctx.memory(0), dest) as *mut c_void;
let src_addr = emscripten_memory_pointer!(ctx.memory(0), src) 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, ctx.data().memory(0), src) as *mut c_void;
unsafe {
memcpy(dest_addr, src_addr, len as size_t);
}
dest
}
fn get_heap_size(ctx: &ContextMut<'_, EmEnv>) -> u32 {
ctx.data().memory(0).size(&ctx).bytes().0 as u32
}
/// 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");
let result = ctx.memory(0).size().bytes().0 as u32;
let result = get_heap_size(&ctx);
trace!("=> {}", result);
result
@@ -36,11 +42,9 @@ fn align_up(mut val: usize, multiple: usize) -> usize {
val
}
/// emscripten: _emscripten_resize_heap
/// Note: this function only allows growing the size of heap
pub fn _emscripten_resize_heap(ctx: &EmEnv, requested_size: u32) -> u32 {
fn resize_heap(ctx: &mut ContextMut<'_, EmEnv>, requested_size: u32) -> u32 {
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;
// 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;
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);
1
} 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
pub fn sbrk(ctx: &EmEnv, increment: i32) -> i32 {
pub fn sbrk(mut ctx: ContextMut<'_, EmEnv>, increment: i32) -> i32 {
debug!("emscripten::sbrk");
// let old_dynamic_top = 0;
// let new_dynamic_top = 0;
let memory = ctx.memory(0);
let dynamictop_ptr = {
let globals = &get_emscripten_data(ctx).globals;
WasmPtr::<i32>::new(globals.dynamictop_ptr).deref(&memory)
};
let memory = ctx.data().memory(0);
let top_ptr = get_emscripten_data(&ctx).globals.dynamictop_ptr;
let dynamictop_ptr = WasmPtr::<i32>::new(top_ptr).deref(&ctx, &memory);
let old_dynamic_top = dynamictop_ptr.read().unwrap();
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!(
" => PTR {}, old: {}, new: {}, increment: {}, total: {}",
dynamictop_ptr.offset(),
@@ -94,25 +106,27 @@ pub fn sbrk(ctx: &EmEnv, increment: i32) -> i32 {
return -1;
}
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 {
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();
old_dynamic_top as _
}
/// emscripten: getTotalMemory
pub fn get_total_memory(_ctx: &EmEnv) -> u32 {
pub fn get_total_memory(ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::get_total_memory");
// instance.memories[0].current_pages()
// TODO: Fix implementation
_ctx.memory(0).size().bytes().0 as u32
ctx.data().memory(0).size(&ctx).bytes().0 as u32
}
/// emscripten: enlargeMemory
pub fn enlarge_memory(_ctx: &EmEnv) -> u32 {
pub fn enlarge_memory(_ctx: ContextMut<'_, EmEnv>) -> u32 {
debug!("emscripten::enlarge_memory");
// instance.memories[0].grow(100);
// TODO: Fix implementation
@@ -120,7 +134,7 @@ pub fn enlarge_memory(_ctx: &EmEnv) -> u32 {
}
/// 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!(
"emscripten::abort_on_cannot_grow_memory {}",
_requested_size
@@ -130,32 +144,32 @@ pub fn abort_on_cannot_grow_memory(ctx: &EmEnv, _requested_size: u32) -> u32 {
}
/// 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");
abort_with_message(ctx, "Cannot enlarge memory arrays!");
0
}
/// emscripten: segfault
pub fn segfault(ctx: &EmEnv) {
pub fn segfault(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::segfault");
abort_with_message(ctx, "segmentation fault");
}
/// emscripten: alignfault
pub fn alignfault(ctx: &EmEnv) {
pub fn alignfault(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::alignfault");
abort_with_message(ctx, "alignment fault");
}
/// emscripten: ftfault
pub fn ftfault(ctx: &EmEnv) {
pub fn ftfault(ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::ftfault");
abort_with_message(ctx, "Function table mask error");
}
/// 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");
// NOTE: TODO: Em returns -1 here as well. May need to implement properly
-1

View File

@@ -6,34 +6,35 @@ type PidT = libc::pid_t;
type PidT = c_int;
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");
println!("{}", message);
_abort(ctx);
}
/// 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");
eprintln!("Program aborted with value {}", arg);
_abort(ctx);
}
pub fn _abort(_ctx: &EmEnv) {
pub fn _abort(_ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_abort");
unsafe {
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");
abort_with_message(ctx, "missing function: prctl");
-1
}
pub fn _fork(_ctx: &EmEnv) -> PidT {
pub fn _fork(_ctx: ContextMut<'_, EmEnv>) -> PidT {
debug!("emscripten::_fork");
// unsafe {
// fork()
@@ -41,132 +42,132 @@ pub fn _fork(_ctx: &EmEnv) -> PidT {
-1
}
pub fn _endgrent(_ctx: &EmEnv) {
pub fn _endgrent(_ctx: ContextMut<'_, EmEnv>) {
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");
-1
}
#[allow(unreachable_code)]
pub fn _exit(_ctx: &EmEnv, status: c_int) {
pub fn _exit(_ctx: ContextMut<'_, EmEnv>, status: c_int) {
// -> !
debug!("emscripten::_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");
-1
}
pub fn _sched_yield(_ctx: &EmEnv) -> i32 {
pub fn _sched_yield(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::_sched_yield");
-1
}
pub fn _llvm_stacksave(_ctx: &EmEnv) -> i32 {
pub fn _llvm_stacksave(_ctx: ContextMut<'_, EmEnv>) -> i32 {
debug!("emscripten::_llvm_stacksave");
-1
}
pub fn _llvm_stackrestore(_ctx: &EmEnv, _one: i32) {
pub fn _llvm_stackrestore(_ctx: ContextMut<'_, EmEnv>, _one: i32) {
debug!("emscripten::_llvm_stackrestore");
}
pub fn _raise(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _raise(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_raise");
-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);
0
}
pub fn _sem_destroy(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _sem_destroy(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sem_destroy");
0
}
pub fn _sem_post(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _sem_post(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sem_post");
-1
}
pub fn _sem_wait(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _sem_wait(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sem_post");
-1
}
#[allow(clippy::cast_ptr_alignment)]
pub fn _getgrent(_ctx: &EmEnv) -> c_int {
pub fn _getgrent(_ctx: ContextMut<'_, EmEnv>) -> c_int {
debug!("emscripten::_getgrent");
-1
}
pub fn _setgrent(_ctx: &EmEnv) {
pub fn _setgrent(_ctx: ContextMut<'_, EmEnv>) {
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");
-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");
-1
}
pub fn _usleep(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _usleep(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_usleep");
-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");
-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");
-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");
-1
}
pub fn _wait(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _wait(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_wait");
-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");
-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");
-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");
-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");
-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");
// TODO: Message incomplete. Need to finish em runtime data first
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");
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");
-1
}
pub fn _system(_ctx: &EmEnv, _one: i32) -> c_int {
pub fn _system(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> c_int {
debug!("emscripten::_system");
// TODO: May need to change this Em impl to a working version
eprintln!("Can't call external programs");
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");
// TODO: May need to change this Em impl to a working version
eprintln!("Missing function: popen");

View File

@@ -1,11 +1,17 @@
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");
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!(
"emscripten::_pthread_attr_getstack({}, {}, {})",
_stackaddr,
@@ -18,175 +24,175 @@ pub fn _pthread_attr_getstack(_ctx: &EmEnv, _stackaddr: i32, _stacksize: i32, _o
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);
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");
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");
}
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");
}
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");
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");
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");
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");
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");
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");
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");
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");
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");
// 11 seems to mean "no"
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");
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");
0
}
pub fn _pthread_exit(_ctx: &EmEnv, _a: i32) {
pub fn _pthread_exit(mut _ctx: ContextMut<'_, EmEnv>, _a: i32) {
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);
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");
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");
0
}
pub fn _pthread_self(_ctx: &EmEnv) -> i32 {
pub fn _pthread_self(mut _ctx: ContextMut<'_, EmEnv>) -> i32 {
trace!("emscripten::_pthread_self");
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");
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");
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");
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");
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");
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");
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");
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);
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);
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");
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");
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);
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");
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");
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");
0
}

View File

@@ -1,47 +1,48 @@
// use super::varargs::VarArgs;
use crate::EmEnv;
use wasmer::ContextMut;
#[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");
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 {
*set_addr = 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);
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);
0
}
#[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);
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 {
*set_addr |= 1 << (signum - 1);
}
0
}
pub fn _sigsuspend(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _sigsuspend(_ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_sigsuspend");
-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");
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);
0
}

View File

@@ -48,54 +48,54 @@ use super::env;
#[allow(unused_imports)]
use std::io::Error;
use std::slice;
use wasmer::WasmPtr;
use wasmer::{AsContextMut, ContextMut, WasmPtr};
/// 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);
let status: i32 = varargs.get(ctx);
let status: i32 = varargs.get(&ctx);
unsafe {
exit(status);
}
}
/// 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
debug!("emscripten::___syscall3 (read) {}", _which);
let fd: i32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx);
let count: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let buf: u32 = varargs.get(&ctx);
let count: i32 = varargs.get(&ctx);
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 _) };
debug!("=> ret: {}", ret);
ret as _
}
/// 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);
let fd: i32 = varargs.get(ctx);
let buf: i32 = varargs.get(ctx);
let count: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let buf: i32 = varargs.get(&ctx);
let count: i32 = varargs.get(&ctx);
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 }
}
/// 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);
let fd: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
debug!("fd: {}", fd);
unsafe { close(fd) }
}
// 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);
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 = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
@@ -111,63 +111,63 @@ pub fn ___syscall12(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
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");
-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");
-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");
-1
}
// 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)");
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");
-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");
-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");
-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");
-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");
-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");
-1
}
// 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)");
let old_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 old_path = varargs.get_str(&ctx);
let new_path = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
@@ -190,9 +190,9 @@ pub fn ___syscall38(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
}
// 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)");
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 = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
@@ -203,16 +203,16 @@ pub fn ___syscall40(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
}
// 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)");
// 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
let mut fd_vec: [c_int; 2] = WasmPtr::<[c_int; 2]>::new(fd_offset)
.deref(&emscripten_memory)
.deref(&ctx, &emscripten_memory)
.read()
.unwrap();
@@ -230,133 +230,133 @@ pub fn ___syscall42(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
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");
-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");
-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");
-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");
-1
}
// 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);
let src: i32 = varargs.get(ctx);
let dst: i32 = varargs.get(ctx);
let src: i32 = varargs.get(&ctx);
let dst: i32 = varargs.get(&ctx);
unsafe { dup2(src, dst) }
}
// 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)");
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");
-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");
-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");
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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-1
}
// 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");
let buf_offset: WasmPtr<libc::c_char> = varargs.get(ctx);
let _size: c_int = varargs.get(ctx);
let path = get_current_directory(ctx);
let buf_offset: WasmPtr<libc::c_char> = varargs.get(&ctx);
let _size: c_int = varargs.get(&ctx);
let path = get_current_directory(ctx.as_context_mut());
let path_string = path.unwrap().display().to_string();
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() {
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
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);
let _addr: i32 = varargs.get(ctx);
let len: u32 = varargs.get(ctx);
let _prot: i32 = varargs.get(ctx);
let _flags: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(ctx);
let _off: i32 = varargs.get(ctx);
let _addr: i32 = varargs.get(&ctx);
let len: u32 = varargs.get(&ctx);
let _prot: i32 = varargs.get(&ctx);
let _flags: i32 = varargs.get(&ctx);
let fd: i32 = varargs.get(&ctx);
let _off: i32 = varargs.get(&ctx);
debug!(
"=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}",
_addr, len, _prot, _flags, fd, _off
);
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 {
// ENOMEM
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);
for i in 0..(len as usize) {
unsafe {
@@ -400,19 +400,19 @@ pub fn ___syscall192(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
/// 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
debug!("emscripten::___syscall140 (lseek) {}", _which);
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_low: u32 = varargs.get(ctx);
let result_ptr_value: WasmPtr<i64> = varargs.get(ctx);
let whence: 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_low: u32 = varargs.get(&ctx);
let result_ptr_value: WasmPtr<i64> = varargs.get(&ctx);
let whence: i32 = varargs.get(&ctx);
let offset = offset_low;
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();
debug!(
@@ -429,13 +429,13 @@ pub fn ___syscall140(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
/// readv
#[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
debug!("emscripten::___syscall145 (readv) {}", _which);
let fd: i32 = varargs.get(ctx);
let iov: i32 = varargs.get(ctx);
let iovcnt: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let iov: i32 = varargs.get(&ctx);
let iovcnt: i32 = varargs.get(&ctx);
#[repr(C)]
struct GuestIovec {
@@ -448,9 +448,11 @@ pub fn ___syscall145(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
unsafe {
for i in 0..iovcnt {
let guest_iov_addr =
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec;
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
as *mut c_void;
emscripten_memory_pointer!(ctx, ctx.data().memory(0), (iov + i * 8))
as *mut GuestIovec;
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 _;
// debug!("=> iov_addr: {:?}, {:?}", 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
#[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
debug!("emscripten::___syscall146 (writev) {}", _which);
let fd: i32 = varargs.get(ctx);
let iov: i32 = varargs.get(ctx);
let iovcnt: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let iov: i32 = varargs.get(&ctx);
let iovcnt: i32 = varargs.get(&ctx);
#[repr(C)]
struct GuestIovec {
@@ -484,9 +486,11 @@ pub fn ___syscall146(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
for i in 0..iovcnt {
unsafe {
let guest_iov_addr =
emscripten_memory_pointer!(ctx.memory(0), (iov + i * 8)) as *mut GuestIovec;
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
as *const c_void;
emscripten_memory_pointer!(ctx, ctx.data().memory(0), (iov + i * 8))
as *mut GuestIovec;
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 _;
// debug!("=> iov_addr: {:?}, {:?}", 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 _
}
pub fn ___syscall191(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
let _resource: i32 = varargs.get(ctx);
pub fn ___syscall191(ctx: ContextMut<'_, EmEnv>, _which: i32, mut varargs: VarArgs) -> i32 {
let _resource: i32 = varargs.get(&ctx);
debug!(
"emscripten::___syscall191 - mostly stub, resource: {}",
_resource
);
let rlim_emptr: i32 = varargs.get(ctx);
let rlim_ptr = emscripten_memory_pointer!(ctx.memory(0), rlim_emptr) as *mut u8;
let rlim_emptr: i32 = varargs.get(&ctx);
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) };
// set all to RLIM_INIFINTY
@@ -524,18 +528,18 @@ pub fn ___syscall191(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
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");
-1
}
// 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);
let pathname_addr = varargs.get_str(ctx);
let buf: u32 = varargs.get(ctx);
let pathname_addr = varargs.get_str(&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 {
rp.as_c_str().as_ptr()
} else {
@@ -561,11 +565,11 @@ pub fn ___syscall195(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
// 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);
let fd: c_int = varargs.get(ctx);
let buf: u32 = varargs.get(ctx);
let fd: c_int = varargs.get(&ctx);
let buf: u32 = varargs.get(&ctx);
unsafe {
let mut stat = std::mem::zeroed();
@@ -580,135 +584,135 @@ pub fn ___syscall197(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-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");
-1
}
// 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);
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");
-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");
-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");
-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");
-1
}
// 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);
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway.
let _pid: i32 = varargs.get(ctx);
let resource: i32 = varargs.get(ctx);
let _new_limit: u32 = varargs.get(ctx);
let old_limit: u32 = varargs.get(ctx);
let _pid: i32 = varargs.get(&ctx);
let resource: i32 = varargs.get(&ctx);
let _new_limit: u32 = varargs.get(&ctx);
let old_limit: u32 = varargs.get(&ctx);
let val = match resource {
// RLIMIT_NOFILE
@@ -718,7 +722,7 @@ pub fn ___syscall340(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
if old_limit != 0 {
// 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) };
LittleEndian::write_i64(&mut *buf, val);
@@ -728,7 +732,7 @@ pub fn ___syscall340(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
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");
-1
}

View File

@@ -81,7 +81,7 @@ use libc::{
// TCGETS,
// TCSETSW,
};
use wasmer::{ValueType, WasmPtr};
use wasmer::{AsContextMut, ContextMut, ValueType, WasmPtr};
// They are not exposed in in Rust libc in macOS
const TCGETS: u64 = 0x5401;
@@ -157,12 +157,12 @@ use libc::SO_NOSIGPIPE;
const SO_NOSIGPIPE: c_int = 0;
/// 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);
let pathname_addr = varargs.get_str(ctx);
let flags: i32 = varargs.get(ctx);
let mode: u32 = varargs.get(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let pathname_addr = varargs.get_str(&ctx);
let flags: i32 = varargs.get(&ctx);
let mode: u32 = varargs.get(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
@@ -181,11 +181,11 @@ pub fn ___syscall5(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
}
/// 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);
let oldname_ptr = varargs.get_str(ctx);
let newname_ptr = varargs.get_str(ctx);
let oldname_ptr = varargs.get_str(&ctx);
let newname_ptr = varargs.get_str(&ctx);
let result = unsafe { link(oldname_ptr, newname_ptr) };
debug!(
"=> oldname: {}, newname: {}, result: {}",
@@ -197,30 +197,30 @@ pub fn ___syscall9(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
}
/// 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);
let resource: c_int = varargs.get(ctx);
let rusage_ptr: c_int = varargs.get(ctx);
let resource: c_int = varargs.get(&ctx);
let rusage_ptr: c_int = varargs.get(&ctx);
#[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));
unsafe { getrusage(resource, rusage) }
}
/// 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);
let path1 = varargs.get_str(ctx);
let path2 = varargs.get_str(ctx);
let real_path1_owned = utils::get_cstr_path(ctx, path1 as *const _);
let path1 = varargs.get_str(&ctx);
let path2 = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
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 {
rp.as_c_str().as_ptr()
} else {
@@ -237,13 +237,13 @@ pub fn ___syscall83(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
}
/// 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)");
let pathname_addr = varargs.get_str(ctx);
let buf = varargs.get_str(ctx);
// let buf_addr: i32 = varargs.get(ctx);
let buf_size: i32 = varargs.get(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let pathname_addr = varargs.get_str(&ctx);
let buf = varargs.get_str(&ctx);
// let buf_addr: i32 = varargs.get(&ctx);
let buf_size: i32 = varargs.get(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
@@ -266,10 +266,10 @@ pub fn ___syscall85(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> i32 {
}
/// 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);
let _fd: c_int = varargs.get(ctx);
let _length: i64 = varargs.get(ctx);
let _fd: c_int = varargs.get(&ctx);
let _length: i64 = varargs.get(&ctx);
#[cfg(not(any(target_os = "freebsd", target_vendor = "apple")))]
unsafe {
ftruncate64(_fd, _length)
@@ -283,17 +283,17 @@ pub fn ___syscall194(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
/// 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);
let path_ptr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path_ptr as *const _);
let path_ptr = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
path_ptr
};
let uid: uid_t = varargs.get(ctx);
let gid: gid_t = varargs.get(ctx);
let uid: uid_t = varargs.get(&ctx);
let gid: gid_t = varargs.get(&ctx);
let result = unsafe { lchown(real_path, uid, gid) };
debug!(
"=> path: {}, uid: {}, gid: {}, result: {}",
@@ -306,13 +306,13 @@ pub fn ___syscall198(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
/// 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);
let ngroups_max: c_int = varargs.get(ctx);
let groups: c_int = varargs.get(ctx);
let ngroups_max: c_int = varargs.get(&ctx);
let groups: c_int = varargs.get(&ctx);
#[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));
let result = unsafe { getgroups(ngroups_max, gid_ptr) };
debug!(
@@ -323,46 +323,46 @@ pub fn ___syscall205(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
// 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);
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let pathname_addr = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
pathname_addr
};
let owner: u32 = varargs.get(ctx);
let group: u32 = varargs.get(ctx);
let owner: u32 = varargs.get(&ctx);
let group: u32 = varargs.get(&ctx);
unsafe { chown(real_path, owner, group) }
}
/// 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);
let addr_ptr: c_int = varargs.get(ctx);
let len: usize = varargs.get(ctx);
let advice: c_int = varargs.get(ctx);
let addr_ptr: c_int = varargs.get(&ctx);
let len: usize = 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) }
}
/// 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);
let path = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _);
let path = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
path
};
let amode: c_int = varargs.get(ctx);
let amode: c_int = varargs.get(&ctx);
let result = unsafe { access(real_path, amode) };
debug!(
"=> path: {}, amode: {}, result: {}",
@@ -374,41 +374,41 @@ pub fn ___syscall33(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
}
/// 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);
let inc_r: c_int = varargs.get(ctx);
let inc_r: c_int = varargs.get(&ctx);
unsafe { nice(inc_r) }
}
// 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);
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let pathname_addr = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
pathname_addr
};
let mode: u32 = varargs.get(ctx);
let mode: u32 = varargs.get(&ctx);
unsafe { mkdir(real_path, mode as _) }
}
/// 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);
let fd: c_int = varargs.get(ctx);
let fd: c_int = varargs.get(&ctx);
unsafe { dup(fd) }
}
/// 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)");
unsafe { getgid() as i32 }
}
// 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)");
unsafe {
// Maybe fix: Emscripten returns 0 always
@@ -417,7 +417,7 @@ pub fn ___syscall201(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
}
// getegid32
pub fn ___syscall202(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
pub fn ___syscall202(_ctx: ContextMut<'_, EmEnv>, _one: i32, _two: i32) -> i32 {
// gid_t
debug!("emscripten::___syscall202 (getegid32)");
unsafe {
@@ -427,21 +427,21 @@ pub fn ___syscall202(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
}
/// 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);
let fd: c_int = varargs.get(ctx);
let owner: uid_t = varargs.get(ctx);
let group: gid_t = varargs.get(ctx);
let fd: c_int = varargs.get(&ctx);
let owner: uid_t = varargs.get(&ctx);
let group: gid_t = varargs.get(&ctx);
unsafe { fchown(fd, owner, group) }
}
/// 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
debug!("emscripten::___syscall330 (dup3)");
let oldfd: c_int = varargs.get(ctx);
let newfd: c_int = varargs.get(ctx);
let flags: c_int = varargs.get(ctx);
let oldfd: c_int = varargs.get(&ctx);
let newfd: c_int = varargs.get(&ctx);
let flags: c_int = varargs.get(&ctx);
if oldfd == newfd {
return EINVAL;
@@ -474,19 +474,20 @@ pub fn ___syscall330(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> pid_t
}
/// 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);
let fd: i32 = varargs.get(ctx);
let request: u32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let request: u32 = varargs.get(&ctx);
debug!("=> fd: {}, op: {}", fd, request);
// Got the equivalents here: https://code.woboq.org/linux/linux/include/uapi/asm-generic/ioctls.h.html
match request {
WASM_FIOCLEX | WASM_FIONBIO | WASM_TIOCGWINSZ | WASM_TIOCSPGRP | WASM_TCGETS
| WASM_TCSETSW => {
let argp: u32 = varargs.get(ctx);
let argp_ptr = emscripten_memory_pointer!(ctx.memory(0), argp) as *mut c_void;
let argp: u32 = varargs.get(&ctx);
let argp_ptr =
emscripten_memory_pointer!(ctx, ctx.data().memory(0), argp) as *mut c_void;
let translated_request = translate_ioctl(request);
let ret = unsafe { ioctl(fd, translated_request as _, argp_ptr) };
debug!(
@@ -516,11 +517,11 @@ const SOCK_CLOEXC: i32 = 0x80000;
// socketcall
#[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);
let call: u32 = varargs.get(ctx);
let mut socket_varargs: VarArgs = varargs.get(ctx);
let memory = ctx.memory(0);
let call: u32 = varargs.get(&ctx);
let mut socket_varargs: VarArgs = varargs.get(&ctx);
let memory = ctx.data().memory(0);
// migrating to EmSockAddr, port being separate here is nice, should update that too
#[repr(C)]
@@ -541,9 +542,9 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
1 => {
debug!("socket: socket");
// socket (domain: c_int, ty: c_int, protocol: c_int) -> c_int
let domain: i32 = socket_varargs.get(ctx);
let ty_and_flags: i32 = socket_varargs.get(ctx);
let protocol: i32 = socket_varargs.get(ctx);
let domain: i32 = socket_varargs.get(&ctx);
let ty_and_flags: i32 = socket_varargs.get(&ctx);
let protocol: i32 = socket_varargs.get(&ctx);
let ty = ty_and_flags & (!SOCK_NON_BLOCK) & (!SOCK_CLOEXC);
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");
// bind (socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int
// TODO: Emscripten has a different signature.
let socket = socket_varargs.get(ctx);
let address: u32 = socket_varargs.get(ctx);
let address_len = socket_varargs.get(ctx);
let address = emscripten_memory_pointer!(&memory, address) as *mut sockaddr;
let socket = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(&ctx);
let address_len = socket_varargs.get(&ctx);
let address = emscripten_memory_pointer!(ctx, &memory, address) as *mut sockaddr;
// Debug received address
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");
// connect (socket: c_int, address: *const sockaddr, len: socklen_t) -> c_int
// TODO: Emscripten has a different signature.
let socket = socket_varargs.get(ctx);
let address: u32 = socket_varargs.get(ctx);
let address_len = socket_varargs.get(ctx);
let address = emscripten_memory_pointer!(&memory, address) as *mut sockaddr;
let socket = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(&ctx);
let address_len = socket_varargs.get(&ctx);
let address = emscripten_memory_pointer!(ctx, &memory, address) as *mut sockaddr;
unsafe { connect(socket, address, address_len) }
}
4 => {
debug!("socket: listen");
// listen (socket: c_int, backlog: c_int) -> c_int
let socket = socket_varargs.get(ctx);
let backlog: i32 = socket_varargs.get(ctx);
let socket = socket_varargs.get(&ctx);
let backlog: i32 = socket_varargs.get(&ctx);
let status = unsafe { listen(socket, backlog) };
debug!(
"=> socketfd: {}, backlog: {} = status: {}",
@@ -628,17 +629,17 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
5 => {
debug!("socket: accept");
// accept (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
let socket: i32 = socket_varargs.get(ctx);
let address: WasmPtr<EmSockAddr> = socket_varargs.get(ctx);
let address_len: WasmPtr<u32> = socket_varargs.get(ctx);
let socket: i32 = socket_varargs.get(&ctx);
let address: WasmPtr<EmSockAddr> = socket_varargs.get(&ctx);
let address_len: WasmPtr<u32> = socket_varargs.get(&ctx);
debug!(
"=> socket: {}, address: {:?}, address_len: {}",
socket,
address.deref(&memory).read().unwrap(),
address_len.deref(&memory).read().unwrap()
address.deref(&ctx, &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 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(),
};
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_data = host_address.sa_data;
@@ -669,10 +670,10 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
6 => {
debug!("socket: getsockname");
// getsockname (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
let socket: i32 = socket_varargs.get(ctx);
let address: WasmPtr<EmSockAddr> = socket_varargs.get(ctx);
let address_len: WasmPtr<u32> = socket_varargs.get(ctx);
let address_len_addr = address_len.deref(&memory).read().unwrap();
let socket: i32 = socket_varargs.get(&ctx);
let address: WasmPtr<EmSockAddr> = socket_varargs.get(&ctx);
let address_len: WasmPtr<u32> = socket_varargs.get(&ctx);
let address_len_addr = address_len.deref(&ctx, &memory).read().unwrap();
let mut sock_addr_host: sockaddr = sockaddr {
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
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_data = sock_addr_host.sa_data;
@@ -702,40 +703,40 @@ pub fn ___syscall102(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
7 => {
debug!("socket: getpeername");
// getpeername (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
let socket = socket_varargs.get(ctx);
let address: u32 = socket_varargs.get(ctx);
let address_len: u32 = socket_varargs.get(ctx);
let address = emscripten_memory_pointer!(memory, address) as *mut sockaddr;
let socket = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(&ctx);
let address_len: u32 = socket_varargs.get(&ctx);
let address = emscripten_memory_pointer!(ctx, memory, address) as *mut sockaddr;
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) }
}
11 => {
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
let socket = socket_varargs.get(ctx);
let buf: u32 = socket_varargs.get(ctx);
let flags = socket_varargs.get(ctx);
let len: i32 = socket_varargs.get(ctx);
let address: u32 = socket_varargs.get(ctx);
let address_len = socket_varargs.get(ctx);
let buf_addr = emscripten_memory_pointer!(memory, buf) as _;
let address = emscripten_memory_pointer!(memory, address) as *mut sockaddr;
let socket = socket_varargs.get(&ctx);
let buf: u32 = socket_varargs.get(&ctx);
let flags = socket_varargs.get(&ctx);
let len: i32 = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(&ctx);
let address_len = socket_varargs.get(&ctx);
let buf_addr = emscripten_memory_pointer!(ctx, memory, buf) as _;
let address = emscripten_memory_pointer!(ctx, memory, address) as *mut sockaddr;
unsafe { sendto(socket, buf_addr, flags, len, address, address_len) as i32 }
}
12 => {
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
let socket = socket_varargs.get(ctx);
let buf: u32 = socket_varargs.get(ctx);
let len: i32 = socket_varargs.get(ctx);
let flags: i32 = socket_varargs.get(ctx);
let address: u32 = socket_varargs.get(ctx);
let address_len: u32 = socket_varargs.get(ctx);
let buf_addr = emscripten_memory_pointer!(memory, buf) as _;
let address = emscripten_memory_pointer!(memory, address) as *mut sockaddr;
let socket = socket_varargs.get(&ctx);
let buf: u32 = socket_varargs.get(&ctx);
let len: i32 = socket_varargs.get(&ctx);
let flags: i32 = socket_varargs.get(&ctx);
let address: u32 = socket_varargs.get(&ctx);
let address_len: u32 = socket_varargs.get(&ctx);
let buf_addr = emscripten_memory_pointer!(ctx, memory, buf) as _;
let address = emscripten_memory_pointer!(ctx, memory, address) as *mut sockaddr;
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 {
recvfrom(
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
// 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 level: i32 = socket_varargs.get(ctx);
let socket = socket_varargs.get(&ctx);
let level: i32 = socket_varargs.get(&ctx);
let level = if level == 1 { SOL_SOCKET } else { level };
let untranslated_name: i32 = socket_varargs.get(ctx);
let value: 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 untranslated_name: i32 = socket_varargs.get(&ctx);
let value: u32 = socket_varargs.get(&ctx);
let option_len: u32 = socket_varargs.get(&ctx);
let value_addr = emscripten_memory_pointer!(ctx, memory, value) as *const libc::c_void;
let name: i32 = translate_socket_name_flag(untranslated_name);
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 => {
debug!("socket: getsockopt");
// 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 level: i32 = socket_varargs.get(ctx);
let socket = socket_varargs.get(&ctx);
let level: i32 = socket_varargs.get(&ctx);
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 value: u32 = socket_varargs.get(ctx);
let option_len: u32 = socket_varargs.get(ctx);
let value_addr = emscripten_memory_pointer!(memory, value) as _;
let option_len_addr = emscripten_memory_pointer!(memory, option_len) as *mut socklen_t;
let value: u32 = socket_varargs.get(&ctx);
let option_len: u32 = socket_varargs.get(&ctx);
let value_addr = emscripten_memory_pointer!(ctx, memory, value) as _;
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) }
}
16 => {
debug!("socket: sendmsg");
// sendmsg (fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t
let socket: i32 = socket_varargs.get(ctx);
let msg: u32 = socket_varargs.get(ctx);
let flags: i32 = socket_varargs.get(ctx);
let msg_addr = emscripten_memory_pointer!(memory, msg) as *const msghdr;
let socket: i32 = socket_varargs.get(&ctx);
let msg: u32 = socket_varargs.get(&ctx);
let flags: i32 = socket_varargs.get(&ctx);
let msg_addr = emscripten_memory_pointer!(ctx, memory, msg) as *const msghdr;
unsafe { sendmsg(socket, msg_addr, flags) as i32 }
}
17 => {
debug!("socket: recvmsg");
// recvmsg (fd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t
let socket: i32 = socket_varargs.get(ctx);
let msg: u32 = socket_varargs.get(ctx);
let flags: i32 = socket_varargs.get(ctx);
let msg_addr = emscripten_memory_pointer!(memory, msg) as *mut msghdr;
let socket: i32 = socket_varargs.get(&ctx);
let msg: u32 = socket_varargs.get(&ctx);
let flags: i32 = socket_varargs.get(&ctx);
let msg_addr = emscripten_memory_pointer!(ctx, memory, msg) as *mut msghdr;
unsafe { recvmsg(socket, msg_addr, flags) as i32 }
}
_ => {
@@ -831,10 +833,10 @@ fn translate_socket_name_flag(name: i32) -> i32 {
}
/// 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)");
let pid: pid_t = varargs.get(ctx);
let pid: pid_t = varargs.get(&ctx);
let ret = unsafe { getpgid(pid) };
debug!("=> pid: {} = {}", pid, ret);
@@ -853,14 +855,14 @@ pub struct EmPollFd {
}
/// 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)");
let fds: WasmPtr<EmPollFd> = varargs.get(ctx);
let nfds: u32 = varargs.get(ctx);
let timeout: i32 = varargs.get(ctx);
let memory = ctx.memory(0);
let fds: WasmPtr<EmPollFd> = varargs.get(&ctx);
let nfds: u32 = varargs.get(&ctx);
let timeout: i32 = varargs.get(&ctx);
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 {
libc::poll(
@@ -872,35 +874,35 @@ pub fn ___syscall168(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
}
// 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);
let fd: i32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx);
let count: u32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let buf: 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);
}
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 _ }
}
// 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);
let fd: i32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx);
let count: u32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let buf: 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);
}
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 _ };
debug!(
"=> fd: {}, buf: {}, count: {}, offset: {} = status:{}",
@@ -910,24 +912,24 @@ pub fn ___syscall181(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
/// 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);
let fd: c_int = varargs.get(ctx);
let mode: mode_t = varargs.get(ctx);
let fd: c_int = varargs.get(&ctx);
let mode: mode_t = varargs.get(&ctx);
unsafe { fchmod(fd, mode) }
}
/// wait4
#[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)");
let pid: pid_t = varargs.get(ctx);
let status: u32 = varargs.get(ctx);
let options: c_int = varargs.get(ctx);
let rusage: u32 = varargs.get(ctx);
let status_addr = emscripten_memory_pointer!(ctx.memory(0), status) as *mut c_int;
let pid: pid_t = varargs.get(&ctx);
let status: u32 = varargs.get(&ctx);
let options: c_int = varargs.get(&ctx);
let rusage: u32 = varargs.get(&ctx);
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) };
debug!(
"=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}",
@@ -937,22 +939,22 @@ pub fn ___syscall114(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> pid_t
}
/// 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);
let fd: c_int = varargs.get(ctx);
let fd: c_int = varargs.get(&ctx);
unsafe { fsync(fd) }
}
// select
#[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);
let nfds: i32 = varargs.get(ctx);
let readfds: u32 = varargs.get(ctx);
let writefds: u32 = varargs.get(ctx);
let exceptfds: u32 = varargs.get(ctx);
let _timeout: i32 = varargs.get(ctx);
let nfds: i32 = varargs.get(&ctx);
let readfds: u32 = varargs.get(&ctx);
let writefds: u32 = varargs.get(&ctx);
let exceptfds: u32 = varargs.get(&ctx);
let _timeout: i32 = varargs.get(&ctx);
if nfds > 1024 {
// 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");
let readfds_ptr = emscripten_memory_pointer!(ctx.memory(0), readfds) as _;
let writefds_ptr = emscripten_memory_pointer!(ctx.memory(0), writefds) as _;
let readfds_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), readfds) 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 _) }
}
/// 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);
let fd: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
unsafe { fdatasync(fd) }
}
// 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);
let pid: i32 = varargs.get(ctx);
let pgid: i32 = varargs.get(ctx);
let pid: i32 = varargs.get(&ctx);
let pgid: i32 = varargs.get(&ctx);
let ret = unsafe { setpgid(pid, pgid) };
debug!("=> pid: {}, pgid: {} = {}", pid, pgid, ret);
@@ -992,25 +994,25 @@ pub fn ___syscall57(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int {
/// uname
// 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);
let buf: u32 = varargs.get(ctx);
let buf: u32 = varargs.get(&ctx);
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) }
}
/// 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);
let path = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _);
let path = varargs.get_str(&ctx);
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 {
rp.as_c_str().as_ptr()
} else {
path
};
let buf_ptr: u32 = varargs.get(ctx);
let buf_ptr: u32 = varargs.get(&ctx);
unsafe {
let mut stat: stat = std::mem::zeroed();
@@ -1034,7 +1036,7 @@ pub fn ___syscall196(ctx: &EmEnv, _which: i32, mut varargs: VarArgs) -> i32 {
}
// 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)");
let uid = unsafe { getuid() as _ };
debug!(" => {}", uid);
@@ -1044,20 +1046,20 @@ pub fn ___syscall199(_ctx: &EmEnv, _one: i32, _two: i32) -> i32 {
// getdents
// dirent structure is
// 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;
let fd: i32 = varargs.get(ctx);
let dirp_addr: i32 = varargs.get(ctx);
let count: u32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let dirp_addr: i32 = varargs.get(&ctx);
let count: u32 = varargs.get(&ctx);
debug!(
"emscripten::___syscall220 (getdents) {} {} {}",
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?
// 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
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);
let fd: i32 = varargs.get(ctx);
let cmd: i32 = varargs.get(ctx);
let arg: i32 = varargs.get(ctx);
let fd: i32 = varargs.get(&ctx);
let cmd: i32 = varargs.get(&ctx);
let arg: i32 = varargs.get(&ctx);
// (FAPPEND - 0x08
// |FASYNC - 0x40
// |FFSYNC - 0x80
@@ -1126,12 +1128,12 @@ pub fn ___syscall221(ctx: &EmEnv, _which: c_int, mut varargs: VarArgs) -> c_int
}
/// 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);
let _fd: c_int = varargs.get(ctx);
let _mode: c_int = varargs.get(ctx);
let _offset: off_t = varargs.get(ctx);
let _len: off_t = varargs.get(ctx);
let _fd: c_int = varargs.get(&ctx);
let _mode: c_int = varargs.get(&ctx);
let _offset: off_t = varargs.get(&ctx);
let _len: off_t = varargs.get(&ctx);
#[cfg(not(any(target_os = "freebsd", target_vendor = "apple", target_os = "android")))]
unsafe {
fallocate(_fd, _mode, _offset, _len)

View File

@@ -13,6 +13,8 @@ use std::ffi::CString;
#[cfg(target_os = "windows")]
use libc::time_t;
use wasmer::{AsContextMut, ContextMut};
#[cfg(target_os = "windows")]
#[allow(non_camel_case_types)]
type clockid_t = c_int;
@@ -50,7 +52,7 @@ const CLOCK_MONOTONIC_COARSE: clockid_t = 6;
/// emscripten: _gettimeofday
#[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);
#[repr(C)]
struct GuestTimeVal {
@@ -65,7 +67,8 @@ pub fn _gettimeofday(ctx: &EmEnv, tp: c_int, tz: c_int) -> c_int {
unsafe {
let now = SystemTime::now();
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_usec = since_epoch.subsec_nanos() as _;
@@ -73,7 +76,7 @@ pub fn _gettimeofday(ctx: &EmEnv, tp: c_int, tz: c_int) -> c_int {
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");
// clock_getres(clk_id, tp)
0
@@ -81,7 +84,7 @@ pub fn _clock_getres(_ctx: &EmEnv, _clk_id: i32, _tp: i32) -> i32 {
/// emscripten: _clock_gettime
#[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!("Memory {:?}", ctx.memory(0)[..]);
#[repr(C)]
@@ -106,48 +109,48 @@ pub fn _clock_gettime(ctx: &EmEnv, clk_id: clockid_t, tp: c_int) -> c_int {
unsafe {
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_nsec = (duration % 1_000_000_000) as _;
}
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");
// clock_settime(clk_id, tp)
0
}
/// 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);
_clock_gettime(ctx, clk_id, tp)
}
/// emscripten: _clock
pub fn _clock(_ctx: &EmEnv) -> c_int {
pub fn _clock(mut _ctx: ContextMut<'_, EmEnv>) -> c_int {
debug!("emscripten::_clock");
0 // TODO: unimplemented
}
/// 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");
(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");
-1
}
pub fn _mktime(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _mktime(mut _ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_mktime");
-1
}
pub fn _gmtime(_ctx: &EmEnv, _one: i32) -> i32 {
pub fn _gmtime(mut _ctx: ContextMut<'_, EmEnv>, _one: i32) -> i32 {
debug!("emscripten::_gmtime");
-1
}
@@ -168,14 +171,14 @@ struct guest_tm {
}
/// emscripten: _tvset
pub fn _tvset(_ctx: &EmEnv) {
pub fn _tvset(mut _ctx: ContextMut<'_, EmEnv>) {
debug!("emscripten::_tvset UNIMPLEMENTED");
}
/// formats time as a C string
#[allow(clippy::cast_ptr_alignment)]
unsafe fn fmt_time(ctx: &EmEnv, time: u32) -> *const c_char {
let date = &*(emscripten_memory_pointer!(ctx.memory(0), time) as *mut guest_tm);
unsafe fn fmt_time(ctx: ContextMut<'_, EmEnv>, time: u32) -> *const c_char {
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 months = vec![
@@ -199,21 +202,21 @@ unsafe fn fmt_time(ctx: &EmEnv, time: u32) -> *const c_char {
}
/// emscripten: _asctime
pub fn _asctime(ctx: &EmEnv, time: u32) -> u32 {
pub fn _asctime(mut ctx: ContextMut<'_, EmEnv>, time: u32) -> u32 {
debug!("emscripten::_asctime {}", time);
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)
// 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;
// debug!("#### cstr = {:?}", CStr::from_ptr(c_str));
}
}
/// 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);
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).
// 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.
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)
// 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;
// debug!("#### cstr = {:?}", CStr::from_ptr(c_str));
}
@@ -232,21 +235,22 @@ pub fn _asctime_r(ctx: &EmEnv, time: u32, buf: u32) -> u32 {
/// emscripten: _localtime
#[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);
// 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
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;
time::OffsetDateTime::from_unix_timestamp(seconds)
};
unsafe {
let tm_struct_offset = env::call_malloc(ctx, mem::size_of::<guest_tm>() as _);
let tm_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), tm_struct_offset) as *mut guest_tm;
let tm_struct_offset =
env::call_malloc(ctx.as_context_mut(), mem::size_of::<guest_tm>() as _);
let tm_struct_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), tm_struct_offset)
as *mut guest_tm;
// debug!(
// ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}",
// 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
#[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);
// 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
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 _);
// 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,
// );
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_min = timespec.minute() as _;
@@ -305,24 +310,27 @@ pub fn _localtime_r(ctx: &EmEnv, time_p: u32, result: u32) -> c_int {
/// emscripten: _time
#[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);
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
}
}
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);
let (result_offset, _result_slice): (u32, &mut [u8]) = unsafe { allocate_on_stack(ctx, 44) };
let time = _localtime_r(ctx, time_p, result_offset) as u32;
// var stack = stackSave();
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)
// 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);
let tm_current = 2414544;
_ctime_r(ctx, time_p, tm_current)
@@ -331,11 +339,12 @@ pub fn _ctime(ctx: &EmEnv, time_p: u32) -> u32 {
/// emscripten: _timegm
#[cfg(not(target_os = "windows"))]
#[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);
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 mut rust_tm = libc_tm {
@@ -371,7 +380,7 @@ pub fn _timegm(ctx: &EmEnv, time_ptr: u32) -> i32 {
}
#[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!(
"emscripten::_timegm - UNIMPLEMENTED IN WINDOWS {}",
_time_ptr
@@ -380,18 +389,24 @@ pub fn _timegm(_ctx: &EmEnv, _time_ptr: c_int) -> i32 {
}
/// 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!(
"emscripten::_strftime {} {} {} {}",
s_ptr, maxsize, format_ptr, tm_ptr
);
#[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)]
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)]
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() };
@@ -428,7 +443,7 @@ pub fn _strftime(ctx: &EmEnv, s_ptr: c_int, maxsize: u32, format_ptr: c_int, tm_
/// emscripten: _strftime_l
pub fn _strftime_l(
ctx: &EmEnv,
ctx: ContextMut<'_, EmEnv>,
s_ptr: c_int,
maxsize: u32,
format_ptr: c_int,

View File

@@ -1,20 +1,27 @@
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);
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!(
"emscripten::_makecontext({}, {}, {}, {})",
_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);
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);
0
}

View File

@@ -1,6 +1,7 @@
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);
0
}

View File

@@ -1,5 +1,5 @@
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::EmEnv;
use libc::stat;
@@ -8,7 +8,7 @@ use std::mem::size_of;
use std::os::raw::c_char;
use std::path::PathBuf;
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
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 {
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_char;
pub unsafe fn write_to_buf(
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 {
*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.
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 cstr_len = s.len();
let space_offset = env::call_malloc(ctx, (cstr_len as u32) + 1);
let raw_memory = emscripten_memory_pointer!(ctx.memory(0), space_offset) as *mut c_char;
let space_offset = env::call_malloc(ctx.as_context_mut(), (cstr_len as u32) + 1);
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);
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
/// 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]) {
let offset = get_emscripten_data(ctx)
.stack_alloc_ref()
.unwrap()
.call(count * (size_of::<T>() as u32))
pub unsafe fn allocate_on_stack<'a, T: Copy>(
ctx: &mut ContextMut<'a, EmEnv>,
count: u32,
) -> (u32, &'a mut [T]) {
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();
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);
(offset, slice)
@@ -139,7 +147,10 @@ pub unsafe fn allocate_on_stack<T: Copy>(ctx: &EmEnv, count: u32) -> (u32, &mut
/// # Safety
/// 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);
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"))]
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 mut ptr = cstrs;
let mut counter = 0;
@@ -189,8 +203,8 @@ pub struct GuestStat {
}
#[allow(clippy::cast_ptr_alignment)]
pub unsafe fn copy_stat_into_wasm(ctx: &EmEnv, buf: u32, stat: &stat) {
let stat_ptr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut GuestStat;
pub unsafe fn copy_stat_into_wasm(ctx: ContextMut<'_, EmEnv>, buf: u32, stat: &stat) {
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_padding = 0;
(*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`.
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)
.read_utf8_string_with_nul(memory)
.read_utf8_string_with_nul(&ctx, memory)
.unwrap()
}
/// This function trys to find an entry in mapdir
/// 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;
let path_str =
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 mut prefix_added = false;
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
/// handles mapdir logic
pub fn get_current_directory(ctx: &EmEnv) -> Option<PathBuf> {
if let Some(val) = get_emscripten_data(ctx).mapped_dirs.get(".") {
pub fn get_current_directory(ctx: ContextMut<'_, EmEnv>) -> Option<PathBuf> {
if let Some(val) = get_emscripten_data(&ctx).mapped_dirs.get(".") {
return Some(val.clone());
}
std::env::current_dir()
.map(|cwd| {
if let Some(val) = get_emscripten_data(ctx)
if let Some(val) = get_emscripten_data(&ctx)
.mapped_dirs
.get(&cwd.to_string_lossy().to_string())
{

View File

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