Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MemoryView lifetime tied to memory and not StoreRef #3097

Merged
merged 3 commits into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/api/src/sys/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::slice;
#[cfg(feature = "tracing")]
use tracing::warn;
use wasmer_types::Pages;
use wasmer_vm::{InternalStoreHandle, MemoryError, StoreHandle, StoreObjects, VMExtern, VMMemory};
use wasmer_vm::{InternalStoreHandle, MemoryError, StoreHandle, VMExtern, VMMemory};

use super::MemoryView;

Expand Down Expand Up @@ -79,7 +79,7 @@ impl Memory {

/// Creates a view into the memory that then allows for
/// read and write
pub fn view<'a>(&self, store: &'a impl AsStoreRef) -> MemoryView<'a> {
pub fn view<'a>(&'a self, store: &impl AsStoreRef) -> MemoryView<'a> {
MemoryView::new(self, store)
}

Expand Down Expand Up @@ -169,7 +169,7 @@ impl<'a> Exportable<'a> for Memory {
pub(crate) struct MemoryBuffer<'a> {
pub(crate) base: *mut u8,
pub(crate) len: usize,
pub(crate) marker: PhantomData<(&'a MemoryView<'a>, &'a StoreObjects)>,
pub(crate) marker: PhantomData<&'a MemoryView<'a>>,
}

impl<'a> MemoryBuffer<'a> {
Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/sys/externals/memory_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub struct MemoryView<'a> {
}

impl<'a> MemoryView<'a> {
pub(crate) fn new(memory: &Memory, store: &'a impl AsStoreRef) -> Self {
pub(crate) fn new(memory: &'a Memory, store: &impl AsStoreRef) -> Self {
let size = memory.handle.get(store.as_store_ref().objects()).size();

let definition = memory.handle.get(store.as_store_ref().objects()).vmmemory();
Expand Down
14 changes: 6 additions & 8 deletions lib/emscripten/src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,15 @@ pub fn ___build_environment(mut ctx: FunctionEnvMut<EmEnv>, environ: c_int) {
debug!("emscripten::___build_environment {}", environ);
const MAX_ENV_VALUES: u32 = 64;
const TOTAL_ENV_SIZE: u32 = 1024;
let environment =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), environ) as *mut c_int;
let memory = ctx.data().memory(0);
let environment = emscripten_memory_pointer!(memory.view(&ctx), environ) as *mut c_int;
let (mut pool_offset, env_ptr, mut pool_ptr) = unsafe {
let (pool_offset, _pool_slice): (u32, &mut [u8]) =
allocate_on_stack(&mut ctx, TOTAL_ENV_SIZE as u32);
let (env_offset, _env_slice): (u32, &mut [u8]) =
allocate_on_stack(&mut ctx, (MAX_ENV_VALUES * 4) as u32);
let env_ptr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), env_offset) as *mut c_int;
let pool_ptr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), pool_offset) as *mut u8;
let env_ptr = emscripten_memory_pointer!(memory.view(&ctx), env_offset) as *mut c_int;
let pool_ptr = emscripten_memory_pointer!(memory.view(&ctx), pool_offset) as *mut u8;
*env_ptr = pool_offset as i32;
*environment = env_offset as i32;

Expand Down Expand Up @@ -137,8 +135,8 @@ pub fn _pathconf(ctx: FunctionEnvMut<EmEnv>, path_addr: c_int, name: c_int) -> c
"emscripten::_pathconf {} {} - UNIMPLEMENTED",
path_addr, name
);
let _path =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), path_addr) as *const c_char;
let memory = ctx.data().memory(0);
let _path = emscripten_memory_pointer!(memory.view(&ctx), path_addr) as *const c_char;
match name {
0 => 32000,
1 | 2 | 3 => 255,
Expand Down
54 changes: 29 additions & 25 deletions lib/emscripten/src/env/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use wasmer::{FunctionEnvMut, WasmPtr};
pub fn _getenv(mut ctx: FunctionEnvMut<EmEnv>, name: i32) -> u32 {
debug!("emscripten::_getenv");

let name_addr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), name) as *const c_char;
let memory = ctx.data().memory(0);
let name_addr = emscripten_memory_pointer!(memory.view(&ctx), name) as *const c_char;

debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });

Expand All @@ -34,10 +34,9 @@ pub fn _getenv(mut ctx: FunctionEnvMut<EmEnv>, name: i32) -> u32 {
pub fn _setenv(ctx: FunctionEnvMut<EmEnv>, name: c_int, value: c_int, overwrite: c_int) -> c_int {
debug!("emscripten::_setenv");

let name_addr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), name) as *const c_char;
let value_addr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), value) as *const c_char;
let memory = ctx.data().memory(0);
let name_addr = emscripten_memory_pointer!(memory.view(&ctx), name) as *const c_char;
let value_addr = emscripten_memory_pointer!(memory.view(&ctx), value) as *const c_char;

debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) });
Expand All @@ -49,8 +48,8 @@ pub fn _setenv(ctx: FunctionEnvMut<EmEnv>, name: c_int, value: c_int, overwrite:
pub fn _putenv(ctx: FunctionEnvMut<EmEnv>, name: c_int) -> c_int {
debug!("emscripten::_putenv");

let name_addr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), name) as *const c_char;
let memory = ctx.data().memory(0);
let name_addr = emscripten_memory_pointer!(memory.view(&ctx), name) as *const c_char;

debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });

Expand All @@ -61,8 +60,8 @@ pub fn _putenv(ctx: FunctionEnvMut<EmEnv>, name: c_int) -> c_int {
pub fn _unsetenv(ctx: FunctionEnvMut<EmEnv>, name: c_int) -> c_int {
debug!("emscripten::_unsetenv");

let name_addr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), name) as *const c_char;
let memory = ctx.data().memory(0);
let name_addr = emscripten_memory_pointer!(memory.view(&ctx), name) as *const c_char;

debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });

Expand All @@ -86,8 +85,9 @@ pub fn _getpwnam(mut ctx: FunctionEnvMut<EmEnv>, name_ptr: c_int) -> c_int {
pw_shell: u32,
}

let memory = ctx.data().memory(0);
let name = unsafe {
let memory = ctx.data().memory_view(0, &ctx);
let memory = memory.view(&ctx);
let memory_name_ptr = emscripten_memory_pointer!(&memory, name_ptr) as *const c_char;
CStr::from_ptr(memory_name_ptr)
};
Expand All @@ -96,7 +96,7 @@ pub fn _getpwnam(mut ctx: FunctionEnvMut<EmEnv>, name_ptr: c_int) -> c_int {
let passwd = &*libc_getpwnam(name.as_ptr());
let passwd_struct_offset = call_malloc(&mut ctx, mem::size_of::<GuestPasswd>() as _);

let memory = ctx.data().memory_view(0, &ctx);
let memory = memory.view(&ctx);
let passwd_struct_ptr =
emscripten_memory_pointer!(&memory, passwd_struct_offset) as *mut GuestPasswd;
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(&mut ctx, passwd.pw_name);
Expand All @@ -123,9 +123,10 @@ pub fn _getgrnam(mut ctx: FunctionEnvMut<EmEnv>, name_ptr: c_int) -> c_int {
gr_mem: u32,
}

let memory = ctx.data().memory(0);
let name = unsafe {
let memory_name_ptr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), name_ptr) as *const c_char;
emscripten_memory_pointer!(memory.view(&ctx), name_ptr) as *const c_char;
CStr::from_ptr(memory_name_ptr)
};

