wasmtime_environ/component/
intrinsic.rs1use crate::prelude::*;
4use core::str::FromStr;
5use serde_derive::{Deserialize, Serialize};
6
7#[macro_export]
9macro_rules! for_each_unsafe_intrinsic {
10 ($mac:ident) => {
11 $mac! {
12 "store-data-address" => StoreDataAddress : store_data_address() -> u64;
13
14 "u8-native-load" => U8NativeLoad : u8_native_load(address: u64) -> u8;
15 "u8-native-store" => U8NativeStore : u8_native_store(address: u64, value: u8);
16
17 "u16-native-load" => U16NativeLoad : u16_native_load(address: u64) -> u16;
18 "u16-native-store" => U16NativeStore : u16_native_store(address: u64, value: u16);
19
20 "u32-native-load" => U32NativeLoad : u32_native_load(address: u64) -> u32;
21 "u32-native-store" => U32NativeStore : u32_native_store(address: u64, value: u32);
22
23 "u64-native-load" => U64NativeLoad : u64_native_load(address: u64) -> u64;
24 "u64-native-store" => U64NativeStore : u64_native_store(address: u64, value: u64);
25 }
26 };
27}
28
29macro_rules! define_unsafe_intrinsics {
30 (
31 $(
32 $symbol:expr => $variant:ident : $ctor:ident ( $( $param:ident : $param_ty:ident ),* ) $( -> $result_ty:ident )? ;
33 )*
34 ) => {
35 #[repr(u32)]
38 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
39 pub enum UnsafeIntrinsic {
40 $(
41 #[doc = concat!("The `", $symbol, "` intrinsic.")]
42 $variant,
43 )*
44 }
45
46 impl UnsafeIntrinsic {
47 pub const fn len() -> u32 {
49 let mut len = 0;
50 $(
51 let _ = Self::$variant;
52 len += 1;
53 )*
54 len
55 }
56
57 pub const fn from_u32(i: u32) -> Self {
61 assert!(i < Self::len());
62 $(
63 if i == Self::$variant.index() {
64 return Self::$variant;
65 }
66 )*
67 unreachable!()
68 }
69
70 pub const fn index(&self) -> u32 {
72 *self as u32
73 }
74
75 pub const fn name(&self) -> &'static str {
77 match self {
78 $(
79 Self::$variant => $symbol,
80 )*
81 }
82 }
83
84 pub const fn core_params(&self) -> &'static [$crate::WasmValType] {
86 match self {
87 $(
88 Self::$variant => &[ $( define_unsafe_intrinsics!(@core_type $param_ty) ),* ],
89 )*
90 }
91 }
92
93 pub const fn core_results(&self) -> &'static [$crate::WasmValType] {
95 match self {
96 $(
97 Self::$variant => &[ $( define_unsafe_intrinsics!(@core_type $result_ty) )? ],
98 )*
99 }
100 }
101
102 pub const fn component_params(&self) -> &'static [$crate::component::InterfaceType] {
104 match self {
105 $(
106 Self::$variant => &[ $( define_unsafe_intrinsics!(@component_type $param_ty) ),* ],
107 )*
108 }
109 }
110
111 pub const fn component_results(&self) -> &'static [$crate::component::InterfaceType] {
113 match self {
114 $(
115 Self::$variant => &[ $( define_unsafe_intrinsics!(@component_type $result_ty) ),* ],
116 )*
117 }
118 }
119 }
120
121 impl FromStr for UnsafeIntrinsic {
122 type Err = Error;
123
124 fn from_str(s: &str) -> Result<Self> {
125 match s {
126 $(
127 $symbol => Ok(Self::$variant),
128 )*
129 _ => bail!("invalid unsafe intrinsic: {s:?}"),
130 }
131 }
132 }
133 };
134
135 (@core_type u8) => { $crate::WasmValType::I32 };
136 (@core_type u16) => { $crate::WasmValType::I32 };
137 (@core_type u32) => { $crate::WasmValType::I32 };
138 (@core_type u64) => { $crate::WasmValType::I64 };
139
140 (@component_type u8) => { $crate::component::InterfaceType::U8 };
141 (@component_type u16) => { $crate::component::InterfaceType::U16 };
142 (@component_type u32) => { $crate::component::InterfaceType::U32 };
143 (@component_type u64) => { $crate::component::InterfaceType::U64 };
144}
145
146for_each_unsafe_intrinsic!(define_unsafe_intrinsics);