1use heck::*;
2use std::collections::{BTreeSet, HashMap, HashSet};
3use std::fmt::Write;
4use std::mem;
5use wai_bindgen_gen_core::wai_parser::abi::{
6 AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType,
7};
8use wai_bindgen_gen_core::{uwrite, uwriteln, wai_parser::*, Direction, Files, Generator, Ns};
9
10#[derive(Default)]
11pub struct C {
12 src: Source,
13 in_import: bool,
14 opts: Opts,
15 funcs: HashMap<String, Vec<Func>>,
16 return_pointer_area_size: usize,
17 return_pointer_area_align: usize,
18 sizes: SizeAlign,
19 names: Ns,
20
21 public_anonymous_types: BTreeSet<TypeId>,
25
26 private_anonymous_types: BTreeSet<TypeId>,
31
32 types: HashMap<TypeId, wai_bindgen_gen_core::Source>,
35
36 needs_string: bool,
37}
38
39struct Func {
40 src: Source,
41}
42
43#[derive(Default, Debug, Clone)]
44#[cfg_attr(feature = "structopt", derive(structopt::StructOpt))]
45pub struct Opts {
46 }
48
49impl Opts {
50 pub fn build(&self) -> C {
51 let mut r = C::new();
52 r.opts = self.clone();
53 r
54 }
55}
56
57#[derive(Debug)]
58struct Return {
59 splat_tuple: bool,
60 scalar: Option<Scalar>,
61 retptrs: Vec<Type>,
62}
63
64struct CSig {
65 name: String,
66 sig: String,
67 params: Vec<(bool, String)>,
68 ret: Return,
69 retptrs: Vec<String>,
70}
71
72#[derive(Debug)]
73enum Scalar {
74 Void,
75 OptionBool(Type),
76 ExpectedEnum { err: TypeId, max_err: usize },
77 Type(Type),
78}
79
80impl C {
81 pub fn new() -> C {
82 C::default()
83 }
84
85 fn abi_variant(dir: Direction) -> AbiVariant {
86 match dir {
88 Direction::Export => AbiVariant::GuestExport,
89 Direction::Import => AbiVariant::GuestImport,
90 }
91 }
92
93 fn classify_ret(&mut self, iface: &Interface, func: &Function) -> Return {
94 let mut ret = Return {
95 splat_tuple: false,
96 scalar: None,
97 retptrs: Vec::new(),
98 };
99 ret.return_single(iface, &func.result, &func.result);
100 return ret;
101 }
102
103 fn print_sig(&mut self, iface: &Interface, func: &Function) -> CSig {
104 let name = format!(
105 "{}_{}",
106 iface.name.to_snake_case(),
107 func.name.to_snake_case()
108 );
109 self.names.insert(&name).expect("duplicate symbols");
110 let start = self.src.h.len();
111
112 let ret = self.classify_ret(iface, func);
113 match &ret.scalar {
114 None | Some(Scalar::Void) => self.src.h("void"),
115 Some(Scalar::OptionBool(_id)) => self.src.h("bool"),
116 Some(Scalar::ExpectedEnum { err, .. }) => self.print_ty(iface, &Type::Id(*err)),
117 Some(Scalar::Type(ty)) => self.print_ty(iface, ty),
118 }
119 self.src.h(" ");
120 self.src.h(&name);
121 self.src.h("(");
122 let mut params = Vec::new();
123 for (i, (name, ty)) in func.params.iter().enumerate() {
124 if i > 0 {
125 self.src.h(", ");
126 }
127 self.print_ty(iface, ty);
128 self.src.h(" ");
129 let pointer = self.is_arg_by_pointer(iface, ty);
130 if pointer {
131 self.src.h("*");
132 }
133 let name = name.to_snake_case();
134 self.src.h(&name);
135 params.push((pointer, name));
136 }
137 let mut retptrs = Vec::new();
138 for (i, ty) in ret.retptrs.iter().enumerate() {
139 if i > 0 || func.params.len() > 0 {
140 self.src.h(", ");
141 }
142 self.print_ty(iface, ty);
143 self.src.h(" *");
144 let name = format!("ret{}", i);
145 self.src.h(&name);
146 retptrs.push(name);
147 }
148 if func.params.len() == 0 && ret.retptrs.len() == 0 {
149 self.src.h("void");
150 }
151 self.src.h(")");
152
153 let sig = self.src.h[start..].to_string();
154 self.src.h(";\n");
155
156 CSig {
157 sig,
158 name,
159 params,
160 ret,
161 retptrs,
162 }
163 }
164
165 fn is_arg_by_pointer(&self, iface: &Interface, ty: &Type) -> bool {
166 match ty {
167 Type::Id(id) => match &iface.types[*id].kind {
168 TypeDefKind::Type(t) => self.is_arg_by_pointer(iface, t),
169 TypeDefKind::Variant(_) => true,
170 TypeDefKind::Union(_) => true,
171 TypeDefKind::Option(_) => true,
172 TypeDefKind::Expected(_) => true,
173 TypeDefKind::Enum(_) => false,
174 TypeDefKind::Flags(_) => false,
175 TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
176 TypeDefKind::Future(_) => todo!("is_arg_by_pointer for future"),
177 TypeDefKind::Stream(_) => todo!("is_arg_by_pointer for stream"),
178 },
179 Type::String => true,
180 _ => false,
181 }
182 }
183
184 fn type_string(&mut self, iface: &Interface, ty: &Type) -> String {
185 let prev = mem::take(&mut self.src.h);
191 let prev_public = mem::take(&mut self.public_anonymous_types);
192 let prev_private = mem::take(&mut self.private_anonymous_types);
193
194 self.print_ty(iface, ty);
197
198 let new_private = mem::replace(&mut self.public_anonymous_types, prev_public);
203 assert!(self.private_anonymous_types.is_empty());
204 self.private_anonymous_types = prev_private;
205
206 for id in new_private {
209 if !self.public_anonymous_types.contains(&id) {
210 self.private_anonymous_types.insert(id);
211 }
212 }
213
214 mem::replace(&mut self.src.h, prev).into()
215 }
216
217 fn print_ty(&mut self, iface: &Interface, ty: &Type) {
218 match ty {
219 Type::Unit => self.src.h("void"),
220 Type::Bool => self.src.h("bool"),
221 Type::Char => self.src.h("uint32_t"), Type::U8 => self.src.h("uint8_t"),
223 Type::S8 => self.src.h("int8_t"),
224 Type::U16 => self.src.h("uint16_t"),
225 Type::S16 => self.src.h("int16_t"),
226 Type::U32 => self.src.h("uint32_t"),
227 Type::S32 => self.src.h("int32_t"),
228 Type::U64 => self.src.h("uint64_t"),
229 Type::S64 => self.src.h("int64_t"),
230 Type::Float32 => self.src.h("float"),
231 Type::Float64 => self.src.h("double"),
232 Type::Handle(id) => {
233 self.print_namespace(iface);
234 self.src.h(&iface.resources[*id].name.to_snake_case());
235 self.src.h("_t");
236 }
237 Type::String => {
238 self.print_namespace(iface);
239 self.src.h("string_t");
240 self.needs_string = true;
241 }
242 Type::Id(id) => {
243 let ty = &iface.types[*id];
244 match &ty.name {
245 Some(name) => {
246 self.print_namespace(iface);
247 self.src.h(&name.to_snake_case());
248 self.src.h("_t");
249 }
250 None => match &ty.kind {
251 TypeDefKind::Type(t) => self.print_ty(iface, t),
252 _ => {
253 self.public_anonymous_types.insert(*id);
254 self.private_anonymous_types.remove(id);
255 self.print_namespace(iface);
256 self.print_ty_name(iface, &Type::Id(*id));
257 self.src.h("_t");
258 }
259 },
260 }
261 }
262 }
263 }
264
265 fn print_ty_name(&mut self, iface: &Interface, ty: &Type) {
266 match ty {
267 Type::Unit => self.src.h("unit"),
268 Type::Bool => self.src.h("bool"),
269 Type::Char => self.src.h("char32"),
270 Type::U8 => self.src.h("u8"),
271 Type::S8 => self.src.h("s8"),
272 Type::U16 => self.src.h("u16"),
273 Type::S16 => self.src.h("s16"),
274 Type::U32 => self.src.h("u32"),
275 Type::S32 => self.src.h("s32"),
276 Type::U64 => self.src.h("u64"),
277 Type::S64 => self.src.h("s64"),
278 Type::Float32 => self.src.h("float32"),
279 Type::Float64 => self.src.h("float64"),
280 Type::Handle(id) => self.src.h(&iface.resources[*id].name.to_snake_case()),
281 Type::String => self.src.h("string"),
282 Type::Id(id) => {
283 let ty = &iface.types[*id];
284 if let Some(name) = &ty.name {
285 return self.src.h(&name.to_snake_case());
286 }
287 match &ty.kind {
288 TypeDefKind::Type(t) => self.print_ty_name(iface, t),
289 TypeDefKind::Record(_)
290 | TypeDefKind::Flags(_)
291 | TypeDefKind::Enum(_)
292 | TypeDefKind::Variant(_)
293 | TypeDefKind::Union(_) => {
294 unimplemented!()
295 }
296 TypeDefKind::Tuple(t) => {
297 self.src.h("tuple");
298 self.src.h(&t.types.len().to_string());
299 for ty in t.types.iter() {
300 self.src.h("_");
301 self.print_ty_name(iface, ty);
302 }
303 }
304 TypeDefKind::Option(ty) => {
305 self.src.h("option_");
306 self.print_ty_name(iface, ty);
307 }
308 TypeDefKind::Expected(e) => {
309 self.src.h("expected_");
310 self.print_ty_name(iface, &e.ok);
311 self.src.h("_");
312 self.print_ty_name(iface, &e.err);
313 }
314 TypeDefKind::List(t) => {
315 self.src.h("list_");
316 self.print_ty_name(iface, t);
317 }
318 TypeDefKind::Future(t) => {
319 self.src.h("future_");
320 self.print_ty_name(iface, t);
321 }
322 TypeDefKind::Stream(s) => {
323 self.src.h("stream_");
324 self.print_ty_name(iface, &s.element);
325 self.src.h("_");
326 self.print_ty_name(iface, &s.end);
327 }
328 }
329 }
330 }
331 }
332
333 fn print_anonymous_type(&mut self, iface: &Interface, ty: TypeId) {
334 let prev = mem::take(&mut self.src.h);
335 self.src.h("typedef ");
336 let kind = &iface.types[ty].kind;
337 match kind {
338 TypeDefKind::Type(_)
339 | TypeDefKind::Flags(_)
340 | TypeDefKind::Record(_)
341 | TypeDefKind::Enum(_)
342 | TypeDefKind::Variant(_)
343 | TypeDefKind::Union(_) => {
344 unreachable!()
345 }
346 TypeDefKind::Tuple(t) => {
347 self.src.h("struct {\n");
348 for (i, t) in t.types.iter().enumerate() {
349 self.print_ty(iface, t);
350 uwriteln!(self.src.h, " f{i};");
351 }
352 self.src.h("}");
353 }
354 TypeDefKind::Option(t) => {
355 self.src.h("struct {\n");
356 self.src.h("bool is_some;\n");
357 if !self.is_empty_type(iface, t) {
358 self.print_ty(iface, t);
359 self.src.h(" val;\n");
360 }
361 self.src.h("}");
362 }
363 TypeDefKind::Expected(e) => {
364 self.src.h("struct {
365 bool is_err;
366 union {
367 ");
368 if !self.is_empty_type(iface, &e.ok) {
369 self.print_ty(iface, &e.ok);
370 self.src.h(" ok;\n");
371 }
372 if !self.is_empty_type(iface, &e.err) {
373 self.print_ty(iface, &e.err);
374 self.src.h(" err;\n");
375 }
376 self.src.h("} val;\n");
377 self.src.h("}");
378 }
379 TypeDefKind::List(t) => {
380 self.src.h("struct {\n");
381 self.print_ty(iface, t);
382 self.src.h(" *ptr;\n");
383 self.src.h("size_t len;\n");
384 self.src.h("}");
385 }
386 TypeDefKind::Future(_) => todo!("print_anonymous_type for future"),
387 TypeDefKind::Stream(_) => todo!("print_anonymous_type for stream"),
388 }
389 self.src.h(" ");
390 self.print_namespace(iface);
391 self.print_ty_name(iface, &Type::Id(ty));
392 self.src.h("_t;\n");
393 self.types.insert(ty, mem::replace(&mut self.src.h, prev));
394 }
395
396 fn is_empty_type(&self, iface: &Interface, ty: &Type) -> bool {
397 let id = match ty {
398 Type::Id(id) => *id,
399 Type::Unit => return true,
400 _ => return false,
401 };
402 match &iface.types[id].kind {
403 TypeDefKind::Type(t) => self.is_empty_type(iface, t),
404 TypeDefKind::Record(r) => r.fields.is_empty(),
405 TypeDefKind::Tuple(t) => t.types.is_empty(),
406 _ => false,
407 }
408 }
409
410 fn print_intrinsics(&mut self) {
411 self.src.c("
414 __attribute__((weak, export_name(\"canonical_abi_realloc\")))
415 void *canonical_abi_realloc(
416 void *ptr,
417 size_t orig_size,
418 size_t org_align,
419 size_t new_size
420 ) {
421 void *ret = realloc(ptr, new_size);
422 if (!ret)
423 abort();
424 return ret;
425 }
426
427 __attribute__((weak, export_name(\"canonical_abi_free\")))
428 void canonical_abi_free(
429 void *ptr,
430 size_t size,
431 size_t align
432 ) {
433 free(ptr);
434 }
435 ");
436 }
437
438 fn print_namespace(&mut self, iface: &Interface) {
439 self.src.h(&iface.name.to_snake_case());
440 self.src.h("_");
441 }
442
443 fn print_dtor(&mut self, iface: &Interface, id: TypeId) {
444 let ty = Type::Id(id);
445 if !self.owns_anything(iface, &ty) {
446 return;
447 }
448 let pos = self.src.h.len();
449 self.src.h("void ");
450 self.print_namespace(iface);
451 self.print_ty_name(iface, &ty);
452 self.src.h("_free(");
453 self.print_namespace(iface);
454 self.print_ty_name(iface, &ty);
455 self.src.h("_t *ptr)");
456
457 self.src.c(&self.src.h[pos..].to_string());
458 self.src.h(";\n");
459 self.src.c(" {\n");
460 match &iface.types[id].kind {
461 TypeDefKind::Type(t) => self.free(iface, t, "ptr"),
462
463 TypeDefKind::Flags(_) => {}
464 TypeDefKind::Enum(_) => {}
465
466 TypeDefKind::Record(r) => {
467 for field in r.fields.iter() {
468 if !self.owns_anything(iface, &field.ty) {
469 continue;
470 }
471 self.free(
472 iface,
473 &field.ty,
474 &format!("&ptr->{}", field.name.to_snake_case()),
475 );
476 }
477 }
478
479 TypeDefKind::Tuple(t) => {
480 for (i, ty) in t.types.iter().enumerate() {
481 if !self.owns_anything(iface, ty) {
482 continue;
483 }
484 self.free(iface, ty, &format!("&ptr->f{i}"));
485 }
486 }
487
488 TypeDefKind::List(t) => {
489 if self.owns_anything(iface, t) {
490 self.src.c("for (size_t i = 0; i < ptr->len; i++) {\n");
491 self.free(iface, t, "&ptr->ptr[i]");
492 self.src.c("}\n");
493 }
494 uwriteln!(
495 self.src.c,
496 "canonical_abi_free(ptr->ptr, ptr->len * {}, {});",
497 self.sizes.size(t),
498 self.sizes.align(t),
499 );
500 }
501
502 TypeDefKind::Variant(v) => {
503 self.src.c("switch ((int32_t) ptr->tag) {\n");
504 for (i, case) in v.cases.iter().enumerate() {
505 if !self.owns_anything(iface, &case.ty) {
506 continue;
507 }
508 uwriteln!(self.src.c, "case {}: {{", i);
509 let expr = format!("&ptr->val.{}", case.name.to_snake_case());
510 self.free(iface, &case.ty, &expr);
511 self.src.c("break;\n");
512 self.src.c("}\n");
513 }
514 self.src.c("}\n");
515 }
516
517 TypeDefKind::Union(u) => {
518 self.src.c("switch ((int32_t) ptr->tag) {\n");
519 for (i, case) in u.cases.iter().enumerate() {
520 if !self.owns_anything(iface, &case.ty) {
521 continue;
522 }
523 uwriteln!(self.src.c, "case {i}: {{");
524 let expr = format!("&ptr->val.f{i}");
525 self.free(iface, &case.ty, &expr);
526 self.src.c("break;\n");
527 self.src.c("}\n");
528 }
529 self.src.c("}\n");
530 }
531
532 TypeDefKind::Option(t) => {
533 self.src.c("if (ptr->is_some) {\n");
534 self.free(iface, t, "&ptr->val");
535 self.src.c("}\n");
536 }
537
538 TypeDefKind::Expected(e) => {
539 self.src.c("if (!ptr->is_err) {\n");
540 if self.owns_anything(iface, &e.ok) {
541 self.free(iface, &e.ok, "&ptr->val.ok");
542 }
543 if self.owns_anything(iface, &e.err) {
544 self.src.c("} else {\n");
545 self.free(iface, &e.err, "&ptr->val.err");
546 }
547 self.src.c("}\n");
548 }
549 TypeDefKind::Future(_) => todo!("print_dtor for future"),
550 TypeDefKind::Stream(_) => todo!("print_dtor for stream"),
551 }
552 self.src.c("}\n");
553 }
554
555 fn owns_anything(&self, iface: &Interface, ty: &Type) -> bool {
556 let id = match ty {
557 Type::Id(id) => *id,
558 Type::String => return true,
559 Type::Handle(_) => return true,
560 _ => return false,
561 };
562 match &iface.types[id].kind {
563 TypeDefKind::Type(t) => self.owns_anything(iface, t),
564 TypeDefKind::Record(r) => r.fields.iter().any(|t| self.owns_anything(iface, &t.ty)),
565 TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.owns_anything(iface, t)),
566 TypeDefKind::Flags(_) => false,
567 TypeDefKind::Enum(_) => false,
568 TypeDefKind::List(_) => true,
569 TypeDefKind::Variant(v) => v.cases.iter().any(|c| self.owns_anything(iface, &c.ty)),
570 TypeDefKind::Union(v) => v
571 .cases
572 .iter()
573 .any(|case| self.owns_anything(iface, &case.ty)),
574 TypeDefKind::Option(t) => self.owns_anything(iface, t),
575 TypeDefKind::Expected(e) => {
576 self.owns_anything(iface, &e.ok) || self.owns_anything(iface, &e.err)
577 }
578 TypeDefKind::Future(_) => todo!("owns_anything for future"),
579 TypeDefKind::Stream(_) => todo!("owns_anything for stream"),
580 }
581 }
582
583 fn free(&mut self, iface: &Interface, ty: &Type, expr: &str) {
584 let prev = mem::take(&mut self.src.h);
585 self.print_namespace(iface);
586 self.print_ty_name(iface, ty);
587 let name = mem::replace(&mut self.src.h, prev);
588
589 self.src.c(&name);
590 self.src.c("_free(");
591 self.src.c(expr);
592 self.src.c(");\n");
593 }
594
595 fn docs(&mut self, docs: &Docs) {
596 let docs = match &docs.contents {
597 Some(docs) => docs,
598 None => return,
599 };
600 for line in docs.trim().lines() {
601 self.src.h("// ");
602 self.src.h(line);
603 self.src.h("\n");
604 }
605 }
606}
607
608impl Return {
609 fn return_single(&mut self, iface: &Interface, ty: &Type, orig_ty: &Type) {
610 let id = match ty {
611 Type::Id(id) => *id,
612 Type::String => {
613 self.retptrs.push(*orig_ty);
614 return;
615 }
616 Type::Unit => {
617 self.scalar = Some(Scalar::Void);
618 return;
619 }
620 _ => {
621 self.scalar = Some(Scalar::Type(*orig_ty));
622 return;
623 }
624 };
625 match &iface.types[id].kind {
626 TypeDefKind::Type(t) => self.return_single(iface, t, orig_ty),
627
628 TypeDefKind::Flags(_) => {
630 self.scalar = Some(Scalar::Type(*orig_ty));
631 }
632
633 TypeDefKind::Tuple(_) => self.splat_tuples(iface, ty, orig_ty),
635
636 TypeDefKind::Record(_) => {
638 self.retptrs.push(*orig_ty);
639 }
640
641 TypeDefKind::List(_) => self.retptrs.push(*orig_ty),
643
644 TypeDefKind::Enum(_) => {
646 self.scalar = Some(Scalar::Type(*orig_ty));
647 }
648
649 TypeDefKind::Option(ty) => {
653 self.scalar = Some(Scalar::OptionBool(*ty));
654 self.retptrs.push(*ty);
655 }
656
657 TypeDefKind::Expected(e) => {
661 if let Type::Id(err) = e.err {
662 if let TypeDefKind::Enum(enum_) = &iface.types[err].kind {
663 self.scalar = Some(Scalar::ExpectedEnum {
664 err,
665 max_err: enum_.cases.len(),
666 });
667 self.splat_tuples(iface, &e.ok, &e.ok);
668 return;
669 }
670 }
671
672 self.retptrs.push(*orig_ty);
675 }
676
677 TypeDefKind::Variant(_) | TypeDefKind::Union(_) => {
678 self.retptrs.push(*orig_ty);
679 }
680 TypeDefKind::Future(_) => todo!("return_single for future"),
681 TypeDefKind::Stream(_) => todo!("return_single for stream"),
682 }
683 }
684
685 fn splat_tuples(&mut self, iface: &Interface, ty: &Type, orig_ty: &Type) {
686 let id = match ty {
687 Type::Id(id) => *id,
688 Type::Unit => return,
689 _ => {
690 self.retptrs.push(*orig_ty);
691 return;
692 }
693 };
694 match &iface.types[id].kind {
695 TypeDefKind::Tuple(t) => {
696 self.splat_tuple = true;
697 self.retptrs.extend(t.types.iter());
698 }
699 _ => self.retptrs.push(*orig_ty),
700 }
701 }
702}
703
704impl Generator for C {
705 fn preprocess_one(&mut self, iface: &Interface, dir: Direction) {
706 let variant = Self::abi_variant(dir);
707 self.sizes.fill(iface);
708 self.in_import = variant == AbiVariant::GuestImport;
709 }
710
711 fn type_record(
712 &mut self,
713 iface: &Interface,
714 id: TypeId,
715 name: &str,
716 record: &Record,
717 docs: &Docs,
718 ) {
719 let prev = mem::take(&mut self.src.h);
720 self.docs(docs);
721 self.names.insert(&name.to_snake_case()).unwrap();
722 self.src.h("typedef struct {\n");
723 for field in record.fields.iter() {
724 self.print_ty(iface, &field.ty);
725 self.src.h(" ");
726 self.src.h(&field.name.to_snake_case());
727 self.src.h(";\n");
728 }
729 self.src.h("} ");
730 self.print_namespace(iface);
731 self.src.h(&name.to_snake_case());
732 self.src.h("_t;\n");
733
734 self.types.insert(id, mem::replace(&mut self.src.h, prev));
735 }
736
737 fn type_tuple(
738 &mut self,
739 iface: &Interface,
740 id: TypeId,
741 name: &str,
742 tuple: &Tuple,
743 docs: &Docs,
744 ) {
745 let prev = mem::take(&mut self.src.h);
746 self.docs(docs);
747 self.names.insert(&name.to_snake_case()).unwrap();
748 self.src.h("typedef struct {\n");
749 for (i, ty) in tuple.types.iter().enumerate() {
750 self.print_ty(iface, ty);
751 uwriteln!(self.src.h, " f{i};");
752 }
753 self.src.h("} ");
754 self.print_namespace(iface);
755 self.src.h(&name.to_snake_case());
756 self.src.h("_t;\n");
757
758 self.types.insert(id, mem::replace(&mut self.src.h, prev));
759 }
760
761 fn type_flags(
762 &mut self,
763 iface: &Interface,
764 id: TypeId,
765 name: &str,
766 flags: &Flags,
767 docs: &Docs,
768 ) {
769 let prev = mem::take(&mut self.src.h);
770 self.docs(docs);
771 self.names.insert(&name.to_snake_case()).unwrap();
772 self.src.h("typedef ");
773 let repr = flags_repr(flags);
774 self.src.h(int_repr(repr));
775 self.src.h(" ");
776 self.print_namespace(iface);
777 self.src.h(&name.to_snake_case());
778 self.src.h("_t;\n");
779
780 for (i, flag) in flags.flags.iter().enumerate() {
781 uwriteln!(
782 self.src.h,
783 "#define {}_{}_{} (1 << {})",
784 iface.name.to_shouty_snake_case(),
785 name.to_shouty_snake_case(),
786 flag.name.to_shouty_snake_case(),
787 i,
788 );
789 }
790
791 self.types.insert(id, mem::replace(&mut self.src.h, prev));
792 }
793
794 fn type_variant(
795 &mut self,
796 iface: &Interface,
797 id: TypeId,
798 name: &str,
799 variant: &Variant,
800 docs: &Docs,
801 ) {
802 let prev = mem::take(&mut self.src.h);
803 self.docs(docs);
804 self.names.insert(&name.to_snake_case()).unwrap();
805 self.src.h("typedef struct {\n");
806 self.src.h(int_repr(variant.tag()));
807 self.src.h(" tag;\n");
808 self.src.h("union {\n");
809 for case in variant.cases.iter() {
810 if self.is_empty_type(iface, &case.ty) {
811 continue;
812 }
813 self.print_ty(iface, &case.ty);
814 self.src.h(" ");
815 self.src.h(&case.name.to_snake_case());
816 self.src.h(";\n");
817 }
818 self.src.h("} val;\n");
819 self.src.h("} ");
820 self.print_namespace(iface);
821 self.src.h(&name.to_snake_case());
822 self.src.h("_t;\n");
823 for (i, case) in variant.cases.iter().enumerate() {
824 uwriteln!(
825 self.src.h,
826 "#define {}_{}_{} {}",
827 iface.name.to_shouty_snake_case(),
828 name.to_shouty_snake_case(),
829 case.name.to_shouty_snake_case(),
830 i,
831 );
832 }
833
834 self.types.insert(id, mem::replace(&mut self.src.h, prev));
835 }
836
837 fn type_union(
838 &mut self,
839 iface: &Interface,
840 id: TypeId,
841 name: &str,
842 union: &Union,
843 docs: &Docs,
844 ) {
845 let prev = mem::take(&mut self.src.h);
846 self.docs(docs);
847 self.names.insert(&name.to_snake_case()).unwrap();
848 self.src.h("typedef struct {\n");
849 self.src.h(int_repr(union.tag()));
850 self.src.h(" tag;\n");
851 self.src.h("union {\n");
852 for (i, case) in union.cases.iter().enumerate() {
853 self.print_ty(iface, &case.ty);
854 uwriteln!(self.src.h, " f{i};");
855 }
856 self.src.h("} val;\n");
857 self.src.h("} ");
858 self.print_namespace(iface);
859 self.src.h(&name.to_snake_case());
860 self.src.h("_t;\n");
861
862 self.types.insert(id, mem::replace(&mut self.src.h, prev));
863 }
864
865 fn type_option(
866 &mut self,
867 iface: &Interface,
868 id: TypeId,
869 name: &str,
870 payload: &Type,
871 docs: &Docs,
872 ) {
873 let prev = mem::take(&mut self.src.h);
874 self.docs(docs);
875 self.names.insert(&name.to_snake_case()).unwrap();
876 self.src.h("typedef struct {\n");
877 self.src.h("bool is_some;\n");
878 if !self.is_empty_type(iface, payload) {
879 self.print_ty(iface, payload);
880 self.src.h(" val;\n");
881 }
882 self.src.h("} ");
883 self.print_namespace(iface);
884 self.src.h(&name.to_snake_case());
885 self.src.h("_t;\n");
886
887 self.types.insert(id, mem::replace(&mut self.src.h, prev));
888 }
889
890 fn type_expected(
891 &mut self,
892 iface: &Interface,
893 id: TypeId,
894 name: &str,
895 expected: &Expected,
896 docs: &Docs,
897 ) {
898 let prev = mem::take(&mut self.src.h);
899 self.docs(docs);
900 self.names.insert(&name.to_snake_case()).unwrap();
901 self.src.h("typedef struct {\n");
902 self.src.h("bool is_err;\n");
903 self.src.h("union {\n");
904 if !self.is_empty_type(iface, &expected.ok) {
905 self.print_ty(iface, &expected.ok);
906 self.src.h(" ok;\n");
907 }
908 if !self.is_empty_type(iface, &expected.err) {
909 self.print_ty(iface, &expected.err);
910 self.src.h(" err;\n");
911 }
912 self.src.h("} val;\n");
913 self.src.h("} ");
914 self.print_namespace(iface);
915 self.src.h(&name.to_snake_case());
916 self.src.h("_t;\n");
917
918 self.types.insert(id, mem::replace(&mut self.src.h, prev));
919 }
920
921 fn type_enum(&mut self, iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
922 let prev = mem::take(&mut self.src.h);
923 self.docs(docs);
924 self.names.insert(&name.to_snake_case()).unwrap();
925 self.src.h("typedef ");
926 self.src.h(int_repr(enum_.tag()));
927 self.src.h(" ");
928 self.print_namespace(iface);
929 self.src.h(&name.to_snake_case());
930 self.src.h("_t;\n");
931 for (i, case) in enum_.cases.iter().enumerate() {
932 uwriteln!(
933 self.src.h,
934 "#define {}_{}_{} {}",
935 iface.name.to_shouty_snake_case(),
936 name.to_shouty_snake_case(),
937 case.name.to_shouty_snake_case(),
938 i,
939 );
940 }
941
942 self.types.insert(id, mem::replace(&mut self.src.h, prev));
943 }
944
945 fn type_resource(&mut self, iface: &Interface, ty: ResourceId) {
946 drop((iface, ty));
947 }
948
949 fn type_alias(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
950 let prev = mem::take(&mut self.src.h);
951 self.docs(docs);
952 self.src.h("typedef ");
953 self.print_ty(iface, ty);
954 self.src.h(" ");
955 self.print_namespace(iface);
956 self.src.h(&name.to_snake_case());
957 self.src.h("_t;\n");
958 self.types.insert(id, mem::replace(&mut self.src.h, prev));
959 }
960
961 fn type_list(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
962 let prev = mem::take(&mut self.src.h);
963 self.docs(docs);
964 self.src.h("typedef struct {\n");
965 self.print_ty(iface, ty);
966 self.src.h(" *ptr;\n");
967 self.src.h("size_t len;\n");
968 self.src.h("} ");
969 self.print_namespace(iface);
970 self.src.h(&name.to_snake_case());
971 self.src.h("_t;\n");
972 self.types.insert(id, mem::replace(&mut self.src.h, prev));
973 }
974
975 fn type_builtin(&mut self, iface: &Interface, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
976 drop((iface, _id, name, ty, docs));
977 }
978
979 fn import(&mut self, iface: &Interface, func: &Function) {
980 assert!(!func.is_async, "async not supported yet");
981 let prev = mem::take(&mut self.src);
982 let sig = iface.wasm_signature(AbiVariant::GuestImport, func);
983
984 uwriteln!(
988 self.src.c,
989 "__attribute__((import_module(\"{}\"), import_name(\"{}\")))",
990 iface.name,
991 func.name
992 );
993 let import_name = self.names.tmp(&format!(
994 "__wasm_import_{}_{}",
995 iface.name.to_snake_case(),
996 func.name.to_snake_case()
997 ));
998 match sig.results.len() {
999 0 => self.src.c("void"),
1000 1 => self.src.c(wasm_type(sig.results[0])),
1001 _ => unimplemented!("multi-value return not supported"),
1002 }
1003 self.src.c(" ");
1004 self.src.c(&import_name);
1005 self.src.c("(");
1006 for (i, param) in sig.params.iter().enumerate() {
1007 if i > 0 {
1008 self.src.c(", ");
1009 }
1010 self.src.c(wasm_type(*param));
1011 }
1012 if sig.params.len() == 0 {
1013 self.src.c("void");
1014 }
1015 self.src.c(");\n");
1016
1017 let c_sig = self.print_sig(iface, func);
1020 self.src.c(&c_sig.sig);
1021 self.src.c(" {\n");
1022
1023 let mut f = FunctionBindgen::new(self, c_sig, &import_name);
1024 for (pointer, param) in f.sig.params.iter() {
1025 f.locals.insert(param).unwrap();
1026
1027 if *pointer {
1028 f.params.push(format!("*{}", param));
1029 } else {
1030 f.params.push(param.clone());
1031 }
1032 }
1033 for ptr in f.sig.retptrs.iter() {
1034 f.locals.insert(ptr).unwrap();
1035 }
1036 iface.call(
1037 AbiVariant::GuestImport,
1038 LiftLower::LowerArgsLiftResults,
1039 func,
1040 &mut f,
1041 );
1042
1043 let FunctionBindgen { src, .. } = f;
1044
1045 self.src.c(&String::from(src));
1046 self.src.c("}\n");
1047
1048 let src = mem::replace(&mut self.src, prev);
1049 self.funcs
1050 .entry(iface.name.to_string())
1051 .or_insert(Vec::new())
1052 .push(Func { src });
1053 }
1054
1055 fn export(&mut self, iface: &Interface, func: &Function) {
1056 assert!(!func.is_async, "async not supported yet");
1057 let prev = mem::take(&mut self.src);
1058 let sig = iface.wasm_signature(AbiVariant::GuestExport, func);
1059
1060 let c_sig = self.print_sig(iface, func);
1063
1064 uwriteln!(
1067 self.src.c,
1068 "__attribute__((export_name(\"{}\")))",
1069 func.name
1070 );
1071 let import_name = self.names.tmp(&format!(
1072 "__wasm_export_{}_{}",
1073 iface.name.to_snake_case(),
1074 func.name.to_snake_case()
1075 ));
1076
1077 let mut f = FunctionBindgen::new(self, c_sig, &import_name);
1078 match sig.results.len() {
1079 0 => f.gen.src.c("void"),
1080 1 => f.gen.src.c(wasm_type(sig.results[0])),
1081 _ => unimplemented!("multi-value return not supported"),
1082 }
1083 f.gen.src.c(" ");
1084 f.gen.src.c(&import_name);
1085 f.gen.src.c("(");
1086 for (i, param) in sig.params.iter().enumerate() {
1087 if i > 0 {
1088 f.gen.src.c(", ");
1089 }
1090 let name = f.locals.tmp("arg");
1091 uwrite!(f.gen.src.c, "{} {}", wasm_type(*param), name);
1092 f.params.push(name);
1093 }
1094 if sig.params.len() == 0 {
1095 f.gen.src.c("void");
1096 }
1097 f.gen.src.c(") {\n");
1098
1099 iface.call(
1101 AbiVariant::GuestExport,
1102 LiftLower::LiftArgsLowerResults,
1103 func,
1104 &mut f,
1105 );
1106 let FunctionBindgen { src, .. } = f;
1107 self.src.c(&src);
1108 self.src.c("}\n");
1109
1110 let src = mem::replace(&mut self.src, prev);
1111 self.funcs
1112 .entry(iface.name.to_string())
1113 .or_insert(Vec::new())
1114 .push(Func { src });
1115 }
1116
1117 fn finish_one(&mut self, iface: &Interface, files: &mut Files) {
1118 uwrite!(
1119 self.src.h,
1120 "\
1121 #ifndef __BINDINGS_{0}_H
1122 #define __BINDINGS_{0}_H
1123 #ifdef __cplusplus
1124 extern \"C\"
1125 {{
1126 #endif
1127
1128 #include <stdint.h>
1129 #include <stdbool.h>
1130 ",
1131 iface.name.to_shouty_snake_case(),
1132 );
1133 uwrite!(
1134 self.src.c,
1135 "\
1136 #include <stdlib.h>
1137 #include <{}.h>
1138 ",
1139 iface.name.to_kebab_case(),
1140 );
1141
1142 self.print_intrinsics();
1143
1144 for (_, resource) in iface.resources.iter() {
1145 let ns = iface.name.to_snake_case();
1146 let name = resource.name.to_snake_case();
1147 uwrite!(
1148 self.src.h,
1149 "
1150 typedef struct {{
1151 uint32_t idx;
1152 }} {ns}_{name}_t;
1153 void {ns}_{name}_free({ns}_{name}_t *ptr);
1154 {ns}_{name}_t {ns}_{name}_clone({ns}_{name}_t *ptr);
1155 ",
1156 ns = ns,
1157 name = name,
1158 );
1159 uwrite!(
1160 self.src.c,
1161 "
1162 __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_drop_{name_orig}\")))
1163 void __resource_{name}_drop(uint32_t idx);
1164
1165 void {ns}_{name}_free({ns}_{name}_t *ptr) {{
1166 __resource_{name}_drop(ptr->idx);
1167 }}
1168
1169 __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_clone_{name_orig}\")))
1170 uint32_t __resource_{name}_clone(uint32_t idx);
1171
1172 {ns}_{name}_t {ns}_{name}_clone({ns}_{name}_t *ptr) {{
1173 return ({ns}_{name}_t){{__resource_{name}_clone(ptr->idx)}};
1174 }}
1175 ",
1176 ns = ns,
1177 name = name,
1178 name_orig = resource.name,
1179 );
1180
1181 if !self.in_import {
1186 uwrite!(
1187 self.src.h,
1188 "\
1189 {ns}_{name}_t {ns}_{name}_new(void *data);
1190 void* {ns}_{name}_get({ns}_{name}_t *ptr);
1191
1192 __attribute__((weak))
1193 void {ns}_{name}_dtor(void *data);
1194 ",
1195 ns = ns,
1196 name = name,
1197 );
1198 uwrite!(
1199 self.src.c,
1200 "
1201 __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_new_{name_orig}\")))
1202 uint32_t __resource_{name}_new(uint32_t val);
1203
1204 {ns}_{name}_t {ns}_{name}_new(void *data) {{
1205 return ({ns}_{name}_t){{__resource_{name}_new((uint32_t) data)}};
1206 }}
1207
1208 __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_get_{name_orig}\")))
1209 uint32_t __resource_{name}_get(uint32_t idx);
1210
1211 void* {ns}_{name}_get({ns}_{name}_t *ptr) {{
1212 return (void*) __resource_{name}_get(ptr->idx);
1213 }}
1214
1215 __attribute__((export_name(\"canonical_abi_drop_{name_orig}\")))
1216 void __resource_{name}_dtor(uint32_t val) {{
1217 if ({ns}_{name}_dtor)
1218 {ns}_{name}_dtor((void*) val);
1219 }}
1220 ",
1221 ns = ns,
1222 name = name,
1223 name_orig = resource.name,
1224 );
1225 }
1226 }
1227
1228 while !self.public_anonymous_types.is_empty() {
1234 for ty in mem::take(&mut self.public_anonymous_types) {
1235 self.print_anonymous_type(iface, ty);
1236 }
1237 }
1238
1239 let mut private_types = HashSet::new();
1247 self.public_anonymous_types = mem::take(&mut self.private_anonymous_types);
1248 while !self.public_anonymous_types.is_empty() {
1249 for ty in mem::take(&mut self.public_anonymous_types) {
1250 if self.types.contains_key(&ty) {
1251 continue;
1252 }
1253 private_types.insert(ty);
1254 self.print_anonymous_type(iface, ty);
1255 }
1256 }
1257
1258 if self.needs_string {
1259 uwrite!(
1260 self.src.h,
1261 "
1262 typedef struct {{
1263 char *ptr;
1264 size_t len;
1265 }} {0}_string_t;
1266
1267 void {0}_string_set({0}_string_t *ret, const char *s);
1268 void {0}_string_dup({0}_string_t *ret, const char *s);
1269 void {0}_string_free({0}_string_t *ret);
1270 ",
1271 iface.name.to_snake_case(),
1272 );
1273 self.src.c("#include <string.h>\n");
1274 uwrite!(
1275 self.src.c,
1276 "
1277 void {0}_string_set({0}_string_t *ret, const char *s) {{
1278 ret->ptr = (char*) s;
1279 ret->len = strlen(s);
1280 }}
1281
1282 void {0}_string_dup({0}_string_t *ret, const char *s) {{
1283 ret->len = strlen(s);
1284 ret->ptr = canonical_abi_realloc(NULL, 0, 1, ret->len);
1285 memcpy(ret->ptr, s, ret->len);
1286 }}
1287
1288 void {0}_string_free({0}_string_t *ret) {{
1289 canonical_abi_free(ret->ptr, ret->len, 1);
1290 ret->ptr = NULL;
1291 ret->len = 0;
1292 }}
1293 ",
1294 iface.name.to_snake_case(),
1295 );
1296 }
1297
1298 for id in iface.topological_types() {
1301 if let Some(ty) = self.types.get(&id) {
1302 if private_types.contains(&id) {
1303 self.src.c(ty);
1304 } else {
1305 self.src.h(ty);
1306 self.print_dtor(iface, id);
1307 }
1308 }
1309 }
1310
1311 if self.return_pointer_area_size > 0 {
1312 uwrite!(
1313 self.src.c,
1314 "
1315 __attribute__((aligned({})))
1316 static uint8_t RET_AREA[{}];
1317 ",
1318 self.return_pointer_area_align,
1319 self.return_pointer_area_size,
1320 );
1321 }
1322
1323 for (_module, funcs) in mem::take(&mut self.funcs) {
1324 for func in funcs {
1325 self.src.h(&func.src.h);
1326 self.src.c(&func.src.c);
1327 }
1328 }
1329
1330 self.src.h("\
1331 #ifdef __cplusplus
1332 }
1333 #endif
1334 ");
1335 self.src.h("#endif\n");
1336
1337 files.push(
1338 &format!("{}.c", iface.name.to_kebab_case()),
1339 self.src.c.as_bytes(),
1340 );
1341 files.push(
1342 &format!("{}.h", iface.name.to_kebab_case()),
1343 self.src.h.as_bytes(),
1344 );
1345 }
1346}
1347
1348struct FunctionBindgen<'a> {
1349 gen: &'a mut C,
1350 locals: Ns,
1351 src: wai_bindgen_gen_core::Source,
1353 sig: CSig,
1354 func_to_call: &'a str,
1355 block_storage: Vec<wai_bindgen_gen_core::Source>,
1356 blocks: Vec<(String, Vec<String>)>,
1357 payloads: Vec<String>,
1358 params: Vec<String>,
1359 wasm_return: Option<String>,
1360}
1361
1362impl<'a> FunctionBindgen<'a> {
1363 fn new(gen: &'a mut C, sig: CSig, func_to_call: &'a str) -> FunctionBindgen<'a> {
1364 FunctionBindgen {
1365 gen,
1366 sig,
1367 locals: Default::default(),
1368 src: Default::default(),
1369 func_to_call,
1370 block_storage: Vec::new(),
1371 blocks: Vec::new(),
1372 payloads: Vec::new(),
1373 params: Vec::new(),
1374 wasm_return: None,
1375 }
1376 }
1377
1378 fn store_op(&mut self, op: &str, loc: &str) {
1379 self.src.push_str(loc);
1380 self.src.push_str(" = ");
1381 self.src.push_str(op);
1382 self.src.push_str(";\n");
1383 }
1384
1385 fn load(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1386 results.push(format!("*(({}*) ({} + {}))", ty, operands[0], offset));
1387 }
1388
1389 fn load_ext(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1390 self.load(ty, offset, operands, results);
1391 let result = results.pop().unwrap();
1392 results.push(format!("(int32_t) ({})", result));
1393 }
1394
1395 fn store(&mut self, ty: &str, offset: i32, operands: &[String]) {
1396 uwriteln!(
1397 self.src,
1398 "*(({}*)({} + {})) = {};",
1399 ty,
1400 operands[1],
1401 offset,
1402 operands[0]
1403 );
1404 }
1405
1406 fn store_in_retptrs(&mut self, operands: &[String]) {
1407 if self.sig.ret.splat_tuple {
1408 assert_eq!(operands.len(), 1);
1409 let op = &operands[0];
1410 for (i, ptr) in self.sig.retptrs.clone().into_iter().enumerate() {
1411 self.store_op(&format!("{}.f{}", op, i), &format!("*{}", ptr));
1412 }
1413 } else {
1415 assert_eq!(operands.len(), self.sig.retptrs.len());
1416 for (op, ptr) in operands.iter().zip(self.sig.retptrs.clone()) {
1417 self.store_op(op, &format!("*{}", ptr));
1418 }
1419 }
1420 }
1421}
1422
1423impl Bindgen for FunctionBindgen<'_> {
1424 type Operand = String;
1425
1426 fn sizes(&self) -> &SizeAlign {
1427 &self.gen.sizes
1428 }
1429
1430 fn push_block(&mut self) {
1431 let prev = mem::take(&mut self.src);
1432 self.block_storage.push(prev);
1433 }
1434
1435 fn finish_block(&mut self, operands: &mut Vec<String>) {
1436 let to_restore = self.block_storage.pop().unwrap();
1437 let src = mem::replace(&mut self.src, to_restore);
1438 self.blocks.push((src.into(), mem::take(operands)));
1439 }
1440
1441 fn return_pointer(&mut self, _iface: &Interface, size: usize, align: usize) -> String {
1442 self.gen.return_pointer_area_size = self.gen.return_pointer_area_size.max(size);
1443 self.gen.return_pointer_area_align = self.gen.return_pointer_area_align.max(align);
1444 let ptr = self.locals.tmp("ptr");
1445 uwriteln!(self.src, "int32_t {} = (int32_t) &RET_AREA;", ptr);
1446 ptr
1447 }
1448
1449 fn is_list_canonical(&self, iface: &Interface, ty: &Type) -> bool {
1450 iface.all_bits_valid(ty)
1451 }
1452
1453 fn emit(
1454 &mut self,
1455 iface: &Interface,
1456 inst: &Instruction<'_>,
1457 operands: &mut Vec<String>,
1458 results: &mut Vec<String>,
1459 ) {
1460 match inst {
1461 Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
1462 Instruction::I32Const { val } => results.push(val.to_string()),
1463 Instruction::ConstZero { tys } => {
1464 for _ in tys.iter() {
1465 results.push("0".to_string());
1466 }
1467 }
1468
1469 Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
1471 Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
1472 Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
1473 Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
1474 Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
1475 Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
1476 Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
1477
1478 Instruction::I32FromU8
1479 | Instruction::I32FromS8
1480 | Instruction::I32FromU16
1481 | Instruction::I32FromS16
1482 | Instruction::I32FromU32 => {
1483 results.push(format!("(int32_t) ({})", operands[0]));
1484 }
1485 Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
1486 Instruction::I64FromU64 => {
1487 results.push(format!("(int64_t) ({})", operands[0]));
1488 }
1489
1490 Instruction::F32FromFloat32
1493 | Instruction::F64FromFloat64
1494 | Instruction::Float32FromF32
1495 | Instruction::Float64FromF64 => {
1496 results.push(operands[0].clone());
1497 }
1498
1499 Instruction::CharFromI32 => {
1501 results.push(format!("(uint32_t) ({})", operands[0]));
1502 }
1503 Instruction::I32FromChar => {
1504 results.push(format!("(int32_t) ({})", operands[0]));
1505 }
1506
1507 Instruction::Bitcasts { casts } => {
1508 for (cast, op) in casts.iter().zip(operands) {
1509 let op = op;
1510 match cast {
1511 Bitcast::I32ToF32 | Bitcast::I64ToF32 => {
1512 results
1513 .push(format!("((union {{ int32_t a; float b; }}){{ {} }}).b", op));
1514 }
1515 Bitcast::F32ToI32 | Bitcast::F32ToI64 => {
1516 results
1517 .push(format!("((union {{ float a; int32_t b; }}){{ {} }}).b", op));
1518 }
1519 Bitcast::I64ToF64 => {
1520 results.push(format!(
1521 "((union {{ int64_t a; double b; }}){{ {} }}).b",
1522 op
1523 ));
1524 }
1525 Bitcast::F64ToI64 => {
1526 results.push(format!(
1527 "((union {{ double a; int64_t b; }}){{ {} }}).b",
1528 op
1529 ));
1530 }
1531 Bitcast::I32ToI64 => {
1532 results.push(format!("(int64_t) {}", op));
1533 }
1534 Bitcast::I64ToI32 => {
1535 results.push(format!("(int32_t) {}", op));
1536 }
1537 Bitcast::None => results.push(op.to_string()),
1538 }
1539 }
1540 }
1541
1542 Instruction::UnitLower => {}
1543 Instruction::UnitLift => {
1544 results.push("INVALID".to_string());
1545 }
1546 Instruction::BoolFromI32 | Instruction::I32FromBool => {
1547 results.push(operands[0].clone());
1548 }
1549
1550 Instruction::I32FromOwnedHandle { .. } | Instruction::I32FromBorrowedHandle { .. } => {
1551 results.push(format!("({}).idx", operands[0]));
1552 }
1553
1554 Instruction::HandleBorrowedFromI32 { ty, .. }
1555 | Instruction::HandleOwnedFromI32 { ty, .. } => {
1556 results.push(format!(
1557 "({}_{}_t){{ {} }}",
1558 iface.name.to_snake_case(),
1559 iface.resources[*ty].name.to_snake_case(),
1560 operands[0],
1561 ));
1562 }
1563
1564 Instruction::RecordLower { record, .. } => {
1565 let op = &operands[0];
1566 for f in record.fields.iter() {
1567 results.push(format!("({}).{}", op, f.name.to_snake_case()));
1568 }
1569 }
1570 Instruction::RecordLift { ty, .. } => {
1571 let name = self.gen.type_string(iface, &Type::Id(*ty));
1572 let mut result = format!("({}) {{\n", name);
1573 for op in operands {
1574 uwriteln!(result, "{},", op);
1575 }
1576 result.push_str("}");
1577 results.push(result);
1578 }
1579
1580 Instruction::TupleLower { tuple, .. } => {
1581 let op = &operands[0];
1582 for i in 0..tuple.types.len() {
1583 results.push(format!("({}).f{}", op, i));
1584 }
1585 }
1586 Instruction::TupleLift { ty, .. } => {
1587 let name = self.gen.type_string(iface, &Type::Id(*ty));
1588 let mut result = format!("({}) {{\n", name);
1589 for op in operands {
1590 uwriteln!(result, "{},", op);
1591 }
1592 result.push_str("}");
1593 results.push(result);
1594 }
1595
1596 Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
1598 Int::U8 | Int::U16 | Int::U32 => {
1599 results.push(operands.pop().unwrap());
1600 }
1601 Int::U64 => {
1602 let name = self.gen.type_string(iface, &Type::Id(*ty));
1603 let tmp = self.locals.tmp("flags");
1604 uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
1605 results.push(format!("{tmp} & 0xffffffff"));
1606 results.push(format!("({tmp} >> 32) & 0xffffffff"));
1607 }
1608 },
1609
1610 Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
1611 Int::U8 | Int::U16 | Int::U32 => {
1612 results.push(operands.pop().unwrap());
1613 }
1614 Int::U64 => {
1615 let name = self.gen.type_string(iface, &Type::Id(*ty));
1616 let op0 = &operands[0];
1617 let op1 = &operands[1];
1618 results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
1619 }
1620 },
1621
1622 Instruction::VariantPayloadName => {
1623 let name = self.locals.tmp("payload");
1624 results.push(format!("*{}", name));
1625 self.payloads.push(name);
1626 }
1627
1628 Instruction::VariantLower {
1629 variant,
1630 results: result_types,
1631 ..
1632 } => {
1633 let blocks = self
1634 .blocks
1635 .drain(self.blocks.len() - variant.cases.len()..)
1636 .collect::<Vec<_>>();
1637 let payloads = self
1638 .payloads
1639 .drain(self.payloads.len() - variant.cases.len()..)
1640 .collect::<Vec<_>>();
1641
1642 let mut variant_results = Vec::with_capacity(result_types.len());
1643 for ty in result_types.iter() {
1644 let name = self.locals.tmp("variant");
1645 results.push(name.clone());
1646 self.src.push_str(wasm_type(*ty));
1647 self.src.push_str(" ");
1648 self.src.push_str(&name);
1649 self.src.push_str(";\n");
1650 variant_results.push(name);
1651 }
1652
1653 let expr_to_match = format!("({}).tag", operands[0]);
1654
1655 uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
1656 for (i, ((case, (block, block_results)), payload)) in
1657 variant.cases.iter().zip(blocks).zip(payloads).enumerate()
1658 {
1659 uwriteln!(self.src, "case {}: {{", i);
1660 if !self.gen.is_empty_type(iface, &case.ty) {
1661 let ty = self.gen.type_string(iface, &case.ty);
1662 uwrite!(
1663 self.src,
1664 "const {} *{} = &({}).val",
1665 ty,
1666 payload,
1667 operands[0],
1668 );
1669 self.src.push_str(".");
1670 self.src.push_str(&case.name.to_snake_case());
1671 self.src.push_str(";\n");
1672 }
1673 self.src.push_str(&block);
1674
1675 for (name, result) in variant_results.iter().zip(&block_results) {
1676 uwriteln!(self.src, "{} = {};", name, result);
1677 }
1678 self.src.push_str("break;\n}\n");
1679 }
1680 self.src.push_str("}\n");
1681 }
1682
1683 Instruction::VariantLift { variant, ty, .. } => {
1684 let blocks = self
1685 .blocks
1686 .drain(self.blocks.len() - variant.cases.len()..)
1687 .collect::<Vec<_>>();
1688
1689 let ty = self.gen.type_string(iface, &Type::Id(*ty));
1690 let result = self.locals.tmp("variant");
1691 uwriteln!(self.src, "{} {};", ty, result);
1692 uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1693 uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1694 for (i, (case, (block, block_results))) in
1695 variant.cases.iter().zip(blocks).enumerate()
1696 {
1697 uwriteln!(self.src, "case {}: {{", i);
1698 self.src.push_str(&block);
1699 assert!(block_results.len() == 1);
1700
1701 if !self.gen.is_empty_type(iface, &case.ty) {
1702 let mut dst = format!("{}.val", result);
1703 dst.push_str(".");
1704 dst.push_str(&case.name.to_snake_case());
1705 self.store_op(&block_results[0], &dst);
1706 }
1707 self.src.push_str("break;\n}\n");
1708 }
1709 self.src.push_str("}\n");
1710 results.push(result);
1711 }
1712
1713 Instruction::UnionLower {
1714 union,
1715 results: result_types,
1716 ..
1717 } => {
1718 let blocks = self
1719 .blocks
1720 .drain(self.blocks.len() - union.cases.len()..)
1721 .collect::<Vec<_>>();
1722 let payloads = self
1723 .payloads
1724 .drain(self.payloads.len() - union.cases.len()..)
1725 .collect::<Vec<_>>();
1726
1727 let mut union_results = Vec::with_capacity(result_types.len());
1728 for ty in result_types.iter() {
1729 let name = self.locals.tmp("unionres");
1730 results.push(name.clone());
1731 let ty = wasm_type(*ty);
1732 uwriteln!(self.src, "{ty} {name};");
1733 union_results.push(name);
1734 }
1735
1736 let op0 = &operands[0];
1737 uwriteln!(self.src, "switch (({op0}).tag) {{");
1738 for (i, ((case, (block, block_results)), payload)) in
1739 union.cases.iter().zip(blocks).zip(payloads).enumerate()
1740 {
1741 uwriteln!(self.src, "case {i}: {{");
1742 if !self.gen.is_empty_type(iface, &case.ty) {
1743 let ty = self.gen.type_string(iface, &case.ty);
1744 uwriteln!(self.src, "const {ty} *{payload} = &({op0}).val.f{i};");
1745 }
1746 self.src.push_str(&block);
1747
1748 for (name, result) in union_results.iter().zip(&block_results) {
1749 uwriteln!(self.src, "{name} = {result};");
1750 }
1751 self.src.push_str("break;\n}\n");
1752 }
1753 self.src.push_str("}\n");
1754 }
1755
1756 Instruction::UnionLift { union, ty, .. } => {
1757 let blocks = self
1758 .blocks
1759 .drain(self.blocks.len() - union.cases.len()..)
1760 .collect::<Vec<_>>();
1761
1762 let ty = self.gen.type_string(iface, &Type::Id(*ty));
1763 let result = self.locals.tmp("unionres");
1764 uwriteln!(self.src, "{} {};", ty, result);
1765 uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1766 uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1767 for (i, (_case, (block, block_results))) in
1768 union.cases.iter().zip(blocks).enumerate()
1769 {
1770 uwriteln!(self.src, "case {i}: {{");
1771 self.src.push_str(&block);
1772
1773 assert!(block_results.len() == 1);
1774 let dst = format!("{result}.val.f{i}");
1775 self.store_op(&block_results[0], &dst);
1776 self.src.push_str("break;\n}\n");
1777 }
1778 self.src.push_str("}\n");
1779 results.push(result);
1780 }
1781
1782 Instruction::OptionLower {
1783 results: result_types,
1784 payload,
1785 ..
1786 } => {
1787 let (mut some, some_results) = self.blocks.pop().unwrap();
1788 let (mut none, none_results) = self.blocks.pop().unwrap();
1789 let some_payload = self.payloads.pop().unwrap();
1790 let _none_payload = self.payloads.pop().unwrap();
1791
1792 for (i, ty) in result_types.iter().enumerate() {
1793 let name = self.locals.tmp("option");
1794 results.push(name.clone());
1795 self.src.push_str(wasm_type(*ty));
1796 self.src.push_str(" ");
1797 self.src.push_str(&name);
1798 self.src.push_str(";\n");
1799 let some_result = &some_results[i];
1800 uwriteln!(some, "{name} = {some_result};");
1801 let none_result = &none_results[i];
1802 uwriteln!(none, "{name} = {none_result};");
1803 }
1804
1805 let op0 = &operands[0];
1806 let ty = self.gen.type_string(iface, payload);
1807 let bind_some = if self.gen.is_empty_type(iface, payload) {
1808 String::new()
1809 } else {
1810 format!("const {ty} *{some_payload} = &({op0}).val;")
1811 };
1812 uwrite!(
1813 self.src,
1814 "
1815 if (({op0}).is_some) {{
1816 {bind_some}
1817 {some}
1818 }} else {{
1819 {none}
1820 }}
1821 "
1822 );
1823 }
1824
1825 Instruction::OptionLift { payload, ty, .. } => {
1826 let (some, some_results) = self.blocks.pop().unwrap();
1827 let (none, none_results) = self.blocks.pop().unwrap();
1828 assert!(none_results.len() == 1);
1829 assert!(some_results.len() == 1);
1830 let some_result = &some_results[0];
1831 assert_eq!(none_results[0], "INVALID");
1832
1833 let ty = self.gen.type_string(iface, &Type::Id(*ty));
1834 let result = self.locals.tmp("option");
1835 uwriteln!(self.src, "{ty} {result};");
1836 let op0 = &operands[0];
1837 let set_some = if self.gen.is_empty_type(iface, payload) {
1838 String::new()
1839 } else {
1840 format!("{result}.val = {some_result};")
1841 };
1842 uwrite!(
1843 self.src,
1844 "switch ({op0}) {{
1845 case 0: {{
1846 {result}.is_some = false;
1847 {none}
1848 break;
1849 }}
1850 case 1: {{
1851 {result}.is_some = true;
1852 {some}
1853 {set_some}
1854 break;
1855 }}
1856 }}"
1857 );
1858 results.push(result);
1859 }
1860
1861 Instruction::ExpectedLower {
1862 results: result_types,
1863 expected,
1864 ..
1865 } => {
1866 let (mut err, err_results) = self.blocks.pop().unwrap();
1867 let (mut ok, ok_results) = self.blocks.pop().unwrap();
1868 let err_payload = self.payloads.pop().unwrap();
1869 let ok_payload = self.payloads.pop().unwrap();
1870
1871 for (i, ty) in result_types.iter().enumerate() {
1872 let name = self.locals.tmp("expected");
1873 results.push(name.clone());
1874 self.src.push_str(wasm_type(*ty));
1875 self.src.push_str(" ");
1876 self.src.push_str(&name);
1877 self.src.push_str(";\n");
1878 let ok_result = &ok_results[i];
1879 uwriteln!(ok, "{name} = {ok_result};");
1880 let err_result = &err_results[i];
1881 uwriteln!(err, "{name} = {err_result};");
1882 }
1883
1884 let op0 = &operands[0];
1885 let ok_ty = self.gen.type_string(iface, &expected.ok);
1886 let err_ty = self.gen.type_string(iface, &expected.err);
1887 let bind_ok = if self.gen.is_empty_type(iface, &expected.ok) {
1888 String::new()
1889 } else {
1890 format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
1891 };
1892 let bind_err = if self.gen.is_empty_type(iface, &expected.err) {
1893 String::new()
1894 } else {
1895 format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
1896 };
1897 uwrite!(
1898 self.src,
1899 "
1900 if (({op0}).is_err) {{
1901 {bind_err}
1902 {err}
1903 }} else {{
1904 {bind_ok}
1905 {ok}
1906 }}
1907 "
1908 );
1909 }
1910
1911 Instruction::ExpectedLift { expected, ty, .. } => {
1912 let (err, err_results) = self.blocks.pop().unwrap();
1913 assert!(err_results.len() == 1);
1914 let err_result = &err_results[0];
1915 let (ok, ok_results) = self.blocks.pop().unwrap();
1916 assert!(ok_results.len() == 1);
1917 let ok_result = &ok_results[0];
1918
1919 let result = self.locals.tmp("expected");
1920 let set_ok = if self.gen.is_empty_type(iface, &expected.ok) {
1921 String::new()
1922 } else {
1923 format!("{result}.val.ok = {ok_result};")
1924 };
1925 let set_err = if self.gen.is_empty_type(iface, &expected.err) {
1926 String::new()
1927 } else {
1928 format!("{result}.val.err = {err_result};")
1929 };
1930
1931 let ty = self.gen.type_string(iface, &Type::Id(*ty));
1932 uwriteln!(self.src, "{ty} {result};");
1933 let op0 = &operands[0];
1934 uwrite!(
1935 self.src,
1936 "switch ({op0}) {{
1937 case 0: {{
1938 {result}.is_err = false;
1939 {ok}
1940 {set_ok}
1941 break;
1942 }}
1943 case 1: {{
1944 {result}.is_err = true;
1945 {err}
1946 {set_err}
1947 break;
1948 }}
1949 }}"
1950 );
1951 results.push(result);
1952 }
1953
1954 Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
1955 Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
1956
1957 Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
1958 results.push(format!("(int32_t) ({}).ptr", operands[0]));
1959 results.push(format!("(int32_t) ({}).len", operands[0]));
1960 }
1961 Instruction::ListCanonLift { element, ty, .. } => {
1962 let list_name = self.gen.type_string(iface, &Type::Id(*ty));
1963 let elem_name = self.gen.type_string(iface, element);
1964 results.push(format!(
1965 "({}) {{ ({}*)({}), (size_t)({}) }}",
1966 list_name, elem_name, operands[0], operands[1]
1967 ));
1968 }
1969 Instruction::StringLift { .. } => {
1970 let list_name = self.gen.type_string(iface, &Type::String);
1971 results.push(format!(
1972 "({}) {{ (char*)({}), (size_t)({}) }}",
1973 list_name, operands[0], operands[1]
1974 ));
1975 }
1976
1977 Instruction::ListLower { .. } => {
1978 let _body = self.blocks.pop().unwrap();
1979 results.push(format!("(int32_t) ({}).ptr", operands[0]));
1980 results.push(format!("(int32_t) ({}).len", operands[0]));
1981 }
1982
1983 Instruction::ListLift { element, ty, .. } => {
1984 let _body = self.blocks.pop().unwrap();
1985 let list_name = self.gen.type_string(iface, &Type::Id(*ty));
1986 let elem_name = self.gen.type_string(iface, element);
1987 results.push(format!(
1988 "({}) {{ ({}*)({}), (size_t)({}) }}",
1989 list_name, elem_name, operands[0], operands[1]
1990 ));
1991 }
1992 Instruction::IterElem { .. } => results.push("e".to_string()),
1993 Instruction::IterBasePointer => results.push("base".to_string()),
1994
1995 Instruction::CallWasm { sig, .. } => {
1996 match sig.results.len() {
1997 0 => {}
1998 1 => {
1999 self.src.push_str(wasm_type(sig.results[0]));
2000 let ret = self.locals.tmp("ret");
2001 self.wasm_return = Some(ret.clone());
2002 uwrite!(self.src, " {} = ", ret);
2003 results.push(ret);
2004 }
2005 _ => unimplemented!(),
2006 }
2007 self.src.push_str(self.func_to_call);
2008 self.src.push_str("(");
2009 for (i, op) in operands.iter().enumerate() {
2010 if i > 0 {
2011 self.src.push_str(", ");
2012 }
2013 self.src.push_str(op);
2014 }
2015 self.src.push_str(");\n");
2016 }
2017
2018 Instruction::CallInterface { module: _, func } => {
2019 let mut args = String::new();
2020 for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
2021 if i > 0 {
2022 args.push_str(", ");
2023 }
2024 if *byref {
2025 let name = self.locals.tmp("arg");
2026 let ty = self.gen.type_string(iface, &func.params[i].1);
2027 uwriteln!(self.src, "{} {} = {};", ty, name, op);
2028 args.push_str("&");
2029 args.push_str(&name);
2030 } else {
2031 args.push_str(op);
2032 }
2033 }
2034 match &self.sig.ret.scalar {
2035 None => {
2036 let mut retptrs = Vec::new();
2037 for ty in self.sig.ret.retptrs.iter() {
2038 let name = self.locals.tmp("ret");
2039 let ty = self.gen.type_string(iface, ty);
2040 uwriteln!(self.src, "{} {};", ty, name);
2041 if args.len() > 0 {
2042 args.push_str(", ");
2043 }
2044 args.push_str("&");
2045 args.push_str(&name);
2046 retptrs.push(name);
2047 }
2048 uwriteln!(self.src, "{}({});", self.sig.name, args);
2049 if self.sig.ret.splat_tuple {
2050 let ty = self.gen.type_string(iface, &func.result);
2051 results.push(format!("({}){{ {} }}", ty, retptrs.join(", ")));
2052 } else if self.sig.retptrs.len() > 0 {
2053 results.extend(retptrs);
2054 }
2055 }
2056 Some(Scalar::Void) => {
2057 uwriteln!(self.src, "{}({});", self.sig.name, args);
2058 results.push("INVALID".to_string());
2059 }
2060 Some(Scalar::Type(_)) => {
2061 let ret = self.locals.tmp("ret");
2062 let ty = self.gen.type_string(iface, &func.result);
2063 uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
2064 results.push(ret);
2065 }
2066 Some(Scalar::OptionBool(ty)) => {
2067 let ret = self.locals.tmp("ret");
2068 let val = self.locals.tmp("val");
2069 if args.len() > 0 {
2070 args.push_str(", ");
2071 }
2072 args.push_str("&");
2073 args.push_str(&val);
2074 let payload_ty = self.gen.type_string(iface, ty);
2075 uwriteln!(self.src, "{} {};", payload_ty, val);
2076 uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
2077 let option_ty = self.gen.type_string(iface, &func.result);
2078 let option_ret = self.locals.tmp("ret");
2079 uwrite!(
2080 self.src,
2081 "
2082 {ty} {ret};
2083 {ret}.is_some = {tag};
2084 {ret}.val = {val};
2085 ",
2086 ty = option_ty,
2087 ret = option_ret,
2088 tag = ret,
2089 val = val,
2090 );
2091 results.push(option_ret);
2092 }
2093 Some(Scalar::ExpectedEnum { err, max_err }) => {
2094 let ret = self.locals.tmp("ret");
2095 let mut ok_names = Vec::new();
2096 for ty in self.sig.ret.retptrs.iter() {
2097 let val = self.locals.tmp("ok");
2098 if args.len() > 0 {
2099 args.push_str(", ");
2100 }
2101 args.push_str("&");
2102 args.push_str(&val);
2103 let ty = self.gen.type_string(iface, ty);
2104 uwriteln!(self.src, "{} {};", ty, val);
2105 ok_names.push(val);
2106 }
2107 let err_ty = self.gen.type_string(iface, &Type::Id(*err));
2108 uwriteln!(
2109 self.src,
2110 "{} {} = {}({});",
2111 err_ty,
2112 ret,
2113 self.sig.name,
2114 args,
2115 );
2116 let expected_ty = self.gen.type_string(iface, &func.result);
2117 let expected_ret = self.locals.tmp("ret");
2118 uwrite!(
2119 self.src,
2120 "
2121 {ty} {ret};
2122 if ({tag} <= {max}) {{
2123 {ret}.is_err = true;
2124 {ret}.val.err = {tag};
2125 }} else {{
2126 {ret}.is_err = false;
2127 {set_ok}
2128 }}
2129 ",
2130 ty = expected_ty,
2131 ret = expected_ret,
2132 tag = ret,
2133 max = max_err,
2134 set_ok = if self.sig.ret.retptrs.len() == 0 {
2135 String::new()
2136 } else if self.sig.ret.splat_tuple {
2137 let mut s = String::new();
2138 for (i, name) in ok_names.iter().enumerate() {
2139 uwriteln!(s, "{}.val.ok.f{} = {};", expected_ret, i, name,);
2140 }
2141 s
2142 } else {
2143 let name = ok_names.pop().unwrap();
2144 format!("{}.val.ok = {};", expected_ret, name)
2145 },
2146 );
2147 results.push(expected_ret);
2148 }
2149 }
2150 }
2151 Instruction::Return { .. } if self.gen.in_import => match self.sig.ret.scalar {
2152 None => self.store_in_retptrs(operands),
2153 Some(Scalar::Void) => {
2154 assert_eq!(operands, &["INVALID"]);
2155 }
2156 Some(Scalar::Type(_)) => {
2157 assert_eq!(operands.len(), 1);
2158 self.src.push_str("return ");
2159 self.src.push_str(&operands[0]);
2160 self.src.push_str(";\n");
2161 }
2162 Some(Scalar::OptionBool(_)) => {
2163 assert_eq!(operands.len(), 1);
2164 let variant = &operands[0];
2165 self.store_in_retptrs(&[format!("{}.val", variant)]);
2166 self.src.push_str("return ");
2167 self.src.push_str(&variant);
2168 self.src.push_str(".is_some;\n");
2169 }
2170 Some(Scalar::ExpectedEnum { .. }) => {
2171 assert_eq!(operands.len(), 1);
2172 let variant = &operands[0];
2173 if self.sig.retptrs.len() > 0 {
2174 self.store_in_retptrs(&[format!("{}.val.ok", variant)]);
2175 }
2176 uwriteln!(self.src, "return {}.is_err ? {0}.val.err : -1;", variant);
2177 }
2178 },
2179 Instruction::Return { amt, .. } => {
2180 assert!(*amt <= 1);
2181 if *amt == 1 {
2182 uwriteln!(self.src, "return {};", operands[0]);
2183 }
2184 }
2185
2186 Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
2187 Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
2188 Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
2189 Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
2190 Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
2191 Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
2192 Instruction::F32Store { offset } => self.store("float", *offset, operands),
2193 Instruction::F64Store { offset } => self.store("double", *offset, operands),
2194 Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
2195 Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
2196
2197 Instruction::I32Load8U { offset } => {
2198 self.load_ext("uint8_t", *offset, operands, results)
2199 }
2200 Instruction::I32Load8S { offset } => {
2201 self.load_ext("int8_t", *offset, operands, results)
2202 }
2203 Instruction::I32Load16U { offset } => {
2204 self.load_ext("uint16_t", *offset, operands, results)
2205 }
2206 Instruction::I32Load16S { offset } => {
2207 self.load_ext("int16_t", *offset, operands, results)
2208 }
2209
2210 Instruction::Free { .. } => {
2211 uwriteln!(self.src, "free((void*) ({}));", operands[0]);
2212 }
2213
2214 i => unimplemented!("{:?}", i),
2215 }
2216 }
2217}
2218
2219#[derive(Default)]
2220struct Source {
2221 h: wai_bindgen_gen_core::Source,
2222 c: wai_bindgen_gen_core::Source,
2223}
2224
2225impl Source {
2226 fn c(&mut self, s: &str) {
2227 self.c.push_str(s);
2228 }
2229 fn h(&mut self, s: &str) {
2230 self.h.push_str(s);
2231 }
2232}
2233
2234fn wasm_type(ty: WasmType) -> &'static str {
2235 match ty {
2236 WasmType::I32 => "int32_t",
2237 WasmType::I64 => "int64_t",
2238 WasmType::F32 => "float",
2239 WasmType::F64 => "double",
2240 }
2241}
2242
2243fn int_repr(ty: Int) -> &'static str {
2244 match ty {
2245 Int::U8 => "uint8_t",
2246 Int::U16 => "uint16_t",
2247 Int::U32 => "uint32_t",
2248 Int::U64 => "uint64_t",
2249 }
2250}
2251
2252fn flags_repr(f: &Flags) -> Int {
2253 match f.repr() {
2254 FlagsRepr::U8 => Int::U8,
2255 FlagsRepr::U16 => Int::U16,
2256 FlagsRepr::U32(1) => Int::U32,
2257 FlagsRepr::U32(2) => Int::U64,
2258 repr => panic!("unimplemented flags {:?}", repr),
2259 }
2260}