From d7edfaa0b7c0e73eb6e409a1fa84809060edc316 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Fri, 8 Apr 2022 17:35:13 +0800 Subject: [PATCH] Fix riscv32 atomics and fix tests on 32-bit platforms (#533) * tests: fix alloc range test on 32-bit Windows This test checks the range, which is necessarily different when running on another platform. Signed-off-by: Sean Cross * enc: case usize/isize as u64/i64 in serialization The deserialization process assumes that usize/isize are 64-bits, as does the spec at https://github.com/bincode-org/bincode/blob/trunk/docs/spec.md#varintencoding Force `usize` and `isize` to be encoded as `u64` and `i64` to force 32-bit platforms to conform to this spec. This fixes running tests under `cargo test --target i686-pc-windows-msvc` Signed-off-by: Sean Cross * atomic: only provide Atomic*64 on supported platforms Not all platforms support AtomicI64 or AtomicU64. Use the `target_has_atomic` config flag to determine whether to include these. This fixes #532. Signed-off-by: Sean Cross * atomic: remove feature and use new attributes Now that there is an attribute to indicate which atomic features are supported on this platform, remove the `atomic` Feature and use these new attributes. Signed-off-by: Sean Cross * alloc: run `cargo fmt` Signed-off-by: Sean Cross --- Cargo.toml | 3 +-- src/{features => }/atomic.rs | 42 ++++++++++++++++++++++++++++++++---- src/features/mod.rs | 5 ----- src/lib.rs | 2 ++ tests/alloc.rs | 3 +++ 5 files changed, 44 insertions(+), 11 deletions(-) rename src/{features => }/atomic.rs (79%) diff --git a/Cargo.toml b/Cargo.toml index 3f615c5..c19371c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,10 +24,9 @@ description = "A binary serialization / deserialization strategy for transformin edition = "2021" [features] -default = ["std", "derive", "atomic"] +default = ["std", "derive"] std = ["alloc"] alloc = [] -atomic = [] derive = ["bincode_derive"] # BlockedTODO: https://github.com/rust-lang/cargo/issues/8832 diff --git a/src/features/atomic.rs b/src/atomic.rs similarity index 79% rename from src/features/atomic.rs rename to src/atomic.rs index c1c4d24..5267dc9 100644 --- a/src/features/atomic.rs +++ b/src/atomic.rs @@ -1,9 +1,22 @@ use crate::{de::Decode, enc::Encode}; -use core::sync::atomic::{ - AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, - AtomicU64, AtomicU8, AtomicUsize, Ordering, -}; +use core::sync::atomic::Ordering; +#[cfg(target_has_atomic = "ptr")] +use core::sync::atomic::{AtomicIsize, AtomicUsize}; + +#[cfg(target_has_atomic = "8")] +use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU8}; + +#[cfg(target_has_atomic = "16")] +use core::sync::atomic::{AtomicI16, AtomicU16}; + +#[cfg(target_has_atomic = "32")] +use core::sync::atomic::{AtomicI32, AtomicU32}; + +#[cfg(target_has_atomic = "64")] +use core::sync::atomic::{AtomicI64, AtomicU64}; + +#[cfg(target_has_atomic = "8")] impl Encode for AtomicBool { fn encode( &self, @@ -13,12 +26,14 @@ impl Encode for AtomicBool { } } +#[cfg(target_has_atomic = "8")] impl Decode for AtomicBool { fn decode(decoder: &mut D) -> Result { Ok(AtomicBool::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "8")] impl Encode for AtomicU8 { fn encode( &self, @@ -28,12 +43,14 @@ impl Encode for AtomicU8 { } } +#[cfg(target_has_atomic = "8")] impl Decode for AtomicU8 { fn decode(decoder: &mut D) -> Result { Ok(AtomicU8::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "16")] impl Encode for AtomicU16 { fn encode( &self, @@ -43,12 +60,14 @@ impl Encode for AtomicU16 { } } +#[cfg(target_has_atomic = "16")] impl Decode for AtomicU16 { fn decode(decoder: &mut D) -> Result { Ok(AtomicU16::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "32")] impl Encode for AtomicU32 { fn encode( &self, @@ -58,12 +77,14 @@ impl Encode for AtomicU32 { } } +#[cfg(target_has_atomic = "32")] impl Decode for AtomicU32 { fn decode(decoder: &mut D) -> Result { Ok(AtomicU32::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "64")] impl Encode for AtomicU64 { fn encode( &self, @@ -73,12 +94,14 @@ impl Encode for AtomicU64 { } } +#[cfg(target_has_atomic = "64")] impl Decode for AtomicU64 { fn decode(decoder: &mut D) -> Result { Ok(AtomicU64::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "ptr")] impl Encode for AtomicUsize { fn encode( &self, @@ -88,12 +111,14 @@ impl Encode for AtomicUsize { } } +#[cfg(target_has_atomic = "ptr")] impl Decode for AtomicUsize { fn decode(decoder: &mut D) -> Result { Ok(AtomicUsize::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "8")] impl Encode for AtomicI8 { fn encode( &self, @@ -103,12 +128,14 @@ impl Encode for AtomicI8 { } } +#[cfg(target_has_atomic = "8")] impl Decode for AtomicI8 { fn decode(decoder: &mut D) -> Result { Ok(AtomicI8::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "16")] impl Encode for AtomicI16 { fn encode( &self, @@ -118,12 +145,14 @@ impl Encode for AtomicI16 { } } +#[cfg(target_has_atomic = "16")] impl Decode for AtomicI16 { fn decode(decoder: &mut D) -> Result { Ok(AtomicI16::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "32")] impl Encode for AtomicI32 { fn encode( &self, @@ -133,12 +162,14 @@ impl Encode for AtomicI32 { } } +#[cfg(target_has_atomic = "32")] impl Decode for AtomicI32 { fn decode(decoder: &mut D) -> Result { Ok(AtomicI32::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "64")] impl Encode for AtomicI64 { fn encode( &self, @@ -148,12 +179,14 @@ impl Encode for AtomicI64 { } } +#[cfg(target_has_atomic = "64")] impl Decode for AtomicI64 { fn decode(decoder: &mut D) -> Result { Ok(AtomicI64::new(Decode::decode(decoder)?)) } } +#[cfg(target_has_atomic = "ptr")] impl Encode for AtomicIsize { fn encode( &self, @@ -163,6 +196,7 @@ impl Encode for AtomicIsize { } } +#[cfg(target_has_atomic = "ptr")] impl Decode for AtomicIsize { fn decode(decoder: &mut D) -> Result { Ok(AtomicIsize::new(Decode::decode(decoder)?)) diff --git a/src/features/mod.rs b/src/features/mod.rs index 7392570..16a67e1 100644 --- a/src/features/mod.rs +++ b/src/features/mod.rs @@ -1,8 +1,3 @@ -#[cfg(feature = "atomic")] -mod atomic; -#[cfg(feature = "atomic")] -pub use self::atomic::*; - #[cfg(feature = "alloc")] mod impl_alloc; #[cfg(feature = "alloc")] diff --git a/src/lib.rs b/src/lib.rs index a2aa764..f2f5176 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,6 +80,7 @@ extern crate alloc; #[cfg(any(feature = "std", test))] extern crate std; +mod atomic; mod features; pub(crate) mod utils; pub(crate) mod varint; @@ -93,6 +94,7 @@ pub mod de; pub mod enc; pub mod error; +pub use atomic::*; pub use de::{BorrowDecode, Decode}; pub use enc::Encode; diff --git a/tests/alloc.rs b/tests/alloc.rs index 3173ed7..37b55bb 100644 --- a/tests/alloc.rs +++ b/tests/alloc.rs @@ -104,7 +104,10 @@ fn test_container_limits() { // for this test we'll create a malformed package of a lot of bytes let test_cases = &[ // u64::max_value(), should overflow + #[cfg(target_pointer_width = "64")] bincode::encode_to_vec(u64::max_value(), bincode::config::standard()).unwrap(), + #[cfg(target_pointer_width = "32")] + bincode::encode_to_vec(u32::max_value(), bincode::config::standard()).unwrap(), // A high value which doesn't overflow, but exceeds the decode limit bincode::encode_to_vec(DECODE_LIMIT as u64, bincode::config::standard()).unwrap(), ];