Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #128330

Merged
merged 11 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2921,7 +2921,7 @@ impl<'a, K, V> Cursor<'a, K, V> {
/// Returns a reference to the key and value of the next element without
/// moving the cursor.
///
/// If the cursor is at the end of the map then `None` is returned
/// If the cursor is at the end of the map then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&self) -> Option<(&'a K, &'a V)> {
self.clone().next()
Expand Down Expand Up @@ -2963,7 +2963,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> {
/// Returns a reference to the key and value of the next element without
/// moving the cursor.
///
/// If the cursor is at the end of the map then `None` is returned
/// If the cursor is at the end of the map then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&mut self) -> Option<(&K, &mut V)> {
let (k, v) = self.inner.peek_next()?;
Expand Down Expand Up @@ -3061,7 +3061,7 @@ impl<'a, K, V, A> CursorMutKey<'a, K, V, A> {
/// Returns a reference to the key and value of the next element without
/// moving the cursor.
///
/// If the cursor is at the end of the map then `None` is returned
/// If the cursor is at the end of the map then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&mut self) -> Option<(&mut K, &mut V)> {
let current = self.current.as_mut()?;
Expand Down
65 changes: 35 additions & 30 deletions library/std/src/io/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,55 +209,60 @@ impl<T> Cursor<T>
where
T: AsRef<[u8]>,
{
/// Returns the remaining slice.
/// Splits the underlying slice at the cursor position and returns them.
///
/// # Examples
///
/// ```
/// #![feature(cursor_remaining)]
/// #![feature(cursor_split)]
/// use std::io::Cursor;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// assert_eq!(buff.remaining_slice(), &[1, 2, 3, 4, 5]);
/// assert_eq!(buff.split(), ([].as_slice(), [1, 2, 3, 4, 5].as_slice()));
///
/// buff.set_position(2);
/// assert_eq!(buff.remaining_slice(), &[3, 4, 5]);
///
/// buff.set_position(4);
/// assert_eq!(buff.remaining_slice(), &[5]);
/// assert_eq!(buff.split(), ([1, 2].as_slice(), [3, 4, 5].as_slice()));
///
/// buff.set_position(6);
/// assert_eq!(buff.remaining_slice(), &[]);
/// assert_eq!(buff.split(), ([1, 2, 3, 4, 5].as_slice(), [].as_slice()));
/// ```
#[unstable(feature = "cursor_remaining", issue = "86369")]
pub fn remaining_slice(&self) -> &[u8] {
let len = self.pos.min(self.inner.as_ref().len() as u64);
&self.inner.as_ref()[(len as usize)..]
#[unstable(feature = "cursor_split", issue = "86369")]
pub fn split(&self) -> (&[u8], &[u8]) {
let slice = self.inner.as_ref();
let pos = self.pos.min(slice.len() as u64);
slice.split_at(pos as usize)
}
}

/// Returns `true` if the remaining slice is empty.
impl<T> Cursor<T>
where
T: AsMut<[u8]>,
{
/// Splits the underlying slice at the cursor position and returns them
/// mutably.
///
/// # Examples
///
/// ```
/// #![feature(cursor_remaining)]
/// #![feature(cursor_split)]
/// use std::io::Cursor;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// buff.set_position(2);
/// assert!(!buff.is_empty());
/// assert_eq!(buff.split_mut(), ([].as_mut_slice(), [1, 2, 3, 4, 5].as_mut_slice()));
///
/// buff.set_position(5);
/// assert!(buff.is_empty());
/// buff.set_position(2);
/// assert_eq!(buff.split_mut(), ([1, 2].as_mut_slice(), [3, 4, 5].as_mut_slice()));
///
/// buff.set_position(10);
/// assert!(buff.is_empty());
/// buff.set_position(6);
/// assert_eq!(buff.split_mut(), ([1, 2, 3, 4, 5].as_mut_slice(), [].as_mut_slice()));
/// ```
#[unstable(feature = "cursor_remaining", issue = "86369")]
pub fn is_empty(&self) -> bool {
self.pos >= self.inner.as_ref().len() as u64
#[unstable(feature = "cursor_split", issue = "86369")]
pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
let slice = self.inner.as_mut();
let pos = self.pos.min(slice.len() as u64);
slice.split_at_mut(pos as usize)
}
}

Expand Down Expand Up @@ -319,15 +324,15 @@ where
T: AsRef<[u8]>,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = Read::read(&mut self.remaining_slice(), buf)?;
let n = Read::read(&mut Cursor::split(self).1, buf)?;
self.pos += n as u64;
Ok(n)
}

fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let prev_written = cursor.written();

Read::read_buf(&mut self.remaining_slice(), cursor.reborrow())?;
Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?;

self.pos += (cursor.written() - prev_written) as u64;

Expand All @@ -351,7 +356,7 @@ where
}

fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
let result = Read::read_exact(&mut self.remaining_slice(), buf);
let result = Read::read_exact(&mut Cursor::split(self).1, buf);

match result {
Ok(_) => self.pos += buf.len() as u64,
Expand All @@ -365,14 +370,14 @@ where
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let prev_written = cursor.written();

let result = Read::read_buf_exact(&mut self.remaining_slice(), cursor.reborrow());
let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow());
self.pos += (cursor.written() - prev_written) as u64;

result
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
let content = self.remaining_slice();
let content = Cursor::split(self).1;
let len = content.len();
buf.try_reserve(len)?;
buf.extend_from_slice(content);
Expand All @@ -383,7 +388,7 @@ where

fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
let content =
crate::str::from_utf8(self.remaining_slice()).map_err(|_| io::Error::INVALID_UTF8)?;
crate::str::from_utf8(Cursor::split(self).1).map_err(|_| io::Error::INVALID_UTF8)?;
let len = content.len();
buf.try_reserve(len)?;
buf.push_str(content);
Expand All @@ -399,7 +404,7 @@ where
T: AsRef<[u8]>,
{
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Ok(self.remaining_slice())
Ok(Cursor::split(self).1)
}
fn consume(&mut self, amt: usize) {
self.pos += amt as u64;
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,13 +676,13 @@ fn cursor_read_exact_eof() {

let mut r = slice.clone();
assert!(r.read_exact(&mut [0; 10]).is_err());
assert!(r.is_empty());
assert!(Cursor::split(&r).1.is_empty());

let mut r = slice;
let buf = &mut [0; 10];
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
assert!(r.read_buf_exact(buf.unfilled()).is_err());
assert!(r.is_empty());
assert!(Cursor::split(&r).1.is_empty());
assert_eq!(buf.filled(), b"123456");
}

Expand Down
112 changes: 60 additions & 52 deletions library/std/src/sys/personality/dwarf/eh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,45 +70,51 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result

let func_start = context.func_start;
let mut reader = DwarfReader::new(lsda);

let start_encoding = reader.read::<u8>();
// base address for landing pad offsets
let lpad_base = if start_encoding != DW_EH_PE_omit {
read_encoded_pointer(&mut reader, context, start_encoding)?
} else {
func_start
let lpad_base = unsafe {
let start_encoding = reader.read::<u8>();
// base address for landing pad offsets
if start_encoding != DW_EH_PE_omit {
read_encoded_pointer(&mut reader, context, start_encoding)?
} else {
func_start
}
};
let call_site_encoding = unsafe {
let ttype_encoding = reader.read::<u8>();
if ttype_encoding != DW_EH_PE_omit {
// Rust doesn't analyze exception types, so we don't care about the type table
reader.read_uleb128();
}

let ttype_encoding = reader.read::<u8>();
if ttype_encoding != DW_EH_PE_omit {
// Rust doesn't analyze exception types, so we don't care about the type table
reader.read_uleb128();
}

let call_site_encoding = reader.read::<u8>();
let call_site_table_length = reader.read_uleb128();
let action_table = reader.ptr.add(call_site_table_length as usize);
reader.read::<u8>()
};
let action_table = unsafe {
let call_site_table_length = reader.read_uleb128();
reader.ptr.add(call_site_table_length as usize)
};
let ip = context.ip;

if !USING_SJLJ_EXCEPTIONS {
// read the callsite table
while reader.ptr < action_table {
// these are offsets rather than pointers;
let cs_start = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_len = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_lpad = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_action_entry = reader.read_uleb128();
// Callsite table is sorted by cs_start, so if we've passed the ip, we
// may stop searching.
if ip < func_start.wrapping_add(cs_start) {
break;
}
if ip < func_start.wrapping_add(cs_start + cs_len) {
if cs_lpad == 0 {
return Ok(EHAction::None);
} else {
let lpad = lpad_base.wrapping_add(cs_lpad);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
unsafe {
// these are offsets rather than pointers;
let cs_start = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_len = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_lpad = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_action_entry = reader.read_uleb128();
// Callsite table is sorted by cs_start, so if we've passed the ip, we
// may stop searching.
if ip < func_start.wrapping_add(cs_start) {
break;
}
if ip < func_start.wrapping_add(cs_start + cs_len) {
if cs_lpad == 0 {
return Ok(EHAction::None);
} else {
let lpad = lpad_base.wrapping_add(cs_lpad);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
}
}
}
}
Expand All @@ -125,15 +131,15 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
}
let mut idx = ip.addr();
loop {
let cs_lpad = reader.read_uleb128();
let cs_action_entry = reader.read_uleb128();
let cs_lpad = unsafe { reader.read_uleb128() };
let cs_action_entry = unsafe { reader.read_uleb128() };
idx -= 1;
if idx == 0 {
// Can never have null landing pad for sjlj -- that would have
// been indicated by a -1 call site index.
// FIXME(strict provenance)
let lpad = ptr::with_exposed_provenance((cs_lpad + 1) as usize);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
return Ok(unsafe { interpret_cs_action(action_table, cs_action_entry, lpad) });
}
}
}
Expand All @@ -151,9 +157,9 @@ unsafe fn interpret_cs_action(
} else {
// If lpad != 0 and cs_action_entry != 0, we have to check ttype_index.
// If ttype_index == 0 under the condition, we take cleanup action.
let action_record = action_table.offset(cs_action_entry as isize - 1);
let action_record = unsafe { action_table.offset(cs_action_entry as isize - 1) };
let mut action_reader = DwarfReader::new(action_record);
let ttype_index = action_reader.read_sleb128();
let ttype_index = unsafe { action_reader.read_sleb128() };
if ttype_index == 0 {
EHAction::Cleanup(lpad)
} else if ttype_index > 0 {
Expand Down Expand Up @@ -186,18 +192,20 @@ unsafe fn read_encoded_offset(reader: &mut DwarfReader, encoding: u8) -> Result<
if encoding == DW_EH_PE_omit || encoding & 0xF0 != 0 {
return Err(());
}
let result = match encoding & 0x0F {
// despite the name, LLVM also uses absptr for offsets instead of pointers
DW_EH_PE_absptr => reader.read::<usize>(),
DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
DW_EH_PE_udata2 => reader.read::<u16>() as usize,
DW_EH_PE_udata4 => reader.read::<u32>() as usize,
DW_EH_PE_udata8 => reader.read::<u64>() as usize,
DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
_ => return Err(()),
let result = unsafe {
match encoding & 0x0F {
// despite the name, LLVM also uses absptr for offsets instead of pointers
DW_EH_PE_absptr => reader.read::<usize>(),
DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
DW_EH_PE_udata2 => reader.read::<u16>() as usize,
DW_EH_PE_udata4 => reader.read::<u32>() as usize,
DW_EH_PE_udata8 => reader.read::<u64>() as usize,
DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
_ => return Err(()),
}
};
Ok(result)
}
Expand Down Expand Up @@ -250,14 +258,14 @@ unsafe fn read_encoded_pointer(
if encoding & 0x0F != DW_EH_PE_absptr {
return Err(());
}
reader.read::<*const u8>()
unsafe { reader.read::<*const u8>() }
} else {
let offset = read_encoded_offset(reader, encoding & 0x0F)?;
let offset = unsafe { read_encoded_offset(reader, encoding & 0x0F)? };
base_ptr.wrapping_add(offset)
};

if encoding & DW_EH_PE_indirect != 0 {
ptr = *(ptr.cast::<*const u8>());
ptr = unsafe { *(ptr.cast::<*const u8>()) };
}

Ok(ptr)
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/personality/dwarf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// This module is used only by x86_64-pc-windows-gnu for now, but we
// are compiling it everywhere to avoid regressions.
#![allow(unused)]
#![forbid(unsafe_op_in_unsafe_fn)]

#[cfg(test)]
mod tests;
Expand All @@ -17,7 +18,6 @@ pub struct DwarfReader {
pub ptr: *const u8,
}

#[forbid(unsafe_op_in_unsafe_fn)]
impl DwarfReader {
pub fn new(ptr: *const u8) -> DwarfReader {
DwarfReader { ptr }
Expand Down
Loading
Loading