@@ -10,8 +10,8 @@ struct InstructionMetadata {
1010 labels : Vec < Label > ,
1111}
1212
13- impl InstructionMetadata {
14- fn from_multiple ( metas : Vec < Self > ) -> Self {
13+ impl From < Vec < InstructionMetadata > > for InstructionMetadata {
14+ fn from ( metas : Vec < Self > ) -> Self {
1515 debug_assert ! ( !metas. is_empty( ) , "`metas` must not be empty" ) ;
1616 InstructionMetadata {
1717 loc : metas[ 0 ] . loc . clone ( ) ,
@@ -69,28 +69,28 @@ impl<O: OutputStream> PeepholeOptimizer<O> {
6969 }
7070
7171 fn optimize ( & mut self , instruction : Instruction , meta : InstructionMetadata ) {
72+ macro_rules! lc {
73+ ( $name: ident { $( $field: tt) * } ) => {
74+ Instruction :: LoadConst {
75+ value: bytecode:: Constant :: $name { $( $field) * } ,
76+ }
77+ } ;
78+ ( $name: ident, $( $value: tt) * ) => {
79+ lc!( $name { value: $( $value) * } )
80+ } ;
81+ }
82+ macro_rules! emitconst {
83+ ( [ $( $metas: expr) ,* ] , $( $arg: tt) * ) => {
84+ self . emit(
85+ lc!( $( $arg) * ) ,
86+ InstructionMetadata :: from( vec![ $( $metas) ,* ] ) ,
87+ )
88+ } ;
89+ }
7290 match instruction {
7391 Instruction :: BinaryOperation { op, inplace } => {
7492 let ( rhs, rhs_meta) = self . pop ( ) ;
7593 let ( lhs, lhs_meta) = self . pop ( ) ;
76- macro_rules! lc {
77- ( $name: ident { $( $field: tt) * } ) => {
78- Instruction :: LoadConst {
79- value: bytecode:: Constant :: $name { $( $field) * } ,
80- }
81- } ;
82- ( $name: ident, $( $value: tt) * ) => {
83- lc!( $name { value: $( $value) * } )
84- } ;
85- }
86- macro_rules! emitconst {
87- ( [ $( $metas: expr) ,* ] , $( $arg: tt) * ) => {
88- self . emit(
89- lc!( $( $arg) * ) ,
90- InstructionMetadata :: from_multiple( vec![ $( $metas) ,* ] ) ,
91- )
92- } ;
93- }
9494 macro_rules! op {
9595 ( $op: ident) => {
9696 bytecode:: BinaryOperator :: $op
@@ -129,6 +129,24 @@ impl<O: OutputStream> PeepholeOptimizer<O> {
129129 }
130130 }
131131 }
132+ Instruction :: UnpackSequence { size } => {
133+ let ( arg, arg_meta) = self . pop ( ) ;
134+ match arg {
135+ Instruction :: BuildTuple {
136+ size : tup_size,
137+ unpack,
138+ } if !unpack && tup_size == size => {
139+ self . emit (
140+ Instruction :: Reverse { amount : size } ,
141+ vec ! [ arg_meta, meta] . into ( ) ,
142+ ) ;
143+ }
144+ arg => {
145+ self . emit ( arg, arg_meta) ;
146+ self . emit ( instruction, meta) ;
147+ }
148+ }
149+ }
132150 other => self . emit ( other, meta) ,
133151 }
134152 }
0 commit comments