diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/long_mode/display.rs | 168 |
1 files changed, 89 insertions, 79 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 45c488e..c69e648 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -893,22 +893,27 @@ impl DisplaySink for alloc::string::String { fn write_u8(&mut self, mut v: u8) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((8 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((8 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } self.reserve(printed_size); let buf = unsafe { self.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -916,10 +921,6 @@ impl DisplaySink for alloc::string::String { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } /// write a u16 to the output as a base-16 integer. @@ -931,22 +932,27 @@ impl DisplaySink for alloc::string::String { fn write_u16(&mut self, mut v: u16) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((16 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((16 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } self.reserve(printed_size); let buf = unsafe { self.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -954,10 +960,6 @@ impl DisplaySink for alloc::string::String { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } /// write a u32 to the output as a base-16 integer. @@ -969,22 +971,27 @@ impl DisplaySink for alloc::string::String { fn write_u32(&mut self, mut v: u32) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((32 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((32 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } self.reserve(printed_size); let buf = unsafe { self.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -992,10 +999,6 @@ impl DisplaySink for alloc::string::String { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } /// write a u64 to the output as a base-16 integer. @@ -1007,22 +1010,27 @@ impl DisplaySink for alloc::string::String { fn write_u64(&mut self, mut v: u64) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((64 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((64 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } self.reserve(printed_size); let buf = unsafe { self.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -1030,10 +1038,6 @@ impl DisplaySink for alloc::string::String { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } fn span_start(&mut self, _ty: TokenType) {} @@ -1047,7 +1051,7 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { let new_bytes = s.as_bytes(); if new_bytes.len() == 0 { - unsafe { unreachable_kinda_unchecked() } + return Ok(()); } if new_bytes.len() >= 16 { @@ -1279,20 +1283,25 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { fn write_u8(&mut self, mut v: u8) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((8 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((8 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } let buf = unsafe { self.buf.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -1300,10 +1309,6 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } /// write a u16 to the output as a base-16 integer. @@ -1315,20 +1320,25 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { fn write_u16(&mut self, mut v: u16) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((16 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((16 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } let buf = unsafe { self.buf.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -1336,10 +1346,6 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } /// write a u32 to the output as a base-16 integer. @@ -1351,20 +1357,25 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { fn write_u32(&mut self, mut v: u32) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((32 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((32 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } let buf = unsafe { self.buf.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -1372,10 +1383,6 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { } } - unsafe { - buf.set_len(buf.len() + printed_size); - } - Ok(()) } /// write a u64 to the output as a base-16 integer. @@ -1387,20 +1394,25 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { fn write_u64(&mut self, mut v: u64) -> Result<(), core::fmt::Error> { // we can fairly easily predict the size of a formatted string here with lzcnt, which also // means we can write directly into the correct offsets of the output string. - let mut printed_size = ((64 - v.leading_zeros() + 3) >> 2) as usize; + let printed_size = ((64 - v.leading_zeros() + 3) >> 2) as usize; if printed_size == 0 { - printed_size = 1; + return self.write_fixed_size("0"); } let buf = unsafe { self.buf.as_mut_vec() }; - let p = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) }; - let mut curr = printed_size; + let new_len = buf.len() + printed_size; + + unsafe { + buf.set_len(new_len); + } + let mut p = unsafe { buf.as_mut_ptr().offset(new_len as isize) }; + loop { let digit = v % 16; let c = c_to_hex(digit as u8); - curr -= 1; unsafe { - p.offset(curr as isize).write(c); + p = p.offset(-1); + p.write(c); } v = v / 16; if v == 0 { @@ -1408,8 +1420,6 @@ impl<'buf> DisplaySink for InstructionTextSink<'buf> { } } - unsafe { buf.set_len(buf.len() + printed_size); } - Ok(()) } fn span_start(&mut self, _ty: TokenType) {} |