@@ -11,7 +11,7 @@ use crate::{asm::CodeBlock, cruby::*, options::debug, virtualmem::CodePtr};
1111use crate :: backend:: lir:: { self , asm_comment, asm_ccall, Assembler , Opnd , SideExitContext , Target , CFP , C_ARG_OPNDS , C_RET_OPND , EC , NATIVE_STACK_PTR , SP } ;
1212use crate :: hir:: { iseq_to_hir, Block , BlockId , BranchEdge , CallInfo , Invariant , RangeType , SideExitReason , SideExitReason :: * , SpecialObjectType , SELF_PARAM_IDX } ;
1313use crate :: hir:: { Const , FrameState , Function , Insn , InsnId } ;
14- use crate :: hir_type:: { types:: Fixnum , Type } ;
14+ use crate :: hir_type:: { types:: { Fixnum , Flonum , StaticSymbol , NilClass , TrueClass , FalseClass } , Type } ;
1515use crate :: options:: get_option;
1616
1717/// Ephemeral code generation state
@@ -1047,9 +1047,27 @@ fn gen_test(asm: &mut Assembler, val: lir::Opnd) -> Option<lir::Opnd> {
10471047/// Compile a type check with a side exit
10481048fn gen_guard_type ( jit : & mut JITState , asm : & mut Assembler , val : lir:: Opnd , guard_type : Type , state : & FrameState ) -> Option < lir:: Opnd > {
10491049 if guard_type. is_subtype ( Fixnum ) {
1050- // Check if opnd is Fixnum
10511050 asm. test ( val, Opnd :: UImm ( RUBY_FIXNUM_FLAG as u64 ) ) ;
10521051 asm. jz ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1052+ } else if guard_type. is_subtype ( Flonum ) {
1053+ // Flonum: (val & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG
1054+ let masked = asm. and ( val, Opnd :: UImm ( RUBY_FLONUM_MASK as u64 ) ) ;
1055+ asm. cmp ( masked, Opnd :: UImm ( RUBY_FLONUM_FLAG as u64 ) ) ;
1056+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1057+ } else if guard_type. is_subtype ( StaticSymbol ) {
1058+ // Static symbols have (val & 0xff) == RUBY_SYMBOL_FLAG
1059+ // Use 8-bit comparison like YJIT does
1060+ asm. cmp ( val. with_num_bits ( 8 ) . unwrap ( ) , Opnd :: UImm ( RUBY_SYMBOL_FLAG as u64 ) ) ;
1061+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1062+ } else if guard_type. is_subtype ( NilClass ) {
1063+ asm. cmp ( val, Qnil . into ( ) ) ;
1064+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1065+ } else if guard_type. is_subtype ( TrueClass ) {
1066+ asm. cmp ( val, Qtrue . into ( ) ) ;
1067+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1068+ } else if guard_type. is_subtype ( FalseClass ) {
1069+ asm. test ( val, val) ;
1070+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
10531071 } else if let Some ( expected_class) = guard_type. runtime_exact_ruby_class ( ) {
10541072 asm_comment ! ( asm, "guard exact class" ) ;
10551073
0 commit comments