@@ -128,6 +128,13 @@ Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator
128128
129129 // init PID members
130130 InitPids();
131+
132+ #ifdef ENABLE_TEST_HOOKS
133+ if (scriptContext->GetConfig()->IsInternalCommandsEnabled())
134+ {
135+ InitInternalCommandPids();
136+ }
137+ #endif
131138}
132139
133140Parser::~Parser(void)
@@ -2626,6 +2633,74 @@ void Parser::CheckForDuplicateExportEntry(ModuleImportOrExportEntryList* exportE
26262633 }
26272634}
26282635
2636+ #ifdef ENABLE_TEST_HOOKS
2637+ template<bool buildAST>
2638+ ParseNodePtr Parser::ParseInternalCommand()
2639+ {
2640+ this->GetScanner()->Scan();
2641+ if (m_token.tk != tkID)
2642+ {
2643+ Error(ERRTokenAfter, GetTokenString(m_token.tk), _u("@@"));
2644+ }
2645+ charcount_t ichMin = this->GetScanner()->IchMinTok();
2646+
2647+ // find the command type
2648+ InternalCommandType type;
2649+ IdentPtr id = m_token.GetIdentifier(GetHashTbl());
2650+
2651+ if (id == internalCommandPids.Conv_Num)
2652+ {
2653+ type = InternalCommandType::Conv_Num;
2654+ }
2655+ else if (id == internalCommandPids.Conv_Obj)
2656+ {
2657+ type = InternalCommandType::Conv_Obj;
2658+ }
2659+ else
2660+ {
2661+ Error(ERRTokenAfter, m_token.GetIdentifier(GetHashTbl())->Psz(), _u("@@"));
2662+ }
2663+
2664+ // parse the parameters - currently only accept identifiers
2665+ this->GetScanner()->Scan();
2666+ ChkCurTok(tkLParen, ERRnoLparen);
2667+ ParseNodePtr params = nullptr;
2668+ ParseNodePtr * lastParam = nullptr;
2669+ ParseNodePtr currentParam = nullptr;
2670+
2671+ for (;;)
2672+ {
2673+ currentParam = ParseExpr<buildAST>(0);
2674+ if (buildAST)
2675+ {
2676+ AddToNodeListEscapedUse(¶ms, &lastParam, currentParam);
2677+ }
2678+
2679+ if (m_token.tk == tkComma)
2680+ {
2681+ this->GetScanner()->Scan();
2682+ }
2683+ else if (m_token.tk == tkRParen)
2684+ {
2685+ this->GetScanner()->Scan();
2686+ break;
2687+ }
2688+ else
2689+ {
2690+ Error(ERRTokenAfter, GetTokenString(m_token.tk), GetTokenString(this->GetScanner()->GetPrevious()));
2691+ }
2692+ }
2693+
2694+ ParseNodePtr command = nullptr;
2695+ if (buildAST)
2696+ {
2697+ command = Anew(&m_nodeAllocator, ParseNodeInternalCommand, ichMin, this->GetScanner()->IchLimTok(), type, params);
2698+ }
2699+
2700+ return command;
2701+ }
2702+ #endif
2703+
26292704template<bool buildAST>
26302705void Parser::ParseImportClause(ModuleImportOrExportEntryList* importEntryList, bool parsingAfterComma)
26312706{
@@ -3744,6 +3819,16 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
37443819 }
37453820 break;
37463821
3822+ #ifdef ENABLE_TEST_HOOKS
3823+ case tkIntCommand:
3824+ if (!m_scriptContext->GetConfig()->IsInternalCommandsEnabled())
3825+ {
3826+ Error(ERRTokenAfter, _u("@@"), GetTokenString(GetScanner()->GetPrevious()));
3827+ }
3828+ pnode = ParseInternalCommand<buildAST>();
3829+ break;
3830+ #endif
3831+
37473832#if ENABLE_BACKGROUND_PARSING
37483833 case tkCASE:
37493834 {
@@ -11775,6 +11860,14 @@ void Parser::InitPids()
1177511860 wellKnownPropertyPids._importMeta = this->GetHashTbl()->PidHashNameLen(_u("*import.meta*"), sizeof("*import.meta*") - 1);
1177611861}
1177711862
11863+ #ifdef ENABLE_TEST_HOOKS
11864+ void Parser::InitInternalCommandPids()
11865+ {
11866+ internalCommandPids.Conv_Num = this->GetHashTbl()->PidHashNameLen(_u("Conv_Num"), sizeof("Conv_Num") - 1);
11867+ internalCommandPids.Conv_Obj = this->GetHashTbl()->PidHashNameLen(_u("Conv_Obj"), sizeof("Conv_Obj") - 1);
11868+ }
11869+ #endif
11870+
1177811871void Parser::RestoreScopeInfo(Js::ScopeInfo * scopeInfo)
1177911872{
1178011873 if (!scopeInfo)
0 commit comments