From b97d4131fe2cb3f32c13a0f5b0e3eb6f97c4f75a 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 d4e718cb603e8..b84f6ef51ac20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3722,7 +3722,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 302a907538c84..a5a860a38b3e8 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.21.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 c7e32dd07082b..afbb67555df4f 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}; @@ -561,18 +561,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 74b4eea64d91d016652f991fa9c4525897b701a0 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 505939d56ed32..ee1ea816e0192 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 fe2a867125ff80dcb12df19581bd28b342b15c28 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 afbb67555df4f..90f8195a50cb5 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -570,7 +570,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 dc00efff9f44ddda1ce318e28f69e716f58d39dd 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 90f8195a50cb5..99966121e4d97 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -561,17 +561,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 2df552b406d8794dc0617672b34e1542498fd0ce 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 99966121e4d97..cbc362d934ff8 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -565,7 +565,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(()) @@ -576,12 +576,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 } ////////////////////////////////////////////////////////////////////////////////