@@ -367,7 +367,8 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
367367 Insn :: AnyToString { val, str, state } => gen_anytostring ( asm, opnd ! ( val) , opnd ! ( str ) , & function. frame_state ( * state) ) ?,
368368 Insn :: Defined { op_type, obj, pushval, v } => gen_defined ( jit, asm, * op_type, * obj, * pushval, opnd ! ( v) ) ?,
369369 & Insn :: IncrCounter ( counter) => return Some ( gen_incr_counter ( asm, counter) ) ,
370- Insn :: ArrayExtend { .. }
370+ Insn :: ToArray { val, state } => gen_to_array ( asm, opnd ! ( val) , & function. frame_state ( * state) ) ?,
371+ Insn :: ArrayExtend { left, right, state } => return gen_array_extend ( asm, opnd ! ( left) , opnd ! ( right) , & function. frame_state ( * state) ) ,
371372 | Insn :: ArrayMax { .. }
372373 | Insn :: ArrayPush { .. }
373374 | Insn :: DefinedIvar { .. }
@@ -379,7 +380,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
379380 | Insn :: Send { .. }
380381 | Insn :: StringIntern { .. }
381382 | Insn :: Throw { .. }
382- | Insn :: ToArray { .. }
383383 | Insn :: ToNewArray { .. }
384384 | Insn :: Const { .. }
385385 => {
@@ -1042,6 +1042,42 @@ fn gen_anytostring(asm: &mut Assembler, val: lir::Opnd, str: lir::Opnd, state: &
10421042 Some ( asm_ccall ! ( asm, rb_obj_as_string_result, str , val) )
10431043}
10441044
1045+ fn gen_to_array ( asm : & mut Assembler , val : lir:: Opnd , state : & FrameState ) -> Option < lir:: Opnd > {
1046+ // Save PC
1047+ gen_save_pc ( asm, state) ;
1048+
1049+ let klass = asm. ccall ( rb_yarv_class_of as * const u8 , vec ! [ val] ) ;
1050+ asm. cmp ( klass, Opnd :: Value ( unsafe { rb_cArray } ) ) ;
1051+
1052+ // Store whether val is an array (1 if array, 0 if not)
1053+ let is_array = asm. csel_e ( Opnd :: Imm ( 1 ) , Opnd :: Imm ( 0 ) ) ;
1054+ // Try to convert value to array using to_a
1055+ let converted = asm_ccall ! ( asm, rb_check_to_array, val) ;
1056+
1057+ // Create array with single element (for when conversion fails)
1058+ let wrapped = gen_new_array ( asm, vec ! [ val] , state) ;
1059+
1060+ // Check if conversion succeeded (returned non-nil)
1061+ asm. cmp ( converted, Qnil . into ( ) ) ;
1062+
1063+ // If conversion failed (nil), use wrapped; otherwise use converted
1064+ let converted_or_wrapped = asm. csel_e ( wrapped, converted) ;
1065+
1066+ // If val was already array, use it; otherwise use converted_or_wrapped
1067+ asm. cmp ( is_array, Opnd :: Imm ( 1 ) ) ;
1068+ let result = asm. csel_e ( val, converted_or_wrapped) ;
1069+
1070+ Some ( result)
1071+ }
1072+
1073+ fn gen_array_extend ( asm : & mut Assembler , left : lir:: Opnd , right : lir:: Opnd , state : & FrameState ) -> Option < ( ) > {
1074+ // Save PC
1075+ gen_save_pc ( asm, state) ;
1076+
1077+ asm_ccall ! ( asm, rb_ary_concat, left, right) ;
1078+ Some ( ( ) )
1079+ }
1080+
10451081/// Evaluate if a value is truthy
10461082/// Produces a CBool type (0 or 1)
10471083/// In Ruby, only nil and false are falsy
0 commit comments