| 153 | } |
| 154 | |
| 155 | fn find_or_push_const(chunk: &mut SSAChunk, v: Val) -> Option<u16> { |
| 156 | let target: Value = if v.is_int() { |
| 157 | Value::Int(v.as_int()) |
| 158 | } else if v.is_float() { |
| 159 | Value::Float(v.as_float()) |
| 160 | } else { |
| 161 | return None; |
| 162 | }; |
| 163 | let pos = chunk.constants.iter().position(|c| match (c, &target) { |
| 164 | // -0.0 and 0.0 compare `==` but must not share a slot, or the folded sign is lost. |
| 165 | (Value::Float(a), Value::Float(b)) => a.to_bits() == b.to_bits(), |
| 166 | _ => c == &target, |
| 167 | }); |
| 168 | if let Some(pos) = pos { |
| 169 | return u16::try_from(pos).ok(); |
| 170 | } |
| 171 | let idx = chunk.constants.len(); |
| 172 | if idx >= u16::MAX as usize { return None; } |
| 173 | chunk.constants.push(target); |
| 174 | u16::try_from(idx).ok() |
| 175 | } |
| 176 | |
| 177 | fn const_to_val(constants: &[Value], idx: u16) -> Option<Val> { |
| 178 | match constants.get(idx as usize)? { |