Skip to content

Commit a84fc40

Browse files
committed
[1.7>1.8] [MERGE #4411 @MikeHolman] 17-12 Security Update
Merge pull request #4411 from MikeHolman:1712 17-12 Security Update that addresses the following issues in ChakraCore: CVE-2017-11889 CVE-2017-11893 CVE-2017-11894 CVE-2017-11905 CVE-2017-11908 CVE-2017-11909 CVE-2017-11910 CVE-2017-11911 CVE-2017-11912 CVE-2017-11914 CVE-2017-11916 CVE-2017-11918 CVE-2017-11919 CVE-2017-11930
2 parents 1750fb6 + f5ab042 commit a84fc40

23 files changed

+272
-120
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7861,6 +7861,14 @@ BackwardPass::RemoveEmptyLoopAfterMemOp(Loop *loop)
78617861

78627862
outerBlock->RemovePred(head, this->func->m_fg);
78637863
landingPad->RemoveSucc(head, this->func->m_fg);
7864+
Assert(landingPad->GetSuccList()->Count() == 0);
7865+
7866+
IR::Instr* firstOuterInstr = outerBlock->GetFirstInstr();
7867+
AssertOrFailFast(firstOuterInstr->IsLabelInstr() && !landingPad->GetLastInstr()->EndsBasicBlock());
7868+
IR::LabelInstr* label = firstOuterInstr->AsLabelInstr();
7869+
// Add br to Outer block to keep coherence between branches and flow graph
7870+
IR::BranchInstr *outerBr = IR::BranchInstr::New(Js::OpCode::Br, label, this->func);
7871+
landingPad->InsertAfter(outerBr);
78647872
this->func->m_fg->AddEdge(landingPad, outerBlock);
78657873

78667874
this->func->m_fg->RemoveBlock(head, nullptr);

lib/Backend/GlobOpt.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12992,7 +12992,9 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
1299212992
Assert(kills.KillsTypedArrayHeadSegmentLengths());
1299312993

1299412994
// - Calls need to kill the value types of values in the following list. For instance, calls can transform a JS array
12995-
// into an ES5 array, so any definitely-array value types need to be killed. Update the value types.
12995+
// into an ES5 array, so any definitely-array value types need to be killed. Also, VirtualTypeArrays do not have
12996+
// bounds checks; this can be problematic if the array is detached, so check to ensure that it is a virtual array.
12997+
// Update the value types to likley to ensure a bailout that asserts Array type is generated.
1299612998
// - Calls also need to kill typed array head segment lengths. A typed array's array buffer may be transferred to a web
1299712999
// worker, in which case the typed array's length is set to zero.
1299813000
for(auto it = valuesToKillOnCalls->GetIterator(); it.IsValid(); it.MoveNext())
@@ -13002,7 +13004,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
1300213004
Assert(
1300313005
valueInfo->IsArrayOrObjectWithArray() ||
1300413006
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
13005-
if(valueInfo->IsArrayOrObjectWithArray())
13007+
if (valueInfo->IsArrayOrObjectWithArray() || valueInfo->IsOptimizedVirtualTypedArray())
1300613008
{
1300713009
ChangeValueType(nullptr, value, valueInfo->Type().ToLikely(), false);
1300813010
continue;
@@ -18225,8 +18227,8 @@ GlobOpt::TrackTempObjectSyms(IR::Instr * instr, IR::RegOpnd * opnd)
1822518227
(instr->GetSrc1()->IsRegOpnd() && globOptData.canStoreTempObjectSyms->Test(instr->GetSrc1()->AsRegOpnd()->m_sym->m_id))
1822618228
&& (!instr->GetSrc2() || (instr->GetSrc2()->IsRegOpnd() && globOptData.canStoreTempObjectSyms->Test(instr->GetSrc2()->AsRegOpnd()->m_sym->m_id))));
1822718229

18228-
Assert(!canStoreTemp || instr->dstIsTempObject);
18229-
Assert(!maybeTemp || instr->dstIsTempObject);
18230+
AssertOrFailFast(!canStoreTemp || instr->dstIsTempObject);
18231+
AssertOrFailFast(!maybeTemp || instr->dstIsTempObject);
1823018232
}
1823118233

1823218234
// Need to get the var equiv sym as assignment of type specialized sym kill the var sym value anyway.

lib/Backend/IRBuilderAsmJs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ IRBuilderAsmJs::CreateLabel(IR::BranchInstr * branchInstr, uint & offset)
10571057
}
10581058

