@@ -2622,6 +2622,16 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
26222622 let val = state. stack_pop ( ) ?;
26232623 fun. push_insn ( block, Insn :: SetIvar { self_val : self_param, id, val, state : exit_id } ) ;
26242624 }
2625+ YARVINSN_opt_reverse => {
2626+ // Reverse the order of the top N stack items.
2627+ let n = get_arg ( pc, 0 ) . as_usize ( ) ;
2628+ for i in 0 ..n/2 {
2629+ let bottom = state. stack_topn ( n - 1 - i) ?;
2630+ let top = state. stack_topn ( i) ?;
2631+ state. stack_setn ( i, bottom) ;
2632+ state. stack_setn ( n - 1 - i, top) ;
2633+ }
2634+ }
26252635 YARVINSN_newrange => {
26262636 let flag = RangeType :: from ( get_arg ( pc, 0 ) . as_u32 ( ) ) ;
26272637 let high = state. stack_pop ( ) ?;
@@ -4209,6 +4219,47 @@ mod tests {
42094219 "# ] ] ) ;
42104220 }
42114221
4222+ #[ test]
4223+ fn opt_reverse ( ) {
4224+ eval ( "
4225+ def reverse_odd
4226+ a, b, c = @a, @b, @c
4227+ [a, b, c]
4228+ end
4229+
4230+ def reverse_even
4231+ a, b, c, d = @a, @b, @c, @d
4232+ [a, b, c, d]
4233+ end
4234+ " ) ;
4235+ assert_method_hir_with_opcode ( "reverse_odd" , YARVINSN_opt_reverse , expect ! [ [ r#"
4236+ fn reverse_odd:
4237+ bb0(v0:BasicObject):
4238+ v1:NilClassExact = Const Value(nil)
4239+ v2:NilClassExact = Const Value(nil)
4240+ v3:NilClassExact = Const Value(nil)
4241+ v6:BasicObject = GetIvar v0, :@a
4242+ v8:BasicObject = GetIvar v0, :@b
4243+ v10:BasicObject = GetIvar v0, :@c
4244+ v12:ArrayExact = NewArray v6, v8, v10
4245+ Return v12
4246+ "# ] ] ) ;
4247+ assert_method_hir_with_opcode ( "reverse_even" , YARVINSN_opt_reverse , expect ! [ [ r#"
4248+ fn reverse_even:
4249+ bb0(v0:BasicObject):
4250+ v1:NilClassExact = Const Value(nil)
4251+ v2:NilClassExact = Const Value(nil)
4252+ v3:NilClassExact = Const Value(nil)
4253+ v4:NilClassExact = Const Value(nil)
4254+ v7:BasicObject = GetIvar v0, :@a
4255+ v9:BasicObject = GetIvar v0, :@b
4256+ v11:BasicObject = GetIvar v0, :@c
4257+ v13:BasicObject = GetIvar v0, :@d
4258+ v15:ArrayExact = NewArray v7, v9, v11, v13
4259+ Return v15
4260+ "# ] ] ) ;
4261+ }
4262+
42124263 #[ test]
42134264 fn test_branchnil ( ) {
42144265 eval ( "
0 commit comments