@@ -3387,6 +3387,15 @@ bool Instr::CanHaveArgOutChain() const
33873387        this ->m_opcode  == Js::OpCode::NewScObjArraySpread;
33883388}
33893389
3390+ bool  Instr::IsNewScObjCallVariantInstr ()
3391+ {
3392+     return 
3393+         this ->m_opcode  == Js::OpCode::NewScObject ||
3394+         this ->m_opcode  == Js::OpCode::NewScObjectSpread ||
3395+         this ->m_opcode  == Js::OpCode::NewScObjArray ||
3396+         this ->m_opcode  == Js::OpCode::NewScObjArraySpread;
3397+ }
3398+ 
33903399bool  Instr::HasEmptyArgOutChain (IR::Instr** startCallInstrOut)
33913400{
33923401    Assert (CanHaveArgOutChain ());
@@ -3408,6 +3417,22 @@ bool Instr::HasEmptyArgOutChain(IR::Instr** startCallInstrOut)
34083417    return  false ;
34093418}
34103419
3420+ uint Instr::ArgOutChainLength ()
3421+ {
3422+     Assert (CanHaveArgOutChain ());
3423+ 
3424+     uint length = 0 ;
3425+     Instr* currArgOutInstr = GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3426+ 
3427+     while  (currArgOutInstr->m_opcode  != Js::OpCode::StartCall)
3428+     {
3429+         length++;
3430+         currArgOutInstr = currArgOutInstr->GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3431+     }
3432+ 
3433+     return  length;
3434+ }
3435+ 
34113436bool  Instr::HasFixedFunctionAddressTarget () const 
34123437{
34133438    Assert (
@@ -3417,14 +3442,96 @@ bool Instr::HasFixedFunctionAddressTarget() const
34173442        this ->m_opcode  == Js::OpCode::NewScObjectSpread ||
34183443        this ->m_opcode  == Js::OpCode::NewScObjArray ||
34193444        this ->m_opcode  == Js::OpCode::NewScObjArraySpread ||
3420-         this ->m_opcode  == Js::OpCode::NewScObjectNoCtor);
3445+         this ->m_opcode  == Js::OpCode::NewScObjectNoCtor ||
3446+         this ->m_opcode  == Js::OpCode::GenCtorObj);
34213447    return 
34223448        this ->GetSrc1 () != nullptr  &&
34233449        this ->GetSrc1 ()->IsAddrOpnd () &&
34243450        this ->GetSrc1 ()->AsAddrOpnd ()->GetAddrOpndKind () == IR::AddrOpndKind::AddrOpndKindDynamicVar &&
34253451        this ->GetSrc1 ()->AsAddrOpnd ()->m_isFunction ;
34263452}
34273453
3454+ Instr* Instr::GetGenCtorInstr ()
3455+ {
3456+     Assert (IsNewScObjCallVariantInstr ());
3457+     Instr* currArgOutInstr = this ;
3458+     Instr* currArgOutInstrValDef = this ;
3459+     do 
3460+     {
3461+         //  TODO: should use helper method here? GetNextInstr?
3462+         Assert (currArgOutInstr->GetSrc2 ());
3463+         currArgOutInstr = currArgOutInstr->GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3464+         Assert (currArgOutInstr);
3465+         if  (currArgOutInstr->m_opcode  == Js::OpCode::GenCtorObj)
3466+         {
3467+             return  currArgOutInstr;
3468+         }
3469+         if  (currArgOutInstr->m_opcode  == Js::OpCode::LdSpreadIndices)
3470+         {
3471+             //  This instr is a redirection, move on to next instr.
3472+             continue ;
3473+         }
3474+         Assert (currArgOutInstr->m_opcode  == Js::OpCode::ArgOut_A);
3475+         if  (currArgOutInstr->GetSrc1 ()->IsAddrOpnd ())
3476+         {
3477+             //  This instr's src1 is not a symbol, thus it does not have a def instr
3478+             //  and thus it cannot be from a GenCtorObj instr.
3479+             continue ;
3480+         }
3481+ 
3482+         //  Looking for the opcode GenCtorObj in currArgOutInstrValDef.
3483+         currArgOutInstrValDef = currArgOutInstr->GetSrc1 ()->GetStackSym ()->GetInstrDef ();
3484+         Assert (currArgOutInstrValDef);
3485+         if  (currArgOutInstrValDef->m_opcode  == Js::OpCode::BytecodeArgOutCapture)
3486+         {
3487+             if  (currArgOutInstrValDef->GetSrc1 ()->GetStackSym ())
3488+             {
3489+                 //  Indirection through BytecodeArgOutCapture.
3490+                 currArgOutInstrValDef = currArgOutInstrValDef->GetSrc1 ()->GetStackSym ()->GetInstrDef ();
3491+             }
3492+             Assert (currArgOutInstrValDef);
3493+         }
3494+     } while  (currArgOutInstrValDef->m_opcode  != Js::OpCode::GenCtorObj);
3495+     return  currArgOutInstrValDef;
3496+ }
3497+ 
3498+ Opnd* Instr::GetArgOutVal (uint argIndex)
3499+ {
3500+     Assert (IsNewScObjCallVariantInstr ());
3501+     Instr* currArgOutInstr = this ;
3502+     do 
3503+     {
3504+         Assert (currArgOutInstr->GetSrc2 ());
3505+         currArgOutInstr = currArgOutInstr->GetSrc2 ()->GetStackSym ()->GetInstrDef ();
3506+         Assert (currArgOutInstr);
3507+         if  (currArgOutInstr->m_opcode  == Js::OpCode::StartCall)
3508+         {
3509+             //  argIndex is larger than this argOutChain's length.
3510+             return  nullptr ;
3511+         }
3512+ 
3513+         if  (currArgOutInstr->m_opcode  == Js::OpCode::LdSpreadIndices)
3514+         {
3515+             //  This instr is a redirection, move on to next instr.
3516+             continue ;
3517+         }
3518+         Assert (currArgOutInstr->m_opcode  == Js::OpCode::ArgOut_A);
3519+ 
3520+         if  (argIndex > 0 )
3521+         {
3522+             argIndex--;
3523+         }
3524+     } while  (argIndex > 0 );
3525+ 
3526+     Opnd* argOutVal = currArgOutInstr->GetSrc1 ();
3527+     if  (argOutVal->GetStackSym ()->m_instrDef ->m_opcode  == Js::OpCode::BytecodeArgOutCapture)
3528+     {
3529+         argOutVal = argOutVal->GetStackSym ()->m_instrDef ->GetSrc1 ();
3530+     }
3531+ 
3532+     return  argOutVal;
3533+ }
3534+ 
34283535bool  Instr::TransfersSrcValue ()
34293536{
34303537    //  Return whether the instruction transfers a value to the destination.
@@ -3635,7 +3742,7 @@ uint Instr::GetArgOutCount(bool getInterpreterArgOutCount)
36353742           opcode == Js::OpCode::EndCallForPolymorphicInlinee || opcode == Js::OpCode::LoweredStartCall);
36363743
36373744    Assert (!getInterpreterArgOutCount || opcode == Js::OpCode::StartCall);
3638-     uint argOutCount = !this ->GetSrc2 () || !getInterpreterArgOutCount || m_func->GetJITFunctionBody ()->IsAsmJsMode ()
3745+       uint argOutCount = !this ->GetSrc2 () || !getInterpreterArgOutCount || m_func->GetJITFunctionBody ()->IsAsmJsMode ()
36393746        ? this ->GetSrc1 ()->AsIntConstOpnd ()->AsUint32 ()
36403747        : this ->GetSrc2 ()->AsIntConstOpnd ()->AsUint32 ();
36413748
0 commit comments