@@ -3380,6 +3380,15 @@ bool Instr::CanHaveArgOutChain() const
3380
3380
this ->m_opcode == Js::OpCode::NewScObjArraySpread;
3381
3381
}
3382
3382
3383
+ bool Instr::IsNewScObjCallVarientInstr ()
3384
+ {
3385
+ return
3386
+ this ->m_opcode == Js::OpCode::NewScObject ||
3387
+ this ->m_opcode == Js::OpCode::NewScObjectSpread ||
3388
+ this ->m_opcode == Js::OpCode::NewScObjArray ||
3389
+ this ->m_opcode == Js::OpCode::NewScObjArraySpread;
3390
+ }
3391
+
3383
3392
bool Instr::HasEmptyArgOutChain (IR::Instr** startCallInstrOut)
3384
3393
{
3385
3394
Assert (CanHaveArgOutChain ());
@@ -3401,6 +3410,22 @@ bool Instr::HasEmptyArgOutChain(IR::Instr** startCallInstrOut)
3401
3410
return false ;
3402
3411
}
3403
3412
3413
+ uint Instr::ArgOutChainLength ()
3414
+ {
3415
+ Assert (CanHaveArgOutChain ());
3416
+
3417
+ uint length = 0 ;
3418
+ Instr* currArgOutInstr = GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3419
+
3420
+ while (currArgOutInstr->m_opcode != Js::OpCode::StartCall)
3421
+ {
3422
+ length++;
3423
+ currArgOutInstr = currArgOutInstr->GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3424
+ }
3425
+
3426
+ return length;
3427
+ }
3428
+
3404
3429
bool Instr::HasFixedFunctionAddressTarget () const
3405
3430
{
3406
3431
Assert (
@@ -3418,6 +3443,40 @@ bool Instr::HasFixedFunctionAddressTarget() const
3418
3443
this ->GetSrc1 ()->AsAddrOpnd ()->m_isFunction ;
3419
3444
}
3420
3445
3446
+ Instr* Instr::GetGenCtorInstr ()
3447
+ {
3448
+ Assert (IsNewScObjCallVarientInstr ());
3449
+ Instr* currArgOutInstr = this ;
3450
+ Instr* currArgOutInstrValDef = this ;
3451
+ do
3452
+ {
3453
+ // TODO: should use helper method here? GetNextInstr?
3454
+ Assert (currArgOutInstr->GetSrc2 ());
3455
+ currArgOutInstr = currArgOutInstr->GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3456
+ Assert (currArgOutInstr);
3457
+ if (currArgOutInstr->m_opcode == Js::OpCode::LdSpreadIndices)
3458
+ {
3459
+ // This instr is a redirection, move on to next instr.
3460
+ continue ;
3461
+ }
3462
+ Assert (currArgOutInstr->m_opcode == Js::OpCode::ArgOut_A);
3463
+ if (currArgOutInstr->GetSrc1 ()->IsAddrOpnd ())
3464
+ {
3465
+ // This instr's src1 is not a symbol, thus it does not have a def instr
3466
+ // and thus it cannot be from a GenCtorObj instr.
3467
+ continue ;
3468
+ }
3469
+ currArgOutInstrValDef = currArgOutInstr->GetSrc1 ()->GetStackSym ()->GetInstrDef ();
3470
+ Assert (currArgOutInstrValDef);
3471
+ if (currArgOutInstrValDef->m_opcode == Js::OpCode::BytecodeArgOutCapture)
3472
+ {
3473
+ currArgOutInstrValDef = currArgOutInstrValDef->GetSrc1 ()->GetStackSym ()->GetInstrDef ();
3474
+ Assert (currArgOutInstrValDef);
3475
+ }
3476
+ } while (currArgOutInstrValDef->m_opcode != Js::OpCode::GenCtorObj);
3477
+ return currArgOutInstrValDef;
3478
+ }
3479
+
3421
3480
bool Instr::TransfersSrcValue ()
3422
3481
{
3423
3482
// Return whether the instruction transfers a value to the destination.
@@ -3628,7 +3687,7 @@ uint Instr::GetArgOutCount(bool getInterpreterArgOutCount)
3628
3687
opcode == Js::OpCode::EndCallForPolymorphicInlinee || opcode == Js::OpCode::LoweredStartCall);
3629
3688
3630
3689
Assert (!getInterpreterArgOutCount || opcode == Js::OpCode::StartCall);
3631
- uint argOutCount = !this ->GetSrc2 () || !getInterpreterArgOutCount || m_func->GetJITFunctionBody ()->IsAsmJsMode ()
3690
+ uint argOutCount = !this ->GetSrc2 () || !getInterpreterArgOutCount || m_func->GetJITFunctionBody ()->IsAsmJsMode ()
3632
3691
? this ->GetSrc1 ()->AsIntConstOpnd ()->AsUint32 ()
3633
3692
: this ->GetSrc2 ()->AsIntConstOpnd ()->AsUint32 ();
3634
3693
0 commit comments