1mod component_type_object;
2
3use heck::*;
4use std::collections::{BTreeSet, HashMap, HashSet};
5use std::fmt::Write;
6use std::mem;
7use wit_bindgen_core::wit_parser::abi::{
8 AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType,
9};
10use wit_bindgen_core::{
11 uwrite, uwriteln, wit_parser::*, Files, InterfaceGenerator as _, Ns, WorldGenerator,
12};
13use wit_component::StringEncoding;
14
15#[derive(Default)]
16struct C {
17 src: Source,
18 opts: Opts,
19 includes: Vec<String>,
20 return_pointer_area_size: usize,
21 return_pointer_area_align: usize,
22 names: Ns,
23 needs_string: bool,
24 world: String,
25 sizes: SizeAlign,
26 interface_names: HashMap<InterfaceId, String>,
27}
28
29#[derive(Default, Debug, Clone)]
30#[cfg_attr(feature = "clap", derive(clap::Args))]
31pub struct Opts {
32 #[cfg_attr(feature = "clap", arg(long))]
34 pub no_helpers: bool,
35 #[cfg_attr(feature = "clap", arg(long, default_value_t = StringEncoding::default()))]
37 pub string_encoding: StringEncoding,
38}
39
40impl Opts {
41 pub fn build(&self) -> Box<dyn WorldGenerator> {
42 let mut r = C::default();
43 r.opts = self.clone();
44 Box::new(r)
45 }
46}
47
48#[derive(Debug, Default)]
49struct Return {
50 scalar: Option<Scalar>,
51 retptrs: Vec<Type>,
52}
53
54struct CSig {
55 name: String,
56 sig: String,
57 params: Vec<(bool, String)>,
58 ret: Return,
59 retptrs: Vec<String>,
60}
61
62#[derive(Debug)]
63enum Scalar {
64 Void,
65 OptionBool(Type),
66 ResultBool(Option<Type>, Option<Type>),
67 Type(Type),
68}
69
70impl WorldGenerator for C {
71 fn preprocess(&mut self, resolve: &Resolve, world: WorldId) {
72 let name = &resolve.worlds[world].name;
73 self.world = name.to_string();
74 self.sizes.fill(resolve);
75 }
76
77 fn import_interface(
78 &mut self,
79 resolve: &Resolve,
80 name: &str,
81 id: InterfaceId,
82 _files: &mut Files,
83 ) {
84 let prev = self.interface_names.insert(id, name.to_string());
85 assert!(prev.is_none());
86 let mut gen = self.interface(name, resolve, true);
87 gen.interface = Some(id);
88 gen.types(id);
89
90 for (i, (_name, func)) in resolve.interfaces[id].functions.iter().enumerate() {
91 if i == 0 {
92 uwriteln!(gen.src.h_fns, "\n// Imported Functions from `{name}`");
93 }
94 gen.import(name, func);
95 }
96
97 gen.finish();
98
99 gen.gen.src.append(&gen.src);
100 }
101
102 fn import_funcs(
103 &mut self,
104 resolve: &Resolve,
105 world: WorldId,
106 funcs: &[(&str, &Function)],
107 _files: &mut Files,
108 ) {
109 let name = &resolve.worlds[world].name;
110 let mut gen = self.interface(name, resolve, true);
111
112 for (i, (_name, func)) in funcs.iter().enumerate() {
113 if i == 0 {
114 uwriteln!(gen.src.h_fns, "\n// Imported Functions from `{name}`");
115 }
116 gen.import("$root", func);
117 }
118
119 gen.finish();
120
121 gen.gen.src.append(&gen.src);
122 }
123
124 fn export_interface(
125 &mut self,
126 resolve: &Resolve,
127 name: &str,
128 id: InterfaceId,
129 _files: &mut Files,
130 ) {
131 self.interface_names.insert(id, name.to_string());
132 let mut gen = self.interface(name, resolve, false);
133 gen.interface = Some(id);
134 gen.types(id);
135
136 for (i, (_name, func)) in resolve.interfaces[id].functions.iter().enumerate() {
137 if i == 0 {
138 uwriteln!(gen.src.h_fns, "\n// Exported Functions from `{name}`");
139 }
140 gen.export(func, Some(name));
141 }
142
143 gen.finish();
144
145 gen.gen.src.append(&gen.src);
146 }
147
148 fn export_funcs(
149 &mut self,
150 resolve: &Resolve,
151 world: WorldId,
152 funcs: &[(&str, &Function)],
153 _files: &mut Files,
154 ) {
155 let name = &resolve.worlds[world].name;
156 let mut gen = self.interface(name, resolve, false);
157
158 for (i, (_name, func)) in funcs.iter().enumerate() {
159 if i == 0 {
160 uwriteln!(gen.src.h_fns, "\n// Exported Functions from `{name}`");
161 }
162 gen.export(func, None);
163 }
164
165 gen.finish();
166
167 gen.gen.src.append(&gen.src);
168 }
169
170 fn export_types(
171 &mut self,
172 resolve: &Resolve,
173 world: WorldId,
174 types: &[(&str, TypeId)],
175 _files: &mut Files,
176 ) {
177 let name = &resolve.worlds[world].name;
178 let mut gen = self.interface(name, resolve, false);
179 for (name, id) in types {
180 gen.define_type(name, *id);
181 }
182 gen.finish();
183 gen.gen.src.append(&gen.src);
184 }
185
186 fn finish(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) {
187 let world = &resolve.worlds[id];
188 let linking_symbol = component_type_object::linking_symbol(&world.name);
189 self.include("<stdlib.h>");
190 let snake = world.name.to_snake_case();
191 uwrite!(
192 self.src.c_adapters,
193 "
194 extern void {linking_symbol}(void);
195 void {linking_symbol}_public_use_in_this_compilation_unit(void) {{
196 {linking_symbol}();
197 }}
198 ",
199 );
200
201 self.print_intrinsics();
202
203 if self.needs_string {
204 self.include("<string.h>");
205 let (strlen, size) = match self.opts.string_encoding {
206 StringEncoding::UTF8 => (format!("strlen(s)"), 1),
207 StringEncoding::UTF16 => {
208 self.include("<uchar.h>");
209 uwrite!(
210 self.src.h_helpers,
211 "
212 size_t {snake}_string_len(const char16_t* s);
213 ",
214 );
215 uwrite!(
216 self.src.c_helpers,
217 "
218 size_t {snake}_string_len(const char16_t* s) {{
219 char16_t* c = (char16_t*)s;
220 for (; *c; ++c);
221 return c-s;
222 }}
223 ",
224 );
225 (format!("{snake}_string_len(s)"), 2)
226 }
227 StringEncoding::CompactUTF16 => unimplemented!(),
228 };
229 let ty = self.char_type();
230 uwrite!(
231 self.src.h_helpers,
232 "
233 void {snake}_string_set({snake}_string_t *ret, const {ty} *s);
234 void {snake}_string_dup({snake}_string_t *ret, const {ty} *s);
235 void {snake}_string_free({snake}_string_t *ret);\
236 ",
237 );
238 uwrite!(
239 self.src.c_helpers,
240 "
241 void {snake}_string_set({snake}_string_t *ret, const {ty} *s) {{
242 ret->ptr = ({ty}*) s;
243 ret->len = {strlen};
244 }}
245
246 void {snake}_string_dup({snake}_string_t *ret, const {ty} *s) {{
247 ret->len = {strlen};
248 ret->ptr = cabi_realloc(NULL, 0, {size}, ret->len * {size});
249 memcpy(ret->ptr, s, ret->len * {size});
250 }}
251
252 void {snake}_string_free({snake}_string_t *ret) {{
253 if (ret->len > 0) {{
254 free(ret->ptr);
255 }}
256 ret->ptr = NULL;
257 ret->len = 0;
258 }}
259 ",
260 );
261 }
262
263 let mut h_str = wit_bindgen_core::Source::default();
264
265 uwrite!(
266 h_str,
267 "#ifndef __BINDINGS_{0}_H
268 #define __BINDINGS_{0}_H
269 #ifdef __cplusplus
270 extern \"C\" {{",
271 world.name.to_shouty_snake_case(),
272 );
273
274 h_str.deindent(1);
276 uwriteln!(h_str, "\n#endif\n");
277
278 self.include("<stdint.h>");
279 self.include("<stdbool.h>");
280
281 for include in self.includes.iter() {
282 uwriteln!(h_str, "#include {include}");
283 }
284
285 let mut c_str = wit_bindgen_core::Source::default();
286 uwriteln!(c_str, "#include \"{snake}.h\"");
287 if c_str.len() > 0 {
288 c_str.push_str("\n");
289 }
290 c_str.push_str(&self.src.c_defs);
291 c_str.push_str(&self.src.c_fns);
292
293 if self.needs_string {
294 uwriteln!(
295 h_str,
296 "
297 typedef struct {{\n\
298 {ty} *ptr;\n\
299 size_t len;\n\
300 }} {snake}_string_t;",
301 ty = self.char_type(),
302 );
303 }
304 if self.src.h_defs.len() > 0 {
305 h_str.push_str(&self.src.h_defs);
306 }
307
308 h_str.push_str(&self.src.h_fns);
309
310 if !self.opts.no_helpers && self.src.h_helpers.len() > 0 {
311 uwriteln!(h_str, "\n// Helper Functions");
312 h_str.push_str(&self.src.h_helpers);
313 h_str.push_str("\n");
314 }
315
316 if !self.opts.no_helpers && self.src.c_helpers.len() > 0 {
317 uwriteln!(c_str, "\n// Helper Functions");
318 c_str.push_str(self.src.c_helpers.as_mut_string());
319 }
320
321 uwriteln!(c_str, "\n// Component Adapters");
322
323 if self.return_pointer_area_size > 0 {
327 uwrite!(
329 c_str,
330 "
331 __attribute__((aligned({})))
332 static uint8_t RET_AREA[{}];
333 ",
334 self.return_pointer_area_align,
335 self.return_pointer_area_size,
336 );
337 }
338 c_str.push_str(&self.src.c_adapters);
339
340 uwriteln!(
341 h_str,
342 "
343 #ifdef __cplusplus
344 }}
345 #endif
346 #endif"
347 );
348
349 files.push(&format!("{snake}.c"), c_str.as_bytes());
350 files.push(&format!("{snake}.h"), h_str.as_bytes());
351 files.push(
352 &format!("{snake}_component_type.o",),
353 component_type_object::object(resolve, id, self.opts.string_encoding)
354 .unwrap()
355 .as_slice(),
356 );
357 }
358}
359
360impl C {
361 fn interface<'a>(
362 &'a mut self,
363 name: &'a str,
364 resolve: &'a Resolve,
365 in_import: bool,
366 ) -> InterfaceGenerator<'a> {
367 InterfaceGenerator {
368 name,
369 src: Source::default(),
370 gen: self,
371 resolve,
372 interface: None,
373 public_anonymous_types: Default::default(),
374 private_anonymous_types: Default::default(),
375 types: Default::default(),
376 in_import,
377 }
378 }
379
380 fn include(&mut self, s: &str) {
381 self.includes.push(s.to_string());
382 }
383
384 fn char_type(&self) -> &'static str {
385 match self.opts.string_encoding {
386 StringEncoding::UTF8 => "char",
387 StringEncoding::UTF16 => "char16_t",
388 StringEncoding::CompactUTF16 => panic!("Compact UTF16 unsupported"),
389 }
390 }
391}
392
393struct InterfaceGenerator<'a> {
394 name: &'a str,
395 src: Source,
396 in_import: bool,
397 gen: &'a mut C,
398 resolve: &'a Resolve,
399 interface: Option<InterfaceId>,
400
401 public_anonymous_types: BTreeSet<TypeId>,
405
406 private_anonymous_types: BTreeSet<TypeId>,
411
412 types: HashMap<TypeId, wit_bindgen_core::Source>,
415}
416
417impl C {
418 fn print_intrinsics(&mut self) {
419 self.src.c_fns(
422 r#"
423 __attribute__((weak, export_name("cabi_realloc")))
424 void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
425 if (new_size == 0) return (void*) align;
426 void *ret = realloc(ptr, new_size);
427 if (!ret) abort();
428 return ret;
429 }
430 "#,
431 );
432 }
433}
434
435impl Return {
436 fn return_single(&mut self, resolve: &Resolve, ty: &Type, orig_ty: &Type) {
437 let id = match ty {
438 Type::Id(id) => *id,
439 Type::String => {
440 self.retptrs.push(*orig_ty);
441 return;
442 }
443 _ => {
444 self.scalar = Some(Scalar::Type(*orig_ty));
445 return;
446 }
447 };
448 match &resolve.types[id].kind {
449 TypeDefKind::Type(t) => return self.return_single(resolve, t, orig_ty),
450
451 TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => {
453 self.scalar = Some(Scalar::Type(*orig_ty));
454 return;
455 }
456
457 TypeDefKind::Option(ty) => {
461 self.scalar = Some(Scalar::OptionBool(*ty));
462 self.retptrs.push(*ty);
463 return;
464 }
465
466 TypeDefKind::Result(r) => {
469 if let Some(ok) = r.ok {
470 self.retptrs.push(ok);
471 }
472 if let Some(err) = r.err {
473 self.retptrs.push(err);
474 }
475 self.scalar = Some(Scalar::ResultBool(r.ok, r.err));
476 return;
477 }
478
479 TypeDefKind::Tuple(_)
481 | TypeDefKind::Record(_)
482 | TypeDefKind::List(_)
483 | TypeDefKind::Variant(_)
484 | TypeDefKind::Union(_) => {}
485
486 TypeDefKind::Future(_) => todo!("return_single for future"),
487 TypeDefKind::Stream(_) => todo!("return_single for stream"),
488 TypeDefKind::Unknown => unreachable!(),
489 }
490
491 self.retptrs.push(*orig_ty);
492 }
493}
494
495impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
496 fn resolve(&self) -> &'a Resolve {
497 self.resolve
498 }
499
500 fn type_record(&mut self, id: TypeId, name: &str, record: &Record, docs: &Docs) {
501 let prev = mem::take(&mut self.src.h_defs);
502 self.src.h_defs("\n");
503 self.docs(docs);
504 self.src.h_defs("typedef struct {\n");
505 for field in record.fields.iter() {
506 self.print_ty(SourceType::HDefs, &field.ty);
507 self.src.h_defs(" ");
508 self.src.h_defs(&to_c_ident(&field.name));
509 self.src.h_defs(";\n");
510 }
511 self.src.h_defs("} ");
512 self.print_typedef_target(name);
513
514 self.types
515 .insert(id, mem::replace(&mut self.src.h_defs, prev));
516 }
517
518 fn type_tuple(&mut self, id: TypeId, name: &str, tuple: &Tuple, docs: &Docs) {
519 let prev = mem::take(&mut self.src.h_defs);
520 self.src.h_defs("\n");
521 self.docs(docs);
522 self.src.h_defs("typedef struct {\n");
523 for (i, ty) in tuple.types.iter().enumerate() {
524 self.print_ty(SourceType::HDefs, ty);
525 uwriteln!(self.src.h_defs, " f{i};");
526 }
527 self.src.h_defs("} ");
528 self.print_typedef_target(name);
529
530 self.types
531 .insert(id, mem::replace(&mut self.src.h_defs, prev));
532 }
533
534 fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
535 let prev = mem::take(&mut self.src.h_defs);
536 self.src.h_defs("\n");
537 self.docs(docs);
538 self.src.h_defs("typedef ");
539 let repr = flags_repr(flags);
540 self.src.h_defs(int_repr(repr));
541 self.src.h_defs(" ");
542 self.print_typedef_target(name);
543
544 if flags.flags.len() > 0 {
545 self.src.h_defs("\n");
546 }
547 for (i, flag) in flags.flags.iter().enumerate() {
548 uwriteln!(
549 self.src.h_defs,
550 "#define {}_{}_{} (1 << {})",
551 self.name.to_shouty_snake_case(),
552 name.to_shouty_snake_case(),
553 flag.name.to_shouty_snake_case(),
554 i,
555 );
556 }
557
558 self.types
559 .insert(id, mem::replace(&mut self.src.h_defs, prev));
560 }
561
562 fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs) {
563 let prev = mem::take(&mut self.src.h_defs);
564 self.src.h_defs("\n");
565 self.docs(docs);
566 self.src.h_defs("typedef struct {\n");
567 self.src.h_defs(int_repr(variant.tag()));
568 self.src.h_defs(" tag;\n");
569 self.src.h_defs("union {\n");
570 for case in variant.cases.iter() {
571 if let Some(ty) = self.get_nonempty_type(case.ty.as_ref()) {
572 self.print_ty(SourceType::HDefs, ty);
573 self.src.h_defs(" ");
574 self.src.h_defs(&to_c_ident(&case.name));
575 self.src.h_defs(";\n");
576 }
577 }
578 self.src.h_defs("} val;\n");
579 self.src.h_defs("} ");
580 self.print_typedef_target(name);
581
582 if variant.cases.len() > 0 {
583 self.src.h_defs("\n");
584 }
585 for (i, case) in variant.cases.iter().enumerate() {
586 uwriteln!(
587 self.src.h_defs,
588 "#define {}_{}_{} {}",
589 self.name.to_shouty_snake_case(),
590 name.to_shouty_snake_case(),
591 case.name.to_shouty_snake_case(),
592 i,
593 );
594 }
595
596 self.types
597 .insert(id, mem::replace(&mut self.src.h_defs, prev));
598 }
599
600 fn type_union(&mut self, id: TypeId, name: &str, union: &Union, docs: &Docs) {
601 let prev = mem::take(&mut self.src.h_defs);
602 self.src.h_defs("\n");
603 self.docs(docs);
604 self.src.h_defs("typedef struct {\n");
605 self.src.h_defs(int_repr(union.tag()));
606 self.src.h_defs(" tag;\n");
607 self.src.h_defs("union {\n");
608 for (i, case) in union.cases.iter().enumerate() {
609 self.print_ty(SourceType::HDefs, &case.ty);
610 uwriteln!(self.src.h_defs, " f{i};");
611 }
612 self.src.h_defs("} val;\n");
613 self.src.h_defs("} ");
614 self.print_typedef_target(name);
615
616 self.types
617 .insert(id, mem::replace(&mut self.src.h_defs, prev));
618 }
619
620 fn type_option(&mut self, id: TypeId, name: &str, payload: &Type, docs: &Docs) {
621 let prev = mem::take(&mut self.src.h_defs);
622 self.src.h_defs("\n");
623 self.docs(docs);
624 self.src.h_defs("typedef struct {\n");
625 self.src.h_defs("bool is_some;\n");
626 if !self.is_empty_type(payload) {
627 self.print_ty(SourceType::HDefs, payload);
628 self.src.h_defs(" val;\n");
629 }
630 self.src.h_defs("} ");
631 self.print_typedef_target(name);
632
633 self.types
634 .insert(id, mem::replace(&mut self.src.h_defs, prev));
635 }
636
637 fn type_result(&mut self, id: TypeId, name: &str, result: &Result_, docs: &Docs) {
638 let prev = mem::take(&mut self.src.h_defs);
639 self.src.h_defs("\n");
640 self.docs(docs);
641 self.src.h_defs("typedef struct {\n");
642 self.src.h_defs("bool is_err;\n");
643 self.src.h_defs("union {\n");
644 if let Some(ok) = self.get_nonempty_type(result.ok.as_ref()) {
645 self.print_ty(SourceType::HDefs, ok);
646 self.src.h_defs(" ok;\n");
647 }
648 if let Some(err) = self.get_nonempty_type(result.err.as_ref()) {
649 self.print_ty(SourceType::HDefs, err);
650 self.src.h_defs(" err;\n");
651 }
652 self.src.h_defs("} val;\n");
653 self.src.h_defs("} ");
654 self.print_typedef_target(name);
655
656 self.types
657 .insert(id, mem::replace(&mut self.src.h_defs, prev));
658 }
659
660 fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
661 let prev = mem::take(&mut self.src.h_defs);
662 uwrite!(self.src.h_defs, "\n");
663 self.docs(docs);
664 let int_t = int_repr(enum_.tag());
665 uwrite!(self.src.h_defs, "typedef {int_t} ");
666 self.print_typedef_target(name);
667
668 if enum_.cases.len() > 0 {
669 self.src.h_defs("\n");
670 }
671 for (i, case) in enum_.cases.iter().enumerate() {
672 uwriteln!(
673 self.src.h_defs,
674 "#define {}_{}_{} {}",
675 self.name.to_shouty_snake_case(),
676 name.to_shouty_snake_case(),
677 case.name.to_shouty_snake_case(),
678 i,
679 );
680 }
681
682 self.types
683 .insert(id, mem::replace(&mut self.src.h_defs, prev));
684 }
685
686 fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
687 let prev = mem::take(&mut self.src.h_defs);
688 self.src.h_defs("\n");
689 self.docs(docs);
690 self.src.h_defs("typedef ");
691 self.print_ty(SourceType::HDefs, ty);
692 self.src.h_defs(" ");
693 self.print_typedef_target(name);
694 self.types
695 .insert(id, mem::replace(&mut self.src.h_defs, prev));
696 }
697
698 fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
699 let prev = mem::take(&mut self.src.h_defs);
700 self.src.h_defs("\n");
701 self.docs(docs);
702 self.src.h_defs("typedef struct {\n");
703 self.print_ty(SourceType::HDefs, ty);
704 self.src.h_defs(" *ptr;\n");
705 self.src.h_defs("size_t len;\n");
706 self.src.h_defs("} ");
707 self.print_typedef_target(name);
708 self.types
709 .insert(id, mem::replace(&mut self.src.h_defs, prev));
710 }
711
712 fn type_builtin(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
713 drop((_id, name, ty, docs));
714 }
715}
716
717impl InterfaceGenerator<'_> {
718 fn import(&mut self, wasm_import_module: &str, func: &Function) {
719 let sig = self.resolve.wasm_signature(AbiVariant::GuestImport, func);
720
721 self.src.c_fns("\n");
722
723 uwriteln!(
727 self.src.c_fns,
728 "__attribute__((import_module(\"{}\"), import_name(\"{}\")))",
729 wasm_import_module,
730 func.name
731 );
732 let import_name = self.gen.names.tmp(&format!(
733 "__wasm_import_{}_{}",
734 self.name.to_snake_case(),
735 func.name.to_snake_case()
736 ));
737 match sig.results.len() {
738 0 => self.src.c_fns("void"),
739 1 => self.src.c_fns(wasm_type(sig.results[0])),
740 _ => unimplemented!("multi-value return not supported"),
741 }
742 self.src.c_fns(" ");
743 self.src.c_fns(&import_name);
744 self.src.c_fns("(");
745 for (i, param) in sig.params.iter().enumerate() {
746 if i > 0 {
747 self.src.c_fns(", ");
748 }
749 self.src.c_fns(wasm_type(*param));
750 }
751 if sig.params.len() == 0 {
752 self.src.c_fns("void");
753 }
754 self.src.c_fns(");\n");
755
756 let c_sig = self.print_sig(func);
759 self.src.c_adapters("\n");
760 self.src.c_adapters(&c_sig.sig);
761 self.src.c_adapters(" {\n");
762
763 let mut optional_adapters = String::from("");
766 for (i, (_, param)) in c_sig.params.iter().enumerate() {
767 let ty = &func.params[i].1;
768 if let Type::Id(id) = ty {
769 if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
770 let ty = self.type_string(ty);
771 uwrite!(
772 optional_adapters,
773 "{ty} {param};
774 {param}.is_some = maybe_{param} != NULL;"
775 );
776 if !self.is_empty_type(option_ty) {
777 uwriteln!(
778 optional_adapters,
779 "if (maybe_{param}) {{
780 {param}.val = *maybe_{param};
781 }}",
782 );
783 }
784 }
785 }
786 }
787
788 let mut f = FunctionBindgen::new(self, c_sig, &import_name);
789 for (pointer, param) in f.sig.params.iter() {
790 f.locals.insert(¶m).unwrap();
791 if *pointer {
792 f.params.push(format!("*{}", param));
793 } else {
794 f.params.push(param.clone());
795 }
796 }
797 for ptr in f.sig.retptrs.iter() {
798 f.locals.insert(ptr).unwrap();
799 }
800 f.src.push_str(&optional_adapters);
801 f.gen.resolve.call(
802 AbiVariant::GuestImport,
803 LiftLower::LowerArgsLiftResults,
804 func,
805 &mut f,
806 );
807
808 let FunctionBindgen {
809 src,
810 import_return_pointer_area_size,
811 import_return_pointer_area_align,
812 ..
813 } = f;
814
815 if import_return_pointer_area_size > 0 {
816 self.src.c_adapters(&format!(
817 "\
818 __attribute__((aligned({import_return_pointer_area_align})))
819 uint8_t ret_area[{import_return_pointer_area_size}];
820 ",
821 ));
822 }
823
824 self.src.c_adapters(&String::from(src));
825 self.src.c_adapters("}\n");
826 }
827
828 fn export(&mut self, func: &Function, interface_name: Option<&str>) {
829 let sig = self.resolve.wasm_signature(AbiVariant::GuestExport, func);
830
831 let export_name = func.core_export_name(interface_name);
832
833 let h_sig = self.print_sig(func);
836
837 uwriteln!(
840 self.src.c_adapters,
841 "\n__attribute__((export_name(\"{export_name}\")))"
842 );
843 let import_name = self.gen.names.tmp(&format!(
844 "__wasm_export_{}_{}",
845 self.name.to_snake_case(),
846 func.name.to_snake_case()
847 ));
848
849 let mut f = FunctionBindgen::new(self, h_sig, &import_name);
850 match sig.results.len() {
851 0 => f.gen.src.c_adapters("void"),
852 1 => f.gen.src.c_adapters(wasm_type(sig.results[0])),
853 _ => unimplemented!("multi-value return not supported"),
854 }
855 f.gen.src.c_adapters(" ");
856 f.gen.src.c_adapters(&import_name);
857 f.gen.src.c_adapters("(");
858 for (i, param) in sig.params.iter().enumerate() {
859 if i > 0 {
860 f.gen.src.c_adapters(", ");
861 }
862 let name = f.locals.tmp("arg");
863 uwrite!(f.gen.src.c_adapters, "{} {}", wasm_type(*param), name);
864 f.params.push(name);
865 }
866 if sig.params.len() == 0 {
867 f.gen.src.c_adapters("void");
868 }
869 f.gen.src.c_adapters(") {\n");
870
871 f.gen.resolve.call(
873 AbiVariant::GuestExport,
874 LiftLower::LiftArgsLowerResults,
875 func,
876 &mut f,
877 );
878 let FunctionBindgen { src, .. } = f;
879 self.src.c_adapters(&src);
880 self.src.c_adapters("}\n");
881
882 if self.resolve.guest_export_needs_post_return(func) {
883 uwriteln!(
884 self.src.c_fns,
885 "__attribute__((weak, export_name(\"cabi_post_{export_name}\")))"
886 );
887 uwrite!(self.src.c_fns, "void {import_name}_post_return(");
888
889 let mut params = Vec::new();
890 let mut c_sig = CSig {
891 name: String::from("INVALID"),
892 sig: String::from("INVALID"),
893 params: Vec::new(),
894 ret: Return::default(),
895 retptrs: Vec::new(),
896 };
897 for (i, result) in sig.results.iter().enumerate() {
898 let name = format!("arg{i}");
899 uwrite!(self.src.c_fns, "{} {name}", wasm_type(*result));
900 c_sig.params.push((false, name.clone()));
901 params.push(name);
902 }
903 self.src.c_fns.push_str(") {\n");
904
905 let mut f = FunctionBindgen::new(self, c_sig, &import_name);
906 f.params = params;
907 f.gen.resolve.post_return(func, &mut f);
908 let FunctionBindgen { src, .. } = f;
909 self.src.c_fns(&src);
910 self.src.c_fns("}\n");
911 }
912 }
913
914 fn finish(&mut self) {
915 while !self.public_anonymous_types.is_empty() {
921 for ty in mem::take(&mut self.public_anonymous_types) {
922 self.print_anonymous_type(ty);
923 }
924 }
925
926 let mut private_types = HashSet::new();
934 self.public_anonymous_types = mem::take(&mut self.private_anonymous_types);
935 while !self.public_anonymous_types.is_empty() {
936 for ty in mem::take(&mut self.public_anonymous_types) {
937 if self.types.contains_key(&ty) {
938 continue;
939 }
940 private_types.insert(ty);
941 self.print_anonymous_type(ty);
942 }
943 }
944
945 for (id, _) in self.resolve.types.iter() {
946 if let Some(ty) = self.types.get(&id) {
947 if private_types.contains(&id) {
948 self.src.c_defs(ty);
950 } else {
951 self.src.h_defs(ty);
953 self.print_dtor(id);
954 }
955 }
956 }
957 }
958
959 fn print_sig(&mut self, func: &Function) -> CSig {
960 let name = format!(
961 "{}_{}",
962 self.name.to_snake_case(),
963 func.name.to_snake_case()
964 );
965 self.gen.names.insert(&name).expect("duplicate symbols");
966
967 let start = self.src.h_fns.len();
968 let mut result_rets = false;
969 let mut result_rets_has_ok_type = false;
970
971 let ret = self.classify_ret(func);
972 match &ret.scalar {
973 None | Some(Scalar::Void) => self.src.h_fns("void"),
974 Some(Scalar::OptionBool(_id)) => self.src.h_fns("bool"),
975 Some(Scalar::ResultBool(ok, _err)) => {
976 result_rets = true;
977 result_rets_has_ok_type = ok.is_some();
978 self.src.h_fns("bool");
979 }
980 Some(Scalar::Type(ty)) => self.print_ty(SourceType::HFns, ty),
981 }
982 self.src.h_fns(" ");
983 self.src.h_fns(&name);
984 self.src.h_fns("(");
985 let mut params = Vec::new();
986 for (i, (name, ty)) in func.params.iter().enumerate() {
987 if i > 0 {
988 self.src.h_fns(", ");
989 }
990 let pointer = self.is_arg_by_pointer(ty);
991 let optional_type = if let Type::Id(id) = ty {
993 if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
994 Some(option_ty)
995 } else {
996 None
997 }
998 } else {
999 None
1000 };
1001 let (print_ty, print_name) = if let Some(option_ty) = optional_type {
1002 (option_ty, format!("maybe_{}", to_c_ident(name)))
1003 } else {
1004 (ty, to_c_ident(name))
1005 };
1006 self.print_ty(SourceType::HFns, print_ty);
1007 self.src.h_fns(" ");
1008 if pointer {
1009 self.src.h_fns("*");
1010 }
1011 self.src.h_fns(&print_name);
1012 params.push((optional_type.is_none() && pointer, to_c_ident(name)));
1013 }
1014 let mut retptrs = Vec::new();
1015 let single_ret = ret.retptrs.len() == 1;
1016 for (i, ty) in ret.retptrs.iter().enumerate() {
1017 if i > 0 || func.params.len() > 0 {
1018 self.src.h_fns(", ");
1019 }
1020 self.print_ty(SourceType::HFns, ty);
1021 self.src.h_fns(" *");
1022 let name: String = if result_rets {
1023 assert!(i <= 1);
1024 if i == 0 && result_rets_has_ok_type {
1025 "ret".into()
1026 } else {
1027 "err".into()
1028 }
1029 } else if single_ret {
1030 "ret".into()
1031 } else {
1032 format!("ret{}", i)
1033 };
1034 self.src.h_fns(&name);
1035 retptrs.push(name);
1036 }
1037 if func.params.len() == 0 && ret.retptrs.len() == 0 {
1038 self.src.h_fns("void");
1039 }
1040 self.src.h_fns(")");
1041
1042 let sig = self.src.h_fns[start..].to_string();
1043 self.src.h_fns(";\n");
1044
1045 CSig {
1046 sig,
1047 name,
1048 params,
1049 ret,
1050 retptrs,
1051 }
1052 }
1053
1054 fn classify_ret(&mut self, func: &Function) -> Return {
1055 let mut ret = Return::default();
1056 match func.results.len() {
1057 0 => ret.scalar = Some(Scalar::Void),
1058 1 => {
1059 let ty = func.results.iter_types().next().unwrap();
1060 ret.return_single(self.resolve, ty, ty);
1061 }
1062 _ => {
1063 ret.retptrs.extend(func.results.iter_types().cloned());
1064 }
1065 }
1066 return ret;
1067 }
1068
1069 fn is_arg_by_pointer(&self, ty: &Type) -> bool {
1070 match ty {
1071 Type::Id(id) => match &self.resolve.types[*id].kind {
1072 TypeDefKind::Type(t) => self.is_arg_by_pointer(t),
1073 TypeDefKind::Variant(_) => true,
1074 TypeDefKind::Union(_) => true,
1075 TypeDefKind::Option(_) => true,
1076 TypeDefKind::Result(_) => true,
1077 TypeDefKind::Enum(_) => false,
1078 TypeDefKind::Flags(_) => false,
1079 TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
1080 TypeDefKind::Future(_) => todo!("is_arg_by_pointer for future"),
1081 TypeDefKind::Stream(_) => todo!("is_arg_by_pointer for stream"),
1082 TypeDefKind::Unknown => unreachable!(),
1083 },
1084 Type::String => true,
1085 _ => false,
1086 }
1087 }
1088
1089 fn print_typedef_target(&mut self, name: &str) {
1090 let iface_snake = self.name.to_snake_case();
1091 let snake = name.to_snake_case();
1092 self.print_namespace(SourceType::HDefs);
1093 self.src.h_defs(&snake);
1094 self.src.h_defs("_t;\n");
1095 self.gen
1096 .names
1097 .insert(&format!("{iface_snake}_{snake}_t"))
1098 .unwrap();
1099 }
1100
1101 fn print_namespace(&mut self, stype: SourceType) {
1102 self.src.print(stype, &self.name.to_snake_case());
1103 self.src.print(stype, "_");
1104 }
1105
1106 fn print_ty(&mut self, stype: SourceType, ty: &Type) {
1107 match ty {
1108 Type::Bool => self.src.print(stype, "bool"),
1109 Type::Char => self.src.print(stype, "uint32_t"), Type::U8 => self.src.print(stype, "uint8_t"),
1111 Type::S8 => self.src.print(stype, "int8_t"),
1112 Type::U16 => self.src.print(stype, "uint16_t"),
1113 Type::S16 => self.src.print(stype, "int16_t"),
1114 Type::U32 => self.src.print(stype, "uint32_t"),
1115 Type::S32 => self.src.print(stype, "int32_t"),
1116 Type::U64 => self.src.print(stype, "uint64_t"),
1117 Type::S64 => self.src.print(stype, "int64_t"),
1118 Type::Float32 => self.src.print(stype, "float"),
1119 Type::Float64 => self.src.print(stype, "double"),
1120 Type::String => {
1121 self.src.print(stype, &self.gen.world.to_snake_case());
1122 self.src.print(stype, "_");
1123 self.src.print(stype, "string_t");
1124 self.gen.needs_string = true;
1125 }
1126 Type::Id(id) => {
1127 let ty = &self.resolve.types[*id];
1128 match &ty.name {
1129 Some(name) => {
1130 match ty.owner {
1131 TypeOwner::Interface(owner) => {
1132 self.src.print(
1133 stype,
1134 &self.gen.interface_names[&owner].to_snake_case(),
1135 );
1136 self.src.print(stype, "_");
1137 }
1138 TypeOwner::World(owner) => {
1139 self.src
1140 .print(stype, &self.resolve.worlds[owner].name.to_snake_case());
1141 self.src.print(stype, "_");
1142 }
1143 TypeOwner::None => {}
1144 }
1145
1146 self.src.print(stype, &name.to_snake_case());
1147 self.src.print(stype, "_t");
1148 }
1149 None => match &ty.kind {
1150 TypeDefKind::Type(t) => self.print_ty(stype, t),
1151 _ => {
1152 self.public_anonymous_types.insert(*id);
1153 self.private_anonymous_types.remove(id);
1154 self.print_namespace(stype);
1155 self.print_ty_name(stype, &Type::Id(*id));
1156 self.src.print(stype, "_t");
1157 }
1158 },
1159 }
1160 }
1161 }
1162 }
1163
1164 fn print_ty_name(&mut self, stype: SourceType, ty: &Type) {
1165 match ty {
1166 Type::Bool => self.src.print(stype, "bool"),
1167 Type::Char => self.src.print(stype, "char32"),
1168 Type::U8 => self.src.print(stype, "u8"),
1169 Type::S8 => self.src.print(stype, "s8"),
1170 Type::U16 => self.src.print(stype, "u16"),
1171 Type::S16 => self.src.print(stype, "s16"),
1172 Type::U32 => self.src.print(stype, "u32"),
1173 Type::S32 => self.src.print(stype, "s32"),
1174 Type::U64 => self.src.print(stype, "u64"),
1175 Type::S64 => self.src.print(stype, "s64"),
1176 Type::Float32 => self.src.print(stype, "float32"),
1177 Type::Float64 => self.src.print(stype, "float64"),
1178 Type::String => self.src.print(stype, "string"),
1179 Type::Id(id) => {
1180 let ty = &self.resolve.types[*id];
1181 if let Some(name) = &ty.name {
1182 return self.src.print(stype, &name.to_snake_case());
1183 }
1184 match &ty.kind {
1185 TypeDefKind::Type(t) => self.print_ty_name(stype, t),
1186 TypeDefKind::Record(_)
1187 | TypeDefKind::Flags(_)
1188 | TypeDefKind::Enum(_)
1189 | TypeDefKind::Variant(_)
1190 | TypeDefKind::Union(_) => {
1191 unimplemented!()
1192 }
1193 TypeDefKind::Tuple(t) => {
1194 self.src.print(stype, "tuple");
1195 self.src.print(stype, &t.types.len().to_string());
1196 for ty in t.types.iter() {
1197 self.src.print(stype, "_");
1198 self.print_ty_name(stype, ty);
1199 }
1200 }
1201 TypeDefKind::Option(ty) => {
1202 self.src.print(stype, "option_");
1203 self.print_ty_name(stype, ty);
1204 }
1205 TypeDefKind::Result(r) => {
1206 self.src.print(stype, "result_");
1207 self.print_optional_ty_name(stype, r.ok.as_ref());
1208 self.src.print(stype, "_");
1209 self.print_optional_ty_name(stype, r.err.as_ref());
1210 }
1211 TypeDefKind::List(t) => {
1212 self.src.print(stype, "list_");
1213 self.print_ty_name(stype, t);
1214 }
1215 TypeDefKind::Future(t) => {
1216 self.src.print(stype, "future_");
1217 self.print_optional_ty_name(stype, t.as_ref());
1218 }
1219 TypeDefKind::Stream(s) => {
1220 self.src.print(stype, "stream_");
1221 self.print_optional_ty_name(stype, s.element.as_ref());
1222 self.src.print(stype, "_");
1223 self.print_optional_ty_name(stype, s.end.as_ref());
1224 }
1225 TypeDefKind::Unknown => unreachable!(),
1226 }
1227 }
1228 }
1229 }
1230
1231 fn print_optional_ty_name(&mut self, stype: SourceType, ty: Option<&Type>) {
1232 match ty {
1233 Some(ty) => self.print_ty_name(stype, ty),
1234 None => self.src.print(stype, "void"),
1235 }
1236 }
1237
1238 fn docs(&mut self, docs: &Docs) {
1239 let docs = match &docs.contents {
1240 Some(docs) => docs,
1241 None => return,
1242 };
1243 for line in docs.trim().lines() {
1244 self.src.h_defs("// ");
1245 self.src.h_defs(line);
1246 self.src.h_defs("\n");
1247 }
1248 }
1249
1250 fn is_empty_type(&self, ty: &Type) -> bool {
1251 let id = match ty {
1252 Type::Id(id) => *id,
1253 _ => return false,
1254 };
1255 match &self.resolve.types[id].kind {
1256 TypeDefKind::Type(t) => self.is_empty_type(t),
1257 TypeDefKind::Record(r) => r.fields.is_empty(),
1258 TypeDefKind::Tuple(t) => t.types.is_empty(),
1259 _ => false,
1260 }
1261 }
1262
1263 fn get_nonempty_type<'o>(&self, ty: Option<&'o Type>) -> Option<&'o Type> {
1264 match ty {
1265 Some(ty) => {
1266 if self.is_empty_type(ty) {
1267 None
1268 } else {
1269 Some(ty)
1270 }
1271 }
1272 None => None,
1273 }
1274 }
1275
1276 fn type_string(&mut self, ty: &Type) -> String {
1277 let prev = mem::take(&mut self.src.h_defs);
1283 let prev_public = mem::take(&mut self.public_anonymous_types);
1284 let prev_private = mem::take(&mut self.private_anonymous_types);
1285
1286 self.print_ty(SourceType::HDefs, ty);
1289
1290 let new_private = mem::replace(&mut self.public_anonymous_types, prev_public);
1295 assert!(self.private_anonymous_types.is_empty());
1296 self.private_anonymous_types = prev_private;
1297
1298 for id in new_private {
1301 if !self.public_anonymous_types.contains(&id) {
1302 self.private_anonymous_types.insert(id);
1303 }
1304 }
1305
1306 mem::replace(&mut self.src.h_defs, prev).into()
1307 }
1308
1309 fn print_anonymous_type(&mut self, ty: TypeId) {
1310 let prev = mem::take(&mut self.src.h_defs);
1311 self.src.h_defs("\ntypedef ");
1312 let kind = &self.resolve.types[ty].kind;
1313 match kind {
1314 TypeDefKind::Type(_)
1315 | TypeDefKind::Flags(_)
1316 | TypeDefKind::Record(_)
1317 | TypeDefKind::Enum(_)
1318 | TypeDefKind::Variant(_)
1319 | TypeDefKind::Union(_) => {
1320 unreachable!()
1321 }
1322 TypeDefKind::Tuple(t) => {
1323 self.src.h_defs("struct {\n");
1324 for (i, t) in t.types.iter().enumerate() {
1325 self.print_ty(SourceType::HDefs, t);
1326 uwriteln!(self.src.h_defs, " f{i};");
1327 }
1328 self.src.h_defs("}");
1329 }
1330 TypeDefKind::Option(t) => {
1331 self.src.h_defs("struct {\n");
1332 self.src.h_defs("bool is_some;\n");
1333 if !self.is_empty_type(t) {
1334 self.print_ty(SourceType::HDefs, t);
1335 self.src.h_defs(" val;\n");
1336 }
1337 self.src.h_defs("}");
1338 }
1339 TypeDefKind::Result(r) => {
1340 self.src.h_defs(
1341 "struct {
1342 bool is_err;
1343 union {
1344 ",
1345 );
1346 if let Some(ok) = self.get_nonempty_type(r.ok.as_ref()) {
1347 self.print_ty(SourceType::HDefs, ok);
1348 self.src.h_defs(" ok;\n");
1349 }
1350 if let Some(err) = self.get_nonempty_type(r.err.as_ref()) {
1351 self.print_ty(SourceType::HDefs, err);
1352 self.src.h_defs(" err;\n");
1353 }
1354 self.src.h_defs("} val;\n");
1355 self.src.h_defs("}");
1356 }
1357 TypeDefKind::List(t) => {
1358 self.src.h_defs("struct {\n");
1359 self.print_ty(SourceType::HDefs, t);
1360 self.src.h_defs(" *ptr;\n");
1361 self.src.h_defs("size_t len;\n");
1362 self.src.h_defs("}");
1363 }
1364 TypeDefKind::Future(_) => todo!("print_anonymous_type for future"),
1365 TypeDefKind::Stream(_) => todo!("print_anonymous_type for stream"),
1366 TypeDefKind::Unknown => unreachable!(),
1367 }
1368 self.src.h_defs(" ");
1369 self.print_namespace(SourceType::HDefs);
1370 self.print_ty_name(SourceType::HDefs, &Type::Id(ty));
1371 self.src.h_defs("_t;\n");
1372 let type_source = mem::replace(&mut self.src.h_defs, prev);
1373 self.types.insert(ty, type_source);
1374 }
1375
1376 fn print_dtor(&mut self, id: TypeId) {
1377 let ty = Type::Id(id);
1378 if !self.owns_anything(&ty) {
1379 return;
1380 }
1381 let pos = self.src.h_helpers.len();
1382 self.src.h_helpers("\nvoid ");
1383 self.print_namespace(SourceType::HHelpers);
1384 self.print_ty_name(SourceType::HHelpers, &ty);
1385 self.src.h_helpers("_free(");
1386 self.print_namespace(SourceType::HHelpers);
1387 self.print_ty_name(SourceType::HHelpers, &ty);
1388 self.src.h_helpers("_t *ptr)");
1389
1390 self.src.c_helpers(&self.src.h_helpers[pos..].to_string());
1391 self.src.h_helpers(";");
1392 self.src.c_helpers(" {\n");
1393 match &self.resolve.types[id].kind {
1394 TypeDefKind::Type(t) => self.free(t, "ptr"),
1395
1396 TypeDefKind::Flags(_) => {}
1397 TypeDefKind::Enum(_) => {}
1398
1399 TypeDefKind::Record(r) => {
1400 for field in r.fields.iter() {
1401 if !self.owns_anything(&field.ty) {
1402 continue;
1403 }
1404 self.free(&field.ty, &format!("&ptr->{}", to_c_ident(&field.name)));
1405 }
1406 }
1407
1408 TypeDefKind::Tuple(t) => {
1409 for (i, ty) in t.types.iter().enumerate() {
1410 if !self.owns_anything(ty) {
1411 continue;
1412 }
1413 self.free(ty, &format!("&ptr->f{i}"));
1414 }
1415 }
1416
1417 TypeDefKind::List(t) => {
1418 if self.owns_anything(t) {
1419 self.src
1420 .c_helpers("for (size_t i = 0; i < ptr->len; i++) {\n");
1421 self.free(t, "&ptr->ptr[i]");
1422 self.src.c_helpers("}\n");
1423 }
1424 uwriteln!(self.src.c_helpers, "if (ptr->len > 0) {{");
1425 uwriteln!(self.src.c_helpers, "free(ptr->ptr);");
1426 uwriteln!(self.src.c_helpers, "}}");
1427 }
1428
1429 TypeDefKind::Variant(v) => {
1430 self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
1431 for (i, case) in v.cases.iter().enumerate() {
1432 if let Some(ty) = &case.ty {
1433 if !self.owns_anything(ty) {
1434 continue;
1435 }
1436 uwriteln!(self.src.c_helpers, "case {}: {{", i);
1437 let expr = format!("&ptr->val.{}", to_c_ident(&case.name));
1438 if let Some(ty) = &case.ty {
1439 self.free(ty, &expr);
1440 }
1441 self.src.c_helpers("break;\n");
1442 self.src.c_helpers("}\n");
1443 }
1444 }
1445 self.src.c_helpers("}\n");
1446 }
1447
1448 TypeDefKind::Union(u) => {
1449 self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
1450 for (i, case) in u.cases.iter().enumerate() {
1451 if !self.owns_anything(&case.ty) {
1452 continue;
1453 }
1454 uwriteln!(self.src.c_helpers, "case {i}: {{");
1455 let expr = format!("&ptr->val.f{i}");
1456 self.free(&case.ty, &expr);
1457 self.src.c_helpers("break;\n");
1458 self.src.c_helpers("}\n");
1459 }
1460 self.src.c_helpers("}\n");
1461 }
1462
1463 TypeDefKind::Option(t) => {
1464 self.src.c_helpers("if (ptr->is_some) {\n");
1465 self.free(t, "&ptr->val");
1466 self.src.c_helpers("}\n");
1467 }
1468
1469 TypeDefKind::Result(r) => {
1470 self.src.c_helpers("if (!ptr->is_err) {\n");
1471 if let Some(ok) = &r.ok {
1472 if self.owns_anything(ok) {
1473 self.free(ok, "&ptr->val.ok");
1474 }
1475 }
1476 if let Some(err) = &r.err {
1477 if self.owns_anything(err) {
1478 self.src.c_helpers("} else {\n");
1479 self.free(err, "&ptr->val.err");
1480 }
1481 }
1482 self.src.c_helpers("}\n");
1483 }
1484 TypeDefKind::Future(_) => todo!("print_dtor for future"),
1485 TypeDefKind::Stream(_) => todo!("print_dtor for stream"),
1486 TypeDefKind::Unknown => unreachable!(),
1487 }
1488 self.src.c_helpers("}\n");
1489 }
1490
1491 fn owns_anything(&self, ty: &Type) -> bool {
1492 let id = match ty {
1493 Type::Id(id) => *id,
1494 Type::String => return true,
1495 _ => return false,
1496 };
1497 match &self.resolve.types[id].kind {
1498 TypeDefKind::Type(t) => self.owns_anything(t),
1499 TypeDefKind::Record(r) => r.fields.iter().any(|t| self.owns_anything(&t.ty)),
1500 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.owns_anything(t)),
1501 TypeDefKind::Flags(_) => false,
1502 TypeDefKind::Enum(_) => false,
1503 TypeDefKind::List(_) => true,
1504 TypeDefKind::Variant(v) => v
1505 .cases
1506 .iter()
1507 .any(|c| self.optional_owns_anything(c.ty.as_ref())),
1508 TypeDefKind::Union(v) => v.cases.iter().any(|case| self.owns_anything(&case.ty)),
1509 TypeDefKind::Option(t) => self.owns_anything(t),
1510 TypeDefKind::Result(r) => {
1511 self.optional_owns_anything(r.ok.as_ref())
1512 || self.optional_owns_anything(r.err.as_ref())
1513 }
1514 TypeDefKind::Future(_) => todo!("owns_anything for future"),
1515 TypeDefKind::Stream(_) => todo!("owns_anything for stream"),
1516 TypeDefKind::Unknown => unreachable!(),
1517 }
1518 }
1519
1520 fn optional_owns_anything(&self, ty: Option<&Type>) -> bool {
1521 match ty {
1522 Some(ty) => self.owns_anything(ty),
1523 None => false,
1524 }
1525 }
1526
1527 fn free(&mut self, ty: &Type, expr: &str) {
1528 let prev = mem::take(&mut self.src.h_helpers);
1529 match ty {
1530 Type::String => {
1531 self.src.h_helpers(&self.gen.world.to_snake_case());
1532 self.src.h_helpers("_");
1533 }
1534 _ => {
1535 self.print_namespace(SourceType::HHelpers);
1536 }
1537 }
1538 self.print_ty_name(SourceType::HHelpers, ty);
1539 let name = mem::replace(&mut self.src.h_helpers, prev);
1540
1541 self.src.c_helpers(&name);
1542 self.src.c_helpers("_free(");
1543 self.src.c_helpers(expr);
1544 self.src.c_helpers(");\n");
1545 }
1546}
1547
1548struct FunctionBindgen<'a, 'b> {
1549 gen: &'a mut InterfaceGenerator<'b>,
1550 locals: Ns,
1551 src: wit_bindgen_core::Source,
1552 sig: CSig,
1553 func_to_call: &'a str,
1554 block_storage: Vec<wit_bindgen_core::Source>,
1555 blocks: Vec<(String, Vec<String>)>,
1556 payloads: Vec<String>,
1557 params: Vec<String>,
1558 wasm_return: Option<String>,
1559 ret_store_cnt: usize,
1560 import_return_pointer_area_size: usize,
1561 import_return_pointer_area_align: usize,
1562}
1563
1564impl<'a, 'b> FunctionBindgen<'a, 'b> {
1565 fn new(
1566 gen: &'a mut InterfaceGenerator<'b>,
1567 sig: CSig,
1568 func_to_call: &'a str,
1569 ) -> FunctionBindgen<'a, 'b> {
1570 FunctionBindgen {
1571 gen,
1572 sig,
1573 locals: Default::default(),
1574 src: Default::default(),
1575 func_to_call,
1576 block_storage: Vec::new(),
1577 blocks: Vec::new(),
1578 payloads: Vec::new(),
1579 params: Vec::new(),
1580 wasm_return: None,
1581 ret_store_cnt: 0,
1582 import_return_pointer_area_size: 0,
1583 import_return_pointer_area_align: 0,
1584 }
1585 }
1586
1587 fn store_op(&mut self, op: &str, loc: &str) {
1588 self.src.push_str(loc);
1589 self.src.push_str(" = ");
1590 self.src.push_str(op);
1591 self.src.push_str(";\n");
1592 }
1593
1594 fn load(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1595 results.push(format!("*(({}*) ({} + {}))", ty, operands[0], offset));
1596 }
1597
1598 fn load_ext(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1599 self.load(ty, offset, operands, results);
1600 let result = results.pop().unwrap();
1601 results.push(format!("(int32_t) ({})", result));
1602 }
1603
1604 fn store(&mut self, ty: &str, offset: i32, operands: &[String]) {
1605 uwriteln!(
1606 self.src,
1607 "*(({}*)({} + {})) = {};",
1608 ty,
1609 operands[1],
1610 offset,
1611 operands[0]
1612 );
1613 }
1614
1615 fn store_in_retptr(&mut self, operand: &String) {
1616 self.store_op(
1617 operand,
1618 &format!("*{}", self.sig.retptrs[self.ret_store_cnt]),
1619 );
1620 self.ret_store_cnt = self.ret_store_cnt + 1;
1621 }
1622}
1623
1624impl Bindgen for FunctionBindgen<'_, '_> {
1625 type Operand = String;
1626
1627 fn sizes(&self) -> &SizeAlign {
1628 &self.gen.gen.sizes
1629 }
1630
1631 fn push_block(&mut self) {
1632 let prev = mem::take(&mut self.src);
1633 self.block_storage.push(prev);
1634 }
1635
1636 fn finish_block(&mut self, operands: &mut Vec<String>) {
1637 let to_restore = self.block_storage.pop().unwrap();
1638 let src = mem::replace(&mut self.src, to_restore);
1639 self.blocks.push((src.into(), mem::take(operands)));
1640 }
1641
1642 fn return_pointer(&mut self, size: usize, align: usize) -> String {
1643 let ptr = self.locals.tmp("ptr");
1644
1645 if self.gen.in_import {
1648 self.import_return_pointer_area_size = self.import_return_pointer_area_size.max(size);
1649 self.import_return_pointer_area_align =
1650 self.import_return_pointer_area_align.max(align);
1651 uwriteln!(self.src, "int32_t {} = (int32_t) &ret_area;", ptr);
1652 } else {
1653 self.gen.gen.return_pointer_area_size = self.gen.gen.return_pointer_area_size.max(size);
1654 self.gen.gen.return_pointer_area_align =
1655 self.gen.gen.return_pointer_area_align.max(align);
1656 uwriteln!(self.src, "int32_t {} = (int32_t) &RET_AREA;", ptr);
1658 }
1659
1660 ptr
1661 }
1662
1663 fn is_list_canonical(&self, resolve: &Resolve, ty: &Type) -> bool {
1664 resolve.all_bits_valid(ty)
1665 }
1666
1667 fn emit(
1668 &mut self,
1669 _resolve: &Resolve,
1670 inst: &Instruction<'_>,
1671 operands: &mut Vec<String>,
1672 results: &mut Vec<String>,
1673 ) {
1674 match inst {
1675 Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
1676 Instruction::I32Const { val } => results.push(val.to_string()),
1677 Instruction::ConstZero { tys } => {
1678 for _ in tys.iter() {
1679 results.push("0".to_string());
1680 }
1681 }
1682
1683 Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
1685 Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
1686 Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
1687 Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
1688 Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
1689 Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
1690 Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
1691
1692 Instruction::I32FromU8
1693 | Instruction::I32FromS8
1694 | Instruction::I32FromU16
1695 | Instruction::I32FromS16
1696 | Instruction::I32FromU32 => {
1697 results.push(format!("(int32_t) ({})", operands[0]));
1698 }
1699 Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
1700 Instruction::I64FromU64 => {
1701 results.push(format!("(int64_t) ({})", operands[0]));
1702 }
1703
1704 Instruction::F32FromFloat32
1707 | Instruction::F64FromFloat64
1708 | Instruction::Float32FromF32
1709 | Instruction::Float64FromF64 => {
1710 results.push(operands[0].clone());
1711 }
1712
1713 Instruction::CharFromI32 => {
1715 results.push(format!("(uint32_t) ({})", operands[0]));
1716 }
1717 Instruction::I32FromChar => {
1718 results.push(format!("(int32_t) ({})", operands[0]));
1719 }
1720
1721 Instruction::Bitcasts { casts } => {
1722 for (cast, op) in casts.iter().zip(operands) {
1723 let op = op;
1724 match cast {
1725 Bitcast::I32ToF32 | Bitcast::I64ToF32 => {
1726 results
1727 .push(format!("((union {{ int32_t a; float b; }}){{ {} }}).b", op));
1728 }
1729 Bitcast::F32ToI32 | Bitcast::F32ToI64 => {
1730 results
1731 .push(format!("((union {{ float a; int32_t b; }}){{ {} }}).b", op));
1732 }
1733 Bitcast::I64ToF64 => {
1734 results.push(format!(
1735 "((union {{ int64_t a; double b; }}){{ {} }}).b",
1736 op
1737 ));
1738 }
1739 Bitcast::F64ToI64 => {
1740 results.push(format!(
1741 "((union {{ double a; int64_t b; }}){{ {} }}).b",
1742 op
1743 ));
1744 }
1745 Bitcast::I32ToI64 => {
1746 results.push(format!("(int64_t) {}", op));
1747 }
1748 Bitcast::I64ToI32 => {
1749 results.push(format!("(int32_t) {}", op));
1750 }
1751 Bitcast::None => results.push(op.to_string()),
1752 }
1753 }
1754 }
1755
1756 Instruction::BoolFromI32 | Instruction::I32FromBool => {
1757 results.push(operands[0].clone());
1758 }
1759
1760 Instruction::RecordLower { record, .. } => {
1761 let op = &operands[0];
1762 for f in record.fields.iter() {
1763 results.push(format!("({}).{}", op, to_c_ident(&f.name)));
1764 }
1765 }
1766 Instruction::RecordLift { ty, .. } => {
1767 let name = self.gen.type_string(&Type::Id(*ty));
1768 let mut result = format!("({}) {{\n", name);
1769 for op in operands {
1770 uwriteln!(result, "{},", op);
1771 }
1772 result.push_str("}");
1773 results.push(result);
1774 }
1775
1776 Instruction::TupleLower { tuple, .. } => {
1777 let op = &operands[0];
1778 for i in 0..tuple.types.len() {
1779 results.push(format!("({}).f{}", op, i));
1780 }
1781 }
1782 Instruction::TupleLift { ty, .. } => {
1783 let name = self.gen.type_string(&Type::Id(*ty));
1784 let mut result = format!("({}) {{\n", name);
1785 for op in operands {
1786 uwriteln!(result, "{},", op);
1787 }
1788 result.push_str("}");
1789 results.push(result);
1790 }
1791
1792 Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
1794 Int::U8 | Int::U16 | Int::U32 => {
1795 results.push(operands.pop().unwrap());
1796 }
1797 Int::U64 => {
1798 let name = self.gen.type_string(&Type::Id(*ty));
1799 let tmp = self.locals.tmp("flags");
1800 uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
1801 results.push(format!("{tmp} & 0xffffffff"));
1802 results.push(format!("({tmp} >> 32) & 0xffffffff"));
1803 }
1804 },
1805
1806 Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
1807 Int::U8 | Int::U16 | Int::U32 => {
1808 results.push(operands.pop().unwrap());
1809 }
1810 Int::U64 => {
1811 let name = self.gen.type_string(&Type::Id(*ty));
1812 let op0 = &operands[0];
1813 let op1 = &operands[1];
1814 results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
1815 }
1816 },
1817
1818 Instruction::VariantPayloadName => {
1819 let name = self.locals.tmp("payload");
1820 results.push(format!("*{}", name));
1821 self.payloads.push(name);
1822 }
1823
1824 Instruction::VariantLower {
1825 variant,
1826 results: result_types,
1827 ..
1828 } => {
1829 let blocks = self
1830 .blocks
1831 .drain(self.blocks.len() - variant.cases.len()..)
1832 .collect::<Vec<_>>();
1833 let payloads = self
1834 .payloads
1835 .drain(self.payloads.len() - variant.cases.len()..)
1836 .collect::<Vec<_>>();
1837
1838 let mut variant_results = Vec::with_capacity(result_types.len());
1839 for ty in result_types.iter() {
1840 let name = self.locals.tmp("variant");
1841 results.push(name.clone());
1842 self.src.push_str(wasm_type(*ty));
1843 self.src.push_str(" ");
1844 self.src.push_str(&name);
1845 self.src.push_str(";\n");
1846 variant_results.push(name);
1847 }
1848
1849 let expr_to_match = format!("({}).tag", operands[0]);
1850
1851 uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
1852 for (i, ((case, (block, block_results)), payload)) in
1853 variant.cases.iter().zip(blocks).zip(payloads).enumerate()
1854 {
1855 uwriteln!(self.src, "case {}: {{", i);
1856 if let Some(ty) = self.gen.get_nonempty_type(case.ty.as_ref()) {
1857 let ty = self.gen.type_string(ty);
1858 uwrite!(
1859 self.src,
1860 "const {} *{} = &({}).val",
1861 ty,
1862 payload,
1863 operands[0],
1864 );
1865 self.src.push_str(".");
1866 self.src.push_str(&to_c_ident(&case.name));
1867 self.src.push_str(";\n");
1868 }
1869 self.src.push_str(&block);
1870
1871 for (name, result) in variant_results.iter().zip(&block_results) {
1872 uwriteln!(self.src, "{} = {};", name, result);
1873 }
1874 self.src.push_str("break;\n}\n");
1875 }
1876 self.src.push_str("}\n");
1877 }
1878
1879 Instruction::VariantLift { variant, ty, .. } => {
1880 let blocks = self
1881 .blocks
1882 .drain(self.blocks.len() - variant.cases.len()..)
1883 .collect::<Vec<_>>();
1884
1885 let ty = self.gen.type_string(&Type::Id(*ty));
1886 let result = self.locals.tmp("variant");
1887 uwriteln!(self.src, "{} {};", ty, result);
1888 uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1889 uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1890 for (i, (case, (block, block_results))) in
1891 variant.cases.iter().zip(blocks).enumerate()
1892 {
1893 uwriteln!(self.src, "case {}: {{", i);
1894 self.src.push_str(&block);
1895 assert!(block_results.len() == (case.ty.is_some() as usize));
1896
1897 if let Some(_) = self.gen.get_nonempty_type(case.ty.as_ref()) {
1898 let mut dst = format!("{}.val", result);
1899 dst.push_str(".");
1900 dst.push_str(&to_c_ident(&case.name));
1901 self.store_op(&block_results[0], &dst);
1902 }
1903 self.src.push_str("break;\n}\n");
1904 }
1905 self.src.push_str("}\n");
1906 results.push(result);
1907 }
1908
1909 Instruction::UnionLower {
1910 union,
1911 results: result_types,
1912 ..
1913 } => {
1914 let blocks = self
1915 .blocks
1916 .drain(self.blocks.len() - union.cases.len()..)
1917 .collect::<Vec<_>>();
1918 let payloads = self
1919 .payloads
1920 .drain(self.payloads.len() - union.cases.len()..)
1921 .collect::<Vec<_>>();
1922
1923 let mut union_results = Vec::with_capacity(result_types.len());
1924 for ty in result_types.iter() {
1925 let name = self.locals.tmp("unionres");
1926 results.push(name.clone());
1927 let ty = wasm_type(*ty);
1928 uwriteln!(self.src, "{ty} {name};");
1929 union_results.push(name);
1930 }
1931
1932 let op0 = &operands[0];
1933 uwriteln!(self.src, "switch (({op0}).tag) {{");
1934 for (i, ((case, (block, block_results)), payload)) in
1935 union.cases.iter().zip(blocks).zip(payloads).enumerate()
1936 {
1937 uwriteln!(self.src, "case {i}: {{");
1938 if !self.gen.is_empty_type(&case.ty) {
1939 let ty = self.gen.type_string(&case.ty);
1940 uwriteln!(self.src, "const {ty} *{payload} = &({op0}).val.f{i};");
1941 }
1942 self.src.push_str(&block);
1943
1944 for (name, result) in union_results.iter().zip(&block_results) {
1945 uwriteln!(self.src, "{name} = {result};");
1946 }
1947 self.src.push_str("break;\n}\n");
1948 }
1949 self.src.push_str("}\n");
1950 }
1951
1952 Instruction::UnionLift { union, ty, .. } => {
1953 let blocks = self
1954 .blocks
1955 .drain(self.blocks.len() - union.cases.len()..)
1956 .collect::<Vec<_>>();
1957
1958 let ty = self.gen.type_string(&Type::Id(*ty));
1959 let result = self.locals.tmp("unionres");
1960 uwriteln!(self.src, "{} {};", ty, result);
1961 uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1962 uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1963 for (i, (_case, (block, block_results))) in
1964 union.cases.iter().zip(blocks).enumerate()
1965 {
1966 uwriteln!(self.src, "case {i}: {{");
1967 self.src.push_str(&block);
1968
1969 assert!(block_results.len() == 1);
1970 let dst = format!("{result}.val.f{i}");
1971 self.store_op(&block_results[0], &dst);
1972 self.src.push_str("break;\n}\n");
1973 }
1974 self.src.push_str("}\n");
1975 results.push(result);
1976 }
1977
1978 Instruction::OptionLower {
1979 results: result_types,
1980 payload,
1981 ..
1982 } => {
1983 let (mut some, some_results) = self.blocks.pop().unwrap();
1984 let (mut none, none_results) = self.blocks.pop().unwrap();
1985 let some_payload = self.payloads.pop().unwrap();
1986 let _none_payload = self.payloads.pop().unwrap();
1987
1988 for (i, ty) in result_types.iter().enumerate() {
1989 let name = self.locals.tmp("option");
1990 results.push(name.clone());
1991 self.src.push_str(wasm_type(*ty));
1992 self.src.push_str(" ");
1993 self.src.push_str(&name);
1994 self.src.push_str(";\n");
1995 let some_result = &some_results[i];
1996 uwriteln!(some, "{name} = {some_result};");
1997 let none_result = &none_results[i];
1998 uwriteln!(none, "{name} = {none_result};");
1999 }
2000
2001 let op0 = &operands[0];
2002 let ty = self.gen.type_string(payload);
2003 let bind_some = if self.gen.is_empty_type(payload) {
2004 String::new()
2005 } else {
2006 format!("const {ty} *{some_payload} = &({op0}).val;")
2007 };
2008
2009 uwrite!(
2010 self.src,
2011 "\
2012 if (({op0}).is_some) {{
2013 {bind_some}
2014 {some}}} else {{
2015 {none}}}
2016 "
2017 );
2018 }
2019
2020 Instruction::OptionLift { payload, ty, .. } => {
2021 let (mut some, some_results) = self.blocks.pop().unwrap();
2022 let (mut none, none_results) = self.blocks.pop().unwrap();
2023 assert!(none_results.len() == 0);
2024 assert!(some_results.len() == 1);
2025 let some_result = &some_results[0];
2026
2027 let ty = self.gen.type_string(&Type::Id(*ty));
2028 let result = self.locals.tmp("option");
2029 uwriteln!(self.src, "{ty} {result};");
2030 let op0 = &operands[0];
2031 let set_some = if self.gen.is_empty_type(payload) {
2032 String::new()
2033 } else {
2034 format!("{result}.val = {some_result};\n")
2035 };
2036 if none.len() > 0 {
2037 none.push('\n');
2038 }
2039 if some.len() > 0 {
2040 some.push('\n');
2041 }
2042 uwrite!(
2043 self.src,
2044 "switch ({op0}) {{
2045 case 0: {{
2046 {result}.is_some = false;
2047 {none}\
2048 break;
2049 }}
2050 case 1: {{
2051 {result}.is_some = true;
2052 {some}\
2053 {set_some}\
2054 break;
2055 }}
2056 }}\n"
2057 );
2058 results.push(result);
2059 }
2060
2061 Instruction::ResultLower {
2062 results: result_types,
2063 result,
2064 ..
2065 } => {
2066 let (mut err, err_results) = self.blocks.pop().unwrap();
2067 let (mut ok, ok_results) = self.blocks.pop().unwrap();
2068 let err_payload = self.payloads.pop().unwrap();
2069 let ok_payload = self.payloads.pop().unwrap();
2070
2071 for (i, ty) in result_types.iter().enumerate() {
2072 let name = self.locals.tmp("result");
2073 results.push(name.clone());
2074 self.src.push_str(wasm_type(*ty));
2075 self.src.push_str(" ");
2076 self.src.push_str(&name);
2077 self.src.push_str(";\n");
2078 let ok_result = &ok_results[i];
2079 uwriteln!(ok, "{name} = {ok_result};");
2080 let err_result = &err_results[i];
2081 uwriteln!(err, "{name} = {err_result};");
2082 }
2083
2084 let op0 = &operands[0];
2085 let bind_ok = if let Some(ok) = self.gen.get_nonempty_type(result.ok.as_ref()) {
2086 let ok_ty = self.gen.type_string(ok);
2087 format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
2088 } else {
2089 String::new()
2090 };
2091 let bind_err = if let Some(err) = self.gen.get_nonempty_type(result.err.as_ref()) {
2092 let err_ty = self.gen.type_string(err);
2093 format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
2094 } else {
2095 String::new()
2096 };
2097 uwrite!(
2098 self.src,
2099 "\
2100 if (({op0}).is_err) {{
2101 {bind_err}\
2102 {err}\
2103 }} else {{
2104 {bind_ok}\
2105 {ok}\
2106 }}
2107 "
2108 );
2109 }
2110
2111 Instruction::ResultLift { result, ty, .. } => {
2112 let (mut err, err_results) = self.blocks.pop().unwrap();
2113 assert!(err_results.len() == (result.err.is_some() as usize));
2114 let (mut ok, ok_results) = self.blocks.pop().unwrap();
2115 assert!(ok_results.len() == (result.ok.is_some() as usize));
2116
2117 if err.len() > 0 {
2118 err.push_str("\n");
2119 }
2120 if ok.len() > 0 {
2121 ok.push_str("\n");
2122 }
2123
2124 let result_tmp = self.locals.tmp("result");
2125 let set_ok = if let Some(_) = self.gen.get_nonempty_type(result.ok.as_ref()) {
2126 let ok_result = &ok_results[0];
2127 format!("{result_tmp}.val.ok = {ok_result};\n")
2128 } else {
2129 String::new()
2130 };
2131 let set_err = if let Some(_) = self.gen.get_nonempty_type(result.err.as_ref()) {
2132 let err_result = &err_results[0];
2133 format!("{result_tmp}.val.err = {err_result};\n")
2134 } else {
2135 String::new()
2136 };
2137
2138 let ty = self.gen.type_string(&Type::Id(*ty));
2139 uwriteln!(self.src, "{ty} {result_tmp};");
2140 let op0 = &operands[0];
2141 uwriteln!(
2142 self.src,
2143 "switch ({op0}) {{
2144 case 0: {{
2145 {result_tmp}.is_err = false;
2146 {ok}\
2147 {set_ok}\
2148 break;
2149 }}
2150 case 1: {{
2151 {result_tmp}.is_err = true;
2152 {err}\
2153 {set_err}\
2154 break;
2155 }}
2156 }}"
2157 );
2158 results.push(result_tmp);
2159 }
2160
2161 Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
2162 Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
2163
2164 Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
2165 results.push(format!("(int32_t) ({}).ptr", operands[0]));
2166 results.push(format!("(int32_t) ({}).len", operands[0]));
2167 }
2168 Instruction::ListCanonLift { element, ty, .. } => {
2169 let list_name = self.gen.type_string(&Type::Id(*ty));
2170 let elem_name = self.gen.type_string(element);
2171 results.push(format!(
2172 "({}) {{ ({}*)({}), (size_t)({}) }}",
2173 list_name, elem_name, operands[0], operands[1]
2174 ));
2175 }
2176 Instruction::StringLift { .. } => {
2177 let list_name = self.gen.type_string(&Type::String);
2178 results.push(format!(
2179 "({}) {{ ({}*)({}), (size_t)({}) }}",
2180 list_name,
2181 self.gen.gen.char_type(),
2182 operands[0],
2183 operands[1]
2184 ));
2185 }
2186
2187 Instruction::ListLower { .. } => {
2188 let _body = self.blocks.pop().unwrap();
2189 results.push(format!("(int32_t) ({}).ptr", operands[0]));
2190 results.push(format!("(int32_t) ({}).len", operands[0]));
2191 }
2192
2193 Instruction::ListLift { element, ty, .. } => {
2194 let _body = self.blocks.pop().unwrap();
2195 let list_name = self.gen.type_string(&Type::Id(*ty));
2196 let elem_name = self.gen.type_string(element);
2197 results.push(format!(
2198 "({}) {{ ({}*)({}), (size_t)({}) }}",
2199 list_name, elem_name, operands[0], operands[1]
2200 ));
2201 }
2202 Instruction::IterElem { .. } => results.push("e".to_string()),
2203 Instruction::IterBasePointer => results.push("base".to_string()),
2204
2205 Instruction::CallWasm { sig, .. } => {
2206 match sig.results.len() {
2207 0 => {}
2208 1 => {
2209 self.src.push_str(wasm_type(sig.results[0]));
2210 let ret = self.locals.tmp("ret");
2211 self.wasm_return = Some(ret.clone());
2212 uwrite!(self.src, " {} = ", ret);
2213 results.push(ret);
2214 }
2215 _ => unimplemented!(),
2216 }
2217 self.src.push_str(self.func_to_call);
2218 self.src.push_str("(");
2219 for (i, op) in operands.iter().enumerate() {
2220 if i > 0 {
2221 self.src.push_str(", ");
2222 }
2223 self.src.push_str(op);
2224 }
2225 self.src.push_str(");\n");
2226 }
2227
2228 Instruction::CallInterface { func } => {
2229 let mut args = String::new();
2230 for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
2231 if i > 0 {
2232 args.push_str(", ");
2233 }
2234 let ty = &func.params[i].1;
2235 if *byref {
2236 let name = self.locals.tmp("arg");
2237 let ty = self.gen.type_string(ty);
2238 uwriteln!(self.src, "{} {} = {};", ty, name, op);
2239 args.push_str("&");
2240 args.push_str(&name);
2241 } else {
2242 if !self.gen.in_import {
2243 if let Type::Id(id) = ty {
2244 if let TypeDefKind::Option(option_ty) =
2245 &self.gen.resolve.types[*id].kind
2246 {
2247 if self.gen.is_empty_type(option_ty) {
2248 uwrite!(args, "{op}.is_some ? (void*)1 : NULL");
2249 } else {
2250 uwrite!(args, "{op}.is_some ? &({op}.val) : NULL");
2251 }
2252 continue;
2253 }
2254 }
2255 }
2256 args.push_str(op);
2257 }
2258 }
2259 match &self.sig.ret.scalar {
2260 None => {
2261 let mut retptrs = Vec::new();
2262 for ty in self.sig.ret.retptrs.iter() {
2263 let name = self.locals.tmp("ret");
2264 let ty = self.gen.type_string(ty);
2265 uwriteln!(self.src, "{} {};", ty, name);
2266 if args.len() > 0 {
2267 args.push_str(", ");
2268 }
2269 args.push_str("&");
2270 args.push_str(&name);
2271 retptrs.push(name);
2272 }
2273 uwriteln!(self.src, "{}({});", self.sig.name, args);
2274 results.extend(retptrs);
2275 }
2276 Some(Scalar::Void) => {
2277 uwriteln!(self.src, "{}({});", self.sig.name, args);
2278 }
2279 Some(Scalar::Type(_)) => {
2280 let ret = self.locals.tmp("ret");
2281 let ty = self
2282 .gen
2283 .type_string(func.results.iter_types().next().unwrap());
2284 uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
2285 results.push(ret);
2286 }
2287 Some(Scalar::OptionBool(ty)) => {
2288 let ret = self.locals.tmp("ret");
2289 let val = self.locals.tmp("val");
2290 if args.len() > 0 {
2291 args.push_str(", ");
2292 }
2293 args.push_str("&");
2294 args.push_str(&val);
2295 let payload_ty = self.gen.type_string(ty);
2296 uwriteln!(self.src, "{} {};", payload_ty, val);
2297 uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
2298 let option_ty = self
2299 .gen
2300 .type_string(func.results.iter_types().next().unwrap());
2301 let option_ret = self.locals.tmp("ret");
2302 if !self.gen.is_empty_type(ty) {
2303 uwrite!(
2304 self.src,
2305 "
2306 {ty} {ret};
2307 {ret}.is_some = {tag};
2308 {ret}.val = {val};
2309 ",
2310 ty = option_ty,
2311 ret = option_ret,
2312 tag = ret,
2313 val = val,
2314 );
2315 } else {
2316 uwrite!(
2317 self.src,
2318 "
2319 {ty} {ret};
2320 {ret}.is_some = {tag};
2321 ",
2322 ty = option_ty,
2323 ret = option_ret,
2324 tag = ret,
2325 );
2326 }
2327 results.push(option_ret);
2328 }
2329 Some(Scalar::ResultBool(ok, err)) => {
2330 let result_ty = self
2331 .gen
2332 .type_string(func.results.iter_types().next().unwrap());
2333 let ret = self.locals.tmp("ret");
2334 let mut ret_iter = self.sig.ret.retptrs.iter();
2335 uwriteln!(self.src, "{result_ty} {ret};");
2336 let ok_name = if ok.is_some() {
2337 if let Some(ty) = ret_iter.next() {
2338 let val = self.locals.tmp("ok");
2339 if args.len() > 0 {
2340 uwrite!(args, ", ");
2341 }
2342 uwrite!(args, "&{val}");
2343 let ty = self.gen.type_string(ty);
2344 uwriteln!(self.src, "{} {};", ty, val);
2345 Some(val)
2346 } else {
2347 None
2348 }
2349 } else {
2350 None
2351 };
2352 let err_name = if let Some(ty) = ret_iter.next() {
2353 let val = self.locals.tmp("err");
2354 if args.len() > 0 {
2355 uwrite!(args, ", ")
2356 }
2357 uwrite!(args, "&{val}");
2358 let ty = self.gen.type_string(ty);
2359 uwriteln!(self.src, "{} {};", ty, val);
2360 Some(val)
2361 } else {
2362 None
2363 };
2364 assert!(ret_iter.next().is_none());
2365 uwrite!(self.src, "");
2366 uwriteln!(self.src, "{ret}.is_err = !{}({args});", self.sig.name);
2367 if self.gen.get_nonempty_type(err.as_ref()).is_some() {
2368 if let Some(err_name) = err_name {
2369 uwriteln!(
2370 self.src,
2371 "if ({ret}.is_err) {{
2372 {ret}.val.err = {err_name};
2373 }}",
2374 );
2375 }
2376 }
2377 if self.gen.get_nonempty_type(ok.as_ref()).is_some() {
2378 if let Some(ok_name) = ok_name {
2379 uwriteln!(
2380 self.src,
2381 "if (!{ret}.is_err) {{
2382 {ret}.val.ok = {ok_name};
2383 }}"
2384 );
2385 } else {
2386 uwrite!(self.src, "\n");
2387 }
2388 }
2389 results.push(ret);
2390 }
2391 }
2392 }
2393 Instruction::Return { .. } if self.gen.in_import => match self.sig.ret.scalar {
2394 None => {
2395 for op in operands.iter() {
2396 self.store_in_retptr(op);
2397 }
2398 }
2399 Some(Scalar::Void) => {
2400 assert!(operands.is_empty());
2401 }
2402 Some(Scalar::Type(_)) => {
2403 assert_eq!(operands.len(), 1);
2404 self.src.push_str("return ");
2405 self.src.push_str(&operands[0]);
2406 self.src.push_str(";\n");
2407 }
2408 Some(Scalar::OptionBool(o)) => {
2409 assert_eq!(operands.len(), 1);
2410 let variant = &operands[0];
2411 if !self.gen.is_empty_type(&o) {
2412 self.store_in_retptr(&format!("{}.val", variant));
2413 }
2414 self.src.push_str("return ");
2415 self.src.push_str(&variant);
2416 self.src.push_str(".is_some;\n");
2417 }
2418 Some(Scalar::ResultBool(ok, err)) => {
2419 assert_eq!(operands.len(), 1);
2420 let variant = &operands[0];
2421 assert!(self.sig.retptrs.len() <= 2);
2422 uwriteln!(self.src, "if (!{}.is_err) {{", variant);
2423 if let Some(_) = self.gen.get_nonempty_type(ok.as_ref()) {
2424 if self.sig.retptrs.len() == 2 {
2425 self.store_in_retptr(&format!("{}.val.ok", variant));
2426 } else if self.sig.retptrs.len() == 1 && ok.is_some() {
2427 self.store_in_retptr(&format!("{}.val.ok", variant));
2428 }
2429 }
2430 uwriteln!(
2431 self.src,
2432 " return 1;
2433 }} else {{"
2434 );
2435 if let Some(_) = self.gen.get_nonempty_type(err.as_ref()) {
2436 if self.sig.retptrs.len() == 2 {
2437 self.store_in_retptr(&format!("{}.val.err", variant));
2438 } else if self.sig.retptrs.len() == 1 && !ok.is_some() {
2439 self.store_in_retptr(&format!("{}.val.err", variant));
2440 }
2441 }
2442 uwriteln!(
2443 self.src,
2444 " return 0;
2445 }}"
2446 );
2447 }
2448 },
2449 Instruction::Return { amt, .. } => {
2450 assert!(*amt <= 1);
2451 if *amt == 1 {
2452 uwriteln!(self.src, "return {};", operands[0]);
2453 }
2454 }
2455
2456 Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
2457 Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
2458 Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
2459 Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
2460 Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
2461 Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
2462 Instruction::F32Store { offset } => self.store("float", *offset, operands),
2463 Instruction::F64Store { offset } => self.store("double", *offset, operands),
2464 Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
2465 Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
2466
2467 Instruction::I32Load8U { offset } => {
2468 self.load_ext("uint8_t", *offset, operands, results)
2469 }
2470 Instruction::I32Load8S { offset } => {
2471 self.load_ext("int8_t", *offset, operands, results)
2472 }
2473 Instruction::I32Load16U { offset } => {
2474 self.load_ext("uint16_t", *offset, operands, results)
2475 }
2476 Instruction::I32Load16S { offset } => {
2477 self.load_ext("int16_t", *offset, operands, results)
2478 }
2479
2480 Instruction::GuestDeallocate { .. } => {
2481 uwriteln!(self.src, "free((void*) ({}));", operands[0]);
2482 }
2483 Instruction::GuestDeallocateString => {
2484 uwriteln!(self.src, "if (({}) > 0) {{", operands[1]);
2485 uwriteln!(self.src, "free((void*) ({}));", operands[0]);
2486 uwriteln!(self.src, "}}");
2487 }
2488 Instruction::GuestDeallocateVariant { blocks } => {
2489 let blocks = self
2490 .blocks
2491 .drain(self.blocks.len() - blocks..)
2492 .collect::<Vec<_>>();
2493
2494 uwriteln!(self.src, "switch ((int32_t) {}) {{", operands[0]);
2495 for (i, (block, results)) in blocks.into_iter().enumerate() {
2496 assert!(results.is_empty());
2497 uwriteln!(self.src, "case {}: {{", i);
2498 self.src.push_str(&block);
2499 self.src.push_str("break;\n}\n");
2500 }
2501 self.src.push_str("}\n");
2502 }
2503 Instruction::GuestDeallocateList { element } => {
2504 let (body, results) = self.blocks.pop().unwrap();
2505 assert!(results.is_empty());
2506 let ptr = self.locals.tmp("ptr");
2507 let len = self.locals.tmp("len");
2508 uwriteln!(self.src, "int32_t {ptr} = {};", operands[0]);
2509 uwriteln!(self.src, "int32_t {len} = {};", operands[1]);
2510 let i = self.locals.tmp("i");
2511 uwriteln!(self.src, "for (int32_t {i} = 0; {i} < {len}; {i}++) {{");
2512 let size = self.gen.gen.sizes.size(element);
2513 uwriteln!(self.src, "int32_t base = {ptr} + {i} * {size};");
2514 uwriteln!(self.src, "(void) base;");
2515 uwrite!(self.src, "{body}");
2516 uwriteln!(self.src, "}}");
2517 uwriteln!(self.src, "if ({len} > 0) {{");
2518 uwriteln!(self.src, "free((void*) ({ptr}));");
2519 uwriteln!(self.src, "}}");
2520 }
2521
2522 i => unimplemented!("{:?}", i),
2523 }
2524 }
2525}
2526
2527#[derive(Default, Clone, Copy)]
2528enum SourceType {
2529 #[default]
2530 HDefs,
2531 HFns,
2532 HHelpers,
2533 }
2538
2539#[derive(Default)]
2540struct Source {
2541 h_defs: wit_bindgen_core::Source,
2542 h_fns: wit_bindgen_core::Source,
2543 h_helpers: wit_bindgen_core::Source,
2544 c_defs: wit_bindgen_core::Source,
2545 c_fns: wit_bindgen_core::Source,
2546 c_helpers: wit_bindgen_core::Source,
2547 c_adapters: wit_bindgen_core::Source,
2548}
2549
2550impl Source {
2551 fn print(&mut self, stype: SourceType, s: &str) {
2552 match stype {
2553 SourceType::HDefs => self.h_defs(s),
2554 SourceType::HFns => self.h_fns(s),
2555 SourceType::HHelpers => self.h_helpers(s),
2556 }
2561 }
2562 fn append(&mut self, append_src: &Source) {
2563 self.h_defs.push_str(&append_src.h_defs);
2564 self.h_fns.push_str(&append_src.h_fns);
2565 self.h_helpers.push_str(&append_src.h_helpers);
2566 self.c_defs.push_str(&append_src.c_defs);
2567 self.c_fns.push_str(&append_src.c_fns);
2568 self.c_helpers.push_str(&append_src.c_helpers);
2569 self.c_adapters.push_str(&append_src.c_adapters);
2570 }
2571 fn h_defs(&mut self, s: &str) {
2572 self.h_defs.push_str(s);
2573 }
2574 fn h_fns(&mut self, s: &str) {
2575 self.h_fns.push_str(s);
2576 }
2577 fn h_helpers(&mut self, s: &str) {
2578 self.h_helpers.push_str(s);
2579 }
2580 fn c_defs(&mut self, s: &str) {
2581 self.c_defs.push_str(s);
2582 }
2583 fn c_fns(&mut self, s: &str) {
2584 self.c_fns.push_str(s);
2585 }
2586 fn c_helpers(&mut self, s: &str) {
2587 self.c_helpers.push_str(s);
2588 }
2589 fn c_adapters(&mut self, s: &str) {
2590 self.c_adapters.push_str(s);
2591 }
2592}
2593
2594fn wasm_type(ty: WasmType) -> &'static str {
2595 match ty {
2596 WasmType::I32 => "int32_t",
2597 WasmType::I64 => "int64_t",
2598 WasmType::F32 => "float",
2599 WasmType::F64 => "double",
2600 }
2601}
2602
2603fn int_repr(ty: Int) -> &'static str {
2604 match ty {
2605 Int::U8 => "uint8_t",
2606 Int::U16 => "uint16_t",
2607 Int::U32 => "uint32_t",
2608 Int::U64 => "uint64_t",
2609 }
2610}
2611
2612fn flags_repr(f: &Flags) -> Int {
2613 match f.repr() {
2614 FlagsRepr::U8 => Int::U8,
2615 FlagsRepr::U16 => Int::U16,
2616 FlagsRepr::U32(1) => Int::U32,
2617 FlagsRepr::U32(2) => Int::U64,
2618 repr => panic!("unimplemented flags {:?}", repr),
2619 }
2620}
2621
2622pub fn to_c_ident(name: &str) -> String {
2623 match name {
2624 "auto" => "auto_".into(),
2627 "else" => "else_".into(),
2628 "long" => "long_".into(),
2629 "switch" => "switch_".into(),
2630 "break" => "break_".into(),
2631 "enum" => "enum_".into(),
2632 "register" => "register_".into(),
2633 "typedef" => "typedef_".into(),
2634 "case" => "case_".into(),
2635 "extern" => "extern_".into(),
2636 "return" => "return_".into(),
2637 "union" => "union_".into(),
2638 "char" => "char_".into(),
2639 "float" => "float_".into(),
2640 "short" => "short_".into(),
2641 "unsigned" => "unsigned_".into(),
2642 "const" => "const_".into(),
2643 "for" => "for_".into(),
2644 "signed" => "signed_".into(),
2645 "void" => "void_".into(),
2646 "continue" => "continue_".into(),
2647 "goto" => "goto_".into(),
2648 "sizeof" => "sizeof_".into(),
2649 "volatile" => "volatile_".into(),
2650 "default" => "default_".into(),
2651 "if" => "if_".into(),
2652 "static" => "static_".into(),
2653 "while" => "while_".into(),
2654 "do" => "do_".into(),
2655 "int" => "int_".into(),
2656 "struct" => "struct_".into(),
2657 "_Packed" => "_Packed_".into(),
2658 "double" => "double_".into(),
2659 s => s.to_snake_case(),
2660 }
2661}