@@ -16,7 +16,7 @@ pub enum CmpOperator {
1616}
1717
1818impl CmpOperator {
19- pub fn from_bytecode ( n : u16 ) -> Self {
19+ pub fn from_bytecode ( n : u32 ) -> Self {
2020 match n {
2121 0 => CmpOperator :: Lt ,
2222 1 => CmpOperator :: Leq ,
@@ -52,6 +52,7 @@ pub enum Instruction {
5252 ForIter ( usize ) ,
5353 LoadConst ( usize ) ,
5454 LoadName ( usize ) ,
55+ BuildTuple ( usize ) ,
5556 LoadAttr ( usize ) ,
5657 SetupLoop ( usize ) ,
5758 SetupExcept ( usize ) ,
@@ -70,12 +71,13 @@ pub enum Instruction {
7071#[ derive( Debug ) ]
7172pub struct InstructionDecoder < I > where I : Iterator {
7273 bytestream : I ,
74+ arg_prefix : Option < u32 > ,
7375 pending_nops : u8 , // Number of NOPs to be inserted after this instruction to match CPython's addresses (instructions have different sizes)
7476}
7577
7678impl < I > InstructionDecoder < I > where I : Iterator {
7779 pub fn new ( bytes : I ) -> InstructionDecoder < I > {
78- InstructionDecoder { bytestream : bytes, pending_nops : 0 , }
80+ InstructionDecoder { bytestream : bytes, pending_nops : 0 , arg_prefix : None , }
7981 }
8082}
8183
@@ -89,11 +91,19 @@ impl<'a, I> InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
8991 _ => panic ! ( "End of stream in the middle of an instruction." ) ,
9092 }
9193 }
92- fn read_argument ( & mut self ) -> u16 {
94+ fn read_argument ( & mut self ) -> u32 {
9395 match ( self . bytestream . next ( ) , self . bytestream . next ( ) ) {
9496 ( Some ( b1) , Some ( b2) ) => {
9597 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+ } ,
97107 _ => panic ! ( "End of stream in the middle of an instruction." ) ,
98108 }
99109 }
@@ -122,6 +132,7 @@ impl<'a, I> Iterator for InstructionDecoder<I> where I: Iterator<Item=&'a u8> {
122132 93 => Instruction :: ForIter ( self . read_argument ( ) as usize ) ,
123133 100 => Instruction :: LoadConst ( self . read_argument ( ) as usize ) ,
124134 101 => Instruction :: LoadName ( self . read_argument ( ) as usize ) ,
135+ 102 => Instruction :: BuildTuple ( self . read_argument ( ) as usize ) ,
125136 106 => Instruction :: LoadAttr ( self . read_argument ( ) as usize ) ,
126137 107 => Instruction :: CompareOp ( CmpOperator :: from_bytecode ( self . read_argument ( ) ) ) ,
127138 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> {
142153 let nb_annot = 0 ;
143154 Instruction :: MakeFunction ( nb_pos as usize , nb_kw as usize , nb_annot as usize )
144155 } ,
156+ 144 => { self . arg_prefix = Some ( self . read_argument ( ) ) ; Instruction :: Nop } ,
145157 _ => panic ! ( format!( "Opcode not supported: {}" , opcode) ) ,
146158 }
147159 } )
0 commit comments