@@ -850,7 +850,7 @@ pub enum Insn {
850850 /// Get the block parameter as a Proc.
851851 GetBlockParam { level : u32 , ep_offset : u32 , state : InsnId } ,
852852 /// Set a local variable in a higher scope or the heap
853- SetLocal { level : u32 , ep_offset : u32 , val : InsnId } ,
853+ SetLocal { level : u32 , ep_offset : u32 , ep : InsnId , val : InsnId } ,
854854 GetSpecialSymbol { symbol_type : SpecialBackrefSymbol , state : InsnId } ,
855855 GetSpecialNumber { nth : u64 , state : InsnId } ,
856856
@@ -2376,7 +2376,7 @@ impl Function {
23762376 & SetIvar { self_val, id, ic, val, state } => SetIvar { self_val : find ! ( self_val) , id, ic, val : find ! ( val) , state } ,
23772377 & GetClassVar { id, ic, state } => GetClassVar { id, ic, state } ,
23782378 & SetClassVar { id, val, ic, state } => SetClassVar { id, val : find ! ( val) , ic, state } ,
2379- & SetLocal { val, ep_offset, level } => SetLocal { val : find ! ( val) , ep_offset, level } ,
2379+ & SetLocal { val, ep_offset, level, ep } => SetLocal { val : find ! ( val) , ep_offset, level, ep } ,
23802380 & GetSpecialSymbol { symbol_type, state } => GetSpecialSymbol { symbol_type, state } ,
23812381 & GetSpecialNumber { nth, state } => GetSpecialNumber { nth, state } ,
23822382 & ToArray { val, state } => ToArray { val : find ! ( val) , state } ,
@@ -6752,14 +6752,18 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
67526752 YARVINSN_setlocal_WC_0 => {
67536753 // TODO(Jacob): Modify this to use guards
67546754 let ep_offset = get_arg ( pc, 0 ) . as_u32 ( ) ;
6755+ const level: u32 = 0 ;
6756+ let ep = fun. push_insn ( block, Insn :: GetEP { level } ) ;
67556757 let val = state. stack_pop ( ) ?;
67566758 if ep_escaped || has_blockiseq { // TODO: figure out how to drop has_blockiseq here
67576759 // Write the local using EP
6758- fun. push_insn ( block, Insn :: SetLocal { val, ep_offset, level : 0 } ) ;
6760+ fun. push_insn ( block, Insn :: SetLocal { val, ep , ep_offset, level } ) ;
67596761 } else if local_inval {
67606762 // If there has been any non-leaf call since JIT entry or the last patch point,
67616763 // add a patch point to make sure locals have not been escaped.
67626764 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state. without_locals ( ) } ) ; // skip spilling locals
6765+ let flags = fun. push_insn ( block, Insn :: LoadField { recv : ep, id : ID ! ( _env_data_index_flags) , offset : SIZEOF_VALUE_I32 * ( VM_ENV_DATA_INDEX_FLAGS as i32 ) , return_type : types:: CInt64 } ) ;
6766+ fun. push_insn ( block, Insn :: GuardNoBitsSet { val : flags, mask : Const :: CUInt64 ( VM_ENV_FLAG_WB_REQUIRED . into ( ) ) , reason : SideExitReason :: WriteBarrierRequired , state : exit_id } ) ;
67636767 fun. push_insn ( block, Insn :: PatchPoint { invariant : Invariant :: NoEPEscape ( iseq) , state : exit_id } ) ;
67646768 local_inval = false ;
67656769 }
@@ -6773,7 +6777,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
67736777 YARVINSN_setlocal_WC_1 => {
67746778 // TODO(Jacob): Modify this to use guards
67756779 let ep_offset = get_arg ( pc, 0 ) . as_u32 ( ) ;
6776- fun. push_insn ( block, Insn :: SetLocal { val : state. stack_pop ( ) ?, ep_offset, level : 1 } ) ;
6780+ const level: u32 = 1 ;
6781+ let ep = fun. push_insn ( block, Insn :: GetEP { level } ) ;
6782+ let flags = fun. push_insn ( block, Insn :: LoadField { recv : ep, id : ID ! ( _env_data_index_flags) , offset : SIZEOF_VALUE_I32 * ( VM_ENV_DATA_INDEX_FLAGS as i32 ) , return_type : types:: CInt64 } ) ;
6783+ fun. push_insn ( block, Insn :: GuardNoBitsSet { val : flags, mask : Const :: CUInt64 ( VM_ENV_FLAG_WB_REQUIRED . into ( ) ) , reason : SideExitReason :: WriteBarrierRequired , state : exit_id } ) ;
6784+ fun. push_insn ( block, Insn :: SetLocal { val : state. stack_pop ( ) ?, ep, ep_offset, level } ) ;
67776785 }
67786786 YARVINSN_getlocal => {
67796787 let ep_offset = get_arg ( pc, 0 ) . as_u32 ( ) ;
@@ -6788,7 +6796,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
67886796 let ep = fun. push_insn ( block, Insn :: GetEP { level } ) ;
67896797 let flags = fun. push_insn ( block, Insn :: LoadField { recv : ep, id : ID ! ( _env_data_index_flags) , offset : SIZEOF_VALUE_I32 * ( VM_ENV_DATA_INDEX_FLAGS as i32 ) , return_type : types:: CInt64 } ) ;
67906798 fun. push_insn ( block, Insn :: GuardNoBitsSet { val : flags, mask : Const :: CUInt64 ( VM_ENV_FLAG_WB_REQUIRED . into ( ) ) , reason : SideExitReason :: WriteBarrierRequired , state : exit_id } ) ;
6791- fun. push_insn ( block, Insn :: SetLocal { val : state. stack_pop ( ) ?, ep_offset, level } ) ;
6799+ fun. push_insn ( block, Insn :: SetLocal { val : state. stack_pop ( ) ?, ep , ep_offset, level } ) ;
67926800 }
67936801 YARVINSN_getblockparamproxy => {
67946802 let level = get_arg ( pc, 1 ) . as_u32 ( ) ;
0 commit comments