@@ -300,7 +300,7 @@ pub enum Insn {
300300
301301 NewArray { elements : Vec < InsnId > } ,
302302 ArraySet { array : InsnId , idx : usize , val : InsnId } ,
303- ArrayDup { val : InsnId } ,
303+ ArrayDup { val : InsnId , state : InsnId } ,
304304
305305 // Check if the value is truthy and "return" a C boolean. In reality, we will likely fuse this
306306 // with IfTrue/IfFalse in the backend to generate jcc.
@@ -433,7 +433,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
433433 Ok ( ( ) )
434434 }
435435 Insn :: ArraySet { array, idx, val } => { write ! ( f, "ArraySet {array}, {idx}, {val}" ) }
436- Insn :: ArrayDup { val } => { write ! ( f, "ArrayDup {val}" ) }
436+ Insn :: ArrayDup { val, .. } => { write ! ( f, "ArrayDup {val}" ) }
437437 Insn :: StringCopy { val } => { write ! ( f, "StringCopy {val}" ) }
438438 Insn :: Test { val } => { write ! ( f, "Test {val}" ) }
439439 Insn :: Jump ( target) => { write ! ( f, "Jump {target}" ) }
@@ -789,7 +789,7 @@ impl Function {
789789 state : * state,
790790 } ,
791791 ArraySet { array, idx, val } => ArraySet { array : find ! ( * array) , idx : * idx, val : find ! ( * val) } ,
792- ArrayDup { val } => ArrayDup { val : find ! ( * val) } ,
792+ ArrayDup { val , state } => ArrayDup { val : find ! ( * val) , state : * state } ,
793793 CCall { cfun, args, name, return_type } => CCall { cfun : * cfun, args : args. iter ( ) . map ( |arg| find ! ( * arg) ) . collect ( ) , name : * name, return_type : * return_type } ,
794794 Defined { .. } => todo ! ( "find(Defined)" ) ,
795795 }
@@ -1196,7 +1196,6 @@ impl Function {
11961196 | Insn :: GetConstantPath { .. } =>
11971197 { }
11981198 Insn :: StringCopy { val }
1199- | Insn :: ArrayDup { val }
12001199 | Insn :: StringIntern { val }
12011200 | Insn :: Return { val }
12021201 | Insn :: Defined { v : val, .. }
@@ -1240,6 +1239,10 @@ impl Function {
12401239 worklist. push_back ( val) ;
12411240 worklist. extend ( args) ;
12421241 }
1242+ Insn :: ArrayDup { val , state } => {
1243+ worklist. push_back ( val) ;
1244+ worklist. push_back ( state) ;
1245+ }
12431246 Insn :: Send { self_val, args, state, .. }
12441247 | Insn :: SendWithoutBlock { self_val, args, state, .. }
12451248 | Insn :: SendWithoutBlockDirect { self_val, args, state, .. } => {
@@ -1639,7 +1642,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
16391642 }
16401643 YARVINSN_duparray => {
16411644 let val = fun. push_insn ( block, Insn :: Const { val : Const :: Value ( get_arg ( pc, 0 ) ) } ) ;
1642- let insn_id = fun. push_insn ( block, Insn :: ArrayDup { val } ) ;
1645+ let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state. clone ( ) } ) ;
1646+ let insn_id = fun. push_insn ( block, Insn :: ArrayDup { val, state : exit_id } ) ;
16431647 state. stack_push ( insn_id) ;
16441648 }
16451649 YARVINSN_putobject_INT2FIX_0_ => {
@@ -2050,7 +2054,8 @@ mod infer_tests {
20502054 fn arraydup ( ) {
20512055 let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
20522056 let arr = function. push_insn ( function. entry_block , Insn :: NewArray { elements : vec ! [ ] } ) ;
2053- let val = function. push_insn ( function. entry_block , Insn :: ArrayDup { val : arr } ) ;
2057+ // Fake FrameState index of 0usize
2058+ let val = function. push_insn ( function. entry_block , Insn :: ArrayDup { val : arr, state : InsnId ( 0usize ) } ) ;
20542059 assert_bit_equal ( function. infer_type ( val) , types:: ArrayExact ) ;
20552060 }
20562061
@@ -2197,8 +2202,8 @@ mod tests {
21972202 fn test:
21982203 bb0():
21992204 v1:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
2200- v2 :ArrayExact = ArrayDup v1
2201- Return v2
2205+ v3 :ArrayExact = ArrayDup v1
2206+ Return v3
22022207 "# ] ] ) ;
22032208 }
22042209
@@ -2657,16 +2662,16 @@ mod tests {
26572662 bb0():
26582663 v1:BasicObject = PutSelf
26592664 v2:ArrayExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
2660- v3:ArrayExact = ArrayDup v2
2661- v4:ArrayExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
2662- v5:ArrayExact = ArrayDup v4
2663- v6:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010))
2664- v7:StringExact = StringCopy v6
2665+ v4:ArrayExact = ArrayDup v2
2666+ v5:ArrayExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
2667+ v7:ArrayExact = ArrayDup v5
26652668 v8:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010))
26662669 v9:StringExact = StringCopy v8
2667- v11:BasicObject = SendWithoutBlock v1, :unknown_method, v3, v5, v7, v9
2668- PatchPoint CalleeModifiedLocals(v11)
2669- Return v11
2670+ v10:StringExact[VALUE(0x1010)] = Const Value(VALUE(0x1010))
2671+ v11:StringExact = StringCopy v10
2672+ v13:BasicObject = SendWithoutBlock v1, :unknown_method, v4, v7, v9, v11
2673+ PatchPoint CalleeModifiedLocals(v13)
2674+ Return v13
26702675 "# ] ] ) ;
26712676 }
26722677}
@@ -3018,8 +3023,8 @@ mod opt_tests {
30183023 assert_optimized_method_hir ( "test" , expect ! [ [ r#"
30193024 fn test:
30203025 bb0():
3021- v4 :Fixnum[5] = Const Value(5)
3022- Return v4
3026+ v5 :Fixnum[5] = Const Value(5)
3027+ Return v5
30233028 "# ] ] ) ;
30243029 }
30253030
0 commit comments