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