Skip to content

Commit

Permalink
[MERGE #3509 @pleath] 17-08 ChakraCore servicing release
Browse files Browse the repository at this point in the history
Merge pull request #3509 from pleath:1708

Addresses the following:

CVE-2017-0228
CVE-2017-8634
CVE-2017-8635
CVE-2017-8636
CVE-2017-8637
CVE-2017-8638
CVE-2017-8640
CVE-2017-8641
CVE-2017-8645
CVE-2017-8646
CVE-2017-8647
CVE-2017-8655
CVE-2017-8656
CVE-2017-8657
CVE-2017-8658
CVE-2017-8659
CVE-2017-8670
CVE-2017-8671
CVE-2017-8672
CVE-2017-8674

Details:

[CVE-2017-8656] PreVisitCatch doesn't call SetIsCatch for all cases

The catch block has a var declaration with the same name as the destructured parameter. When we emit code for initializing vars we don't emit the initialization code for the symbol in the body as the catch param is not marked. The fix is to mark the destructured param as catch param.

Blind constants more aggressively in jitted code

Let RPC do handle marshalling for the JIT process

[CVE-2017-8647] Fix oop jit diff to check msvcrt instead of ucrt

[CVE-2017-8637] [CVE-2017-8659] Harden JIT process against bad input

[CVE-2017-8655] Prevent restoring inlinee frame with the wrong function object

Invalidate lastUsedSegment of an array at the right point

[CVE-2017-8638] Fix function object inline cache if function body got reparsed

[CVE-2017-8657] Postpone adding deferred top-level functions to the deferred function dictionary. Do this so that if byte code gen is interrupted or restarted, we are not left with orphaned functions in the dictionary that may be semi-initialized.

[CVE-2017-8658] Don't attempt to use deferred function stubs inside a formal argument list, as this leads to issues with arrow functions, nested functions, etc.

[CVE-2017-8635] Don't try to reuse property indexes on re-add of a deleted property if the object is non-extensible. Doing so exhausts the free indexes on repeated re-adds, which violates our assumption that a free index will always be available if a property has been deleted.

[CVE-2017-8671] Consider CallFlags_ExtraArg in Function.call implementation. Extra arg (for proxy, etc.) should not be a factor when copying/eliding arguments to delegate to the real target.

[CVE-2017-8674] Re-map function object types if AutoRestoreFunctionInfo has to restore FunctionInfo on failed re-parse/byte code gen.

[CVE-2017-8640] Mark the correct function node when we're detecting 'arguments' declaration that overrides the built-in declaration.

[CVE-2017-8670] Make sure we mark the correct function node when we're processing formal named 'arguments' in a destructured expression.

[CVE-2017-8672] Avoid passing JsNull as JsFunction*

In JavascriptStackWalker GetCaller we were sending out JsNull as a
JavascriptFunction* in the outparam. I checked all locations that
did a call to this function, and recursively as far as the outparam
escaped. Virtually all of the callers of the function or the other
functions that allowed escape of the outparam were safe, as checks
against the return value of GetCaller are near-ubiquitous. The one
callsite where this wasn't the case was in GlobalObject.cpp L#693,
which is in VEval. This location used the outparam without checks,
which meant that if a JsNull object were returned, we'd call other
functions which wouldn't necessarily be correct.

[CVE-2017-8645] Whitelist the type of functions allow to be asm.js module

[CVE-2017-8646] Correctly use PushPopFrameHelper in ProcessLinkFailedAsmJsModule.
No longer ignore arbitrary javascript code after a `let`

[CVE-2017-8641] Integer overflow in chakra!Js::GlobalObject
Integer overflow can happen in multiple cases of add-mult and allocate.
Fix by using UInt32Math::AddMul() to catch overflows.

[CVE-2017-8634] Type confusion in Concat due to IsConcatSpreadable

[CVE-2017-8636] Limiting args count to a certain limit. This limit will be enforced during the parser time. During the bytecode time we add so many extra args which actually overflowed the initial assumption.

[CVE-2017-0228]  We have attempted to fix the ReverseHelper case where the inline segment was swapped from head to bottom due to reverse loop below. However that fix was done for multi-segment scenario. The EnsureHeadStartsFromZero can also insert head segment in between if the segment's length is less than Array's length (look at the loop above), which will make the code vulnerable. Fixed that scenario by allocating the segment (for the single segment case) if the segment's length is less than array's length.
  • Loading branch information
pleath committed Aug 10, 2017
2 parents 8403578 + 2500e1c commit 63034a0
Show file tree
Hide file tree
Showing 78 changed files with 1,385 additions and 344 deletions.
1 change: 1 addition & 0 deletions Build/Chakra.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<PropertyGroup>
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win7)'">0x0601</Win32_WinNTVersion>
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win8)'">0x0602</Win32_WinNTVersion>
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_WinBlue)'">0x0603</Win32_WinNTVersion>
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win10)'">0x0A00</Win32_WinNTVersion>
</PropertyGroup>
<PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions Build/Common.Build.Default.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<PropertyGroup>
<NtTargetVersion_Win7 >0x601</NtTargetVersion_Win7>
<NtTargetVersion_Win8 >0x602</NtTargetVersion_Win8>
<NtTargetVersion_WinBlue>0x603</NtTargetVersion_WinBlue>
<NtTargetVersion_Win10>0xA00</NtTargetVersion_Win10>
</PropertyGroup>