10591059
IR::LabelInstr * labelInstr;
1060-
if (instrPrev && instrPrev->IsLabelInstr() && instrPrev->GetByteCodeOffset() == offset)
1060+
if (instrPrev && instrPrev->IsLabelInstr())
10611061
{
10621062
// Found an existing label at the right offset. Just reuse it.
10631063
labelInstr = instrPrev->AsLabelInstr();

lib/Backend/Inline.cpp

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,19 +2065,7 @@ Inline::InlineBuiltInFunction(IR::Instr *callInstr, const FunctionJITTimeInfo *
20652065
StackSym* originalCallTargetStackSym = callInstr->GetSrc1()->GetStackSym();
20662066
bool originalCallTargetOpndIsJITOpt = callInstr->GetSrc1()->GetIsJITOptimizedReg();
20672067

2068-
// We are committed to inlining, optimize the call instruction for fixed fields now and don't attempt it later.
2069-
bool safeThis = false;
2070-
if (TryOptimizeCallInstrWithFixedMethod(callInstr, inlineeData, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/, safeThis /*unused here*/))
2071-
{
2072-
Assert(callInstr->m_opcode == Js::OpCode::CallIFixed);
2073-
Assert(callInstr->GetFixedFunction()->GetFuncInfoAddr() == inlineeData->GetFunctionInfoAddr());
2074-
}
2075-
else
2076-
{
2077-
// FunctionObject check for built-ins
2078-
IR::BailOutInstr * bailOutInstr = IR::BailOutInstr::New(Js::OpCode::BailOnNotBuiltIn, IR::BailOutOnInlineFunction, callInstr, callInstr->m_func);
2079-
InsertFunctionObjectCheck(callInstr, callInstr, bailOutInstr, inlineeData);
2080-
}
2068+
IR::ByteCodeUsesInstr* useCallTargetInstr = EmitFixedMethodOrFunctionObjectChecksForBuiltIns(callInstr, callInstr, inlineeData, false, true, false, true);
20812069

20822070
// To push function object for cases when we have to make calls to helper method to assist in inlining
20832071
if(inlineCallOpCode == Js::OpCode::CallDirect)
@@ -2113,11 +2101,9 @@ Inline::InlineBuiltInFunction(IR::Instr *callInstr, const FunctionJITTimeInfo *
21132101
}
21142102
}
21152103

2116-
// Insert a byteCodeUsesInstr to make sure the function object's lifetime is extended beyond the last bailout point
2117-
// at which we may need to call the inlinee again in the interpreter.
2104+
if (useCallTargetInstr)
21182105
{
2119-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr);
2120-
useCallTargetInstr->SetRemovedOpndSymbol(originalCallTargetOpndIsJITOpt, originalCallTargetStackSym->m_id);
2106+
useCallTargetInstr->Unlink();
21212107
callInstr->InsertBefore(useCallTargetInstr);
21222108
}
21232109

@@ -2153,7 +2139,7 @@ Inline::InlineBuiltInFunction(IR::Instr *callInstr, const FunctionJITTimeInfo *
21532139

21542140
// Insert a byteCodeUsesInstr to make sure the function object's lifetime is extended beyond the last bailout point
21552141
// at which we may need to call the inlinee again in the interpreter.
2156-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr->GetPrevRealInstrOrLabel());
2142+
useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr->GetPrevRealInstrOrLabel());
21572143
useCallTargetInstr->SetRemovedOpndSymbol(originalCallTargetOpndIsJITOpt, originalCallTargetStackSym->m_id);
21582144

