@@ -16,7 +16,7 @@ pub enum CmpOperator {
16
16
}
17
17
18
18
impl CmpOperator {
19
- pub fn from_bytecode ( n : u16 ) -> Self {
19
+ pub fn from_bytecode ( n : u32 ) -> Self {
20
20
match n {
21
21
0 => CmpOperator :: Lt ,
22
22
1 => CmpOperator :: Leq ,
@@ -52,6 +52,7 @@ pub enum Instruction {
52
52
ForIter ( usize ) ,
53
53
LoadConst ( usize ) ,
54
54
LoadName ( usize ) ,
55
+ BuildTuple ( usize ) ,
55
56
LoadAttr ( usize ) ,
56
57
SetupLoop ( usize ) ,
57
58
SetupExcept ( usize ) ,
@@ -70,12 +71,13 @@ pub enum Instruction {
70
71
#[ derive( Debug ) ]
71
72
pub struct InstructionDecoder < I > where I : Iterator {
72
73
bytestream : I ,
74
+ arg_prefix : Option < u32 > ,
73
75
pending_nops : u8 , // Number of NOPs to be inserted after this instruction to match CPython's addresses (instructions have different sizes)
74
76
}
75
77
76
78
impl < I > InstructionDecoder < I > where I : Iterator {
77
79
pub fn new ( bytes : I ) -> InstructionDecoder < I > {
78
- InstructionDecoder { bytestream : bytes, pending_nops : 0 , }
80
+ InstructionDecoder { bytestream : bytes, pending_nops : 0 , arg_prefix : None , }
79
81
}
80
82
}
81
83
@@ -89,11 +91,19 @@ impl<'a, I> InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
89
91
_ => panic ! ( "End of stream in the middle of an instruction." ) ,
90
92
}
91
93
}
92
- fn read_argument ( & mut self ) -> u16 {
94
+ fn read_argument ( & mut self ) -> u32 {
93
95
match ( self . bytestream . next ( ) , self . bytestream . next ( ) ) {
94
96
( Some ( b1) , Some ( b2) ) => {
95
97
self . pending_nops += 2 ;
96
- ( ( * b2 as u16 ) << 8 ) + ( * b1 as u16 ) } ,
98
+ let arg = ( ( * b2 as u32 ) << 8 ) + ( * b1 as u32 ) ;
99
+ if let Some ( prefix) = self . arg_prefix {
100
+ self . arg_prefix = None ;
101
+ ( prefix << 16 ) + arg
102
+ }
103
+ else {
104
+ arg
105
+ }
106
+ } ,
97
107
_ => panic ! ( "End of stream in the middle of an instruction." ) ,
98
108
}
99
109
}
@@ -122,6 +132,7 @@ impl<'a, I> Iterator for InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
122
132
93 => Instruction :: ForIter ( self . read_argument ( ) as usize ) ,
123
133
100 => Instruction :: LoadConst ( self . read_argument ( ) as usize ) ,
124
134
101 => Instruction :: LoadName ( self . read_argument ( ) as usize ) ,
135
+ 102 => Instruction :: BuildTuple ( self . read_argument ( ) as usize ) ,
125
136
106 => Instruction :: LoadAttr ( self . read_argument ( ) as usize ) ,
126
137
107 => Instruction :: CompareOp ( CmpOperator :: from_bytecode ( self . read_argument ( ) ) ) ,
127
138
110 => Instruction :: JumpForward ( self . read_argument ( ) as usize + 2 ) , // +2, because JumpForward takes 3 bytes, and the relative address is computed from the next instruction.
@@ -142,6 +153,7 @@ impl<'a, I> Iterator for InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
142
153
let nb_annot = 0 ;
143
154
Instruction :: MakeFunction ( nb_pos as usize , nb_kw as usize , nb_annot as usize )
144
155
} ,
156
+ 144 => { self . arg_prefix = Some ( self . read_argument ( ) ) ; Instruction :: Nop } ,
145
157
_ => panic ! ( format!( "Opcode not supported: {}" , opcode) ) ,
146
158
}
147
159
} )
0 commit comments