@@ -3749,7 +3749,7 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3749
3749
IR::Opnd*
3750
3750
IRBuilder::GetEnvironmentOperand (uint32 offset)
3751
3751
{
3752
- SymID symID ;
3752
+ StackSym* sym = nullptr ;
3753
3753
// The byte code doesn't refer directly to a closure environment. Get the implicit one
3754
3754
// that's pointed to by the function body.
3755
3755
if (m_func->DoStackFrameDisplay () && m_func->GetLocalFrameDisplaySym ())
@@ -3760,19 +3760,35 @@ IRBuilder::GetEnvironmentOperand(uint32 offset)
3760
3760
this ->AddInstr (
3761
3761
IR::Instr::New (Js::OpCode::LdSlotArr, regOpnd, fieldOpnd, m_func),
3762
3762
offset);
3763
- symID = regOpnd->m_sym -> m_id ;
3763
+ sym = regOpnd->m_sym ;
3764
3764
}
3765
3765
else
3766
3766
{
3767
+ SymID symID;
3767
3768
symID = this ->GetEnvRegForInnerFrameDisplay ();
3768
3769
Assert (symID != Js::Constants::NoRegister);
3769
3770
if (IsLoopBody () && !RegIsConstant (symID))
3770
3771
{
3771
3772
this ->EnsureLoopBodyLoadSlot (symID);
3772
3773
}
3774
+
3775
+ if (m_func->DoStackNestedFunc () && symID == GetEnvReg ())
3776
+ {
3777
+ // Environment is not guaranteed constant during this function because it could become boxed during execution,
3778
+ // so load the environment every time you need it.
3779
+ IR::RegOpnd *regOpnd = IR::RegOpnd::New (TyVar, m_func);
3780
+ this ->AddInstr (
3781
+ IR::Instr::New (Js::OpCode::LdEnv, regOpnd, m_func),
3782
+ offset);
3783
+ sym = regOpnd->m_sym ;
3784
+ }
3785
+ else
3786
+ {
3787
+ sym = StackSym::FindOrCreate (symID, (Js::RegSlot)symID, m_func);
3788
+ }
3773
3789
}
3774
3790
3775
- return IR::RegOpnd::New (StackSym::FindOrCreate (symID, (Js::RegSlot)symID, m_func) , TyVar, m_func);
3791
+ return IR::RegOpnd::New (sym , TyVar, m_func);
3776
3792
}
3777
3793
3778
3794
template <typename SizePolicy>
0 commit comments