From 864f2dce068268381c0c4cd807a411dbfac16178 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 20 Aug 2020 02:37:00 -0700 Subject: [PATCH 1/5] Refactor byteorder to std in rustc_middle Use std::io::{Read, Write} and {to, from}_{le, be}_bytes methods in order to remove byteorder from librustc_middle's dependency graph. --- Cargo.lock | 1 - compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/src/mir/interpret/mod.rs | 16 +++++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffc1f0dec1d9..42180e9c3b51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3726,7 +3726,6 @@ name = "rustc_middle" version = "0.0.0" dependencies = [ "bitflags", - "byteorder", "chalk-ir", "measureme", "polonius-engine", diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 5a82cbf2997d..d555fbd5d29b 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,7 +26,6 @@ rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -byteorder = { version = "1.3" } chalk-ir = "0.14.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 0dc3d6e344a7..42a142a188b5 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -98,10 +98,10 @@ mod value; use std::convert::TryFrom; use std::fmt; use std::io; +use std::io::{Read, Write}; use std::num::NonZeroU32; use std::sync::atomic::{AtomicU32, Ordering}; -use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; @@ -560,18 +560,20 @@ pub fn write_target_uint( mut target: &mut [u8], data: u128, ) -> Result<(), io::Error> { - let len = target.len(); match endianness { - Endian::Little => target.write_uint128::(data, len), - Endian::Big => target.write_uint128::(data, len), - } + Endian::Little => target.write(&data.to_le_bytes())?, + Endian::Big => target.write(&data.to_be_bytes())?, + }; + Ok(()) } #[inline] pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result { + let mut buf = [0; 16]; + source.read(&mut buf)?; match endianness { - Endian::Little => source.read_uint128::(source.len()), - Endian::Big => source.read_uint128::(source.len()), + Endian::Little => Ok(u128::from_le_bytes(buf)), + Endian::Big => Ok(u128::from_be_bytes(buf)), } } From fd959c1b8b627e17ef30fd17e0e5f783f3010107 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 20 Aug 2020 05:32:14 -0700 Subject: [PATCH 2/5] Remove reference to byteorder limits --- .../rustc_middle/src/mir/interpret/allocation.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 505939d56ed3..ee1ea816e019 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -345,10 +345,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { /// Reads a *non-ZST* scalar. /// - /// ZSTs can't be read for two reasons: - /// * byte-order cannot work with zero-element buffers; - /// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer - /// pointers being valid for ZSTs. + /// ZSTs can't be read because in order to obtain a `Pointer`, we need to check + /// for ZSTness anyway due to integer pointers being valid for ZSTs. /// /// It is the caller's responsibility to check bounds and alignment beforehand. /// Most likely, you want to call `InterpCx::read_scalar` instead of this method. @@ -397,10 +395,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { /// Writes a *non-ZST* scalar. /// - /// ZSTs can't be read for two reasons: - /// * byte-order cannot work with zero-element buffers; - /// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer - /// pointers being valid for ZSTs. + /// ZSTs can't be read because in order to obtain a `Pointer`, we need to check + /// for ZSTness anyway due to integer pointers being valid for ZSTs. /// /// It is the caller's responsibility to check bounds and alignment beforehand. /// Most likely, you want to call `InterpCx::write_scalar` instead of this method. From 28d31001af32c8e54367e7080b66d19e057d8694 Mon Sep 17 00:00:00 2001 From: Jubilee <46493976+workingjubilee@users.noreply.github.com> Date: Thu, 20 Aug 2020 15:55:02 -0700 Subject: [PATCH 3/5] Be explicit that we're handling bytes Co-authored-by: Aleksey Kladov --- compiler/rustc_middle/src/mir/interpret/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 42a142a188b5..75db4dac8006 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -569,7 +569,7 @@ pub fn write_target_uint( #[inline] pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result { - let mut buf = [0; 16]; + let mut buf = [0u8; std::mem::size_of::()]; source.read(&mut buf)?; match endianness { Endian::Little => Ok(u128::from_le_bytes(buf)), From 91c9351559e2bf51664b876d3f3e2239492c55b5 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 21 Aug 2020 00:55:33 -0700 Subject: [PATCH 4/5] Explain contract of {read, write}_target_uint --- compiler/rustc_middle/src/mir/interpret/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 75db4dac8006..11dc71ce08af 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -560,17 +560,23 @@ pub fn write_target_uint( mut target: &mut [u8], data: u128, ) -> Result<(), io::Error> { + // This u128 holds an "any-size uint" (since smaller uints can fits in it) + // So we do not write all bytes of the u128, just the "payload". match endianness { Endian::Little => target.write(&data.to_le_bytes())?, Endian::Big => target.write(&data.to_be_bytes())?, }; + debug_assert!(target.len() == 0); // We should have filled the target buffer. Ok(()) } #[inline] pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result { + // This u128 holds an "any-size uint" (since smaller uints can fits in it) let mut buf = [0u8; std::mem::size_of::()]; + // So we do not read exactly 16 bytes into the u128, just the "payload". source.read(&mut buf)?; + debug_assert!(source.len() == 0); // We should have consumed the source buffer. match endianness { Endian::Little => Ok(u128::from_le_bytes(buf)), Endian::Big => Ok(u128::from_be_bytes(buf)), From b68831423a45503f2ae2c4b410e08dbf82165558 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 22 Aug 2020 03:54:15 -0700 Subject: [PATCH 5/5] Fix big endian read/write Co-authored-by: matthewjasper --- compiler/rustc_middle/src/mir/interpret/mod.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 11dc71ce08af..47a6ad86cadb 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -564,7 +564,7 @@ pub fn write_target_uint( // So we do not write all bytes of the u128, just the "payload". match endianness { Endian::Little => target.write(&data.to_le_bytes())?, - Endian::Big => target.write(&data.to_be_bytes())?, + Endian::Big => target.write(&data.to_be_bytes()[16 - target.len()..])?, }; debug_assert!(target.len() == 0); // We should have filled the target buffer. Ok(()) @@ -575,12 +575,18 @@ pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result()]; // So we do not read exactly 16 bytes into the u128, just the "payload". - source.read(&mut buf)?; + let uint = match endianness { + Endian::Little => { + source.read(&mut buf)?; + Ok(u128::from_le_bytes(buf)) + } + Endian::Big => { + source.read(&mut buf[16 - source.len()..])?; + Ok(u128::from_be_bytes(buf)) + } + }; debug_assert!(source.len() == 0); // We should have consumed the source buffer. - match endianness { - Endian::Little => Ok(u128::from_le_bytes(buf)), - Endian::Big => Ok(u128::from_be_bytes(buf)), - } + uint } ////////////////////////////////////////////////////////////////////////////////