Collects an iterator of `InstructionAddressMap` into a `Vec` for insertion into a `FunctionAddressMap`. This will automatically coalesce adjacent instructions which map to the same original source position.
(
code_size: u32,
iter: impl IntoIterator<Item = (ir::SourceLoc, u32, u32)>,
)
| 234 | // into a `FunctionAddressMap`. This will automatically coalesce adjacent |
| 235 | // instructions which map to the same original source position. |
| 236 | fn collect_address_maps( |
| 237 | code_size: u32, |
| 238 | iter: impl IntoIterator<Item = (ir::SourceLoc, u32, u32)>, |
| 239 | ) -> Vec<InstructionAddressMap> { |
| 240 | let mut iter = iter.into_iter(); |
| 241 | let (mut cur_loc, mut cur_offset, mut cur_len) = match iter.next() { |
| 242 | Some(i) => i, |
| 243 | None => return Vec::new(), |
| 244 | }; |
| 245 | let mut ret = Vec::new(); |
| 246 | for (loc, offset, len) in iter { |
| 247 | // If this instruction is adjacent to the previous and has the same |
| 248 | // source location then we can "coalesce" it with the current |
| 249 | // instruction. |
| 250 | if cur_offset + cur_len == offset && loc == cur_loc { |
| 251 | cur_len += len; |
| 252 | continue; |
| 253 | } |
| 254 | |
| 255 | // Push an entry for the previous source item. |
| 256 | ret.push(InstructionAddressMap { |
| 257 | srcloc: cvt(cur_loc), |
| 258 | code_offset: cur_offset, |
| 259 | }); |
| 260 | // And push a "dummy" entry if necessary to cover the span of ranges, |
| 261 | // if any, between the previous source offset and this one. |
| 262 | if cur_offset + cur_len != offset { |
| 263 | ret.push(InstructionAddressMap { |
| 264 | srcloc: FilePos::default(), |
| 265 | code_offset: cur_offset + cur_len, |
| 266 | }); |
| 267 | } |
| 268 | // Update our current location to get extended later or pushed on at |
| 269 | // the end. |
| 270 | cur_loc = loc; |
| 271 | cur_offset = offset; |
| 272 | cur_len = len; |
| 273 | } |
| 274 | ret.push(InstructionAddressMap { |
| 275 | srcloc: cvt(cur_loc), |
| 276 | code_offset: cur_offset, |
| 277 | }); |
| 278 | if cur_offset + cur_len != code_size { |
| 279 | ret.push(InstructionAddressMap { |
| 280 | srcloc: FilePos::default(), |
| 281 | code_offset: cur_offset + cur_len, |
| 282 | }); |
| 283 | } |
| 284 | |
| 285 | return ret; |
| 286 | |
| 287 | fn cvt(loc: ir::SourceLoc) -> FilePos { |
| 288 | if loc.is_default() { |
| 289 | FilePos::default() |
| 290 | } else { |
| 291 | FilePos::new(loc.bits()) |
| 292 | } |
| 293 | } |