@@ -675,6 +675,8 @@ pub enum Insn {
675675 GetIvar { self_val : InsnId , id : ID , state : InsnId } ,
676676 /// Set `self_val`'s instance variable `id` to `val`
677677 SetIvar { self_val : InsnId , id : ID , val : InsnId , state : InsnId } ,
678+ /// Set `self_val`'s instance variable `id` to `val` using the interpreter inline cache
679+ SetInstanceVariable { self_val : InsnId , id : ID , ic : * const iseq_inline_constant_cache , val : InsnId , state : InsnId } ,
678680 /// Check whether an instance variable exists on `self_val`
679681 DefinedIvar { self_val : InsnId , id : ID , pushval : VALUE , state : InsnId } ,
680682
@@ -866,7 +868,7 @@ impl Insn {
866868 | Insn :: PatchPoint { .. } | Insn :: SetIvar { .. } | Insn :: SetClassVar { .. } | Insn :: ArrayExtend { .. }
867869 | Insn :: ArrayPush { .. } | Insn :: SideExit { .. } | Insn :: SetGlobal { .. }
868870 | Insn :: SetLocal { .. } | Insn :: Throw { .. } | Insn :: IncrCounter ( _) | Insn :: IncrCounterPtr { .. }
869- | Insn :: CheckInterrupts { .. } | Insn :: GuardBlockParamProxy { .. } => false ,
871+ | Insn :: CheckInterrupts { .. } | Insn :: GuardBlockParamProxy { .. } | Insn :: SetInstanceVariable { .. } => false ,
870872 _ => true ,
871873 }
872874 }
@@ -1193,6 +1195,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
11931195 Insn :: LoadSelf => write ! ( f, "LoadSelf" ) ,
11941196 & Insn :: LoadField { recv, id, offset, return_type : _ } => write ! ( f, "LoadField {recv}, :{}@{:p}" , id. contents_lossy( ) , self . ptr_map. map_offset( offset) ) ,
11951197 Insn :: SetIvar { self_val, id, val, .. } => write ! ( f, "SetIvar {self_val}, :{}, {val}" , id. contents_lossy( ) ) ,
1198+ Insn :: SetInstanceVariable { self_val, id, val, .. } => write ! ( f, "SetInstanceVariable {self_val}, :{}, {val}" , id. contents_lossy( ) ) ,
11961199 Insn :: GetGlobal { id, .. } => write ! ( f, "GetGlobal :{}" , id. contents_lossy( ) ) ,
11971200 Insn :: SetGlobal { id, val, .. } => write ! ( f, "SetGlobal :{}, {val}" , id. contents_lossy( ) ) ,
11981201 & Insn :: GetLocal { level, ep_offset, use_sp : true , rest_param } => write ! ( f, "GetLocal l{level}, SP@{}{}" , ep_offset + 1 , if rest_param { ", *" } else { "" } ) ,
@@ -1817,6 +1820,7 @@ impl Function {
18171820 & GetIvar { self_val, id, state } => GetIvar { self_val : find ! ( self_val) , id, state } ,
18181821 & LoadField { recv, id, offset, return_type } => LoadField { recv : find ! ( recv) , id, offset, return_type } ,
18191822 & SetIvar { self_val, id, val, state } => SetIvar { self_val : find ! ( self_val) , id, val : find ! ( val) , state } ,
1823+ & SetInstanceVariable { self_val, id, ic, val, state } => SetInstanceVariable { self_val : find ! ( self_val) , id, ic, val : find ! ( val) , state } ,
18201824 & GetClassVar { id, ic, state } => GetClassVar { id, ic, state } ,
18211825 & SetClassVar { id, val, ic, state } => SetClassVar { id, val : find ! ( val) , ic, state } ,
18221826 & SetLocal { val, ep_offset, level } => SetLocal { val : find ! ( val) , ep_offset, level } ,
@@ -1870,7 +1874,8 @@ impl Function {
18701874 | Insn :: IfTrue { .. } | Insn :: IfFalse { .. } | Insn :: Return { .. } | Insn :: Throw { .. }
18711875 | Insn :: PatchPoint { .. } | Insn :: SetIvar { .. } | Insn :: SetClassVar { .. } | Insn :: ArrayExtend { .. }
18721876 | Insn :: ArrayPush { .. } | Insn :: SideExit { .. } | Insn :: SetLocal { .. } | Insn :: IncrCounter ( _)
1873- | Insn :: CheckInterrupts { .. } | Insn :: GuardBlockParamProxy { .. } | Insn :: IncrCounterPtr { .. } =>
1877+ | Insn :: CheckInterrupts { .. } | Insn :: GuardBlockParamProxy { .. } | Insn :: IncrCounterPtr { .. }
1878+ | Insn :: SetInstanceVariable { .. } =>
18741879 panic ! ( "Cannot infer type of instruction with no output: {}" , self . insns[ insn. 0 ] ) ,
18751880 Insn :: Const { val : Const :: Value ( val) } => Type :: from_value ( * val) ,
18761881 Insn :: Const { val : Const :: CBool ( val) } => Type :: from_cbool ( * val) ,
@@ -3379,7 +3384,8 @@ impl Function {
33793384 worklist. push_back ( self_val) ;
33803385 worklist. push_back ( state) ;
33813386 }
3382- & Insn :: SetIvar { self_val, val, state, .. } => {
3387+ & Insn :: SetIvar { self_val, val, state, .. }
3388+ | & Insn :: SetInstanceVariable { self_val, val, state, .. } => {
33833389 worklist. push_back ( self_val) ;
33843390 worklist. push_back ( val) ;
33853391 worklist. push_back ( state) ;
@@ -5089,13 +5095,13 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
50895095 }
50905096 YARVINSN_setinstancevariable => {
50915097 let id = ID ( get_arg ( pc, 0 ) . as_u64 ( ) ) ;
5092- // ic is in arg 1
5098+ let ic = get_arg ( pc , 1 ) . as_ptr ( ) ;
50935099 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
50945100 // Assume single-Ractor mode to omit gen_prepare_non_leaf_call on gen_setivar
50955101 // TODO: We only really need this if self_val is a class/module
50965102 fun. push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: SingleRactorMode , state : exit_id } ) ;
50975103 let val = state. stack_pop ( ) ?;
5098- fun. push_insn ( block, Insn :: SetIvar { self_val : self_param, id, val, state : exit_id } ) ;
5104+ fun. push_insn ( block, Insn :: SetInstanceVariable { self_val : self_param, id, ic , val, state : exit_id } ) ;
50995105 }
51005106 YARVINSN_getclassvariable => {
51015107 let id = ID ( get_arg ( pc, 0 ) . as_u64 ( ) ) ;
0 commit comments