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