Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/component-macro/tests/codegen.rs
1692 views
1
#![allow(dead_code, reason = "lots of macro-generated code")]
2
3
macro_rules! gentest {
4
($id:ident $name:tt $path:tt) => {
5
mod $id {
6
mod sugar {
7
wasmtime::component::bindgen!(in $path);
8
}
9
mod async_ {
10
wasmtime::component::bindgen!({
11
path: $path,
12
imports: { default: async },
13
exports: { default: async },
14
});
15
}
16
mod concurrent {
17
wasmtime::component::bindgen!({
18
path: $path,
19
imports: { default: async | store },
20
exports: { default: async | store },
21
});
22
}
23
mod tracing {
24
wasmtime::component::bindgen!({
25
path: $path,
26
imports: { default: tracing | verbose_tracing },
27
exports: { default: tracing | verbose_tracing },
28
ownership: Borrowing {
29
duplicate_if_necessary: true
30
}
31
});
32
}
33
}
34
};
35
}
36
37
component_macro_test_helpers::foreach!(gentest);
38
39
mod with_key_and_resources {
40
use anyhow::Result;
41
use wasmtime::component::Resource;
42
43
wasmtime::component::bindgen!({
44
inline: "
45
package demo:pkg;
46
47
interface bar {
48
resource a;
49
resource b;
50
}
51
52
world foo {
53
resource a;
54
resource b;
55
56
import foo: interface {
57
resource a;
58
resource b;
59
}
60
61
import bar;
62
}
63
",
64
with: {
65
"a": MyA,
66
"b": MyA,
67
"foo/a": MyA,
68
"foo/b": MyA,
69
"demo:pkg/bar/a": MyA,
70
"demo:pkg/bar/b": MyA,
71
},
72
});
73
74
pub struct MyA;
75
76
struct MyComponent;
77
78
impl FooImports for MyComponent {}
79
80
impl HostA for MyComponent {
81
fn drop(&mut self, _: Resource<MyA>) -> Result<()> {
82
loop {}
83
}
84
}
85
86
impl HostB for MyComponent {
87
fn drop(&mut self, _: Resource<MyA>) -> Result<()> {
88
loop {}
89
}
90
}
91
92
impl foo::Host for MyComponent {}
93
94
impl foo::HostA for MyComponent {
95
fn drop(&mut self, _: Resource<MyA>) -> Result<()> {
96
loop {}
97
}
98
}
99
100
impl foo::HostB for MyComponent {
101
fn drop(&mut self, _: Resource<MyA>) -> Result<()> {
102
loop {}
103
}
104
}
105
106
impl demo::pkg::bar::Host for MyComponent {}
107
108
impl demo::pkg::bar::HostA for MyComponent {
109
fn drop(&mut self, _: Resource<MyA>) -> Result<()> {
110
loop {}
111
}
112
}
113
114
impl demo::pkg::bar::HostB for MyComponent {
115
fn drop(&mut self, _: Resource<MyA>) -> Result<()> {
116
loop {}
117
}
118
}
119
}
120
121
mod trappable_errors_with_versioned_and_unversioned_packages {
122
wasmtime::component::bindgen!({
123
world: "foo:foo/nope",
124
inline: "
125
package foo:[email protected];
126
127
interface a {
128
variant error {
129
other(string),
130
}
131
132
f: func() -> result<_, error>;
133
}
134
135
world foo {
136
import a;
137
}
138
",
139
path: "tests/codegen/unversioned-foo.wit",
140
trappable_error_type: {
141
"foo:foo/[email protected]/error" => MyX,
142
},
143
});
144
145
type MyX = u64;
146
}
147
148
mod trappable_errors {
149
wasmtime::component::bindgen!({
150
inline: "
151
package demo:pkg;
152
153
interface a {
154
type b = u64;
155
156
z1: func() -> result<_, b>;
157
z2: func() -> result<_, b>;
158
}
159
160
interface b {
161
use a.{b};
162
z: func() -> result<_, b>;
163
}
164
165
interface c {
166
type b = u64;
167
}
168
169
interface d {
170
use c.{b};
171
z: func() -> result<_, b>;
172
}
173
174
world foo {
175
import a;
176
import b;
177
import d;
178
}
179
",
180
trappable_error_type: {
181
"demo:pkg/a/b" => MyX,
182
"demo:pkg/c/b" => MyX,
183
},
184
});
185
186
type MyX = u32;
187
}
188
189
mod interface_name_with_rust_keyword {
190
wasmtime::component::bindgen!({
191
inline: "
192
package foo:foo;
193
194
interface crate { }
195
196
world foo {
197
export crate;
198
}
199
"
200
});
201
}
202
203
mod with_works_with_hierarchy {
204
mod bindings {
205
wasmtime::component::bindgen!({
206
inline: "
207
package foo:foo;
208
209
interface a {
210
record t {
211
x: u32,
212
}
213
x: func() -> t;
214
}
215
216
interface b {
217
use a.{t};
218
x: func() -> t;
219
}
220
221
interface c {
222
use b.{t};
223
x: func() -> t;
224
}
225
226
world foo {
227
import c;
228
}
229
"
230
});
231
}
232
233
mod with_just_one_interface {
234
wasmtime::component::bindgen!({
235
inline: "
236
package foo:foo;
237
238
interface a {
239
record t {
240
x: u32,
241
}
242
x: func() -> t;
243
}
244
245
interface b {
246
use a.{t};
247
x: func() -> t;
248
}
249
250
interface c {
251
use b.{t};
252
x: func() -> t;
253
}
254
255
world foo {
256
use c.{t};
257
258
import x: func() -> t;
259
}
260
",
261
with: { "foo:foo/a": super::bindings::foo::foo::a }
262
});
263
264
struct X;
265
266
impl FooImports for X {
267
fn x(&mut self) -> super::bindings::foo::foo::a::T {
268
loop {}
269
}
270
}
271
}
272
273
mod with_whole_package {
274
wasmtime::component::bindgen!({
275
inline: "
276
package foo:foo;
277
278
interface a {
279
record t {
280
x: u32,
281
}
282
x: func() -> t;
283
}
284
285
interface b {
286
use a.{t};
287
x: func() -> t;
288
}
289
290
interface c {
291
use b.{t};
292
x: func() -> t;
293
}
294
295
world foo {
296
use c.{t};
297
298
import x: func() -> t;
299
}
300
",
301
with: { "foo:foo": super::bindings::foo::foo }
302
});
303
304
struct X;
305
306
impl FooImports for X {
307
fn x(&mut self) -> super::bindings::foo::foo::a::T {
308
loop {}
309
}
310
}
311
}
312
313
mod with_whole_namespace {
314
wasmtime::component::bindgen!({
315
inline: "
316
package foo:foo;
317
318
interface a {
319
record t {
320
x: u32,
321
}
322
x: func() -> t;
323
}
324
325
interface b {
326
use a.{t};
327
x: func() -> t;
328
}
329
330
interface c {
331
use b.{t};
332
x: func() -> t;
333
}
334
335
world foo {
336
use c.{t};
337
338
import x: func() -> t;
339
}
340
",
341
with: { "foo": super::bindings::foo }
342
});
343
344
struct X;
345
346
impl FooImports for X {
347
fn x(&mut self) -> super::bindings::foo::foo::a::T {
348
loop {}
349
}
350
}
351
}
352
}
353
354
mod trappable_imports {
355
mod none {
356
wasmtime::component::bindgen!({
357
inline: "
358
package foo:foo;
359
360
world foo {
361
import foo: func();
362
}
363
",
364
});
365
struct X;
366
367
impl FooImports for X {
368
fn foo(&mut self) {}
369
}
370
}
371
372
mod all {
373
wasmtime::component::bindgen!({
374
inline: "
375
package foo:foo;
376
377
world foo {
378
import foo: func();
379
}
380
",
381
imports: { default: trappable },
382
});
383
struct X;
384
385
impl FooImports for X {
386
fn foo(&mut self) -> wasmtime::Result<()> {
387
Ok(())
388
}
389
}
390
}
391
392
mod some {
393
wasmtime::component::bindgen!({
394
inline: "
395
package foo:foo;
396
397
world foo {
398
import foo: func();
399
import bar: func();
400
}
401
",
402
imports: { "foo": trappable },
403
});
404
struct X;
405
406
impl FooImports for X {
407
fn foo(&mut self) -> wasmtime::Result<()> {
408
Ok(())
409
}
410
fn bar(&mut self) {}
411
}
412
}
413
414
mod across_interfaces {
415
use wasmtime::component::Resource;
416
417
wasmtime::component::bindgen!({
418
inline: "
419
package foo:foo;
420
421
interface a {
422
foo: func();
423
bar: func();
424
425
resource r {
426
constructor();
427
foo: func();
428
bar: static func();
429
}
430
}
431
432
world foo {
433
import a;
434
import foo: func();
435
import bar: func();
436
import i: interface {
437
foo: func();
438
bar: func();
439
}
440
441
}
442
",
443
imports: {
444
"foo": trappable | exact,
445
"i/foo": trappable,
446
"foo:foo/a/foo": trappable,
447
},
448
with: { "foo:foo/a/r": R },
449
});
450
451
struct X;
452
pub struct R;
453
454
impl FooImports for X {
455
fn foo(&mut self) -> wasmtime::Result<()> {
456
Ok(())
457
}
458
fn bar(&mut self) {}
459
}
460
461
impl i::Host for X {
462
fn foo(&mut self) -> wasmtime::Result<()> {
463
Ok(())
464
}
465
fn bar(&mut self) {}
466
}
467
468
impl foo::foo::a::Host for X {
469
fn foo(&mut self) -> wasmtime::Result<()> {
470
Ok(())
471
}
472
fn bar(&mut self) {}
473
}
474
475
impl foo::foo::a::HostR for X {
476
fn new(&mut self) -> Resource<R> {
477
loop {}
478
}
479
fn foo(&mut self, _: Resource<R>) {}
480
fn bar(&mut self) {}
481
fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> {
482
Ok(())
483
}
484
}
485
}
486
487
mod resources {
488
use wasmtime::component::Resource;
489
490
wasmtime::component::bindgen!({
491
inline: "
492
package foo:foo;
493
494
interface a {
495
resource r {
496
constructor();
497
foo: func();
498
bar: static func();
499
}
500
}
501
502
world foo {
503
import a;
504
505
}
506
",
507
imports: {
508
"foo:foo/a/[constructor]r": trappable,
509
"foo:foo/a/[method]r.foo": trappable,
510
"foo:foo/a/[static]r.bar": trappable,
511
},
512
with: { "foo:foo/a/r": R },
513
});
514
515
struct X;
516
pub struct R;
517
518
impl foo::foo::a::Host for X {}
519
520
impl foo::foo::a::HostR for X {
521
fn new(&mut self) -> wasmtime::Result<Resource<R>> {
522
loop {}
523
}
524
fn foo(&mut self, _: Resource<R>) -> wasmtime::Result<()> {
525
Ok(())
526
}
527
fn bar(&mut self) -> wasmtime::Result<()> {
528
Ok(())
529
}
530
fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> {
531
Ok(())
532
}
533
}
534
}
535
}
536
537
mod custom_derives {
538
use std::collections::{HashSet, hash_map::RandomState};
539
540
wasmtime::component::bindgen!({
541
inline: "
542
package my:inline;
543
544
interface blah {
545
variant abc {
546
a,
547
b,
548
c
549
}
550
551
record foo {
552
field1: string,
553
field2: list<u32>,
554
field3: abc
555
}
556
557
bar: func(cool: foo);
558
}
559
560
world baz {
561
import blah;
562
}
563
",
564
// Clone is included by default almost everywhere, so include it here to make sure it
565
// doesn't conflict
566
additional_derives: [serde::Serialize, serde::Deserialize, Hash, Clone, PartialEq, Eq],
567
});
568
569
use my::inline::blah::{Abc, Foo, Host};
570
571
struct X;
572
573
impl Host for X {
574
fn bar(&mut self, cool: Foo) {
575
// Check that built in derives that I've added actually work by seeing that this hashes
576
let _blah: HashSet<Foo, RandomState> = HashSet::from_iter([Foo {
577
field1: "hello".to_string(),
578
field2: vec![1, 2, 3],
579
field3: Abc::B,
580
}]);
581
582
// Check that the attributes from an external crate actually work. If they don't work,
583
// compilation will fail here
584
let _ = serde_json::to_string(&cool);
585
}
586
}
587
}
588
589
mod with_and_mixing_async {
590
mod with_async {
591
wasmtime::component::bindgen!({
592
inline: "
593
package my:inline;
594
interface foo {
595
type t = u32;
596
foo: func() -> t;
597
}
598
interface bar {
599
use foo.{t};
600
bar: func() -> t;
601
}
602
world x {
603
import bar;
604
}
605
",
606
imports: {
607
"my:inline/bar/bar": async,
608
},
609
});
610
}
611
612
mod without_async {
613
wasmtime::component::bindgen!({
614
inline: "
615
package my:inline;
616
interface foo {
617
type t = u32;
618
foo: func() -> t;
619
}
620
interface bar {
621
use foo.{t};
622
bar: func() -> t;
623
}
624
world x {
625
import bar;
626
}
627
",
628
with: {
629
"my:inline/foo": super::with_async::my::inline::foo,
630
},
631
require_store_data_send: true,
632
});
633
}
634
635
mod third {
636
wasmtime::component::bindgen!({
637
inline: "
638
package my:inline;
639
interface foo {
640
type t = u32;
641
foo: func() -> t;
642
}
643
interface bar {
644
use foo.{t};
645
bar: func() -> t;
646
}
647
interface baz {
648
use bar.{t};
649
baz: func() -> t;
650
}
651
world x {
652
import baz;
653
}
654
",
655
with: {
656
"my:inline/foo": super::with_async::my::inline::foo,
657
"my:inline/bar": super::without_async::my::inline::bar,
658
},
659
require_store_data_send: true,
660
});
661
}
662
}
663
664
mod trappable_error_type_and_versions {
665
struct MyError;
666
667
mod package_no_version_path_no_version {
668
wasmtime::component::bindgen!({
669
inline: "
670
package my:inline;
671
interface i {
672
enum e { a, b, c }
673
}
674
world foo {}
675
",
676
trappable_error_type: {
677
"my:inline/i/e" => super::MyError,
678
},
679
});
680
}
681
mod package_version_path_no_version {
682
wasmtime::component::bindgen!({
683
inline: "
684
package my:[email protected];
685
interface i {
686
enum e { a, b, c }
687
}
688
world foo {}
689
",
690
trappable_error_type: {
691
"my:inline/i/e" => super::MyError,
692
},
693
});
694
}
695
mod package_version_path_version {
696
wasmtime::component::bindgen!({
697
inline: "
698
package my:[email protected];
699
interface i {
700
enum e { a, b, c }
701
}
702
world foo {}
703
",
704
trappable_error_type: {
705
"my:inline/[email protected]/e" => super::MyError,
706
},
707
});
708
}
709
}
710
711
mod paths {
712
mod multiple_paths {
713
wasmtime::component::bindgen!({
714
world: "test:paths/test",
715
inline: r#"
716
package test:paths;
717
world test {
718
import paths:path1/test;
719
export paths:path2/test;
720
}
721
"#,
722
path: ["tests/codegen/path1", "tests/codegen/path2"],
723
});
724
}
725
}
726
727