@@ -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, Type } ;
1515use crate :: options:: get_option;
1616
1717/// Ephemeral code generation state
@@ -1046,10 +1046,29 @@ fn gen_test(asm: &mut Assembler, val: lir::Opnd) -> Option<lir::Opnd> {
10461046
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 > {
1049- if guard_type. is_subtype ( Fixnum ) {
1050- // Check if opnd is Fixnum
1049+ if guard_type. is_subtype ( types:: 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 ( types:: 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 ( types:: 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 ( types:: NilClassExact ) {
1063+ asm. cmp ( val, Qnil . into ( ) ) ;
1064+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1065+ } else if guard_type. is_subtype ( types:: TrueClassExact ) {
1066+ asm. cmp ( val, Qtrue . into ( ) ) ;
1067+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
1068+ } else if guard_type. is_subtype ( types:: FalseClassExact ) {
1069+ assert ! ( Qfalse . as_i64( ) == 0 ) ;
1070+ asm. test ( val, val) ;
1071+ asm. jne ( side_exit ( jit, state, GuardType ( guard_type) ) ?) ;
10531072 } else if let Some ( expected_class) = guard_type. runtime_exact_ruby_class ( ) {
10541073 asm_comment ! ( asm, "guard exact class" ) ;
10551074
0 commit comments