| 103 | } |
| 104 | |
| 105 | fn gen_arguments_method(formats: &[Rc<InstructionFormat>], fmt: &mut Formatter, is_mut: bool) { |
| 106 | let (method, mut_, rslice, as_slice) = if is_mut { |
| 107 | ( |
| 108 | "arguments_mut", |
| 109 | "mut ", |
| 110 | "core::slice::from_mut", |
| 111 | "as_mut_slice", |
| 112 | ) |
| 113 | } else { |
| 114 | ("arguments", "", "core::slice::from_ref", "as_slice") |
| 115 | }; |
| 116 | |
| 117 | fmt.add_block(&format!( |
| 118 | "pub fn {method}<'a>(&'a {mut_}self, pool: &'a {mut_}ir::ValueListPool) -> &'a {mut_}[Value]"), |
| 119 | |
| 120 | |fmt| { |
| 121 | let mut m = Match::new("*self"); |
| 122 | for format in formats { |
| 123 | let name = format!("Self::{}", format.name); |
| 124 | |
| 125 | // Formats with a value list put all of their arguments in the list. We don't split |
| 126 | // them up, just return it all as variable arguments. (I expect the distinction to go |
| 127 | // away). |
| 128 | if format.has_value_list { |
| 129 | m.arm( |
| 130 | name, |
| 131 | vec![format!("ref {}args", mut_), "..".to_string()], |
| 132 | format!("args.{as_slice}(pool)"), |
| 133 | ); |
| 134 | continue; |
| 135 | } |
| 136 | |
| 137 | // Fixed args. |
| 138 | let mut fields = Vec::new(); |
| 139 | let arg = if format.num_value_operands == 0 { |
| 140 | format!("&{mut_}[]") |
| 141 | } else if format.num_value_operands == 1 { |
| 142 | fields.push(format!("ref {mut_}arg")); |
| 143 | format!("{rslice}(arg)") |
| 144 | } else { |
| 145 | let arg = format!("args_arity{}", format.num_value_operands); |
| 146 | fields.push(format!("args: ref {mut_}{arg}")); |
| 147 | arg |
| 148 | }; |
| 149 | fields.push("..".into()); |
| 150 | |
| 151 | m.arm(name, fields, arg); |
| 152 | } |
| 153 | fmt.add_match(m); |
| 154 | }); |
| 155 | } |
| 156 | |
| 157 | /// Generate the boring parts of the InstructionData implementation. |
| 158 | /// |