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 "context-get-i32-0" => ContextGetI32_0 : context_get_i32_0() -> u32;
27 "context-set-i32-0" => ContextSetI32_0 : context_set_i32_0(val: u32);
28 "context-get-i32-1" => ContextGetI32_1 : context_get_i32_1() -> u32;
29 "context-set-i32-1" => ContextSetI32_1 : context_set_i32_1(val: u32);
30 }
31 };
32}
33
34macro_rules! define_unsafe_intrinsics {
35 (
36 $(
37 $symbol:expr => $variant:ident : $ctor:ident ( $( $param:ident : $param_ty:ident ),* ) $( -> $result_ty:ident )? ;
38 )*
39 ) => {
40 #[repr(u32)]
43 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
44 pub enum UnsafeIntrinsic {
45 $(
46 #[doc = concat!("The `", $symbol, "` intrinsic.")]
47 $variant,
48 )*
49 }
50
51 impl UnsafeIntrinsic {
52 pub const fn len() -> u32 {
54 let mut len = 0;
55 $(
56 let _ = Self::$variant;
57 len += 1;
58 )*
59 len
60 }
61
62 pub const fn from_u32(i: u32) -> Self {
66 assert!(i < Self::len());
67 $(
68 if i == Self::$variant.index() {
69 return Self::$variant;
70 }
71 )*
72 unreachable!()
73 }
74
75 pub const fn index(&self) -> u32 {
77 *self as u32
78 }
79
80 pub const fn name(&self) -> &'static str {
82 match self {
83 $(
84 Self::$variant => $symbol,
85 )*
86 }
87 }
88
89 pub const fn core_params(&self) -> &'static [$crate::WasmValType] {
91 match self {
92 $(
93 Self::$variant => &[ $( define_unsafe_intrinsics!(@core_type $param_ty) ),* ],
94 )*
95 }
96 }
97
98 pub const fn core_results(&self) -> &'static [$crate::WasmValType] {
100 match self {
101 $(
102 Self::$variant => &[ $( define_unsafe_intrinsics!(@core_type $result_ty) )? ],
103 )*
104 }
105 }
106
107 pub const fn component_params(&self) -> &'static [$crate::component::InterfaceType] {
109 match self {
110 $(
111 Self::$variant => &[ $( define_unsafe_intrinsics!(@component_type $param_ty) ),* ],
112 )*
113 }
114 }
115
116 pub const fn component_results(&self) -> &'static [$crate::component::InterfaceType] {
118 match self {
119 $(
120 Self::$variant => &[ $( define_unsafe_intrinsics!(@component_type $result_ty) ),* ],
121 )*
122 }
123 }
124 }
125
126 impl FromStr for UnsafeIntrinsic {
127 type Err = Error;
128
129 fn from_str(s: &str) -> Result<Self> {
130 match s {
131 $(
132 $symbol => Ok(Self::$variant),
133 )*
134 _ => bail!("invalid unsafe intrinsic: {s:?}"),
135 }
136 }
137 }
138 };
139
140 (@core_type u8) => { $crate::WasmValType::I32 };
141 (@core_type u16) => { $crate::WasmValType::I32 };
142 (@core_type u32) => { $crate::WasmValType::I32 };
143 (@core_type u64) => { $crate::WasmValType::I64 };
144
145 (@component_type u8) => { $crate::component::InterfaceType::U8 };
146 (@component_type u16) => { $crate::component::InterfaceType::U16 };
147 (@component_type u32) => { $crate::component::InterfaceType::U32 };
148 (@component_type u64) => { $crate::component::InterfaceType::U64 };
149}
150
151for_each_unsafe_intrinsic!(define_unsafe_intrinsics);