21592145
if(inlineCallOpCode == Js::OpCode::InlineArrayPop)
@@ -2451,7 +2437,7 @@ IR::Instr* Inline::InlineApply(IR::Instr *callInstr, const FunctionJITTimeInfo *
24512437

24522438
// TODO: OOP JIT enable assert (readprocessmemory?)
24532439
//Assert((inlineeData->GetFunctionInfo()->GetAttributes() & Js::FunctionInfo::Attributes::BuiltInInlinableAsLdFldInlinee) != 0);
2454-
return InlineApplyWithArray(callInstr, applyData, Js::JavascriptLibrary::GetBuiltInForFuncInfo(inlineeData->GetFunctionInfoAddr(), this->topFunc->GetThreadContextInfo()));
2440+
return InlineApplyBuiltInTargetWithArray(callInstr, applyData, inlineeData);
24552441
}
24562442
else
24572443
{
@@ -2568,7 +2554,7 @@ IR::Instr * Inline::InlineApplyWithArgumentsObject(IR::Instr * callInstr, IR::In
25682554
/*
25692555
This method will only do CallDirect style inlining of built-in targets. No script function inlining.
25702556
*/
2571-
IR::Instr * Inline::InlineApplyWithArray(IR::Instr * callInstr, const FunctionJITTimeInfo * funcInfo, Js::BuiltinFunction builtInId)
2557+
IR::Instr * Inline::InlineApplyBuiltInTargetWithArray(IR::Instr * callInstr, const FunctionJITTimeInfo * applyInfo, const FunctionJITTimeInfo * builtInInfo)
25722558
{
25732559
IR::Instr * implicitThisArgOut = nullptr;
25742560
IR::Instr * explicitThisArgOut = nullptr;
@@ -2579,8 +2565,25 @@ IR::Instr * Inline::InlineApplyWithArray(IR::Instr * callInstr, const FunctionJI
25792565
Assert(implicitThisArgOut);
25802566
Assert(explicitThisArgOut);
25812567
Assert(arrayArgOut);
2568+
Js::OpCode originalCallOpcode = callInstr->m_opcode;
2569+
IR::Opnd * originalCallSrc1 = callInstr->GetSrc1()->Copy(this->topFunc);
2570+
IR::AutoReuseOpnd autoReuseOriginalCallSrc1(originalCallSrc1, this->topFunc);
25822571

2583-
TryFixedMethodAndPrepareInsertionPoint(callInstr, funcInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
2572+
IR::Instr* applyLdInstr = nullptr;
2573+
IR::Instr* applyTargetLdInstr = nullptr;
2574+
if (!TryGetApplyAndTargetLdInstrs(callInstr, &applyLdInstr, &applyTargetLdInstr))
2575+
{
2576+
return callInstr;
2577+
}
2578+
AnalysisAssert(applyTargetLdInstr != nullptr);
2579+
// Fixed function/function object checks for target built-in
2580+
callInstr->ReplaceSrc1(applyTargetLdInstr->GetDst());
2581+
EmitFixedMethodOrFunctionObjectChecksForBuiltIns(callInstr, callInstr, builtInInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
2582+
2583+
// Fixed function/function object checks for .apply
2584+
callInstr->m_opcode = originalCallOpcode;
2585+
callInstr->ReplaceSrc1(originalCallSrc1);
2586+
EmitFixedMethodOrFunctionObjectChecksForBuiltIns(callInstr, callInstr, applyInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
25842587

25852588
IR::Instr* builtInEndInstr = InsertInlineeBuiltInStartEndTags(callInstr, 3); // 3 args (implicit this + explicit this + array = 3)
25862589
builtInEndInstr->m_opcode = Js::OpCode::InlineNonTrackingBuiltInEnd; // We will call EndTrackCall when we see CallDirect for reasons explained in GlobOpt::TrackCalls
@@ -2608,6 +2611,7 @@ IR::Instr * Inline::InlineApplyWithArray(IR::Instr * callInstr, const FunctionJI
26082611
argOut = IR::Instr::New(Js::OpCode::ArgOut_A_InlineSpecialized, linkOpnd, implicitThisArgOut->GetSrc1(), argOut->GetDst(), callInstr->m_func);
26092612
callInstr->InsertBefore(argOut);
26102613

2614+
Js::BuiltinFunction builtInId = Js::JavascriptLibrary::GetBuiltInForFuncInfo(builtInInfo->GetFunctionInfoAddr(), this->topFunc->GetThreadContextInfo());
26112615
IR::HelperCallOpnd * helperCallOpnd = nullptr;
26122616
switch (builtInId)
26132617
{
@@ -2641,7 +2645,7 @@ IR::Instr * Inline::InlineApplyWithoutArrayArgument(IR::Instr *callInstr, const
26412645
Assert(implicitThisArgOut);
26422646
Assert(explicitThisArgOut);
26432647

2644-
TryFixedMethodAndPrepareInsertionPoint(callInstr, applyInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
2648+
EmitFixedMethodOrFunctionObjectChecksForBuiltIns(callInstr, callInstr, applyInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
26452649

26462650
InsertInlineeBuiltInStartEndTags(callInstr, 2); // 2 args (implicit this + explicit this)
26472651

@@ -2714,6 +2718,22 @@ void Inline::GetArgInstrsForCallAndApply(IR::Instr* callInstr, IR::Instr** impli
27142718
linkOpnd->AsRegOpnd()->m_sym->m_isInlinedArgSlot = true;
27152719
}
27162720

2721+
bool Inline::TryGetApplyAndTargetLdInstrs(IR::Instr * callInstr, _Outptr_result_maybenull_ IR::Instr ** applyLdInstr, _Outptr_result_maybenull_ IR::Instr ** applyTargetLdInstr)
2722+
{
2723+
IR::Opnd* applyOpnd = callInstr->GetSrc1();
2724+
Assert(applyOpnd->IsRegOpnd());
2725+
StackSym* applySym = applyOpnd->AsRegOpnd()->m_sym->AsStackSym();
2726+
if (!applySym->IsSingleDef())
2727+
{
2728+
*applyLdInstr = nullptr;
2729+
*applyTargetLdInstr = nullptr;
2730+
return false;
2731+
}
2732+
*applyLdInstr = applySym->GetInstrDef();;
2733+
*applyTargetLdInstr = (*applyLdInstr)->m_prev;
2734+
return true;
2735+
}
2736+
27172737
/*
27182738
This method only inlines targets which are script functions, under the
27192739
condition that the second argument (if any) passed to apply is arguments object.
@@ -2735,16 +2755,14 @@ bool Inline::InlineApplyScriptTarget(IR::Instr *callInstr, const FunctionJITTime
27352755

27362756
// Begin inlining apply target
27372757

2738-
IR::Opnd* applyOpnd = callInstr->GetSrc1();
2739-
Assert(applyOpnd->IsRegOpnd());
2740-
StackSym* applySym = applyOpnd->AsRegOpnd()->m_sym->AsStackSym();
2741-
if (!applySym->IsSingleDef())
2758+
IR::Instr* applyLdInstr = nullptr;
2759+
IR::Instr* applyTargetLdInstr = nullptr;
2760+
if (!TryGetApplyAndTargetLdInstrs(callInstr, &applyLdInstr, &applyTargetLdInstr))
27422761
{
27432762
return false;
27442763
}
2745-
IR::Instr* applyLdInstr = applySym->GetInstrDef();
2746-
IR::Instr* applyTargetLdInstr = applyLdInstr->m_prev;
2747-
2764+
AnalysisAssert(applyTargetLdInstr != nullptr);
2765+
27482766
if(applyTargetLdInstr->m_opcode != Js::OpCode::LdFldForCallApplyTarget ||
27492767
((applyTargetLdInstr->AsProfiledInstr()->u.FldInfo().flags & Js::FldInfo_FromAccessor) != 0))
27502768
{
@@ -3008,7 +3026,7 @@ Inline::InlineCall(IR::Instr *callInstr, const FunctionJITTimeInfo *funcInfo, co
30083026

30093027
IR::SymOpnd* orgLinkOpnd = callInstr->GetSrc2()->AsSymOpnd();
30103028

3011-
TryFixedMethodAndPrepareInsertionPoint(callInstr, funcInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
3029+
EmitFixedMethodOrFunctionObjectChecksForBuiltIns(callInstr, callInstr, funcInfo, false /*isPolymorphic*/, true /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/);
30123030

30133031
InsertInlineeBuiltInStartEndTags(callInstr, actualCount);
30143032

@@ -4330,26 +4348,29 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
43304348
return primaryBailOutInstr;
43314349
}
43324350

4333-
void
4334-
Inline::TryFixedMethodAndPrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo * inlineeInfo, bool isPolymorphic, bool isBuiltIn, bool isCtor, bool isInlined)
4351+
IR::ByteCodeUsesInstr*
4352+
Inline::EmitFixedMethodOrFunctionObjectChecksForBuiltIns(IR::Instr *callInstr, IR::Instr * funcObjCheckInsertInstr, const FunctionJITTimeInfo * inlineeInfo, bool isPolymorphic, bool isBuiltIn, bool isCtor, bool isInlined)
43354353
{
43364354
StackSym* originalCallTargetStackSym = callInstr->GetSrc1()->GetStackSym();
43374355
bool originalCallTargetIsJITOpt = callInstr->GetSrc1()->GetIsJITOptimizedReg();
43384356

4357+
IR::ByteCodeUsesInstr * useCallTargetInstr = nullptr;
43394358
bool safeThis = false;
43404359
if (TryOptimizeCallInstrWithFixedMethod(callInstr, inlineeInfo, isPolymorphic, isBuiltIn, isCtor, isInlined, safeThis))
43414360
{
43424361
Assert(callInstr->m_opcode == Js::OpCode::CallIFixed);
4343-
4362+
Assert(callInstr->GetFixedFunction()->GetFuncInfoAddr() == inlineeInfo->GetFunctionInfoAddr());
43444363
// If we optimized the call instruction for a fixed function, we must extend the function object's lifetime until after the last bailout before the call.
4345-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr);
4364+
useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr);
43464365
useCallTargetInstr->SetRemovedOpndSymbol(originalCallTargetIsJITOpt, originalCallTargetStackSym->m_id);
43474366
callInstr->InsertBefore(useCallTargetInstr);
43484367
}
43494368
else
43504369
{
4351-
PrepareInsertionPoint(callInstr, inlineeInfo, callInstr);
4370+
IR::BailOutInstr * bailOutInstr = IR::BailOutInstr::New(Js::OpCode::BailOnNotBuiltIn, IR::BailOutOnInlineFunction, callInstr, callInstr->m_func);
4371+
InsertFunctionObjectCheck(callInstr, funcObjCheckInsertInstr, bailOutInstr, inlineeInfo);
43524372
}
4373+
return useCallTargetInstr;
43534374
}
43544375

43554376
uint Inline::CountActuals(IR::Instr *callInstr)

lib/Backend/Inline.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ class Inline
4747
IR::Instr * SimulateCallForGetterSetter(IR::Instr *accessorInstr, IR::Instr* insertInstr, IR::PropertySymOpnd* methodOpnd, bool isGetter);
4848

4949
IR::Instr * InlineApply(IR::Instr *callInstr, const FunctionJITTimeInfo * applyData, const FunctionJITTimeInfo * inlinerData, const StackSym *symThis, bool* pIsInlined, uint callSiteId, uint recursiveInlineDepth, uint argsCount);
50-
IR::Instr * InlineApplyWithArray(IR::Instr *callInstr, const FunctionJITTimeInfo * inlineeInfo, Js::BuiltinFunction builtInId);
50+
IR::Instr * InlineApplyBuiltInTargetWithArray(IR::Instr *callInstr, const FunctionJITTimeInfo * applyInfo, const FunctionJITTimeInfo * builtInInfo);
5151
IR::Instr * InlineApplyWithArgumentsObject(IR::Instr * callInstr, IR::Instr * argsObjectArgInstr, const FunctionJITTimeInfo * inlineeInfo);
5252
IR::Instr * InlineApplyWithoutArrayArgument(IR::Instr *callInstr, const FunctionJITTimeInfo * applyInfo, const FunctionJITTimeInfo * applyTargetInfo);
5353
bool InlineApplyScriptTarget(IR::Instr *callInstr, const FunctionJITTimeInfo* inlinerData, const FunctionJITTimeInfo** pInlineeData, const FunctionJITTimeInfo * applyFuncInfo,
5454
const StackSym *symThis, IR::Instr ** returnInstr, uint recursiveInlineDepth, bool isArrayOpndArgumentsObject, uint argsCount);
5555
void GetArgInstrsForCallAndApply(IR::Instr* callInstr, IR::Instr** implicitThisArgOut, IR::Instr** explicitThisArgOut, IR::Instr** argumentsOrArrayArgOut, uint &argOutCount);
56-
56+
bool TryGetApplyAndTargetLdInstrs(IR::Instr * callInstr, _Outptr_result_maybenull_ IR::Instr ** applyLdInstr, _Outptr_result_maybenull_ IR::Instr ** applyTargetLdInstr);
5757
IR::Instr * InlineCall(IR::Instr *callInstr, const FunctionJITTimeInfo * inlineeData, const FunctionJITTimeInfo * inlinerData, const StackSym *symThis, bool* pIsInlined, uint callSiteId, uint recursiveInlineDepth);
5858
bool InlineCallTarget(IR::Instr *callInstr, const FunctionJITTimeInfo* inlinerData, const FunctionJITTimeInfo** pInlineeData, const FunctionJITTimeInfo *callFuncInfo,
5959
const StackSym *symThis, IR::Instr ** returnInstr, uint recursiveInlineDepth);
@@ -83,7 +83,7 @@ class Inline
8383
void FixupExtraActualParams(IR::Instr * instr, IR::Instr *argOuts[], IR::Instr *argOutsExtra[], uint index, uint actualCount, Js::ProfileId callSiteId);
8484
void RemoveExtraFixupArgouts(IR::Instr* instr, uint argoutRemoveCount, Js::ProfileId callSiteId);
8585
IR::Instr* PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *funcInfo, IR::Instr *insertBeforeInstr, IR::BailOutKind bailOutKind = IR::BailOutOnInlineFunction);
86-
void TryFixedMethodAndPrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo * inlineeInfo, bool isPolymorphic, bool isBuiltIn, bool isCtor, bool isInlined);
86+
IR::ByteCodeUsesInstr* EmitFixedMethodOrFunctionObjectChecksForBuiltIns(IR::Instr *callInstr, IR::Instr * funcObjCheckInsertInstr, const FunctionJITTimeInfo * inlineeInfo, bool isPolymorphic, bool isBuiltIn, bool isCtor, bool isInlined);
8787
Js::ArgSlot MapActuals(IR::Instr *callInstr, __out_ecount(maxParamCount) IR::Instr *argOuts[], Js::ArgSlot formalCount, Func *inlinee, Js::ProfileId callSiteId, bool *stackArgsArgOutExpanded, IR::Instr *argOutsExtra[] = nullptr, Js::ArgSlot maxParamCount = Js::InlineeCallInfo::MaxInlineeArgoutCount);
8888
uint32 CountActuals(IR::Instr *callIntr);
8989
void MapFormals(Func *inlinee, __in_ecount(formalCount) IR::Instr *argOuts[], uint formalCount, uint actualCount, IR::RegOpnd *retOpnd, IR::Opnd * funcObjOpnd, const StackSym *symCallerThis, bool stackArgsArgOutExpanded, bool fixedFunctionSafeThis = false, IR::Instr *argOutsExtra[] = nullptr);

0 commit comments

Comments
 (0)