@@ -98,34 +98,42 @@ fn make_map<const PC_FIRST: bool>(code: &[u8]) -> FxHashMap<u32, u32> {
98
98
}
99
99
100
100
/// Represents a single instruction consisting of the opcode and its immediate data.
101
- pub struct Instruction < ' a > {
101
+ pub struct Instruction {
102
102
/// OpCode, if it could be decoded.
103
103
pub op : Option < OpCode > ,
104
104
/// Immediate data following the opcode.
105
- pub immediate : & ' a [ u8 ] ,
105
+ pub immediate : Box < [ u8 ] > ,
106
106
/// Program counter of the opcode.
107
107
pub pc : u32 ,
108
108
}
109
109
110
110
/// Decodes raw opcode bytes into [`Instruction`]s.
111
- pub fn decode_instructions ( code : & [ u8 ] ) -> Result < Vec < Instruction < ' _ > > > {
111
+ pub fn decode_instructions ( code : & [ u8 ] ) -> Result < Vec < Instruction > > {
112
112
assert ! ( code. len( ) <= u32 :: MAX as usize , "bytecode is too big" ) ;
113
113
114
114
let mut pc = 0usize ;
115
115
let mut steps = Vec :: new ( ) ;
116
116
117
117
while pc < code. len ( ) {
118
118
let op = OpCode :: new ( code[ pc] ) ;
119
- pc += 1 ;
120
- let immediate_size = op. map ( |op| immediate_size ( op, & code[ pc..] ) ) . unwrap_or ( 0 ) as usize ;
119
+ let next_pc = pc + 1 ;
120
+ let immediate_size =
121
+ op. map ( |op| immediate_size ( op, & code[ next_pc..] ) ) . unwrap_or ( 0 ) as usize ;
122
+ let is_normal_push = op. map ( |op| op. is_push ( ) ) . unwrap_or ( false ) ;
121
123
122
- if pc + immediate_size > code. len ( ) {
124
+ if !is_normal_push && next_pc + immediate_size > code. len ( ) {
123
125
eyre:: bail!( "incomplete sequence of bytecode" ) ;
124
126
}
125
127
126
- steps. push ( Instruction { op, pc : pc as u32 , immediate : & code[ pc..pc + immediate_size] } ) ;
128
+ // Ensure immediate is padded if needed.
129
+ let immediate_end = ( next_pc + immediate_size) . min ( code. len ( ) ) ;
130
+ let mut immediate = vec ! [ 0u8 ; immediate_size] ;
131
+ let immediate_part = & code[ next_pc..immediate_end] ;
132
+ immediate[ ..immediate_part. len ( ) ] . copy_from_slice ( immediate_part) ;
133
+
134
+ steps. push ( Instruction { op, pc : pc as u32 , immediate : immediate. into_boxed_slice ( ) } ) ;
127
135
128
- pc += immediate_size;
136
+ pc = next_pc + immediate_size;
129
137
}
130
138
131
139
Ok ( steps)
0 commit comments