mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-12 22:05:33 +00:00
Merge branch 'master' into command/dash
This commit is contained in:
commit
9b501e4c3f
6
Makefile
6
Makefile
@ -105,8 +105,8 @@ lint:
|
||||
|
||||
precommit: lint test
|
||||
|
||||
build:
|
||||
cargo build --release --features debug
|
||||
debug:
|
||||
cargo build --release --features backend:singlepass,debug,trace
|
||||
|
||||
install:
|
||||
cargo install --path .
|
||||
@ -118,7 +118,7 @@ release:
|
||||
release-fast:
|
||||
# If you are in OS-X, you will need mingw-w64 for cross compiling to windows
|
||||
# brew install mingw-w64
|
||||
cargo build --release
|
||||
cargo build --release --features backend:singlepass
|
||||
|
||||
bench:
|
||||
cargo bench --all
|
||||
|
@ -68,159 +68,6 @@ pub fn _dladdr(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
debug!("emscripten::_dladdr");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_attr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_attr_destroy");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_attr_getstack(
|
||||
_ctx: &mut Ctx,
|
||||
_stackaddr: i32,
|
||||
_stacksize: i32,
|
||||
_other: i32,
|
||||
) -> i32 {
|
||||
debug!(
|
||||
"emscripten::_pthread_attr_getstack({}, {}, {})",
|
||||
_stackaddr, _stacksize, _other
|
||||
);
|
||||
// TODO: Translate from Emscripten
|
||||
// HEAP32[stackaddr >> 2] = STACK_BASE;
|
||||
// HEAP32[stacksize >> 2] = TOTAL_STACK;
|
||||
0
|
||||
}
|
||||
pub fn _pthread_attr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_attr_init({})", _a);
|
||||
0
|
||||
}
|
||||
pub fn _pthread_attr_setstacksize(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_attr_setstacksize");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_cleanup_pop(_ctx: &mut Ctx, _a: i32) -> () {
|
||||
trace!("emscripten::_pthread_cleanup_pop");
|
||||
}
|
||||
pub fn _pthread_cleanup_push(_ctx: &mut Ctx, _a: i32, _b: i32) -> () {
|
||||
trace!("emscripten::_pthread_cleanup_push");
|
||||
}
|
||||
pub fn _pthread_cond_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_destroy");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_cond_init(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_init");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_cond_signal(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_signal");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_cond_timedwait(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_timedwait");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_cond_wait(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_wait");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_condattr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_condattr_destroy");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_condattr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_condattr_init");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_condattr_setclock(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_condattr_setclock");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_create(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32, _d: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_create");
|
||||
// 11 seems to mean "no"
|
||||
11
|
||||
}
|
||||
pub fn _pthread_detach(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_detach");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_equal(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_equal");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_exit(_ctx: &mut Ctx, _a: i32) -> () {
|
||||
trace!("emscripten::_pthread_exit");
|
||||
}
|
||||
pub fn _pthread_getattr_np(_ctx: &mut Ctx, _thread: i32, _attr: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_getattr_np({}, {})", _thread, _attr);
|
||||
0
|
||||
}
|
||||
pub fn _pthread_getspecific(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_getspecific");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_join(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_join");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_key_create(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_key_create");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_mutex_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutex_destroy");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_mutex_init(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutex_init");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_mutexattr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutexattr_destroy");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_mutexattr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutexattr_init");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_mutexattr_settype(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutexattr_settype");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_once(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_once");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_rwlock_destroy(_ctx: &mut Ctx, _rwlock: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_destroy({})", _rwlock);
|
||||
0
|
||||
}
|
||||
pub fn _pthread_rwlock_init(_ctx: &mut Ctx, _rwlock: i32, _attr: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_init({}, {})", _rwlock, _attr);
|
||||
0
|
||||
}
|
||||
pub fn _pthread_rwlock_rdlock(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_rdlock");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_rwlock_unlock(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_unlock");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_rwlock_wrlock(_ctx: &mut Ctx, _rwlock: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_wrlock({})", _rwlock);
|
||||
0
|
||||
}
|
||||
pub fn _pthread_setcancelstate(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_setcancelstate");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_setspecific(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_setspecific");
|
||||
0
|
||||
}
|
||||
pub fn _pthread_sigmask(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_sigmask");
|
||||
0
|
||||
}
|
||||
pub fn ___gxx_personality_v0(
|
||||
_ctx: &mut Ctx,
|
||||
_a: i32,
|
||||
|
11
lib/emscripten/src/env/mod.rs
vendored
11
lib/emscripten/src/env/mod.rs
vendored
@ -22,11 +22,16 @@ use wasmer_runtime_core::{
|
||||
};
|
||||
|
||||
pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 {
|
||||
get_emscripten_data(ctx).malloc.call(size).unwrap()
|
||||
get_emscripten_data(ctx)
|
||||
.malloc
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.call(size)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn call_malloc_with_cast<T: Copy, Ty>(ctx: &mut Ctx, size: u32) -> WasmPtr<T, Ty> {
|
||||
WasmPtr::new(get_emscripten_data(ctx).malloc.call(size).unwrap())
|
||||
WasmPtr::new(call_malloc(ctx, size))
|
||||
}
|
||||
|
||||
pub fn call_memalign(ctx: &mut Ctx, alignment: u32, size: u32) -> u32 {
|
||||
@ -40,6 +45,8 @@ pub fn call_memalign(ctx: &mut Ctx, alignment: u32, size: u32) -> u32 {
|
||||
pub fn call_memset(ctx: &mut Ctx, pointer: u32, value: u32, size: u32) -> u32 {
|
||||
get_emscripten_data(ctx)
|
||||
.memset
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.call(pointer, value, size)
|
||||
.unwrap()
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ mod lock;
|
||||
mod math;
|
||||
mod memory;
|
||||
mod process;
|
||||
mod pthread;
|
||||
mod signal;
|
||||
mod storage;
|
||||
mod syscalls;
|
||||
@ -84,11 +85,13 @@ const GLOBAL_BASE: u32 = 1024;
|
||||
const STATIC_BASE: u32 = GLOBAL_BASE;
|
||||
|
||||
pub struct EmscriptenData<'a> {
|
||||
pub malloc: Func<'a, u32, u32>,
|
||||
pub free: Func<'a, u32>,
|
||||
pub globals: &'a EmscriptenGlobalsData,
|
||||
|
||||
pub malloc: Option<Func<'a, u32, u32>>,
|
||||
pub free: Option<Func<'a, u32>>,
|
||||
pub memalign: Option<Func<'a, (u32, u32), u32>>,
|
||||
pub memset: Func<'a, (u32, u32, u32), u32>,
|
||||
pub stack_alloc: Func<'a, u32, u32>,
|
||||
pub memset: Option<Func<'a, (u32, u32, u32), u32>>,
|
||||
pub stack_alloc: Option<Func<'a, u32, u32>>,
|
||||
pub jumps: Vec<UnsafeCell<[u32; 27]>>,
|
||||
pub opened_dirs: HashMap<i32, Box<*mut libcDIR>>,
|
||||
|
||||
@ -162,13 +165,17 @@ pub struct EmscriptenData<'a> {
|
||||
impl<'a> EmscriptenData<'a> {
|
||||
pub fn new(
|
||||
instance: &'a mut Instance,
|
||||
globals: &'a EmscriptenGlobalsData,
|
||||
mapped_dirs: HashMap<String, PathBuf>,
|
||||
) -> EmscriptenData<'a> {
|
||||
let malloc = instance.func("_malloc").unwrap();
|
||||
let free = instance.func("_free").unwrap();
|
||||
let memalign = instance.func("_memalign").ok();
|
||||
let memset = instance.func("_memset").unwrap();
|
||||
let stack_alloc = instance.func("stackAlloc").unwrap();
|
||||
let malloc = instance.func("_malloc").or(instance.func("malloc")).ok();
|
||||
let free = instance.func("_free").or(instance.func("free")).ok();
|
||||
let memalign = instance
|
||||
.func("_memalign")
|
||||
.or(instance.func("memalign"))
|
||||
.ok();
|
||||
let memset = instance.func("_memset").or(instance.func("memset")).ok();
|
||||
let stack_alloc = instance.func("stackAlloc").ok();
|
||||
|
||||
let dyn_call_i = instance.func("dynCall_i").ok();
|
||||
let dyn_call_ii = instance.func("dynCall_ii").ok();
|
||||
@ -227,9 +234,14 @@ impl<'a> EmscriptenData<'a> {
|
||||
|
||||
let stack_save = instance.func("stackSave").ok();
|
||||
let stack_restore = instance.func("stackRestore").ok();
|
||||
let set_threw = instance.func("_setThrew").ok();
|
||||
let set_threw = instance
|
||||
.func("_setThrew")
|
||||
.or(instance.func("setThrew"))
|
||||
.ok();
|
||||
|
||||
EmscriptenData {
|
||||
globals,
|
||||
|
||||
malloc,
|
||||
free,
|
||||
memalign,
|
||||
@ -305,12 +317,13 @@ impl<'a> EmscriptenData<'a> {
|
||||
pub fn run_emscripten_instance(
|
||||
_module: &Module,
|
||||
instance: &mut Instance,
|
||||
globals: &mut EmscriptenGlobals,
|
||||
path: &str,
|
||||
args: Vec<&str>,
|
||||
entrypoint: Option<String>,
|
||||
mapped_dirs: Vec<(String, PathBuf)>,
|
||||
) -> CallResult<()> {
|
||||
let mut data = EmscriptenData::new(instance, mapped_dirs.into_iter().collect());
|
||||
let mut data = EmscriptenData::new(instance, &globals.data, mapped_dirs.into_iter().collect());
|
||||
let data_ptr = &mut data as *mut _ as *mut c_void;
|
||||
instance.context_mut().data = data_ptr;
|
||||
|
||||
@ -332,17 +345,26 @@ pub fn run_emscripten_instance(
|
||||
//let (argc, argv) = store_module_arguments(instance.context_mut(), args);
|
||||
instance.call(&ep, &[Value::I32(arg as i32)])?;
|
||||
} else {
|
||||
let main_func = instance.dyn_func("_main")?;
|
||||
let (func_name, main_func) = match instance.dyn_func("_main") {
|
||||
Ok(func) => Ok(("_main", func)),
|
||||
Err(_e) => match instance.dyn_func("main") {
|
||||
Ok(func) => Ok(("main", func)),
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
}?;
|
||||
let num_params = main_func.signature().params().len();
|
||||
let _result = match num_params {
|
||||
2 => {
|
||||
let mut new_args = vec![path];
|
||||
new_args.extend(args);
|
||||
let (argc, argv) = store_module_arguments(instance.context_mut(), new_args);
|
||||
instance.call("_main", &[Value::I32(argc as i32), Value::I32(argv as i32)])?;
|
||||
instance.call(
|
||||
func_name,
|
||||
&[Value::I32(argc as i32), Value::I32(argv as i32)],
|
||||
)?;
|
||||
}
|
||||
0 => {
|
||||
instance.call("_main", &[])?;
|
||||
instance.call(func_name, &[])?;
|
||||
}
|
||||
_ => panic!(
|
||||
"The emscripten main function has received an incorrect number of params {}",
|
||||
@ -430,13 +452,13 @@ impl EmscriptenGlobals {
|
||||
}
|
||||
|
||||
let (table_min, table_max) = get_emscripten_table_size(&module);
|
||||
let (memory_min, memory_max) = get_emscripten_memory_size(&module);
|
||||
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module);
|
||||
|
||||
// Memory initialization
|
||||
let memory_type = MemoryDescriptor {
|
||||
minimum: memory_min,
|
||||
maximum: memory_max,
|
||||
shared: false,
|
||||
shared: shared,
|
||||
};
|
||||
let memory = Memory::new(memory_type).unwrap();
|
||||
|
||||
@ -750,6 +772,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"alignfault" => func!(crate::memory::alignfault),
|
||||
"ftfault" => func!(crate::memory::ftfault),
|
||||
"getTotalMemory" => func!(crate::memory::get_total_memory),
|
||||
"_sbrk" => func!(crate::memory::sbrk),
|
||||
"___map_file" => func!(crate::memory::___map_file),
|
||||
|
||||
// Exception
|
||||
@ -781,6 +804,8 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"_strftime_l" => func!(crate::time::_strftime_l),
|
||||
"_localtime_r" => func!(crate::time::_localtime_r),
|
||||
"_gmtime_r" => func!(crate::time::_gmtime_r),
|
||||
"_ctime" => func!(crate::time::_ctime),
|
||||
"_ctime_r" => func!(crate::time::_ctime_r),
|
||||
"_mktime" => func!(crate::time::_mktime),
|
||||
"_gmtime" => func!(crate::time::_gmtime),
|
||||
|
||||
@ -856,42 +881,43 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"___cxa_free_exception" => func!(crate::emscripten_target::___cxa_free_exception),
|
||||
"___resumeException" => func!(crate::emscripten_target::___resumeException),
|
||||
"_dladdr" => func!(crate::emscripten_target::_dladdr),
|
||||
"_pthread_attr_destroy" => func!(crate::emscripten_target::_pthread_attr_destroy),
|
||||
"_pthread_attr_getstack" => func!(crate::emscripten_target::_pthread_attr_getstack),
|
||||
"_pthread_attr_init" => func!(crate::emscripten_target::_pthread_attr_init),
|
||||
"_pthread_attr_setstacksize" => func!(crate::emscripten_target::_pthread_attr_setstacksize),
|
||||
"_pthread_cleanup_pop" => func!(crate::emscripten_target::_pthread_cleanup_pop),
|
||||
"_pthread_cleanup_push" => func!(crate::emscripten_target::_pthread_cleanup_push),
|
||||
"_pthread_cond_destroy" => func!(crate::emscripten_target::_pthread_cond_destroy),
|
||||
"_pthread_cond_init" => func!(crate::emscripten_target::_pthread_cond_init),
|
||||
"_pthread_cond_signal" => func!(crate::emscripten_target::_pthread_cond_signal),
|
||||
"_pthread_cond_timedwait" => func!(crate::emscripten_target::_pthread_cond_timedwait),
|
||||
"_pthread_cond_wait" => func!(crate::emscripten_target::_pthread_cond_wait),
|
||||
"_pthread_condattr_destroy" => func!(crate::emscripten_target::_pthread_condattr_destroy),
|
||||
"_pthread_condattr_init" => func!(crate::emscripten_target::_pthread_condattr_init),
|
||||
"_pthread_condattr_setclock" => func!(crate::emscripten_target::_pthread_condattr_setclock),
|
||||
"_pthread_create" => func!(crate::emscripten_target::_pthread_create),
|
||||
"_pthread_detach" => func!(crate::emscripten_target::_pthread_detach),
|
||||
"_pthread_equal" => func!(crate::emscripten_target::_pthread_equal),
|
||||
"_pthread_exit" => func!(crate::emscripten_target::_pthread_exit),
|
||||
"_pthread_getattr_np" => func!(crate::emscripten_target::_pthread_getattr_np),
|
||||
"_pthread_getspecific" => func!(crate::emscripten_target::_pthread_getspecific),
|
||||
"_pthread_join" => func!(crate::emscripten_target::_pthread_join),
|
||||
"_pthread_key_create" => func!(crate::emscripten_target::_pthread_key_create),
|
||||
"_pthread_mutex_destroy" => func!(crate::emscripten_target::_pthread_mutex_destroy),
|
||||
"_pthread_mutex_init" => func!(crate::emscripten_target::_pthread_mutex_init),
|
||||
"_pthread_mutexattr_destroy" => func!(crate::emscripten_target::_pthread_mutexattr_destroy),
|
||||
"_pthread_mutexattr_init" => func!(crate::emscripten_target::_pthread_mutexattr_init),
|
||||
"_pthread_mutexattr_settype" => func!(crate::emscripten_target::_pthread_mutexattr_settype),
|
||||
"_pthread_once" => func!(crate::emscripten_target::_pthread_once),
|
||||
"_pthread_rwlock_destroy" => func!(crate::emscripten_target::_pthread_rwlock_destroy),
|
||||
"_pthread_rwlock_init" => func!(crate::emscripten_target::_pthread_rwlock_init),
|
||||
"_pthread_rwlock_rdlock" => func!(crate::emscripten_target::_pthread_rwlock_rdlock),
|
||||
"_pthread_rwlock_unlock" => func!(crate::emscripten_target::_pthread_rwlock_unlock),
|
||||
"_pthread_rwlock_wrlock" => func!(crate::emscripten_target::_pthread_rwlock_wrlock),
|
||||
"_pthread_setcancelstate" => func!(crate::emscripten_target::_pthread_setcancelstate),
|
||||
"_pthread_setspecific" => func!(crate::emscripten_target::_pthread_setspecific),
|
||||
"_pthread_sigmask" => func!(crate::emscripten_target::_pthread_sigmask),
|
||||
"_pthread_attr_destroy" => func!(crate::pthread::_pthread_attr_destroy),
|
||||
"_pthread_attr_getstack" => func!(crate::pthread::_pthread_attr_getstack),
|
||||
"_pthread_attr_init" => func!(crate::pthread::_pthread_attr_init),
|
||||
"_pthread_attr_setstacksize" => func!(crate::pthread::_pthread_attr_setstacksize),
|
||||
"_pthread_cleanup_pop" => func!(crate::pthread::_pthread_cleanup_pop),
|
||||
"_pthread_cleanup_push" => func!(crate::pthread::_pthread_cleanup_push),
|
||||
"_pthread_cond_destroy" => func!(crate::pthread::_pthread_cond_destroy),
|
||||
"_pthread_cond_init" => func!(crate::pthread::_pthread_cond_init),
|
||||
"_pthread_cond_signal" => func!(crate::pthread::_pthread_cond_signal),
|
||||
"_pthread_cond_timedwait" => func!(crate::pthread::_pthread_cond_timedwait),
|
||||
"_pthread_cond_wait" => func!(crate::pthread::_pthread_cond_wait),
|
||||
"_pthread_condattr_destroy" => func!(crate::pthread::_pthread_condattr_destroy),
|
||||
"_pthread_condattr_init" => func!(crate::pthread::_pthread_condattr_init),
|
||||
"_pthread_condattr_setclock" => func!(crate::pthread::_pthread_condattr_setclock),
|
||||
"_pthread_create" => func!(crate::pthread::_pthread_create),
|
||||
"_pthread_detach" => func!(crate::pthread::_pthread_detach),
|
||||
"_pthread_equal" => func!(crate::pthread::_pthread_equal),
|
||||
"_pthread_exit" => func!(crate::pthread::_pthread_exit),
|
||||
"_pthread_self" => func!(crate::pthread::_pthread_self),
|
||||
"_pthread_getattr_np" => func!(crate::pthread::_pthread_getattr_np),
|
||||
"_pthread_getspecific" => func!(crate::pthread::_pthread_getspecific),
|
||||
"_pthread_join" => func!(crate::pthread::_pthread_join),
|
||||
"_pthread_key_create" => func!(crate::pthread::_pthread_key_create),
|
||||
"_pthread_mutex_destroy" => func!(crate::pthread::_pthread_mutex_destroy),
|
||||
"_pthread_mutex_init" => func!(crate::pthread::_pthread_mutex_init),
|
||||
"_pthread_mutexattr_destroy" => func!(crate::pthread::_pthread_mutexattr_destroy),
|
||||
"_pthread_mutexattr_init" => func!(crate::pthread::_pthread_mutexattr_init),
|
||||
"_pthread_mutexattr_settype" => func!(crate::pthread::_pthread_mutexattr_settype),
|
||||
"_pthread_once" => func!(crate::pthread::_pthread_once),
|
||||
"_pthread_rwlock_destroy" => func!(crate::pthread::_pthread_rwlock_destroy),
|
||||
"_pthread_rwlock_init" => func!(crate::pthread::_pthread_rwlock_init),
|
||||
"_pthread_rwlock_rdlock" => func!(crate::pthread::_pthread_rwlock_rdlock),
|
||||
"_pthread_rwlock_unlock" => func!(crate::pthread::_pthread_rwlock_unlock),
|
||||
"_pthread_rwlock_wrlock" => func!(crate::pthread::_pthread_rwlock_wrlock),
|
||||
"_pthread_setcancelstate" => func!(crate::pthread::_pthread_setcancelstate),
|
||||
"_pthread_setspecific" => func!(crate::pthread::_pthread_setspecific),
|
||||
"_pthread_sigmask" => func!(crate::pthread::_pthread_sigmask),
|
||||
"___gxx_personality_v0" => func!(crate::emscripten_target::___gxx_personality_v0),
|
||||
"_gai_strerror" => func!(crate::env::_gai_strerror),
|
||||
"_getdtablesize" => func!(crate::emscripten_target::_getdtablesize),
|
||||
@ -952,6 +978,17 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
|
||||
"_confstr" => func!(crate::unistd::confstr),
|
||||
};
|
||||
|
||||
// Compatibility with newer versions of Emscripten
|
||||
use crate::wasmer_runtime_core::import::LikeNamespace;
|
||||
for (k, v) in env_ns.get_exports() {
|
||||
if k.starts_with("_") {
|
||||
let k = &k[1..];
|
||||
if !env_ns.contains_key(k) {
|
||||
env_ns.insert(k, v.to_export());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for null_func_name in globals.null_func_names.iter() {
|
||||
env_ns.insert(null_func_name.as_str(), Func::new(nullfunc).to_export());
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use super::env::get_emscripten_data;
|
||||
use super::process::abort_with_message;
|
||||
use libc::{c_int, c_void, memcpy, size_t};
|
||||
use wasmer_runtime_core::{
|
||||
@ -65,6 +66,34 @@ pub fn _emscripten_resize_heap(ctx: &mut Ctx, requested_size: u32) -> u32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// emscripten: sbrk
|
||||
pub fn sbrk(ctx: &mut Ctx, increment: i32) -> i32 {
|
||||
debug!("emscripten::sbrk");
|
||||
// let old_dynamic_top = 0;
|
||||
// let new_dynamic_top = 0;
|
||||
let mut globals = get_emscripten_data(ctx).globals;
|
||||
let dynamictop_ptr = (globals.dynamictop_ptr) as usize;
|
||||
let old_dynamic_top = ctx.memory(0).view::<u32>()[dynamictop_ptr].get() as i32;
|
||||
let new_dynamic_top: i32 = old_dynamic_top + increment;
|
||||
let total_memory = _emscripten_get_heap_size(ctx) as i32;
|
||||
debug!(
|
||||
" => PTR {}, old: {}, new: {}, increment: {}, total: {}",
|
||||
dynamictop_ptr, old_dynamic_top, new_dynamic_top, increment, total_memory
|
||||
);
|
||||
if increment > 0 && new_dynamic_top < old_dynamic_top || new_dynamic_top < 0 {
|
||||
abort_on_cannot_grow_memory_old(ctx);
|
||||
return -1;
|
||||
}
|
||||
if new_dynamic_top > total_memory {
|
||||
let resized = _emscripten_resize_heap(ctx, new_dynamic_top as u32);
|
||||
if resized == 0 {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ctx.memory(0).view::<u32>()[dynamictop_ptr].set(new_dynamic_top as u32);
|
||||
return old_dynamic_top as _;
|
||||
}
|
||||
|
||||
/// emscripten: getTotalMemory
|
||||
pub fn get_total_memory(_ctx: &mut Ctx) -> u32 {
|
||||
debug!("emscripten::get_total_memory");
|
||||
|
197
lib/emscripten/src/pthread.rs
Normal file
197
lib/emscripten/src/pthread.rs
Normal file
@ -0,0 +1,197 @@
|
||||
use wasmer_runtime_core::vm::Ctx;
|
||||
|
||||
pub fn _pthread_attr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_attr_destroy");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_attr_getstack(
|
||||
_ctx: &mut Ctx,
|
||||
_stackaddr: i32,
|
||||
_stacksize: i32,
|
||||
_other: i32,
|
||||
) -> i32 {
|
||||
trace!(
|
||||
"emscripten::_pthread_attr_getstack({}, {}, {})",
|
||||
_stackaddr,
|
||||
_stacksize,
|
||||
_other
|
||||
);
|
||||
// TODO: Translate from Emscripten
|
||||
// HEAP32[stackaddr >> 2] = STACK_BASE;
|
||||
// HEAP32[stacksize >> 2] = TOTAL_STACK;
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_attr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_attr_init({})", _a);
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_attr_setstacksize(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_attr_setstacksize");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_cleanup_pop(_ctx: &mut Ctx, _a: i32) -> () {
|
||||
trace!("emscripten::_pthread_cleanup_pop");
|
||||
}
|
||||
|
||||
pub fn _pthread_cleanup_push(_ctx: &mut Ctx, _a: i32, _b: i32) -> () {
|
||||
trace!("emscripten::_pthread_cleanup_push");
|
||||
}
|
||||
|
||||
pub fn _pthread_cond_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_destroy");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_cond_init(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_init");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_cond_signal(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_signal");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_cond_timedwait(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_timedwait");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_cond_wait(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_cond_wait");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_condattr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_condattr_destroy");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_condattr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_condattr_init");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_condattr_setclock(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_condattr_setclock");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_create(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32, _d: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_create");
|
||||
// 11 seems to mean "no"
|
||||
11
|
||||
}
|
||||
|
||||
pub fn _pthread_detach(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_detach");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_equal(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_equal");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_exit(_ctx: &mut Ctx, _a: i32) -> () {
|
||||
trace!("emscripten::_pthread_exit");
|
||||
}
|
||||
|
||||
pub fn _pthread_getattr_np(_ctx: &mut Ctx, _thread: i32, _attr: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_getattr_np({}, {})", _thread, _attr);
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_getspecific(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_getspecific");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_join(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_join");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_self(_ctx: &mut Ctx) -> i32 {
|
||||
trace!("emscripten::_pthread_self");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_key_create(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_key_create");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_mutex_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutex_destroy");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_mutex_init(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutex_init");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_mutexattr_destroy(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutexattr_destroy");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_mutexattr_init(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutexattr_init");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_mutexattr_settype(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_mutexattr_settype");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_once(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_once");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_rwlock_destroy(_ctx: &mut Ctx, _rwlock: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_destroy({})", _rwlock);
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_rwlock_init(_ctx: &mut Ctx, _rwlock: i32, _attr: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_init({}, {})", _rwlock, _attr);
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_rwlock_rdlock(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_rdlock");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_rwlock_unlock(_ctx: &mut Ctx, _a: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_unlock");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_rwlock_wrlock(_ctx: &mut Ctx, _rwlock: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_rwlock_wrlock({})", _rwlock);
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_setcancelstate(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_setcancelstate");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_setspecific(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_setspecific");
|
||||
0
|
||||
}
|
||||
|
||||
pub fn _pthread_sigmask(_ctx: &mut Ctx, _a: i32, _b: i32, _c: i32) -> i32 {
|
||||
trace!("emscripten::_pthread_sigmask");
|
||||
0
|
||||
}
|
@ -32,7 +32,6 @@ use libc::{
|
||||
// iovec,
|
||||
loff_t,
|
||||
lseek,
|
||||
off_t,
|
||||
// open,
|
||||
pid_t,
|
||||
read,
|
||||
@ -427,8 +426,8 @@ pub fn ___syscall140(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
||||
let offset_low: u32 = varargs.get(ctx);
|
||||
let result_ptr_value: WasmPtr<loff_t> = varargs.get(ctx);
|
||||
let whence: i32 = varargs.get(ctx);
|
||||
let offset = offset_low as off_t;
|
||||
let ret = unsafe { lseek(fd, offset, whence) as i64 };
|
||||
let offset = offset_low;
|
||||
let ret = unsafe { lseek(fd, offset as _, whence) as i64 };
|
||||
|
||||
let result_ptr = result_ptr_value.deref(ctx.memory(0)).unwrap();
|
||||
result_ptr.set(ret);
|
||||
|
@ -25,6 +25,7 @@ use libc::{
|
||||
getgid,
|
||||
getgroups,
|
||||
getpeername,
|
||||
getpgid,
|
||||
getrusage,
|
||||
getsockname,
|
||||
getsockopt,
|
||||
@ -76,22 +77,36 @@ use libc::{
|
||||
SOL_SOCKET,
|
||||
TIOCGWINSZ,
|
||||
TIOCSPGRP,
|
||||
// TCGETS,
|
||||
// TCSETSW,
|
||||
};
|
||||
|
||||
// They are not exposed in in Rust libc in macOS
|
||||
const TCGETS: u64 = 0x5401;
|
||||
const TCSETSW: u64 = 0x5403;
|
||||
|
||||
// `libc` constants as provided by `emscripten`. Maybe move to own file?
|
||||
const WASM_FIONBIO: u32 = 0x5421;
|
||||
const WASM_FIOCLEX: u32 = 0x5451;
|
||||
const WASM_TIOCSPGRP: u32 = 0x5410;
|
||||
const WASM_TIOCGWINSZ: u32 = 0x5413;
|
||||
const WASM_TCGETS: u32 = 0x5401;
|
||||
const WASM_TCSETSW: u32 = 0x5403;
|
||||
|
||||
// Based on @syrusakbary sugerence at
|
||||
// https://github.com/wasmerio/wasmer/pull/532#discussion_r300837800
|
||||
fn translate_ioctl(wasm_ioctl: u32) -> c_ulong {
|
||||
match wasm_ioctl {
|
||||
WASM_FIOCLEX => FIOCLEX,
|
||||
WASM_FIONBIO => FIONBIO,
|
||||
WASM_TIOCGWINSZ => TIOCGWINSZ,
|
||||
WASM_TIOCSPGRP => TIOCSPGRP,
|
||||
WASM_TCGETS => TCGETS,
|
||||
WASM_TCSETSW => TCSETSW,
|
||||
|
||||
otherwise => otherwise as c_ulong,
|
||||
_otherwise => {
|
||||
unimplemented!("The ioctl {} is not yet implemented", wasm_ioctl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,33 +459,27 @@ pub fn ___syscall54(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
|
||||
debug!("=> fd: {}, op: {}", fd, request);
|
||||
|
||||
// Got the equivalents here: https://code.woboq.org/linux/linux/include/uapi/asm-generic/ioctls.h.html
|
||||
let argp: u32 = varargs.get(ctx);
|
||||
let argp_ptr = emscripten_memory_pointer!(ctx.memory(0), argp) as *mut c_void;
|
||||
// let ret = unsafe { ioctl(fd, translate_ioctl(request) as _, argp_ptr) };
|
||||
// debug!("=> {}", ret);
|
||||
// ret
|
||||
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 translated_request = translate_ioctl(request);
|
||||
let ret = unsafe { ioctl(fd, translated_request, argp_ptr) };
|
||||
debug!(
|
||||
" => request: {}, translated: {}, return: {}",
|
||||
request, translated_request, ret
|
||||
);
|
||||
|
||||
match request as _ {
|
||||
TIOCGWINSZ => {
|
||||
let ret = unsafe { ioctl(fd, translate_ioctl(request) as _, argp_ptr) };
|
||||
debug!("ret(TIOCGWINSZ): {} (harcoded to 0)", ret);
|
||||
// ret
|
||||
// TODO: We hardcode the value to have emscripten tests pass, as for some reason
|
||||
// when the capturer is active, ioctl returns -1 instead of 0
|
||||
if ret == -1 {
|
||||
0
|
||||
} else {
|
||||
ret
|
||||
if request == WASM_TIOCGWINSZ && ret == -1 {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
TIOCSPGRP => {
|
||||
debug!("ret(TIOCSPGRP): (noop)");
|
||||
0
|
||||
ret
|
||||
}
|
||||
_ => {
|
||||
let ret = unsafe { ioctl(fd, translate_ioctl(request) as _, argp_ptr) };
|
||||
debug!("ret({}): {}", request, ret);
|
||||
ret
|
||||
unimplemented!("not implemented case {}", request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -794,6 +803,20 @@ fn translate_socket_name_flag(name: i32) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// getpgid
|
||||
pub fn ___syscall132(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||
debug!("emscripten::___syscall132 (getpgid)");
|
||||
|
||||
let pid: pid_t = varargs.get(ctx);
|
||||
|
||||
let ret = unsafe { getpgid(pid) };
|
||||
debug!("=> pid: {} = {}", pid, ret);
|
||||
if ret == -1 {
|
||||
debug!("=> last os error: {}", Error::last_os_error(),);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct EmPollFd {
|
||||
@ -1051,6 +1074,24 @@ pub fn ___syscall220(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
|
||||
pos as i32
|
||||
}
|
||||
|
||||
// fcntl64
|
||||
pub fn ___syscall221(ctx: &mut Ctx, _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);
|
||||
// (FAPPEND - 0x08
|
||||
// |FASYNC - 0x40
|
||||
// |FFSYNC - 0x80
|
||||
// |FNONBLOCK - 0x04
|
||||
let ret = unsafe { fcntl(fd, cmd, arg) };
|
||||
debug!("=> fd: {}, cmd: {} = {}", fd, cmd, ret);
|
||||
if ret == -1 {
|
||||
debug!("=> last os error: {}", Error::last_os_error(),);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
/// fallocate
|
||||
pub fn ___syscall324(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
|
||||
debug!("emscripten::___syscall324 (fallocate) {}", _which);
|
||||
|
@ -134,6 +134,12 @@ pub fn ___syscall85(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
|
||||
-1
|
||||
}
|
||||
|
||||
/// getpgid
|
||||
pub fn ___syscall132(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int {
|
||||
debug!("emscripten::___syscall132 (getpgid)");
|
||||
-1
|
||||
}
|
||||
|
||||
/// lchown
|
||||
pub fn ___syscall198(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
|
||||
debug!("emscripten::___syscall198 (lchown) {}", _which);
|
||||
@ -288,6 +294,12 @@ pub fn ___syscall220(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
|
||||
-1
|
||||
}
|
||||
|
||||
// fcntl64
|
||||
pub fn ___syscall221(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int {
|
||||
debug!("emscripten::___syscall221 (fcntl64) {}", _which);
|
||||
-1
|
||||
}
|
||||
|
||||
/// fchown
|
||||
pub fn ___syscall207(_ctx: &mut Ctx, _which: c_int, _varargs: VarArgs) -> c_int {
|
||||
debug!("emscripten::___syscall207 (fchown) {}", _which);
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::utils::{copy_cstr_into_wasm, write_to_buf};
|
||||
use crate::allocate_on_stack;
|
||||
use libc::{c_char, c_int};
|
||||
// use libc::{c_char, c_int, clock_getres, clock_settime};
|
||||
use std::mem;
|
||||
@ -313,6 +314,23 @@ pub fn _time(ctx: &mut Ctx, time_p: u32) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _ctime_r(ctx: &mut Ctx, time_p: u32, buf: u32) -> u32 {
|
||||
debug!("emscripten::_ctime_r {} {}", time_p, buf);
|
||||
|
||||
// var stack = stackSave();
|
||||
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;
|
||||
let rv = _asctime_r(ctx, time, buf);
|
||||
// stackRestore(stack);
|
||||
rv
|
||||
}
|
||||
|
||||
pub fn _ctime(ctx: &mut Ctx, time_p: u32) -> u32 {
|
||||
debug!("emscripten::_ctime {}", time_p);
|
||||
let tm_current = 2414544;
|
||||
_ctime_r(ctx, time_p, tm_current)
|
||||
}
|
||||
|
||||
/// emscripten: _timegm
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
|
@ -24,7 +24,9 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
||||
.namespace_table
|
||||
.get(import_name.namespace_index);
|
||||
let field = module.info().name_table.get(import_name.name_index);
|
||||
if field == "_emscripten_memcpy_big" && namespace == "env" {
|
||||
if (field == "_emscripten_memcpy_big" || field == "emscripten_memcpy_big")
|
||||
&& namespace == "env"
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -36,9 +38,9 @@ pub fn get_emscripten_table_size(module: &Module) -> (u32, Option<u32>) {
|
||||
(table.minimum, table.maximum)
|
||||
}
|
||||
|
||||
pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option<Pages>) {
|
||||
pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option<Pages>, bool) {
|
||||
let (_, memory) = &module.info().imported_memories[ImportedMemoryIndex::new(0)];
|
||||
(memory.minimum, memory.maximum)
|
||||
(memory.minimum, memory.maximum, memory.shared)
|
||||
}
|
||||
|
||||
/// Reads values written by `-s EMIT_EMSCRIPTEN_METADATA=1`
|
||||
@ -110,6 +112,8 @@ pub unsafe fn copy_cstr_into_wasm(ctx: &mut Ctx, cstr: *const c_char) -> u32 {
|
||||
pub unsafe fn allocate_on_stack<'a, T: Copy>(ctx: &'a mut Ctx, count: u32) -> (u32, &'a mut [T]) {
|
||||
let offset = get_emscripten_data(ctx)
|
||||
.stack_alloc
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.call(count * (size_of::<T>() as u32))
|
||||
.unwrap();
|
||||
let addr = emscripten_memory_pointer!(ctx.memory(0), offset) as *mut T;
|
||||
|
@ -53,6 +53,7 @@ macro_rules! assert_emscripten_output {
|
||||
wasmer_emscripten::run_emscripten_instance(
|
||||
&module,
|
||||
&mut instance,
|
||||
&mut emscripten_globals,
|
||||
$name,
|
||||
$args,
|
||||
None,
|
||||
|
@ -189,6 +189,13 @@ impl Namespace {
|
||||
{
|
||||
self.map.insert(name.into(), Box::new(export))
|
||||
}
|
||||
|
||||
pub fn contains_key<S>(&mut self, key: S) -> bool
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
self.map.contains_key(&key.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl LikeNamespace for Namespace {
|
||||
|
@ -474,6 +474,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
wasmer_emscripten::run_emscripten_instance(
|
||||
&module,
|
||||
&mut instance,
|
||||
&mut emscripten_globals,
|
||||
if let Some(cn) = &options.command_name {
|
||||
cn
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user