Expand Down
3 changes: 3 additions & 0 deletions Build/Common.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
<!-- ======== sources.inc ======== -->
<!-- generates SAL annotations for our interface -->
<AdditionalOptions>%(AdditionalOptions) -sal_local</AdditionalOptions>

<PreprocessorDefinitions>%(PreprocessorDefinitions);WINVER=$(Win32_WinNTVersion)</PreprocessorDefinitions>
</Midl>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);NOMINMAX;USE_EDGEMODE_JSRT</PreprocessorDefinitions>
Expand Down Expand Up @@ -105,6 +107,7 @@

<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win7)'" >6.1</MinimumRequiredVersion>
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win8)'" >6.2</MinimumRequiredVersion>
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_WinBlue)'" >6.3</MinimumRequiredVersion>
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win10)'" >10.00</MinimumRequiredVersion>

<!-- Always set the checksum -->
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/AsmJsJITInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ AsmJsJITInfo::GetArgTypeArray() const
Js::AsmJsVarType::Which
AsmJsJITInfo::GetArgType(Js::ArgSlot argNum) const
{
Assert(argNum < GetArgCount());
AssertOrFailFast(argNum < GetArgCount());
return GetArgTypeArray()[argNum];
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/AsmJsJITInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class AsmJsJITInfo
Js::ArgSlot GetArgCount() const;
Js::ArgSlot GetArgByteSize() const;
Js::AsmJsRetType::Which GetRetType() const;
Js::AsmJsVarType::Which * GetArgTypeArray() const;
Js::AsmJsVarType::Which GetArgType(Js::ArgSlot argNum) const;

#ifdef ENABLE_WASM
Expand All @@ -40,6 +39,7 @@ class AsmJsJITInfo
bool AccessNeedsBoundCheck(uint offset) const;

private:
Js::AsmJsVarType::Which * GetArgTypeArray() const;
AsmJsDataIDL m_data;
#endif
};
7 changes: 7 additions & 0 deletions lib/Backend/CodeGenWorkItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ struct CodeGenWorkItem : public JsUtil::Job
return functionBody->GetScriptContext();
}

uint GetByteCodeLength() const
{
return this->functionBody->IsInDebugMode()
? this->functionBody->GetOriginalByteCode()->GetLength()
: this->functionBody->GetByteCode()->GetLength();
}

