use std::marker::PhantomData; use unique_type_id::UniqueTypeId; use wasmer::FromToNativeWasmType; use crate::script_implementations::wasm::script_resolver::{WebAssemblyEnv, WebAssemblyScriptResolver}; pub(crate) struct ExternRef> { index: u32, _phantom: PhantomData, } impl> ExternRef { pub fn new(env: &WebAssemblyEnv, value: &T) -> Self { Self { index: env.resolver().get_extern_ref_index(value), _phantom: Default::default(), } } /// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable. pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self { Self { index: resolver.environment_data().get_extern_ref_index(value), _phantom: Default::default(), } } /// An empty value ExternRef. pub fn null() -> Self { Self { index: 0, _phantom: Default::default(), } } /// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the /// value when it was passed before. If these types do not match, this will panic. pub fn value<'a, 'b>(&'a self, env: &'b WebAssemblyEnv) -> Option<&'b T> { let ptr = env.resolver().get_extern_ref_value(self.index) as *const T; unsafe { ptr.as_ref() } } } unsafe impl> FromToNativeWasmType for ExternRef { type Native = i32; fn from_native(native: Self::Native) -> Self { Self { index: native as u32, _phantom: Default::default(), } } fn to_native(self) -> Self::Native { self.index as i32 } }