diff --git a/Cargo.lock b/Cargo.lock index 9b0551916..cff878ec4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,15 +489,15 @@ dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.1.0", - "wasmer-emscripten 0.1.1", - "wasmer-runtime 0.1.0", - "wasmer-runtime-core 0.1.0", + "wasmer-clif-backend 0.2.0", + "wasmer-emscripten 0.2.0", + "wasmer-runtime 0.2.0", + "wasmer-runtime-core 0.2.0", ] [[package]] name = "wasmer-clif-backend" -version = "0.1.0" +version = "0.2.0" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -507,13 +507,13 @@ dependencies = [ "hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.1.0", + "wasmer-runtime-core 0.2.0", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmer-emscripten" -version = "0.1.1" +version = "0.2.0" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -521,21 +521,21 @@ dependencies = [ "libc 0.2.44 (git+https://github.com/rust-lang/libc)", "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.1.0", - "wasmer-runtime-core 0.1.0", + "wasmer-clif-backend 0.2.0", + "wasmer-runtime-core 0.2.0", ] [[package]] name = "wasmer-runtime" -version = "0.1.0" +version = "0.2.0" dependencies = [ - "wasmer-clif-backend 0.1.0", - "wasmer-runtime-core 0.1.0", + "wasmer-clif-backend 0.2.0", + "wasmer-runtime-core 0.2.0", ] [[package]] name = "wasmer-runtime-core" -version = "0.1.0" +version = "0.2.0" dependencies = [ "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -543,7 +543,7 @@ dependencies = [ "nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.1.0", + "wasmer-clif-backend 0.2.0", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/lib/clif-backend/src/module_env.rs b/lib/clif-backend/src/module_env.rs index c396f7fd5..d9e1ba032 100644 --- a/lib/clif-backend/src/module_env.rs +++ b/lib/clif-backend/src/module_env.rs @@ -106,7 +106,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> GlobalInit::F32Const(x) => Initializer::Const(Value::F32(f32::from_bits(x))), GlobalInit::F64Const(x) => Initializer::Const(Value::F64(f64::from_bits(x))), GlobalInit::GetGlobal(global_index) => { - assert!(!desc.mutable); + // assert!(!desc.mutable); // Can be mutable let global_index: GlobalIndex = Converter(global_index).into(); let imported_global_index = global_index .local_or_import(self.module) diff --git a/lib/emscripten/src/README.md b/lib/emscripten/src/README.md index b88f1fc03..8bbc3b3b7 100644 --- a/lib/emscripten/src/README.md +++ b/lib/emscripten/src/README.md @@ -10,7 +10,7 @@ ``` - **abort** ✅ 🔥     [:top:](#host-apis) ```rust - fn abort(message: u32, instance: &mut Instance) + fn abort(message: u32, vmctx: &mut Ctx) ``` - **abort_on_cannot_grow_memory** ✅     [:top:](#host-apis) ```rust @@ -28,11 +28,11 @@ - **\_getenv** ✅     [:top:](#host-apis) ```rust - fn _getenv(name: c_int, instance: &mut Instance) + fn _getenv(name: c_int, vmctx: &mut Ctx) ``` - **\_putenv** ✅     [:top:](#host-apis) ```rust - fn _putenv(name: c_int, instance: &mut Instance) + fn _putenv(name: c_int, vmctx: &mut Ctx) ``` - **\_setenv** ✅     [:top:](#host-apis) ```rust @@ -40,7 +40,7 @@ ``` - **\_unsetenv** ✅     [:top:](#host-apis) ```rust - fn _unsetenv(name: c_int, instance: &mut Instance) + fn _unsetenv(name: c_int, vmctx: &mut Ctx) ``` ###### THREAD @@ -70,7 +70,7 @@ - **\_emscripten_memcpy_big** ✅ 🔥     [:top:](#host-apis) ```rust - fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, instance: &mut Instance) -> u32 + fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, vmctx: &mut Ctx) -> u32 ``` - **enlarge_memory** ✅     [:top:](#host-apis) ```rust @@ -78,7 +78,7 @@ ``` - **get_total_memory** ✅     [:top:](#host-apis) ```rust - fn get_total_memory(instance: &mut Instance) -> u32 + fn get_total_memory(vmctx: &mut Ctx) -> u32 ``` ###### TIMING @@ -337,7 +337,7 @@ ``` - **open** (\_\_\_syscall5) ✅ ❗️ 🔥     [:top:](#host-apis) ```rust - fn open(path: u32, flags: c_int, mode: c_int, instance: &mut Instance) -> c_int + fn open(path: u32, flags: c_int, mode: c_int, vmctx: &mut Ctx) -> c_int ``` - **openat** (\_\_\_syscall295)     [:top:](#host-apis) ```rust @@ -385,7 +385,7 @@ ``` - **read** (\_\_\_syscall3) ✅ ❗️     [:top:](#host-apis) ```rust - fn read(fd: c_int, buf: u32, count: size_t, instance: &mut Instance) -> ssize_t + fn read(fd: c_int, buf: u32, count: size_t, vmctx: &mut Ctx) -> ssize_t ``` - **readlink** (\_\_\_syscall85)     [:top:](#host-apis) ```rust diff --git a/lib/emscripten/src/env.rs b/lib/emscripten/src/env.rs index 65c9d9520..df1c624eb 100644 --- a/lib/emscripten/src/env.rs +++ b/lib/emscripten/src/env.rs @@ -8,7 +8,7 @@ use std::mem; use std::os::raw::c_char; use super::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; -use wasmer_runtime_core::{types::Value, Instance}; +use wasmer_runtime_core::{types::Value, vm::Ctx}; //use super::EmscriptenData; //impl Instance { @@ -23,10 +23,10 @@ use wasmer_runtime_core::{types::Value, Instance}; // #[no_mangle] /// emscripten: _getenv // (name: *const char) -> *const c_char; -pub extern "C" fn _getenv(name: c_int, instance: &mut Instance) -> u32 { +pub extern "C" fn _getenv(name: c_int, vmctx: &mut Ctx) -> u32 { debug!("emscripten::_getenv"); - let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char; + let name_addr = vmctx.memory(0)[name as usize] as *const c_char; debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); @@ -35,15 +35,15 @@ pub extern "C" fn _getenv(name: c_int, instance: &mut Instance) -> u32 { return 0; } - unsafe { copy_cstr_into_wasm(instance, c_str) } + unsafe { copy_cstr_into_wasm(vmctx, c_str) } } /// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int); -pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, instance: &mut Instance) { +pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, vmctx: &mut Ctx) { debug!("emscripten::_setenv"); - let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char; - let value_addr = instance.memory_offset_addr(0, value as usize) as *const c_char; + let name_addr = vmctx.memory(0)[name as usize] as *const c_char; + let value_addr = vmctx.memory(0)[value as usize] as *const c_char; debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) }); @@ -52,10 +52,10 @@ pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, instance: } /// emscripten: _putenv // (name: *const char); -pub extern "C" fn _putenv(name: c_int, instance: &mut Instance) { +pub extern "C" fn _putenv(name: c_int, vmctx: &mut Ctx) { debug!("emscripten::_putenv"); - let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char; + let name_addr = vmctx.memory(0)[name as usize] as *const c_char; debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); @@ -63,10 +63,10 @@ pub extern "C" fn _putenv(name: c_int, instance: &mut Instance) { } /// emscripten: _unsetenv // (name: *const char); -pub extern "C" fn _unsetenv(name: c_int, instance: &mut Instance) { +pub extern "C" fn _unsetenv(name: c_int, vmctx: &mut Ctx) { debug!("emscripten::_unsetenv"); - let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char; + let name_addr = vmctx.memory(0)[name as usize] as *const c_char; debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) }); @@ -74,7 +74,7 @@ pub extern "C" fn _unsetenv(name: c_int, instance: &mut Instance) { } #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int { +pub extern "C" fn _getpwnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int { debug!("emscripten::_getpwnam {}", name_ptr); #[repr(C)] @@ -89,21 +89,20 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int { } let name = unsafe { - let memory_name_ptr = instance.memory_offset_addr(0, name_ptr as usize) as *const c_char; + let memory_name_ptr = vmctx.memory(0)[name_ptr as usize] as *const c_char; CStr::from_ptr(memory_name_ptr) }; unsafe { let passwd = &*libc_getpwnam(name.as_ptr()); - let passwd_struct_offset = call_malloc(mem::size_of::() as _, instance); + let passwd_struct_offset = call_malloc(mem::size_of::() as _, vmctx); - let passwd_struct_ptr = - instance.memory_offset_addr(0, passwd_struct_offset as _) as *mut GuestPasswd; - (*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(instance, passwd.pw_name); - (*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(instance, passwd.pw_passwd); - (*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(instance, passwd.pw_gecos); - (*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(instance, passwd.pw_dir); - (*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(instance, passwd.pw_shell); + let passwd_struct_ptr = vmctx.memory(0)[passwd_struct_offset as usize] as *mut GuestPasswd; + (*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(vmctx, passwd.pw_name); + (*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(vmctx, passwd.pw_passwd); + (*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(vmctx, passwd.pw_gecos); + (*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(vmctx, passwd.pw_dir); + (*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(vmctx, passwd.pw_shell); (*passwd_struct_ptr).pw_uid = passwd.pw_uid; (*passwd_struct_ptr).pw_gid = passwd.pw_gid; @@ -112,7 +111,7 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int { } #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int { +pub extern "C" fn _getgrnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int { debug!("emscripten::_getgrnam {}", name_ptr); #[repr(C)] @@ -124,66 +123,69 @@ pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int { } let name = unsafe { - let memory_name_ptr = instance.memory_offset_addr(0, name_ptr as usize) as *const c_char; + let memory_name_ptr = vmctx.memory(0)[name_ptr as usize] as *const c_char; CStr::from_ptr(memory_name_ptr) }; unsafe { let group = &*libc_getgrnam(name.as_ptr()); - let group_struct_offset = call_malloc(mem::size_of::() as _, instance); + let group_struct_offset = call_malloc(mem::size_of::() as _, vmctx); - let group_struct_ptr = - instance.memory_offset_addr(0, group_struct_offset as _) as *mut GuestGroup; - (*group_struct_ptr).gr_name = copy_cstr_into_wasm(instance, group.gr_name); - (*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(instance, group.gr_passwd); + let group_struct_ptr = vmctx.memory(0)[group_struct_offset as usize] as *mut GuestGroup; + (*group_struct_ptr).gr_name = copy_cstr_into_wasm(vmctx, group.gr_name); + (*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(vmctx, group.gr_passwd); (*group_struct_ptr).gr_gid = group.gr_gid; - (*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(instance, group.gr_mem); + (*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(vmctx, group.gr_mem); group_struct_offset as c_int } } -pub fn call_malloc(size: i32, instance: &mut Instance) -> u32 { - let ret = instance - .call("_malloc", &[Value::I32(size)]) - .expect("_malloc call failed"); - if let [Value::I32(x)] = ret.as_slice() { - *x as u32 - } else { - panic!("unexpected value from _malloc: {:?}", ret); - } +pub fn call_malloc(size: i32, vmctx: &mut Ctx) -> u32 { + unimplemented!() +// let ret = instance +// .call("_malloc", &[Value::I32(size)]) +// .expect("_malloc call failed"); +// if let [Value::I32(x)] = ret.as_slice() { +// *x as u32 +// } else { +// panic!("unexpected value from _malloc: {:?}", ret); +// } } -pub fn call_memalign(alignment: u32, size: u32, instance: &mut Instance) -> u32 { - let ret = instance - .call( - "_memalign", - &[Value::I32(alignment as i32), Value::I32(size as i32)], - ) - .expect("_memalign call failed"); - if let [Value::I32(x)] = ret.as_slice() { - *x as u32 - } else { - panic!("unexpected value from _memalign {:?}", ret); - } +pub fn call_memalign(alignment: u32, size: u32, vmctx: &mut Ctx) -> u32 { + unimplemented!() + // let ret = + // call( + // vmctx, + // "_memalign", + // &[Value::I32(alignment as i32), Value::I32(size as i32)], + // ) + // .expect("_memalign call failed"); + // if let [Value::I32(x)] = ret.as_slice() { + // *x as u32 + // } else { + // panic!("unexpected value from _memalign {:?}", ret); + // } } -pub fn call_memset(pointer: u32, value: i32, size: u32, instance: &mut Instance) -> u32 { - let ret = instance - .call( - "_memset", - &[ - Value::I32(pointer as i32), - Value::I32(value), - Value::I32(size as i32), - ], - ) - .expect("_memset call failed"); - if let [Value::I32(x)] = ret.as_slice() { - *x as u32 - } else { - panic!("unexpected value from _memset {:?}", ret); - } +pub fn call_memset(pointer: u32, value: i32, size: u32, vmctx: &mut Ctx) -> u32 { + unimplemented!() +// let ret = instance +// .call( +// "_memset", +// &[ +// Value::I32(pointer as i32), +// Value::I32(value), +// Value::I32(size as i32), +// ], +// ) +// .expect("_memset call failed"); +// if let [Value::I32(x)] = ret.as_slice() { +// *x as u32 +// } else { +// panic!("unexpected value from _memset {:?}", ret); +// } } pub extern "C" fn _getpagesize() -> u32 { @@ -192,18 +194,18 @@ pub extern "C" fn _getpagesize() -> u32 { } #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn ___build_environment(environ: c_int, instance: &mut Instance) { +pub extern "C" fn ___build_environment(environ: c_int, vmctx: &mut Ctx) { debug!("emscripten::___build_environment {}", environ); const MAX_ENV_VALUES: u32 = 64; const TOTAL_ENV_SIZE: u32 = 1024; - let mut environment = instance.memory_offset_addr(0, environ as _) as *mut c_int; + let mut environment = vmctx.memory(0)[environ as usize] as *mut c_int; unsafe { let (pool_offset, _pool_slice): (u32, &mut [u8]) = - allocate_on_stack(TOTAL_ENV_SIZE as u32, instance); + allocate_on_stack(TOTAL_ENV_SIZE as u32, vmctx); let (env_offset, _env_slice): (u32, &mut [u8]) = - allocate_on_stack((MAX_ENV_VALUES * 4) as u32, instance); - let mut env_ptr = instance.memory_offset_addr(0, env_offset as _) as *mut c_int; - let mut _pool_ptr = instance.memory_offset_addr(0, pool_offset as _) as *mut c_int; + allocate_on_stack((MAX_ENV_VALUES * 4) as u32, vmctx); + let mut env_ptr = vmctx.memory(0)[env_offset as usize] as *mut c_int; + let mut _pool_ptr = vmctx.memory(0)[pool_offset as usize] as *mut c_int; *env_ptr = pool_offset as i32; *environment = env_offset as i32; @@ -214,7 +216,7 @@ pub extern "C" fn ___build_environment(environ: c_int, instance: &mut Instance) // }; } -pub extern "C" fn _sysconf(name: c_int, _instance: &mut Instance) -> c_long { +pub extern "C" fn _sysconf(name: c_int, _vmctx: &mut Ctx) -> c_long { debug!("emscripten::_sysconf {}", name); // TODO: Implement like emscripten expects regarding memory/page size unsafe { sysconf(name) } diff --git a/lib/emscripten/src/exception.rs b/lib/emscripten/src/exception.rs index 418ef6501..cf8a12ea6 100644 --- a/lib/emscripten/src/exception.rs +++ b/lib/emscripten/src/exception.rs @@ -1,16 +1,16 @@ use super::env; use super::process::_abort; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::{Instance, vm::Ctx}; /// emscripten: ___cxa_allocate_exception -pub extern "C" fn ___cxa_allocate_exception(size: u32, instance: &mut Instance) -> u32 { +pub extern "C" fn ___cxa_allocate_exception(size: u32, vmctx: &mut Ctx) -> u32 { debug!("emscripten::___cxa_allocate_exception"); - env::call_malloc(size as _, instance) + env::call_malloc(size as _, vmctx) } /// emscripten: ___cxa_throw /// TODO: We don't have support for exceptions yet -pub extern "C" fn ___cxa_throw(_ptr: u32, ty: u32, destructor: u32, instance: &mut Instance) { +pub extern "C" fn ___cxa_throw(_ptr: u32, ty: u32, destructor: u32, vmctx: &mut Ctx) { debug!("emscripten::___cxa_throw"); _abort(); } diff --git a/lib/emscripten/src/jmp.rs b/lib/emscripten/src/jmp.rs index eb28a68c5..87d105546 100644 --- a/lib/emscripten/src/jmp.rs +++ b/lib/emscripten/src/jmp.rs @@ -1,15 +1,15 @@ use libc::{c_int, c_void}; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; /// setjmp -pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int { +pub extern "C" fn __setjmp(env_addr: u32, vmctx: &mut Ctx) -> c_int { debug!("emscripten::__setjmp (setjmp)"); unimplemented!() // unsafe { // // Rather than using the env as the holder of the jump buffer pointer, // // we use the environment address to store the index relative to jumps // // so the address of the jump it's outside the wasm memory itself. - // let jump_index = instance.memory_offset_addr(0, env_addr as usize) as *mut i8; + // let jump_index = vmctx.memory(0)[env_addr as usize] as *mut i8; // // We create the jump buffer outside of the wasm memory // let jump_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]); // let mut jumps = &mut instance.emscripten_data().as_mut().unwrap().jumps; @@ -23,12 +23,12 @@ pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int { } /// longjmp -pub extern "C" fn __longjmp(env_addr: u32, val: c_int, instance: &mut Instance) -> ! { +pub extern "C" fn __longjmp(env_addr: u32, val: c_int, vmctx: &mut Ctx) -> ! { debug!("emscripten::__longjmp (longjmp) {}", val); unimplemented!() // unsafe { // // We retrieve the jump index from the env address - // let jump_index = instance.memory_offset_addr(0, env_addr as usize) as *mut i8; + // let jump_index = vmctx.memory(0)[env_addr as usize] as *mut i8; // let mut jumps = &mut instance.emscripten_data().as_mut().unwrap().jumps; // // We get the real jump buffer from the jumps vector, using the retrieved index // let mut jump_buf = &jumps[*jump_index as usize]; diff --git a/lib/emscripten/src/lock.rs b/lib/emscripten/src/lock.rs index 7a8ec9cb1..17073b591 100644 --- a/lib/emscripten/src/lock.rs +++ b/lib/emscripten/src/lock.rs @@ -1,17 +1,17 @@ use libc::c_int; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; // NOTE: Not implemented by Emscripten -pub extern "C" fn ___lock(which: c_int, varargs: c_int, _instance: &mut Instance) { +pub extern "C" fn ___lock(which: c_int, varargs: c_int, _vmctx: &mut Ctx) { debug!("emscripten::___lock {}, {}", which, varargs); } // NOTE: Not implemented by Emscripten -pub extern "C" fn ___unlock(which: c_int, varargs: c_int, _instance: &mut Instance) { +pub extern "C" fn ___unlock(which: c_int, varargs: c_int, _vmctx: &mut Ctx) { debug!("emscripten::___unlock {}, {}", which, varargs); } // NOTE: Not implemented by Emscripten -pub extern "C" fn ___wait(_which: c_int, _varargs: c_int, _instance: &mut Instance) { +pub extern "C" fn ___wait(_which: c_int, _varargs: c_int, _vmctx: &mut Ctx) { debug!("emscripten::___wait"); } diff --git a/lib/emscripten/src/memory.rs b/lib/emscripten/src/memory.rs index c59af6317..7e48e0144 100644 --- a/lib/emscripten/src/memory.rs +++ b/lib/emscripten/src/memory.rs @@ -1,20 +1,15 @@ use super::process::abort_with_message; use libc::{c_int, c_void, memcpy, size_t}; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; /// emscripten: _emscripten_memcpy_big -pub extern "C" fn _emscripten_memcpy_big( - dest: u32, - src: u32, - len: u32, - instance: &mut Instance, -) -> u32 { +pub extern "C" fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, vmctx: &mut Ctx) -> u32 { debug!( "emscripten::_emscripten_memcpy_big {}, {}, {}", dest, src, len ); - let dest_addr = instance.memory_offset_addr(0, dest as usize) as *mut c_void; - let src_addr = instance.memory_offset_addr(0, src as usize) as *mut c_void; + let dest_addr = vmctx.memory(0)[dest as usize] as *mut c_void; + let src_addr = vmctx.memory(0)[src as usize] as *mut c_void; unsafe { memcpy(dest_addr, src_addr, len as size_t); } @@ -22,16 +17,18 @@ pub extern "C" fn _emscripten_memcpy_big( } /// emscripten: getTotalMemory -pub extern "C" fn get_total_memory(_instance: &mut Instance) -> u32 { +pub extern "C" fn get_total_memory(_vmctx: &mut Ctx) -> u32 { debug!("emscripten::get_total_memory"); // instance.memories[0].current_pages() + // TODO: Fix implementation 16_777_216 } /// emscripten: enlargeMemory -pub extern "C" fn enlarge_memory(_instance: &mut Instance) { +pub extern "C" fn enlarge_memory(_vmctx: &mut Ctx) { debug!("emscripten::enlarge_memory"); // instance.memories[0].grow(100); + // TODO: Fix implementation } /// emscripten: abortOnCannotGrowMemory diff --git a/lib/emscripten/src/nullfunc.rs b/lib/emscripten/src/nullfunc.rs index 3cfc44bdd..3121b094a 100644 --- a/lib/emscripten/src/nullfunc.rs +++ b/lib/emscripten/src/nullfunc.rs @@ -1,62 +1,62 @@ use super::process::abort_with_message; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; -pub extern "C" fn nullfunc_ii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_ii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_ii {}", x); abort_with_message("Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_iii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_iii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_iii {}", x); abort_with_message("Invalid function pointer called with signature 'iii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_iiii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_iiii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_iiii {}", x); abort_with_message("Invalid function pointer called with signature 'iiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_iiiii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_iiiii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_iiiii {}", x); abort_with_message("Invalid function pointer called with signature 'iiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_iiiiii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_iiiiii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_iiiiii {}", x); abort_with_message("Invalid function pointer called with signature 'iiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_v(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_v(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_v {}", x); abort_with_message("Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_vi(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_vi(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_vi {}", x); abort_with_message("Invalid function pointer called with signature 'vi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_vii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_vii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_vii {}", x); abort_with_message("Invalid function pointer called with signature 'vii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_viii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_viii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_viii {}", x); abort_with_message("Invalid function pointer called with signature 'viii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_viiii(x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_viiii(x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_viiii {}", x); abort_with_message("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_viiiii(_x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_viiiii(_x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_viiiii"); abort_with_message("Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub extern "C" fn nullfunc_viiiiii(_x: u32, _instance: &Instance) { +pub extern "C" fn nullfunc_viiiiii(_x: u32, _vmctx: &mut Ctx) { debug!("emscripten::nullfunc_viiiiii"); abort_with_message("Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } diff --git a/lib/emscripten/src/process.rs b/lib/emscripten/src/process.rs index 6f65f75e2..ae48bdff8 100644 --- a/lib/emscripten/src/process.rs +++ b/lib/emscripten/src/process.rs @@ -1,7 +1,7 @@ use libc::{abort, c_char, c_int, exit, pid_t, EAGAIN}; use std::ffi::CStr; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; pub extern "C" fn abort_with_message(message: &str) { debug!("emscripten::abort_with_message"); @@ -16,7 +16,7 @@ pub extern "C" fn _abort() { } } -pub extern "C" fn _fork(_instance: &mut Instance) -> pid_t { +pub extern "C" fn _fork(_vmctx: &mut Ctx) -> pid_t { debug!("emscripten::_fork"); // unsafe { // fork() @@ -24,14 +24,14 @@ pub extern "C" fn _fork(_instance: &mut Instance) -> pid_t { -1 } -pub extern "C" fn _exit(status: c_int, _instance: &mut Instance) -> ! { +pub extern "C" fn _exit(status: c_int, _vmctx: &mut Ctx) -> ! { debug!("emscripten::_exit {}", status); unsafe { exit(status) } } -pub extern "C" fn em_abort(message: u32, instance: &mut Instance) { +pub extern "C" fn em_abort(message: u32, vmctx: &mut Ctx) { debug!("emscripten::em_abort {}", message); - let message_addr = instance.memory_offset_addr(0, message as usize) as *mut c_char; + let message_addr = vmctx.memory(0)[message as usize] as *mut c_char; unsafe { let message = CStr::from_ptr(message_addr) .to_str() diff --git a/lib/emscripten/src/signal.rs b/lib/emscripten/src/signal.rs index 97792588d..1e7c5dbac 100644 --- a/lib/emscripten/src/signal.rs +++ b/lib/emscripten/src/signal.rs @@ -1,25 +1,25 @@ // use super::varargs::VarArgs; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _sigemptyset(set: u32, instance: &mut Instance) -> i32 { +pub extern "C" fn _sigemptyset(set: u32, vmctx: &mut Ctx) -> i32 { debug!("emscripten::_sigemptyset"); - let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; + let set_addr = vmctx.memory(0)[set as usize] as *mut u32; unsafe { *set_addr = 0; } 0 } -pub extern "C" fn _sigaction(signum: u32, act: u32, oldact: u32, _instance: &mut Instance) -> i32 { +pub extern "C" fn _sigaction(signum: u32, act: u32, oldact: u32, _vmctx: &mut Ctx) -> i32 { debug!("emscripten::_sigaction {}, {}, {}", signum, act, oldact); 0 } #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _sigaddset(set: u32, signum: u32, instance: &mut Instance) -> i32 { +pub extern "C" fn _sigaddset(set: u32, signum: u32, vmctx: &mut Ctx) -> i32 { debug!("emscripten::_sigaddset {}, {}", set, signum); - let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; + let set_addr = vmctx.memory(0)[set as usize] as *mut u32; unsafe { *set_addr |= 1 << (signum - 1); } @@ -31,7 +31,7 @@ pub extern "C" fn _sigprocmask() -> i32 { 0 } -pub extern "C" fn _signal(sig: u32, _instance: &mut Instance) -> i32 { +pub extern "C" fn _signal(sig: u32, _vmctx: &mut Ctx) -> i32 { debug!("emscripten::_signal ({})", sig); 0 } diff --git a/lib/emscripten/src/syscalls.rs b/lib/emscripten/src/syscalls.rs index 7a58c7cb7..3cafdcc64 100644 --- a/lib/emscripten/src/syscalls.rs +++ b/lib/emscripten/src/syscalls.rs @@ -70,7 +70,7 @@ use libc::{ SO_REUSEADDR, TIOCGWINSZ, }; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; use super::env; use std::mem; @@ -96,9 +96,9 @@ use libc::SO_NOSIGPIPE; const SO_NOSIGPIPE: c_int = 0; /// exit -pub extern "C" fn ___syscall1(which: c_int, mut varargs: VarArgs, instance: &mut Instance) { +pub extern "C" fn ___syscall1(which: c_int, mut varargs: VarArgs, vmctx: &mut Ctx) { debug!("emscripten::___syscall1 (exit) {}", which); - let status: i32 = varargs.get(instance); + let status: i32 = varargs.get(vmctx); unsafe { exit(status); } @@ -108,14 +108,14 @@ pub extern "C" fn ___syscall1(which: c_int, mut varargs: VarArgs, instance: &mut pub extern "C" fn ___syscall3( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> ssize_t { debug!("emscripten::___syscall3 (read) {}", which); - let fd: i32 = varargs.get(instance); - let buf: u32 = varargs.get(instance); - let count: usize = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let buf: u32 = varargs.get(vmctx); + let count: usize = varargs.get(vmctx); debug!("=> fd: {}, buf_offset: {}, count: {}", fd, buf, count); - let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut c_void; + let buf_addr = vmctx.memory(0)[buf as usize] as *mut c_void; let ret = unsafe { read(fd, buf_addr, count) }; debug!("=> ret: {}", ret); ret @@ -125,14 +125,14 @@ pub extern "C" fn ___syscall3( pub extern "C" fn ___syscall4( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall4 (write) {}", which); - let fd: i32 = varargs.get(instance); - let buf: u32 = varargs.get(instance); - let count: u32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let buf: u32 = varargs.get(vmctx); + let count: u32 = varargs.get(vmctx); debug!("=> fd: {}, buf: {}, count: {}", fd, buf, count); - let buf_addr = instance.memory_offset_addr(0, buf as usize) as *const c_void; + let buf_addr = vmctx.memory(0)[buf as usize] as *const c_void; unsafe { write(fd, buf_addr, count as usize) as i32 } } @@ -140,13 +140,13 @@ pub extern "C" fn ___syscall4( pub extern "C" fn ___syscall5( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall5 (open) {}", which); - let pathname: u32 = varargs.get(instance); - let flags: i32 = varargs.get(instance); - let mode: u32 = varargs.get(instance); - let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8; + let pathname: u32 = varargs.get(vmctx); + let flags: i32 = varargs.get(vmctx); + let mode: u32 = varargs.get(vmctx); + let pathname_addr = vmctx.memory(0)[pathname as usize] as *const i8; let path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() }; let fd = unsafe { open(pathname_addr, flags, mode) }; debug!( @@ -160,10 +160,10 @@ pub extern "C" fn ___syscall5( pub extern "C" fn ___syscall6( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall6 (close) {}", which); - let fd: i32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); debug!("fd: {}", fd); unsafe { close(fd) } } @@ -172,12 +172,12 @@ pub extern "C" fn ___syscall6( pub extern "C" fn ___syscall12( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall12 (chdir) {}", which); - let path_addr: i32 = varargs.get(instance); + let path_addr: i32 = varargs.get(vmctx); unsafe { - let path_ptr = instance.memory_offset_addr(0, path_addr as usize) as *const i8; + let path_ptr = vmctx.memory(0)[path_addr as usize] as *const i8; let path = std::ffi::CStr::from_ptr(path_ptr); let ret = chdir(path_ptr); debug!("=> path: {:?}, ret: {}", path, ret); @@ -195,12 +195,12 @@ pub extern "C" fn ___syscall20() -> pid_t { pub extern "C" fn ___syscall39( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall39 (mkdir) {}", which); - let pathname: u32 = varargs.get(instance); - let mode: u32 = varargs.get(instance); - let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8; + let pathname: u32 = varargs.get(vmctx); + let mode: u32 = varargs.get(vmctx); + let pathname_addr = vmctx.memory(0)[pathname as usize] as *const i8; unsafe { mkdir(pathname_addr, mode as _) } } @@ -208,11 +208,11 @@ pub extern "C" fn ___syscall39( pub extern "C" fn ___syscall40( _which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall40 (rmdir)"); - let pathname: u32 = varargs.get(instance); - let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8; + let pathname: u32 = varargs.get(vmctx); + let pathname_addr = vmctx.memory(0)[pathname as usize] as *const i8; unsafe { rmdir(pathname_addr) } } @@ -220,18 +220,18 @@ pub extern "C" fn ___syscall40( pub extern "C" fn ___syscall54( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall54 (ioctl) {}", which); - let fd: i32 = varargs.get(instance); - let request: u32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let request: u32 = varargs.get(vmctx); debug!("fd: {}, op: {}", fd, request); // Got the equivalents here: https://code.woboq.org/linux/linux/include/uapi/asm-generic/ioctls.h.html match request as _ { 21537 => { // FIONBIO - let argp: u32 = varargs.get(instance); - let argp_ptr = instance.memory_offset_addr(0, argp as _); + let argp: u32 = varargs.get(vmctx); + let argp_ptr = vmctx.memory(0)[argp as usize] as *mut c_void; let ret = unsafe { ioctl(fd, FIONBIO, argp_ptr) }; debug!("ret(FIONBIO): {}", ret); ret @@ -239,8 +239,8 @@ pub extern "C" fn ___syscall54( } 21523 => { // TIOCGWINSZ - let argp: u32 = varargs.get(instance); - let argp_ptr = instance.memory_offset_addr(0, argp as _); + let argp: u32 = varargs.get(vmctx); + let argp_ptr = vmctx.memory(0)[argp as usize] as *mut c_void; let ret = unsafe { ioctl(fd, TIOCGWINSZ, argp_ptr) }; debug!("ret(TIOCGWINSZ): {} (harcoded to 0)", ret); // ret @@ -266,11 +266,11 @@ pub extern "C" fn ___syscall54( pub extern "C" fn ___syscall57( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall57 (setpgid) {}", which); - let pid: i32 = varargs.get(instance); - let pgid: i32 = varargs.get(instance); + let pid: i32 = varargs.get(vmctx); + let pgid: i32 = varargs.get(vmctx); unsafe { setpgid(pid, pgid) } } @@ -278,12 +278,12 @@ pub extern "C" fn ___syscall57( pub extern "C" fn ___syscall63( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall63 (dup2) {}", which); - let src: i32 = varargs.get(instance); - let dst: i32 = varargs.get(instance); + let src: i32 = varargs.get(vmctx); + let dst: i32 = varargs.get(vmctx); unsafe { dup2(src, dst) } } @@ -299,11 +299,11 @@ pub extern "C" fn ___syscall64() -> pid_t { pub extern "C" fn ___syscall102( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall102 (socketcall) {}", which); - let call: u32 = varargs.get(instance); - let mut socket_varargs: VarArgs = varargs.get(instance); + let call: u32 = varargs.get(vmctx); + let mut socket_varargs: VarArgs = varargs.get(vmctx); #[repr(C)] pub struct GuestSockaddrIn { @@ -330,9 +330,9 @@ pub extern "C" fn ___syscall102( 1 => { debug!("socket: socket"); // socket (domain: c_int, ty: c_int, protocol: c_int) -> c_int - let domain: i32 = socket_varargs.get(instance); - let ty: i32 = socket_varargs.get(instance); - let protocol: i32 = socket_varargs.get(instance); + let domain: i32 = socket_varargs.get(vmctx); + let ty: i32 = socket_varargs.get(vmctx); + let protocol: i32 = socket_varargs.get(vmctx); let fd = unsafe { socket(domain, ty, protocol) }; // set_cloexec unsafe { @@ -361,10 +361,10 @@ pub extern "C" fn ___syscall102( debug!("socket: bind"); // bind (socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int // TODO: Emscripten has a different signature. - let socket: i32 = socket_varargs.get(instance); - let address: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; + let socket: i32 = socket_varargs.get(vmctx); + let address: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let address = vmctx.memory(0)[address as usize] as *mut sockaddr; // Debug received address unsafe { @@ -388,17 +388,17 @@ pub extern "C" fn ___syscall102( debug!("socket: connect"); // connect (socket: c_int, address: *const sockaddr, len: socklen_t) -> c_int // TODO: Emscripten has a different signature. - let socket: i32 = socket_varargs.get(instance); - let address: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; + let socket: i32 = socket_varargs.get(vmctx); + let address: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let address = vmctx.memory(0)[address as usize] as *mut sockaddr; unsafe { connect(socket, address, address_len) } } 4 => { debug!("socket: listen"); // listen (socket: c_int, backlog: c_int) -> c_int - let socket: i32 = socket_varargs.get(instance); - let backlog: i32 = socket_varargs.get(instance); + let socket: i32 = socket_varargs.get(vmctx); + let backlog: i32 = socket_varargs.get(vmctx); let status = unsafe { listen(socket, backlog) }; debug!( "=> socketfd: {}, backlog: {} = status: {}", @@ -409,24 +409,22 @@ pub extern "C" fn ___syscall102( 5 => { debug!("socket: accept"); // accept (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int - let socket: i32 = socket_varargs.get(instance); - let address_addr: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let address = instance.memory_offset_addr(0, address_addr as usize) as *mut sockaddr; + let socket: i32 = socket_varargs.get(vmctx); + let address_addr: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let address = vmctx.memory(0)[address_addr as usize] as *mut sockaddr; debug!( "=> socket: {}, address: {:?}, address_len: {}", socket, address, address_len ); - let address_len_addr = - instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t; + let address_len_addr = vmctx.memory(0)[address_len as usize] as *mut socklen_t; // let mut address_len_addr: socklen_t = 0; let fd = unsafe { accept(socket, address, address_len_addr) }; unsafe { - let address_linux = - instance.memory_offset_addr(0, address_addr as usize) as *mut LinuxSockAddr; + let address_linux = vmctx.memory(0)[address_addr as usize] as *mut LinuxSockAddr; (*address_linux).sa_family = (*address).sa_family as u16; (*address_linux).sa_data = (*address).sa_data; }; @@ -443,51 +441,48 @@ pub extern "C" fn ___syscall102( 6 => { debug!("socket: getsockname"); // getsockname (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int - let socket: i32 = socket_varargs.get(instance); - let address: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; - let address_len_addr = - instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t; + let socket: i32 = socket_varargs.get(vmctx); + let address: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let address = vmctx.memory(0)[address as usize] as *mut sockaddr; + let address_len_addr = vmctx.memory(0)[address_len as usize] as *mut socklen_t; unsafe { getsockname(socket, address, address_len_addr) } } 7 => { debug!("socket: getpeername"); // getpeername (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int - let socket: i32 = socket_varargs.get(instance); - let address: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; - let address_len_addr = - instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t; + let socket: i32 = socket_varargs.get(vmctx); + let address: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let address = vmctx.memory(0)[address as usize] as *mut sockaddr; + let address_len_addr = vmctx.memory(0)[address_len as usize] 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: i32 = socket_varargs.get(instance); - let buf: u32 = socket_varargs.get(instance); - let flags: usize = socket_varargs.get(instance); - let len: i32 = socket_varargs.get(instance); - let address: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut c_void; - let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; + let socket: i32 = socket_varargs.get(vmctx); + let buf: u32 = socket_varargs.get(vmctx); + let flags: usize = socket_varargs.get(vmctx); + let len: i32 = socket_varargs.get(vmctx); + let address: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let buf_addr = vmctx.memory(0)[buf as usize] as *mut c_void; + let address = vmctx.memory(0)[address as usize] 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: i32 = socket_varargs.get(instance); - let buf: u32 = socket_varargs.get(instance); - let flags: usize = socket_varargs.get(instance); - let len: i32 = socket_varargs.get(instance); - let address: u32 = socket_varargs.get(instance); - let address_len: u32 = socket_varargs.get(instance); - let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut c_void; - let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; - let address_len_addr = - instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t; + let socket: i32 = socket_varargs.get(vmctx); + let buf: u32 = socket_varargs.get(vmctx); + let flags: usize = socket_varargs.get(vmctx); + let len: i32 = socket_varargs.get(vmctx); + let address: u32 = socket_varargs.get(vmctx); + let address_len: u32 = socket_varargs.get(vmctx); + let buf_addr = vmctx.memory(0)[buf as usize] as *mut c_void; + let address = vmctx.memory(0)[address as usize] as *mut sockaddr; + let address_len_addr = vmctx.memory(0)[address_len as usize] as *mut socklen_t; unsafe { recvfrom(socket, buf_addr, flags, len, address, address_len_addr) as i32 } } 14 => { @@ -498,16 +493,16 @@ pub extern "C" fn ___syscall102( // 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: i32 = socket_varargs.get(instance); + let socket: i32 = socket_varargs.get(vmctx); // SOL_SOCKET = 0xffff (BSD, Linux) let level: i32 = SOL_SOCKET; - let _: u32 = socket_varargs.get(instance); + let _: u32 = socket_varargs.get(vmctx); // SO_REUSEADDR = 0x4 (BSD, Linux) let name: i32 = SO_REUSEADDR; - let _: u32 = socket_varargs.get(instance); - let value: u32 = socket_varargs.get(instance); - let option_len: u32 = socket_varargs.get(instance); - let value_addr = instance.memory_offset_addr(0, value as usize) as *mut c_void; // Endian problem + let _: u32 = socket_varargs.get(vmctx); + let value: u32 = socket_varargs.get(vmctx); + let option_len: u32 = socket_varargs.get(vmctx); + let value_addr = vmctx.memory(0)[value as usize] as *mut c_void; // Endian problem let ret = unsafe { setsockopt(socket, level, name, value_addr, option_len) }; debug!("=> socketfd: {}, level: {} (SOL_SOCKET/0xffff), name: {} (SO_REUSEADDR/4), value_addr: {:?}, option_len: {} = status: {}", socket, level, name, value_addr, option_len, ret); @@ -516,32 +511,31 @@ pub extern "C" fn ___syscall102( 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: i32 = socket_varargs.get(instance); - let level: i32 = socket_varargs.get(instance); - let name: i32 = socket_varargs.get(instance); - let value: u32 = socket_varargs.get(instance); - let option_len: u32 = socket_varargs.get(instance); - let value_addr = instance.memory_offset_addr(0, value as usize) as *mut c_void; - let option_len_addr = - instance.memory_offset_addr(0, option_len as usize) as *mut socklen_t; + let socket: i32 = socket_varargs.get(vmctx); + let level: i32 = socket_varargs.get(vmctx); + let name: i32 = socket_varargs.get(vmctx); + let value: u32 = socket_varargs.get(vmctx); + let option_len: u32 = socket_varargs.get(vmctx); + let value_addr = vmctx.memory(0)[value as usize] as *mut c_void; + let option_len_addr = vmctx.memory(0)[option_len as usize] 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(instance); - let msg: u32 = socket_varargs.get(instance); - let flags: i32 = socket_varargs.get(instance); - let msg_addr = instance.memory_offset_addr(0, msg as usize) as *const msghdr; + let socket: i32 = socket_varargs.get(vmctx); + let msg: u32 = socket_varargs.get(vmctx); + let flags: i32 = socket_varargs.get(vmctx); + let msg_addr = vmctx.memory(0)[msg as usize] 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(instance); - let msg: u32 = socket_varargs.get(instance); - let flags: i32 = socket_varargs.get(instance); - let msg_addr = instance.memory_offset_addr(0, msg as usize) as *mut msghdr; + let socket: i32 = socket_varargs.get(vmctx); + let msg: u32 = socket_varargs.get(vmctx); + let flags: i32 = socket_varargs.get(vmctx); + let msg_addr = vmctx.memory(0)[msg as usize] as *mut msghdr; unsafe { recvmsg(socket, msg_addr, flags) as i32 } } _ => { @@ -556,15 +550,15 @@ pub extern "C" fn ___syscall102( pub extern "C" fn ___syscall114( _which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> pid_t { debug!("emscripten::___syscall114 (wait4)"); - let pid: pid_t = varargs.get(instance); - let status: u32 = varargs.get(instance); - let options: c_int = varargs.get(instance); - let rusage: u32 = varargs.get(instance); - let status_addr = instance.memory_offset_addr(0, status as usize) as *mut c_int; - let rusage_addr = instance.memory_offset_addr(0, rusage as usize) as *mut rusage; + let pid: pid_t = varargs.get(vmctx); + let status: u32 = varargs.get(vmctx); + let options: c_int = varargs.get(vmctx); + let rusage: u32 = varargs.get(vmctx); + let status_addr = vmctx.memory(0)[status as usize] as *mut c_int; + let rusage_addr = vmctx.memory(0)[rusage as usize] as *mut rusage; let res = unsafe { wait4(pid, status_addr, options, rusage_addr) }; debug!( "=> pid: {}, status: {:?}, options: {}, rusage: {:?} = pid: {}", @@ -578,12 +572,12 @@ pub extern "C" fn ___syscall114( pub extern "C" fn ___syscall122( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall122 (uname) {}", which); - let buf: u32 = varargs.get(instance); + let buf: u32 = varargs.get(vmctx); debug!("=> buf: {}", buf); - let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut utsname; + let buf_addr = vmctx.memory(0)[buf as usize] as *mut utsname; unsafe { uname(buf_addr) } } @@ -592,21 +586,21 @@ pub extern "C" fn ___syscall122( pub extern "C" fn ___syscall142( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall142 (newselect) {}", which); - let nfds: i32 = varargs.get(instance); - let readfds: u32 = varargs.get(instance); - let writefds: u32 = varargs.get(instance); - let exceptfds: u32 = varargs.get(instance); - let _timeout: i32 = varargs.get(instance); + let nfds: i32 = varargs.get(vmctx); + let readfds: u32 = varargs.get(vmctx); + let writefds: u32 = varargs.get(vmctx); + let exceptfds: u32 = varargs.get(vmctx); + let _timeout: i32 = varargs.get(vmctx); assert!(nfds <= 64, "`nfds` must be less than or equal to 64"); assert!(exceptfds == 0, "`exceptfds` is not supporrted"); - let readfds_ptr = instance.memory_offset_addr(0, readfds as _) as _; - let writefds_ptr = instance.memory_offset_addr(0, writefds as _) as _; + let readfds_ptr = vmctx.memory(0)[readfds as usize] as _; + let writefds_ptr = vmctx.memory(0)[writefds as usize] as _; unsafe { select(nfds, readfds_ptr, writefds_ptr, 0 as _, 0 as _) } } @@ -615,26 +609,26 @@ pub extern "C" fn ___syscall142( pub extern "C" fn ___syscall192( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall192 (mmap2) {}", which); - let addr: i32 = varargs.get(instance); - let len: u32 = varargs.get(instance); - let prot: i32 = varargs.get(instance); - let flags: i32 = varargs.get(instance); - let fd: i32 = varargs.get(instance); - let off: i32 = varargs.get(instance); + let addr: i32 = varargs.get(vmctx); + let len: u32 = varargs.get(vmctx); + let prot: i32 = varargs.get(vmctx); + let flags: i32 = varargs.get(vmctx); + let fd: i32 = varargs.get(vmctx); + let off: i32 = varargs.get(vmctx); debug!( "=> addr: {}, len: {}, prot: {}, flags: {}, fd: {}, off: {}", addr, len, prot, flags, fd, off ); if fd == -1 { - let ptr = env::call_memalign(16384, len, instance); + let ptr = env::call_memalign(16384, len, vmctx); if ptr == 0 { return -1; } - env::call_memset(ptr, 0, len, instance); + env::call_memset(ptr, 0, len, vmctx); ptr as _ } else { -1 @@ -645,12 +639,12 @@ pub extern "C" fn ___syscall192( pub extern "C" fn ___syscall140( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> off_t { debug!("emscripten::___syscall140 (lseek) {}", which); - let fd: i32 = varargs.get(instance); - let offset: i64 = varargs.get(instance); - let whence: i32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let offset: i64 = varargs.get(vmctx); + let whence: i32 = varargs.get(vmctx); debug!("=> fd: {}, offset: {}, whence = {}", fd, offset, whence); unsafe { lseek(fd, offset, whence) } } @@ -660,19 +654,19 @@ pub extern "C" fn ___syscall140( pub extern "C" fn ___syscall145( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> ssize_t { debug!("emscripten::___syscall145 (readv) {}", which); - // let fd: i32 = varargs.get(instance); - // let iov: u32 = varargs.get(instance); - // let iovcnt: i32 = varargs.get(instance); + // let fd: i32 = varargs.get(vmctx); + // let iov: u32 = varargs.get(vmctx); + // let iovcnt: i32 = varargs.get(vmctx); // debug!("=> fd: {}, iov: {}, iovcnt = {}", fd, iov, iovcnt); - // let iov_addr = instance.memory_offset_addr(0, iov as usize) as *mut iovec; + // let iov_addr = vmctx.memory(0)[iov as usize] as *mut iovec; // unsafe { readv(fd, iov_addr, iovcnt) } - let fd: i32 = varargs.get(instance); - let iov: i32 = varargs.get(instance); - let iovcnt: i32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let iov: i32 = varargs.get(vmctx); + let iovcnt: i32 = varargs.get(vmctx); #[repr(C)] struct GuestIovec { @@ -684,10 +678,8 @@ pub extern "C" fn ___syscall145( let mut ret = 0; unsafe { for i in 0..iovcnt { - let guest_iov_addr = - instance.memory_offset_addr(0, (iov + i * 8) as usize) as *mut GuestIovec; - let iov_base = - instance.memory_offset_addr(0, (*guest_iov_addr).iov_base as usize) as *mut c_void; + let guest_iov_addr = vmctx.memory(0)[(iov + i * 8) as usize] as *mut GuestIovec; + let iov_base = vmctx.memory(0)[(*guest_iov_addr).iov_base as usize] as *mut c_void; let iov_len: usize = (*guest_iov_addr).iov_len as _; // debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len); let curr = read(fd, iov_base, iov_len); @@ -706,12 +698,12 @@ pub extern "C" fn ___syscall145( pub extern "C" fn ___syscall146( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> ssize_t { debug!("emscripten::___syscall146 (writev) {}", which); - let fd: i32 = varargs.get(instance); - let iov: i32 = varargs.get(instance); - let iovcnt: i32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let iov: i32 = varargs.get(vmctx); + let iovcnt: i32 = varargs.get(vmctx); #[repr(C)] struct GuestIovec { @@ -723,10 +715,8 @@ pub extern "C" fn ___syscall146( let mut ret = 0; unsafe { for i in 0..iovcnt { - let guest_iov_addr = - instance.memory_offset_addr(0, (iov + i * 8) as usize) as *mut GuestIovec; - let iov_base = instance.memory_offset_addr(0, (*guest_iov_addr).iov_base as usize) - as *const c_void; + let guest_iov_addr = vmctx.memory(0)[(iov + i * 8) as usize] as *mut GuestIovec; + let iov_base = vmctx.memory(0)[(*guest_iov_addr).iov_base as usize] as *const c_void; let iov_len: usize = (*guest_iov_addr).iov_len as _; // debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len); let curr = write(fd, iov_base, iov_len); @@ -744,19 +734,19 @@ pub extern "C" fn ___syscall146( pub extern "C" fn ___syscall180( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall180 (pread) {}", which); - let fd: i32 = varargs.get(instance); - let buf: u32 = varargs.get(instance); - let count: u32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let buf: u32 = varargs.get(vmctx); + let count: u32 = varargs.get(vmctx); { - let zero: u32 = varargs.get(instance); + let zero: u32 = varargs.get(vmctx); assert_eq!(zero, 0); } - let offset: i64 = varargs.get(instance); + let offset: i64 = varargs.get(vmctx); - let buf_ptr = instance.memory_offset_addr(0, buf as _) as _; + let buf_ptr = vmctx.memory(0)[buf as usize] as _; unsafe { pread(fd, buf_ptr, count as _, offset) as _ } } @@ -765,19 +755,19 @@ pub extern "C" fn ___syscall180( pub extern "C" fn ___syscall181( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall181 (pwrite) {}", which); - let fd: i32 = varargs.get(instance); - let buf: u32 = varargs.get(instance); - let count: u32 = varargs.get(instance); + let fd: i32 = varargs.get(vmctx); + let buf: u32 = varargs.get(vmctx); + let count: u32 = varargs.get(vmctx); { - let zero: u32 = varargs.get(instance); + let zero: u32 = varargs.get(vmctx); assert_eq!(zero, 0); } - let offset: i64 = varargs.get(instance); + let offset: i64 = varargs.get(vmctx); - let buf_ptr = instance.memory_offset_addr(0, buf as _) as _; + let buf_ptr = vmctx.memory(0)[buf as usize] as _; let status = unsafe { pwrite(fd, buf_ptr, count as _, offset) as _ }; debug!( "=> fd: {}, buf: {}, count: {}, offset: {} = status:{}", @@ -790,13 +780,13 @@ pub extern "C" fn ___syscall181( pub extern "C" fn ___syscall195( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall195 (stat64) {}", which); - let pathname: u32 = varargs.get(instance); - let buf: u32 = varargs.get(instance); + let pathname: u32 = varargs.get(vmctx); + let buf: u32 = varargs.get(vmctx); - let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8; + let pathname_addr = vmctx.memory(0)[pathname as usize] as *const i8; unsafe { let mut _stat: stat = std::mem::zeroed(); @@ -805,7 +795,7 @@ pub extern "C" fn ___syscall195( if ret != 0 { return ret; } - copy_stat_into_wasm(instance, buf, &_stat); + copy_stat_into_wasm(vmctx, buf, &_stat); } 0 } @@ -814,11 +804,11 @@ pub extern "C" fn ___syscall195( pub extern "C" fn ___syscall197( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall197 (fstat64) {}", which); - let fd: c_int = varargs.get(instance); - let buf: u32 = varargs.get(instance); + let fd: c_int = varargs.get(vmctx); + let buf: u32 = varargs.get(vmctx); unsafe { let mut stat = std::mem::zeroed(); @@ -827,7 +817,7 @@ pub extern "C" fn ___syscall197( if ret != 0 { return ret; } - copy_stat_into_wasm(instance, buf, &stat); + copy_stat_into_wasm(vmctx, buf, &stat); } 0 @@ -855,15 +845,15 @@ pub extern "C" fn ___syscall202() -> gid_t { pub extern "C" fn ___syscall212( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall212 (chown) {}", which); - let pathname: u32 = varargs.get(instance); - let owner: u32 = varargs.get(instance); - let group: u32 = varargs.get(instance); + let pathname: u32 = varargs.get(vmctx); + let owner: u32 = varargs.get(vmctx); + let group: u32 = varargs.get(vmctx); - let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8; + let pathname_addr = vmctx.memory(0)[pathname as usize] as *const i8; unsafe { chown(pathname_addr, owner, group) } } @@ -872,12 +862,12 @@ pub extern "C" fn ___syscall212( pub extern "C" fn ___syscall221( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___syscall221 (fcntl64) {}", which); // fcntl64 - let _fd: i32 = varargs.get(instance); - let cmd: u32 = varargs.get(instance); + let _fd: i32 = varargs.get(vmctx); + let cmd: u32 = varargs.get(vmctx); match cmd { 2 => 0, _ => -1, @@ -888,13 +878,13 @@ pub extern "C" fn ___syscall221( pub extern "C" fn ___syscall330( _which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> pid_t { // Implementation based on description at https://linux.die.net/man/2/dup3 debug!("emscripten::___syscall330 (dup3)"); - let oldfd: c_int = varargs.get(instance); - let newfd: c_int = varargs.get(instance); - let flags: c_int = varargs.get(instance); + let oldfd: c_int = varargs.get(vmctx); + let newfd: c_int = varargs.get(vmctx); + let flags: c_int = varargs.get(vmctx); if oldfd == newfd { return EINVAL; @@ -926,18 +916,18 @@ pub extern "C" fn ___syscall330( pub extern "C" fn ___syscall340( which: c_int, mut varargs: VarArgs, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> 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(instance); - let _resource: i32 = varargs.get(instance); - let _new_limit: u32 = varargs.get(instance); - let old_limit: u32 = varargs.get(instance); + let _pid: i32 = varargs.get(vmctx); + let _resource: i32 = varargs.get(vmctx); + let _new_limit: u32 = varargs.get(vmctx); + let old_limit: u32 = varargs.get(vmctx); if old_limit != 0 { // just report no limits - let buf_ptr = instance.memory_offset_addr(0, old_limit as _) as *mut u8; + let buf_ptr = vmctx.memory(0)[old_limit as usize] as *mut u8; let buf = unsafe { slice::from_raw_parts_mut(buf_ptr, 16) }; LittleEndian::write_i32(&mut buf[..], -1); // RLIM_INFINITY diff --git a/lib/emscripten/src/time.rs b/lib/emscripten/src/time.rs index c053f7440..bfaeb8331 100644 --- a/lib/emscripten/src/time.rs +++ b/lib/emscripten/src/time.rs @@ -6,7 +6,7 @@ use std::time::SystemTime; use time; use super::env; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; #[cfg(target_os = "linux")] use libc::{CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_REALTIME}; @@ -26,7 +26,7 @@ const CLOCK_MONOTONIC_COARSE: libc::clockid_t = 6; /// emscripten: _gettimeofday #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int { +pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, vmctx: &mut Ctx) -> c_int { debug!("emscripten::_gettimeofday {} {}", tp, tz); #[repr(C)] struct GuestTimeVal { @@ -41,7 +41,7 @@ pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) - unsafe { let now = SystemTime::now(); let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); - let timeval_struct_ptr = instance.memory_offset_addr(0, tp as _) as *mut GuestTimeVal; + let timeval_struct_ptr = vmctx.memory(0)[tp as usize] as *mut GuestTimeVal; (*timeval_struct_ptr).tv_sec = since_epoch.as_secs() as _; (*timeval_struct_ptr).tv_usec = since_epoch.subsec_nanos() as _; @@ -54,7 +54,7 @@ pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) - pub extern "C" fn _clock_gettime( clk_id: libc::clockid_t, tp: c_int, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::_clock_gettime {} {}", clk_id, tp); #[repr(C)] @@ -76,7 +76,7 @@ pub extern "C" fn _clock_gettime( }; unsafe { - let timespec_struct_ptr = instance.memory_offset_addr(0, tp as _) as *mut GuestTimeSpec; + let timespec_struct_ptr = vmctx.memory(0)[tp as usize] as *mut GuestTimeSpec; (*timespec_struct_ptr).tv_sec = timespec.sec as _; (*timespec_struct_ptr).tv_nsec = timespec.nsec as _; } @@ -87,10 +87,10 @@ pub extern "C" fn _clock_gettime( pub extern "C" fn ___clock_gettime( clk_id: libc::clockid_t, tp: c_int, - instance: &mut Instance, + vmctx: &mut Ctx, ) -> c_int { debug!("emscripten::___clock_gettime {} {}", clk_id, tp); - _clock_gettime(clk_id, tp, instance) + _clock_gettime(clk_id, tp, vmctx) } /// emscripten: _clock @@ -127,8 +127,8 @@ pub extern "C" fn _tvset() { /// formats time as a C string #[allow(clippy::cast_ptr_alignment)] -unsafe extern "C" fn fmt_time(time: u32, instance: &Instance) -> *const c_char { - let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm); +unsafe extern "C" fn fmt_time(time: u32, vmctx: &mut Ctx) -> *const c_char { + let date = &*(vmctx.memory(0)[time as usize] as *mut guest_tm); let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; let months = vec![ @@ -152,21 +152,21 @@ unsafe extern "C" fn fmt_time(time: u32, instance: &Instance) -> *const c_char { } /// emscripten: _asctime -pub extern "C" fn _asctime(time: u32, instance: &mut Instance) -> u32 { +pub extern "C" fn _asctime(time: u32, vmctx: &mut Ctx) -> u32 { debug!("emscripten::_asctime {}", time); unsafe { - let time_str_ptr = fmt_time(time, instance); - copy_cstr_into_wasm(instance, time_str_ptr) + let time_str_ptr = fmt_time(time, vmctx); + copy_cstr_into_wasm(vmctx, time_str_ptr) - // let c_str = instance.memory_offset_addr(0, res as _) as *mut i8; + // let c_str = vmctx.memory(0)[res as usize] as *mut i8; // use std::ffi::CStr; // debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); } } /// emscripten: _asctime_r -pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u32 { +pub extern "C" fn _asctime_r(time: u32, buf: u32, vmctx: &mut Ctx) -> u32 { debug!("emscripten::_asctime_r {}, {}", time, buf); unsafe { @@ -174,10 +174,10 @@ pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u3 // 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(time, instance); - write_to_buf(time_str_ptr, buf, 26, instance) + let time_str_ptr = fmt_time(time, vmctx); + write_to_buf(time_str_ptr, buf, 26, vmctx) - // let c_str = instance.memory_offset_addr(0, res as _) as *mut i8; + // let c_str = vmctx.memory(0)[res as usize] as *mut i8; // use std::ffi::CStr; // debug!("#### cstr = {:?}", CStr::from_ptr(c_str)); } @@ -185,21 +185,21 @@ pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u3 /// emscripten: _localtime #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int { +pub extern "C" fn _localtime(time_p: u32, vmctx: &mut Ctx) -> 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 = instance.memory_offset_addr(0, time_p as _) as *mut i64; + let time_p_addr = vmctx.memory(0)[time_p as usize] as *mut i64; let seconds = *time_p_addr.clone(); time::Timespec::new(seconds, 0) }; let result_tm = time::at(timespec); unsafe { - let tm_struct_offset = env::call_malloc(mem::size_of::() as _, instance); - let tm_struct_ptr = instance.memory_offset_addr(0, tm_struct_offset as _) as *mut guest_tm; + let tm_struct_offset = env::call_malloc(mem::size_of::() as _, vmctx); + let tm_struct_ptr = vmctx.memory(0)[tm_struct_offset as usize] as *mut guest_tm; // debug!( // ">>>>>>> time = {}, {}, {}, {}, {}, {}, {}, {}", // result_tm.tm_sec, result_tm.tm_min, result_tm.tm_hour, result_tm.tm_mday, @@ -222,14 +222,14 @@ pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int { } /// emscripten: _localtime_r #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance) -> c_int { +pub extern "C" fn _localtime_r(time_p: u32, result: u32, vmctx: &mut Ctx) -> 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 = instance.memory_offset_addr(0, time_p as _) as *const i32; + let seconds = vmctx.memory(0)[time_p as usize] as *const i32; let timespec = time::Timespec::new(*seconds as _, 0); let result_tm = time::at(timespec); @@ -239,7 +239,7 @@ pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance // result_tm.tm_mon, result_tm.tm_year, result_tm.tm_wday, result_tm.tm_yday, // ); - let result_addr = instance.memory_offset_addr(0, result as _) as *mut guest_tm; + let result_addr = vmctx.memory(0)[result as usize] as *mut guest_tm; (*result_addr).tm_sec = result_tm.tm_sec; (*result_addr).tm_min = result_tm.tm_min; @@ -259,11 +259,11 @@ pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance /// emscripten: _time #[allow(clippy::cast_ptr_alignment)] -pub extern "C" fn _time(time_p: u32, instance: &mut Instance) -> time_t { +pub extern "C" fn _time(time_p: u32, vmctx: &mut Ctx) -> time_t { debug!("emscripten::_time {}", time_p); unsafe { - let time_p_addr = instance.memory_offset_addr(0, time_p as _) as *mut i64; + let time_p_addr = vmctx.memory(0)[time_p as usize] as *mut i64; libc_time(time_p_addr) } } @@ -274,7 +274,7 @@ pub extern "C" fn _strftime( maxsize: u32, format_ptr: c_int, tm_ptr: c_int, - _instance: &mut Instance, + _vmctx: &mut Ctx, ) -> time_t { debug!( "emscripten::_strftime {} {} {} {}", diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs index 110802e0f..23bb9e68e 100644 --- a/lib/emscripten/src/utils.rs +++ b/lib/emscripten/src/utils.rs @@ -1,4 +1,4 @@ -use wasmer_runtime_core::{module::Module, Instance}; +use wasmer_runtime_core::{module::Module, vm::Ctx}; //use wasmer_runtime_core::Instance; use super::env; use libc::stat; @@ -15,8 +15,8 @@ pub fn is_emscripten_module(module: &Module) -> bool { false } -pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: &Instance) -> u32 { - let buf_addr = instance.memory_offset_addr(0, buf as _) as *mut c_char; +pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, vmctx: &mut Ctx) -> u32 { + let buf_addr = vmctx.memory(0)[buf as usize] as *mut c_char; for i in 0..max { *buf_addr.add(i as _) = *string.add(i as _); @@ -26,11 +26,11 @@ pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, instance: } /// This function expects nullbyte to be appended. -pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char) -> u32 { +pub unsafe fn copy_cstr_into_wasm(vmctx: &mut Ctx, 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((cstr_len as i32) + 1, instance); - let raw_memory = instance.memory_offset_addr(0, space_offset as _) as *mut u8; + let space_offset = env::call_malloc((cstr_len as i32) + 1, vmctx); + let raw_memory = vmctx.memory(0)[space_offset as usize] as *mut u8; let slice = slice::from_raw_parts_mut(raw_memory, cstr_len); for (byte, loc) in s.bytes().zip(slice.iter_mut()) { @@ -44,23 +44,20 @@ pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char) space_offset } -pub unsafe fn allocate_on_stack<'a, T: Copy>( - count: u32, - instance: &'a Instance, -) -> (u32, &'a mut [T]) { +pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, vmctx: &'a Ctx) -> (u32, &'a mut [T]) { unimplemented!("allocate_on_stack not implemented") // let offset = (instance.emscripten_data().as_ref().unwrap().stack_alloc)( // count * (size_of::() as u32), - // instance, + // vmctx, // ); - // let addr = instance.memory_offset_addr(0, offset as _) as *mut T; + // let addr = vmctx.memory(0)[offset as usize] as *mut T; // let slice = slice::from_raw_parts_mut(addr, count as usize); // // (offset, slice) } -pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, instance: &'a Instance) -> (u32, &'a [u8]) { - let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, instance); +pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, vmctx: &'a Ctx) -> (u32, &'a [u8]) { + let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, vmctx); use std::iter; for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) { @@ -70,10 +67,7 @@ pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, instance: &'a Instance) -> (u3 (offset, slice) } -pub unsafe fn copy_terminated_array_of_cstrs( - _instance: &mut Instance, - cstrs: *mut *mut c_char, -) -> u32 { +pub unsafe fn copy_terminated_array_of_cstrs(_vmctx: &mut Ctx, cstrs: *mut *mut c_char) -> u32 { let total_num = { let mut ptr = cstrs; let mut counter = 0; @@ -111,8 +105,8 @@ pub struct GuestStat { } #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn copy_stat_into_wasm(instance: &mut Instance, buf: u32, stat: &stat) { - let stat_ptr = instance.memory_offset_addr(0, buf as _) as *mut GuestStat; +pub unsafe fn copy_stat_into_wasm(vmctx: &mut Ctx, buf: u32, stat: &stat) { + let stat_ptr = vmctx.memory(0)[buf as usize] 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 _; @@ -144,14 +138,14 @@ mod tests { use std::sync::Arc; use wabt::wat2wasm; use wasmer_clif_backend::CraneliftCompiler; - use wasmer_runtime_core::{compile, module::Module}; + use wasmer_runtime_core::{compile_with, module::Module}; #[test] fn should_detect_emscripten_files() { const wast_bytes: &[u8] = include_bytes!("tests/is_emscripten_true.wast"); let wasm_binary = wat2wasm(wast_bytes.to_vec()).expect("Can't convert to wasm"); let module = - compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); + compile_with(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); let module = Arc::new(module); assert!(is_emscripten_module(&module)); } @@ -161,7 +155,7 @@ mod tests { const wast_bytes: &[u8] = include_bytes!("tests/is_emscripten_false.wast"); let wasm_binary = wat2wasm(wast_bytes.to_vec()).expect("Can't convert to wasm"); let module = - compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); + compile_with(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); let module = Arc::new(module); assert!(!is_emscripten_module(&module)); } diff --git a/lib/emscripten/src/varargs.rs b/lib/emscripten/src/varargs.rs index 6664ec9a9..dba4f956a 100644 --- a/lib/emscripten/src/varargs.rs +++ b/lib/emscripten/src/varargs.rs @@ -1,5 +1,5 @@ use std::mem; -use wasmer_runtime_core::Instance; +use wasmer_runtime_core::vm::Ctx; #[repr(transparent)] pub struct VarArgs { @@ -7,8 +7,8 @@ pub struct VarArgs { } impl VarArgs { - pub fn get(&mut self, instance: &mut Instance) -> T { - let ptr = instance.memory_offset_addr(0, self.pointer as usize); + pub fn get(&mut self, vmctx: &mut Ctx) -> T { + let ptr = vmctx.memory(0)[self.pointer as usize]; self.pointer += mem::size_of::() as u32; unsafe { (ptr as *const T).read() } } diff --git a/lib/emscripten/tests/emtests/_common.rs b/lib/emscripten/tests/emtests/_common.rs index 93f5128cc..5b54bd580 100644 --- a/lib/emscripten/tests/emtests/_common.rs +++ b/lib/emscripten/tests/emtests/_common.rs @@ -10,7 +10,7 @@ macro_rules! assert_emscripten_output { let wasm_bytes = include_bytes!($file); - let module = wasmer_runtime_core::compile(&wasm_bytes[..], &CraneliftCompiler::new()) + let module = wasmer_runtime_core::compile_with(&wasm_bytes[..], &CraneliftCompiler::new()) .expect("WASM can't be compiled"); // let module = compile(&wasm_bytes[..]) diff --git a/lib/runtime-core/build/spectests.rs b/lib/runtime-core/build/spectests.rs index 6cbd9ade2..867f99454 100644 --- a/lib/runtime-core/build/spectests.rs +++ b/lib/runtime-core/build/spectests.rs @@ -374,7 +374,7 @@ fn test_module_{}() {{ let start_module_call = format!("start_module_{}", self.last_module); self.buffer.push_str( format!( - "\nfn {}(instance: &mut Instance) {{ + "\nfn {}(vmctx: &mut Ctx) {{ // TODO Review is explicit start needed? Start now called in runtime::Instance::new() //instance.start(); }}\n", @@ -437,7 +437,7 @@ fn {}_assert_invalid() {{ let func_name = format!("{}_assert_return_arithmetic_nan", self.command_name()); self.buffer.push_str( format!( - "fn {func_name}(instance: &mut Instance) {{ + "fn {func_name}(vmctx: &mut Ctx) {{ println!(\"Executing function {{}}\", \"{func_name}\"); let result = instance.call(\"{field}\", &[{args_values}]).unwrap().first().expect(\"Missing result in {func_name}\").clone(); {assertion} @@ -496,7 +496,7 @@ fn {}_assert_invalid() {{ let func_name = format!("{}_assert_return_canonical_nan", self.command_name()); self.buffer.push_str( format!( - "fn {func_name}(instance: &mut Instance) {{ + "fn {func_name}(vmctx: &mut Ctx) {{ println!(\"Executing function {{}}\", \"{func_name}\"); let result = instance.call(\"{field}\", &[{args_values}]).unwrap().first().expect(\"Missing result in {func_name}\").clone(); {assertion} @@ -611,7 +611,7 @@ fn {}_assert_malformed() {{ let func_name = format!("{}_action_invoke", self.command_name()); self.buffer.push_str( format!( - "fn {func_name}(instance: &mut Instance) -> Result<()> {{ + "fn {func_name}(vmctx: &mut Ctx) -> Result<()> {{ println!(\"Executing function {{}}\", \"{func_name}\"); let result = instance.call(\"{field}\", &[{args_values}]); {assertion}