Js::FunctionBody* GetFunctionBody() const
{
return functionBody;
Expand Down
8 changes: 8 additions & 0 deletions lib/Backend/Func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,

Assert(this->IsInlined() == !!runtimeInfo);

AssertOrFailFast(!HasProfileInfo() || GetReadOnlyProfileInfo()->GetLoopCount() == GetJITFunctionBody()->GetLoopCount());
Js::RegSlot tmpResult;
AssertOrFailFast(!UInt32Math::Add(GetJITFunctionBody()->GetConstCount(), GetJITFunctionBody()->GetVarCount(), &tmpResult));
AssertOrFailFast(GetJITFunctionBody()->IsAsmJsMode() || GetJITFunctionBody()->GetFirstTmpReg() <= GetJITFunctionBody()->GetLocalsCount());
AssertOrFailFast(!IsLoopBody() || m_workItem->GetLoopNumber() < GetJITFunctionBody()->GetLoopCount());
AssertOrFailFast(CONFIG_FLAG(Prejit) || CONFIG_ISENABLED(Js::ForceNativeFlag) || GetJITFunctionBody()->GetByteCodeLength() < (uint)CONFIG_FLAG(MaxJITFunctionBytecodeByteLength));
GetJITFunctionBody()->EnsureConsistentConstCount();

if (this->IsTopFunc())
{
outputData->hasJittedStackClosure = false;
Expand Down
6 changes: 6 additions & 0 deletions lib/Backend/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ Instr::HasEquivalentTypeCheckBailOut() const
return this->HasBailOutInfo() && IR::IsEquivalentTypeCheckBailOutKind(this->GetBailOutKind());
}

bool
Instr::HasBailOnNoProfile() const
{
return this->HasBailOutInfo() && this->GetBailOutKind() == IR::BailOutOnNoProfile;
}

void
Instr::ChangeEquivalentToMonoTypeCheckBailOut()
{
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class Instr
bool HasAuxBailOut() const { return hasAuxBailOut; }
bool HasTypeCheckBailOut() const;
bool HasEquivalentTypeCheckBailOut() const;
bool HasBailOnNoProfile() const;
void ClearBailOutInfo();
bool IsDstNotAlwaysConvertedToInt32() const;
bool IsDstNotAlwaysConvertedToNumber() const;
Expand Down
5 changes: 4 additions & 1 deletion lib/Backend/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ IRBuilder::Build()
Js::RegSlot tempCount = m_func->GetJITFunctionBody()->GetTempCount();
if (tempCount > 0)
{
this->tempMap = (SymID*)m_tempAlloc->AllocZero(sizeof(SymID) * tempCount);
this->tempMap = AnewArrayZ(m_tempAlloc, SymID, tempCount);
this->fbvTempUsed = BVFixed::New<JitArenaAllocator>(tempCount, m_tempAlloc);
}
else
Expand Down Expand Up @@ -446,6 +446,7 @@ IRBuilder::Build()
#endif

lastOffset = m_func->m_workItem->GetLoopHeader()->endOffset;
AssertOrFailFast(lastOffset < m_func->GetJITFunctionBody()->GetByteCodeLength());
// Ret is created at lastOffset + 1, so we need lastOffset + 2 entries
offsetToInstructionCount = lastOffset + 2;

Expand Down Expand Up @@ -2721,6 +2722,7 @@ IRBuilder::BuildUnsigned1(Js::OpCode newOpcode, uint32 offset, uint32 num)

case Js::OpCode::ProfiledLoopStart:
{
AssertOrFailFast(num < m_func->GetJITFunctionBody()->GetLoopCount());
// If we're in profiling SimpleJit and jitting loop bodies, we need to keep this until lowering.
if (m_func->DoSimpleJitDynamicProfile() && m_func->GetJITFunctionBody()->DoJITLoopBody())
{
Expand Down Expand Up @@ -2771,6 +2773,7 @@ IRBuilder::BuildUnsigned1(Js::OpCode newOpcode, uint32 offset, uint32 num)

case Js::OpCode::ProfiledLoopEnd:
{
AssertOrFailFast(num < m_func->GetJITFunctionBody()->GetLoopCount());
// TODO: Decide whether we want the implicit loop call flags to be recorded in simplejitted loop bodies
if (m_func->DoSimpleJitDynamicProfile() && m_func->GetJITFunctionBody()->DoJITLoopBody())
{
Expand Down
18 changes: 13 additions & 5 deletions lib/Backend/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,37 +225,45 @@ class IRBuilder
AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(this->tempMap, "Processing non-temp reg without a temp map?");

return this->tempMap[reg - this->firstTemp];
Js::RegSlot tempIndex = reg - this->firstTemp;
AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
return this->tempMap[tempIndex];
}

void SetMappedTemp(Js::RegSlot reg, SymID tempId)
{
AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(this->tempMap, "Processing non-temp reg without a temp map?");

this->tempMap[reg - this->firstTemp] = tempId;
Js::RegSlot tempIndex = reg - this->firstTemp;
AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
this->tempMap[tempIndex] = tempId;
}

BOOL GetTempUsed(Js::RegSlot reg)
{
AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(this->fbvTempUsed, "Processing non-temp reg without a used BV?");

return this->fbvTempUsed->Test(reg - this->firstTemp);
Js::RegSlot tempIndex = reg - this->firstTemp;
AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
return this->fbvTempUsed->Test(tempIndex);
}

void SetTempUsed(Js::RegSlot reg, BOOL used)
{
AssertMsg(this->RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(this->fbvTempUsed, "Processing non-temp reg without a used BV?");

Js::RegSlot tempIndex = reg - this->firstTemp;
AssertOrFailFast(tempIndex < m_func->GetJITFunctionBody()->GetTempCount());
if (used)
{
this->fbvTempUsed->Set(reg - this->firstTemp);
this->fbvTempUsed->Set(tempIndex);
}
else
{
this->fbvTempUsed->Clear(reg - this->firstTemp);
this->fbvTempUsed->Clear(tempIndex);
}
}

Expand Down
33 changes: 22 additions & 11 deletions lib/Backend/IRBuilderAsmJs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ IRBuilderAsmJs::Build()
m_switchBuilder.Init(m_func, m_tempAlloc, true);

m_firstVarConst = 0;
Js::RegSlot tempCount = 0;
m_tempCount = 0;
m_firstsType[0] = m_firstVarConst + AsmJsRegSlots::RegCount;
for (int i = 0, j = 1; i < WAsmJs::LIMIT; ++i, ++j)
{
Expand All @@ -36,7 +36,7 @@ IRBuilderAsmJs::Build()
m_firstsType[j] = typedInfo.constCount;
m_firstsType[j + WAsmJs::LIMIT] = typedInfo.varCount;
m_firstsType[j + 2 * WAsmJs::LIMIT] = typedInfo.tmpCount;
tempCount += typedInfo.tmpCount;
m_tempCount += typedInfo.tmpCount;
}
// Fixup the firsts by looking at the previous value
for (int i = 1; i < m_firstsTypeCount; ++i)
Expand Down Expand Up @@ -66,10 +66,10 @@ IRBuilderAsmJs::Build()
// we will be using lower space for type specialized syms, so bump up where new temp syms can be created
m_func->m_symTable->IncreaseStartingID(m_firstIRTemp - m_func->m_symTable->GetMaxSymID());

if (tempCount > 0)
if (m_tempCount > 0)
{
m_tempMap = (SymID*)m_tempAlloc->AllocZero(sizeof(SymID) * tempCount);
m_fbvTempUsed = BVFixed::New<JitArenaAllocator>(tempCount, m_tempAlloc);
m_tempMap = AnewArrayZ(m_tempAlloc, SymID, m_tempCount);
m_fbvTempUsed = BVFixed::New<JitArenaAllocator>(m_tempCount, m_tempAlloc);
}
else
{
Expand Down Expand Up @@ -359,9 +359,10 @@ IRBuilderAsmJs::BuildIntConstOpnd(Js::RegSlot regSlot)
Js::Var * constTable = (Js::Var*)m_func->GetJITFunctionBody()->GetConstTable();
const WAsmJs::TypedSlotInfo& info = m_func->GetJITFunctionBody()->GetAsmJsInfo()->GetTypedSlotInfo(WAsmJs::INT32);
Assert(info.constSrcByteOffset != Js::Constants::InvalidOffset);
AssertOrFailFast(info.constSrcByteOffset < UInt32Math::Mul<sizeof(Js::Var)>(m_func->GetJITFunctionBody()->GetConstCount()));
int* intConstTable = reinterpret_cast<int*>(((byte*)constTable) + info.constSrcByteOffset);
Js::RegSlot srcReg = GetTypedRegFromRegSlot(regSlot, WAsmJs::INT32);
Assert(srcReg >= Js::FunctionBody::FirstRegSlot && srcReg < info.constCount);
AssertOrFailFast(srcReg >= Js::FunctionBody::FirstRegSlot && srcReg < info.constCount);
const int32 value = intConstTable[srcReg];
IR::IntConstOpnd *opnd = IR::IntConstOpnd::New(value, TyInt32, m_func);

Expand Down Expand Up @@ -536,7 +537,9 @@ IRBuilderAsmJs::GetMappedTemp(Js::RegSlot reg)
AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(m_tempMap, "Processing non-temp reg without a temp map?");

return m_tempMap[reg - GetFirstTmp(WAsmJs::FirstType)];
Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
AssertOrFailFast(tempIndex < m_tempCount);
return m_tempMap[tempIndex];
}

void
Expand All @@ -545,7 +548,9 @@ IRBuilderAsmJs::SetMappedTemp(Js::RegSlot reg, SymID tempId)
AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(m_tempMap, "Processing non-temp reg without a temp map?");

m_tempMap[reg - GetFirstTmp(WAsmJs::FirstType)] = tempId;
Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
AssertOrFailFast(tempIndex < m_tempCount);
m_tempMap[tempIndex] = tempId;
}

BOOL
Expand All @@ -554,7 +559,9 @@ IRBuilderAsmJs::GetTempUsed(Js::RegSlot reg)
AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(m_fbvTempUsed, "Processing non-temp reg without a used BV?");

return m_fbvTempUsed->Test(reg - GetFirstTmp(WAsmJs::FirstType));
Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
AssertOrFailFast(tempIndex < m_tempCount);
return m_fbvTempUsed->Test(tempIndex);
}

void
Expand All @@ -563,13 +570,15 @@ IRBuilderAsmJs::SetTempUsed(Js::RegSlot reg, BOOL used)
AssertMsg(RegIsTemp(reg), "Processing non-temp reg as a temp?");
AssertMsg(m_fbvTempUsed, "Processing non-temp reg without a used BV?");

Js::RegSlot tempIndex = reg - GetFirstTmp(WAsmJs::FirstType);
AssertOrFailFast(tempIndex < m_tempCount);
if (used)
{
m_fbvTempUsed->Set(reg - GetFirstTmp(WAsmJs::FirstType));
m_fbvTempUsed->Set(tempIndex);
}
else
{
m_fbvTempUsed->Clear(reg - GetFirstTmp(WAsmJs::FirstType));
m_fbvTempUsed->Clear(tempIndex);
}
}

Expand Down Expand Up @@ -697,6 +706,8 @@ void IRBuilderAsmJs::CreateLoadConstInstrForType(
)
{
T* typedTable = (T*)(table + byteOffset);
AssertOrFailFast(byteOffset < UInt32Math::Mul<sizeof(Js::Var)>(m_func->GetJITFunctionBody()->GetConstCount()));
AssertOrFailFast(AllocSizeMath::Add((size_t)typedTable, UInt32Math::Mul<sizeof(T)>(constCount)) <= (size_t)((Js::Var*)m_func->GetJITFunctionBody()->GetConstTable() + m_func->GetJITFunctionBody()->GetConstCount()));
// 1 for return register
++regAllocated;
++typedTable;
Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/IRBuilderAsmJs.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ class IRBuilderAsmJs
Js::RegSlot m_firstsType[m_firstsTypeCount];
Js::RegSlot m_firstVarConst;
Js::RegSlot m_firstIRTemp;
Js::RegSlot m_tempCount;

Js::OpCode * m_simdOpcodesMap;

Js::RegSlot GetFirstConst(WAsmJs::Types type) { return m_firstsType[type]; }
Expand Down
17 changes: 16 additions & 1 deletion lib/Backend/JITTimeFunctionBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,19 @@ JITTimeFunctionBody::GetConstantContent(Js::RegSlot location) const
return obj;
}

void
JITTimeFunctionBody::EnsureConsistentConstCount() const
{
if (GetConstCount() == 0 || IsAsmJsMode())
{
AssertOrFailFast(m_bodyData.constTableContent == nullptr);
}
else
{
AssertOrFailFast(m_bodyData.constTableContent != nullptr && GetConstCount() == m_bodyData.constTableContent->count);
}
}

intptr_t
JITTimeFunctionBody::GetInlineCache(uint index) const
{
Expand Down Expand Up @@ -1059,20 +1072,22 @@ JITTimeFunctionBody::GetAuxDataAddr(uint offset) const
void *
JITTimeFunctionBody::ReadFromAuxData(uint offset) const
{
AssertOrFailFast(offset < m_bodyData.auxDataCount);
return (void *)(m_bodyData.auxData + offset);
}

void *
JITTimeFunctionBody::ReadFromAuxContextData(uint offset) const
{
AssertOrFailFast(offset < m_bodyData.auxContextDataCount);
return (void *)(m_bodyData.auxContextData + offset);
}

const Js::PropertyIdArray *
JITTimeFunctionBody::ReadPropertyIdArrayFromAuxData(uint offset) const
{
Js::PropertyIdArray * auxArray = (Js::PropertyIdArray *)(m_bodyData.auxData + offset);
Assert(offset + auxArray->GetDataSize() <= m_bodyData.auxDataCount);
AssertOrFailFast(AllocSizeMath::Add(offset, auxArray->GetDataSize()) <= m_bodyData.auxDataCount);
return auxArray;
}

Expand Down
1 change: 1 addition & 0 deletions lib/Backend/JITTimeFunctionBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class JITTimeFunctionBody
bool CanInlineRecursively(uint depth, bool tryAggressive = true) const;
bool NeedScopeObjectForArguments(bool hasNonSimpleParams) const;
bool GetDoScopeObjectCreation() const;
void EnsureConsistentConstCount() const;

const byte * GetByteCodeBuffer() const;
StatementMapIDL * GetFullStatementMap() const;
Expand Down
3 changes: 2 additions & 1 deletion lib/Backend/JITTimeProfileInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class JITTimeProfileInfo
Js::ImplicitCallFlags GetImplicitCallFlags() const;
Js::LoopFlags GetLoopFlags(uint loopNum) const;

uint GetLoopCount() const;

uint16 GetConstantArgInfo(Js::ProfileId callSiteId) const;

bool IsModulusOpByPowerOf2(Js::ProfileId profileId) const;
Expand Down Expand Up @@ -116,7 +118,6 @@ class JITTimeProfileInfo
Js::ProfileId GetProfiledSlotCount() const;
Js::ArgSlot GetProfiledInParamsCount() const;
uint GetProfiledFldCount() const;
uint GetLoopCount() const;
BVFixed * GetLoopFlags() const;

bool TestFlag(ProfileDataFlags flag) const;
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/LinearScan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3632,7 +3632,7 @@ void LinearScan::TrackInlineeArgLifetimes(IR::Instr* instr)
Assert(this->currentBlock->inlineeStack.Count() == 0);
}
}
else if (instr->m_opcode == Js::OpCode::InlineeEnd)
else if (instr->m_opcode == Js::OpCode::InlineeEnd || instr->HasBailOnNoProfile())
{
if (instr->m_func->m_hasInlineArgsOpt)
{
Expand Down
Loading

0 comments on commit 63034a0

Please sign in to comment.