Skip to content

Commit c341e3a

Browse files
authored
Merge pull request #720 from wasmx/rust-constnull
rust: add simple CostNonNull wrapper based on std::ptr::NonNull
2 parents 7b700be + 7694ed6 commit c341e3a

2 files changed

Lines changed: 40 additions & 10 deletions

File tree

bindings/rust/src/constnonnull.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Fizzy: A fast WebAssembly interpreter
2+
// Copyright 2021 The Fizzy Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
/// A minimalistic version of std::ptr::NonNull for *const T.
6+
pub(crate) struct ConstNonNull<T: ?Sized> {
7+
pointer: *const T,
8+
}
9+
10+
impl<T: ?Sized> ConstNonNull<T> {
11+
#[inline]
12+
pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
13+
// SAFETY: the caller must guarantee that `ptr` is non-null.
14+
unsafe { ConstNonNull { pointer: ptr } }
15+
}
16+
17+
#[must_use]
18+
#[inline]
19+
pub const fn as_ptr(self) -> *const T {
20+
self.pointer
21+
}
22+
}
23+
24+
impl<T: ?Sized> Clone for ConstNonNull<T> {
25+
#[inline]
26+
fn clone(&self) -> Self {
27+
*self
28+
}
29+
}
30+
31+
impl<T: ?Sized> Copy for ConstNonNull<T> {}

bindings/rust/src/lib.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@
3535
//! }
3636
//! ```
3737
38+
mod constnonnull;
3839
mod sys;
3940

4041
use std::ffi::{CStr, CString};
4142
use std::ptr::NonNull;
4243

44+
use crate::constnonnull::ConstNonNull;
45+
4346
/// A safe container for handling the low-level FizzyError struct.
4447
struct FizzyErrorBox(Box<sys::FizzyError>);
4548

@@ -102,23 +105,20 @@ pub fn validate<T: AsRef<[u8]>>(input: T) -> Result<(), String> {
102105
}
103106

104107
/// A parsed and validated WebAssembly 1.0 module.
105-
// NOTE: cannot use NonNull here given this is *const
106-
pub struct Module(*const sys::FizzyModule);
108+
pub struct Module(ConstNonNull<sys::FizzyModule>);
107109

108110
impl Drop for Module {
109111
fn drop(&mut self) {
110-
debug_assert!(!self.0.is_null());
111-
unsafe { sys::fizzy_free_module(self.0) }
112+
unsafe { sys::fizzy_free_module(self.0.as_ptr()) }
112113
}
113114
}
114115

115116
impl Clone for Module {
116117
fn clone(&self) -> Self {
117-
debug_assert!(!self.0.is_null());
118-
let ptr = unsafe { sys::fizzy_clone_module(self.0) };
118+
let ptr = unsafe { sys::fizzy_clone_module(self.0.as_ptr()) };
119119
// TODO: this can be zero in case of memory allocation error, should this be gracefully handled?
120120
assert!(!ptr.is_null());
121-
Module(ptr)
121+
Module(unsafe { ConstNonNull::new_unchecked(ptr) })
122122
}
123123
}
124124

@@ -137,7 +137,7 @@ pub fn parse<T: AsRef<[u8]>>(input: &T) -> Result<Module, String> {
137137
Err(err.message())
138138
} else {
139139
debug_assert!(err.code() == 0);
140-
Ok(Module(ptr))
140+
Ok(Module(unsafe { ConstNonNull::new_unchecked(ptr) }))
141141
}
142142
}
143143

@@ -154,11 +154,10 @@ impl Module {
154154
/// Create an instance of a module.
155155
// TODO: support imported functions
156156
pub fn instantiate(self) -> Result<Instance, String> {
157-
debug_assert!(!self.0.is_null());
158157
let mut err = FizzyErrorBox::new();
159158
let ptr = unsafe {
160159
sys::fizzy_instantiate(
161-
self.0,
160+
self.0.as_ptr(),
162161
std::ptr::null(),
163162
0,
164163
std::ptr::null(),

0 commit comments

Comments
 (0)