Skip to content

Commit 996d35a

Browse files
committed
Fix unsafe lowering of fast path for String.charAt: we optimistically load a cached value into the result operand. But if the cached value is null, we'll have to call a helper to complete the operation, and if the result operand and string source have the same symbol, then we have overwritten the string we pass to the helper with null. Use a temp in such a case and copy it to the result operand only if it is non-null.
1 parent 291ebec commit 996d35a

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

lib/Backend/LowerMDShared.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5700,6 +5700,15 @@ bool LowererMD::GenerateFastCharAt(Js::BuiltinFunction index, IR::Opnd *dst, IR:
57005700
insertInstr->InsertBefore(instr);
57015701
if (index == Js::BuiltinFunction::String_CharAt)
57025702
{
5703+
IR::RegOpnd *resultOpnd;
5704+
if (dst->IsEqual(srcStr))
5705+
{
5706+
resultOpnd = IR::RegOpnd::New(TyVar, this->m_func);
5707+
}
5708+
else
5709+
{
5710+
resultOpnd = dst;
5711+
}
57035712
this->m_lowerer->GenerateGetSingleCharString(charReg, dst, labelHelper, doneLabel, insertInstr, false);
57045713
}
57055714
else

lib/Backend/arm/LowerMD.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6852,6 +6852,15 @@ bool LowererMD::GenerateFastCharAt(Js::BuiltinFunction index, IR::Opnd *dst, IR:
68526852

68536853
if (index == Js::BuiltinFunction::String_CharAt)
68546854
{
6855+
IR::RegOpnd *resultOpnd;
6856+
if (dst->IsEqual(srcStr))
6857+
{
6858+
resultOpnd = IR::RegOpnd::New(TyVar, this->m_func);
6859+
}
6860+
else
6861+
{
6862+
resultOpnd = dst;
6863+
}
68556864
this->m_lowerer->GenerateGetSingleCharString(charResult, dst, labelHelper, labelDone, insertInstr, false);
68566865
}
68576866
else

0 commit comments

Comments
 (0)