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