Builds an incremental update to append into `image`.
(
&mut self,
image: &Image,
global_vars: HashMap<SymbolKey, GlobalVarInfo>,
program_vars: HashMap<SymbolKey, GlobalVarInfo>,
data: &[Option<ConstantDatum>],
| 256 | |
| 257 | /// Builds an incremental update to append into `image`. |
| 258 | pub(super) fn build_image_delta( |
| 259 | &mut self, |
| 260 | image: &Image, |
| 261 | global_vars: HashMap<SymbolKey, GlobalVarInfo>, |
| 262 | program_vars: HashMap<SymbolKey, GlobalVarInfo>, |
| 263 | data: &[Option<ConstantDatum>], |
| 264 | ) -> Result<ImageDelta> { |
| 265 | self.apply_fixups()?; |
| 266 | |
| 267 | let code_start = image.code.len().saturating_sub(1); |
| 268 | let constants_start = image.constants.len(); |
| 269 | let instrs_start = image.debug_info.instrs.len().saturating_sub(1); |
| 270 | let upcalls_start = image.upcalls.len(); |
| 271 | |
| 272 | debug_assert_eq!(code_start, instrs_start); |
| 273 | debug_assert!(code_start <= self.code.len()); |
| 274 | debug_assert!(constants_start <= self.constants.len()); |
| 275 | debug_assert!(image.data.len() <= data.len()); |
| 276 | debug_assert!(upcalls_start <= self.upcalls.len()); |
| 277 | |
| 278 | debug_assert_eq!(&image.code[..code_start], &self.code[..code_start]); |
| 279 | debug_assert_eq!(&image.debug_info.instrs[..instrs_start], &self.instrs[..instrs_start],); |
| 280 | debug_assert!( |
| 281 | self.constants.keys_to_vec().starts_with(image.constants.as_slice()), |
| 282 | "Image constants must match the compiler state prefix", |
| 283 | ); |
| 284 | debug_assert!( |
| 285 | self.upcalls.keys_to_vec().starts_with(image.upcalls.as_slice()), |
| 286 | "Image upcalls must match the compiler state prefix", |
| 287 | ); |
| 288 | debug_assert_eq!(image.data.as_slice(), &data[..image.data.len()]); |
| 289 | |
| 290 | let mut callables = HashMap::default(); |
| 291 | for (key, (start_pc, end_pc)) in &self.user_callables_addresses { |
| 292 | let previous = callables.insert(*start_pc, (key.clone(), true)); |
| 293 | debug_assert!(previous.is_none(), "An address can only start one callable"); |
| 294 | |
| 295 | let previous = callables.insert(*end_pc, (key.clone(), false)); |
| 296 | debug_assert!(previous.is_none(), "An address can only start one callable"); |
| 297 | } |
| 298 | |
| 299 | Ok(ImageDelta { |
| 300 | code: self.code[code_start..].to_vec(), |
| 301 | upcalls: self.upcalls.keys_to_vec_from(upcalls_start), |
| 302 | constants: self.constants.keys_to_vec_from(constants_start), |
| 303 | data: data[image.data.len()..].to_vec(), |
| 304 | instrs: self.instrs[instrs_start..].to_vec(), |
| 305 | callables, |
| 306 | global_vars, |
| 307 | program_vars, |
| 308 | }) |
| 309 | } |
| 310 | |
| 311 | #[cfg(test)] |
| 312 | /// Builds a ready-to-use `Image`. |
no test coverage detected