#[repr(transparent)]
pub struct VMExternRef(/* private fields */);
Expand description

An external reference to some opaque data.

VMExternRefs dereference to their underlying opaque data as dyn Any.

Unlike the externref in the Wasm spec, VMExternRefs are non-nullable, and always point to a valid value. You may use Option<VMExternRef> to represent nullable references, and Option<VMExternRef> is guaranteed to have the same size and alignment as a raw pointer, with None represented with the null pointer.

VMExternRefs are reference counted, so cloning is a cheap, shallow operation. It also means they are inherently shared, so you may not get a mutable, exclusive reference to their inner contents, only a shared, immutable reference. You may use interior mutability with RefCell or Mutex to work around this restriction, if necessary.

VMExternRefs have pointer-equality semantics, not structural-equality semantics. Given two VMExternRefs a and b, a == b only if a and b point to the same allocation. a and b are considered not equal, even if a and b are two different identical copies of the same data, if they are in two different allocations. The hashing and ordering implementations also only operate on the pointer.

Example

use std::cell::RefCell;
use wasmtime_runtime::VMExternRef;

// Open a file. Wasm doesn't know about files, but we can let Wasm instances
// work with files via opaque `externref` handles.
let file = std::fs::File::create("some/file/path")?;

// Wrap the file up as an `VMExternRef` that can be passed to Wasm.
let extern_ref_to_file = VMExternRef::new(file);

// `VMExternRef`s dereference to `dyn Any`, so you can use `Any` methods to
// perform runtime type checks and downcasts.

assert!(extern_ref_to_file.is::<std::fs::File>());
assert!(!extern_ref_to_file.is::<String>());

if let Some(mut file) = extern_ref_to_file.downcast_ref::<std::fs::File>() {
    use std::io::Write;
    writeln!(&mut file, "Hello, `VMExternRef`!")?;
}

Implementations§

source§

impl VMExternRef

source

pub fn new<T>(value: T) -> VMExternRefwhere T: 'static + Any + Send + Sync,

Wrap the given value inside an VMExternRef.

source

pub fn new_with<T>(make_value: impl FnOnce() -> T) -> VMExternRefwhere T: 'static + Any + Send + Sync,

Construct a new VMExternRef in place by invoking make_value.

source

pub fn as_raw(&self) -> *mut u8

Turn this VMExternRef into a raw, untyped pointer.

Unlike into_raw, this does not consume and forget self. It is not safe to use from_raw on pointers returned from this method; only use clone_from_raw!

Nor does this method increment the reference count. You must ensure that self (or some other clone of self) stays alive until clone_from_raw is called.

source

pub unsafe fn into_raw(self) -> *mut u8

Consume this VMExternRef into a raw, untyped pointer.

Safety

This method forgets self, so it is possible to create a leak of the underlying reference counted data if not used carefully.

Use from_raw to recreate the VMExternRef.

source

pub unsafe fn from_raw(ptr: *mut u8) -> Self

Recreate a VMExternRef from a pointer returned from a previous call to as_raw.

Safety

Unlike clone_from_raw, this does not increment the reference count of the underlying data. It is not safe to continue to use the pointer passed to this function.

source

pub unsafe fn clone_from_raw(ptr: *mut u8) -> Self

Recreate a VMExternRef from a pointer returned from a previous call to as_raw.

Safety

Wildly unsafe to use with anything other than the result of a previous as_raw call!

Additionally, it is your responsibility to ensure that this raw VMExternRef’s reference count has not dropped to zero. Failure to do so will result in use after free!

source

pub fn strong_count(&self) -> usize

Get the strong reference count for this VMExternRef.

Note that this loads with a SeqCst ordering to synchronize with other threads.

source§

impl VMExternRef

Methods that would normally be trait implementations, but aren’t to avoid potential footguns around VMExternRef’s pointer-equality semantics.

Note that none of these methods are on &self, they all require a fully-qualified VMExternRef::foo(my_ref) invocation.

source

pub fn eq(a: &Self, b: &Self) -> bool

Check whether two VMExternRefs point to the same inner allocation.

Note that this uses pointer-equality semantics, not structural-equality semantics, and so only pointers are compared, and doesn’t use any Eq or PartialEq implementation of the pointed-to values.

source

pub fn hash<H>(externref: &Self, hasher: &mut H)where H: Hasher,

Hash a given VMExternRef.

Note that this just hashes the pointer to the inner value, it does not use the inner value’s Hash implementation (if any).

source

pub fn cmp(a: &Self, b: &Self) -> Ordering

Compare two VMExternRefs.

Note that this uses pointer-equality semantics, not structural-equality semantics, and so only pointers are compared, and doesn’t use any Cmp or PartialCmp implementation of the pointed-to values.

Trait Implementations§

source§

impl Clone for VMExternRef

source§

fn clone(&self) -> VMExternRef

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for VMExternRef

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for VMExternRef

§

type Target = dyn Any

The resulting type after dereferencing.
source§

fn deref(&self) -> &dyn Any

Dereferences the value.
source§

impl Drop for VMExternRef

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl From<VMExternRef> for TableElement

source§

fn from(x: VMExternRef) -> TableElement

Converts to this type from the input type.
source§

impl Pointer for VMExternRef

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.