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) {} | 
