11#![ allow( non_camel_case_types) ]
22
3+ //! Definitions and utilities to decode encoded byte streams.
4+
35mod op;
46
57use self :: op:: {
@@ -42,56 +44,76 @@ use crate::{
4244 Slot ,
4345 SlotSpan ,
4446} ;
45- use core:: { mem, num:: NonZero } ;
47+ use core:: {
48+ error:: Error as CoreError ,
49+ fmt,
50+ mem:: { self , MaybeUninit } ,
51+ num:: NonZero ,
52+ } ;
4653
4754/// Types that can be used to decode types implementing [`Decode`].
4855pub trait Decoder {
4956 /// Reads enough bytes from `self` to populate `buffer`.
50- fn read_bytes ( & mut self , buffer : & mut [ u8 ] ) ;
57+ fn read_bytes ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , DecodeError > ;
58+ }
59+
60+ /// An error that may be returned when decoding items.
61+ #[ derive( Debug , Copy , Clone ) ]
62+ pub enum DecodeError {
63+ /// The decoder ran out of bytes.
64+ OutOfBytes ,
65+ /// The decoder found an invalid bit pattern.
66+ InvalidBitPattern ,
67+ }
68+
69+ impl CoreError for DecodeError { }
70+ impl fmt:: Display for DecodeError {
71+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
72+ let s = match self {
73+ DecodeError :: OutOfBytes => "ran out of bytes to decode" ,
74+ DecodeError :: InvalidBitPattern => "encountered invalid bit pattern" ,
75+ } ;
76+ f. write_str ( s)
77+ }
5178}
5279
5380/// Types that can be decoded using a type that implements [`Decoder`].
54- pub trait Decode {
81+ pub trait Decode : Sized {
5582 /// Decodes `Self` via `decoder`.
56- ///
57- /// # Safety
58- ///
59- /// It is the callers responsibility to ensure that the decoder
60- /// decodes items in the order they have been encoded and on valid
61- /// positions within the decode stream.
62- unsafe fn decode < D : Decoder > ( decoder : & mut D ) -> Self ;
83+ fn decode < D : Decoder > ( decoder : & mut D ) -> Result < Self , DecodeError > ;
6384}
6485
6586impl Decode for BoundedSlotSpan {
66- unsafe fn decode < D : Decoder > ( decoder : & mut D ) -> Self {
67- let span = SlotSpan :: decode ( decoder) ;
68- let len = u16:: decode ( decoder) ;
69- Self :: new ( span, len)
87+ fn decode < D : Decoder > ( decoder : & mut D ) -> Result < Self , DecodeError > {
88+ let span = SlotSpan :: decode ( decoder) ? ;
89+ let len = u16:: decode ( decoder) ? ;
90+ Ok ( Self :: new ( span, len) )
7091 }
7192}
7293
7394impl < const N : u16 > Decode for FixedSlotSpan < N > {
74- unsafe fn decode < D : Decoder > ( decoder : & mut D ) -> Self {
75- Self :: new_unchecked ( SlotSpan :: decode ( decoder) )
95+ fn decode < D : Decoder > ( decoder : & mut D ) -> Result < Self , DecodeError > {
96+ let span = SlotSpan :: decode ( decoder) ?;
97+ Self :: new ( span) . map_err ( |_| DecodeError :: InvalidBitPattern )
7698 }
7799}
78100
79101impl Decode for BranchTableTarget {
80- unsafe fn decode < D : Decoder > ( decoder : & mut D ) -> Self {
81- let results = SlotSpan :: decode ( decoder) ;
82- let offset = BranchOffset :: decode ( decoder) ;
83- Self :: new ( results, offset)
102+ fn decode < D : Decoder > ( decoder : & mut D ) -> Result < Self , DecodeError > {
103+ let results = SlotSpan :: decode ( decoder) ? ;
104+ let offset = BranchOffset :: decode ( decoder) ? ;
105+ Ok ( Self :: new ( results, offset) )
84106 }
85107}
86108
87109macro_rules! impl_decode_for_primitive {
88110 ( $( $ty: ty) ,* $( , ) ? ) => {
89111 $(
90112 impl Decode for $ty {
91- unsafe fn decode<D : Decoder >( decoder: & mut D ) -> Self {
113+ fn decode<D : Decoder >( decoder: & mut D ) -> Result < Self , DecodeError > {
92114 let mut bytes = [ 0_u8 ; mem:: size_of:: <$ty>( ) ] ;
93- decoder. read_bytes( & mut bytes) ;
94- Self :: from_ne_bytes( bytes)
115+ decoder. read_bytes( & mut bytes) ? ;
116+ Ok ( Self :: from_ne_bytes( bytes) )
95117 }
96118 }
97119 ) *
@@ -105,8 +127,8 @@ macro_rules! impl_decode_using {
105127 ( $( $ty: ty as $as: ty = $e: expr) ,* $( , ) ? ) => {
106128 $(
107129 impl Decode for $ty {
108- unsafe fn decode<D : Decoder >( decoder: & mut D ) -> Self {
109- $e( <$as as Decode >:: decode( decoder) )
130+ fn decode<D : Decoder >( decoder: & mut D ) -> Result < Self , DecodeError > {
131+ Ok ( $e( <$as as Decode >:: decode( decoder) ? ) )
110132 }
111133 }
112134 ) *
@@ -127,32 +149,66 @@ impl_decode_using! {
127149 Data as u32 = Into :: into,
128150 Elem as u32 = Into :: into,
129151
130- Address as u64 = |address| unsafe { Address :: try_from( address) . unwrap_unchecked( ) } ,
131152 Sign <f32 > as bool = Sign :: new,
132153 Sign <f64 > as bool = Sign :: new,
133154 SlotSpan as Slot = SlotSpan :: new,
134- NonZero <i32 > as i32 = |value| unsafe { NonZero :: new_unchecked( value) } ,
135- NonZero <i64 > as i64 = |value| unsafe { NonZero :: new_unchecked( value) } ,
136- NonZero <u32 > as u32 = |value| unsafe { NonZero :: new_unchecked( value) } ,
137- NonZero <u64 > as u64 = |value| unsafe { NonZero :: new_unchecked( value) } ,
138- TrapCode as u8 = |code: u8 | -> TrapCode {
139- TrapCode :: try_from( code) . unwrap_unchecked( )
155+ }
156+
157+ macro_rules! impl_decode_fallible_using {
158+ ( $( $ty: ty as $as: ty = $e: expr) ,* $( , ) ? ) => {
159+ $(
160+ impl Decode for $ty {
161+ fn decode<D : Decoder >( decoder: & mut D ) -> Result <Self , DecodeError > {
162+ $e( <$as as Decode >:: decode( decoder) ?)
163+ }
164+ }
165+ ) *
166+ } ;
167+ }
168+ impl_decode_fallible_using ! {
169+ Address as u64 = |address| {
170+ Address :: try_from( address) . map_err( |_| DecodeError :: InvalidBitPattern )
171+ } ,
172+ NonZero <i32 > as i32 = |value| {
173+ NonZero :: new( value) . ok_or( DecodeError :: InvalidBitPattern )
174+ } ,
175+ NonZero <i64 > as i64 = |value| {
176+ NonZero :: new( value) . ok_or( DecodeError :: InvalidBitPattern )
177+ } ,
178+ NonZero <u32 > as u32 = |value| {
179+ NonZero :: new( value) . ok_or( DecodeError :: InvalidBitPattern )
180+ } ,
181+ NonZero <u64 > as u64 = |value| {
182+ NonZero :: new( value) . ok_or( DecodeError :: InvalidBitPattern )
183+ } ,
184+ TrapCode as u8 = |code: u8 | {
185+ TrapCode :: try_from( code) . map_err( |_| DecodeError :: InvalidBitPattern )
140186 } ,
141- OpCode as u16 = |code: u16 | -> OpCode {
142- OpCode :: try_from( code) . unwrap_unchecked ( )
187+ OpCode as u16 = |code: u16 | {
188+ OpCode :: try_from( code) . map_err ( |_| DecodeError :: InvalidBitPattern )
143189 }
144190}
145191
146192impl < const N : usize , T : Decode > Decode for [ T ; N ] {
147- unsafe fn decode < D : Decoder > ( decoder : & mut D ) -> Self {
148- core:: array:: from_fn ( |_| <T as Decode >:: decode ( decoder) )
193+ fn decode < D : Decoder > ( decoder : & mut D ) -> Result < Self , DecodeError > {
194+ let mut array = <MaybeUninit < [ T ; N ] > >:: uninit ( ) ;
195+ // Safety: we are going to decode and initialize all array items and won't read any.
196+ let items = unsafe { & mut * array. as_mut_ptr ( ) } ;
197+ for item in items {
198+ * item = <T as Decode >:: decode ( decoder) ?;
199+ }
200+ // Safety: we have decoded and thus initialized all array items.
201+ let array = unsafe { array. assume_init ( ) } ;
202+ Ok ( array)
149203 }
150204}
151205
152206#[ cfg( feature = "simd" ) ]
153207impl < const N : u8 > Decode for ImmLaneIdx < N > {
154- unsafe fn decode < D : Decoder > ( decoder : & mut D ) -> Self {
155- ImmLaneIdx :: try_from ( u8:: decode ( decoder) ) . unwrap_unchecked ( )
208+ fn decode < D : Decoder > ( decoder : & mut D ) -> Result < Self , DecodeError > {
209+ let byte = u8:: decode ( decoder) ?;
210+ let lane = ImmLaneIdx :: try_from ( byte) . map_err ( |_| DecodeError :: InvalidBitPattern ) ?;
211+ Ok ( lane)
156212 }
157213}
158214
0 commit comments