Skip to content

Commit

Permalink
[1.8>1.9] [MERGE #4676 @pleath] ChakraCore 2018-02 security updates
Browse files Browse the repository at this point in the history
Merge pull request #4676 from pleath:1802-1.8
  • Loading branch information
pleath committed Feb 13, 2018
2 parents c6c0ff7 + 263ab1b commit e3e1a36
Show file tree
Hide file tree
Showing 71 changed files with 1,038 additions and 874 deletions.
3 changes: 3 additions & 0 deletions lib/Backend/FlowGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,15 @@ FlowGraph::Build(void)
case Js::OpCode::TryCatch:
if (this->catchLabelStack)
{
AssertOrFailFast(!this->catchLabelStack->Empty());
this->catchLabelStack->Pop();
}
break;

case Js::OpCode::TryFinally:
if (this->finallyLabelStack)
{
AssertOrFailFast(!this->finallyLabelStack->Empty());
this->finallyLabelStack->Pop();
}
break;
Expand Down Expand Up @@ -497,6 +499,7 @@ FlowGraph::Build(void)
}
else if (instr->m_opcode == Js::OpCode::Finally)
{
AssertOrFailFast(!this->finallyLabelStack->Empty());
this->finallyLabelStack->Pop();
}
}
Expand Down
13 changes: 6 additions & 7 deletions lib/Backend/FunctionJITTimeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
if(objTypeSpecInfo)
{
jitData->objTypeSpecFldInfoCount = jitData->bodyData->inlineCacheCount;
jitData->objTypeSpecFldInfoArray = (ObjTypeSpecFldIDL**)objTypeSpecInfo;
jitData->objTypeSpecFldInfoArray = unsafe_write_barrier_cast<ObjTypeSpecFldIDL**>(objTypeSpecInfo);
}
for (Js::InlineCacheIndex i = 0; i < jitData->bodyData->inlineCacheCount; ++i)
{
Expand All @@ -131,7 +131,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
Assert(globObjTypeSpecInfo != nullptr);

jitData->globalObjTypeSpecFldInfoCount = codeGenData->GetGlobalObjTypeSpecFldInfoCount();
jitData->globalObjTypeSpecFldInfoArray = (ObjTypeSpecFldIDL**)globObjTypeSpecInfo;
jitData->globalObjTypeSpecFldInfoArray = unsafe_write_barrier_cast<ObjTypeSpecFldIDL**>(globObjTypeSpecInfo);
}
const Js::FunctionCodeGenJitTimeData * nextJITData = codeGenData->GetNext();
if (nextJITData != nullptr)
Expand Down Expand Up @@ -259,7 +259,7 @@ FunctionJITTimeInfo::GetRuntimeInfo() const
ObjTypeSpecFldInfo *
FunctionJITTimeInfo::GetObjTypeSpecFldInfo(uint index) const
{
Assert(index < GetBody()->GetInlineCacheCount());
AssertOrFailFast(index < GetBody()->GetInlineCacheCount());
if (m_data.objTypeSpecFldInfoArray == nullptr)
{
return nullptr;
Expand All @@ -271,7 +271,7 @@ FunctionJITTimeInfo::GetObjTypeSpecFldInfo(uint index) const
ObjTypeSpecFldInfo *
FunctionJITTimeInfo::GetGlobalObjTypeSpecFldInfo(uint index) const
{
Assert(index < m_data.globalObjTypeSpecFldInfoCount);
AssertOrFailFast(index < m_data.globalObjTypeSpecFldInfoCount);

return reinterpret_cast<ObjTypeSpecFldInfo *>(m_data.globalObjTypeSpecFldInfoArray[index]);
}
Expand All @@ -298,8 +298,7 @@ FunctionJITTimeInfo::GetLdFldInlinee(Js::InlineCacheIndex inlineCacheIndex) cons
{
return nullptr;
}
Assert(inlineCacheIndex < m_data.ldFldInlineeCount);

AssertOrFailFast(inlineCacheIndex < m_data.ldFldInlineeCount);

return reinterpret_cast<const FunctionJITTimeInfo*>(m_data.ldFldInlinees[inlineCacheIndex]);
}
Expand All @@ -312,7 +311,7 @@ FunctionJITTimeInfo::GetInlinee(Js::ProfileId profileId) const
{
return nullptr;
}
Assert(profileId < m_data.inlineeCount);
AssertOrFailFast(profileId < m_data.inlineeCount);

auto inlinee = reinterpret_cast<const FunctionJITTimeInfo *>(m_data.inlinees[profileId]);
if (inlinee == nullptr && m_data.inlineesRecursionFlags[profileId])
Expand Down
43 changes: 42 additions & 1 deletion lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5191,7 +5191,7 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
if (!PHASE_OFF(Js::OptTagChecksPhase, this->func) &&
(src1ValueInfo == nullptr || src1ValueInfo->IsUninitialized()))
{
return this->NewGenericValue(ValueType::GetObject(ObjectType::Object), dst);
return this->NewGenericValue(ValueType::GetObject(ObjectType::Object).ToLikely().SetCanBeTaggedValue(false), dst);
}
break;

Expand Down Expand Up @@ -15399,6 +15399,47 @@ GlobOpt::CheckJsArrayKills(IR::Instr *const instr)
}
break;
}

