@@ -283,7 +283,7 @@ pub enum Insn {
283283 StringCopy { val : InsnId } ,
284284 StringIntern { val : InsnId } ,
285285
286- NewArray { count : usize } ,
286+ NewArray { elements : Vec < InsnId > } ,
287287 ArraySet { array : InsnId , idx : usize , val : InsnId } ,
288288 ArrayDup { val : InsnId } ,
289289
@@ -409,7 +409,15 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
409409 match & self . inner {
410410 Insn :: Const { val } => { write ! ( f, "Const {}" , val. print( & self . ptr_map) ) }
411411 Insn :: Param { idx } => { write ! ( f, "Param {idx}" ) }
412- Insn :: NewArray { count } => { write ! ( f, "NewArray {count}" ) }
412+ Insn :: NewArray { elements } => {
413+ write ! ( f, "NewArray" ) ?;
414+ let mut prefix = " " ;
415+ for element in elements {
416+ write ! ( f, "{prefix}{element}" ) ?;
417+ prefix = ", " ;
418+ }
419+ Ok ( ( ) )
420+ }
413421 Insn :: ArraySet { array, idx, val } => { write ! ( f, "ArraySet {array}, {idx}, {val}" ) }
414422 Insn :: ArrayDup { val } => { write ! ( f, "ArrayDup {val}" ) }
415423 Insn :: StringCopy { val } => { write ! ( f, "StringCopy {val}" ) }
@@ -1468,11 +1476,12 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
14681476 }
14691477 YARVINSN_newarray => {
14701478 let count = get_arg ( pc, 0 ) . as_usize ( ) ;
1471- let array = fun . push_insn ( block , Insn :: NewArray { count } ) ;
1472- for idx in ( 0 ..count) . rev ( ) {
1473- fun . push_insn ( block , Insn :: ArraySet { array , idx , val : state. stack_pop ( ) ? } ) ;
1479+ let mut elements = vec ! [ ] ;
1480+ for _ in 0 ..count {
1481+ elements . push ( state. stack_pop ( ) ?) ;
14741482 }
1475- state. stack_push ( array) ;
1483+ elements. reverse ( ) ;
1484+ state. stack_push ( fun. push_insn ( block, Insn :: NewArray { elements } ) ) ;
14761485 }
14771486 YARVINSN_duparray => {
14781487 let val = fun. push_insn ( block, Insn :: Const { val : Const :: Value ( get_arg ( pc, 0 ) ) } ) ;
@@ -1870,14 +1879,14 @@ mod infer_tests {
18701879 #[ test]
18711880 fn newarray ( ) {
18721881 let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
1873- let val = function. push_insn ( function. entry_block , Insn :: NewArray { count : 0 } ) ;
1882+ let val = function. push_insn ( function. entry_block , Insn :: NewArray { elements : vec ! [ ] } ) ;
18741883 assert_bit_equal ( function. infer_type ( val) , types:: ArrayExact ) ;
18751884 }
18761885
18771886 #[ test]
18781887 fn arraydup ( ) {
18791888 let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
1880- let arr = function. push_insn ( function. entry_block , Insn :: NewArray { count : 0 } ) ;
1889+ let arr = function. push_insn ( function. entry_block , Insn :: NewArray { elements : vec ! [ ] } ) ;
18811890 let val = function. push_insn ( function. entry_block , Insn :: ArrayDup { val : arr } ) ;
18821891 assert_bit_equal ( function. infer_type ( val) , types:: ArrayExact ) ;
18831892 }
@@ -1990,11 +1999,33 @@ mod tests {
19901999 assert_method_hir ( "test" , expect ! [ [ r#"
19912000 fn test:
19922001 bb0():
1993- v1:ArrayExact = NewArray 0
2002+ v1:ArrayExact = NewArray
19942003 Return v1
19952004 "# ] ] ) ;
19962005 }
19972006
2007+ #[ test]
2008+ fn test_new_array_with_element ( ) {
2009+ eval ( "def test(a) = [a]" ) ;
2010+ assert_method_hir ( "test" , expect ! [ [ r#"
2011+ fn test:
2012+ bb0(v0:BasicObject):
2013+ v2:ArrayExact = NewArray v0
2014+ Return v2
2015+ "# ] ] ) ;
2016+ }
2017+
2018+ #[ test]
2019+ fn test_new_array_with_elements ( ) {
2020+ eval ( "def test(a, b) = [a, b]" ) ;
2021+ assert_method_hir ( "test" , expect ! [ [ r#"
2022+ fn test:
2023+ bb0(v0:BasicObject, v1:BasicObject):
2024+ v3:ArrayExact = NewArray v0, v1
2025+ Return v3
2026+ "# ] ] ) ;
2027+ }
2028+
19982029 #[ test]
19992030 fn test_array_dup ( ) {
20002031 eval ( "def test = [1, 2, 3]" ) ;
@@ -2782,38 +2813,36 @@ mod opt_tests {
27822813 }
27832814
27842815 #[ test]
2785- fn test_eliminate_array_dup ( ) {
2816+ fn test_eliminate_new_array_with_elements ( ) {
27862817 eval ( "
2787- def test
2788- c = [1, 2 ]
2818+ def test(a)
2819+ c = [a ]
27892820 5
27902821 end
2791- test; test
2822+ test(1) ; test(2)
27922823 " ) ;
27932824 assert_optimized_method_hir ( "test" , expect ! [ [ r#"
27942825 fn test:
2795- bb0():
2826+ bb0(v0:BasicObject ):
27962827 v4:Fixnum[5] = Const Value(5)
27972828 Return v4
27982829 "# ] ] ) ;
27992830 }
28002831
28012832 #[ test]
2802- fn test_do_not_eliminate_array_set ( ) {
2833+ fn test_eliminate_array_dup ( ) {
28032834 eval ( "
2804- def test(a)
2805- c = [a ]
2835+ def test
2836+ c = [1, 2 ]
28062837 5
28072838 end
2808- test(3) ; test(4)
2839+ test; test
28092840 " ) ;
28102841 assert_optimized_method_hir ( "test" , expect ! [ [ r#"
28112842 fn test:
2812- bb0(v0:BasicObject):
2813- v3:ArrayExact = NewArray 1
2814- ArraySet v3, 0, v0
2815- v5:Fixnum[5] = Const Value(5)
2816- Return v5
2843+ bb0():
2844+ v4:Fixnum[5] = Const Value(5)
2845+ Return v4
28172846 "# ] ] ) ;
28182847 }
28192848
0 commit comments