|
1 | 1 | use std::mem; |
2 | 2 |
|
3 | | -use genco::prelude::*; |
| 3 | +use genco::{prelude::*, tokens::static_literal}; |
4 | 4 | use wit_bindgen_core::{ |
5 | 5 | abi::{Bindgen, Instruction}, |
6 | 6 | wit_parser::{Alignment, ArchitectureSize, Resolve, Result_, SizeAlign, Type, TypeDefKind}, |
@@ -518,7 +518,7 @@ impl Bindgen for Func<'_> { |
518 | 518 | } |
519 | 519 | }; |
520 | 520 |
|
521 | | - results.push(Operand::MultiValue((value.into(), err.into()))); |
| 521 | + results.push(Operand::DoubleValue(value.into(), err.into())); |
522 | 522 | } |
523 | 523 | Instruction::ResultLift { |
524 | 524 | result: |
@@ -608,10 +608,10 @@ impl Bindgen for Func<'_> { |
608 | 608 | results.push(Operand::SingleValue(err.into())); |
609 | 609 | } |
610 | 610 | GoType::ValueOrError(_) => { |
611 | | - results.push(Operand::MultiValue((value.into(), err.into()))); |
| 611 | + results.push(Operand::DoubleValue(value.into(), err.into())); |
612 | 612 | } |
613 | 613 | GoType::ValueOrOk(_) => { |
614 | | - results.push(Operand::MultiValue((value.into(), ok.into()))) |
| 614 | + results.push(Operand::DoubleValue(value.into(), ok.into())) |
615 | 615 | } |
616 | 616 | _ => todo!("TODO(#9): handle return type - {returns:?}"), |
617 | 617 | } |
@@ -756,7 +756,10 @@ impl Bindgen for Func<'_> { |
756 | 756 | Operand::SingleValue(_) => panic!( |
757 | 757 | "impossible: expected Operand::MultiValue but got Operand::SingleValue" |
758 | 758 | ), |
759 | | - Operand::MultiValue(bindings) => bindings, |
| 759 | + Operand::DoubleValue(ok, err) => (ok, err), |
| 760 | + Operand::MultiValue(_) => panic!( |
| 761 | + "impossible: expected Operand::DoubleValue but got Operand::MultiValue" |
| 762 | + ), |
760 | 763 | }; |
761 | 764 | quote_in! { self.body => |
762 | 765 | $['\r'] |
@@ -816,7 +819,7 @@ impl Bindgen for Func<'_> { |
816 | 819 | } |
817 | 820 | }; |
818 | 821 |
|
819 | | - results.push(Operand::MultiValue((result.into(), ok.into()))); |
| 822 | + results.push(Operand::DoubleValue(result.into(), ok.into())); |
820 | 823 | } |
821 | 824 | Instruction::OptionLower { |
822 | 825 | results: result_types, |
@@ -871,7 +874,12 @@ impl Bindgen for Func<'_> { |
871 | 874 | } |
872 | 875 | }; |
873 | 876 | } |
874 | | - Operand::MultiValue((value, ok)) => { |
| 877 | + Operand::MultiValue(_) => { |
| 878 | + panic!( |
| 879 | + "impossible: expected Operand::DoubleValue but got Operand::MultiValue" |
| 880 | + ) |
| 881 | + } |
| 882 | + Operand::DoubleValue(value, ok) => { |
875 | 883 | quote_in! { self.body => |
876 | 884 | $['\r'] |
877 | 885 | if $ok { |
@@ -917,7 +925,7 @@ impl Bindgen for Func<'_> { |
917 | 925 | $['\r'] |
918 | 926 | }; |
919 | 927 | match (&field_type, &op_clone) { |
920 | | - (GoType::Pointer(inner_type), Operand::MultiValue((val, ok))) => { |
| 928 | + (GoType::Pointer(inner_type), Operand::DoubleValue(val, ok)) => { |
921 | 929 | quote_in! { self.body => |
922 | 930 | $['\r'] |
923 | 931 | }; |
@@ -1486,8 +1494,73 @@ impl Bindgen for Func<'_> { |
1486 | 1494 | }; |
1487 | 1495 | results.push(Operand::SingleValue(result.into())); |
1488 | 1496 | } |
1489 | | - Instruction::TupleLower { .. } => todo!("implement instruction: {inst:?}"), |
1490 | | - Instruction::TupleLift { .. } => todo!("implement instruction: {inst:?}"), |
| 1497 | + Instruction::TupleLower { tuple, .. } => { |
| 1498 | + let tmp = self.tmp(); |
| 1499 | + let operand = &operands[0]; |
| 1500 | + for (i, _) in tuple.types.iter().enumerate() { |
| 1501 | + let field = GoIdentifier::public(format!("f-{i}")); |
| 1502 | + let var = &GoIdentifier::local(format!("f-{tmp}-{i}")); |
| 1503 | + quote_in! { self.body => |
| 1504 | + $['\r'] |
| 1505 | + $var := $operand.$field |
| 1506 | + } |
| 1507 | + results.push(Operand::SingleValue(var.into())); |
| 1508 | + } |
| 1509 | + } |
| 1510 | + Instruction::TupleLift { tuple, ty } => { |
| 1511 | + if tuple.types.len() != operands.len() { |
| 1512 | + panic!( |
| 1513 | + "impossible: expected {} operands but got {}", |
| 1514 | + tuple.types.len(), |
| 1515 | + operands.len() |
| 1516 | + ); |
| 1517 | + } |
| 1518 | + let tmp = self.tmp(); |
| 1519 | + let value = &GoIdentifier::local(format!("value{tmp}")); |
| 1520 | + |
| 1521 | + let mut ty_tokens = Tokens::new(); |
| 1522 | + if let Some(ty) = resolve |
| 1523 | + .types |
| 1524 | + .get(ty.clone()) |
| 1525 | + .expect("failed to find tuple type definition") |
| 1526 | + .name |
| 1527 | + .as_ref() |
| 1528 | + { |
| 1529 | + let ty_name = GoIdentifier::public(ty); |
| 1530 | + ty_name.format_into(&mut ty_tokens); |
| 1531 | + } else { |
| 1532 | + ty_tokens.append(static_literal("struct{")); |
| 1533 | + if let Some((last, typs)) = tuple.types.split_last() { |
| 1534 | + for (i, typ) in typs.iter().enumerate() { |
| 1535 | + let go_type = resolve_type(typ, resolve); |
| 1536 | + let field = GoIdentifier::public(format!("f-{i}")); |
| 1537 | + field.format_into(&mut ty_tokens); |
| 1538 | + ty_tokens.space(); |
| 1539 | + go_type.format_into(&mut ty_tokens); |
| 1540 | + ty_tokens.append(static_literal(";")); |
| 1541 | + ty_tokens.space(); |
| 1542 | + } |
| 1543 | + let field = GoIdentifier::public(format!("f-{}", typs.len())); |
| 1544 | + field.format_into(&mut ty_tokens); |
| 1545 | + let go_type = resolve_type(last, resolve); |
| 1546 | + ty_tokens.space(); |
| 1547 | + ty_tokens.append(go_type); |
| 1548 | + } |
| 1549 | + ty_tokens.append(static_literal("}")); |
| 1550 | + } |
| 1551 | + quote_in! { self.body => |
| 1552 | + $['\r'] |
| 1553 | + var $value $ty_tokens |
| 1554 | + } |
| 1555 | + for (i, (operand, _)) in operands.iter().zip(&tuple.types).enumerate() { |
| 1556 | + let field = &GoIdentifier::public(format!("f-{i}")); |
| 1557 | + quote_in! { self.body => |
| 1558 | + $['\r'] |
| 1559 | + $value.$field = $operand |
| 1560 | + } |
| 1561 | + } |
| 1562 | + results.push(Operand::SingleValue(value.into())); |
| 1563 | + } |
1491 | 1564 | Instruction::FlagsLower { .. } => todo!("implement instruction: {inst:?}"), |
1492 | 1565 | Instruction::FlagsLift { .. } => todo!("implement instruction: {inst:?}"), |
1493 | 1566 | Instruction::VariantLift { .. } => { |
|
0 commit comments