case Js::OpCode::InitProto:
{
// Find the 'this' parameter and check if it's possible for it to be an array
IR::Opnd *const arrayOpnd = instr->GetSrc1();
Assert(arrayOpnd);
const ValueType arrayValueType(arrayOpnd->GetValueType());
if(!arrayOpnd->IsRegOpnd() || (useValueTypes && arrayValueType.IsNotArrayOrObjectWithArray()))
{
break;
}

if(doNativeArrayTypeSpec && !(useValueTypes && arrayValueType.IsNotNativeArray()))
{
kills.SetKillsNativeArrays();
}
break;
}

case Js::OpCode::InitClass:
Assert(instr->GetSrc1());
if (instr->GetSrc2() == nullptr)
{
// No extends operand, so the InitClass will not make something into a prototype
break;
}

if(doNativeArrayTypeSpec)
{
// Class/object construction can make something a prototype
kills.SetKillsNativeArrays();
}
break;

case Js::OpCode::NewScObjectNoCtor:
if(doNativeArrayTypeSpec)
{
// Class/object construction can make something a prototype
kills.SetKillsNativeArrays();
}
break;
}

return kills;
Expand Down
56 changes: 32 additions & 24 deletions lib/Backend/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,7 @@ IRBuilder::Build()
this->m_loopBodyLocalsStartSlot = (Js::PropertyId)(localsOffset / sizeof(Js::Var));
}

#if DBG
m_offsetToInstructionCount = offsetToInstructionCount;
#endif
m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount);

