wasmtime/runtime/externals/
tag.rs

1use crate::runtime::types::TagType;
2use crate::{
3    AsContext,
4    store::{StoreInstanceId, StoreOpaque},
5};
6use wasmtime_environ::{DefinedTagIndex, VMSharedTypeIndex};
7
8/// A WebAssembly `tag`.
9#[derive(Copy, Clone, Debug)]
10#[repr(C)] // here for the C API in the future
11pub struct Tag {
12    instance: StoreInstanceId,
13    index: DefinedTagIndex,
14}
15
16impl Tag {
17    pub(crate) unsafe fn from_wasmtime_tag(
18        wasmtime_export: crate::runtime::vm::ExportTag,
19        store: &StoreOpaque,
20    ) -> Self {
21        debug_assert!(
22            wasmtime_export.tag.signature.unwrap_engine_type_index()
23                != VMSharedTypeIndex::default()
24        );
25        Tag {
26            instance: store.vmctx_id(wasmtime_export.vmctx),
27            index: wasmtime_export.index,
28        }
29    }
30
31    /// Returns the underlying type of this `tag`.
32    ///
33    /// # Panics
34    ///
35    /// Panics if `store` does not own this tag.
36    pub fn ty(&self, store: impl AsContext) -> TagType {
37        self._ty(store.as_context().0)
38    }
39
40    pub(crate) fn _ty(&self, store: &StoreOpaque) -> TagType {
41        TagType::from_wasmtime_tag(store.engine(), self.wasmtime_ty(store))
42    }
43
44    pub(crate) fn wasmtime_ty<'a>(&self, store: &'a StoreOpaque) -> &'a wasmtime_environ::Tag {
45        let module = store[self.instance].env_module();
46        let index = module.tag_index(self.index);
47        &module.tags[index]
48    }
49
50    pub(crate) fn vmimport(&self, store: &StoreOpaque) -> crate::runtime::vm::VMTagImport {
51        let instance = &store[self.instance];
52        crate::runtime::vm::VMTagImport {
53            from: instance.tag_ptr(self.index).into(),
54            vmctx: instance.vmctx().into(),
55            index: self.index,
56        }
57    }
58
59    pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
60        store.id() == self.instance.store_id()
61    }
62
63    /// Determines whether this tag is reference equal to the other
64    /// given tag in the given store.
65    ///
66    /// # Panics
67    ///
68    /// Panics if either tag do not belong to the given `store`.
69    pub fn eq(a: &Tag, b: &Tag, store: impl AsContext) -> bool {
70        // make sure both tags belong to the store
71        let store = store.as_context();
72        let _ = &store[a.instance];
73        let _ = &store[b.instance];
74
75        // then compare to see if they have the same definition
76        a.instance == b.instance && a.index == b.index
77    }
78}