Skip to content

Commit

Permalink
support mcopy (#7130)
Browse files Browse the repository at this point in the history
  • Loading branch information
emo-eth committed Feb 14, 2024
1 parent 85669c2 commit 3cdee82
Showing 1 changed file with 37 additions and 9 deletions.
46 changes: 37 additions & 9 deletions crates/debugger/src/tui/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,30 +513,32 @@ impl DebuggerContext<'_> {
// Color memory region based on read/write.
let mut offset = None;
let mut size = None;
let mut write_offset = None;
let mut write_size = None;
let mut color = None;
if let Instruction::OpCode(op) = step.instruction {
let stack_len = step.stack.len();
if stack_len > 0 {
if let Some(accesses) = get_buffer_accesses(op, &step.stack) {
if accesses.read.as_ref().is_some_and(|a| a.0 == self.active_buffer) {
let read_access = accesses.read.unwrap();
if let Some(read_access) = accesses.read {
offset = Some(read_access.1.offset);
size = Some(read_access.1.size);
color = Some(Color::Cyan);
} else if let Some(write_access) = accesses.write {
// TODO: with MCOPY, it will be possible to both read from and write to the
// memory buffer with the same opcode
}
if let Some(write_access) = accesses.write {
if self.active_buffer == BufferKind::Memory {
offset = Some(write_access.offset);
size = Some(write_access.size);
color = Some(Color::Red);
write_offset = Some(write_access.offset);
write_size = Some(write_access.size);
}
}
}
}
}

// color word on previous write op
// TODO: technically it's possible for this to conflict with the current op, ie, with
// subsequent MCOPYs, but solc can't seem to generate that code even with high optimizer
// settings
if self.current_step > 0 {
let prev_step = self.current_step - 1;
let prev_step = &self.debug_steps()[prev_step];
Expand Down Expand Up @@ -573,15 +575,40 @@ impl DebuggerContext<'_> {
// Word hex bytes.
hex_bytes_spans(buf_word, &mut spans, |j, _| {
let mut byte_color = Color::White;
let mut end = None;
let idx = i * 32 + j;
if let (Some(offset), Some(size), Some(color)) = (offset, size, color) {
let idx = i * 32 + j;
end = Some(offset + size);
if (offset..offset + size).contains(&idx) {
// [offset, offset + size] is the memory region to be colored.
// If a byte at row i and column j in the memory panel
// falls in this region, set the color.
byte_color = color;
}
}
if let (Some(write_offset), Some(write_size)) = (write_offset, write_size) {
// check for overlap with read region
let write_end = write_offset + write_size;
if let Some(read_end) = end {
let read_start = offset.unwrap();
if (write_offset..write_end).contains(&read_end) {
// if it contains end, start from write_start up to read_end
if (write_offset..read_end).contains(&idx) {
return Style::new().fg(Color::Yellow);
}
} else if (write_offset..write_end).contains(&read_start) {
// otherwise if it contains read start, start from read_start up to
// write_end
if (read_start..write_end).contains(&idx) {
return Style::new().fg(Color::Yellow);
}
}
}
if (write_offset..write_end).contains(&idx) {
byte_color = Color::Red;
}
}

Style::new().fg(byte_color)
});

Expand Down Expand Up @@ -682,6 +709,7 @@ fn get_buffer_accesses(op: u8, stack: &[U256]) -> Option<BufferAccesses> {
opcode::CREATE | opcode::CREATE2 => (Some((BufferKind::Memory, 2, 3)), None),
opcode::CALL | opcode::CALLCODE => (Some((BufferKind::Memory, 4, 5)), None),
opcode::DELEGATECALL | opcode::STATICCALL => (Some((BufferKind::Memory, 3, 4)), None),
opcode::MCOPY => (Some((BufferKind::Memory, 2, 3)), Some((1, 3))),
_ => Default::default(),
};

Expand Down

0 comments on commit 3cdee82

Please sign in to comment.