@@ -2405,6 +2405,14 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
24052405 }
24062406 YARVINSN_pop => { state. stack_pop ( ) ?; }
24072407 YARVINSN_dup => { state. stack_push ( state. stack_top ( ) ?) ; }
2408+ YARVINSN_dupn => {
2409+ // Duplicate the top N element of the stack. As we push, n-1 naturally
2410+ // points higher in the original stack.
2411+ let n = get_arg ( pc, 0 ) . as_usize ( ) ;
2412+ for _ in 0 ..n {
2413+ state. stack_push ( state. stack_topn ( n-1 ) ?) ;
2414+ }
2415+ }
24082416 YARVINSN_swap => {
24092417 let right = state. stack_pop ( ) ?;
24102418 let left = state. stack_pop ( ) ?;
@@ -4314,6 +4322,28 @@ mod tests {
43144322 Return v8
43154323 "# ] ] ) ;
43164324 }
4325+
4326+ #[ test]
4327+ fn dupn ( ) {
4328+ eval ( "
4329+ def test(x) = (x[0, 1] ||= 2)
4330+ " ) ;
4331+ assert_method_hir_with_opcode ( "test" , YARVINSN_dupn , expect ! [ [ r#"
4332+ fn test:
4333+ bb0(v0:BasicObject, v1:BasicObject):
4334+ v3:NilClassExact = Const Value(nil)
4335+ v4:Fixnum[0] = Const Value(0)
4336+ v5:Fixnum[1] = Const Value(1)
4337+ v7:BasicObject = SendWithoutBlock v1, :[], v4, v5
4338+ v8:CBool = Test v7
4339+ IfTrue v8, bb1(v0, v1, v3, v1, v4, v5, v7)
4340+ v10:Fixnum[2] = Const Value(2)
4341+ v12:BasicObject = SendWithoutBlock v1, :[]=, v4, v5, v10
4342+ Return v10
4343+ bb1(v14:BasicObject, v15:BasicObject, v16:NilClassExact, v17:BasicObject, v18:Fixnum[0], v19:Fixnum[1], v20:BasicObject):
4344+ Return v20
4345+ "# ] ] ) ;
4346+ }
43174347}
43184348
43194349#[ cfg( test) ]
0 commit comments