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