(
previous_locals: &[VerificationType],
locals: &[VerificationType],
stack: Vec<VerificationType>,
instruction_delta: u16,
byte_delta: u16,
)
| 315 | stack, |
| 316 | )); |
| 317 | previous_locals = locals; |
| 318 | previous_instruction_offset = Some(target); |
| 319 | } |
| 320 | |
| 321 | if frames.is_empty() { |
| 322 | Ok(Vec::new()) |
| 323 | } else { |
| 324 | Ok(vec![Attribute::StackMapTable { name_index, frames }]) |
| 325 | } |
| 326 | } |
| 327 | |
| 328 | fn compact_stack_frame( |
| 329 | offset_delta: u16, |
| 330 | previous_locals: &[VerificationType], |
| 331 | locals: &[VerificationType], |
| 332 | stack: Vec<VerificationType>, |
| 333 | ) -> StackFrame { |
| 334 | if locals == previous_locals { |
| 335 | return match stack.len() { |
| 336 | 0 => StackFrame::SameFrameExtended { |
| 337 | frame_type: 251, |
| 338 | offset_delta, |
| 339 | }, |
| 340 | 1 => StackFrame::SameLocals1StackItemFrameExtended { |
| 341 | frame_type: 247, |
| 342 | offset_delta, |
| 343 | stack, |
| 344 | }, |
| 345 | _ => StackFrame::FullFrame { |
| 346 | frame_type: 255, |
| 347 | offset_delta, |
| 348 | locals: locals.to_vec(), |
| 349 | stack, |
| 350 | }, |
| 351 | }; |
| 352 | } |
| 353 | |
| 354 | if stack.is_empty() && locals.starts_with(previous_locals) { |
| 355 | let appended = &locals[previous_locals.len()..]; |
| 356 | if (1..=3).contains(&appended.len()) { |
| 357 | return StackFrame::AppendFrame { |
| 358 | frame_type: 251 + appended.len() as u8, |
| 359 | offset_delta, |
| 360 | locals: appended.to_vec(), |
| 361 | }; |
| 362 | } |
| 363 | } |
| 364 | if stack.is_empty() && previous_locals.starts_with(locals) { |
| 365 | let removed = previous_locals.len() - locals.len(); |
| 366 | if (1..=3).contains(&removed) { |
| 367 | return StackFrame::ChopFrame { |
| 368 | frame_type: 251 - removed as u8, |
| 369 | offset_delta, |
| 370 | }; |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | StackFrame::FullFrame { |
no test coverage detected