Expand All @@ -134,8 +135,7 @@ pub fn _getgrnam(mut ctx: FunctionEnvMut<EmEnv>, name_ptr: c_int) -> c_int {
let group_struct_offset = call_malloc(&mut ctx, mem::size_of::<GuestGroup>() as _);

let group_struct_ptr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), group_struct_offset)
as *mut GuestGroup;
emscripten_memory_pointer!(memory.view(&ctx), group_struct_offset) as *mut GuestGroup;
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(&mut ctx, group.gr_name);
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(&mut ctx, group.gr_passwd);
(*group_struct_ptr).gr_gid = group.gr_gid;
Expand All @@ -158,7 +158,8 @@ pub fn _gai_strerror(mut ctx: FunctionEnvMut<EmEnv>, ecode: i32) -> i32 {
let cstr = unsafe { std::ffi::CStr::from_ptr(libc::gai_strerror(ecode)) };
let bytes = cstr.to_bytes_with_nul();
let string_on_guest: WasmPtr<c_char> = call_malloc_with_cast(&mut ctx, bytes.len() as _);
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let memory = memory.view(&ctx);

let writer = string_on_guest.slice(&memory, bytes.len() as _).unwrap();
for (i, byte) in bytes.iter().enumerate() {
Expand Down Expand Up @@ -195,10 +196,8 @@ pub fn _getaddrinfo(
let hints = if hints_ptr.is_null() {
None
} else {
let hints_guest = hints_ptr
.deref(&ctx.data().memory_view(0, &ctx))
.read()
.unwrap();
let memory = ctx.data().memory(0);
let hints_guest = hints_ptr.deref(&memory.view(&ctx)).read().unwrap();
Some(addrinfo {
ai_flags: hints_guest.ai_flags,
ai_family: hints_guest.ai_family,
Expand Down Expand Up @@ -252,7 +251,8 @@ pub fn _getaddrinfo(

// connect list
if let Some(prev_guest) = previous_guest_node {
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let memory = memory.view(&ctx);
let derefed_prev_guest = prev_guest.deref(&memory);
let mut pg = derefed_prev_guest.read().unwrap();
pg.ai_next = current_guest_node_ptr;
Expand All @@ -268,7 +268,8 @@ pub fn _getaddrinfo(
let guest_sockaddr_ptr: WasmPtr<EmSockAddr> =
call_malloc_with_cast(&mut ctx, host_addrlen as _);

let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let memory = memory.view(&ctx);
let derefed_guest_sockaddr = guest_sockaddr_ptr.deref(&memory);
let mut gs = derefed_guest_sockaddr.read().unwrap();
gs.sa_family = (*host_sockaddr_ptr).sa_family as i16;
Expand All @@ -288,7 +289,8 @@ pub fn _getaddrinfo(
let guest_canonname: WasmPtr<c_char> =
call_malloc_with_cast(&mut ctx, str_size as _);

let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let memory = memory.view(&ctx);
let guest_canonname_writer =
guest_canonname.slice(&memory, str_size as _).unwrap();
for (i, b) in canonname_bytes.iter().enumerate() {
Expand All @@ -304,7 +306,8 @@ pub fn _getaddrinfo(
}
};

let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let memory = memory.view(&ctx);
let derefed_current_guest_node = current_guest_node_ptr.deref(&memory);
let mut cgn = derefed_current_guest_node.read().unwrap();
cgn.ai_flags = (*current_host_node).ai_flags;
Expand All @@ -325,8 +328,9 @@ pub fn _getaddrinfo(
head_of_list.unwrap_or_else(|| WasmPtr::new(0))
};

let memory = ctx.data().memory(0);
res_val_ptr
.deref(&ctx.data().memory_view(0, &ctx))
.deref(&memory.view(&ctx))
.write(head_of_list)
.unwrap();

Expand Down
32 changes: 19 additions & 13 deletions lib/emscripten/src/env/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ extern "C" {
/// emscripten: _getenv // (name: *const char) -> *const c_char;
pub fn _getenv(mut ctx: FunctionEnvMut<EmEnv>, name: u32) -> u32 {
debug!("emscripten::_getenv");
let memory = ctx.data().memory_view(0, &ctx);
let name_string = read_string_from_wasm(&memory, name);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
let name_string = read_string_from_wasm(&view, name);
debug!("=> name({:?})", name_string);
let c_str = unsafe { getenv(name_string.as_ptr() as *const libc::c_char) };
if c_str.is_null() {
Expand All @@ -32,10 +33,11 @@ pub fn _getenv(mut ctx: FunctionEnvMut<EmEnv>, name: u32) -> u32 {
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int);
pub fn _setenv(ctx: FunctionEnvMut<EmEnv>, name: u32, value: u32, _overwrite: u32) -> c_int {
debug!("emscripten::_setenv");
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
// setenv does not exist on windows, so we hack it with _putenv
let name = read_string_from_wasm(&memory, name);
let value = read_string_from_wasm(&memory, value);
let name = read_string_from_wasm(&view, name);
let value = read_string_from_wasm(&view, value);
let putenv_string = format!("{}={}", name, value);
let putenv_cstring = CString::new(putenv_string).unwrap();
let putenv_raw_ptr = putenv_cstring.as_ptr();
Expand All @@ -47,8 +49,9 @@ pub fn _setenv(ctx: FunctionEnvMut<EmEnv>, name: u32, value: u32, _overwrite: u3
/// emscripten: _putenv // (name: *const char);
pub fn _putenv(ctx: FunctionEnvMut<EmEnv>, name: c_int) -> c_int {
debug!("emscripten::_putenv");
let memory = ctx.data().memory_view(0, &ctx);
let name_addr = emscripten_memory_pointer!(&memory, name) as *const c_char;
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
let name_addr = emscripten_memory_pointer!(&view, name) as *const c_char;
debug!("=> name({:?})", unsafe {
std::ffi::CStr::from_ptr(name_addr)
});
Expand All @@ -58,8 +61,9 @@ pub fn _putenv(ctx: FunctionEnvMut<EmEnv>, name: c_int) -> c_int {
/// emscripten: _unsetenv // (name: *const char);
pub fn _unsetenv(ctx: FunctionEnvMut<EmEnv>, name: u32) -> c_int {
debug!("emscripten::_unsetenv");
let memory = ctx.data().memory_view(0, &ctx);
let name = read_string_from_wasm(&memory, name);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
let name = read_string_from_wasm(&view, name);
// no unsetenv on windows, so use putenv with an empty value
let unsetenv_string = format!("{}=", name);
let unsetenv_cstring = CString::new(unsetenv_string).unwrap();
Expand Down Expand Up @@ -88,9 +92,10 @@ pub fn _getpwnam(mut ctx: FunctionEnvMut<EmEnv>, name_ptr: c_int) -> c_int {
// stub this in windows as it is not valid
unsafe {
let passwd_struct_offset = call_malloc(&mut ctx, mem::size_of::<GuestPasswd>() as _);
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
let passwd_struct_ptr =
emscripten_memory_pointer!(&memory, passwd_struct_offset) as *mut GuestPasswd;
emscripten_memory_pointer!(&view, passwd_struct_offset) as *mut GuestPasswd;
(*passwd_struct_ptr).pw_name = 0;
(*passwd_struct_ptr).pw_passwd = 0;
(*passwd_struct_ptr).pw_gecos = 0;
Expand Down Expand Up @@ -120,9 +125,10 @@ pub fn _getgrnam(mut ctx: FunctionEnvMut<EmEnv>, name_ptr: c_int) -> c_int {
// stub the group struct as it is not supported on windows
unsafe {
let group_struct_offset = call_malloc(&mut ctx, mem::size_of::<GuestGroup>() as _);
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
let group_struct_ptr =
emscripten_memory_pointer!(&memory, group_struct_offset) as *mut GuestGroup;
emscripten_memory_pointer!(&view, group_struct_offset) as *mut GuestGroup;
(*group_struct_ptr).gr_name = 0;
(*group_struct_ptr).gr_passwd = 0;
(*group_struct_ptr).gr_gid = 0;
Expand Down
3 changes: 2 additions & 1 deletion lib/emscripten/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use wasmer::{FunctionEnvMut, WasmPtr};

pub fn execvp(ctx: FunctionEnvMut<EmEnv>, command_name_offset: u32, argv_offset: u32) -> i32 {
// a single reference to re-use
let emscripten_memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let emscripten_memory = memory.view(&ctx);

// read command name as string
let command_name_string_vec = WasmPtr::<u8>::new(command_name_offset)
Expand Down
10 changes: 6 additions & 4 deletions lib/emscripten/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ pub fn getprotobynumber(_ctx: FunctionEnvMut<EmEnv>, _one: i32) -> i32 {
/// sigdelset
pub fn sigdelset(ctx: FunctionEnvMut<EmEnv>, set: i32, signum: i32) -> i32 {
debug!("emscripten::sigdelset");
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
#[allow(clippy::cast_ptr_alignment)]
let ptr = emscripten_memory_pointer!(&memory, set) as *mut i32;
let ptr = emscripten_memory_pointer!(&view, set) as *mut i32;

unsafe { *ptr &= !(1 << (signum - 1)) }

Expand All @@ -40,9 +41,10 @@ pub fn sigdelset(ctx: FunctionEnvMut<EmEnv>, set: i32, signum: i32) -> i32 {
/// sigfillset
pub fn sigfillset(ctx: FunctionEnvMut<EmEnv>, set: i32) -> i32 {
debug!("emscripten::sigfillset");
let memory = ctx.data().memory_view(0, &ctx);
let memory = ctx.data().memory(0);
let view = memory.view(&ctx);
#[allow(clippy::cast_ptr_alignment)]
let ptr = emscripten_memory_pointer!(&memory, set) as *mut i32;
let ptr = emscripten_memory_pointer!(&view, set) as *mut i32;

unsafe {
*ptr = -1;
Expand Down
6 changes: 3 additions & 3 deletions lib/emscripten/src/io/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ pub fn putchar(_ctx: FunctionEnvMut<EmEnv>, chr: i32) {
pub fn printf(ctx: FunctionEnvMut<EmEnv>, memory_offset: i32, extra: i32) -> i32 {
debug!("emscripten::printf {}, {}", memory_offset, extra);
unsafe {
let addr = emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), memory_offset) as _;
let addr = emscripten_memory_pointer!(ctx.data().memory(0).view(&ctx), memory_offset) as _;
_printf(addr, extra)
}
}

/// chroot
pub fn chroot(ctx: FunctionEnvMut<EmEnv>, name_ptr: i32) -> i32 {
debug!("emscripten::chroot");
let name = emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), name_ptr) as *const i8;
let name = emscripten_memory_pointer!(ctx.data().memory(0).view(&ctx), name_ptr) as *const i8;
unsafe { _chroot(name as *const _) }
}

Expand All @@ -47,7 +47,7 @@ pub fn getpwuid(mut ctx: FunctionEnvMut<EmEnv>, uid: i32) -> i32 {
let passwd = &*_getpwuid(uid as _);
let passwd_struct_offset = call_malloc(&mut ctx, mem::size_of::<GuestPasswd>() as _);
let passwd_struct_ptr =
emscripten_memory_pointer!(ctx.data().memory_view(0, &ctx), passwd_struct_offset)
emscripten_memory_pointer!(ctx.data().memory(0).view(&ctx), passwd_struct_offset)
as *mut GuestPasswd;
assert_eq!(
passwd_struct_ptr as usize % std::mem::align_of::<GuestPasswd>(),
Expand Down
11 changes: 3 additions & 8 deletions lib/emscripten/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use std::f64;
use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock};
use wasmer::{
imports, namespace, AsStoreMut, AsStoreRef, ExportError, Exports, Function, FunctionEnv,
FunctionEnvMut, FunctionType, Global, Imports, Instance, Memory, MemoryType, MemoryView,
Module, Pages, RuntimeError, Table, TableType, TypedFunction, Value, WasmPtr,
imports, namespace, AsStoreMut, ExportError, Exports, Function, FunctionEnv, FunctionEnvMut,
FunctionType, Global, Imports, Instance, Memory, MemoryType, Module, Pages, RuntimeError,
Table, TableType, TypedFunction, Value, WasmPtr,
};
use wasmer_types::Type as ValType;

Expand Down Expand Up @@ -108,11 +108,6 @@ impl EmEnv {
(&*self.memory.read().unwrap()).as_ref().cloned().unwrap()
}

/// Get a reference to the memory view
pub fn memory_view<'a>(&self, mem_idx: u32, store: &'a impl AsStoreRef) -> MemoryView<'a> {
self.memory(mem_idx).view(store)
}

pub fn set_functions(&mut self, funcs: EmscriptenFunctions) {
self.funcs = Arc::new(Mutex::new(funcs));
}
Expand Down
Loading