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