Skip to content

Commit af81897

Browse files
bors[bot]Mark McCaskey
and
Mark McCaskey
authored
Merge #820
820: Remove null pointer checks generally, re-add them in Emscripten r=MarkMcCaskey a=MarkMcCaskey Resolves #818 - [x] Add a short description of the the change to the CHANGELOG.md file Co-authored-by: Mark McCaskey <mark@wasmer.io>
2 parents 0790ebf + 882a77c commit af81897

File tree

9 files changed

+136
-30
lines changed

9 files changed

+136
-30
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Blocks of changes will separated by version increments.
66

77
## **[Unreleased]**
88

9+
- [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten
910
- [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex`
1011
- [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model.
1112
- [#788](https://github.com/wasmerio/wasmer/pull/788) Use union merge on the changelog file.

lib/emscripten/src/env/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ pub use self::windows::*;
1212

1313
use libc::c_char;
1414

15-
use crate::{allocate_on_stack, EmscriptenData};
15+
use crate::{
16+
allocate_on_stack,
17+
ptr::{Array, WasmPtr},
18+
EmscriptenData,
19+
};
1620

1721
use std::os::raw::c_int;
18-
use wasmer_runtime_core::{
19-
memory::ptr::{Array, WasmPtr},
20-
types::ValueType,
21-
vm::Ctx,
22-
};
22+
use wasmer_runtime_core::{types::ValueType, vm::Ctx};
2323

2424
pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 {
2525
get_emscripten_data(ctx)

lib/emscripten/src/env/unix/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ use std::mem;
99
use std::os::raw::c_char;
1010

1111
use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr};
12+
use crate::ptr::{Array, WasmPtr};
1213
use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
13-
use wasmer_runtime_core::{
14-
memory::ptr::{Array, WasmPtr},
15-
vm::Ctx,
16-
};
14+
use wasmer_runtime_core::vm::Ctx;
1715

1816
// #[no_mangle]
1917
/// emscripten: _getenv // (name: *const char) -> *const c_char;

lib/emscripten/src/env/windows/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use std::mem;
66
use std::os::raw::c_char;
77

88
use crate::env::{call_malloc, EmAddrInfo};
9+
use crate::ptr::WasmPtr;
910
use crate::utils::{copy_cstr_into_wasm, read_string_from_wasm};
10-
use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
11+
use wasmer_runtime_core::vm::Ctx;
1112

1213
extern "C" {
1314
#[link_name = "_putenv"]

lib/emscripten/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ mod math;
6262
mod memory;
6363
mod process;
6464
mod pthread;
65+
mod ptr;
6566
mod signal;
6667
mod storage;
6768
mod syscalls;

lib/emscripten/src/ptr.rs

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0
2+
//! This is a common assumption in Emscripten code
3+
4+
use std::{cell::Cell, fmt};
5+
pub use wasmer_runtime_core::memory::ptr::Array;
6+
use wasmer_runtime_core::{
7+
memory::{ptr, Memory},
8+
types::{ValueType, WasmExternType},
9+
};
10+
11+
#[repr(transparent)]
12+
pub struct WasmPtr<T: Copy, Ty = ptr::Item>(ptr::WasmPtr<T, Ty>);
13+
14+
unsafe impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {}
15+
impl<T: Copy, Ty> Copy for WasmPtr<T, Ty> {}
16+
17+
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
18+
fn clone(&self) -> Self {
19+
Self(self.0.clone())
20+
}
21+
}
22+
23+
impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
24+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25+
write!(f, "{:?}", self.0)
26+
}
27+
}
28+
29+
unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
30+
type Native = <ptr::WasmPtr<T, Ty> as WasmExternType>::Native;
31+
32+
fn to_native(self) -> Self::Native {
33+
self.0.to_native()
34+
}
35+
fn from_native(n: Self::Native) -> Self {
36+
Self(ptr::WasmPtr::from_native(n))
37+
}
38+
}
39+
40+
impl<T: Copy, Ty> PartialEq for WasmPtr<T, Ty> {
41+
fn eq(&self, other: &Self) -> bool {
42+
self.0 == other.0
43+
}
44+
}
45+
46+
impl<T: Copy, Ty> Eq for WasmPtr<T, Ty> {}
47+
48+
impl<T: Copy, Ty> WasmPtr<T, Ty> {
49+
#[inline(always)]
50+
pub fn new(offset: u32) -> Self {
51+
Self(ptr::WasmPtr::new(offset))
52+
}
53+
54+
#[inline(always)]
55+
pub fn offset(self) -> u32 {
56+
self.0.offset()
57+
}
58+
}
59+
60+
impl<T: Copy + ValueType> WasmPtr<T, ptr::Item> {
61+
#[inline(always)]
62+
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
63+
if self.0.offset() == 0 {
64+
None
65+
} else {
66+
self.0.deref(memory)
67+
}
68+
}
69+
70+
#[inline(always)]
71+
pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell<T>> {
72+
if self.0.offset() == 0 {
73+
None
74+
} else {
75+
self.0.deref_mut(memory)
76+
}
77+
}
78+
}
79+
80+
impl<T: Copy + ValueType> WasmPtr<T, ptr::Array> {
81+
#[inline(always)]
82+
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> {
83+
if self.0.offset() == 0 {
84+
None
85+
} else {
86+
self.0.deref(memory, index, length)
87+
}
88+
}
89+
90+
#[inline]
91+
pub unsafe fn deref_mut<'a>(
92+
self,
93+
memory: &'a Memory,
94+
index: u32,
95+
length: u32,
96+
) -> Option<&'a mut [Cell<T>]> {
97+
if self.0.offset() == 0 {
98+
None
99+
} else {
100+
self.0.deref_mut(memory, index, length)
101+
}
102+
}
103+
104+
#[allow(dead_code)]
105+
#[inline(always)]
106+
pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
107+
if self.0.offset() == 0 {
108+
None
109+
} else {
110+
self.0.get_utf8_string(memory, str_len)
111+
}
112+
}
113+
}

lib/emscripten/src/syscalls/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ pub use self::unix::*;
1010
#[cfg(windows)]
1111
pub use self::windows::*;
1212

13-
use crate::utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory};
13+
use crate::{
14+
ptr::{Array, WasmPtr},
15+
utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory},
16+
};
1417

1518
use super::varargs::VarArgs;
1619
use byteorder::{ByteOrder, LittleEndian};
@@ -40,10 +43,7 @@ use libc::{
4043
write,
4144
// ENOTTY,
4245
};
43-
use wasmer_runtime_core::{
44-
memory::ptr::{Array, WasmPtr},
45-
vm::Ctx,
46-
};
46+
use wasmer_runtime_core::vm::Ctx;
4747

4848
use super::env;
4949
use std::cell::Cell;

lib/emscripten/src/syscalls/unix.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::varargs::VarArgs;
1+
use crate::{ptr::WasmPtr, varargs::VarArgs};
22
#[cfg(target_os = "macos")]
33
use libc::size_t;
44
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
@@ -111,7 +111,7 @@ fn translate_ioctl(wasm_ioctl: u32) -> c_ulong {
111111

112112
#[allow(unused_imports)]
113113
use std::ffi::CStr;
114-
use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
114+
use wasmer_runtime_core::vm::Ctx;
115115

116116
use crate::env::EmSockAddr;
117117
use crate::utils::{self, get_cstr_path};

lib/runtime-core/src/memory/ptr.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ fn align_pointer(ptr: usize, align: usize) -> usize {
4646
impl<T: Copy + ValueType> WasmPtr<T, Item> {
4747
#[inline]
4848
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
49-
if self.offset == 0
50-
|| (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0
51-
{
49+
if (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0 {
5250
return None;
5351
}
5452
unsafe {
@@ -62,9 +60,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Item> {
6260

6361
#[inline]
6462
pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell<T>> {
65-
if self.offset == 0
66-
|| (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0
67-
{
63+
if (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0 {
6864
return None;
6965
}
7066
let cell_ptr = align_pointer(
@@ -83,9 +79,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
8379
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
8480
let slice_full_len = index as usize + length as usize;
8581

86-
if self.offset == 0
87-
|| (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0
88-
{
82+
if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 {
8983
return None;
9084
}
9185

@@ -112,9 +106,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
112106
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
113107
let slice_full_len = index as usize + length as usize;
114108

115-
if self.offset == 0
116-
|| (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0
117-
{
109+
if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 {
118110
return None;
119111
}
120112

0 commit comments

Comments
 (0)