#ifdef BYTECODE_BRANCH_ISLAND
Expand Down Expand Up @@ -820,7 +818,8 @@ IRBuilder::Build()
m_lastInstr->m_opcode == Js::OpCode::RuntimeTypeError)
{
uint32 lastInstrOffset = m_lastInstr->GetByteCodeOffset();
Assert(lastInstrOffset < m_offsetToInstructionCount);

AssertOrFailFast(lastInstrOffset < m_offsetToInstructionCount);
#if DBG
__analysis_assume(lastInstrOffset < this->m_offsetToInstructionCount);
#endif
Expand Down Expand Up @@ -1069,7 +1068,7 @@ IRBuilder::CreateLabel(IR::BranchInstr * branchInstr, uint& offset)

for (;;)
{
Assert(offset < m_offsetToInstructionCount);
AssertOrFailFast(offset < m_offsetToInstructionCount);
targetInstr = this->m_offsetToInstruction[offset];
if (targetInstr != nullptr)
{
Expand Down Expand Up @@ -1118,7 +1117,7 @@ IRBuilder::CreateLabel(IR::BranchInstr * branchInstr, uint& offset)

void IRBuilder::InsertInstr(IR::Instr *instr, IR::Instr* insertBeforeInstr)
{
Assert(insertBeforeInstr->GetByteCodeOffset() < m_offsetToInstructionCount);
AssertOrFailFast(insertBeforeInstr->GetByteCodeOffset() < m_offsetToInstructionCount);
instr->SetByteCodeOffset(insertBeforeInstr);
uint32 offset = insertBeforeInstr->GetByteCodeOffset();
if (m_offsetToInstruction[offset] == insertBeforeInstr)
Expand Down Expand Up @@ -1150,7 +1149,7 @@ IRBuilder::AddInstr(IR::Instr *instr, uint32 offset)
m_lastInstr->InsertAfter(instr);
if (offset != Js::Constants::NoByteCodeOffset)
{
Assert(offset < m_offsetToInstructionCount);
AssertOrFailFast(offset < m_offsetToInstructionCount);
if (m_offsetToInstruction[offset] == nullptr)
{
m_offsetToInstruction[offset] = instr;
Expand Down Expand Up @@ -1213,6 +1212,7 @@ IRBuilder::BuildIndirOpnd(IR::RegOpnd *baseReg, uint32 offset, const char16 *des
IR::SymOpnd *
IRBuilder::BuildFieldOpnd(Js::OpCode newOpcode, Js::RegSlot reg, Js::PropertyId propertyId, Js::PropertyIdIndexType propertyIdIndex, PropertyKind propertyKind, uint inlineCacheIndex)
{
AssertOrFailFast(inlineCacheIndex < m_func->GetJITFunctionBody()->GetInlineCacheCount() || inlineCacheIndex == Js::Constants::NoInlineCacheIndex);
PropertySym * propertySym = BuildFieldSym(reg, propertyId, propertyIdIndex, inlineCacheIndex, propertyKind);
IR::SymOpnd * symOpnd;

Expand Down Expand Up @@ -1798,7 +1798,8 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
case Js::OpCode::Catch:
if (this->handlerOffsetStack)
{
Assert(this->handlerOffsetStack->Top().Second() == true);
AssertOrFailFast(!this->handlerOffsetStack->Empty());
AssertOrFailFast(this->handlerOffsetStack->Top().Second() == true);
this->handlerOffsetStack->Pop();
}
dstIsCatchObject = true;
Expand Down Expand Up @@ -6125,19 +6126,24 @@ IRBuilder::BuildProfiledCallI(Js::OpCode opcode, uint32 offset, Js::RegSlot retu
if(this->m_func->GetWorkItem()->GetJITTimeInfo())
{
const FunctionJITTimeInfo *inlinerData = this->m_func->GetWorkItem()->GetJITTimeInfo();
if(!(this->IsLoopBody() && PHASE_OFF(Js::InlineInJitLoopBodyPhase, this->m_func)) &&
inlinerData && inlinerData->GetInlineesBV() && (!inlinerData->GetInlineesBV()->Test(profileId)
if (!(this->IsLoopBody() && PHASE_OFF(Js::InlineInJitLoopBodyPhase, this->m_func))
&& inlinerData && inlinerData->GetInlineesBV())
{
AssertOrFailFast(profileId < inlinerData->GetInlineesBV()->Length());
if (!inlinerData->GetInlineesBV()->Test(profileId)
#if DBG
|| (PHASE_STRESS(Js::BailOnNoProfilePhase, this->m_func->GetTopFunc()) &&
(CONFIG_FLAG(SkipFuncCountForBailOnNoProfile) < 0 ||
this->m_func->m_callSiteCount >= (uint)CONFIG_FLAG(SkipFuncCountForBailOnNoProfile)))
|| (PHASE_STRESS(Js::BailOnNoProfilePhase, this->m_func->GetTopFunc())
&& (CONFIG_FLAG(SkipFuncCountForBailOnNoProfile) < 0
|| this->m_func->m_callSiteCount >= (uint)CONFIG_FLAG(SkipFuncCountForBailOnNoProfile)))
#endif
))
{
this->InsertBailOnNoProfile(offset);
isProtectedByNoProfileBailout = true;
)
{
this->InsertBailOnNoProfile(offset);
isProtectedByNoProfileBailout = true;
}
}
else

if (!isProtectedByNoProfileBailout)
{
this->callTreeHasSomeProfileInfo = true;
}
Expand Down Expand Up @@ -6398,19 +6404,20 @@ IRBuilder::BuildCallCommon(IR::Instr * instr, StackSym * symDst, Js::ArgSlot arg
#endif

// Link all the args of this call by creating a def/use chain through the src2.

for (argInstr = this->m_argStack->Pop();
argInstr && argInstr->m_opcode != Js::OpCode::StartCall;
argInstr = this->m_argStack->Pop())
AssertOrFailFast(!m_argStack->Empty());
for (argInstr = m_argStack->Pop();
argInstr && !m_argStack->Empty() && argInstr->m_opcode != Js::OpCode::StartCall;
argInstr = m_argStack->Pop())
{
prevInstr->SetSrc2(argInstr->GetDst());
prevInstr = argInstr;
#if DBG
count++;
#endif
}
AssertOrFailFast(argInstr == nullptr || argInstr->m_opcode == Js::OpCode::StartCall);

if (this->m_argStack->Empty())
if (m_argStack->Empty())
{
this->callTreeHasSomeProfileInfo = false;
}
Expand Down Expand Up @@ -6736,7 +6743,8 @@ IRBuilder::BuildEmpty(Js::OpCode newOpcode, uint32 offset)
case Js::OpCode::Finally:
if (this->handlerOffsetStack)
{
Assert(this->handlerOffsetStack->Top().Second() == false);
AssertOrFailFast(!this->handlerOffsetStack->Empty());
AssertOrFailFast(this->handlerOffsetStack->Top().Second() == false);
this->handlerOffsetStack->Pop();
}
finallyBlockLevel++;
Expand Down Expand Up @@ -6971,7 +6979,6 @@ IRBuilder::BuildBr(Js::OpCode newOpcode, uint32 offset)
IR::BranchInstr * branchInstr;
const unaligned Js::OpLayoutBr *branchInsn = m_jnReader.Br();
unsigned int targetOffset = m_jnReader.GetCurrentOffset() + branchInsn->RelativeJumpOffset;

#ifdef BYTECODE_BRANCH_ISLAND
bool isLongBranchIsland = (m_jnReader.PeekOp() == Js::OpCode::BrLong);
if (isLongBranchIsland)
Expand Down Expand Up @@ -7154,6 +7161,7 @@ IRBuilder::BuildBrEnvProperty(Js::OpCode newOpcode, uint32 offset)
BranchReloc *
IRBuilder::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset)
{
AssertOrFailFast(targetOffset <= m_func->GetJITFunctionBody()->GetByteCodeLength());
//
// Loop jitting would be done only till the LoopEnd
// Any branches beyond that offset are for the return stmt
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ class IRBuilder
Func * m_func;
IR::Instr * m_lastInstr;
IR::Instr ** m_offsetToInstruction;
uint32 m_offsetToInstructionCount;
uint32 m_functionStartOffset;
Js::ByteCodeReader m_jnReader;
Js::StatementReader<Js::FunctionBody::ArenaStatementMapList> m_statementReader;
Expand Down Expand Up @@ -363,7 +364,6 @@ class IRBuilder
// used to estimate how much stack we should probe for at the
// beginning of a JITted function.
#if DBG
uint32 m_offsetToInstructionCount;
uint32 m_callsOnStack;
#endif
uint32 m_argsOnStack;
Expand Down
16 changes: 8 additions & 8 deletions lib/Backend/IRBuilderAsmJs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ IRBuilderAsmJs::Build()
offsetToInstructionCount = lastOffset + 2;
}

#if DBG
m_offsetToInstructionCount = offsetToInstructionCount;
#endif
m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount);

LoadNativeCodeData();
Expand Down Expand Up @@ -220,7 +218,7 @@ IRBuilderAsmJs::AddInstr(IR::Instr * instr, uint32 offset)
m_lastInstr->InsertAfter(instr);
if (offset != Js::Constants::NoByteCodeOffset)
{
Assert(offset < m_offsetToInstructionCount);
AssertOrFailFast(offset < m_offsetToInstructionCount);
if (m_offsetToInstruction[offset] == nullptr)
{
m_offsetToInstruction[offset] = instr;
Expand Down Expand Up @@ -670,6 +668,7 @@ IRBuilderAsmJs::RegIsConstant(Js::RegSlot reg)
BranchReloc *
IRBuilderAsmJs::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset)
{
AssertOrFailFast(targetOffset <= m_func->GetJITFunctionBody()->GetByteCodeLength());
//
// Loop jitting would be done only till the LoopEnd
// Any branches beyond that offset are for the return statement
Expand Down Expand Up @@ -1042,8 +1041,8 @@ IRBuilderAsmJs::CreateLabel(IR::BranchInstr * branchInstr, uint & offset)
IR::Instr * targetInstr = nullptr;
while (targetInstr == nullptr)
{
AssertOrFailFast(offset < m_offsetToInstructionCount);
targetInstr = m_offsetToInstruction[offset];
Assert(offset < m_offsetToInstructionCount);
++offset;
}

Expand Down Expand Up @@ -1789,7 +1788,7 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
instr->AsProfiledInstr()->u.profileId = profileId;
}
}

AssertOrFailFast(!this->m_argOffsetStack->Empty());
argOffset = m_argOffsetStack->Pop();
argOffset -= MachPtr;
break;
Expand All @@ -1811,7 +1810,8 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
IR::Instr * argInstr = nullptr;
IR::Instr * prevInstr = instr;

for (argInstr = m_argStack->Pop(); argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop())
AssertOrFailFast(!this->m_argStack->Empty());
for (argInstr = m_argStack->Pop(); !m_argStack->Empty() && argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop())
{
if (newOpcode == Js::OpCodeAsmJs::I_Call || newOpcode == Js::OpCodeAsmJs::ProfiledI_Call)
{
Expand Down Expand Up @@ -1841,10 +1841,10 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
count++;
}

Assert(argInstr->m_opcode == Js::OpCode::StartCall);
AssertOrFailFast(argInstr->m_opcode == Js::OpCode::StartCall);
argInstr->SetSrc1(IR::IntConstOpnd::New(count, TyUint16, m_func));

Assert(argOffset == 0);
AssertOrFailFast(argOffset == 0);
prevInstr->SetSrc2(argInstr->GetDst());

#ifdef ENABLE_SIMDJS
Expand Down
2 changes: 0 additions & 2 deletions lib/Backend/IRBuilderAsmJs.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,7 @@ class IRBuilderAsmJs
JitLoopBodyData* m_jitLoopBodyData = nullptr;
IRBuilderAsmJsSwitchAdapter m_switchAdapter;
SwitchIRBuilder m_switchBuilder;
#if DBG
uint32 m_offsetToInstructionCount;
#endif

#define BUILD_LAYOUT_DEF(layout, ...) void Build##layout (Js::OpCodeAsmJs, uint32, __VA_ARGS__);
#define Reg_Type Js::RegSlot
Expand Down
Loading

0 comments on commit e3e1a36

Please sign in to comment.