Skip to content

Commit 23a77dc

Browse files
committed
Also move read-LEB to using iterators
1 parent 260c250 commit 23a77dc

File tree

3 files changed

+25
-25
lines changed

3 files changed

+25
-25
lines changed

compiler/rustc_serialize/src/leb128.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,25 @@ impl_write_unsigned_leb128!(write_usize_leb128, usize);
4949

5050
macro_rules! impl_read_unsigned_leb128 {
5151
($fn_name:ident, $int_ty:ty) => {
52+
// This returns `Option` to avoid needing to emit the panic paths here.
53+
// Letting the caller do it instead helps keep our code size small.
5254
#[inline]
53-
pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty {
55+
pub fn $fn_name(slice: &mut std::slice::Iter<'_, u8>) -> Option<$int_ty> {
5456
// The first iteration of this loop is unpeeled. This is a
5557
// performance win because this code is hot and integer values less
5658
// than 128 are very common, typically occurring 50-80% or more of
5759
// the time, even for u64 and u128.
58-
let byte = slice[*position];
59-
*position += 1;
60+
let byte = *(slice.next()?);
6061
if (byte & 0x80) == 0 {
61-
return byte as $int_ty;
62+
return Some(byte as $int_ty);
6263
}
6364
let mut result = (byte & 0x7F) as $int_ty;
6465
let mut shift = 7;
6566
loop {
66-
let byte = slice[*position];
67-
*position += 1;
67+
let byte = *(slice.next()?);
6868
if (byte & 0x80) == 0 {
6969
result |= (byte as $int_ty) << shift;
70-
return result;
70+
return Some(result);
7171
} else {
7272
result |= ((byte & 0x7F) as $int_ty) << shift;
7373
}
@@ -126,15 +126,16 @@ impl_write_signed_leb128!(write_isize_leb128, isize);
126126

127127
macro_rules! impl_read_signed_leb128 {
128128
($fn_name:ident, $int_ty:ty) => {
129+
// This returns `Option` to avoid needing to emit the panic paths here.
130+
// Letting the caller do it instead helps keep our code size small.
129131
#[inline]
130-
pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty {
132+
pub fn $fn_name(slice: &mut std::slice::Iter<'_, u8>) -> Option<$int_ty> {
131133
let mut result = 0;
132134
let mut shift = 0;
133135
let mut byte;
134136

135137
loop {
136-
byte = slice[*position];
137-
*position += 1;
138+
byte = *(slice.next()?);
138139
result |= <$int_ty>::from(byte & 0x7F) << shift;
139140
shift += 7;
140141

@@ -148,7 +149,7 @@ macro_rules! impl_read_signed_leb128 {
148149
result |= (!0 << shift);
149150
}
150151

151-
result
152+
Some(result)
152153
}
153154
};
154155
}

compiler/rustc_serialize/src/opaque.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ pub struct MemDecoder<'a> {
538538
// Previously this type stored `position: usize`, but because it's staying
539539
// safe code, that meant that reading `n` bytes meant a bounds check both
540540
// for `position + n` *and* `position`, since there's nothing saying that
541-
// the additions didn't wrap. Storing an iterator like this instead means
541+
// the additions didn't wrap. Storing an iterator like this instead means
542542
// there's no offsetting needed to get to the data, and the iterator instead
543543
// of a slice means only increasing the start pointer on reads, rather than
544544
// also needing to decrease the count in a slice.
@@ -579,10 +579,11 @@ impl<'a> MemDecoder<'a> {
579579

580580
macro_rules! read_leb128 {
581581
($dec:expr, $fun:ident) => {{
582-
let mut position = 0_usize;
583-
let val = leb128::$fun($dec.reader.as_slice(), &mut position);
584-
let _ = $dec.reader.advance_by(position);
585-
val
582+
if let Some(val) = leb128::$fun(&mut $dec.reader) {
583+
val
584+
} else {
585+
$dec.panic_insufficient_data()
586+
}
586587
}};
587588
}
588589

@@ -685,9 +686,7 @@ impl<'a> Decoder for MemDecoder<'a> {
685686
let slice = self.reader.as_slice();
686687
assert!(slice[len] == STR_SENTINEL);
687688
self.reader.advance_by(len + 1).unwrap();
688-
unsafe {
689-
std::str::from_utf8_unchecked(&slice[..len])
690-
}
689+
unsafe { std::str::from_utf8_unchecked(&slice[..len]) }
691690
}
692691

693692
#[inline]

compiler/rustc_serialize/tests/leb128.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ macro_rules! impl_test_unsigned_leb128 {
2828
stream.extend($write_fn_name(&mut buf, x));
2929
}
3030

31-
let mut position = 0;
31+
let mut reader = stream.iter();
3232
for &expected in &values {
33-
let actual = $read_fn_name(&stream, &mut position);
33+
let actual = $read_fn_name(&mut reader).unwrap();
3434
assert_eq!(expected, actual);
3535
}
36-
assert_eq!(stream.len(), position);
36+
assert_eq!(reader.len(), 0);
3737
}
3838
};
3939
}
@@ -74,12 +74,12 @@ macro_rules! impl_test_signed_leb128 {
7474
stream.extend($write_fn_name(&mut buf, x));
7575
}
7676

77-
let mut position = 0;
77+
let mut reader = stream.iter();
7878
for &expected in &values {
79-
let actual = $read_fn_name(&stream, &mut position);
79+
let actual = $read_fn_name(&mut reader).unwrap();
8080
assert_eq!(expected, actual);
8181
}
82-
assert_eq!(stream.len(), position);
82+
assert_eq!(reader.len(), 0);
8383
}
8484
};
8585
}

0 commit comments

Comments
 (0)