@@ -3234,25 +3234,34 @@ impl Function {
32343234 is_t_object : recv_type. flags ( ) . is_t_object ( ) ,
32353235 is_embedded : recv_type. flags ( ) . is_embedded ( )
32363236 } ) ;
3237- self . push_insn ( block, Insn :: GetIvar { self_val : refined_recv, id, ic : std :: ptr:: null ( ) , state } )
3237+ self . push_insn ( block, Insn :: GetIvar { self_val : refined_recv, id, ic : ptr:: null ( ) , state } )
32383238 } else {
3239- self . push_insn ( block, Insn :: GetIvar { self_val : recv, id, ic : std :: ptr:: null ( ) , state } )
3239+ self . push_insn ( block, Insn :: GetIvar { self_val : recv, id, ic : ptr:: null ( ) , state } )
32403240 }
32413241 } else if let Some ( val) = self . type_of ( recv) . ruby_object ( ) {
32423242 // Constant receiver: get shape info from the VALUE directly
3243- let recv_shape = val. shape_id_of ( ) ;
3244- if recv_shape. is_valid ( ) && !recv_shape. is_too_complex ( ) {
3245- let shape = self . load_shape ( block, recv) ;
3246- self . guard_shape ( block, shape, recv_shape, state) ;
3247- let is_t_object = unsafe { RB_TYPE_P ( val, RUBY_T_OBJECT ) } ;
3248- let is_embedded = is_t_object && val. embedded_p ( ) ;
3249- let refined_recv = self . push_insn ( block, Insn :: RefineShape { val : recv, shape : recv_shape, is_t_object, is_embedded } ) ;
3250- self . push_insn ( block, Insn :: GetIvar { self_val : refined_recv, id, ic : std:: ptr:: null ( ) , state } )
3243+ // TODO missing snapshot test: attr reader on special const. Also
3244+ // missing: fallback reason
3245+ if !val. special_const_p ( ) {
3246+ let recv_shape = val. shape_id_of ( ) ;
3247+ if recv_shape. is_valid ( ) && !recv_shape. is_too_complex ( ) {
3248+ // load_shape is valid here without guard because type says recv is on-heap.
3249+ let shape = self . load_shape ( block, recv) ;
3250+ self . guard_shape ( block, shape, recv_shape, state) ;
3251+ let is_t_object = unsafe { RB_TYPE_P ( val, RUBY_T_OBJECT ) } ;
3252+ let is_embedded = is_t_object && val. embedded_p ( ) ;
3253+ let refined_recv = self . push_insn ( block, Insn :: RefineShape { val : recv, shape : recv_shape, is_t_object, is_embedded } ) ;
3254+ self . push_insn ( block, Insn :: GetIvar { self_val : refined_recv, id, ic : ptr:: null ( ) , state } )
3255+ } else {
3256+ self . push_insn ( block, Insn :: GetIvar { self_val : recv, id, ic : ptr:: null ( ) , state } )
3257+ }
32513258 } else {
3252- self . push_insn ( block, Insn :: GetIvar { self_val : recv, id, ic : std:: ptr:: null ( ) , state } )
3259+ // attr_reader on immediates always return nil
3260+ self . push_insn ( block, Insn :: Const { val : Const :: Value ( Qnil ) } )
32533261 }
32543262 } else {
3255- self . push_insn ( block, Insn :: GetIvar { self_val : recv, id, ic : std:: ptr:: null ( ) , state } )
3263+ // No profile and no static type info
3264+ self . push_insn ( block, Insn :: GetIvar { self_val : recv, id, ic : ptr:: null ( ) , state } )
32563265 } ;
32573266 self . make_equal_to ( insn_id, getivar) ;
32583267 } else if let ( false , VM_METHOD_TYPE_ATTRSET , & [ val] ) = ( has_block, def_type, args. as_slice ( ) ) {
0 commit comments