@@ -20,43 +20,37 @@ use crate::module::Parser;
20
20
21
21
pub struct SideTableView < ' m > {
22
22
pub func_idx : usize ,
23
- pub indices : & ' m [ u16 ] , // including 0 and the length of metadata_array
24
- pub metadata : & ' m [ u16 ] ,
23
+ pub indices : & ' m [ u8 ] , // including 0 and the length of metadata_array
24
+ pub metadata : & ' m [ u8 ] ,
25
25
}
26
26
27
27
impl < ' m > SideTableView < ' m > {
28
- pub fn new ( parser : & mut crate :: valid:: Parser < ' m > ) -> Result < Self , Error > {
28
+ pub fn new ( binary : & ' m [ u8 ] ) -> Result < Self , Error > {
29
+ let num_functions = parse_u16 ( binary, 0 ) as usize ;
30
+ let indices_end = 2 + ( num_functions + 1 ) * 2 ;
29
31
Ok ( SideTableView {
30
32
func_idx : 0 ,
31
- indices : parse_side_table_field ( parser ) ? ,
32
- metadata : parse_side_table_field ( parser ) ? ,
33
+ indices : & binary [ 2 .. indices_end ] ,
34
+ metadata : & binary [ indices_end .. ] ,
33
35
} )
34
36
}
35
37
38
+ // TODO(dev/fast-interp): Make it generic since it will be used in both `Check` and `Use` modes.
39
+ // (Returns `MResult<Metadata<'m>, M>` instead.)
36
40
pub fn metadata ( & self , func_idx : usize ) -> Metadata < ' m > {
37
41
Metadata (
38
- & self . metadata [ self . indices [ func_idx] as usize .. self . indices [ func_idx + 1 ] as usize ] ,
42
+ & self . metadata [ parse_u16 ( self . indices , func_idx * 2 ) as usize
43
+ .. parse_u16 ( self . indices , ( func_idx + 1 ) * 2 ) as usize ] ,
39
44
)
40
45
}
41
46
}
42
47
43
- fn parse_u16 ( data : & [ u8 ] ) -> u16 {
44
- bytemuck:: pod_read_unaligned :: < u16 > ( bytemuck:: cast_slice ( & data[ 0 .. 2 ] ) )
45
- }
46
-
47
- fn parse_side_table_field < ' m > ( parser : & mut crate :: valid:: Parser < ' m > ) -> Result < & ' m [ u16 ] , Error > {
48
- let len = parse_u16 ( parser. save ( ) ) as usize ;
49
- let parser = parser. split_at ( len) ?;
50
- let bytes = parser. save ( ) . get ( 0 .. len * 2 ) . unwrap ( ) ;
51
- Ok ( bytemuck:: cast_slice :: < _ , u16 > ( bytes) )
52
- }
53
-
54
48
#[ derive( Default , Copy , Clone ) ]
55
- pub struct Metadata < ' m > ( & ' m [ u16 ] ) ;
49
+ pub struct Metadata < ' m > ( & ' m [ u8 ] ) ;
56
50
57
51
impl < ' m > Metadata < ' m > {
58
52
pub fn type_idx ( & self ) -> usize {
59
- self . 0 [ 0 ] as usize
53
+ parse_u16 ( self . 0 , 0 ) as usize
60
54
}
61
55
62
56
#[ allow( dead_code) ]
@@ -65,15 +59,23 @@ impl<'m> Metadata<'m> {
65
59
}
66
60
67
61
pub fn branch_table ( & self ) -> & [ BranchTableEntry ] {
68
- bytemuck:: cast_slice ( & self . 0 [ 5 ..] )
62
+ let entry_size = size_of :: < BranchTableEntry > ( ) ;
63
+ assert_eq ! (
64
+ ( self . 0 . len( ) - 10 ) % entry_size,
65
+ 0 ,
66
+ "Metadata length for branch table must be divisible by {} bytes" ,
67
+ entry_size
68
+ ) ;
69
+ unsafe {
70
+ core:: slice:: from_raw_parts (
71
+ self . 0 [ 10 ..] . as_ptr ( ) as * const BranchTableEntry ,
72
+ self . 0 . len ( ) / entry_size,
73
+ )
74
+ }
69
75
}
70
76
71
77
pub fn parser_range ( & self ) -> Range < usize > {
72
- self . read_u32 ( 1 ) .. self . read_u32 ( 3 )
73
- }
74
-
75
- fn read_u32 ( & self , idx : usize ) -> usize {
76
- bytemuck:: pod_read_unaligned :: < u32 > ( bytemuck:: cast_slice ( & self . 0 [ idx .. idx + 2 ] ) ) as usize
78
+ parse_u32 ( self . 0 , 2 ) as usize .. parse_u32 ( self . 0 , 6 ) as usize
77
79
}
78
80
}
79
81
@@ -84,9 +86,9 @@ pub struct MetadataEntry {
84
86
pub branch_table : Vec < BranchTableEntry > ,
85
87
}
86
88
87
- #[ derive( Copy , Clone , Debug , bytemuck :: AnyBitPattern ) ]
89
+ #[ derive( Copy , Clone , Debug ) ]
88
90
#[ repr( transparent) ]
89
- pub struct BranchTableEntry ( [ u16 ; 3 ] ) ;
91
+ pub struct BranchTableEntry ( [ u8 ; 6 ] ) ;
90
92
91
93
pub struct BranchTableEntryView {
92
94
/// The amount to adjust the instruction pointer by if the branch is taken.
@@ -105,27 +107,42 @@ impl BranchTableEntry {
105
107
debug_assert ! ( ( i16 :: MIN as i32 .. i16 :: MAX as i32 ) . contains( & view. delta_stp) ) ;
106
108
debug_assert ! ( view. val_cnt <= 0xf ) ;
107
109
debug_assert ! ( view. pop_cnt <= 0xfff ) ;
110
+ let delta_ip_bytes = ( view. delta_ip as u16 ) . to_le_bytes ( ) ;
111
+ let delta_stp_bytes = ( view. delta_stp as u16 ) . to_le_bytes ( ) ;
112
+ let pop_val_counts_bytes = ( ( ( view. pop_cnt << 4 ) | view. val_cnt ) as u16 ) . to_le_bytes ( ) ;
108
113
Ok ( BranchTableEntry ( [
109
- view. delta_ip as u16 ,
110
- view. delta_stp as u16 ,
111
- ( ( view. pop_cnt << 4 ) | view. val_cnt ) as u16 ,
114
+ delta_ip_bytes[ 0 ] ,
115
+ delta_ip_bytes[ 1 ] ,
116
+ delta_stp_bytes[ 0 ] ,
117
+ delta_stp_bytes[ 1 ] ,
118
+ pop_val_counts_bytes[ 0 ] ,
119
+ pop_val_counts_bytes[ 1 ] ,
112
120
] ) )
113
121
}
114
122
115
123
pub fn view ( self ) -> BranchTableEntryView {
124
+ let pop_val_counts = parse_u16 ( & self . 0 , 4 ) ;
116
125
BranchTableEntryView {
117
- delta_ip : ( self . 0 [ 0 ] as i16 ) as i32 ,
118
- delta_stp : ( self . 0 [ 1 ] as i16 ) as i32 ,
119
- val_cnt : ( self . 0 [ 2 ] & 0xf ) as u32 ,
120
- pop_cnt : ( self . 0 [ 2 ] >> 4 ) as u32 ,
126
+ delta_ip : ( parse_u16 ( & self . 0 , 0 ) as i16 ) as i32 ,
127
+ delta_stp : ( parse_u16 ( & self . 0 , 2 ) as i16 ) as i32 ,
128
+ val_cnt : ( pop_val_counts & 0xf ) as u32 ,
129
+ pop_cnt : ( pop_val_counts >> 4 ) as u32 ,
121
130
}
122
131
}
123
132
124
133
pub fn is_invalid ( self ) -> bool {
125
- self . 0 == [ 0 ; 3 ]
134
+ self . 0 == [ 0 ; 6 ]
126
135
}
127
136
128
137
pub fn invalid ( ) -> Self {
129
- BranchTableEntry ( [ 0 ; 3 ] )
138
+ BranchTableEntry ( [ 0 ; 6 ] )
130
139
}
131
140
}
141
+
142
+ fn parse_u16 ( data : & [ u8 ] , offset : usize ) -> u16 {
143
+ u16:: from_le_bytes ( data[ offset ..] [ .. 2 ] . try_into ( ) . unwrap ( ) )
144
+ }
145
+
146
+ fn parse_u32 ( data : & [ u8 ] , offset : usize ) -> u32 {
147
+ u32:: from_le_bytes ( data[ offset ..] [ .. 4 ] . try_into ( ) . unwrap ( ) )
148
+ }
0 commit comments