|
| 1 | +use rustc_abi::FieldIdx; |
1 | 2 | use rustc_middle::{
|
2 | 3 | mir::{BinOp, Body, Operand as MirOperand, Place, Rvalue, UnOp},
|
3 | 4 | ty::{ConstKind, TyCtxt, TyKind, inherent::ValueConst},
|
@@ -655,6 +656,30 @@ pub fn convert_rvalue_to_operand<'a>(
|
655 | 656 | }
|
656 | 657 |
|
657 | 658 | // Construct the enum variant object
|
| 659 | + instructions.push(oomir::Instruction::ConstructObject { |
| 660 | + dest: temp_aggregate_var.clone(), |
| 661 | + class_name: variant_class_name.clone(), |
| 662 | + }); |
| 663 | + |
| 664 | + // Set fields |
| 665 | + for (i, field) in variant_def.fields.iter().enumerate() { |
| 666 | + let field_name = format!("field{}", i); |
| 667 | + let field_mir_ty = field.ty(tcx, substs); |
| 668 | + let field_oomir_type = ty_to_oomir_type(field_mir_ty, tcx, data_types); |
| 669 | + let value_operand = convert_operand( |
| 670 | + &operands[FieldIdx::from_usize(i)], |
| 671 | + tcx, |
| 672 | + mir, |
| 673 | + data_types, |
| 674 | + ); |
| 675 | + instructions.push(oomir::Instruction::SetField { |
| 676 | + object_var: temp_aggregate_var.clone(), |
| 677 | + field_name, |
| 678 | + value: value_operand, |
| 679 | + field_ty: field_oomir_type, |
| 680 | + owner_class: variant_class_name.clone(), |
| 681 | + }); |
| 682 | + } |
658 | 683 | } else {
|
659 | 684 | // Union
|
660 | 685 | println!("Warning: Unhandled ADT Aggregate Kind -> Temp Placeholder");
|
@@ -726,7 +751,46 @@ pub fn convert_rvalue_to_operand<'a>(
|
726 | 751 | }
|
727 | 752 | }
|
728 | 753 | }
|
| 754 | + Rvalue::Discriminant(place) => { |
| 755 | + // get the discriminate of the place (usually an enum) |
| 756 | + // so basically just call `getVariantIdx` on the class in the place |
| 757 | + |
| 758 | + let place_name = place_to_string(place, tcx); |
| 759 | + let place_type = get_place_type(place, mir, tcx, data_types); |
| 760 | + |
| 761 | + let temp_discriminant_var = generate_temp_var_name(&base_temp_name); |
| 762 | + let place_class_name = match place_type.clone() { |
| 763 | + oomir::Type::Class(name) => name.clone(), |
| 764 | + _ => panic!("Discriminant on non-class type {:?}", place), |
| 765 | + }; |
| 766 | + let place_class = data_types.get(&place_class_name).unwrap(); |
| 767 | + let method_name = "getVariantIdx".to_string(); |
| 768 | + let method_return_tuple = place_class.methods.get(&method_name).unwrap(); |
| 769 | + let method_return_type = method_return_tuple.0.clone(); |
| 770 | + |
| 771 | + let method_ty = oomir::Signature { |
| 772 | + params: vec![], |
| 773 | + ret: Box::new(method_return_type.clone()), |
| 774 | + }; |
729 | 775 |
|
| 776 | + // we can InvokeStatic as lower2 makes the field index method static (it doesn't depend on fields at all) |
| 777 | + instructions.push(oomir::Instruction::InvokeVirtual { |
| 778 | + class_name: place_class_name.clone(), |
| 779 | + method_name, |
| 780 | + args: vec![], |
| 781 | + dest: Some(temp_discriminant_var.clone()), |
| 782 | + method_ty, |
| 783 | + operand: oomir::Operand::Variable { |
| 784 | + name: place_name, |
| 785 | + ty: place_type, |
| 786 | + }, |
| 787 | + }); |
| 788 | + |
| 789 | + result_operand = oomir::Operand::Variable { |
| 790 | + name: temp_discriminant_var, |
| 791 | + ty: method_return_type, |
| 792 | + }; |
| 793 | + } |
730 | 794 | // Handle other Rvalue variants by generating a placeholder
|
731 | 795 | _ => {
|
732 | 796 | println!(
|
|
0 commit comments