1 use std::os::raw::c_void; 2 use wasmtime::{ExternRef, Func, Val}; 3 4 /// `*mut wasm_ref_t` is a reference type (`externref` or `funcref`), as seen by 5 /// the C API. Because we do not have a uniform representation for `funcref`s 6 /// and `externref`s, a `*mut wasm_ref_t` is morally a 7 /// `Option<Box<Either<ExternRef, Func>>>`. 8 /// 9 /// A null `*mut wasm_ref_t` is either a null `funcref` or a null `externref` 10 /// depending on context (e.g. the table's element type that it is going into or 11 /// coming out of). 12 /// 13 /// Note: this is not `#[repr(C)]` because it is an opaque type in the header, 14 /// and only ever referenced as `*mut wasm_ref_t`. This also lets us use a 15 /// regular, non-`repr(C)` `enum` to define `WasmRefInner`. 16 #[derive(Clone)] 17 pub struct wasm_ref_t { 18 pub(crate) r: WasmRefInner, 19 } 20 21 #[derive(Clone)] 22 pub(crate) enum WasmRefInner { 23 ExternRef(ExternRef), 24 FuncRef(Func), 25 } 26 27 wasmtime_c_api_macros::declare_own!(wasm_ref_t); 28 29 pub(crate) fn ref_to_val(r: &wasm_ref_t) -> Val { 30 match &r.r { 31 WasmRefInner::ExternRef(x) => Val::ExternRef(Some(x.clone())), 32 WasmRefInner::FuncRef(f) => Val::FuncRef(Some(f.clone())), 33 } 34 } 35 36 pub(crate) fn val_into_ref(val: Val) -> Option<Box<wasm_ref_t>> { 37 match val { 38 Val::ExternRef(Some(x)) => Some(Box::new(wasm_ref_t { 39 r: WasmRefInner::ExternRef(x), 40 })), 41 Val::FuncRef(Some(f)) => Some(Box::new(wasm_ref_t { 42 r: WasmRefInner::FuncRef(f), 43 })), 44 _ => None, 45 } 46 } 47 48 #[no_mangle] 49 pub extern "C" fn wasm_ref_copy(r: Option<&wasm_ref_t>) -> Option<Box<wasm_ref_t>> { 50 r.map(|r| Box::new(r.clone())) 51 } 52 53 fn abort(name: &str) -> ! { 54 eprintln!("`{}` is not implemented", name); 55 std::process::abort(); 56 } 57 58 #[no_mangle] 59 pub extern "C" fn wasm_ref_same(a: Option<&wasm_ref_t>, b: Option<&wasm_ref_t>) -> bool { 60 match (a.map(|a| &a.r), b.map(|b| &b.r)) { 61 (Some(WasmRefInner::ExternRef(a)), Some(WasmRefInner::ExternRef(b))) => a.ptr_eq(b), 62 (None, None) => true, 63 // Note: we don't support equality for `Func`, so we always return 64 // `false` for `funcref`s. 65 _ => false, 66 } 67 } 68 69 #[no_mangle] 70 pub extern "C" fn wasm_ref_get_host_info(_ref: Option<&wasm_ref_t>) -> *mut c_void { 71 std::ptr::null_mut() 72 } 73 74 #[no_mangle] 75 pub extern "C" fn wasm_ref_set_host_info(_ref: Option<&wasm_ref_t>, _info: *mut c_void) { 76 abort("wasm_ref_set_host_info") 77 } 78 79 #[no_mangle] 80 pub extern "C" fn wasm_ref_set_host_info_with_finalizer( 81 _ref: Option<&wasm_ref_t>, 82 _info: *mut c_void, 83 _finalizer: Option<extern "C" fn(*mut c_void)>, 84 ) { 85 abort("wasm_ref_set_host_info_with_finalizer") 86 } 87 88 #[no_mangle] 89 pub extern "C" fn wasm_ref_as_extern(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_extern_t> { 90 abort("wasm_ref_as_extern") 91 } 92 93 #[no_mangle] 94 pub extern "C" fn wasm_ref_as_extern_const( 95 _ref: Option<&wasm_ref_t>, 96 ) -> Option<&crate::wasm_extern_t> { 97 abort("wasm_ref_as_extern_const") 98 } 99 100 #[no_mangle] 101 pub extern "C" fn wasm_ref_as_foreign(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_foreign_t> { 102 abort("wasm_ref_as_foreign") 103 } 104 105 #[no_mangle] 106 pub extern "C" fn wasm_ref_as_foreign_const( 107 _ref: Option<&wasm_ref_t>, 108 ) -> Option<&crate::wasm_foreign_t> { 109 abort("wasm_ref_as_foreign_const") 110 } 111 112 #[no_mangle] 113 pub extern "C" fn wasm_ref_as_func(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_func_t> { 114 abort("wasm_ref_as_func") 115 } 116 117 #[no_mangle] 118 pub extern "C" fn wasm_ref_as_func_const(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_func_t> { 119 abort("wasm_ref_as_func_const") 120 } 121 122 #[no_mangle] 123 pub extern "C" fn wasm_ref_as_global(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_global_t> { 124 abort("wasm_ref_as_global") 125 } 126 127 #[no_mangle] 128 pub extern "C" fn wasm_ref_as_global_const( 129 _ref: Option<&wasm_ref_t>, 130 ) -> Option<&crate::wasm_global_t> { 131 abort("wasm_ref_as_global_const") 132 } 133 134 #[no_mangle] 135 pub extern "C" fn wasm_ref_as_instance( 136 _ref: Option<&wasm_ref_t>, 137 ) -> Option<&crate::wasm_instance_t> { 138 abort("wasm_ref_as_instance") 139 } 140 141 #[no_mangle] 142 pub extern "C" fn wasm_ref_as_instance_const( 143 _ref: Option<&wasm_ref_t>, 144 ) -> Option<&crate::wasm_instance_t> { 145 abort("wasm_ref_as_instance_const") 146 } 147 148 #[no_mangle] 149 pub extern "C" fn wasm_ref_as_memory(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_memory_t> { 150 abort("wasm_ref_as_memory") 151 } 152 153 #[no_mangle] 154 pub extern "C" fn wasm_ref_as_memory_const( 155 _ref: Option<&wasm_ref_t>, 156 ) -> Option<&crate::wasm_memory_t> { 157 abort("wasm_ref_as_memory_const") 158 } 159 160 #[no_mangle] 161 pub extern "C" fn wasm_ref_as_module(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_module_t> { 162 abort("wasm_ref_as_module") 163 } 164 165 #[no_mangle] 166 pub extern "C" fn wasm_ref_as_module_const( 167 _ref: Option<&wasm_ref_t>, 168 ) -> Option<&crate::wasm_module_t> { 169 abort("wasm_ref_as_module_const") 170 } 171 172 #[no_mangle] 173 pub extern "C" fn wasm_ref_as_table(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_table_t> { 174 abort("wasm_ref_as_table") 175 } 176 177 #[no_mangle] 178 pub extern "C" fn wasm_ref_as_table_const( 179 _ref: Option<&wasm_ref_t>, 180 ) -> Option<&crate::wasm_table_t> { 181 abort("wasm_ref_as_table_const") 182 } 183 184 #[no_mangle] 185 pub extern "C" fn wasm_ref_as_trap(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_trap_t> { 186 abort("wasm_ref_as_trap") 187 } 188 189 #[no_mangle] 190 pub extern "C" fn wasm_ref_as_trap_const(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_trap_t> { 191 abort("wasm_ref_as_trap_const") 192 } 193 194 #[derive(Clone)] 195 #[repr(C)] 196 pub struct wasm_foreign_t {} 197 198 #[no_mangle] 199 pub extern "C" fn wasm_foreign_new(_store: &crate::wasm_store_t) -> Box<wasm_foreign_t> { 200 abort("wasm_foreign_new") 201 } 202 203 #[no_mangle] 204 pub extern "C" fn wasm_foreign_delete(_foreign: Box<wasm_foreign_t>) {} 205 206 #[no_mangle] 207 pub extern "C" fn wasm_foreign_copy(r: &wasm_foreign_t) -> Box<wasm_foreign_t> { 208 Box::new(r.clone()) 209 } 210 211 #[no_mangle] 212 pub extern "C" fn wasm_foreign_same(_a: &wasm_foreign_t, _b: &wasm_foreign_t) -> bool { 213 abort("wasm_foreign_same") 214 } 215 216 #[no_mangle] 217 pub extern "C" fn wasm_foreign_get_host_info(_foreign: &wasm_foreign_t) -> *mut c_void { 218 std::ptr::null_mut() 219 } 220 221 #[no_mangle] 222 pub extern "C" fn wasm_foreign_set_host_info(_foreign: &wasm_foreign_t, _info: *mut c_void) { 223 abort("wasm_foreign_set_host_info") 224 } 225 226 #[no_mangle] 227 pub extern "C" fn wasm_foreign_set_host_info_with_finalizer( 228 _foreign: &wasm_foreign_t, 229 _info: *mut c_void, 230 _finalizer: Option<extern "C" fn(*mut c_void)>, 231 ) { 232 abort("wasm_foreign_set_host_info_with_finalizer") 233 } 234 235 #[no_mangle] 236 pub extern "C" fn wasm_foreign_as_ref(_: &wasm_foreign_t) -> &wasm_ref_t { 237 abort("wasm_foreign_as_ref") 238 } 239 240 #[no_mangle] 241 pub extern "C" fn wasm_foreign_as_ref_const(_: &wasm_foreign_t) -> Option<&wasm_ref_t> { 242 abort("wasm_foreign_as_ref_const") 243 } 244