1 use crate::{WasmtimeStoreContextMut, handle_result, wasm_name_t, wasmtime_error_t}; 2 use std::mem; 3 use std::mem::{ManuallyDrop, MaybeUninit}; 4 use std::ptr; 5 use std::slice; 6 use wasmtime::component::{ResourceAny, ResourceDynamic, ResourceType, Val}; 7 8 crate::declare_vecs! { 9 ( 10 name: wasmtime_component_vallist_t, 11 ty: wasmtime_component_val_t, 12 new: wasmtime_component_vallist_new, 13 empty: wasmtime_component_vallist_new_empty, 14 uninit: wasmtime_component_vallist_new_uninit, 15 copy: wasmtime_component_vallist_copy, 16 delete: wasmtime_component_vallist_delete, 17 ) 18 ( 19 name: wasmtime_component_valrecord_t, 20 ty: wasmtime_component_valrecord_entry_t, 21 new: wasmtime_component_valrecord_new, 22 empty: wasmtime_component_valrecord_new_empty, 23 uninit: wasmtime_component_valrecord_new_uninit, 24 copy: wasmtime_component_valrecord_copy, 25 delete: wasmtime_component_valrecord_delete, 26 ) 27 ( 28 name: wasmtime_component_valtuple_t, 29 ty: wasmtime_component_val_t, 30 new: wasmtime_component_valtuple_new, 31 empty: wasmtime_component_valtuple_new_empty, 32 uninit: wasmtime_component_valtuple_new_uninit, 33 copy: wasmtime_component_valtuple_copy, 34 delete: wasmtime_component_valtuple_delete, 35 ) 36 ( 37 name: wasmtime_component_valflags_t, 38 ty: wasm_name_t, 39 new: wasmtime_component_valflags_new, 40 empty: wasmtime_component_valflags_new_empty, 41 uninit: wasmtime_component_valflags_new_uninit, 42 copy: wasmtime_component_valflags_copy, 43 delete: wasmtime_component_valflags_delete, 44 ) 45 } 46 47 impl From<&wasmtime_component_vallist_t> for Vec<Val> { 48 fn from(value: &wasmtime_component_vallist_t) -> Self { 49 value.as_slice().iter().map(Val::from).collect() 50 } 51 } 52 53 impl From<&[Val]> for wasmtime_component_vallist_t { 54 fn from(value: &[Val]) -> Self { 55 value 56 .iter() 57 .map(wasmtime_component_val_t::from) 58 .collect::<Vec<_>>() 59 .into() 60 } 61 } 62 63 #[derive(Clone)] 64 #[repr(C)] 65 pub struct wasmtime_component_valrecord_entry_t { 66 name: wasm_name_t, 67 val: wasmtime_component_val_t, 68 } 69 70 impl Default for wasmtime_component_valrecord_entry_t { 71 fn default() -> Self { 72 Self { 73 name: wasm_name_t::from_name(String::new()), 74 val: Default::default(), 75 } 76 } 77 } 78 79 impl From<&wasmtime_component_valrecord_entry_t> for (String, Val) { 80 fn from(value: &wasmtime_component_valrecord_entry_t) -> Self { 81 ( 82 String::from_utf8(value.name.clone().take()).unwrap(), 83 Val::from(&value.val), 84 ) 85 } 86 } 87 88 impl From<&(String, Val)> for wasmtime_component_valrecord_entry_t { 89 fn from((name, val): &(String, Val)) -> Self { 90 Self { 91 name: wasm_name_t::from_name(name.clone()), 92 val: wasmtime_component_val_t::from(val), 93 } 94 } 95 } 96 97 impl From<&wasmtime_component_valrecord_t> for Vec<(String, Val)> { 98 fn from(value: &wasmtime_component_valrecord_t) -> Self { 99 value.as_slice().iter().map(Into::into).collect() 100 } 101 } 102 103 impl From<&[(String, Val)]> for wasmtime_component_valrecord_t { 104 fn from(value: &[(String, Val)]) -> Self { 105 value 106 .iter() 107 .map(wasmtime_component_valrecord_entry_t::from) 108 .collect::<Vec<_>>() 109 .into() 110 } 111 } 112 113 impl From<&wasmtime_component_valtuple_t> for Vec<Val> { 114 fn from(value: &wasmtime_component_valtuple_t) -> Self { 115 value.as_slice().iter().map(Val::from).collect() 116 } 117 } 118 119 impl From<&[Val]> for wasmtime_component_valtuple_t { 120 fn from(value: &[Val]) -> Self { 121 value 122 .iter() 123 .map(wasmtime_component_val_t::from) 124 .collect::<Vec<_>>() 125 .into() 126 } 127 } 128 129 impl From<&wasmtime_component_valflags_t> for Vec<String> { 130 fn from(value: &wasmtime_component_valflags_t) -> Self { 131 value 132 .clone() 133 .take() 134 .into_iter() 135 .map(|mut x| String::from_utf8(x.take())) 136 .collect::<Result<Vec<_>, _>>() 137 .unwrap() 138 } 139 } 140 141 impl From<&[String]> for wasmtime_component_valflags_t { 142 fn from(value: &[String]) -> Self { 143 value 144 .iter() 145 .map(|x| wasm_name_t::from_name(x.clone())) 146 .collect::<Vec<_>>() 147 .into() 148 } 149 } 150 151 #[repr(C)] 152 #[derive(Clone)] 153 pub struct wasmtime_component_valvariant_t { 154 discriminant: wasm_name_t, 155 val: Option<Box<wasmtime_component_val_t>>, 156 } 157 158 impl From<(&String, &Option<Box<Val>>)> for wasmtime_component_valvariant_t { 159 fn from((discriminant, value): (&String, &Option<Box<Val>>)) -> Self { 160 Self { 161 discriminant: wasm_name_t::from_name(discriminant.clone()), 162 val: value 163 .as_ref() 164 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))), 165 } 166 } 167 } 168 169 impl From<&wasmtime_component_valvariant_t> for (String, Option<Box<Val>>) { 170 fn from(value: &wasmtime_component_valvariant_t) -> Self { 171 ( 172 String::from_utf8(value.discriminant.clone().take()).unwrap(), 173 value.val.as_ref().map(|x| Box::new(Val::from(x.as_ref()))), 174 ) 175 } 176 } 177 178 #[repr(C)] 179 #[derive(Clone)] 180 pub struct wasmtime_component_valresult_t { 181 is_ok: bool, 182 val: Option<Box<wasmtime_component_val_t>>, 183 } 184 185 impl From<&wasmtime_component_valresult_t> for Result<Option<Box<Val>>, Option<Box<Val>>> { 186 fn from(value: &wasmtime_component_valresult_t) -> Self { 187 let val = value.val.as_ref().map(|x| Box::new(Val::from(x.as_ref()))); 188 189 match value.is_ok { 190 true => Ok(val), 191 false => Err(val), 192 } 193 } 194 } 195 196 impl From<&Result<Option<Box<Val>>, Option<Box<Val>>>> for wasmtime_component_valresult_t { 197 fn from(value: &Result<Option<Box<Val>>, Option<Box<Val>>>) -> Self { 198 let (Ok(x) | Err(x)) = value; 199 200 Self { 201 is_ok: value.is_ok(), 202 val: x 203 .as_ref() 204 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))), 205 } 206 } 207 } 208 209 #[repr(C, u8)] 210 #[derive(Clone)] 211 pub enum wasmtime_component_val_t { 212 Bool(bool), 213 S8(i8), 214 U8(u8), 215 S16(i16), 216 U16(u16), 217 S32(i32), 218 U32(u32), 219 S64(i64), 220 U64(u64), 221 F32(f32), 222 F64(f64), 223 Char(u32), 224 String(wasm_name_t), 225 List(wasmtime_component_vallist_t), 226 Record(wasmtime_component_valrecord_t), 227 Tuple(wasmtime_component_valtuple_t), 228 Variant(wasmtime_component_valvariant_t), 229 Enum(wasm_name_t), 230 Option(Option<Box<Self>>), 231 Result(wasmtime_component_valresult_t), 232 Flags(wasmtime_component_valflags_t), 233 Resource(Box<wasmtime_component_resource_any_t>), 234 } 235 236 impl Default for wasmtime_component_val_t { 237 fn default() -> Self { 238 Self::Bool(false) 239 } 240 } 241 242 impl From<&wasmtime_component_val_t> for Val { 243 fn from(value: &wasmtime_component_val_t) -> Self { 244 match value { 245 wasmtime_component_val_t::Bool(x) => Val::Bool(*x), 246 wasmtime_component_val_t::S8(x) => Val::S8(*x), 247 wasmtime_component_val_t::U8(x) => Val::U8(*x), 248 wasmtime_component_val_t::S16(x) => Val::S16(*x), 249 wasmtime_component_val_t::U16(x) => Val::U16(*x), 250 wasmtime_component_val_t::S32(x) => Val::S32(*x), 251 wasmtime_component_val_t::U32(x) => Val::U32(*x), 252 wasmtime_component_val_t::S64(x) => Val::S64(*x), 253 wasmtime_component_val_t::U64(x) => Val::U64(*x), 254 wasmtime_component_val_t::F32(x) => Val::Float32(*x), 255 wasmtime_component_val_t::F64(x) => Val::Float64(*x), 256 wasmtime_component_val_t::Char(x) => Val::Char(char::from_u32(*x).unwrap()), 257 wasmtime_component_val_t::String(x) => { 258 Val::String(String::from_utf8(x.clone().take()).unwrap()) 259 } 260 wasmtime_component_val_t::List(x) => Val::List(x.into()), 261 wasmtime_component_val_t::Record(x) => Val::Record(x.into()), 262 wasmtime_component_val_t::Tuple(x) => Val::Tuple(x.into()), 263 wasmtime_component_val_t::Variant(x) => { 264 let (a, b) = x.into(); 265 Val::Variant(a, b) 266 } 267 wasmtime_component_val_t::Enum(x) => { 268 Val::Enum(String::from_utf8(x.clone().take()).unwrap()) 269 } 270 wasmtime_component_val_t::Option(x) => { 271 Val::Option(x.as_ref().map(|x| Box::new(Val::from(x.as_ref())))) 272 } 273 wasmtime_component_val_t::Result(x) => Val::Result(x.into()), 274 wasmtime_component_val_t::Flags(x) => Val::Flags(x.into()), 275 wasmtime_component_val_t::Resource(x) => Val::Resource(x.resource), 276 } 277 } 278 } 279 280 impl From<&Val> for wasmtime_component_val_t { 281 fn from(value: &Val) -> Self { 282 match value { 283 Val::Bool(x) => wasmtime_component_val_t::Bool(*x), 284 Val::S8(x) => wasmtime_component_val_t::S8(*x), 285 Val::U8(x) => wasmtime_component_val_t::U8(*x), 286 Val::S16(x) => wasmtime_component_val_t::S16(*x), 287 Val::U16(x) => wasmtime_component_val_t::U16(*x), 288 Val::S32(x) => wasmtime_component_val_t::S32(*x), 289 Val::U32(x) => wasmtime_component_val_t::U32(*x), 290 Val::S64(x) => wasmtime_component_val_t::S64(*x), 291 Val::U64(x) => wasmtime_component_val_t::U64(*x), 292 Val::Float32(x) => wasmtime_component_val_t::F32(*x), 293 Val::Float64(x) => wasmtime_component_val_t::F64(*x), 294 Val::Char(x) => wasmtime_component_val_t::Char(*x as _), 295 Val::String(x) => wasmtime_component_val_t::String(wasm_name_t::from_name(x.clone())), 296 Val::List(x) => wasmtime_component_val_t::List(x.as_slice().into()), 297 Val::Record(x) => wasmtime_component_val_t::Record(x.as_slice().into()), 298 Val::Tuple(x) => wasmtime_component_val_t::Tuple(x.as_slice().into()), 299 Val::Variant(discriminant, val) => { 300 wasmtime_component_val_t::Variant((discriminant, val).into()) 301 } 302 Val::Enum(x) => wasmtime_component_val_t::Enum(wasm_name_t::from_name(x.clone())), 303 Val::Option(x) => wasmtime_component_val_t::Option( 304 x.as_ref() 305 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))), 306 ), 307 Val::Result(x) => wasmtime_component_val_t::Result(x.into()), 308 Val::Flags(x) => wasmtime_component_val_t::Flags(x.as_slice().into()), 309 Val::Resource(resource_any) => { 310 wasmtime_component_val_t::Resource(Box::new(wasmtime_component_resource_any_t { 311 resource: *resource_any, 312 })) 313 } 314 Val::Future(_) => todo!(), 315 Val::Stream(_) => todo!(), 316 Val::ErrorContext(_) => todo!(), 317 } 318 } 319 } 320 321 #[unsafe(no_mangle)] 322 pub extern "C" fn wasmtime_component_val_new( 323 src: &mut wasmtime_component_val_t, 324 ) -> Box<wasmtime_component_val_t> { 325 Box::new(mem::replace(src, wasmtime_component_val_t::default())) 326 } 327 328 #[unsafe(no_mangle)] 329 pub extern "C" fn wasmtime_component_val_free(_dst: Option<Box<wasmtime_component_val_t>>) {} 330 331 #[unsafe(no_mangle)] 332 pub extern "C" fn wasmtime_component_val_clone( 333 src: &wasmtime_component_val_t, 334 dst: &mut MaybeUninit<wasmtime_component_val_t>, 335 ) { 336 dst.write(src.clone()); 337 } 338 339 #[unsafe(no_mangle)] 340 pub unsafe extern "C" fn wasmtime_component_val_delete( 341 value: &mut ManuallyDrop<wasmtime_component_val_t>, 342 ) { 343 unsafe { 344 ManuallyDrop::drop(value); 345 } 346 } 347 348 #[repr(C)] 349 pub struct wasmtime_component_resource_type_t { 350 pub(crate) ty: ResourceType, 351 } 352 353 #[unsafe(no_mangle)] 354 pub extern "C" fn wasmtime_component_resource_type_new_host( 355 ty: u32, 356 ) -> Box<wasmtime_component_resource_type_t> { 357 Box::new(wasmtime_component_resource_type_t { 358 ty: ResourceType::host_dynamic(ty), 359 }) 360 } 361 362 #[unsafe(no_mangle)] 363 pub extern "C" fn wasmtime_component_resource_type_clone( 364 ty: &wasmtime_component_resource_type_t, 365 ) -> Box<wasmtime_component_resource_type_t> { 366 Box::new(wasmtime_component_resource_type_t { ty: ty.ty }) 367 } 368 369 #[unsafe(no_mangle)] 370 pub extern "C" fn wasmtime_component_resource_type_equal( 371 a: &wasmtime_component_resource_type_t, 372 b: &wasmtime_component_resource_type_t, 373 ) -> bool { 374 a.ty == b.ty 375 } 376 377 #[unsafe(no_mangle)] 378 pub extern "C" fn wasmtime_component_resource_type_delete( 379 _resource: Option<Box<wasmtime_component_resource_type_t>>, 380 ) { 381 } 382 383 #[repr(C)] 384 #[derive(Clone)] 385 pub struct wasmtime_component_resource_any_t { 386 resource: ResourceAny, 387 } 388 389 #[unsafe(no_mangle)] 390 pub extern "C" fn wasmtime_component_resource_any_type( 391 resource: &wasmtime_component_resource_any_t, 392 ) -> Box<wasmtime_component_resource_type_t> { 393 Box::new(wasmtime_component_resource_type_t { 394 ty: resource.resource.ty(), 395 }) 396 } 397 398 #[unsafe(no_mangle)] 399 pub extern "C" fn wasmtime_component_resource_any_clone( 400 resource: &wasmtime_component_resource_any_t, 401 ) -> Box<wasmtime_component_resource_any_t> { 402 Box::new(wasmtime_component_resource_any_t { 403 resource: resource.resource, 404 }) 405 } 406 407 #[unsafe(no_mangle)] 408 pub extern "C" fn wasmtime_component_resource_any_owned( 409 resource: &wasmtime_component_resource_any_t, 410 ) -> bool { 411 resource.resource.owned() 412 } 413 414 #[unsafe(no_mangle)] 415 pub extern "C" fn wasmtime_component_resource_any_drop( 416 store: WasmtimeStoreContextMut<'_>, 417 resource: &wasmtime_component_resource_any_t, 418 ) -> Option<Box<wasmtime_error_t>> { 419 handle_result(resource.resource.resource_drop(store), |()| ()) 420 } 421 422 #[unsafe(no_mangle)] 423 pub extern "C" fn wasmtime_component_resource_any_delete( 424 _resource: Option<Box<wasmtime_component_resource_any_t>>, 425 ) { 426 } 427 428 #[repr(C)] 429 pub struct wasmtime_component_resource_host_t { 430 resource: ResourceDynamic, 431 } 432 433 impl wasmtime_component_resource_host_t { 434 // "poor man's clone" 435 fn resource(&self) -> ResourceDynamic { 436 let rep = self.resource.rep(); 437 let ty = self.resource.ty(); 438 if self.resource.owned() { 439 ResourceDynamic::new_own(rep, ty) 440 } else { 441 ResourceDynamic::new_borrow(rep, ty) 442 } 443 } 444 } 445 446 #[unsafe(no_mangle)] 447 pub extern "C" fn wasmtime_component_resource_host_new( 448 owned: bool, 449 rep: u32, 450 ty: u32, 451 ) -> Box<wasmtime_component_resource_host_t> { 452 Box::new(wasmtime_component_resource_host_t { 453 resource: if owned { 454 ResourceDynamic::new_own(rep, ty) 455 } else { 456 ResourceDynamic::new_borrow(rep, ty) 457 }, 458 }) 459 } 460 461 #[unsafe(no_mangle)] 462 pub extern "C" fn wasmtime_component_resource_host_clone( 463 resource: &wasmtime_component_resource_host_t, 464 ) -> Box<wasmtime_component_resource_host_t> { 465 Box::new(wasmtime_component_resource_host_t { 466 resource: resource.resource(), 467 }) 468 } 469 470 #[unsafe(no_mangle)] 471 pub extern "C" fn wasmtime_component_resource_host_rep( 472 resource: &wasmtime_component_resource_host_t, 473 ) -> u32 { 474 resource.resource.rep() 475 } 476 477 #[unsafe(no_mangle)] 478 pub extern "C" fn wasmtime_component_resource_host_type( 479 resource: &wasmtime_component_resource_host_t, 480 ) -> u32 { 481 resource.resource.ty() 482 } 483 484 #[unsafe(no_mangle)] 485 pub extern "C" fn wasmtime_component_resource_host_owned( 486 resource: &wasmtime_component_resource_host_t, 487 ) -> bool { 488 resource.resource.owned() 489 } 490 491 #[unsafe(no_mangle)] 492 pub extern "C" fn wasmtime_component_resource_host_delete( 493 _resource: Option<Box<wasmtime_component_resource_host_t>>, 494 ) { 495 } 496 497 #[unsafe(no_mangle)] 498 pub extern "C" fn wasmtime_component_resource_any_to_host( 499 store: WasmtimeStoreContextMut<'_>, 500 resource: &wasmtime_component_resource_any_t, 501 ret: &mut MaybeUninit<Box<wasmtime_component_resource_host_t>>, 502 ) -> Option<Box<wasmtime_error_t>> { 503 handle_result( 504 resource.resource.try_into_resource_dynamic(store), 505 |resource| { 506 ret.write(Box::new(wasmtime_component_resource_host_t { resource })); 507 }, 508 ) 509 } 510 511 #[unsafe(no_mangle)] 512 pub extern "C" fn wasmtime_component_resource_host_to_any( 513 store: WasmtimeStoreContextMut<'_>, 514 resource: &wasmtime_component_resource_host_t, 515 ret: &mut MaybeUninit<Box<wasmtime_component_resource_any_t>>, 516 ) -> Option<Box<wasmtime_error_t>> { 517 handle_result( 518 resource.resource().try_into_resource_any(store), 519 |resource| { 520 ret.write(Box::new(wasmtime_component_resource_any_t { resource })); 521 }, 522 ) 523 } 524