Skip to content

Commit a40e1ca

Browse files
author
bors-servo
authored
Auto merge of #1830 - jrmuizel:even-more-unsafe, r=Gankro
Make the writer even more unsafe. Instead of changing the length every write we just adjust the pointer. This avoids rust-lang/rust#45068. However we now need to ensure that we set the length when we are done. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/1830) <!-- Reviewable:end -->
2 parents c8d82c3 + 94e88a5 commit a40e1ca

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

webrender_api/src/display_list.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -492,15 +492,13 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> {
492492
// }
493493
//
494494

495-
struct UnsafeVecWriter<'a>(&'a mut Vec<u8>);
495+
struct UnsafeVecWriter(*mut u8);
496496

497-
impl<'a> Write for UnsafeVecWriter<'a> {
497+
impl Write for UnsafeVecWriter {
498498
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
499499
unsafe {
500-
let old_len = self.0.len();
501-
self.0.set_len(old_len + buf.len());
502-
debug_assert!(self.0.len() <= self.0.capacity());
503-
ptr::copy_nonoverlapping(buf.as_ptr(), self.0.as_mut_ptr().offset(old_len as isize), buf.len());
500+
ptr::copy_nonoverlapping(buf.as_ptr(), self.0, buf.len());
501+
self.0 = self.0.offset(buf.len() as isize);
504502
}
505503
Ok(buf.len())
506504
}
@@ -523,7 +521,16 @@ fn serialize_fast<T: Serialize>(vec: &mut Vec<u8>, e: &T) {
523521
bincode::serialize_into(&mut size,e , bincode::Infinite).unwrap();
524522
vec.reserve(size.0);
525523

526-
bincode::serialize_into(&mut UnsafeVecWriter(vec), e, bincode::Infinite).unwrap();
524+
let old_len = vec.len();
525+
let ptr = unsafe { vec.as_mut_ptr().offset(old_len as isize) };
526+
let mut w = UnsafeVecWriter(ptr);
527+
bincode::serialize_into(&mut w, e, bincode::Infinite).unwrap();
528+
529+
// fix up the length
530+
unsafe { vec.set_len(old_len + size.0); }
531+
532+
// make sure we wrote the right amount
533+
debug_assert!(((w.0 as usize) - (vec.as_ptr() as usize)) == vec.len());
527534
}
528535

529536
#[derive(Clone)]

0 commit comments

Comments
 (0)