Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JULY 2018 Security Update #5444

Merged
merged 13 commits into from
Jul 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build/NuGet/.pack-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.10.0
1.10.1
8 changes: 4 additions & 4 deletions lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -849,15 +849,15 @@ class GlobOpt
static void TrackByteCodeSymUsed(IR::Opnd * opnd, BVSparse<JitArenaAllocator> * instrByteCodeStackSymUsed, PropertySym **pPropertySymUse);
static void TrackByteCodeSymUsed(IR::RegOpnd * opnd, BVSparse<JitArenaAllocator> * instrByteCodeStackSymUsed);
static void TrackByteCodeSymUsed(StackSym * sym, BVSparse<JitArenaAllocator> * instrByteCodeStackSymUsed);
void CaptureValues(BasicBlock *block, BailOutInfo * bailOutInfo);
void CaptureValues(BasicBlock *block, BailOutInfo * bailOutInfo, BVSparse<JitArenaAllocator>* argsToCapture);
void CaptureValuesFromScratch(
BasicBlock * block,
SListBase<ConstantStackSymValue>::EditingIterator & bailOutConstValuesIter,
SListBase<CopyPropSyms>::EditingIterator & bailOutCopyPropIter);
SListBase<ConstantStackSymValue>::EditingIterator & bailOutConstValuesIter, SListBase<CopyPropSyms>::EditingIterator & bailOutCopyPropIter,
BVSparse<JitArenaAllocator>* argsToCapture);
void CaptureValuesIncremental(
BasicBlock * block,
SListBase<ConstantStackSymValue>::EditingIterator & bailOutConstValuesIter,
SListBase<CopyPropSyms>::EditingIterator & bailOutCopyPropIter);
SListBase<CopyPropSyms>::EditingIterator & bailOutCopyPropIter, BVSparse<JitArenaAllocator>* argsToCapture);
void CaptureCopyPropValue(BasicBlock * block, Sym * sym, Value * val, SListBase<CopyPropSyms>::EditingIterator & bailOutCopySymsIter);
void CaptureArguments(BasicBlock *block, BailOutInfo * bailOutInfo, JitArenaAllocator *allocator);
void CaptureByteCodeSymUses(IR::Instr * instr);
Expand Down
33 changes: 26 additions & 7 deletions lib/Backend/GlobOptBailOut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ GlobOpt::CaptureCopyPropValue(BasicBlock * block, Sym * sym, Value * val, SListB
void
GlobOpt::CaptureValuesFromScratch(BasicBlock * block,
SListBase<ConstantStackSymValue>::EditingIterator & bailOutConstValuesIter,
SListBase<CopyPropSyms>::EditingIterator & bailOutCopySymsIter)
SListBase<CopyPropSyms>::EditingIterator & bailOutCopySymsIter,
BVSparse<JitArenaAllocator>* argsToCapture)
{
Sym * sym = nullptr;
Value * value = nullptr;
Expand All @@ -49,6 +50,11 @@ GlobOpt::CaptureValuesFromScratch(BasicBlock * block,
}
NEXT_GLOBHASHTABLE_ENTRY;

if (argsToCapture)
{
block->globOptData.changedSyms->Or(argsToCapture);
}

FOREACH_BITSET_IN_SPARSEBV(symId, block->globOptData.changedSyms)
{
HashBucket<Sym*, Value*> * bucket = block->globOptData.symToValueMap->GetBucket(symId);
Expand Down Expand Up @@ -80,7 +86,8 @@ GlobOpt::CaptureValuesFromScratch(BasicBlock * block,
void
GlobOpt::CaptureValuesIncremental(BasicBlock * block,
SListBase<ConstantStackSymValue>::EditingIterator & bailOutConstValuesIter,
SListBase<CopyPropSyms>::EditingIterator & bailOutCopySymsIter)
SListBase<CopyPropSyms>::EditingIterator & bailOutCopySymsIter,
BVSparse<JitArenaAllocator>* argsToCapture)
{
CapturedValues * currCapturedValues = block->globOptData.capturedValues;
SListBase<ConstantStackSymValue>::Iterator iterConst(currCapturedValues ? &currCapturedValues->constantValues : nullptr);
Expand All @@ -90,6 +97,11 @@ GlobOpt::CaptureValuesIncremental(BasicBlock * block,

block->globOptData.changedSyms->Set(Js::Constants::InvalidSymID);

if (argsToCapture)
{
block->globOptData.changedSyms->Or(argsToCapture);
}

FOREACH_BITSET_IN_SPARSEBV(symId, block->globOptData.changedSyms)
{
Value * val = nullptr;
Expand Down Expand Up @@ -225,7 +237,7 @@ GlobOpt::CaptureValuesIncremental(BasicBlock * block,


void
GlobOpt::CaptureValues(BasicBlock *block, BailOutInfo * bailOutInfo)
GlobOpt::CaptureValues(BasicBlock *block, BailOutInfo * bailOutInfo, BVSparse<JitArenaAllocator>* argsToCapture)
{
if (!this->func->DoGlobOptsForGeneratorFunc())
{
Expand All @@ -244,11 +256,11 @@ GlobOpt::CaptureValues(BasicBlock *block, BailOutInfo * bailOutInfo)

if (!block->globOptData.capturedValues)
{
CaptureValuesFromScratch(block, bailOutConstValuesIter, bailOutCopySymsIter);
CaptureValuesFromScratch(block, bailOutConstValuesIter, bailOutCopySymsIter, argsToCapture);
}
else
{
CaptureValuesIncremental(block, bailOutConstValuesIter, bailOutCopySymsIter);
CaptureValuesIncremental(block, bailOutConstValuesIter, bailOutCopySymsIter, argsToCapture);
}

// attach capturedValues to bailOutInfo
Expand Down Expand Up @@ -892,6 +904,8 @@ GlobOpt::FillBailOutInfo(BasicBlock *block, BailOutInfo * bailOutInfo)
{
AssertMsg(!this->isCallHelper, "Bail out can't be inserted the middle of CallHelper sequence");

BVSparse<JitArenaAllocator>* argsToCapture = nullptr;

bailOutInfo->liveVarSyms = block->globOptData.liveVarSyms->CopyNew(this->func->m_alloc);
bailOutInfo->liveFloat64Syms = block->globOptData.liveFloat64Syms->CopyNew(this->func->m_alloc);
// The live int32 syms in the bailout info are only the syms resulting from lossless conversion to int. If the int32 value
Expand Down Expand Up @@ -971,7 +985,12 @@ GlobOpt::FillBailOutInfo(BasicBlock *block, BailOutInfo * bailOutInfo)
sym = opnd->GetStackSym();
Assert(this->currentBlock->globOptData.FindValue(sym));
// StackSym args need to be re-captured
this->currentBlock->globOptData.SetChangedSym(sym->m_id);
if (!argsToCapture)
{
argsToCapture = JitAnew(this->tempAlloc, BVSparse<JitArenaAllocator>, this->tempAlloc);
}

argsToCapture->Set(sym->m_id);
}

Assert(totalOutParamCount != 0);
Expand Down Expand Up @@ -1019,7 +1038,7 @@ GlobOpt::FillBailOutInfo(BasicBlock *block, BailOutInfo * bailOutInfo)

// Save the constant values that we know so we can restore them directly.
// This allows us to dead store the constant value assign.
this->CaptureValues(block, bailOutInfo);
this->CaptureValues(block, bailOutInfo, argsToCapture);
}

void
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/JnHelperMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ DECLSPEC_GUARDIGNORE _NOINLINE intptr_t GetNonTableMethodAddress(ThreadContextI
///----------------------------------------------------------------------------
intptr_t GetMethodOriginalAddress(ThreadContextInfo * context, JnHelperMethod helperMethod)
{
AssertOrFailFast(helperMethod >= 0 && helperMethod < IR::JnHelperMethodCount);
Copy link
Contributor Author

@atulkatti atulkatti Jul 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AssertOrFailFast [](start = 4, length = 16)

[CVE-2018-8276] LGTM #Resolved

intptr_t address = GetHelperMethods()[static_cast<WORD>(helperMethod)];
if (address == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/Common/ChakraCoreVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// ChakraCore version number definitions (used in ChakraCore binary metadata)
#define CHAKRA_CORE_MAJOR_VERSION 1
#define CHAKRA_CORE_MINOR_VERSION 10
#define CHAKRA_CORE_PATCH_VERSION 0
#define CHAKRA_CORE_PATCH_VERSION 1
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.

// -------------
Expand Down
5 changes: 5 additions & 0 deletions lib/JITServer/JITServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ ServerAddDOMFastPathHelper(
Assert(false);
return RPC_S_INVALID_ARG;
}
if (helper < 0 || helper >= IR::JnHelperMethodCount)
{
Assert(UNREACHED);
return E_ACCESSDENIED;
}

return ServerCallWrapper(scriptContextInfo, [&]()->HRESULT
{
Expand Down
12 changes: 8 additions & 4 deletions lib/Parser/Parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6311,7 +6311,9 @@ void Parser::ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncN
pnodeFnc->pnodeName = nullptr;

if ((m_token.tk != tkID || flags & fFncNoName)
&& (IsStrictMode() || (pnodeFnc->IsGenerator()) || m_token.tk != tkYIELD || fDeclaration)) // Function expressions can have the name yield even inside generator functions
&& (IsStrictMode() || fDeclaration
|| pnodeFnc->IsGenerator() || pnodeFnc->IsAsync()
|| (m_token.tk != tkYIELD && m_token.tk != tkAWAIT))) // Function expressions can have the name yield/await even inside generator/async functions
{
if (fDeclaration ||
m_token.IsReservedWord()) // For example: var x = (function break(){});
Expand All @@ -6321,7 +6323,7 @@ void Parser::ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncN
return;
}

Assert(m_token.tk == tkID || (m_token.tk == tkYIELD && !fDeclaration));
Assert(m_token.tk == tkID || (m_token.tk == tkYIELD && !fDeclaration) || (m_token.tk == tkAWAIT && !fDeclaration));

if (IsStrictMode())
{
Expand Down Expand Up @@ -8461,15 +8463,17 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
// binding operator, be it unary or binary.
Error(ERRsyntax);
}
if (m_currentScope->GetScopeType() == ScopeType_Parameter)
if (m_currentScope->GetScopeType() == ScopeType_Parameter
|| (m_currentScope->GetScopeType() == ScopeType_Block && m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter)) // Check whether this is a class definition inside param scope
{
Error(ERRsyntax);
}
}
else if (nop == knopAwait)
{
if (!this->GetScanner()->AwaitIsKeywordRegion() ||
m_currentScope->GetScopeType() == ScopeType_Parameter)
m_currentScope->GetScopeType() == ScopeType_Parameter ||
(m_currentScope->GetScopeType() == ScopeType_Block && m_currentScope->GetEnclosingScope()->GetScopeType() == ScopeType_Parameter)) // Check whether this is a class definition inside param scope
{
// As with the 'yield' keyword, the case where 'await' is scanned as a keyword (tkAWAIT)
// but the scanner is not treating await as a keyword (!this->GetScanner()->AwaitIsKeyword())
Expand Down
7 changes: 6 additions & 1 deletion lib/Runtime/Base/CrossSite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,12 @@ namespace Js
{
args.Values[i] = CrossSite::MarshalVar(targetScriptContext, args.Values[i]);
}
if (args.HasExtraArg())
if (args.HasNewTarget())
{
// Last value is new.target
args.Values[count] = CrossSite::MarshalVar(targetScriptContext, args.GetNewTarget());
}
else if (args.HasExtraArg())
{
// The final eval arg is a frame display that needs to be marshaled specially.
args.Values[count] = CrossSite::MarshalFrameDisplay(targetScriptContext, args.GetFrameDisplay());
Expand Down
7 changes: 7 additions & 0 deletions lib/Runtime/Base/ThreadServiceWrapperBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ bool ThreadServiceWrapperBase::ScheduleIdleCollect(uint ticks, bool scheduleAsTa

bool ThreadServiceWrapperBase::IdleCollect()
{
// Tracking service does not AddRef/Release the thread service and only keeps a function pointer and context parameter (this pointer)
// to execute the IdleCollect callback. It is possible that the tracking service gets destroyed as part of the collection
// during this IdleCollect. If that happens then we need to make sure ThreadService (which may be owned by the tracking service)
// is kept alive until this callback completes. Any pending timer is killed in the thread service destructor so we should not get
// any new callbacks after the thread service is destroyed.
AutoAddRefReleaseThreadService autoThreadServiceKeepAlive(this);

Copy link
Contributor Author

@atulkatti atulkatti Jul 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CVE-2018-8287] LGTM #Resolved

Assert(hasScheduledIdleCollect);
IDLE_COLLECT_VERBOSE_TRACE(_u("IdleCollect- reset hasScheduledIdleCollect\n"));
hasScheduledIdleCollect = false;
Expand Down
19 changes: 19 additions & 0 deletions lib/Runtime/Base/ThreadServiceWrapperBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,29 @@ class ThreadServiceWrapperBase : public ThreadServiceWrapper
virtual bool OnScheduleIdleCollect(uint delta, bool scheduleAsTask) = 0;
virtual void OnFinishIdleCollect() = 0;
virtual bool ShouldFinishConcurrentCollectOnIdleCallback() = 0;
virtual void AddRefThreadService() { /* do nothing */ };
virtual void ReleaseThreadService() { /* do nothing */ };

ThreadContext *GetThreadContext() { return threadContext; }

private:
class AutoAddRefReleaseThreadService
{
public:
AutoAddRefReleaseThreadService(ThreadServiceWrapperBase * threadService)
{
this->threadService = threadService;
threadService->AddRefThreadService();
}

~AutoAddRefReleaseThreadService()
{
threadService->ReleaseThreadService();
}

ThreadServiceWrapperBase * threadService;
};

static const unsigned int IdleTicks = 1000; // 1 second
static const unsigned int IdleFinishTicks = 100; // 100 ms;

Expand Down
4 changes: 2 additions & 2 deletions lib/Runtime/ByteCode/ByteCodeCacheReleaseFileVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
//-------------------------------------------------------------------------------------------------------
// NOTE: If there is a merge conflict the correct fix is to make a new GUID.

// {2E95A003-1442-404F-98D5-D5C973B8A719}
// {18949169-1B93-4123-B34A-F42F1C1EAF9A}
const GUID byteCodeCacheReleaseFileVersion =
{ 0x2E95A003, 0x1442, 0x404F, { 0x98, 0xD5, 0xD5, 0xC9, 0x73, 0xB8, 0xA7, 0x19 } };
{ 0x18949169, 0x1B93, 0x4123, { 0xB3, 0x4A, 0xF4, 0x2F, 0x1C, 0x1E, 0xAF, 0x9A } };
6 changes: 5 additions & 1 deletion lib/Runtime/InternalPropertyList.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ INTERNALPROPERTY(FrozenType) // Used to store shared frozen
INTERNALPROPERTY(StackTrace) // Stack trace object for Error.stack generation
INTERNALPROPERTY(StackTraceCache) // Cache of Error.stack string
INTERNALPROPERTY(WeakMapKeyMap) // WeakMap data stored on WeakMap key objects
INTERNALPROPERTY(HiddenObject) // Used to store hidden data for JS library code (Intl as an example will use this)
INTERNALPROPERTY(HiddenObject) // Used to store internal slot data for JS library code (Intl as an example will use this)
INTERNALPROPERTY(CachedUCollator) // Used to store cached UCollator objects for Intl.Collator
INTERNALPROPERTY(CachedUNumberFormat) // Used to store cached UNumberFormat objects for Intl.NumberFormat and Intl.PluralRules
INTERNALPROPERTY(CachedUDateFormat) // Used to store cached UDateFormat objects for Intl.DateTimeFormat
INTERNALPROPERTY(CachedUPluralRules) // Used to store cached UPluralRules objects for Intl.PluralRules
INTERNALPROPERTY(RevocableProxy) // Internal slot for [[RevokableProxy]] for revocable proxy in ES6
INTERNALPROPERTY(MutationBp) // Used to store strong reference to the mutation breakpoint object
#undef INTERNALPROPERTY
2 changes: 1 addition & 1 deletion lib/Runtime/Language/Arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ namespace Js

FrameDisplay* GetFrameDisplay() const
{
AssertOrFailFast(Info.Flags & CallFlags_ExtraArg);
AssertOrFailFast((Info.Flags & CallFlags_ExtraArg) && (!this->HasNewTarget()));

// There is an extra arg, so values should have Count + 1 members
return (FrameDisplay*)(this->Values[Info.Count]);
Expand Down
4 changes: 2 additions & 2 deletions lib/Runtime/Language/InterpreterHandler.inl
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@ EXDEF3_WMS(CUSTOM, LdLocalElemUndef, OP_LdLocalElemen
DEF3 (CUSTOM_L_R0, NewScIntArray, OP_NewScIntArray, Auxiliary)
DEF3 (CUSTOM_L_R0, NewScFltArray, OP_NewScFltArray, Auxiliary)
DEF3_WMS(CUSTOM_L_R0, ProfiledNewScArray, PROFILEDOP(OP_ProfiledNewScArray, OP_ProfiledNewScArray_NoProfile), ProfiledReg1Unsigned1)
DEF3 (CUSTOM_L_R0, ProfiledNewScIntArray, PROFILEDOP(OP_ProfiledNewScIntArray, OP_NewScIntArray), ProfiledAuxiliary)
DEF3 (CUSTOM_L_R0, ProfiledNewScFltArray, PROFILEDOP(OP_ProfiledNewScFltArray, OP_NewScFltArray), ProfiledAuxiliary)
DEF3 (CUSTOM_L_R0, ProfiledNewScIntArray, PROFILEDOP(ProfiledNewScIntArray<true>, ProfiledNewScIntArray<false>), ProfiledAuxiliary)
DEF3 (CUSTOM_L_R0, ProfiledNewScFltArray, PROFILEDOP(ProfiledNewScFltArray<true>, ProfiledNewScFltArray<false>), ProfiledAuxiliary)
DEF2_WMS(RegextoA1, NewRegEx, JavascriptRegExp::OP_NewRegEx)
EXDEF3_WMS(CUSTOM, InitClass, OP_InitClass, Class)
DEF2_WMS(BRBReturnP1toA1, BrOnEmpty, JavascriptOperators::OP_BrOnEmpty)
Expand Down
50 changes: 30 additions & 20 deletions lib/Runtime/Language/InterpreterStackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5144,14 +5144,6 @@ namespace Js

void InterpreterStackFrame::OP_NewScIntArray(const unaligned OpLayoutAuxiliary * playout)
{
#if ENABLE_PROFILE_INFO
if (isAutoProfiling)
{
OP_ProfiledNewScIntArray(static_cast<const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> *>(playout));
return;
}
#endif

const Js::AuxArray<int32> *ints = Js::ByteCodeReader::ReadAuxArray<int32>(playout->Offset, this->GetFunctionBody());

JavascriptNativeIntArray *arr = scriptContext->GetLibrary()->CreateNativeIntArrayLiteral(ints->count);
Expand All @@ -5168,8 +5160,15 @@ namespace Js
}

#if ENABLE_PROFILE_INFO
void InterpreterStackFrame::OP_ProfiledNewScIntArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout)
template <bool Profiled>
void InterpreterStackFrame::ProfiledNewScIntArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout)
{
if (!Profiled && !isAutoProfiling)
{
OP_NewScIntArray(playout);
return;
}

const Js::AuxArray<int32> *ints = Js::ByteCodeReader::ReadAuxArray<int32>(playout->Offset, this->GetFunctionBody());

Js::ProfileId profileId = playout->profileId;
Expand Down Expand Up @@ -5229,18 +5228,16 @@ namespace Js

SetReg(playout->R0, arr);
}
#else
template <bool Profiled>
void InterpreterStackFrame::ProfiledNewScIntArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout)
{
OP_NewScIntArray(playout);
}
#endif

void InterpreterStackFrame::OP_NewScFltArray(const unaligned OpLayoutAuxiliary * playout)
{
#if ENABLE_PROFILE_INFO
if (isAutoProfiling)
{
OP_ProfiledNewScFltArray(static_cast<const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> *>(playout));
return;
}
#endif

const Js::AuxArray<double> *doubles = Js::ByteCodeReader::ReadAuxArray<double>(playout->Offset, this->GetFunctionBody());

JavascriptNativeFloatArray *arr = scriptContext->GetLibrary()->CreateNativeFloatArrayLiteral(doubles->count);
Expand All @@ -5257,8 +5254,15 @@ namespace Js
}

#if ENABLE_PROFILE_INFO
void InterpreterStackFrame::OP_ProfiledNewScFltArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout)
template <bool Profiled>
void InterpreterStackFrame::ProfiledNewScFltArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout)
{
if (!Profiled && !isAutoProfiling)
{
OP_NewScFltArray(playout);
return;
}

const Js::AuxArray<double> *doubles = Js::ByteCodeReader::ReadAuxArray<double>(playout->Offset, this->GetFunctionBody());

Js::ProfileId profileId = playout->profileId;
Expand Down Expand Up @@ -5294,6 +5298,12 @@ namespace Js

SetReg(playout->R0, arr);
}
#else
template <bool Profiled>
void InterpreterStackFrame::ProfiledNewScFltArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout)
{
OP_NewScFltArray(playout);
}
#endif

void InterpreterStackFrame::OP_SetArraySegmentVars(const unaligned OpLayoutAuxiliary * playout)
Expand Down Expand Up @@ -6203,7 +6213,7 @@ namespace Js
}

template <class T, bool Profiled>
void InterpreterStackFrame::OP_NewScObjArray_Impl(const unaligned T* playout, const Js::AuxArray<uint32> *spreadIndices)
void InterpreterStackFrame::OP_ProfiledNewScObjArray_Impl(const unaligned T* playout, const Js::AuxArray<uint32> *spreadIndices)
{
// Always profile this operation when auto-profiling so that array type changes are tracked
#if ENABLE_PROFILE_INFO
Expand All @@ -6212,7 +6222,7 @@ namespace Js
Assert(!Profiled);
#endif
{
OP_NewScObject_Impl<T, Profiled, false>(playout, Js::Constants::NoInlineCacheIndex, spreadIndices);
OP_NewScObjArray_Impl<T, Profiled>(playout, spreadIndices);
return;
}

Expand Down
Loading