[−][src]Struct wiggle_runtime::GuestPtr
A guest pointer into host memory.
This type represents a pointer from the guest that points into host memory.
Internally a GuestPtr
contains a handle to its original GuestMemory
as
well as the offset into the memory that the pointer is pointing at.
Presence of a GuestPtr
does not imply any form of validity. Pointers can
be out-of-bounds, misaligned, etc. It is safe to construct a GuestPtr
with
any offset at any time. Consider a GuestPtr<T>
roughly equivalent to *mut T
, although there are a few more safety guarantees around this type.
Slices and Strings
Note that the type parameter does not need to implement the Sized
trait,
so you can implement types such as this:
GuestPtr<'_, str>
- a pointer to a guest stringGuestPtr<'_, [T]>
- a pointer to a guest array
Unsized types such as this may have extra methods and won't have methods
like GuestPtr::read
or GuestPtr::write
.
Type parameter and pointee
The T
type parameter is largely intended for more static safety in Rust as
well as having a better handle on what we're pointing to. A GuestPtr<T>
,
however, does not necessarily literally imply a guest pointer pointing to
type T
. Instead the GuestType
trait is a layer of abstraction where
GuestPtr<T>
may actually be a pointer to U
in guest memory, but you can
construct a T
from a U
.
For example GuestPtr<GuestPtr<T>>
is a valid type, but this is actually
more equivalent to GuestPtr<u32>
because guest pointers are always
32-bits. That being said you can create a GuestPtr<T>
from a u32
.
Additionally GuestPtr<MyEnum>
will actually delegate, typically, to and
implementation which loads the underlying data as GuestPtr<u8>
(or
similar) and then the bytes loaded are validated to fit within the
definition of MyEnum
before MyEnum
is returned.
For more information see the GuestPtr::read
and GuestPtr::write
methods. In general though be extremely careful about writing unsafe
code
when working with a GuestPtr
if you're not using one of the
already-attached helper methods.
Methods
impl<'a, T: ?Sized + Pointee> GuestPtr<'a, T>
[src]
pub fn new(mem: &'a (dyn GuestMemory + 'a), pointer: T::Pointer) -> GuestPtr<T>
[src]
Creates a new GuestPtr
from the given mem
and pointer
values.
Note that for sized types like u32
, GuestPtr<T>
, etc, the pointer
vlue is a u32
offset into guest memory. For slices and strings,
pointer
is a (u32, u32)
offset/length pair.
pub fn offset(&self) -> T::Pointer
[src]
Returns the offset of this pointer in guest memory.
Note that for sized types this returns a u32
, but for slices and
strings it returns a (u32, u32)
pointer/length pair.
pub fn mem(&self) -> &'a (dyn GuestMemory + 'a)
[src]
Returns the guest memory that this pointer is coming from.
pub fn cast<U>(&self) -> GuestPtr<'a, U> where
T: Pointee<Pointer = u32>,
[src]
T: Pointee<Pointer = u32>,
Casts this GuestPtr
type to a different type.
This is a safe method which is useful for simply reinterpreting the type
parameter on this GuestPtr
. Note that this is a safe method, where
again there's no guarantees about alignment, validity, in-bounds-ness,
etc of the returned pointer.
pub fn read(&self) -> Result<T, GuestError> where
T: GuestType<'a>,
[src]
T: GuestType<'a>,
Safely read a value from this pointer.
This is a fun method, and is one of the lynchpins of this
implementation. The highlight here is that this is a safe operation,
not an unsafe one like *mut T
. This works for a few reasons:
-
The
unsafe
contract of theGuestMemory
trait means that there's always at least some backing memory for thisGuestPtr<T>
. -
This does not use Rust-intrinsics to read the type
T
, but rather it delegates toT
's implementation ofGuestType
to actually read the underlying data. This again is a safe method, so any unsafety, if any, must be internally documented. -
Eventually what typically happens it that this bottoms out in the read implementations for primitives types (like
i32
) which can safely be read at any time, and then it's up to the runtime to determine what to do with the bytes it read in a safe manner.
Naturally lots of things can still go wrong, such as out-of-bounds
checks, alignment checks, validity checks (e.g. for enums), etc. All of
these check failures, however, are returned as a GuestError
in the
Result
here, and Ok
is only returned if all the checks passed.
pub fn write(&self, val: T) -> Result<(), GuestError> where
T: GuestType<'a>,
[src]
T: GuestType<'a>,
Safely write a value to this pointer.
This method, like GuestPtr::read
, is pretty crucial for the safe
operation of this crate. All the same reasons apply though for why this
method is safe, even eventually bottoming out in primitives like writing
an i32
which is safe to write bit patterns into memory at any time due
to the guarantees of GuestMemory
.
Like read
, write
can fail due to any manner of pointer checks, but
any failure is returned as a GuestError
.
pub fn add(&self, amt: u32) -> Result<GuestPtr<'a, T>, GuestError> where
T: GuestType<'a> + Pointee<Pointer = u32>,
[src]
T: GuestType<'a> + Pointee<Pointer = u32>,
Performs pointer arithmetic on this pointer, moving the pointer forward
amt
slots.
This will either return the resulting pointer or Err
if the pointer
arithmetic calculation would overflow around the end of the address
space.
pub fn as_array(&self, elems: u32) -> GuestPtr<'a, [T]> where
T: GuestType<'a> + Pointee<Pointer = u32>,
[src]
T: GuestType<'a> + Pointee<Pointer = u32>,
Returns a GuestPtr
for an array of T
s using this pointer as the
base.
impl<'a, T> GuestPtr<'a, [T]>
[src]
pub fn offset_base(&self) -> u32
[src]
For slices, specifically returns the relative pointer to the base of the array.
This is similar to <[T]>::as_ptr()
pub fn len(&self) -> u32
[src]
For slices, returns the length of the slice, in units.
pub fn iter<'b>(
&'b self
) -> impl ExactSizeIterator<Item = Result<GuestPtr<'a, T>, GuestError>> + 'b where
T: GuestType<'a>,
[src]
&'b self
) -> impl ExactSizeIterator<Item = Result<GuestPtr<'a, T>, GuestError>> + 'b where
T: GuestType<'a>,
Returns an iterator over interior pointers.
Each item is a Result
indicating whether it overflowed past the end of
the address space or not.
pub fn as_raw(&self, bc: &mut GuestBorrows) -> Result<*mut [T], GuestError> where
T: GuestTypeTransparent<'a>,
[src]
T: GuestTypeTransparent<'a>,
Attempts to read a raw *mut [T]
pointer from this pointer, performing
bounds checks and type validation.
The resulting *mut [T]
can be used as a &mut [t]
as long as the
reference is dropped before any Wasm code is re-entered.
This function will return a raw pointer into host memory if all checks
succeed (valid utf-8, valid pointers, etc). If any checks fail then
GuestError
will be returned.
Note that the *mut [T]
pointer is still unsafe to use in general, but
there are specific situations that it is safe to use. For more
information about using the raw pointer, consult the GuestMemory
trait documentation.
For safety against overlapping mutable borrows, the user must use the
same GuestBorrows
to create all *mut str or *mut [T] that are alive
at the same time.
pub fn copy_from_slice(&self, slice: &[T]) -> Result<(), GuestError> where
T: GuestTypeTransparent<'a> + Copy,
[src]
T: GuestTypeTransparent<'a> + Copy,
Copies the data pointed to by slice
into this guest region.
This method is a safe method to copy data from the host to the guest.
This requires that self
and slice
have the same length. The pointee
type T
requires the GuestTypeTransparent
trait which is an
assertion that the representation on the host and on the guest is the
same.
Errors
Returns an error if this guest pointer is out of bounds or if the length of this guest pointer is not equal to the length of the slice provided.
pub fn as_ptr(&self) -> GuestPtr<'a, T>
[src]
Returns a GuestPtr
pointing to the base of the array for the interior
type T
.
impl<'a> GuestPtr<'a, str>
[src]
pub fn offset_base(&self) -> u32
[src]
For strings, returns the relative pointer to the base of the string allocation.
pub fn len(&self) -> u32
[src]
Returns the length, in bytes, of th estring.
pub fn as_bytes(&self) -> GuestPtr<'a, [u8]>
[src]
Returns a raw pointer for the underlying slice of bytes that this pointer points to.
pub fn as_raw(&self, bc: &mut GuestBorrows) -> Result<*mut str, GuestError>
[src]
Attempts to read a raw *mut str
pointer from this pointer, performing
bounds checks and utf-8 checks.
The resulting *mut str
can be used as a &mut str
as long as the
reference is dropped before any Wasm code is re-entered.
This function will return a raw pointer into host memory if all checks
succeed (valid utf-8, valid pointers, etc). If any checks fail then
GuestError
will be returned.
Note that the *mut str
pointer is still unsafe to use in general, but
there are specific situations that it is safe to use. For more
information about using the raw pointer, consult the GuestMemory
trait documentation.
For safety against overlapping mutable borrows, the user must use the
same GuestBorrows
to create all *mut str or *mut [T] that are alive
at the same time.
Trait Implementations
impl<'_, T: ?Sized + Pointee> Clone for GuestPtr<'_, T>
[src]
fn clone(&self) -> Self
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<'_, T: ?Sized + Pointee> Copy for GuestPtr<'_, T>
[src]
impl<'_, T: ?Sized + Pointee> Debug for GuestPtr<'_, T>
[src]
impl<'a, T> GuestType<'a> for GuestPtr<'a, T>
[src]
fn guest_size() -> u32
[src]
fn guest_align() -> usize
[src]
fn read(ptr: &GuestPtr<'a, Self>) -> Result<Self, GuestError>
[src]
fn write(ptr: &GuestPtr<Self>, val: Self) -> Result<(), GuestError>
[src]
Auto Trait Implementations
impl<'a, T> !RefUnwindSafe for GuestPtr<'a, T>
impl<'a, T> !Send for GuestPtr<'a, T>
impl<'a, T> !Sync for GuestPtr<'a, T>
impl<'a, T: ?Sized> Unpin for GuestPtr<'a, T> where
<T as Pointee>::Pointer: Unpin,
<T as Pointee>::Pointer: Unpin,
impl<'a, T> !UnwindSafe for GuestPtr<'a, T>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> Pointee for T
[src]
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,