//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "ParserPch.h"
#include "FormalsUtil.h"
#include "../Runtime/Language/SourceDynamicProfileManager.h"

#include "ByteCode/ByteCodeSerializer.h"


#if DBG_DUMP
void PrintPnodeWIndent(ParseNode *pnode, int indentAmt);
#endif

const char* const nopNames[knopLim] = {
#define PTNODE(nop,sn,pc,nk,grfnop,json) sn,
#include "ptlist.h"
};
void printNop(int nop) {
    Output::Print(_u("%S\n"), nopNames[nop]);
}

const uint ParseNode::mpnopgrfnop[knopLim] =
{
#define PTNODE(nop,sn,pc,nk,grfnop,json) grfnop,
#include "ptlist.h"
};

bool Parser::IsES6DestructuringEnabled() const
{
    return m_scriptContext->GetConfig()->IsES6DestructuringEnabled();
}

struct BlockInfoStack
{
    StmtNest pstmt;
    ParseNodeBlock *pnodeBlock;
    ParseNodePtr *m_ppnodeLex;              // lexical variable list tail
    BlockInfoStack *pBlockInfoOuter;        // containing block's BlockInfoStack
    BlockInfoStack *pBlockInfoFunction;     // nearest function's BlockInfoStack (if pnodeBlock is a function, this points to itself)
};

#if DEBUG
Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground, size_t size)
#else
Parser::Parser(Js::ScriptContext* scriptContext, BOOL strictMode, PageAllocator *alloc, bool isBackground)
#endif
    : m_nodeAllocator(_u("Parser"), alloc ? alloc : scriptContext->GetThreadContext()->GetPageAllocator(), Parser::OutOfMemory),
    m_cactIdentToNodeLookup(0),
    m_grfscr(fscrNil),
    m_length(0),
    m_originalLength(0),
    m_nextFunctionId(nullptr),
    m_sourceContextInfo(nullptr),
#if ENABLE_BACKGROUND_PARSING
    m_isInBackground(isBackground),
    m_hasParallelJob(false),
    m_doingFastScan(false),
#endif
    m_nextBlockId(0),
    m_tempGuestArenaReleased(false),
    m_tempGuestArena(scriptContext->GetTemporaryGuestAllocator(_u("ParserRegex")), scriptContext->GetRecycler()),
    // use the GuestArena directly for keeping the RegexPattern* alive during byte code generation
    m_registeredRegexPatterns(m_tempGuestArena->GetAllocator()),

    m_scriptContext(scriptContext),
    m_token(), // should initialize to 0/nullptrs
    m_scan(this, &m_token, scriptContext),

    m_currentNodeNonLambdaFunc(nullptr),
    m_currentNodeNonLambdaDeferredFunc(nullptr),
    m_currentNodeFunc(nullptr),
    m_currentNodeDeferredFunc(nullptr),
    m_currentNodeProg(nullptr),
    m_currDeferredStub(nullptr),
    m_currDeferredStubCount(0),
    m_pCurrentAstSize(nullptr),
    m_ppnodeScope(nullptr),
    m_ppnodeExprScope(nullptr),
    m_ppnodeVar(nullptr),
    m_inDeferredNestedFunc(false),
    m_reparsingLambdaParams(false),
    m_disallowImportExportStmt(false),
    m_isInParsingArgList(false),
    m_hasDestructuringPattern(false),
    m_hasDeferredShorthandInitError(false),
    m_deferCommaError(false),
    m_pnestedCount(nullptr),

    wellKnownPropertyPids(), // should initialize to nullptrs
    m_sourceLim(0),
    m_functionBody(nullptr),
    m_parseType(ParseType_Upfront),

    m_arrayDepth(0),
    m_funcInArrayDepth(0),
    m_funcInArray(0),
    m_scopeCountNoAst(0),

    m_funcParenExprDepth(0),
    m_deferEllipsisError(false),
    m_deferEllipsisErrorLoc(), // calls default initializer
    m_deferCommaErrorLoc(),
    m_tryCatchOrFinallyDepth(0),

    m_pstmtCur(nullptr),
    m_currentBlockInfo(nullptr),
    m_currentScope(nullptr),

    currBackgroundParseItem(nullptr),
    backgroundParseItems(nullptr),
    fastScannedRegExpNodes(nullptr),

    m_currentDynamicBlock(nullptr),

    m_UsesArgumentsAtGlobal(false),

    m_fUseStrictMode(strictMode),
    m_InAsmMode(false),
    m_deferAsmJs(true),
    m_fExpectExternalSource(FALSE),
    m_deferringAST(FALSE),
    m_stoppedDeferredParse(FALSE)
{
    AssertMsg(size == sizeof(Parser), "verify conditionals affecting the size of Parser agree");
    Assert(scriptContext != nullptr);

    // init PID members
    InitPids();
}

Parser::~Parser(void)
{
    this->ReleaseTemporaryGuestArena();

#if ENABLE_BACKGROUND_PARSING
    if (this->m_hasParallelJob)
    {
        // Let the background threads know that they can decommit their arena pages.
        BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
        Assert(bgp);
        if (bgp->Processor()->ProcessesInBackground())
        {
            JsUtil::BackgroundJobProcessor *processor = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor());

            bool result = processor->IterateBackgroundThreads([&](JsUtil::ParallelThreadData *threadData)->bool {
                threadData->canDecommit = true;
                return false;
            });
            Assert(result);
        }
    }
#endif
}

void Parser::OutOfMemory()
{
    throw ParseExceptionObject(ERRnoMemory);
}

LPCWSTR Parser::GetTokenString(tokens token)
{
    switch (token)
    {
    case tkNone   : return _u("");
    case tkEOF    : return _u("end of script");
    case tkIntCon : return _u("integer literal");
    case tkFltCon : return _u("float literal");
    case tkStrCon : return _u("string literal");
    case tkRegExp : return _u("regular expression literal");

// keywords
    case tkABSTRACT     : return _u("abstract");
    case tkASSERT       : return _u("assert");
    case tkAWAIT        : return _u("await");
    case tkBOOLEAN      : return _u("boolean");
    case tkBREAK        : return _u("break");
    case tkBYTE         : return _u("byte");
    case tkCASE         : return _u("case");
    case tkCATCH        : return _u("catch");
    case tkCHAR         : return _u("char");
    case tkCONTINUE     : return _u("continue");
    case tkDEBUGGER     : return _u("debugger");
    case tkDECIMAL      : return _u("decimal");
    case tkDEFAULT      : return _u("default");
    case tkDELETE       : return _u("delete");
    case tkDO           : return _u("do");
    case tkDOUBLE       : return _u("double");
    case tkELSE         : return _u("else");
    case tkENSURE       : return _u("ensure");
    case tkEVENT        : return _u("event");
    case tkFALSE        : return _u("false");
    case tkFINAL        : return _u("final");
    case tkFINALLY      : return _u("finally");
    case tkFLOAT        : return _u("float");
    case tkFOR          : return _u("for");
    case tkFUNCTION     : return _u("function");
    case tkGET          : return _u("get");
    case tkGOTO         : return _u("goto");
    case tkIF           : return _u("if");
    case tkIN           : return _u("in");
    case tkINSTANCEOF   : return _u("instanceof");
    case tkINT          : return _u("int");
    case tkINTERNAL     : return _u("internal");
    case tkINVARIANT    : return _u("invariant");
    case tkLONG         : return _u("long");
    case tkNAMESPACE    : return _u("namespace");
    case tkNATIVE       : return _u("native");
    case tkNEW          : return _u("new");
    case tkNULL         : return _u("null");
    case tkREQUIRE      : return _u("require");
    case tkRETURN       : return _u("return");
    case tkSBYTE        : return _u("sbyte");
    case tkSET          : return _u("set");
    case tkSHORT        : return _u("short");
    case tkSWITCH       : return _u("switch");
    case tkSYNCHRONIZED : return _u("synchronized");
    case tkTHIS         : return _u("this");
    case tkTHROW        : return _u("throw");
    case tkTHROWS       : return _u("throws");
    case tkTRANSIENT    : return _u("transient");
    case tkTRUE         : return _u("true");
    case tkTRY          : return _u("try");
    case tkTYPEOF       : return _u("typeof");
    case tkUINT         : return _u("uint");
    case tkULONG        : return _u("ulong");
    case tkUSE          : return _u("use");
    case tkUSHORT       : return _u("ushort");
    case tkVAR          : return _u("var");
    case tkVOID         : return _u("void");
    case tkVOLATILE     : return _u("volatile");
    case tkWHILE        : return _u("while");
    case tkWITH         : return _u("with");

// Future reserved words that become keywords in ES6
    case tkCLASS   : return _u("class");
    case tkCONST   : return _u("const");
    case tkEXPORT  : return _u("export");
    case tkEXTENDS : return _u("extends");
    case tkIMPORT  : return _u("import");
    case tkLET     : return _u("let");
    case tkSUPER   : return _u("super");
    case tkYIELD   : return _u("yield");

// Future reserved words in strict and non-strict modes
    case tkENUM : return _u("enum");

// Additional future reserved words in strict mode
    case tkIMPLEMENTS : return _u("implements");
    case tkINTERFACE  : return _u("interface");
    case tkPACKAGE    : return _u("package");
    case tkPRIVATE    : return _u("private");
    case tkPROTECTED  : return _u("protected");
    case tkPUBLIC     : return _u("public");
    case tkSTATIC     : return _u("static");

    case tkID: return _u("identifier");

// Non-operator non-identifier tokens
    case tkSColon: return _u(";");
    case tkRParen: return _u(")");
    case tkRBrack: return _u("]");
    case tkLCurly: return _u("{");
    case tkRCurly: return _u("}");

// Operator non-identifier tokens
    case tkComma: return _u(",");
    case tkDArrow: return _u("=>");
    case tkAsg: return _u("=");
    case tkAsgAdd: return _u("+=");
    case tkAsgSub: return _u("-=");
    case tkAsgMul: return _u("*=");
    case tkAsgDiv: return _u("/=");
    case tkAsgExpo: return _u("**=");
    case tkAsgMod: return _u("%=");
    case tkAsgAnd: return _u("&=");
    case tkAsgXor: return _u("^=");
    case tkAsgOr: return _u("|=");
    case tkAsgLsh: return _u("<<=");
    case tkAsgRsh: return _u(">>=");
    case tkAsgRs2: return _u(">>>=");
    case tkQMark: return _u("?");
    case tkColon: return _u(":");
    case tkLogOr: return _u("||");
    case tkLogAnd: return _u("&&");
    case tkOr: return _u("|");
    case tkXor: return _u("^");
    case tkAnd: return _u("&");
    case tkEQ: return _u("==");
    case tkNE: return _u("!=");
    case tkEqv: return _u("===");
    case tkNEqv: return _u("!==");
    case tkLT: return _u("<");
    case tkLE: return _u("<=");
    case tkGT: return _u(">");
    case tkGE: return _u(">=");
    case tkLsh: return _u("<<");
    case tkRsh: return _u(">>");
    case tkRs2: return _u(">>>");
    case tkAdd: return _u("+");
    case tkSub: return _u("-");
    case tkExpo: return _u("**");
    case tkStar: return _u("*");
    case tkDiv: return _u("/");
    case tkPct: return _u("%");
    case tkTilde: return _u("~");
    case tkBang: return _u("!");
    case tkInc: return _u("++");
    case tkDec: return _u("--");
    case tkEllipsis: return _u("...");
    case tkLParen: return _u("(");
    case tkLBrack: return _u("[");
    case tkDot: return _u(".");

    default:
        return _u("unknown token");
    }
}

void Parser::Error(HRESULT hr, LPCWSTR stringOne, LPCWSTR stringTwo)
{
    throw ParseExceptionObject(hr, stringOne, stringTwo);
}

void Parser::Error(HRESULT hr, ParseNodePtr pnode)
{
    if (pnode && pnode->ichLim)
    {
        Error(hr, pnode->ichMin, pnode->ichLim);
    }
    else
    {
        Error(hr);
    }
}

void Parser::Error(HRESULT hr, charcount_t ichMin, charcount_t ichLim, LPCWSTR stringOne, LPCWSTR stringTwo)
{
    this->GetScanner()->SetErrorPosition(ichMin, ichLim);
    Error(hr, stringOne, stringTwo);
}

void Parser::IdentifierExpectedError(const Token& token)
{
    Assert(token.tk != tkID);

    HRESULT hr;
    if (token.IsReservedWord())
    {
        if (token.IsKeyword())
        {
            hr = ERRKeywordNotId;
        }
        else
        {
            Assert(token.IsFutureReservedWord(true));
            if (token.IsFutureReservedWord(false))
            {
                // Future reserved word in strict and non-strict modes
                hr = ERRFutureReservedWordNotId;
            }
            else
            {
                // Future reserved word only in strict mode. The token would have been converted to tkID by the scanner if not
                // in strict mode.
                Assert(IsStrictMode());
                hr = ERRFutureReservedWordInStrictModeNotId;
            }
        }
    }
    else
    {
        hr = ERRnoIdent;
    }

    Error(hr);
}

HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isGenerator, bool isAsync, CompileScriptException *pse, void (Parser::*validateFunction)())
{
    Assert(pszSrc);

    PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);

    HRESULT hr;
    SmartFPUControl smartFpuControl;
    bool handled = false;

    BOOL fDeferSave = m_deferringAST;
    try
    {
        hr = NOERROR;

        m_length = encodedCharCount;
        m_originalLength = encodedCharCount;

        // make sure deferred parsing is turned off
        ULONG grfscr = fscrNil;

        // Give the scanner the source and get the first token
        this->GetScanner()->SetText(pszSrc, 0, encodedCharCount, 0, false, grfscr);
        this->GetScanner()->SetYieldIsKeywordRegion(isGenerator);
        this->GetScanner()->SetAwaitIsKeywordRegion(isAsync);
        this->GetScanner()->Scan();

        uint nestedCount = 0;
        m_pnestedCount = &nestedCount;

        ParseNodePtr pnodeScope = nullptr;
        m_ppnodeScope = &pnodeScope;
        m_ppnodeExprScope = nullptr;

        uint nextFunctionId = 0;
        m_nextFunctionId = &nextFunctionId;

        m_inDeferredNestedFunc = false;
        m_deferringAST = true;

        m_nextBlockId = 0;

        ParseNodeFnc *pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
        pnodeFnc->SetIsGenerator(isGenerator);
        pnodeFnc->SetIsAsync(isAsync);

        m_ppnodeVar = &pnodeFnc->pnodeVars;
        m_currentNodeFunc = pnodeFnc;
        m_currentNodeDeferredFunc = NULL;
        m_sourceContextInfo = nullptr;
        AssertMsg(m_pstmtCur == NULL, "Statement stack should be empty when we start parse function body");

        ParseNodeBlock * block = StartParseBlock<false>(PnodeBlockType::Function, ScopeType_FunctionBody);
        (this->*validateFunction)();
        FinishParseBlock(block);

        pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
        pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
        pnodeFnc->pnodeVars = nullptr;

        // there should be nothing after successful parsing for a given construct
        if (m_token.tk != tkEOF)
            Error(ERRsyntax);

        m_deferringAST = fDeferSave;
    }
    catch (ParseExceptionObject& e)
    {
        m_deferringAST = fDeferSave;
        hr = e.GetError();
        hr = pse->ProcessError(this->GetScanner(), hr, /* pnodeBase */ NULL, e.GetStringOne(), e.GetStringTwo());
        handled = true;
    }

    if (handled == false && nullptr != pse && FAILED(hr))
    {
        hr = pse->ProcessError(this->GetScanner(), hr, /* pnodeBase */ NULL);
    }
    return hr;
}

HRESULT Parser::ParseSourceInternal(
    __out ParseNodeProg ** parseTree, LPCUTF8 pszSrc, size_t offsetInBytes, size_t encodedCharCount, charcount_t offsetInChars,
    bool isUtf8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo)
{
    Assert(parseTree);
    Assert(pszSrc);

    if (this->IsBackgroundParser())
    {
        PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);
    }
    else
    {
        PROBE_STACK(m_scriptContext, Js::Constants::MinStackDefault);
    }

#ifdef PROFILE_EXEC
    m_scriptContext->ProfileBegin(Js::ParsePhase);
#endif
    JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_START(m_scriptContext, 0));

    *parseTree = NULL;
    m_sourceLim = 0;

    m_grfscr = grfscr;
    m_sourceContextInfo = sourceContextInfo;

    ParseNodeProg * pnodeBase = NULL;
    HRESULT hr;
    SmartFPUControl smartFpuControl;
    bool handled = false;

    try
    {
        if ((grfscr & fscrIsModuleCode) != 0)
        {
            // Module source flag should not be enabled unless module is enabled
            Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());

            // Module code is always strict mode code.
            this->m_fUseStrictMode = TRUE;
        }

        if ((grfscr & fscrUseStrictMode) != 0)
        {
            this->m_fUseStrictMode = TRUE;
        }

        // parse the source
        pnodeBase = Parse(pszSrc, offsetInBytes, encodedCharCount, offsetInChars, isUtf8, grfscr, lineNumber, nextFunctionId, pse);

        Assert(pnodeBase);

        // Record the actual number of words parsed.
        m_sourceLim = pnodeBase->ichLim - offsetInChars;

        // TODO: The assert can be false positive in some scenarios and chuckj to fix it later
        // Assert(utf8::ByteIndexIntoCharacterIndex(pszSrc + offsetInBytes, encodedCharCount, isUtf8 ? utf8::doDefault : utf8::doAllowThreeByteSurrogates) == m_sourceLim);

#if DBG_DUMP
        if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::ParsePhase))
        {
            PrintPnodeWIndent(pnodeBase, 4);
            fflush(stdout);
        }
#endif

        *parseTree = pnodeBase;

        hr = NOERROR;
    }
    catch (ParseExceptionObject& e)
    {
        hr = e.GetError();
        hr = pse->ProcessError(this->GetScanner(), hr, pnodeBase, e.GetStringOne(), e.GetStringTwo());
        handled = true;
    }
    catch (Js::AsmJsParseException&)
    {
        hr = JSERR_AsmJsCompileError;
    }

    if (handled == false && FAILED(hr))
    {
        hr = pse->ProcessError(this->GetScanner(), hr, pnodeBase);
    }

#if ENABLE_BACKGROUND_PARSING
    if (this->m_hasParallelJob)
    {
        ///// Wait here for remaining jobs to finish. Then look for errors, do final const bindings.
        // pleath TODO: If there are remaining jobs, let the main thread help finish them.
        BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
        Assert(bgp);

        CompileScriptException se;
        this->WaitForBackgroundJobs(bgp, &se);

        BackgroundParseItem *failedItem = bgp->GetFailedBackgroundParseItem();
        if (failedItem)
        {
            CompileScriptException *bgPse = failedItem->GetPSE();
            Assert(bgPse);
            *pse = *bgPse;
            hr = failedItem->GetHR();
            bgp->SetFailedBackgroundParseItem(nullptr);
        }

        if (this->fastScannedRegExpNodes != nullptr)
        {
            this->FinishBackgroundRegExpNodes();
        }

        for (BackgroundParseItem *item = this->backgroundParseItems; item; item = item->GetNext())
        {
            Parser *parser = item->GetParser();
            parser->FinishBackgroundPidRefs(item, this != parser);
        }
    }
#endif

    // done with the scanner
    this->GetScanner()->Clear();

#ifdef PROFILE_EXEC
    m_scriptContext->ProfileEnd(Js::ParsePhase);
#endif
    JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_STOP(m_scriptContext, 0));

    return hr;
}

#if ENABLE_BACKGROUND_PARSING
void Parser::WaitForBackgroundJobs(BackgroundParser *bgp, CompileScriptException *pse)
{
    // The scan of the script is done, but there may be unfinished background jobs in the queue.
    // Enlist the main thread to help with those.
    BackgroundParseItem *item;
    if (!*bgp->GetPendingBackgroundItemsPtr())
    {
        // We're done.
        return;
    }

    // Save parser state, since we'll need to restore it in order to bind references correctly later.
    this->m_isInBackground = true;
    this->SetCurrBackgroundParseItem(nullptr);
    uint blockIdSave = this->m_nextBlockId;
    uint functionIdSave = *this->m_nextFunctionId;
    StmtNest *pstmtSave = this->m_pstmtCur;

    if (!bgp->Processor()->ProcessesInBackground())
    {
        // No background thread. Just walk the jobs with no locking and process them.
        for (item = bgp->GetNextUnprocessedItem(); item; item = bgp->GetNextUnprocessedItem())
        {
            bgp->Processor()->RemoveJob(item);
            bool succeeded = bgp->Process(item, this, pse);
            bgp->JobProcessed(item, succeeded);
        }
        Assert(!*bgp->GetPendingBackgroundItemsPtr());
    }
    else
    {
        // Background threads. We need to have the critical section in order to:
        // - Check for unprocessed jobs;
        // - Remove jobs from the processor queue;
        // - Do JobsProcessed work (such as removing jobs from the BackgroundParser's unprocessed list).
        CriticalSection *pcs = static_cast<JsUtil::BackgroundJobProcessor*>(bgp->Processor())->GetCriticalSection();
        pcs->Enter();
        for (;;)
        {
            // Grab a job (in lock)
            item = bgp->GetNextUnprocessedItem();
            if (item == nullptr)
            {
                break;
            }
            bgp->Processor()->RemoveJob(item);
            pcs->Leave();

            // Process job (if there is one) (outside lock)
            bool succeeded = bgp->Process(item, this, pse);

            pcs->Enter();
            bgp->JobProcessed(item, succeeded);
        }
        pcs->Leave();

        // Wait for the background threads to finish jobs they're already processing (if any).
        // TODO: Replace with a proper semaphore.
        while (*bgp->GetPendingBackgroundItemsPtr());
    }

    Assert(!*bgp->GetPendingBackgroundItemsPtr());

    // Restore parser state.
    this->m_pstmtCur = pstmtSave;
    this->m_isInBackground = false;
    this->m_nextBlockId = blockIdSave;
    *this->m_nextFunctionId = functionIdSave;
}

void Parser::FinishBackgroundPidRefs(BackgroundParseItem *item, bool isOtherParser)
{
    for (BlockInfoStack *blockInfo = item->GetParseContext()->currentBlockInfo; blockInfo; blockInfo = blockInfo->pBlockInfoOuter)
    {
        if (isOtherParser)
        {
            this->BindPidRefs<true>(blockInfo, item->GetMaxBlockId());
        }
        else
        {
            this->BindPidRefs<false>(blockInfo, item->GetMaxBlockId());
        }
    }
}

void Parser::FinishBackgroundRegExpNodes()
{
    // We have a list of RegExp nodes that we saw on the UI thread in functions we're parallel parsing,
    // and for each background job we have a list of RegExp nodes for which we couldn't allocate patterns.
    // We need to copy the pattern pointers from the UI thread nodes to the corresponding nodes on the
    // background nodes.
    // There may be UI thread nodes for which there are no background thread equivalents, because the UI thread
    // has to assume that the background thread won't defer anything.

    // Note that because these lists (and the list of background jobs) are SList's built by prepending, they are
    // all in reverse lexical order.

    Assert(!this->IsBackgroundParser());
    Assert(this->fastScannedRegExpNodes);
    Assert(this->backgroundParseItems != nullptr);

    BackgroundParseItem *currBackgroundItem;

#if DBG
    for (currBackgroundItem = this->backgroundParseItems;
        currBackgroundItem;
        currBackgroundItem = currBackgroundItem->GetNext())
    {
        if (currBackgroundItem->RegExpNodeList())
        {
            FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
            {
                Assert(pnode->AsParseNodeRegExp()->regexPattern == nullptr);
            }
            NEXT_DLIST_ENTRY;
        }
    }
#endif

    // Hook up the patterns allocated on the main thread to the nodes created on the background thread.
    // Walk the list of foreground nodes, advancing through the work items and looking up each item.
    // Note that the background thread may have chosen to defer a given RegEx literal, so not every foreground
    // node will have a matching background node. Doesn't matter for correctness.
    // (It's inefficient, of course, to have to restart the inner loop from the beginning of the work item's
    // list, but it should be unusual to have many RegExes in a single work item's chunk of code. Figure out how
    // to start the inner loop from a known internal node within the list if that turns out to be important.)
    currBackgroundItem = this->backgroundParseItems;
    FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeFgnd, this->fastScannedRegExpNodes)
    {
        Assert(pnodeFgnd->nop == knopRegExp);
        Assert(pnodeFgnd->AsParseNodeRegExp()->regexPattern != nullptr);
        bool quit = false;

        while (!quit)
        {
            // Find the next work item with a RegEx in it.
            while (currBackgroundItem && currBackgroundItem->RegExpNodeList() == nullptr)
            {
                currBackgroundItem = currBackgroundItem->GetNext();
            }
            if (!currBackgroundItem)
            {
                break;
            }

            // Walk the RegExps in the work item.
            FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnodeBgnd, currBackgroundItem->RegExpNodeList())
            {
                Assert(pnodeBgnd->nop == knopRegExp);

                if (pnodeFgnd->ichMin <= pnodeBgnd->ichMin)
                {
                    // Either we found a match, or the next background node is past the foreground node.
                    // In any case, we can stop searching.
                    if (pnodeFgnd->ichMin == pnodeBgnd->ichMin)
                    {
                        Assert(pnodeFgnd->ichLim == pnodeBgnd->ichLim);
                        pnodeBgnd->AsParseNodeRegExp()->regexPattern = pnodeFgnd->AsParseNodeRegExp()->regexPattern;
                    }
                    quit = true;
                    break;
                }
            }
            NEXT_DLIST_ENTRY;

            if (!quit)
            {
                // Need to advance to the next work item.
                currBackgroundItem = currBackgroundItem->GetNext();
            }
        }
    }
    NEXT_DLIST_ENTRY;

#if DBG
    for (currBackgroundItem = this->backgroundParseItems;
        currBackgroundItem;
        currBackgroundItem = currBackgroundItem->GetNext())
    {
        if (currBackgroundItem->RegExpNodeList())
        {
            FOREACH_DLIST_ENTRY(ParseNodePtr, ArenaAllocator, pnode, currBackgroundItem->RegExpNodeList())
            {
                Assert(pnode->AsParseNodeRegExp()->regexPattern != nullptr);
            }
            NEXT_DLIST_ENTRY;
        }
    }
#endif
}
#endif

LabelId* Parser::CreateLabelId(IdentPtr pid)
{
    LabelId* pLabelId;

    pLabelId = (LabelId*)m_nodeAllocator.Alloc(sizeof(LabelId));
    if (NULL == pLabelId)
        Error(ERRnoMemory);
    pLabelId->pid = pid;
    pLabelId->next = NULL;

    return pLabelId;
}

/*****************************************************************************
The following set of routines allocate parse tree nodes of various kinds.
They catch an exception on out of memory.
*****************************************************************************/
void
Parser::AddAstSize(int size)
{
    Assert(!this->m_deferringAST);
    Assert(m_pCurrentAstSize != NULL);
    *m_pCurrentAstSize += size;
}

void
Parser::AddAstSizeAllowDefer(int size)
{
    if (!this->m_deferringAST)
    {
        AddAstSize(size);
    }
}

// StaticCreate
ParseNodeVar * Parser::StaticCreateTempNode(ParseNode* initExpr, ArenaAllocator * alloc)
{
    ParseNodeVar * pnode = Anew(alloc, ParseNodeVar, knopTemp, 0, 0, nullptr);
    pnode->pnodeInit = initExpr;
    return pnode;
}

ParseNodeUni * Parser::StaticCreateTempRef(ParseNode* tempNode, ArenaAllocator * alloc)
{
    return Anew(alloc, ParseNodeUni, knopTempRef, 0, 0, tempNode);
}

// Create Node with limit
template <OpCode nop>
typename OpCodeTrait<nop>::ParseNodeType * Parser::CreateNodeForOpT(charcount_t ichMin, charcount_t ichLim)
{
    Assert(!this->m_deferringAST);
    typename OpCodeTrait<nop>::ParseNodeType * pnode = StaticCreateNodeT<nop>(&m_nodeAllocator, ichMin, ichLim);
    AddAstSize(sizeof(typename OpCodeTrait<nop>::ParseNodeType));
    return pnode;
}

template <OpCode nop>
typename OpCodeTrait<nop>::ParseNodeType * Parser::CreateAllowDeferNodeForOpT(charcount_t ichMin, charcount_t ichLim)
{
    CompileAssert(OpCodeTrait<nop>::AllowDefer);
    typename OpCodeTrait<nop>::ParseNodeType * pnode = StaticCreateNodeT<nop>(&m_nodeAllocator, ichMin, ichLim);
    AddAstSizeAllowDefer(sizeof(typename OpCodeTrait<nop>::ParseNodeType));
    return pnode;
}


#if DBG
static const int g_mpnopcbNode[] =
{
#define PTNODE(nop,sn,pc,nk,ok,json) sizeof(ParseNode##nk),
#include "ptlist.h"
};

void VerifyNodeSize(OpCode nop, int size)
{
    Assert(nop >= 0 && nop < knopLim);
    __analysis_assume(nop < knopLim);
    Assert(g_mpnopcbNode[nop] == size);
}
#endif

// Create ParseNodeUni
ParseNodeUni * Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1)
{
    charcount_t ichMin;
    charcount_t ichLim;

    if (nullptr == pnode1)
    {
        // no ops
        ichMin = this->GetScanner()->IchMinTok();
        ichLim = this->GetScanner()->IchLimTok();
    }
    else
    {
        // 1 op
        ichMin = pnode1->ichMin;
        ichLim = pnode1->ichLim;
        this->CheckArguments(pnode1);
    }
    return CreateUniNode(nop, pnode1, ichMin, ichLim);
}

ParseNodeUni * Parser::CreateUniNode(OpCode nop, ParseNodePtr pnode1, charcount_t ichMin, charcount_t ichLim)
{
    Assert(!this->m_deferringAST);
    DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeUni)));
    ParseNodeUni * pnode = Anew(&m_nodeAllocator, ParseNodeUni, nop, ichMin, ichLim, pnode1);
    AddAstSize(sizeof(ParseNodeUni));
    return pnode;
}

// Create ParseNodeBin
ParseNodeBin * Parser::StaticCreateBinNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2, ArenaAllocator* alloc, charcount_t ichMin, charcount_t ichLim)
{
    DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeBin)));
    return Anew(alloc, ParseNodeBin, nop, ichMin, ichLim, pnode1, pnode2);
}

ParseNodeBin * Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
{
    Assert(!this->m_deferringAST);
    charcount_t ichMin;
    charcount_t ichLim;

    if (nullptr == pnode1)
    {
        // no ops
        Assert(nullptr == pnode2);
        ichMin = this->GetScanner()->IchMinTok();
        ichLim = this->GetScanner()->IchLimTok();
    }
    else
    {
        if (nullptr == pnode2)
        {
            // 1 op
            ichMin = pnode1->ichMin;
            ichLim = pnode1->ichLim;
        }
        else
        {
            // 2 ops
            ichMin = pnode1->ichMin;
            ichLim = pnode2->ichLim;
            if (nop != knopDot && nop != knopIndex)
            {
                this->CheckArguments(pnode2);
            }
        }
        if (nop != knopDot && nop != knopIndex)
        {
            this->CheckArguments(pnode1);
        }
    }

    return CreateBinNode(nop, pnode1, pnode2, ichMin, ichLim);
}


ParseNodeBin * Parser::CreateBinNode(OpCode nop, ParseNodePtr pnode1,
    ParseNodePtr pnode2, charcount_t ichMin, charcount_t ichLim)
{
    Assert(!this->m_deferringAST);
    ParseNodeBin * pnode = StaticCreateBinNode(nop, pnode1, pnode2, &m_nodeAllocator, ichMin, ichLim);
    AddAstSize(sizeof(ParseNodeBin));
    return pnode;
}

// Create ParseNodeTri
ParseNodeTri * Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
    ParseNodePtr pnode2, ParseNodePtr pnode3)
{
    charcount_t ichMin;
    charcount_t ichLim;

    if (nullptr == pnode1)
    {
        // no ops
        Assert(nullptr == pnode2);
        Assert(nullptr == pnode3);
        ichMin = this->GetScanner()->IchMinTok();
        ichLim = this->GetScanner()->IchLimTok();
    }
    else if (nullptr == pnode2)
    {
        // 1 op
        Assert(nullptr == pnode3);
        ichMin = pnode1->ichMin;
        ichLim = pnode1->ichLim;
    }
    else if (nullptr == pnode3)
    {
        // 2 op
        ichMin = pnode1->ichMin;
        ichLim = pnode2->ichLim;
    }
    else
    {
        // 3 ops
        ichMin = pnode1->ichMin;
        ichLim = pnode3->ichLim;
    }

    return CreateTriNode(nop, pnode1, pnode2, pnode3, ichMin, ichLim);
}

ParseNodeTri * Parser::CreateTriNode(OpCode nop, ParseNodePtr pnode1,
    ParseNodePtr pnode2, ParseNodePtr pnode3,
    charcount_t ichMin, charcount_t ichLim)
{
    Assert(!this->m_deferringAST);
    DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeTri)));
    ParseNodeTri * pnode = Anew(&m_nodeAllocator, ParseNodeTri, nop, ichMin, ichLim);
    AddAstSize(sizeof(ParseNodeTri));

    pnode->pnode1 = pnode1;
    pnode->pnode2 = pnode2;
    pnode->pnode3 = pnode3;

    return pnode;
}

// Create ParseNodeBlock
ParseNodeBlock *
Parser::StaticCreateBlockNode(ArenaAllocator* alloc, charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType)
{
    return Anew(alloc, ParseNodeBlock, ichMin, ichLim, blockId, blockType);
}

ParseNodeBlock * Parser::CreateBlockNode(PnodeBlockType blockType)
{
    return CreateBlockNode(this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), blockType);
}

ParseNodeBlock * Parser::CreateBlockNode(charcount_t ichMin, charcount_t ichLim, PnodeBlockType blockType)
{
    Assert(OpCodeTrait<knopBlock>::AllowDefer);
    ParseNodeBlock * pnode = StaticCreateBlockNode(&m_nodeAllocator, ichMin, ichLim, this->m_nextBlockId++, blockType);
    AddAstSizeAllowDefer(sizeof(ParseNodeBlock));
    return pnode;
}

// Create ParseNodeVar
ParseNodeVar * Parser::CreateDeclNode(OpCode nop, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
{
    Assert(nop == knopVarDecl || nop == knopLetDecl || nop == knopConstDecl);
    ParseNodeVar * pnode = Anew(&m_nodeAllocator, ParseNodeVar, nop, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
    if (symbolType != STUnknown)
    {
        pnode->sym = AddDeclForPid(pnode, pid, symbolType, errorOnRedecl);
    }

    return pnode;
}

ParseNodeInt * Parser::CreateIntNode(int32 lw)
{
    Assert(!this->m_deferringAST);
    ParseNodeInt * pnode = Anew(&m_nodeAllocator, ParseNodeInt, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), lw);
    AddAstSize(sizeof(ParseNodeInt));
    return pnode;
}

ParseNodeStr * Parser::CreateStrNode(IdentPtr pid)
{
    Assert(!this->m_deferringAST);
    ParseNodeStr * pnode = Anew(&m_nodeAllocator, ParseNodeStr, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
    pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
    AddAstSize(sizeof(ParseNodeStr));
    return pnode;
}

ParseNodeBigInt * Parser::CreateBigIntNode(IdentPtr pid)
{
    Assert(!this->m_deferringAST);
    ParseNodeBigInt * pnode = Anew(&m_nodeAllocator, ParseNodeBigInt, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
    pnode->isNegative = false;
    AddAstSize(sizeof(ParseNodeBigInt));
    return pnode;
}

ParseNodeName * Parser::CreateNameNode(IdentPtr pid)
{
    ParseNodeName * pnode = Anew(&m_nodeAllocator, ParseNodeName, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
    AddAstSizeAllowDefer(sizeof(ParseNodeName));
    return pnode;
}

ParseNodeName * Parser::CreateNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim)
{
    ParseNodeName * pnode = Anew(&m_nodeAllocator, ParseNodeName, ichMin, ichLim, pid);
    pnode->SetSymRef(ref);
    AddAstSize(sizeof(ParseNodeName));
    return pnode;
}

ParseNodeSpecialName * Parser::CreateSpecialNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim)
{
    Assert(!this->m_deferringAST);
    ParseNodeSpecialName * pnode = Anew(&m_nodeAllocator, ParseNodeSpecialName, ichMin, ichLim, pid);
    pnode->SetSymRef(ref);
    if (pid == wellKnownPropertyPids._this)
    {
        pnode->isThis = true;
    }
    else if (pid == wellKnownPropertyPids._super || pid == wellKnownPropertyPids._superConstructor)
    {
        pnode->isSuper = true;
    }

    AddAstSize(sizeof(ParseNodeSpecialName));
    return pnode;
}

ParseNodeSuperReference * Parser::CreateSuperReferenceNode(OpCode nop, ParseNodeSpecialName * pnode1, ParseNodePtr pnode2)
{
    Assert(!this->m_deferringAST);
    Assert(pnode1 && pnode1->isSuper);
    Assert(pnode2 != nullptr);
    Assert(nop == knopDot || nop == knopIndex);

    ParseNodeSuperReference * pnode = Anew(&m_nodeAllocator, ParseNodeSuperReference, nop, pnode1->ichMin, pnode2->ichLim, pnode1, pnode2);
    AddAstSize(sizeof(ParseNodeSuperReference));

    return pnode;
}

ParseNodeProg * Parser::CreateProgNode(bool isModuleSource, ULONG lineNumber)
{
    ParseNodeProg * pnodeProg;

    if (isModuleSource)
    {
        pnodeProg = CreateNodeForOpT<knopModule>();

        // knopModule is not actually handled anywhere since we would need to handle it everywhere we could
        // have knopProg and it would be treated exactly the same except for import/export statements.
        // We are only using it as a way to get the correct size for PnModule.
        // Consider: Should we add a flag to PnProg which is false but set to true in PnModule?
        //           If we do, it can't be a virtual method since the parse nodes are all in a union.
        pnodeProg->nop = knopProg;
    }
    else
    {
        pnodeProg = CreateNodeForOpT<knopProg>();
    }

    pnodeProg->cbMin = this->GetScanner()->IecpMinTok();
    pnodeProg->cbStringMin = pnodeProg->cbMin;
    pnodeProg->lineNumber = lineNumber;
    pnodeProg->homeObjLocation = Js::Constants::NoRegister;
    pnodeProg->superRestrictionState = SuperRestrictionState::Disallowed;
    return pnodeProg;
}

ParseNodeCall * Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2)
{
    charcount_t ichMin;
    charcount_t ichLim;

    if (nullptr == pnode1)
    {
        Assert(nullptr == pnode2);
        ichMin = this->GetScanner()->IchMinTok();
        ichLim = this->GetScanner()->IchLimTok();
    }
    else
    {
        ichMin = pnode1->ichMin;
        ichLim = pnode2 == nullptr ? pnode1->ichLim : pnode2->ichLim;

        if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
        {
            this->CheckArguments(pnode1->AsParseNodeBin()->pnode1);
        }
    }
    return CreateCallNode(nop, pnode1, pnode2, ichMin, ichLim);
}



ParseNodeCall * Parser::CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2, charcount_t ichMin, charcount_t ichLim)
{
    Assert(!this->m_deferringAST);

    // Classes, derived from ParseNodeCall, can be created here as well,
    // as long as their size matches kcbPnCall (that is, they don't add
    // any data members of their own).
    DebugOnly(VerifyNodeSize(nop, sizeof(ParseNodeCall)));
    ParseNodeCall* pnode = Anew(&m_nodeAllocator, ParseNodeCall, nop, ichMin, ichLim, pnode1, pnode2);
    AddAstSize(sizeof(ParseNodeCall));

    return pnode;
}

ParseNodeSuperCall * Parser::CreateSuperCallNode(ParseNodeSpecialName * pnode1, ParseNodePtr pnode2)
{
    Assert(!this->m_deferringAST);
    Assert(pnode1 && pnode1->isSuper);

    ParseNodeSuperCall* pnode = Anew(&m_nodeAllocator, ParseNodeSuperCall, knopCall, pnode1->ichMin, pnode2 == nullptr ? pnode1->ichLim : pnode2->ichLim, pnode1, pnode2);
    AddAstSize(sizeof(ParseNodeSuperCall));
    return pnode;
}

ParseNodeParamPattern * Parser::CreateParamPatternNode(ParseNode * pnode1)
{
    ParseNodeParamPattern * paramPatternNode = CreateNodeForOpT<knopParamPattern>(pnode1->ichMin, pnode1->ichLim);
    paramPatternNode->pnode1 = pnode1;
    paramPatternNode->pnodeNext = nullptr;
    paramPatternNode->location = Js::Constants::NoRegister;
    return paramPatternNode;
}

ParseNodeParamPattern * Parser::CreateDummyParamPatternNode(charcount_t ichMin)
{
    ParseNodeParamPattern * paramPatternNode = CreateNodeForOpT<knopParamPattern>(ichMin);
    paramPatternNode->pnode1 = nullptr;
    paramPatternNode->pnodeNext = nullptr;
    paramPatternNode->location = Js::Constants::NoRegister;
    return paramPatternNode;
}

ParseNodeObjLit * Parser::CreateObjectPatternNode(ParseNodePtr pnodeMemberList, charcount_t ichMin, charcount_t ichLim, bool convertToPattern) {
    // Count the number of non-rest members in the object
    uint32 staticCount = 0;
    uint32 computedCount = 0;
    bool hasRest = false;
    ParseNodePtr pnodeMemberNodeList = convertToPattern ? nullptr : pnodeMemberList;
    if (pnodeMemberList != nullptr)
    {
        Assert(pnodeMemberList->nop == knopList || 
              (!convertToPattern && pnodeMemberList->nop == knopObjectPatternMember) || 
              convertToPattern ||
              pnodeMemberList->nop == knopEllipsis);
        ForEachItemInList(pnodeMemberList, [&](ParseNodePtr item) {
            ParseNodePtr memberNode = convertToPattern ? ConvertMemberToMemberPattern(item) : item;
            if (convertToPattern)
            {
                AppendToList(&pnodeMemberNodeList, memberNode);
            }
            if (memberNode->nop != knopEllipsis)
            {
                ParseNodePtr nameNode = memberNode->AsParseNodeBin()->pnode1;
                Assert(nameNode->nop == knopComputedName || nameNode->nop == knopStr);
                if (nameNode->nop == knopComputedName)
                {
                    computedCount++;
                }
                else
                {
                    staticCount++;
                }
            }
            else
            {
                hasRest = true;
            }
        });
    }

    ParseNodeObjLit * objectPatternNode = CreateNodeForOpT<knopObjectPattern>(ichMin, ichLim);
    objectPatternNode->pnode1 = pnodeMemberNodeList;
    objectPatternNode->computedCount = computedCount;
    objectPatternNode->staticCount = staticCount;
    objectPatternNode->hasRest = hasRest;
    return objectPatternNode;
}

Symbol* Parser::AddDeclForPid(ParseNodeVar * pnodeVar, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl)
{
    Assert(pnodeVar->IsVarLetOrConst());

    PidRefStack *refForUse = nullptr, *refForDecl = nullptr;
    BlockInfoStack *blockInfo;
    bool fBlockScope = false;
    if (pnodeVar->nop != knopVarDecl || symbolType == STFunction)
    {
        Assert(m_pstmtCur);
        if (m_pstmtCur->GetNop() != knopBlock)
        {
            // Let/const declared in a bare statement context.
            Error(ERRDeclOutOfStmt);
        }

        if (m_pstmtCur->pstmtOuter && m_pstmtCur->pstmtOuter->GetNop() == knopSwitch)
        {
            // Let/const declared inside a switch block (requiring conservative use-before-decl check).
            pnodeVar->isSwitchStmtDecl = true;
        }

        fBlockScope = pnodeVar->nop != knopVarDecl ||
            (
                !GetCurrentBlockInfo()->pnodeBlock->scope ||
                GetCurrentBlockInfo()->pnodeBlock->scope->GetScopeType() != ScopeType_GlobalEvalBlock
                );
    }
    if (fBlockScope)
    {
        blockInfo = GetCurrentBlockInfo();
    }
    else
    {
        blockInfo = GetCurrentFunctionBlockInfo();
    }

    refForDecl = this->FindOrAddPidRef(pid, blockInfo->pnodeBlock->blockId, GetCurrentFunctionNode()->functionId);

    if (refForDecl == nullptr)
    {
        Error(ERRnoMemory);
    }

    if (refForDecl->funcId != GetCurrentFunctionNode()->functionId)
    {
        // Fix up the function id, which is incorrect if we're reparsing lambda parameters
        Assert(this->m_reparsingLambdaParams);
        refForDecl->funcId = GetCurrentFunctionNode()->functionId;
    }

    if (blockInfo == GetCurrentBlockInfo())
    {
        refForUse = refForDecl;
    }
    else
    {
        refForUse = this->PushPidRef(pid);
    }
    pnodeVar->symRef = refForUse->GetSymRef();
    Symbol *sym = refForDecl->GetSym();
    if (sym != nullptr)
    {
        // Multiple declarations in the same scope. 3 possibilities: error, existing one wins, new one wins.
        switch (pnodeVar->nop)
        {
        case knopLetDecl:
        case knopConstDecl:
            if (!sym->GetDecl()->AsParseNodeVar()->isBlockScopeFncDeclVar && !sym->IsArguments())
            {
                // If the built-in arguments is shadowed then don't throw
                Assert(errorOnRedecl);
                // Redeclaration error.
                Error(ERRRedeclaration);
            }
            else
            {
                // (New) let/const hides the (old) var
                sym->SetSymbolType(symbolType);
                sym->SetDecl(pnodeVar);
            }
            break;
        case knopVarDecl:
            if (m_currentScope->GetScopeType() == ScopeType_Parameter && !sym->IsArguments())
            {
                // If this is a parameter list, mark the scope to indicate that it has duplicate definition unless it is shadowing the default arguments symbol.
                // If later this turns out to be a non-simple param list (like function f(a, a, c = 1) {}) then it is a SyntaxError to have duplicate formals.
                m_currentScope->SetHasDuplicateFormals();
            }

            if (sym->GetDecl() == nullptr)
            {
                sym->SetDecl(pnodeVar);
                break;
            }
            switch (sym->GetDecl()->nop)
            {
            case knopLetDecl:
            case knopConstDecl:
                // Destructuring made possible to have the formals to be the let bind. But that shouldn't throw the error.
                if (errorOnRedecl && (!IsES6DestructuringEnabled() || sym->GetSymbolType() != STFormal))
                {
                    Error(ERRRedeclaration);
                }
                // If !errorOnRedecl, (old) let/const hides the (new) var, so do nothing.
                break;
            case knopVarDecl:
                // Legal redeclaration. Who wins?
                if (errorOnRedecl || sym->GetDecl()->AsParseNodeVar()->isBlockScopeFncDeclVar || sym->IsArguments())
                {
                    if (symbolType == STFormal ||
                        (symbolType == STFunction && sym->GetSymbolType() != STFormal) ||
                        sym->GetSymbolType() == STVariable)
                    {
                        // New decl wins.
                        sym->SetSymbolType(symbolType);
                        sym->SetDecl(pnodeVar);
                    }
                }
                break;
            }
            break;
        }
    }
    else
    {
        Scope *scope = blockInfo->pnodeBlock->scope;
        if (scope == nullptr)
        {
            Assert(blockInfo->pnodeBlock->blockType == PnodeBlockType::Regular);
            scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, ScopeType_Block);
            if (this->IsCurBlockInLoop())
            {
                scope->SetIsBlockInLoop();
            }
            blockInfo->pnodeBlock->scope = scope;
            PushScope(scope);
        }

        ParseNodeFnc * pnodeFnc = GetCurrentFunctionNode();
        if (scope->GetScopeType() == ScopeType_GlobalEvalBlock)
        {
            Assert(fBlockScope);
            Assert(scope->GetEnclosingScope() == m_currentNodeProg->scope);
            // Check for same-named decl in Global scope.
            CheckRedeclarationErrorForBlockId(pid, 0);
        }
        else if (scope->GetScopeType() == ScopeType_Global && (this->m_grfscr & fscrEvalCode) &&
            !(m_functionBody && m_functionBody->GetScopeInfo()))
        {
            // Check for same-named decl in GlobalEvalBlock scope. Note that this is not necessary
            // if we're compiling a deferred nested function and the global scope was restored from cached info,
            // because in that case we don't need a GlobalEvalScope.
            Assert(!fBlockScope || (this->m_grfscr & fscrConsoleScopeEval) == fscrConsoleScopeEval);
            CheckRedeclarationErrorForBlockId(pid, 1);
        }
        else if (!pnodeFnc->IsBodyAndParamScopeMerged()
            && scope->GetScopeType() == ScopeType_FunctionBody
            && (pnodeVar->nop == knopLetDecl || pnodeVar->nop == knopConstDecl))
        {
            // In case of split scope function when we add a new let or const declaration to the body
            // we have to check whether the param scope already has the same symbol defined.
            CheckRedeclarationErrorForBlockId(pid, pnodeFnc->pnodeScopes->blockId);
        }

        if (!sym)
        {
            const char16 *name = reinterpret_cast<const char16*>(pid->Psz());
            int nameLength = pid->Cch();
            SymbolName const symName(name, nameLength);

            Assert(!scope->FindLocalSymbol(symName));
            sym = Anew(&m_nodeAllocator, Symbol, symName, pnodeVar, symbolType);
            scope->AddNewSymbol(sym);
            sym->SetPid(pid);
        }
        refForDecl->SetSym(sym);
    }
    return sym;
}

void Parser::CheckRedeclarationErrorForBlockId(IdentPtr pid, int blockId)
{
    // If the ref stack entry for the blockId contains a sym then throw redeclaration error
    PidRefStack *pidRefOld = pid->GetPidRefForScopeId(blockId);
    if (pidRefOld && pidRefOld->GetSym() && !pidRefOld->GetSym()->IsArguments())
    {
        Error(ERRRedeclaration);
    }
}

bool Parser::IsCurBlockInLoop() const
{
    for (StmtNest *stmt = this->m_pstmtCur; stmt != nullptr; stmt = stmt->pstmtOuter)
    {
        OpCode nop = stmt->GetNop();
        if (ParseNode::Grfnop(nop) & fnopContinue)
        {
            return true;
        }
        if (nop == knopFncDecl)
        {
            return false;
        }
    }
    return false;
}

void Parser::RestorePidRefForSym(Symbol *sym)
{
    IdentPtr pid = this->GetHashTbl()->PidHashNameLen(sym->GetName().GetBuffer(), sym->GetName().GetLength());
    Assert(pid);
    sym->SetPid(pid);
    PidRefStack *ref = this->PushPidRef(pid);
    ref->SetSym(sym);
}

void Parser::CheckPidIsValid(IdentPtr pid, bool autoArgumentsObject)
{
    if (IsStrictMode())
    {
        // in strict mode, variable named 'eval' cannot be created
        if (pid == wellKnownPropertyPids.eval)
        {
            Error(ERREvalUsage);
        }
        else if (pid == wellKnownPropertyPids.arguments && !autoArgumentsObject)
        {
            Error(ERRArgsUsage);
        }
    }
}

// CreateVarDecl needs m_ppnodeVar to be pointing to the right function.
// Post-parsing rewriting during bytecode gen may have m_ppnodeVar pointing to the last parsed function.
// This function sets up m_ppnodeVar to point to the given pnodeFnc and creates the new var declaration.
// This prevents accidentally adding var declarations to the last parsed function.
ParseNodeVar * Parser::AddVarDeclNode(IdentPtr pid, ParseNodeFnc * pnodeFnc)
{
    AnalysisAssert(pnodeFnc);

    ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;

    m_ppnodeVar = &pnodeFnc->pnodeVars;
    while (*m_ppnodeVar != nullptr)
    {
        m_ppnodeVar = &(*m_ppnodeVar)->AsParseNodeVar()->pnodeNext;
    }

    ParseNodeVar * pnode = CreateVarDeclNode(pid, STUnknown, false, 0, /* checkReDecl = */ false);

    m_ppnodeVar = ppnodeVarSave;

    return pnode;
}

ParseNodeVar * Parser::CreateModuleImportDeclNode(IdentPtr localName)
{
    ParseNodeVar * declNode = CreateBlockScopedDeclNode(localName, knopConstDecl);
    Symbol* sym = declNode->sym;

    sym->SetIsModuleExportStorage(true);
    sym->SetIsModuleImport(true);

    return declNode;
}

ParseNodeVar * Parser::CreateVarDeclNode(IdentPtr pid, SymbolType symbolType, bool autoArgumentsObject, ParseNodePtr pnodeFnc, bool errorOnRedecl)
{
    ParseNodeVar * pnode = CreateDeclNode(knopVarDecl, pid, symbolType, errorOnRedecl);

    // Append the variable to the end of the current variable list.
    Assert(m_ppnodeVar);
    pnode->pnodeNext = *m_ppnodeVar;
    *m_ppnodeVar = pnode;
    if (nullptr != pid)
    {
        // this is not a temp - make sure temps go after this node
        Assert(pid);
        m_ppnodeVar = &pnode->pnodeNext;
        CheckPidIsValid(pid, autoArgumentsObject);
    }

    return pnode;
}

ParseNodeVar * Parser::CreateBlockScopedDeclNode(IdentPtr pid, OpCode nodeType)
{
    Assert(nodeType == knopConstDecl || nodeType == knopLetDecl);

    ParseNodeVar * pnode = CreateDeclNode(nodeType, pid, STVariable, true);

    if (nullptr != pid)
    {
        Assert(pid);
        AddVarDeclToBlock(pnode);
        CheckPidIsValid(pid);
    }

    return pnode;
}

void Parser::AddVarDeclToBlock(ParseNodeVar *pnode)
{
    Assert(pnode->nop == knopConstDecl || pnode->nop == knopLetDecl);

    // Maintain a combined list of let and const declarations to keep
    // track of declaration order.

    Assert(m_currentBlockInfo->m_ppnodeLex);
    *m_currentBlockInfo->m_ppnodeLex = pnode;
    m_currentBlockInfo->m_ppnodeLex = &pnode->pnodeNext;
    pnode->pnodeNext = nullptr;
}

void Parser::SetCurrentStatement(StmtNest *stmt)
{
    m_pstmtCur = stmt;
}

template<bool buildAST>
ParseNodeBlock * Parser::StartParseBlockWithCapacity(PnodeBlockType blockType, ScopeType scopeType, int capacity)
{
    Scope *scope = nullptr;

    // Block scopes are not created lazily in the case where we're repopulating a persisted scope.

    scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType, capacity);
    PushScope(scope);

    return StartParseBlockHelper<buildAST>(blockType, scope, nullptr);
}

template<bool buildAST>
ParseNodeBlock * Parser::StartParseBlock(PnodeBlockType blockType, ScopeType scopeType, LabelId* pLabelId)
{
    Scope *scope = nullptr;
    // Block scopes are created lazily when we discover block-scoped content.
    if (scopeType != ScopeType_Unknown && scopeType != ScopeType_Block)
    {
        scope = Anew(&m_nodeAllocator, Scope, &m_nodeAllocator, scopeType);
        PushScope(scope);
    }

    return StartParseBlockHelper<buildAST>(blockType, scope, pLabelId);
}

template<bool buildAST>
ParseNodeBlock * Parser::StartParseBlockHelper(PnodeBlockType blockType, Scope *scope, LabelId* pLabelId)
{
    ParseNodeBlock * pnodeBlock = CreateBlockNode(blockType);
    pnodeBlock->scope = scope;
    BlockInfoStack *newBlockInfo = PushBlockInfo(pnodeBlock);

    PushStmt<buildAST>(&newBlockInfo->pstmt, pnodeBlock, knopBlock, pLabelId);

    return pnodeBlock;
}

void Parser::PushScope(Scope *scope)
{
    Assert(scope);
    scope->SetEnclosingScope(m_currentScope);
    m_currentScope = scope;
}

void Parser::PopScope(Scope *scope)
{
    Assert(scope == m_currentScope);
    m_currentScope = scope->GetEnclosingScope();
    scope->SetEnclosingScope(nullptr);
}

void Parser::PushFuncBlockScope(ParseNodeBlock * pnodeBlock, ParseNodePtr **ppnodeScopeSave, ParseNodePtr **ppnodeExprScopeSave)
{
    // Maintain the scope tree.

    pnodeBlock->pnodeScopes = nullptr;
    pnodeBlock->pnodeNext = nullptr;

    // Insert this block into the active list of scopes (m_ppnodeExprScope or m_ppnodeScope).
    // Save the current block's "next" pointer as the new endpoint of that list.
    if (m_ppnodeExprScope)
    {
        *ppnodeScopeSave = m_ppnodeScope;

        Assert(*m_ppnodeExprScope == nullptr);
        *m_ppnodeExprScope = pnodeBlock;
        *ppnodeExprScopeSave = &pnodeBlock->pnodeNext;
    }
    else
    {
        Assert(m_ppnodeScope);
        Assert(*m_ppnodeScope == nullptr);
        *m_ppnodeScope = pnodeBlock;
        *ppnodeScopeSave = &pnodeBlock->pnodeNext;

        *ppnodeExprScopeSave = m_ppnodeExprScope;
    }

    // Advance the global scope list pointer to the new block's child list.
    m_ppnodeScope = &pnodeBlock->pnodeScopes;
    // Set m_ppnodeExprScope to NULL to make that list inactive.
    m_ppnodeExprScope = nullptr;
}

void Parser::PopFuncBlockScope(ParseNodePtr *ppnodeScopeSave, ParseNodePtr *ppnodeExprScopeSave)
{
    Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
    m_ppnodeExprScope = ppnodeExprScopeSave;

    Assert(m_ppnodeScope);
    Assert(nullptr == *m_ppnodeScope);
    m_ppnodeScope = ppnodeScopeSave;
}

template<bool buildAST>
ParseNodeBlock * Parser::ParseBlock(LabelId* pLabelId)
{
    ParseNodeBlock * pnodeBlock = nullptr;
    ParseNodePtr *ppnodeScopeSave = nullptr;
    ParseNodePtr *ppnodeExprScopeSave = nullptr;

    pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block, pLabelId);

    BlockInfoStack* outerBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
    if (outerBlockInfo != nullptr && outerBlockInfo->pnodeBlock != nullptr
        && outerBlockInfo->pnodeBlock->scope != nullptr
        && outerBlockInfo->pnodeBlock->scope->GetScopeType() == ScopeType_CatchParamPattern)
    {
        // If we are parsing the catch block then destructured params can have let declarations. Let's add them to the new block.
        for (ParseNodePtr pnode = m_currentBlockInfo->pBlockInfoOuter->pnodeBlock->pnodeLexVars; pnode; pnode = pnode->AsParseNodeVar()->pnodeNext)
        {
            PidRefStack* ref = PushPidRef(pnode->AsParseNodeVar()->sym->GetPid());
            ref->SetSym(pnode->AsParseNodeVar()->sym);
        }
    }

    ChkCurTok(tkLCurly, ERRnoLcurly);
    ParseNodePtr * ppnodeList = nullptr;
    if (buildAST)
    {
        PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
        ppnodeList = &pnodeBlock->pnodeStmt;
    }

    ParseStmtList<buildAST>(ppnodeList);

    if (buildAST)
    {
        PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
    }

    FinishParseBlock(pnodeBlock);

    ChkCurTok(tkRCurly, ERRnoRcurly);

    return pnodeBlock;
}

bool Parser::IsSpecialName(IdentPtr pid)
{
    return pid == wellKnownPropertyPids._this ||
        pid == wellKnownPropertyPids._super ||
        pid == wellKnownPropertyPids._superConstructor ||
        pid == wellKnownPropertyPids._newTarget;
}

ParseNodeSpecialName * Parser::ReferenceSpecialName(IdentPtr pid, charcount_t ichMin, charcount_t ichLim, bool createNode)
{
    PidRefStack* ref = this->PushPidRef(pid);

    if (!createNode)
    {
        return nullptr;
    }

    return CreateSpecialNameNode(pid, ref, ichMin, ichLim);
}

ParseNodeVar * Parser::CreateSpecialVarDeclIfNeeded(ParseNodeFnc * pnodeFnc, IdentPtr pid, bool forceCreate)
{
    Assert(pid != nullptr);

    PidRefStack* ref = pid->GetTopRef();

    // If the function has a reference to pid or we set forceCreate, make a special var decl
    if (forceCreate || (ref && ref->GetScopeId() >= m_currentBlockInfo->pnodeBlock->blockId))
    {
        return this->CreateSpecialVarDeclNode(pnodeFnc, pid);
    }

    return nullptr;
}

void Parser::CreateSpecialSymbolDeclarations(ParseNodeFnc * pnodeFnc)
{
    // Lambda function cannot have any special bindings.
    if (pnodeFnc->IsLambda())
    {
        return;
    }

    bool isTopLevelEventHandler = (this->m_grfscr & fscrImplicitThis) && !pnodeFnc->IsNested();

    // Create a 'this' symbol for non-lambda functions with references to 'this', and all class constructors and top level event hanlders.
    ParseNodePtr varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._this, pnodeFnc->IsClassConstructor() || isTopLevelEventHandler);
    if (varDeclNode)
    {
        varDeclNode->AsParseNodeVar()->sym->SetIsThis(true);

        if (pnodeFnc->IsDerivedClassConstructor())
        {
            varDeclNode->AsParseNodeVar()->sym->SetNeedDeclaration(true);
        }
    }

    // Create a 'new.target' symbol for any ordinary function with a reference and all class constructors.
    varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._newTarget, pnodeFnc->IsClassConstructor());
    if (varDeclNode)
    {
        varDeclNode->AsParseNodeVar()->sym->SetIsNewTarget(true);
    }

    // Create a 'super' (as a reference) symbol.
    varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._super);
    if (varDeclNode)
    {
        varDeclNode->AsParseNodeVar()->sym->SetIsSuper(true);
    }

    // Create a 'super' (as the call target for super()) symbol only for derived class constructors.
        varDeclNode = CreateSpecialVarDeclIfNeeded(pnodeFnc, wellKnownPropertyPids._superConstructor);
        if (varDeclNode)
        {
            varDeclNode->AsParseNodeVar()->sym->SetIsSuperConstructor(true);
        }
    }

void Parser::FinishParseBlock(ParseNodeBlock *pnodeBlock, bool needScanRCurly)
{
    Assert(m_currentBlockInfo != nullptr && pnodeBlock == m_currentBlockInfo->pnodeBlock);

    if (needScanRCurly)
    {
        // Only update the ichLim if we were expecting an RCurly. If there is an
        // expression body without a necessary RCurly, the correct ichLim will
        // have been set already.
        pnodeBlock->ichLim = this->GetScanner()->IchLimTok();
    }

    BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);

    PopStmt(&m_currentBlockInfo->pstmt);

    PopBlockInfo();

    Scope *scope = pnodeBlock->scope;
    if (scope)
    {
        PopScope(scope);
    }
}

void Parser::FinishParseFncExprScope(ParseNodeFnc * pnodeFnc, ParseNodeBlock * pnodeFncExprScope)
{
    int fncExprScopeId = pnodeFncExprScope->blockId;
    ParseNodePtr pnodeName = pnodeFnc->pnodeName;
    if (pnodeName)
    {
        Assert(pnodeName->nop == knopVarDecl);
        BindPidRefsInScope(pnodeName->AsParseNodeVar()->pid, pnodeName->AsParseNodeVar()->sym, fncExprScopeId, m_nextBlockId - 1);
    }
    FinishParseBlock(pnodeFncExprScope);
}

template <const bool backgroundPidRef>
void Parser::BindPidRefs(BlockInfoStack *blockInfo, uint maxBlockId)
{
    // We need to bind all assignments in order to emit assignment to 'const' error
    int blockId = blockInfo->pnodeBlock->blockId;

    Scope *scope = blockInfo->pnodeBlock->scope;
    if (scope)
    {
        auto bindPidRefs = [blockId, maxBlockId, this](Symbol *sym)
        {
            ParseNodePtr pnode = sym->GetDecl();
            IdentPtr pid;
#if PROFILE_DICTIONARY
            int depth = 0;
#endif
            Assert(pnode);
            switch (pnode->nop)
            {
            case knopVarDecl:
            case knopLetDecl:
            case knopConstDecl:
                pid = pnode->AsParseNodeVar()->pid;
                if (backgroundPidRef)
                {
                    pid = this->GetHashTbl()->FindExistingPid(pid->Psz(), pid->Psz() + pid->Cch(), pid->Cch(), pid->Hash(), nullptr, nullptr
#if PROFILE_DICTIONARY
                        , depth
#endif
                    );
                    if (pid == nullptr)
                    {
                        break;
                    }
                }
                this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
                break;
            case knopName:
                pid = pnode->AsParseNodeName()->pid;
                if (backgroundPidRef)
                {
                    pid = this->GetHashTbl()->FindExistingPid(pid->Psz(), pid->Psz() + pid->Cch(), pid->Cch(), pid->Hash(), nullptr, nullptr
#if PROFILE_DICTIONARY
                        , depth
#endif
                    );
                    if (pid == nullptr)
                    {
                        break;
                    }
                }
                this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
                break;
            default:
                Assert(0);
                break;
            }
        };

        scope->ForEachSymbol(bindPidRefs);
    }
}

void Parser::BindPidRefsInScope(IdentPtr pid, Symbol *sym, int blockId, uint maxBlockId)
{
    PidRefStack *ref, *nextRef, *lastRef = nullptr;
    Js::LocalFunctionId funcId = GetCurrentFunctionNode()->functionId;
    Assert(sym);

    if (pid->GetIsModuleExport() && IsTopLevelModuleFunc())
    {
        sym->SetIsModuleExportStorage(true);
    }

    bool hasFuncAssignment = sym->GetHasFuncAssignment();
    bool doesEscape = false;

    for (ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = nextRef)
    {
        // Fix up sym* on PID ref.
        Assert(!ref->GetSym() || ref->GetSym() == sym);
        nextRef = ref->prev;
        Assert(ref->GetScopeId() >= 0);
        if ((uint)ref->GetScopeId() > maxBlockId)
        {
            lastRef = ref;
            continue;
        }
        ref->SetSym(sym);
        this->RemovePrevPidRef(pid, lastRef);

        if (ref->IsUsedInLdElem())
        {
            sym->SetIsUsedInLdElem(true);
        }

        if (ref->IsAssignment())
        {
            sym->PromoteAssignmentState();
            if (sym->GetIsFormal())
            {
                GetCurrentFunctionNode()->SetHasAnyWriteToFormals(true);
            }
        }

        if (ref->GetFuncScopeId() != funcId && !sym->GetIsGlobal() && !sym->GetIsModuleExportStorage())
        {
            Assert(ref->GetFuncScopeId() > funcId);
            sym->SetHasNonLocalReference();
            if (ref->IsDynamicBinding())
            {
                sym->SetNeedsScopeObject();
            }
        }

        if (ref->IsFuncAssignment())
        {
            hasFuncAssignment = true;
        }

        if (ref->IsEscape())
        {
            doesEscape = true;
        }

        if (m_currentNodeFunc && doesEscape && hasFuncAssignment)
        {
            if (m_sourceContextInfo ?
                !PHASE_OFF_RAW(Js::DisableStackFuncOnDeferredEscapePhase, m_sourceContextInfo->sourceContextId, m_currentNodeFunc->functionId) :
                !PHASE_OFF1(Js::DisableStackFuncOnDeferredEscapePhase))
            {
                m_currentNodeFunc->SetNestedFuncEscapes();
            }
        }

        if (ref->GetScopeId() == blockId)
        {
            break;
        }
    }
}

void Parser::MarkEscapingRef(ParseNodePtr pnode, IdentToken *pToken)
{
    if (m_currentNodeFunc == nullptr)
    {
        return;
    }
    if (pnode && pnode->nop == knopFncDecl)
    {
        this->SetNestedFuncEscapes();
    }
    else if (pToken->pid)
    {
        PidRefStack *pidRef = pToken->pid->GetTopRef();
        if (pidRef->sym)
        {
            if (pidRef->sym->GetSymbolType() == STFunction)
            {
                this->SetNestedFuncEscapes();
            }
        }
        else
        {
            pidRef->isEscape = true;
        }
    }
}

void Parser::SetNestedFuncEscapes() const
{
    if (m_sourceContextInfo ?
        !PHASE_OFF_RAW(Js::DisableStackFuncOnDeferredEscapePhase, m_sourceContextInfo->sourceContextId, m_currentNodeFunc->functionId) :
        !PHASE_OFF1(Js::DisableStackFuncOnDeferredEscapePhase))
    {
        m_currentNodeFunc->SetNestedFuncEscapes();
    }
}

void Parser::PopStmt(StmtNest *pStmt)
{
    Assert(pStmt == m_pstmtCur);
    SetCurrentStatement(m_pstmtCur->pstmtOuter);
}

BlockInfoStack *Parser::PushBlockInfo(ParseNodeBlock * pnodeBlock)
{
    BlockInfoStack *newBlockInfo = (BlockInfoStack *)m_nodeAllocator.Alloc(sizeof(BlockInfoStack));
    Assert(nullptr != newBlockInfo);

    newBlockInfo->pnodeBlock = pnodeBlock;
    newBlockInfo->pBlockInfoOuter = m_currentBlockInfo;
    newBlockInfo->m_ppnodeLex = &pnodeBlock->pnodeLexVars;

    if (pnodeBlock->blockType != PnodeBlockType::Regular)
    {
        newBlockInfo->pBlockInfoFunction = newBlockInfo;
    }
    else
    {
        Assert(m_currentBlockInfo);
        newBlockInfo->pBlockInfoFunction = m_currentBlockInfo->pBlockInfoFunction;
    }

    m_currentBlockInfo = newBlockInfo;
    return newBlockInfo;
}

void Parser::PopBlockInfo()
{
    Assert(m_currentBlockInfo);
    PopDynamicBlock();
    m_currentBlockInfo = m_currentBlockInfo->pBlockInfoOuter;
}

void Parser::PushDynamicBlock()
{
    Assert(GetCurrentBlock());
    int blockId = GetCurrentBlock()->blockId;
    if (m_currentDynamicBlock && m_currentDynamicBlock->id == blockId)
    {
        return;
    }
    BlockIdsStack *info = (BlockIdsStack *)m_nodeAllocator.Alloc(sizeof(BlockIdsStack));
    if (nullptr == info)
    {
        Error(ERRnoMemory);
    }

    info->id = blockId;
    info->prev = m_currentDynamicBlock;
    m_currentDynamicBlock = info;
}

void Parser::PopDynamicBlock()
{
    int blockId = GetCurrentDynamicBlockId();
    if (GetCurrentBlock()->blockId != blockId || blockId == -1)
    {
        return;
    }
    Assert(m_currentDynamicBlock);

    this->GetHashTbl()->VisitPids([&](IdentPtr pid) {
        for (PidRefStack *ref = pid->GetTopRef(); ref && ref->GetScopeId() >= blockId; ref = ref->prev)
        {
            ref->SetDynamicBinding();
        }
    });

    m_currentDynamicBlock = m_currentDynamicBlock->prev;
}

int Parser::GetCurrentDynamicBlockId() const
{
    return m_currentDynamicBlock ? m_currentDynamicBlock->id : -1;
}

ParseNodeFnc *Parser::GetCurrentFunctionNode()
{
    if (m_currentNodeDeferredFunc != nullptr)
    {
        return m_currentNodeDeferredFunc;
    }
    else if (m_currentNodeFunc != nullptr)
    {
        return m_currentNodeFunc;
    }
    else
    {
        AssertMsg(GetFunctionBlock()->blockType == PnodeBlockType::Global,
            "Most likely we are trying to find a syntax error, related to 'let' or 'const' in deferred parsing mode with disabled support of 'let' and 'const'");
        return m_currentNodeProg;
    }
}

ParseNodeFnc *Parser::GetCurrentNonLambdaFunctionNode()
{
    if (m_currentNodeNonLambdaDeferredFunc != nullptr)
    {
        return m_currentNodeNonLambdaDeferredFunc;
    }
    return m_currentNodeNonLambdaFunc;

}
void Parser::RegisterRegexPattern(UnifiedRegex::RegexPattern *const regexPattern)
{
    Assert(regexPattern);

    // ensure a no-throw add behavior here, to catch out of memory exceptions, using the guest arena allocator
    if (!m_registeredRegexPatterns.PrependNoThrow(m_tempGuestArena->GetAllocator(), regexPattern))
    {
        Parser::Error(ERRnoMemory);
    }
}

void Parser::CaptureState(ParserState *state)
{
    Assert(state != nullptr);

    state->m_funcInArraySave = m_funcInArray;
    state->m_funcInArrayDepthSave = m_funcInArrayDepth;
    state->m_nestedCountSave = *m_pnestedCount;
    state->m_ppnodeScopeSave = m_ppnodeScope;
    state->m_ppnodeExprScopeSave = m_ppnodeExprScope;
    state->m_pCurrentAstSizeSave = m_pCurrentAstSize;
    state->m_nextBlockId = m_nextBlockId;

    Assert(state->m_ppnodeScopeSave == nullptr || *state->m_ppnodeScopeSave == nullptr);
    Assert(state->m_ppnodeExprScopeSave == nullptr || *state->m_ppnodeExprScopeSave == nullptr);

#if DEBUG
    state->m_currentBlockInfo = m_currentBlockInfo;
#endif
}

void Parser::RestoreStateFrom(ParserState *state)
{
    Assert(state != nullptr);
    Assert(state->m_currentBlockInfo == m_currentBlockInfo);

    m_funcInArray = state->m_funcInArraySave;
    m_funcInArrayDepth = state->m_funcInArrayDepthSave;
    *m_pnestedCount = state->m_nestedCountSave;
    m_pCurrentAstSize = state->m_pCurrentAstSizeSave;
    m_nextBlockId = state->m_nextBlockId;

    if (state->m_ppnodeScopeSave != nullptr)
    {
        *state->m_ppnodeScopeSave = nullptr;
    }

    if (state->m_ppnodeExprScopeSave != nullptr)
    {
        *state->m_ppnodeExprScopeSave = nullptr;
    }

    m_ppnodeScope = state->m_ppnodeScopeSave;
    m_ppnodeExprScope = state->m_ppnodeExprScopeSave;
}

void Parser::AddToNodeListEscapedUse(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
    ParseNode * pnodeAdd)
{
    AddToNodeList(ppnodeList, pppnodeLast, pnodeAdd);
    pnodeAdd->SetIsInList();
}

void Parser::AddToNodeList(ParseNode ** ppnodeList, ParseNode *** pppnodeLast,
    ParseNode * pnodeAdd)
{
    Assert(!this->m_deferringAST);
    if (nullptr == *pppnodeLast)
    {
        // should be an empty list
        Assert(nullptr == *ppnodeList);

        *ppnodeList = pnodeAdd;
        *pppnodeLast = ppnodeList;
    }
    else
    {
        //
        Assert(*ppnodeList);
        Assert(**pppnodeLast);

        ParseNode *pnodeT = CreateBinNode(knopList, **pppnodeLast, pnodeAdd);
        **pppnodeLast = pnodeT;
        *pppnodeLast = &pnodeT->AsParseNodeBin()->pnode2;
    }
}

// Check reference to "arguments" that indicates the object may escape.
void Parser::CheckArguments(ParseNodePtr pnode)
{
    if (m_currentNodeFunc && this->NodeIsIdent(pnode, wellKnownPropertyPids.arguments))
    {
        m_currentNodeFunc->SetHasHeapArguments();
    }
}

// Check use of "arguments" that requires instantiation of the object.
void Parser::CheckArgumentsUse(IdentPtr pid, ParseNodeFnc * pnodeFnc)
{
    if (pid == wellKnownPropertyPids.arguments)
    {
        if (pnodeFnc != nullptr && pnodeFnc != m_currentNodeProg)
        {
            pnodeFnc->SetUsesArguments(TRUE);
        }
        else
        {
            m_UsesArgumentsAtGlobal = true;
        }
    }
}

void Parser::CheckStrictModeEvalArgumentsUsage(IdentPtr pid, ParseNodePtr pnode)
{
    if (pid != nullptr)
    {
        // In strict mode, 'eval' / 'arguments' cannot be assigned to.
        if (pid == wellKnownPropertyPids.eval)
        {
            Error(ERREvalUsage, pnode);
        }

        if (pid == wellKnownPropertyPids.arguments)
        {
            Error(ERRArgsUsage, pnode);
        }
    }
}

void Parser::ReduceDeferredScriptLength(size_t chars)
{
    // If we're in deferred mode, subtract the given char count from the total length,
    // and see if this puts us under the deferral threshold.
    if (((m_grfscr & (fscrCanDeferFncParse | fscrWillDeferFncParse)) == (fscrCanDeferFncParse | fscrWillDeferFncParse)) &&
        (
            PHASE_OFF1(Js::DeferEventHandlersPhase) ||
            (m_grfscr & fscrGlobalCode)
            )
        )
    {
        if (m_length > chars)
        {
            m_length -= chars;
        }
        else
        {
            m_length = 0;
        }
        if (m_length < Parser::GetDeferralThreshold(this->m_sourceContextInfo->IsSourceProfileLoaded()))
        {
            // Stop deferring.
            m_grfscr &= ~fscrWillDeferFncParse;
            m_stoppedDeferredParse = TRUE;
        }
    }
}

void Parser::EnsureStackAvailable()
{
    bool isInterrupt = false;
    if (!m_scriptContext->GetThreadContext()->IsStackAvailable(Js::Constants::MinStackCompile, &isInterrupt))
    {
        Error(isInterrupt ? E_ABORT : VBSERR_OutOfStack);
    }
}

void Parser::ThrowNewTargetSyntaxErrForGlobalScope()
{
    // If we are parsing a previously deferred function, we can skip throwing the SyntaxError for `new.target` at global scope.
    // If we are at global scope, we would have thrown a SyntaxError when we did the Upfront parse pass and we would not have
    // deferred the function in order to come back now and reparse it.
    if (m_parseType == ParseType_Deferred)
    {
        return;
    }

    if (GetCurrentNonLambdaFunctionNode() != nullptr)
    {
        return;
    }

    if ((this->m_grfscr & fscrEval) != 0)
    {
        Js::JavascriptFunction * caller = nullptr;
        if (Js::JavascriptStackWalker::GetCaller(&caller, m_scriptContext))
        {
            Js::FunctionBody * callerBody = caller->GetFunctionBody();
            Assert(callerBody);
            if (!callerBody->GetIsGlobalFunc() && !(callerBody->IsLambda() && callerBody->GetEnclosedByGlobalFunc()))
            {
                return;
            }
        }
    }

    Error(ERRInvalidNewTarget);
}

template<bool buildAST>
IdentPtr Parser::ParseMetaProperty(tokens metaParentKeyword, charcount_t ichMin, _Out_opt_ BOOL* pfCanAssign)
{
    AssertMsg(metaParentKeyword == tkNEW, "Only supported for tkNEW parent keywords");
    AssertMsg(this->m_token.tk == tkDot, "We must be currently sitting on the dot after the parent keyword");

    this->GetScanner()->Scan();

    if (this->m_token.tk == tkID && this->m_token.GetIdentifier(this->GetHashTbl()) == this->GetTargetPid())
    {
        ThrowNewTargetSyntaxErrForGlobalScope();
        if (pfCanAssign)
        {
            *pfCanAssign = FALSE;
        }
        return wellKnownPropertyPids._newTarget;
    }
    else
    {
        Error(ERRValidIfFollowedBy, _u("'new.'"), _u("'target'"));
    }
}

template<bool buildAST>
void Parser::ParseNamedImportOrExportClause(ModuleImportOrExportEntryList* importOrExportEntryList, bool isExportClause)
{
    Assert(m_token.tk == tkLCurly);
    Assert(importOrExportEntryList != nullptr);

    this->GetScanner()->Scan();

    while (m_token.tk != tkRCurly && m_token.tk != tkEOF)
    {
        tokens firstToken = m_token.tk;

        if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
        {
            Error(ERRsyntax);
        }

        IdentPtr identifierName = m_token.GetIdentifier(this->GetHashTbl());
        IdentPtr identifierAs = identifierName;
        charcount_t offsetForError = this->GetScanner()->IchMinTok();

        this->GetScanner()->Scan();

        if (m_token.tk == tkID)
        {
            // We have the pattern "IdentifierName as"
            if (wellKnownPropertyPids.as != m_token.GetIdentifier(this->GetHashTbl()))
            {
                Error(ERRsyntax);
            }

            this->GetScanner()->Scan();

            // If we are parsing an import statement, the token after 'as' must be a BindingIdentifier.
            if (!isExportClause)
            {
                ChkCurTokNoScan(tkID, ERRValidIfFollowedBy, _u("'as'"), _u("an identifier."));
            }

            if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
            {
                Error(ERRValidIfFollowedBy, _u("'as'"), _u("an identifier."));
            }

            identifierAs = m_token.GetIdentifier(this->GetHashTbl());

            // Scan to the next token.
            this->GetScanner()->Scan();
        }
        else if (!isExportClause && firstToken != tkID)
        {
            // If we are parsing an import statement and this ImportSpecifier clause did not have
            // 'as ImportedBinding' at the end of it, identifierName must be a BindingIdentifier.
            Error(ERRsyntax);
        }

        if (m_token.tk == tkComma)
        {
            // Consume a trailing comma
            this->GetScanner()->Scan();
        }

        if (isExportClause)
        {
            identifierName->SetIsModuleExport();
            AddModuleImportOrExportEntry(importOrExportEntryList, nullptr, identifierName, identifierAs, nullptr, offsetForError);
        }
        else if (buildAST)
        {
            // The name we will use 'as' this import/export is a binding identifier in import statements.
            CreateModuleImportDeclNode(identifierAs);
            AddModuleImportOrExportEntry(importOrExportEntryList, identifierName, identifierAs, nullptr, nullptr);
        }
    }

    // Final token in a named import or export clause must be a '}'
    ChkCurTokNoScan(tkRCurly, ERRsyntax);
}

IdentPtrList* Parser::GetRequestedModulesList()
{
    return m_currentNodeProg->AsParseNodeModule()->requestedModules;
}

void Parser::VerifyModuleLocalExportEntries()
{
    ModuleImportOrExportEntryList* localExportRecordList = GetModuleLocalExportEntryList();
    if (localExportRecordList != nullptr)
    {
        localExportRecordList->Map([=](ModuleImportOrExportEntry exportEntry) {
            if (exportEntry.pidRefStack!=nullptr)
            {
                if (exportEntry.pidRefStack->GetSym() == nullptr)
                {
                    Error(ERRUndeclaredExportName, exportEntry.offset, exportEntry.localName->Cch(), exportEntry.localName->Psz());
                }
            }
        });
    }
}

ModuleImportOrExportEntryList* Parser::GetModuleImportEntryList()
{
    return m_currentNodeProg->AsParseNodeModule()->importEntries;
}

ModuleImportOrExportEntryList* Parser::GetModuleLocalExportEntryList()
{
    return m_currentNodeProg->AsParseNodeModule()->localExportEntries;
}

ModuleImportOrExportEntryList* Parser::GetModuleIndirectExportEntryList()
{
    return m_currentNodeProg->AsParseNodeModule()->indirectExportEntries;
}

ModuleImportOrExportEntryList* Parser::GetModuleStarExportEntryList()
{
    return m_currentNodeProg->AsParseNodeModule()->starExportEntries;
}

IdentPtrList* Parser::EnsureRequestedModulesList()
{
    if (m_currentNodeProg->AsParseNodeModule()->requestedModules == nullptr)
    {
        m_currentNodeProg->AsParseNodeModule()->requestedModules = Anew(&m_nodeAllocator, IdentPtrList, &m_nodeAllocator);
    }
    return m_currentNodeProg->AsParseNodeModule()->requestedModules;
}

ModuleImportOrExportEntryList* Parser::EnsureModuleImportEntryList()
{
    if (m_currentNodeProg->AsParseNodeModule()->importEntries == nullptr)
    {
        m_currentNodeProg->AsParseNodeModule()->importEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
    }
    return m_currentNodeProg->AsParseNodeModule()->importEntries;
}

ModuleImportOrExportEntryList* Parser::EnsureModuleLocalExportEntryList()
{
    if (m_currentNodeProg->AsParseNodeModule()->localExportEntries == nullptr)
    {
        m_currentNodeProg->AsParseNodeModule()->localExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
    }
    return m_currentNodeProg->AsParseNodeModule()->localExportEntries;
}

ModuleImportOrExportEntryList* Parser::EnsureModuleIndirectExportEntryList()
{
    if (m_currentNodeProg->AsParseNodeModule()->indirectExportEntries == nullptr)
    {
        m_currentNodeProg->AsParseNodeModule()->indirectExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
    }
    return m_currentNodeProg->AsParseNodeModule()->indirectExportEntries;
}

ModuleImportOrExportEntryList* Parser::EnsureModuleStarExportEntryList()
{
    if (m_currentNodeProg->AsParseNodeModule()->starExportEntries == nullptr)
    {
        m_currentNodeProg->AsParseNodeModule()->starExportEntries = Anew(&m_nodeAllocator, ModuleImportOrExportEntryList, &m_nodeAllocator);
    }
    return m_currentNodeProg->AsParseNodeModule()->starExportEntries;
}

void Parser::AddModuleSpecifier(IdentPtr moduleRequest)
{
    IdentPtrList* requestedModulesList = EnsureRequestedModulesList();

    if (!requestedModulesList->Has(moduleRequest))
    {
        requestedModulesList->Prepend(moduleRequest);
    }
}

ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrExportEntryList* importOrExportEntryList, ModuleImportOrExportEntry* importOrExportEntry)
{
    if (importOrExportEntry->exportName != nullptr)
    {
        CheckForDuplicateExportEntry(importOrExportEntry->exportName);
    }

    importOrExportEntryList->Prepend(*importOrExportEntry);

    return importOrExportEntry;
}

ModuleImportOrExportEntry* Parser::AddModuleImportOrExportEntry(ModuleImportOrExportEntryList* importOrExportEntryList, IdentPtr importName, IdentPtr localName, IdentPtr exportName, IdentPtr moduleRequest, charcount_t offsetForError)
{
    ModuleImportOrExportEntry* importOrExportEntry = Anew(&m_nodeAllocator, ModuleImportOrExportEntry);

    importOrExportEntry->importName = importName;
    importOrExportEntry->localName = localName;
    importOrExportEntry->exportName = exportName;
    importOrExportEntry->moduleRequest = moduleRequest;
    importOrExportEntry->pidRefStack = offsetForError == 0 ? nullptr : PushPidRef(localName);
    importOrExportEntry->offset = offsetForError;

    return AddModuleImportOrExportEntry(importOrExportEntryList, importOrExportEntry);
}

void Parser::AddModuleLocalExportEntry(ParseNodePtr varDeclNode)
{
    AssertOrFailFast(varDeclNode->nop == knopVarDecl || varDeclNode->nop == knopLetDecl || varDeclNode->nop == knopConstDecl);

    IdentPtr localName = varDeclNode->AsParseNodeVar()->pid;
    varDeclNode->AsParseNodeVar()->sym->SetIsModuleExportStorage(true);

    AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, localName, nullptr);
}

void Parser::CheckForDuplicateExportEntry(IdentPtr exportName)
{
    if (m_currentNodeProg->AsParseNodeModule()->indirectExportEntries != nullptr)
    {
        CheckForDuplicateExportEntry(m_currentNodeProg->AsParseNodeModule()->indirectExportEntries, exportName);
    }

    if (m_currentNodeProg->AsParseNodeModule()->localExportEntries != nullptr)
    {
       CheckForDuplicateExportEntry(m_currentNodeProg->AsParseNodeModule()->localExportEntries, exportName);
    }
}

void Parser::CheckForDuplicateExportEntry(ModuleImportOrExportEntryList* exportEntryList, IdentPtr exportName)
{
    ModuleImportOrExportEntry* findResult = exportEntryList->Find([&](ModuleImportOrExportEntry exportEntry)
    {
        if (exportName == exportEntry.exportName)
        {
            return true;
        }
        return false;
    });

    if (findResult != nullptr)
    {
        Error(ERRDuplicateExport, exportName->Psz());
    }
}

template<bool buildAST>
void Parser::ParseImportClause(ModuleImportOrExportEntryList* importEntryList, bool parsingAfterComma)
{
    bool parsedNamespaceOrNamedImport = false;

    switch (m_token.tk)
    {
    case tkID:
        // This is the default binding identifier.

        // If we already saw a comma in the import clause, this is a syntax error.
        if (parsingAfterComma)
        {
            Error(ERRsyntax);
        }

        if (buildAST)
        {
            IdentPtr localName = m_token.GetIdentifier(this->GetHashTbl());
            IdentPtr importName = wellKnownPropertyPids._default;

            CreateModuleImportDeclNode(localName);
            AddModuleImportOrExportEntry(importEntryList, importName, localName, nullptr, nullptr);
        }

        break;

    case tkLCurly:
        // This begins a list of named imports.
        ParseNamedImportOrExportClause<buildAST>(importEntryList, false);

        parsedNamespaceOrNamedImport = true;
        break;

    case tkStar:
        // This begins a namespace import clause.
        // "* as ImportedBinding"

        // Token following * must be the identifier 'as'
        this->GetScanner()->Scan();
        if (m_token.tk != tkID || wellKnownPropertyPids.as != m_token.GetIdentifier(this->GetHashTbl()))
        {
            Error(ERRsyntax);
        }

        // Token following 'as' must be a binding identifier.
        this->GetScanner()->Scan();
        ChkCurTokNoScan(tkID, ERRsyntax);

        if (buildAST)
        {
            IdentPtr localName = m_token.GetIdentifier(this->GetHashTbl());
            IdentPtr importName = wellKnownPropertyPids._star;

            CreateModuleImportDeclNode(localName);
            AddModuleImportOrExportEntry(importEntryList, importName, localName, nullptr, nullptr);
        }

        parsedNamespaceOrNamedImport = true;
        break;

    default:
        Error(ERRsyntax);
    }

    this->GetScanner()->Scan();

    if (m_token.tk == tkComma)
    {
        // There cannot be more than one comma in a module import clause.
        // There cannot be a namespace import or named imports list on the left of the comma in a module import clause.
        if (parsingAfterComma || parsedNamespaceOrNamedImport)
        {
            Error(ERRTokenAfter, _u(","), GetTokenString(this->GetScanner()->GetPrevious()));
        }

        this->GetScanner()->Scan();

        ParseImportClause<buildAST>(importEntryList, true);
    }
}

bool Parser::IsImportOrExportStatementValidHere()
{
    ParseNodeFnc * curFunc = GetCurrentFunctionNode();

    // Import must be located in the top scope of the module body.
    return curFunc->nop == knopFncDecl
        && curFunc->IsModule()
        && this->m_currentBlockInfo->pnodeBlock == curFunc->pnodeBodyScope
        && (this->m_grfscr & fscrEvalCode) != fscrEvalCode
        && this->m_tryCatchOrFinallyDepth == 0
        && !this->m_disallowImportExportStmt;
}

bool Parser::IsTopLevelModuleFunc()
{
    ParseNodeFnc * curFunc = GetCurrentFunctionNode();
    return curFunc->nop == knopFncDecl && curFunc->IsModule();
}

template<bool buildAST> ParseNodePtr Parser::ParseImportCall()
{
    this->GetScanner()->Scan();
    ParseNodePtr specifier = ParseExpr<buildAST>(koplCma, nullptr, /* fAllowIn */FALSE, /* fAllowEllipsis */FALSE);
    if (m_token.tk != tkRParen)
    {
        Error(ERRnoRparen);
    }

    this->GetScanner()->Scan();
    return buildAST ? CreateCallNode(knopCall, CreateNodeForOpT<knopImport>(), specifier) : nullptr;
}

template<bool buildAST>
ParseNodePtr Parser::ParseImport()
{
    Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
    Assert(m_token.tk == tkIMPORT);

    RestorePoint parsedImport;
    this->GetScanner()->Capture(&parsedImport);
    this->GetScanner()->Scan();

    // import()
    if (m_token.tk == tkLParen)
    {
        if (!m_scriptContext->GetConfig()->IsESDynamicImportEnabled())
        {
            Error(ERRExperimental);
        }

        ParseNodePtr pnode = ParseImportCall<buildAST>();
        BOOL fCanAssign;
        IdentToken token;
        return ParsePostfixOperators<buildAST>(pnode, TRUE, FALSE, FALSE, TRUE, &fCanAssign, &token);
    }

    this->GetScanner()->SeekTo(parsedImport);

    if (!IsImportOrExportStatementValidHere())
    {
        Error(ERRInvalidModuleImportOrExport);
    }

    // We just parsed an import token. Next valid token is *, {, string constant, or binding identifier.
    this->GetScanner()->Scan();

    if (m_token.tk == tkStrCon)
    {
        // This import declaration has no import clause.
        // "import ModuleSpecifier;"
        if (buildAST)
        {
            AddModuleSpecifier(m_token.GetStr());
        }

        // Scan past the module identifier.
        this->GetScanner()->Scan();
    }
    else
    {
        ModuleImportOrExportEntryList importEntryList(&m_nodeAllocator);

        // Parse the import clause (default binding can only exist before the comma).
        ParseImportClause<buildAST>(&importEntryList);

        // Token following import clause must be the identifier 'from'
        IdentPtr moduleSpecifier = ParseImportOrExportFromClause<buildAST>(true);

        if (buildAST)
        {
            Assert(moduleSpecifier != nullptr);

            AddModuleSpecifier(moduleSpecifier);

            importEntryList.Map([this, moduleSpecifier](ModuleImportOrExportEntry& importEntry) {
                importEntry.moduleRequest = moduleSpecifier;
                AddModuleImportOrExportEntry(EnsureModuleImportEntryList(), &importEntry);
            });
        }

        importEntryList.Clear();
    }

    // Import statement is actually a nop, we hoist all the imported bindings to the top of the module.
    return nullptr;
}

template<bool buildAST>
IdentPtr Parser::ParseImportOrExportFromClause(bool throwIfNotFound)
{
    IdentPtr moduleSpecifier = nullptr;

    if (m_token.tk == tkID && wellKnownPropertyPids.from == m_token.GetIdentifier(this->GetHashTbl()))
    {
        this->GetScanner()->Scan();

        // Token following the 'from' token must be a string constant - the module specifier.
        ChkCurTokNoScan(tkStrCon, ERRsyntax);

        if (buildAST)
        {
            moduleSpecifier = m_token.GetStr();
        }

        this->GetScanner()->Scan();
    }
    else if (throwIfNotFound)
    {
        Error(ERRsyntax);
    }

    return moduleSpecifier;
}

template<bool buildAST>
ParseNodePtr Parser::ParseDefaultExportClause()
{
    Assert(m_token.tk == tkDEFAULT);

    this->GetScanner()->Scan();
    ParseNodePtr pnode = nullptr;
    ushort flags = fFncNoFlgs;

    switch (m_token.tk)
    {
    case tkCLASS:
    {
        if (!m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
        {
            goto LDefault;
        }

        // Before we parse the class itself we need to know if the class has an identifier name.
        // If it does, we'll treat this class as an ordinary class declaration which will bind
        // it to that name. Otherwise the class should parse as a nameless class expression and
        // bind only to the export binding.
        BOOL classHasName = false;
        RestorePoint parsedClass;
        this->GetScanner()->Capture(&parsedClass);
        this->GetScanner()->Scan();

        if (m_token.tk == tkID)
        {
            classHasName = true;
        }

        this->GetScanner()->SeekTo(parsedClass);
        ParseNodeClass * pnodeClass;
        pnode = pnodeClass = ParseClassDecl<buildAST>(classHasName, nullptr, nullptr, nullptr);

        if (buildAST)
        {
            AnalysisAssert(pnode != nullptr);
            Assert(pnode->nop == knopClassDecl);

            pnodeClass->SetIsDefaultModuleExport(true);
        }

        break;
    }
    case tkID:
        // If we parsed an async token, it could either modify the next token (if it is a
        // function token) or it could be an identifier (let async = 0; export default async;).
        // To handle both cases, when we parse an async token we need to keep the parser state
        // and rewind if the next token is not function.
        if (wellKnownPropertyPids.async == m_token.GetIdentifier(this->GetHashTbl()))
        {
            RestorePoint parsedAsync;
            this->GetScanner()->Capture(&parsedAsync);
            this->GetScanner()->Scan();
            if (m_token.tk == tkFUNCTION)
            {
                // Token after async is function, consume the async token and continue to parse the
                // function as an async function.
                flags |= fFncAsync;
                goto LFunction;
            }
            // Token after async is not function, no idea what the async token is supposed to mean
            // so rewind and let the default case handle it.
            this->GetScanner()->SeekTo(parsedAsync);
        }
        goto LDefault;
        break;
    case tkFUNCTION:
    {
    LFunction:
        // We just parsed a function token but we need to figure out if the function
        // has an identifier name or not before we call the helper.
        RestorePoint parsedFunction;
        this->GetScanner()->Capture(&parsedFunction);
        this->GetScanner()->Scan();

        if (m_token.tk == tkStar)
        {
            // If we saw 'function*' that indicates we are going to parse a generator,
            // but doesn't tell us if the generator has an identifier or not.
            // Skip the '*' token for now as it doesn't matter yet.
            this->GetScanner()->Scan();
        }

        // We say that if the function has an identifier name, it is a 'normal' declaration
        // and should create a binding to that identifier as well as one for our default export.
        if (m_token.tk == tkID)
        {
            flags |= fFncDeclaration;
        }
        else
        {
            flags |= fFncNoName;
        }

        // Rewind back to the function token and let the helper handle the parsing.
        this->GetScanner()->SeekTo(parsedFunction);
        pnode = ParseFncDeclCheckScope<buildAST>(flags);

        if (buildAST)
        {
            AnalysisAssert(pnode != nullptr);
            Assert(pnode->nop == knopFncDecl);

            pnode->AsParseNodeFnc()->SetIsDefaultModuleExport(true);
        }
        break;
    }
    default:
    LDefault:
    {
        ParseNodePtr pnodeExpression = ParseExpr<buildAST>();

        // Consider: Can we detect this syntax error earlier?
        if (pnodeExpression && pnodeExpression->nop == knopComma)
        {
            Error(ERRsyntax);
        }

        if (buildAST)
        {
            AnalysisAssert(pnodeExpression != nullptr);

            // Mark this node as the default module export. We need to make sure it is put into the correct
            // module export slot when we emit the node.
            ParseNodeExportDefault * pnodeExportDefault;
            pnode = pnodeExportDefault = CreateNodeForOpT<knopExportDefault>();
            pnode->AsParseNodeExportDefault()->pnodeExpr = pnodeExpression;
        }
        break;
    }
    }

    IdentPtr exportName = wellKnownPropertyPids._default;
    AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, exportName, exportName, nullptr);

    return pnode;
}

template<bool buildAST>
ParseNodePtr Parser::ParseExportDeclaration(bool *needTerminator)
{
    Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());
    Assert(m_token.tk == tkEXPORT);

    if (!IsImportOrExportStatementValidHere())
    {
        Error(ERRInvalidModuleImportOrExport);
    }

    ParseNodePtr pnode = nullptr;
    IdentPtr moduleIdentifier = nullptr;
    tokens declarationType;

    if (needTerminator != nullptr)
    {
        *needTerminator = false;
    }

    // We just parsed an export token. Next valid tokens are *, {, var, let, const, async, function, class, default.
    this->GetScanner()->Scan();

    switch (m_token.tk)
    {
    case tkStar:
    {
        this->GetScanner()->Scan();
        IdentPtr exportName = nullptr;

        if (m_scriptContext->GetConfig()->IsESExportNsAsEnabled())
        {
            // export * as name
            if (m_token.tk == tkID)
            {
                // check for 'as'
                if (wellKnownPropertyPids.as == m_token.GetIdentifier(this->GetHashTbl()))
                {
                    // scan to the next token
                    this->GetScanner()->Scan();

                    // token after as must be an identifier
                    if (!(m_token.IsIdentifier() || m_token.IsReservedWord()))
                    {
                        Error(ERRValidIfFollowedBy, _u("'as'"), _u("an identifier."));
                    }

                    exportName = m_token.GetIdentifier(this->GetHashTbl());
                    
                    // scan to next token
                    this->GetScanner()->Scan();
                }
            }
        }

        // A star token in an export declaration must be followed by a from clause which begins with a token 'from'.
        moduleIdentifier = ParseImportOrExportFromClause<buildAST>(true);

        if (buildAST)
        {
            Assert(moduleIdentifier != nullptr);

            AddModuleSpecifier(moduleIdentifier);

            if (!exportName)
            {
                AddModuleImportOrExportEntry(EnsureModuleStarExportEntryList(), wellKnownPropertyPids._star, nullptr, nullptr, moduleIdentifier);
            }
            else
            {
                CheckForDuplicateExportEntry(exportName);
                AddModuleImportOrExportEntry(EnsureModuleIndirectExportEntryList(), wellKnownPropertyPids._star, nullptr, exportName, moduleIdentifier);
            }
        }

        if (needTerminator != nullptr)
        {
            *needTerminator = true;
        }

        break;
    }

    case tkLCurly:
    {
        ModuleImportOrExportEntryList exportEntryList(&m_nodeAllocator);

        ParseNamedImportOrExportClause<buildAST>(&exportEntryList, true);

        this->GetScanner()->Scan();

        // Export clause may be followed by a from clause.
        moduleIdentifier = ParseImportOrExportFromClause<buildAST>(false);

        if (buildAST)
        {
            if (moduleIdentifier != nullptr)
            {
                AddModuleSpecifier(moduleIdentifier);
            }

            exportEntryList.Map([this, moduleIdentifier](ModuleImportOrExportEntry& exportEntry) {
                if (moduleIdentifier != nullptr)
                {
                    exportEntry.moduleRequest = moduleIdentifier;

                    // We need to swap localname and importname when this is a re-export.
                    exportEntry.importName = exportEntry.localName;
                    exportEntry.localName = nullptr;

                    AddModuleImportOrExportEntry(EnsureModuleIndirectExportEntryList(), &exportEntry);
                }
                else
                {
                    AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), &exportEntry);
                }
            });

            exportEntryList.Clear();
        }
    }

    if (needTerminator != nullptr)
    {
        *needTerminator = true;
    }

    break;

    case tkID:
    {
        IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());

        if (wellKnownPropertyPids.let == pid)
        {
            declarationType = tkLET;
            goto ParseVarDecl;
        }
        if (wellKnownPropertyPids.async == pid && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
        {
            // In module export statements, async token is only valid if it's followed by function.
            // We need to check here because ParseStatement would think 'async = 20' is a var decl.
            RestorePoint parsedAsync;
            this->GetScanner()->Capture(&parsedAsync);
            this->GetScanner()->Scan();
            if (m_token.tk == tkFUNCTION)
            {
                // Token after async is function, rewind to the async token and let ParseStatement handle it.
                this->GetScanner()->SeekTo(parsedAsync);
                goto ParseFunctionDecl;
            }
            // Token after async is not function, it's a syntax error.
        }
        goto ErrorToken;
    }
    case tkVAR:
    case tkLET:
    case tkCONST:
    {
        declarationType = m_token.tk;

    ParseVarDecl:
        this->GetScanner()->Scan();

        pnode = ParseVariableDeclaration<buildAST>(declarationType, this->GetScanner()->IchMinTok());

        if (buildAST)
        {
            ForEachItemInList(pnode, [&](ParseNodePtr item) {
                if (item->nop == knopAsg)
                {
                    Parser::MapBindIdentifier(item, [&](ParseNodePtr subItem)
                    {
                        AddModuleLocalExportEntry(subItem);
                    });
                }
                else
                {
                    AddModuleLocalExportEntry(item);
                }
            });
        }
    }
    break;

    case tkFUNCTION:
    case tkCLASS:
    {
    ParseFunctionDecl:
        pnode = ParseStatement<buildAST>();

        if (buildAST)
        {
            IdentPtr localName;
            if (pnode->nop == knopClassDecl)
            {
                ParseNodeClass * pnodeClass = pnode->AsParseNodeClass();
                pnodeClass->pnodeDeclName->sym->SetIsModuleExportStorage(true);
                localName = pnodeClass->pnodeName->pid;
            }
            else
            {
                Assert(pnode->nop == knopFncDecl);

                ParseNodeFnc * pnodeFnc = pnode->AsParseNodeFnc();
                pnodeFnc->GetFuncSymbol()->SetIsModuleExportStorage(true);
                localName = pnodeFnc->pid;
            }
            Assert(localName != nullptr);

            AddModuleImportOrExportEntry(EnsureModuleLocalExportEntryList(), nullptr, localName, localName, nullptr);
        }
    }
    break;

    case tkDEFAULT:
    {
        pnode = ParseDefaultExportClause<buildAST>();
    }
    break;

    default:
    {
    ErrorToken:
        Error(ERRsyntax);
    }
    }

    return pnode;
}

/***************************************************************************
Parse an expression term.
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
    LPCOLESTR pNameHint,
    uint32 *pHintLength,
    uint32 *pShortNameOffset,
    _Inout_opt_ IdentToken* pToken /*= nullptr*/,
    bool fUnaryOrParen /*= false*/,
    BOOL fCanAssignToCall /*= TRUE*/,
    _Out_opt_ BOOL* pfCanAssign /*= nullptr*/,
    _Inout_opt_ BOOL* pfLikelyPattern /*= nullptr*/,
    _Out_opt_ bool* pfIsDotOrIndex /*= nullptr*/,
    _Inout_opt_ charcount_t *plastRParen /*= nullptr*/)
{
    ParseNodePtr pnode = nullptr;
    PidRefStack *savedTopAsyncRef = nullptr;
    charcount_t ichMin = 0;
    charcount_t ichLim = 0;
    size_t iecpMin = 0;
    size_t iecpLim = 0;
    size_t iuMin;
    IdentToken term;
    BOOL fInNew = FALSE;
    BOOL fCanAssign = TRUE;
    bool isAsyncExpr = false;
    bool isLambdaExpr = false;
    bool isSpecialName = false;
    IdentPtr pid = nullptr;
    Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially

    PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackParseOneTerm);

    switch (m_token.tk)
    {
    case tkID:
    {
        pid = m_token.GetIdentifier(this->GetHashTbl());
        ichMin = this->GetScanner()->IchMinTok();
        iecpMin = this->GetScanner()->IecpMinTok();
        ichLim = this->GetScanner()->IchLimTok();
        iecpLim = this->GetScanner()->IecpLimTok();

        if (pid == wellKnownPropertyPids.async &&
            m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
        {
            isAsyncExpr = true;
        }

        // Put this into a block to avoid previousAwaitIsKeyword being not initialized after jump to LIdentifier
        {
            bool previousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(isAsyncExpr);
            this->GetScanner()->Scan();
            this->GetScanner()->SetAwaitIsKeywordRegion(previousAwaitIsKeyword);
        }

        // We search for an Async expression (a function declaration or an async lambda expression)
        if (isAsyncExpr && !this->GetScanner()->FHadNewLine())
        {
            if (m_token.tk == tkFUNCTION)
            {
                goto LFunction;
            }
            else if (m_token.tk == tkID || m_token.tk == tkAWAIT)
            {
                isLambdaExpr = true;
                goto LFunction;
            }
            else if (m_token.tk == tkLParen)
            {
                // This is potentially an async arrow function. Save the state of the async references
                // in case it needs to be restored. (Note that the case of a single parameter with no ()'s
                // is detected upstream and need not be handled here.)
                savedTopAsyncRef = pid->GetTopRef();
            }
        }

        CheckArgumentsUse(pid, GetCurrentFunctionNode());

        // Assume this pid is not special - overwrite when we parse a special name
        isSpecialName = false;

    LIdentifier:
        PidRefStack * ref = nullptr;

        // Don't push a reference if this is a single lambda parameter, because we'll reparse with
        // a correct function ID.
        if (m_token.tk != tkDArrow)
        {
            ref = this->PushPidRef(pid);
        }

        if (buildAST)
        {
            if (isSpecialName)
            {
                pnode = CreateSpecialNameNode(pid, ref, ichMin, ichLim);
            }
            else
            {
                pnode = CreateNameNode(pid, ref, ichMin, ichLim);
            }
        }
        else
        {
            // Remember the identifier start and end in case it turns out to be a statement label.
            term.tk = tkID;
            term.pid = pid; // Record the identifier for detection of eval
            term.ichMin = static_cast<charcount_t>(iecpMin);
            term.ichLim = static_cast<charcount_t>(iecpLim);
        }
        break;
    }

    case tkSUPER:
        ichMin = this->GetScanner()->IchMinTok();
        iecpMin = this->GetScanner()->IecpMinTok();
        ichLim = this->GetScanner()->IchLimTok();
        iecpLim = this->GetScanner()->IecpLimTok();

        if (!m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
        {
            goto LUnknown;
        }

        this->GetScanner()->Scan();

        pid = ParseSuper<buildAST>(!!fAllowCall);
        isSpecialName = true;

        // Super reference and super call need to push a pid ref to 'this' even when not building an AST
        ReferenceSpecialName(wellKnownPropertyPids._this, ichMin, ichLim);
        // Super call needs to reference 'new.target'
        if (pid == wellKnownPropertyPids._superConstructor)
        {
            // super() will write to "this", so track the assignment.
            PidRefStack *thisRef = wellKnownPropertyPids._this->GetTopRef();
            thisRef->isAsg = true;
            ReferenceSpecialName(wellKnownPropertyPids._newTarget, ichMin, ichLim);
        }

        goto LIdentifier;

    case tkTHIS:
        ichMin = this->GetScanner()->IchMinTok();
        iecpMin = this->GetScanner()->IecpMinTok();
        ichLim = this->GetScanner()->IchLimTok();
        iecpLim = this->GetScanner()->IecpLimTok();

        pid = wellKnownPropertyPids._this;

        this->GetScanner()->Scan();
        isSpecialName = true;

        goto LIdentifier;

    case tkLParen:
    {
        ichMin = this->GetScanner()->IchMinTok();
        iuMin = this->GetScanner()->IecpMinTok();

        // If we are undeferring a function which has deferred stubs, we can check to see if the next deferred stub
        // is a lambda at the current character. If it is, we know this LParen is the beginning of a lambda nested
        // function and we can avoid parsing the next series of tokens as a parenthetical expression and reparsing
        // after finding the => token.
        if (buildAST && m_currDeferredStub != nullptr && GetCurrentFunctionNode() != nullptr && GetCurrentFunctionNode()->nestedCount < m_currDeferredStubCount)
        {
            DeferredFunctionStub* stub = m_currDeferredStub + GetCurrentFunctionNode()->nestedCount;
            if (stub->ichMin == ichMin)
            {
                Assert((stub->fncFlags & kFunctionIsLambda) == kFunctionIsLambda);

                pnode = ParseFncDeclCheckScope<true>(fFncLambda);
                break;
            }
        }

        this->GetScanner()->Scan();
        if (m_token.tk == tkRParen)
        {
            // Empty parens can only be legal as an empty parameter list to a lambda declaration.
            // We're in a lambda if the next token is =>.
            fAllowCall = FALSE;
            this->GetScanner()->Scan();

            // If the token after the right paren is not => or if there was a newline between () and => this is a syntax error
            if (!IsDoingFastScan() && (m_token.tk != tkDArrow || this->GetScanner()->FHadNewLine()))
            {
                Error(ERRValidIfFollowedBy, _u("Lambda parameter list"), _u("'=>' on the same line"));
            }

            if (buildAST)
            {
                pnode = CreateNodeForOpT<knopEmpty>();
            }
            break;
        }

        // Advance the block ID here in case this parenthetical expression turns out to be a lambda parameter list.
        // That way the pid ref stacks will be created in their correct final form, and we can simply fix
        // up function ID's.
        uint saveNextBlockId = m_nextBlockId;
        uint saveCurrBlockId = GetCurrentBlock()->blockId;
        GetCurrentBlock()->blockId = m_nextBlockId++;

        AutoDeferErrorsRestore deferErrorRestore(this);

        this->m_funcParenExprDepth++;
        pnode = ParseExpr<buildAST>(koplNo, &fCanAssign, TRUE, FALSE, nullptr, nullptr /*nameLength*/, nullptr  /*pShortNameOffset*/, &term, true, nullptr, plastRParen);
        this->m_funcParenExprDepth--;

        if (buildAST && plastRParen)
        {
            *plastRParen = this->GetScanner()->IchLimTok();
        }

        ChkCurTok(tkRParen, ERRnoRparen);

        GetCurrentBlock()->blockId = saveCurrBlockId;
        if (m_token.tk == tkDArrow)
        {
            // We're going to rewind and reinterpret the expression as a parameter list.
            // Put back the original next-block-ID so the existing pid ref stacks will be correct.
            m_nextBlockId = saveNextBlockId;
        }
        else
        {
            // Emit a deferred ... error if one was parsed.
            if (m_deferEllipsisError)
            {
                this->GetScanner()->SeekTo(m_deferEllipsisErrorLoc);
                Error(ERRInvalidSpreadUse);
            }
            else if (m_deferCommaError)
            {
                // Emit a comma error if that was deferred.
                this->GetScanner()->SeekTo(m_deferCommaErrorLoc);
                Error(ERRsyntax);
            }
        }

        break;
    }

    case tkIntCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        if (buildAST)
        {
            pnode = CreateIntNode(m_token.GetLong());
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkBigIntCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        if (buildAST)
        {
            pnode = CreateBigIntNode(m_token.GetBigInt());
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkFltCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        if (buildAST)
        {
            ParseNodeFloat * pnodeFloat;
            pnode = pnodeFloat = CreateNodeForOpT<knopFlt>();
            pnodeFloat->dbl = m_token.GetDouble();
            pnodeFloat->maybeInt = m_token.GetDoubleMayBeInt();
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkStrCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        if (buildAST)
        {
            pnode = CreateStrNode(m_token.GetStr());
        }
        else
        {
            // Subtract the string literal length from the total char count for the purpose
            // of deciding whether to defer parsing and byte code generation.
            this->ReduceDeferredScriptLength(this->GetScanner()->IchLimTok() - this->GetScanner()->IchMinTok());
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkTRUE:
        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopTrue>();
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkFALSE:
        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopFalse>();
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkNULL:
        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopNull>();
        }
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkDiv:
    case tkAsgDiv:
        pnode = ParseRegExp<buildAST>();
        fCanAssign = FALSE;
        this->GetScanner()->Scan();
        break;

    case tkNEW:
    {
        ichMin = this->GetScanner()->IchMinTok();
        iecpMin = this->GetScanner()->IecpMinTok();
        this->GetScanner()->Scan();

        if (m_token.tk == tkDot && m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
        {
            pid = ParseMetaProperty<buildAST>(tkNEW, ichMin, &fCanAssign);

            ichLim = this->GetScanner()->IchLimTok();
            iecpLim = this->GetScanner()->IecpLimTok();

            this->GetScanner()->Scan();
            isSpecialName = true;

            goto LIdentifier;
        }
        else
        {
            ParseNodePtr pnodeExpr = ParseTerm<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset, nullptr, false, TRUE, nullptr, nullptr, nullptr, plastRParen);
            if (buildAST)
            {
                pnode = CreateCallNode(knopNew, pnodeExpr, nullptr);
                pnode->ichMin = ichMin;
            }
            fInNew = TRUE;
            fCanAssign = FALSE;
        }
        break;
    }

    case tkLBrack:
    {
        ichMin = this->GetScanner()->IchMinTok();
        this->GetScanner()->Scan();
        pnode = ParseArrayLiteral<buildAST>();
        if (buildAST)
        {
            pnode->ichMin = ichMin;
            pnode->ichLim = this->GetScanner()->IchLimTok();
        }

        if (this->m_arrayDepth == 0)
        {
            Assert(this->GetScanner()->IchLimTok() - ichMin > m_funcInArray);
            this->ReduceDeferredScriptLength(this->GetScanner()->IchLimTok() - ichMin - this->m_funcInArray);
            this->m_funcInArray = 0;
            this->m_funcInArrayDepth = 0;
        }
        ChkCurTok(tkRBrack, ERRnoRbrack);
        if (!IsES6DestructuringEnabled())
        {
            fCanAssign = FALSE;
        }
        else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
        {
            *pfLikelyPattern = TRUE;
        }
        break;
    }

    case tkLCurly:
    {
        ichMin = this->GetScanner()->IchMinTok();
        this->GetScanner()->ScanForcingPid();
        ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(pNameHint, pHintLength);
        if (buildAST)
        {
            pnode = CreateUniNode(knopObject, pnodeMemberList);
            pnode->ichMin = ichMin;
            pnode->ichLim = this->GetScanner()->IchLimTok();
        }
        ChkCurTok(tkRCurly, ERRnoRcurly);
        if (!IsES6DestructuringEnabled())
        {
            fCanAssign = FALSE;
        }
        else if (pfLikelyPattern != nullptr && !IsPostFixOperators())
        {
            *pfLikelyPattern = TRUE;
        }
        break;
    }

    case tkFUNCTION:
    {
    LFunction:
        if (m_grfscr & fscrDeferredFncExpression)
        {
            // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
            // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
            // first time we see it.
            //
            // Normally, deferred functions will be parsed in ParseStatement upon encountering the 'function' token. The first
            // token of the source code of the function may not a 'function' token though, so we still need to reset this flag
            // for the first function we parse. This can happen in compat modes, for instance, for a function expression enclosed
            // in parentheses, where the legacy behavior was to include the parentheses in the function's source code.
            m_grfscr &= ~fscrDeferredFncExpression;
        }
        ushort flags = fFncNoFlgs;
        if (isLambdaExpr)
        {
            flags |= fFncLambda;
        }
        if (isAsyncExpr)
        {
            flags |= fFncAsync;
        }
        pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, pNameHint, /* needsPIDOnRCurlyScan */ false, fUnaryOrParen);
        if (isAsyncExpr)
        {
            pnode->AsParseNodeFnc()->cbStringMin = iecpMin;
        }
        fCanAssign = FALSE;
        break;
    }

    case tkCLASS:
        if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
        {
            pnode = ParseClassDecl<buildAST>(FALSE, pNameHint, pHintLength, pShortNameOffset);
        }
        else
        {
            goto LUnknown;
        }
        fCanAssign = FALSE;
        break;

    case tkStrTmplBasic:
    case tkStrTmplBegin:
        pnode = ParseStringTemplateDecl<buildAST>(nullptr);
        fCanAssign = FALSE;
        break;

    case tkIMPORT:
        if (m_scriptContext->GetConfig()->IsES6ModuleEnabled() && m_scriptContext->GetConfig()->IsESDynamicImportEnabled())
        {
            if (!fAllowCall)
            {
                Error(ERRTokenAfter, _u("import"), _u("new"));
            }
            this->GetScanner()->Scan();
            ChkCurTokNoScan(tkLParen, ERRnoLparen);
            pnode = ParseImportCall<buildAST>();
        }
        else
        {
            goto LUnknown;
        }
        break;

#if ENABLE_BACKGROUND_PARSING
    case tkCASE:
    {
        if (!m_doingFastScan)
        {
            goto LUnknown;
        }
        ParseNodePtr pnodeUnused;
        pnode = ParseCase<buildAST>(&pnodeUnused);
        break;
    }

    case tkELSE:
        if (!m_doingFastScan)
        {
            goto LUnknown;
        }
        this->GetScanner()->Scan();
        ParseStatement<buildAST>();
        break;
#endif

    default:
    LUnknown:
        if (m_token.tk == tkNone)
        {
            Error(ERRInvalidIdentifier, m_token.GetIdentifier(this->GetHashTbl())->Psz(), GetTokenString(GetScanner()->GetPrevious()));
        }
        else if (m_token.IsKeyword())
        {
            Error(ERRKeywordAfter, GetTokenString(m_token.tk), GetTokenString(GetScanner()->GetPrevious()));
        }
        else
        {
            Error(ERRTokenAfter, GetTokenString(m_token.tk), GetTokenString(GetScanner()->GetPrevious()));
        }
        break;
    }

    pnode = ParsePostfixOperators<buildAST>(pnode, fAllowCall, fInNew, isAsyncExpr, fCanAssignToCall, &fCanAssign, &term, pfIsDotOrIndex);

    if (savedTopAsyncRef != nullptr &&
        this->m_token.tk == tkDArrow)
    {
        // This is an async arrow function; we're going to back up and reparse it.
        // Make sure we don't leave behind a bogus reference to the 'async' identifier.
        for (pid = wellKnownPropertyPids.async; pid->GetTopRef() != savedTopAsyncRef;)
        {
            Assert(pid->GetTopRef() != nullptr);
            pid->RemovePrevPidRef(nullptr);
        }
    }

    // Pass back identifier if requested
    if (pToken && term.tk == tkID)
    {
        *pToken = term;
    }

    if (pfCanAssign)
    {
        *pfCanAssign = fCanAssign;
    }

    return pnode;
}

template <bool buildAST>
ParseNodeRegExp * Parser::ParseRegExp()
{
    ParseNodeRegExp * pnode = nullptr;

    if (buildAST || IsDoingFastScan())
    {
        this->GetScanner()->RescanRegExp();

#if ENABLE_BACKGROUND_PARSING
        BOOL saveDeferringAST = this->m_deferringAST;
        if (m_doingFastScan)
        {
            this->m_deferringAST = false;
        }
#endif
        pnode = CreateNodeForOpT<knopRegExp>();
        pnode->regexPattern = m_token.GetRegex();
#if ENABLE_BACKGROUND_PARSING
        if (m_doingFastScan)
        {
            this->m_deferringAST = saveDeferringAST;
            this->AddFastScannedRegExpNode(pnode);
            if (!buildAST)
            {
                pnode = nullptr;
            }
        }
        else if (this->IsBackgroundParser())
        {
            Assert(pnode->regexPattern == nullptr);
            this->AddBackgroundRegExpNode(pnode);
        }
#endif
    }
    else
    {
        this->GetScanner()->RescanRegExpNoAST();
    }
    Assert(m_token.tk == tkRegExp);

    return pnode;
}

BOOL Parser::NodeIsEvalName(ParseNodePtr pnode)
{
    //WOOB 1107758 Special case of indirect eval binds to local scope in standards mode
    return pnode->nop == knopName && (pnode->AsParseNodeName()->pid == wellKnownPropertyPids.eval);
}

BOOL Parser::NodeIsSuperName(ParseNodePtr pnode)
{
    return pnode->nop == knopName && (pnode->AsParseNodeName()->pid == wellKnownPropertyPids._superConstructor);
}

BOOL Parser::NodeEqualsName(ParseNodePtr pnode, LPCOLESTR sz, uint32 cch)
{
    return pnode->nop == knopName &&
        pnode->AsParseNodeName()->pid->Cch() == cch &&
        !wmemcmp(pnode->AsParseNodeName()->pid->Psz(), sz, cch);
}

BOOL Parser::NodeIsIdent(ParseNodePtr pnode, IdentPtr pid)
{
    for (;;)
    {
        switch (pnode->nop)
        {
        case knopName:
            return (pnode->AsParseNodeName()->pid == pid);

        case knopComma:
            pnode = pnode->AsParseNodeBin()->pnode2;
            break;

        default:
            return FALSE;
        }
    }
}

template<bool buildAST>
ParseNodePtr Parser::ParsePostfixOperators(
    ParseNodePtr pnode,
    BOOL fAllowCall,
    BOOL fInNew,
    BOOL isAsyncExpr,
    BOOL fCanAssignToCallResult,
    BOOL *pfCanAssign,
    _Inout_ IdentToken* pToken,
    _Out_opt_ bool* pfIsDotOrIndex /*= nullptr */)
{
    uint16 count = 0;
    bool callOfConstants = false;
    if (pfIsDotOrIndex)
    {
        *pfIsDotOrIndex = false;
    }

    for (;;)
    {
        uint16 spreadArgCount = 0;
        switch (m_token.tk)
        {
        case tkLParen:
        {
            AutoMarkInParsingArgs autoMarkInParsingArgs(this);

            if (fInNew)
            {
                ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
                if (buildAST)
                {
                    Assert(pnode->nop == knopNew);
                    Assert(pnode->AsParseNodeCall()->pnodeArgs == nullptr);
                    pnode->AsParseNodeCall()->pnodeArgs = pnodeArgs;
                    pnode->AsParseNodeCall()->callOfConstants = callOfConstants;
                    pnode->AsParseNodeCall()->isApplyCall = false;
                    pnode->AsParseNodeCall()->isEvalCall = false;
                    pnode->AsParseNodeCall()->isSuperCall = false;
                    pnode->AsParseNodeCall()->hasDestructuring = m_hasDestructuringPattern;
                    Assert(!m_hasDestructuringPattern || count > 0);
                    pnode->AsParseNodeCall()->argCount = count;
                    pnode->AsParseNodeCall()->spreadArgCount = spreadArgCount;
                    pnode->ichLim = this->GetScanner()->IchLimTok();
                }
                else
                {
                    pnode = nullptr;
                    pToken->tk = tkNone; // This is no longer an identifier
                }
                fInNew = FALSE;
                ChkCurTok(tkRParen, ERRnoRparen);
            }
            else
            {
                if (!fAllowCall)
                {
                    return pnode;
                }

                uint saveNextBlockId = m_nextBlockId;
                uint saveCurrBlockId = GetCurrentBlock()->blockId;

                if (isAsyncExpr)
                {
                    // Advance the block ID here in case this parenthetical expression turns out to be a lambda parameter list.
                    // That way the pid ref stacks will be created in their correct final form, and we can simply fix
                    // up function ID's.
                    GetCurrentBlock()->blockId = m_nextBlockId++;
                }

                ParseNodePtr pnodeArgs = ParseArgList<buildAST>(&callOfConstants, &spreadArgCount, &count);
                // We used to un-defer a deferred function body here if it was called as part of the expression that declared it.
                // We now detect this case up front in ParseFncDecl, which is cheaper and simpler.
                if (buildAST)
                {
                    bool fCallIsEval = false;

                    // Detect super()
                    if (this->NodeIsSuperName(pnode))
                    {
                        pnode = CreateSuperCallNode(pnode->AsParseNodeSpecialName(), pnodeArgs);
                        Assert(pnode);

                        pnode->AsParseNodeSuperCall()->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnode->ichMin, this->GetScanner()->IchLimTok(), true);
                        pnode->AsParseNodeSuperCall()->pnodeNewTarget = ReferenceSpecialName(wellKnownPropertyPids._newTarget, pnode->ichMin, this->GetScanner()->IchLimTok(), true);
                    }
                    else
                    {
                        pnode = CreateCallNode(knopCall, pnode, pnodeArgs);
                        Assert(pnode);
                    }

                    // Detect call to "eval" and record it on the function.
                    // Note: we used to leave it up to the byte code generator to detect eval calls
                    // at global scope, but now it relies on the flag the parser sets, so set it here.

                    if (count > 0 && this->NodeIsEvalName(pnode->AsParseNodeCall()->pnodeTarget))
                    {
                        this->MarkEvalCaller();
                        fCallIsEval = true;

                        // Eval may reference any of the special symbols so we need to push refs to them here.
                        ReferenceSpecialName(wellKnownPropertyPids._this);
                        ReferenceSpecialName(wellKnownPropertyPids._newTarget);
                        ReferenceSpecialName(wellKnownPropertyPids._super);
                        ReferenceSpecialName(wellKnownPropertyPids._superConstructor);
                        ReferenceSpecialName(wellKnownPropertyPids.arguments);
                    }

                    pnode->AsParseNodeCall()->callOfConstants = callOfConstants;
                    pnode->AsParseNodeCall()->spreadArgCount = spreadArgCount;
                    pnode->AsParseNodeCall()->isApplyCall = false;
                    pnode->AsParseNodeCall()->isEvalCall = fCallIsEval;
                    pnode->AsParseNodeCall()->hasDestructuring = m_hasDestructuringPattern;
                    Assert(!m_hasDestructuringPattern || count > 0);
                    pnode->AsParseNodeCall()->argCount = count;
                    pnode->ichLim = this->GetScanner()->IchLimTok();
                }
                else
                {
                    pnode = nullptr;
                    if (pToken->tk == tkID && pToken->pid == wellKnownPropertyPids.eval && count > 0) // Detect eval
                    {
                        this->MarkEvalCaller();

                        ReferenceSpecialName(wellKnownPropertyPids._this);
                        ReferenceSpecialName(wellKnownPropertyPids._newTarget);
                        ReferenceSpecialName(wellKnownPropertyPids._super);
                        ReferenceSpecialName(wellKnownPropertyPids._superConstructor);
                        ReferenceSpecialName(wellKnownPropertyPids.arguments);
                    }
                    pToken->tk = tkNone; // This is no longer an identifier
                }

                ChkCurTok(tkRParen, ERRnoRparen);

                if (isAsyncExpr)
                {
                    GetCurrentBlock()->blockId = saveCurrBlockId;
                    if (m_token.tk == tkDArrow)
                    {
                        // We're going to rewind and reinterpret the expression as a parameter list.
                        // Put back the original next-block-ID so the existing pid ref stacks will be correct.
                        m_nextBlockId = saveNextBlockId;
                    }
                }
            }
            if (pfCanAssign)
            {
                *pfCanAssign = fCanAssignToCallResult && 
                               (m_sourceContextInfo ?
                                !PHASE_ON_RAW(Js::EarlyErrorOnAssignToCallPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId) :
                                !PHASE_ON1(Js::EarlyErrorOnAssignToCallPhase));
            }
            if (pfIsDotOrIndex)
            {
                *pfIsDotOrIndex = false;
            }
            break;
        }
        case tkLBrack:
        {
            this->GetScanner()->Scan();
            IdentToken tok;
            ParseNodePtr pnodeExpr = ParseExpr<buildAST>(0, FALSE, TRUE, FALSE, nullptr, nullptr, nullptr, &tok);
            if (buildAST)
            {
                AnalysisAssert(pnodeExpr);
                if (pnode && pnode->nop == knopName && pnode->AsParseNodeName()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper)
                {
                    pnode = CreateSuperReferenceNode(knopIndex, pnode->AsParseNodeSpecialName(), pnodeExpr);
                    pnode->AsParseNodeSuperReference()->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnode->ichMin, pnode->ichLim, true);
                }
                else
                {
                    pnode = CreateBinNode(knopIndex, pnode, pnodeExpr);
                }

                AnalysisAssert(pnode);
                pnode->ichLim = this->GetScanner()->IchLimTok();
            }
            else
            {
                pnode = nullptr;
                pToken->tk = tkNone; // This is no longer an identifier
            }
            ChkCurTok(tkRBrack, ERRnoRbrack);
            if (pfCanAssign)
            {
                *pfCanAssign = TRUE;
            }
            if (pfIsDotOrIndex)
            {
                *pfIsDotOrIndex = true;
            }

            PidRefStack * topPidRef = nullptr;
            if (buildAST)
            {
                if (pnodeExpr && pnodeExpr->nop == knopName)
                {
                    topPidRef = pnodeExpr->AsParseNodeName()->pid->GetTopRef();
                }
            }
            else if (tok.tk == tkID)
            {
                topPidRef = tok.pid->GetTopRef();
            }
            if (topPidRef)
            {
                topPidRef->SetIsUsedInLdElem(true);
            }

            if (!buildAST)
            {
                break;
            }

            bool shouldConvertToDot = false;
            if (pnode->AsParseNodeBin()->pnode2->nop == knopStr)
            {
                // if the string is empty or contains escape character, we will not convert them to dot node
                shouldConvertToDot = pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Cch() > 0 && !this->GetScanner()->IsEscapeOnLastTkStrCon();
            }

            if (shouldConvertToDot)
            {
                LPCOLESTR str = pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Psz();
                // See if we can convert o["p"] into o.p and o["0"] into o[0] since they're equivalent and the latter forms
                // are faster
                uint32 uintValue;
                if (Js::JavascriptOperators::TryConvertToUInt32(
                    str,
                    pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Cch(),
                    &uintValue) &&
                    !Js::TaggedInt::IsOverflow(uintValue)) // the optimization is not very useful if the number can't be represented as a TaggedInt
                {
                    // No need to verify that uintValue != JavascriptArray::InvalidIndex since all nonnegative TaggedInts are valid indexes
                    auto intNode = CreateIntNode(uintValue); // implicit conversion from uint32 to int32
                    pnode->AsParseNodeBin()->pnode2 = intNode;
                }
                // Field optimization (see GlobOpt::KillLiveElems) checks for value being a Number,
                // and since NaN/Infinity is a number it won't kill o.NaN/o.Infinity which would cause a problem
                // if we decide to hoist o.NaN/o.Infinity.
                // We need to keep o["NaN"] and o["+/-Infinity"] as array element access (we don't hoist that but we may hoist field access),
                // so no matter if it's killed by o[x] inside a loop, we make sure that we never hoist these.
                // We need to follow same logic for strings that convert to a floating point number.
                else
                {
                    bool doConvertToProperty = false;    // Convert a["x"] -> a.x.
                    if (!Parser::IsNaNOrInfinityLiteral<true>(str))
                    {
                        const OLECHAR* terminalChar;
                        double dbl = Js::NumberUtilities::StrToDbl(str, &terminalChar, m_scriptContext);
                        bool convertsToFloat = !Js::NumberUtilities::IsNan(dbl);
                        doConvertToProperty = !convertsToFloat;
                    }

                    if (doConvertToProperty)
                    {
                        ParseNodeName * pnodeNewExpr = CreateNameNode(pnodeExpr->AsParseNodeStr()->pid);
                        pnodeNewExpr->ichMin = pnodeExpr->ichMin;
                        pnodeNewExpr->ichLim = pnodeExpr->ichLim;
                        pnode->AsParseNodeBin()->pnode2 = pnodeNewExpr;
                        pnode->nop = knopDot;
                        pnode->grfpn |= PNodeFlags::fpnIndexOperator;
                    }
                }
            }
        }
        break;

        case tkDot:
        {
            ParseNodePtr name = nullptr;
            OpCode opCode = knopDot;

            this->GetScanner()->Scan();
            if (!m_token.IsIdentifier())
            {
                //allow reserved words in ES5 mode
                if (!(m_token.IsReservedWord()))
                {
                    IdentifierExpectedError(m_token);
                }
            }
            // Note: see comment above about field optimization WRT NaN/Infinity/-Infinity.
            // Convert a.Nan, a.Infinity into a["NaN"], a["Infinity"].
            // We don't care about -Infinity case here because x.-Infinity is invalid in JavaScript.
            // Both NaN and Infinity are identifiers.
            else if (buildAST && Parser::IsNaNOrInfinityLiteral<false>(m_token.GetIdentifier(this->GetHashTbl())->Psz()))
            {
                opCode = knopIndex;
            }

            if (buildAST)
            {
                if (opCode == knopDot)
                {
                    name = CreateNameNode(m_token.GetIdentifier(this->GetHashTbl()));
                }
                else
                {
                    Assert(opCode == knopIndex);
                    name = CreateStrNode(m_token.GetIdentifier(this->GetHashTbl()));
                }
                if (pnode && pnode->nop == knopName && pnode->AsParseNodeName()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper)
                {
                    pnode = CreateSuperReferenceNode(opCode, pnode->AsParseNodeSpecialName(), name);
                    pnode->AsParseNodeSuperReference()->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnode->ichMin, pnode->ichLim, true);
                }
                else
                {
                    pnode = CreateBinNode(opCode, pnode, name);
                }
            }
            else
            {
                pnode = nullptr;
                pToken->tk = tkNone;
            }

            if (pfCanAssign)
            {
                *pfCanAssign = TRUE;
            }
            if (pfIsDotOrIndex)
            {
                *pfIsDotOrIndex = true;
            }
            this->GetScanner()->Scan();

            break;
        }

        case tkStrTmplBasic:
        case tkStrTmplBegin:
        {
            ParseNode* templateNode = nullptr;
            if (pnode != nullptr)
            {
                AutoMarkInParsingArgs autoMarkInParsingArgs(this);
                templateNode = ParseStringTemplateDecl<buildAST>(pnode);
            }
            else
            {
                templateNode = ParseStringTemplateDecl<buildAST>(pnode);
            }

            if (!buildAST)
            {
                pToken->tk = tkNone; // This is no longer an identifier
            }

            pnode = templateNode;
            if (pfCanAssign)
            {
                *pfCanAssign = FALSE;
            }
            if (pfIsDotOrIndex)
            {
                *pfIsDotOrIndex = false;
            }
            break;
        }
        default:
            return pnode;
        }
    }
}

/***************************************************************************
Look for an existing label with the given name.
***************************************************************************/
bool Parser::LabelExists(IdentPtr pid, LabelId* pLabelIdList)
{
    StmtNest dummy;
    dummy.pLabelId = pLabelIdList;
    dummy.pstmtOuter = m_pstmtCur;

    // Look through each label list for the current stack of statements
    for (StmtNest* pStmt = &dummy; pStmt != nullptr; pStmt = pStmt->pstmtOuter)
    {
        for (LabelId* pLabelId = pStmt->pLabelId; pLabelId != nullptr; pLabelId = pLabelId->next)
        {
            if (pLabelId->pid == pid)
                return true;
        }
    }

    return false;
}

// Currently only ints and floats are treated as constants in function call
// TODO: Check if we need for other constants as well
BOOL Parser::IsConstantInFunctionCall(ParseNodePtr pnode)
{
    if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->AsParseNodeInt()->lw))
    {
        return TRUE;
    }

    if (pnode->nop == knopFlt)
    {
        return TRUE;
    }

    return FALSE;
}

/***************************************************************************
Parse a list of arguments.
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseArgList(bool *pCallOfConstants, uint16 *pSpreadArgCount, uint16 * pCount)
{
    ParseNodePtr pnodeArg;
    ParseNodePtr pnodeList = nullptr;
    ParseNodePtr *lastNodeRef = nullptr;

    // Check for an empty list
    Assert(m_token.tk == tkLParen);

    if (this->GetScanner()->Scan() == tkRParen)
    {
        return nullptr;
    }

    *pCallOfConstants = true;
    *pSpreadArgCount = 0;

    int count = 0;
    while (true)
    {
        if (count >= Js::Constants::MaxAllowedArgs)
        {
            Error(ERRTooManyArgs);
        }
        // Allow spread in argument lists.
        IdentToken token;
        pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */TRUE, NULL, nullptr, nullptr, &token);
        ++count;
        this->MarkEscapingRef(pnodeArg, &token);

        if (buildAST)
        {
            this->CheckArguments(pnodeArg);

            if (*pCallOfConstants && !IsConstantInFunctionCall(pnodeArg))
            {
                *pCallOfConstants = false;
            }

            if (pnodeArg->nop == knopEllipsis)
            {
                (*pSpreadArgCount)++;
            }

            AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
        }
        if (m_token.tk != tkComma)
        {
            break;
        }
        this->GetScanner()->Scan();

        if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
        {
            break;
        }
    }

    if (pSpreadArgCount != nullptr && (*pSpreadArgCount) > 0) {
        CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, SpreadFeature, m_scriptContext);
    }

    *pCount = static_cast<uint16>(count);
    if (buildAST)
    {
        Assert(lastNodeRef);
        Assert(*lastNodeRef);
        pnodeList->ichLim = (*lastNodeRef)->ichLim;
    }

    return pnodeList;
}

// Currently only ints are treated as constants in ArrayLiterals
BOOL Parser::IsConstantInArrayLiteral(ParseNodePtr pnode)
{
    if (pnode->nop == knopInt && !Js::TaggedInt::IsOverflow(pnode->AsParseNodeInt()->lw))
    {
        return TRUE;
    }
    return FALSE;
}

template<bool buildAST>
ParseNodeArrLit * Parser::ParseArrayLiteral()
{
    ParseNodeArrLit * pnode = nullptr;
    bool arrayOfTaggedInts = false;
    bool arrayOfInts = false;
    bool arrayOfNumbers = false;
    bool hasMissingValues = false;
    uint count = 0;
    uint spreadCount = 0;

    ParseNodePtr pnode1 = ParseArrayList<buildAST>(&arrayOfTaggedInts, &arrayOfInts, &arrayOfNumbers, &hasMissingValues, &count, &spreadCount);

    if (buildAST)
    {
        pnode = CreateNodeForOpT<knopArray>();
        pnode->pnode1 = pnode1;
        pnode->arrayOfTaggedInts = arrayOfTaggedInts;
        pnode->arrayOfInts = arrayOfInts;
        pnode->arrayOfNumbers = arrayOfNumbers;
        pnode->hasMissingValues = hasMissingValues;
        pnode->count = count;
        pnode->spreadCount = spreadCount;

        if (pnode->pnode1)
        {
            this->CheckArguments(pnode->pnode1);
        }
    }

    return pnode;
}

/***************************************************************************
Create an ArrayLiteral node
Parse a list of array elements. [ a, b, , c, ]
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseArrayList(bool *pArrayOfTaggedInts, bool *pArrayOfInts, bool *pArrayOfNumbers, bool *pHasMissingValues, uint *count, uint *spreadCount)
{
    ParseNodePtr pnodeArg = nullptr;
    ParseNodePtr pnodeList = nullptr;
    ParseNodePtr *lastNodeRef = nullptr;

    *count = 0;

    // Check for an empty list
    if (tkRBrack == m_token.tk)
    {
        return nullptr;
    }

    this->m_arrayDepth++;
    bool arrayOfTaggedInts = buildAST;
    bool arrayOfInts = buildAST;
    bool arrayOfNumbers = buildAST;
    bool arrayOfVarInts = false;
    bool hasMissingValues = false;

    for (;;)
    {
        (*count)++;
        if (tkComma == m_token.tk || tkRBrack == m_token.tk)
        {
            hasMissingValues = true;
            arrayOfTaggedInts = false;
            arrayOfInts = false;
            arrayOfNumbers = false;
            if (buildAST)
            {
                pnodeArg = CreateNodeForOpT<knopEmpty>();
            }
        }
        else
        {
            // Allow Spread in array literals.
            pnodeArg = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */ TRUE);
            if (buildAST)
            {
                if (pnodeArg->nop == knopEllipsis)
                {
                    (*spreadCount)++;
                }
                this->CheckArguments(pnodeArg);
            }
        }

#if DEBUG
        if (m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeArg))
        {
            Error(ERRsyntax);
        }
#endif

        if (buildAST)
        {
            if (arrayOfNumbers)
            {
                if (pnodeArg->nop != knopInt)
                {
                    arrayOfTaggedInts = false;
                    if (pnodeArg->nop != knopFlt)
                    {
                        // Not an array of constants.
                        arrayOfInts = false;
                        arrayOfNumbers = false;
                    }
                    else if (arrayOfInts && Js::JavascriptNumber::IsInt32OrUInt32(pnodeArg->AsParseNodeFloat()->dbl) && (!Js::JavascriptNumber::IsInt32(pnodeArg->AsParseNodeFloat()->dbl) || pnodeArg->AsParseNodeFloat()->dbl == -2147483648.0))
                    {
                        // We've seen nothing but ints, and this is a uint32 but not an int32.
                        // Unless we see an actual float at some point, we want an array of vars
                        // so we can work with tagged ints.
                        arrayOfVarInts = true;
                    }
                    else
                    {
                        // Not an int array, but it may still be a float array.
                        arrayOfInts = false;
                    }
                }
                else
                {
                    if (Js::SparseArraySegment<int32>::IsMissingItem((int32*)&pnodeArg->AsParseNodeInt()->lw))
                    {
                        arrayOfInts = false;
                    }
                    if (Js::TaggedInt::IsOverflow(pnodeArg->AsParseNodeInt()->lw))
                    {
                        arrayOfTaggedInts = false;
                    }
                }
            }
            AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
        }

        if (tkComma != m_token.tk)
        {
            break;
        }
        this->GetScanner()->Scan();

        if (tkRBrack == m_token.tk)
        {
            break;
        }
    }

    if (spreadCount != nullptr && *spreadCount > 0) {
        CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, SpreadFeature, m_scriptContext);
    }

    if (buildAST)
    {
        Assert(lastNodeRef);
        Assert(*lastNodeRef);
        pnodeList->ichLim = (*lastNodeRef)->ichLim;

        if (arrayOfVarInts && arrayOfInts)
        {
            arrayOfInts = false;
            arrayOfNumbers = false;
        }
        *pArrayOfTaggedInts = arrayOfTaggedInts;
        *pArrayOfInts = arrayOfInts;
        *pArrayOfNumbers = arrayOfNumbers;
        *pHasMissingValues = hasMissingValues;
    }
    this->m_arrayDepth--;
    return pnodeList;
}

Parser::MemberNameToTypeMap* Parser::CreateMemberNameMap(ArenaAllocator* pAllocator)
{
    Assert(pAllocator);
    return Anew(pAllocator, MemberNameToTypeMap, pAllocator, 5);
}

template<bool buildAST> void Parser::ParseComputedName(ParseNodePtr* ppnodeName, LPCOLESTR* ppNameHint, LPCOLESTR* ppFullNameHint, uint32 *pNameLength, uint32 *pShortNameOffset)
{
    this->GetScanner()->Scan();
    ParseNodePtr pnodeNameExpr = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, *ppNameHint, pNameLength, pShortNameOffset);
    if (buildAST)
    {
        *ppnodeName = CreateUniNode(knopComputedName, pnodeNameExpr, pnodeNameExpr->ichMin, pnodeNameExpr->ichLim);
    }

    if (ppFullNameHint && buildAST && CONFIG_FLAG(UseFullName))
    {
        *ppFullNameHint = FormatPropertyString(*ppNameHint, pnodeNameExpr, pNameLength, pShortNameOffset);
    }

    ChkCurTokNoScan(tkRBrack, ERRnoRbrack);
}

/***************************************************************************
    Parse a list of object set/get members, e.g.:
    { get foo(){ ... }, set bar(arg) { ... } }
***************************************************************************/
template<bool buildAST>
ParseNodeBin * Parser::ParseMemberGetSet(OpCode nop, LPCOLESTR* ppNameHint, size_t iecpMin, charcount_t ichMin)
{
    ParseNodePtr pnodeName = nullptr;
    Assert(nop == knopGetMember || nop == knopSetMember);
    Assert(ppNameHint);
    IdentPtr pid = nullptr;
    bool isComputedName = false;

    *ppNameHint = nullptr;

    switch (m_token.tk)
    {
    default:
        if (!m_token.IsReservedWord())
        {
            Error(ERRnoMemberIdent);
        }
        // fall through
    case tkID:
        pid = m_token.GetIdentifier(this->GetHashTbl());
        *ppNameHint = pid->Psz();
        if (buildAST)
        {
            pnodeName = CreateStrNode(pid);
        }
        break;
    case tkStrCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }
        pid = m_token.GetStr();
        *ppNameHint = pid->Psz();
        if (buildAST)
        {
            pnodeName = CreateStrNode(pid);
        }
        break;

    case tkIntCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        pid = this->GetScanner()->PidFromLong(m_token.GetLong());
        if (buildAST)
        {
            pnodeName = CreateStrNode(pid);
        }
        break;

    case tkFltCon:
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        pid = this->GetScanner()->PidFromDbl(m_token.GetDouble());
        if (buildAST)
        {
            pnodeName = CreateStrNode(pid);
        }
        break;

    case tkLBrack:
        // Computed property name: get|set [expr] () {  }
        if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
        {
            Error(ERRnoMemberIdent);
        }
        LPCOLESTR emptyHint = nullptr;
        uint32 offset = 0;
        ParseComputedName<buildAST>(&pnodeName, &emptyHint, ppNameHint, &offset);

        isComputedName = true;
        break;
    }

    MemberType memberType;
    ushort flags = fFncMethod | fFncNoName;
    if (nop == knopGetMember)
    {
        memberType = MemberTypeGetter;
        flags |= fFncNoArg;
    }
    else
    {
        Assert(nop == knopSetMember);
        memberType = MemberTypeSetter;
        flags |= fFncOneArg;
    }

    ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::PropertyAllowed, *ppNameHint,
        /*needsPIDOnRCurlyScan*/ false);

    pnodeFnc->cbStringMin = iecpMin;

    if (isComputedName)
    {
        pnodeFnc->SetHasComputedName();
    }
    pnodeFnc->SetHasHomeObj();
    pnodeFnc->SetIsAccessor();

    if (buildAST)
    {
        return CreateBinNode(nop, pnodeName, pnodeFnc);
    }
    else
    {
        return nullptr;
    }
}

/***************************************************************************
Parse a list of object members. e.g. { x:foo, 'y me':bar }
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLength, tokens declarationType)
{
    ParseNodeBin * pnodeArg = nullptr;
    ParseNodePtr pnodeEllipsis = nullptr;
    ParseNodePtr pnodeName = nullptr;
    ParseNodePtr pnodeList = nullptr;
    ParseNodePtr *lastNodeRef = nullptr;
    LPCOLESTR pFullNameHint = nullptr;       // A calculated full name
    uint32 fullNameHintLength = pNameHintLength ? *pNameHintLength : 0;
    uint32 shortNameOffset = 0;
    bool isProtoDeclared = false;
    bool seenRest = false;

    // we get declaration tkLCurly - when the possible object pattern found under the expression.
    bool isObjectPattern = (declarationType == tkVAR || declarationType == tkLET || declarationType == tkCONST || declarationType == tkLCurly) && IsES6DestructuringEnabled();

    // Check for an empty list
    if (tkRCurly == m_token.tk)
    {
        return nullptr;
    }

    ArenaAllocator tempAllocator(_u("MemberNames"), m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);

    bool hasDeferredInitError = false;

    for (;;)
    {
        bool isComputedName = false;
#if DEBUG
        if ((m_grfscr & fscrEnforceJSON) && (tkStrCon != m_token.tk || !(this->GetScanner()->IsDoubleQuoteOnLastTkStrCon())))
        {
            Error(ERRsyntax);
        }
#endif
        bool isAsyncMethod = false;
        charcount_t ichMin = this->GetScanner()->IchMinTok();
        size_t iecpMin = this->GetScanner()->IecpMinTok();
        if (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
        {
            RestorePoint parsedAsync;
            this->GetScanner()->Capture(&parsedAsync);
            ichMin = this->GetScanner()->IchMinTok();
            iecpMin = this->GetScanner()->IecpMinTok();

            this->GetScanner()->ScanForcingPid();
            if (m_token.tk == tkLParen || m_token.tk == tkColon || m_token.tk == tkRCurly || this->GetScanner()->FHadNewLine() || m_token.tk == tkComma)
            {
                this->GetScanner()->SeekTo(parsedAsync);
            }
            else
            {
                isAsyncMethod = true;
            }
        }

        bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
            m_token.tk == tkStar;
        ushort fncDeclFlags = fFncNoName | fFncMethod;
        if (isGenerator)
        {
            if (isAsyncMethod)
            {
                Error(ERRsyntax);
            }

            // Include star character in the function extents
            ichMin = this->GetScanner()->IchMinTok();
            iecpMin = this->GetScanner()->IecpMinTok();

            this->GetScanner()->ScanForcingPid();
            fncDeclFlags |= fFncGenerator;
        }

        IdentPtr pidHint = nullptr;              // A name scoped to current expression
        Token tkHint = m_token;
        charcount_t idHintIchMin = static_cast<charcount_t>(this->GetScanner()->IecpMinTok());
        charcount_t idHintIchLim = static_cast<charcount_t>(this->GetScanner()->IecpLimTok());
        bool wrapInBrackets = false;
        bool seenEllipsis = false;
        switch (m_token.tk)
        {
        default:
            if (!m_token.IsReservedWord())
            {
                Error(ERRnoMemberIdent);
            }
            // allow reserved words
            wrapInBrackets = true;
            // fall-through
        case tkID:
            pidHint = m_token.GetIdentifier(this->GetHashTbl());
            if (buildAST)
            {
                pnodeName = CreateStrNode(pidHint);
            }
            break;

        case tkStrCon:
            if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
            {
                Error(ERRES5NoOctal);
            }
            wrapInBrackets = true;
            pidHint = m_token.GetStr();
            if (buildAST)
            {
                pnodeName = CreateStrNode(pidHint);
            }
            break;

        case tkIntCon:
            // Object initializers with numeric labels allowed in JS6
            if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
            {
                Error(ERRES5NoOctal);
            }

            pidHint = this->GetScanner()->PidFromLong(m_token.GetLong());
            if (buildAST)
            {
                pnodeName = CreateStrNode(pidHint);
            }
            break;

        case tkFltCon:
            if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
            {
                Error(ERRES5NoOctal);
            }

            pidHint = this->GetScanner()->PidFromDbl(m_token.GetDouble());
            if (buildAST)
            {
                pnodeName = CreateStrNode(pidHint);
            }
            wrapInBrackets = true;
            break;

        case tkLBrack:
            // Computed property name: [expr] : value
            if (!m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
            {
                Error(ERRnoMemberIdent);
            }

            ParseComputedName<buildAST>(&pnodeName, &pNameHint, &pFullNameHint, &fullNameHintLength, &shortNameOffset);

            isComputedName = true;
            break;

        case tkEllipsis:
            if (CONFIG_FLAG(ES2018ObjectRestSpread))
            {
                seenEllipsis = true;
            }
            else 
            {
                Error(ERRnoMemberIdent);
            }
            break;
        }

        if (pFullNameHint == nullptr)
        {
            if (CONFIG_FLAG(UseFullName))
            {
                pFullNameHint = AppendNameHints(pNameHint, pidHint, &fullNameHintLength, &shortNameOffset, false, wrapInBrackets);
            }
            else
            {
                pFullNameHint = pidHint ? pidHint->Psz() : nullptr;
                fullNameHintLength = pidHint ? pidHint->Cch() : 0;
                shortNameOffset = 0;
            }
        }

        RestorePoint atPid;

        // Only move to next token if spread op was not seen
        if (!seenEllipsis)
        {
            this->GetScanner()->Capture(&atPid);
            this->GetScanner()->ScanForcingPid();
        }

        if (isGenerator && m_token.tk != tkLParen)
        {
            Error(ERRnoLparen);
        }

        if (tkColon == m_token.tk)
        {
            // It is a syntax error if the production of the form __proto__ : <> occurs more than once. From B.3.1 in spec.
            // Note that previous scan is important because only after that we can determine we have a variable.
            if (!isComputedName && pidHint == wellKnownPropertyPids.__proto__)
            {
                if (isProtoDeclared)
                {
                    Error(ERRsyntax);
                }
                else
                {
                    isProtoDeclared = true;
                }
            }

            this->GetScanner()->Scan();
            ParseNodePtr pnodeExpr = nullptr;
            if (isObjectPattern)
            {
                if (m_token.tk == tkEllipsis)
                {
                    Error(ERRUnexpectedEllipsis);
                }

                RestorePoint atExpression;
                if (!buildAST && declarationType == tkLCurly && IsPossiblePatternStart())
                {
                    this->GetScanner()->Capture(&atExpression);

                    int saveNextBlockId = m_nextBlockId;

                    // It is possible that we might encounter the shorthand init error. Lets find that out.
                    bool savedDeferredInitError = m_hasDeferredShorthandInitError;
                    m_hasDeferredShorthandInitError = false;

                    IdentToken token;
                    BOOL fLikelyPattern = false;

                    // First identify that the current expression is indeed the object/array literal. Otherwise we will just use the ParsrExpr to parse that.

                    ParseTerm<buildAST>(/* fAllowCall */ m_token.tk != tkSUPER, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, false /*fUnaryOrParen*/,
                        TRUE, nullptr /*pfCanAssign*/, &fLikelyPattern);

                     m_nextBlockId = saveNextBlockId;

                    this->GetScanner()->SeekTo(atExpression);

                    if (fLikelyPattern)
                    {
                        pnodeExpr = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
                        if (m_token.tk != tkComma && m_token.tk != tkRCurly)
                        {
                            if (m_token.IsOperator())
                            {
                                Error(ERRDestructNoOper);
                            }
                            Error(ERRsyntax);
                        }
                    }
                    else
                    {
                        if (m_hasDeferredShorthandInitError)
                        {
                            Error(ERRnoColon);
                        }

                        pnodeExpr = ParseExpr<buildAST>(koplCma, nullptr/*pfCantAssign*/, TRUE/*fAllowIn*/, FALSE/*fAllowEllipsis*/, pFullNameHint, &fullNameHintLength, &shortNameOffset);
                    }

                    m_hasDeferredShorthandInitError = savedDeferredInitError;
                }
                else
                {
                    pnodeExpr = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
                    if (m_token.tk != tkComma && m_token.tk != tkRCurly)
                    {
                        if (m_token.IsOperator())
                        {
                            Error(ERRDestructNoOper);
                        }
                        Error(ERRsyntax);
                    }
                }
            }
            else
            {
                pnodeExpr = ParseExpr<buildAST>(koplCma, nullptr/*pfCantAssign*/, TRUE/*fAllowIn*/, FALSE/*fAllowEllipsis*/, pFullNameHint, &fullNameHintLength, &shortNameOffset);

                if (pnodeExpr && pnodeExpr->nop == knopFncDecl)
                {
                    ParseNodeFnc* funcNode = pnodeExpr->AsParseNodeFnc();
                    if (isComputedName)
                    {
                        funcNode->SetHasComputedName();
                    }
                    funcNode->SetHasHomeObj();
                }
            }
#if DEBUG
            if ((m_grfscr & fscrEnforceJSON) && !IsJSONValid(pnodeExpr))
            {
                Error(ERRsyntax);
            }
#endif
            if (buildAST)
            {
                pnodeArg = CreateBinNode(isObjectPattern ? knopObjectPatternMember : knopMember, pnodeName, pnodeExpr);
                if (pnodeArg->pnode1->nop == knopStr)
                {
                    pnodeArg->pnode1->AsParseNodeStr()->pid->PromoteAssignmentState();
                }
            }
        }
        else if (m_token.tk == tkLParen && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
        {
            if (isObjectPattern)
            {
                Error(ERRInvalidAssignmentTarget);
            }
            // Shorthand syntax: foo() {} -> foo: function() {}

            // Rewind to the PID and parse a function expression.
            this->GetScanner()->SeekTo(atPid);

            ParseNodeFnc * pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isAsyncMethod ? fFncAsync : fFncNoFlgs), SuperRestrictionState::PropertyAllowed, pFullNameHint,
                /*needsPIDOnRCurlyScan*/ false);

            if (isAsyncMethod || isGenerator)
            {
                pnodeFnc->cbStringMin = iecpMin;
            }

            if (isComputedName)
            {
                pnodeFnc->SetHasComputedName();
                pnodeFnc->cbStringMin = iecpMin;
                
            }
            pnodeFnc->SetHasHomeObj();

            if (buildAST)
            {
                pnodeArg = CreateBinNode(knopMember, pnodeName, pnodeFnc);
            }
        }
        else if (seenEllipsis)
        {
            if (!isObjectPattern)
            {
                pnodeEllipsis = ParseExpr<buildAST>(koplCma, nullptr, TRUE, /* fAllowEllipsis */ TRUE);  
            }
            else
            {
                pnodeEllipsis = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);
            }
            if (buildAST)
            {
                this->CheckArguments(pnodeEllipsis);
            }
        }
        else if (nullptr != pidHint) //It's either tkID/tkStrCon/tkFloatCon/tkIntCon
        {
            Assert(pidHint->Psz() != nullptr);

            if ((pidHint == wellKnownPropertyPids.get || pidHint == wellKnownPropertyPids.set) &&
                // get/set are only pseudo keywords when they are identifiers (i.e. not strings)
                tkHint.tk == tkID && NextTokenIsPropertyNameStart())
            {
                if (isObjectPattern)
                {
                    Error(ERRInvalidAssignmentTarget);
                }

                LPCOLESTR pNameGetOrSet = nullptr;
                OpCode op = pidHint == wellKnownPropertyPids.get ? knopGetMember : knopSetMember;

                pnodeArg = ParseMemberGetSet<buildAST>(op, &pNameGetOrSet, iecpMin, ichMin);

                if (CONFIG_FLAG(UseFullName) && buildAST && pnodeArg->pnode2->nop == knopFncDecl)
                {
                    // displays as "get object.funcname" or "set object.funcname"
                    uint32 getOrSetOffset = 0;
                    LPCOLESTR intermediateHint = AppendNameHints(pNameHint, pNameGetOrSet, &fullNameHintLength, &shortNameOffset);
                    pFullNameHint = AppendNameHints(pidHint, intermediateHint, &fullNameHintLength, &getOrSetOffset, true);
                    shortNameOffset += getOrSetOffset;
                }
            }
            else if ((m_token.tk == tkRCurly || m_token.tk == tkComma || m_token.tk == tkAsg) && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
            {
                // Shorthand {foo} -> {foo:foo} syntax.
                // {foo = <initializer>} supported only when on object pattern rules are being applied
                if (tkHint.tk != tkID)
                {
                    Assert(tkHint.IsReservedWord()
                        || tkHint.tk == tkIntCon || tkHint.tk == tkFltCon || tkHint.tk == tkStrCon);
                    // All keywords are banned in non-strict mode.
                    // Future reserved words are banned in strict mode.
                    if (IsStrictMode() || !tkHint.IsFutureReservedWord(true))
                    {
                        IdentifierExpectedError(tkHint);
                    }
                }

                if (buildAST)
                {
                    CheckArgumentsUse(pidHint, GetCurrentFunctionNode());
                }

                bool couldBeObjectPattern = !isObjectPattern && m_token.tk == tkAsg;
                // Saving the current state as we may change the isObjectPattern down below.
                bool oldState = isObjectPattern;

                if (couldBeObjectPattern)
                {
                    declarationType = tkLCurly;
                    isObjectPattern = true;

                    // This may be an error but we are deferring for favouring destructuring.
                    hasDeferredInitError = true;
                }

                ParseNodePtr pnodeIdent = nullptr;
                if (isObjectPattern)
                {
                    this->GetScanner()->SeekTo(atPid);
                    pnodeIdent = ParseDestructuredVarDecl<buildAST>(declarationType, declarationType != tkLCurly, &seenRest/* *hasSeenRest*/, false /*topLevel*/, false /*allowEmptyExpression*/, true /*isObjectPattern*/);

                    if (m_token.tk != tkComma && m_token.tk != tkRCurly)
                    {
                        if (m_token.IsOperator())
                        {
                            Error(ERRDestructNoOper);
                        }
                        Error(ERRsyntax);
                    }
                }
                else
                {
                    // Add a reference to the hinted name so we can bind it properly.
                    PidRefStack *ref = PushPidRef(pidHint);

                    if (buildAST)
                    {
                        pnodeIdent = CreateNameNode(pidHint, ref, idHintIchMin, idHintIchLim);
                    }
                }

                if (buildAST)
                {
                    pnodeArg = CreateBinNode(isObjectPattern && !couldBeObjectPattern ? knopObjectPatternMember : knopMemberShort, pnodeName, pnodeIdent);
                }

                isObjectPattern = oldState;
            }
            else
            {
                Error(ERRnoColon);
            }
        }
        else
        {
            Error(ERRnoColon);
        }

        if (buildAST)
        {
            if (seenEllipsis)
            {
                Assert(pnodeEllipsis != nullptr);
                AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeEllipsis);
            }
            else
            {
                Assert(pnodeArg->pnode2 != nullptr);
                if (pnodeArg->pnode2->nop == knopFncDecl)
                {
                    Assert(fullNameHintLength >= shortNameOffset);
                    ParseNodeFnc * pnodeFunc = pnodeArg->pnode2->AsParseNodeFnc();
                    pnodeFunc->hint = pFullNameHint;
                    pnodeFunc->hintLength = fullNameHintLength;
                    pnodeFunc->hintOffset = shortNameOffset;
                }
                AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
            }
        }
        pidHint = nullptr;
        pFullNameHint = nullptr;
        if (tkComma != m_token.tk)
        {
            break;
        }
        this->GetScanner()->ScanForcingPid();
        if (tkRCurly == m_token.tk)
        {
            break;
        }
        if (seenRest) // Rest must be in the last position.
        {
            Error(ERRDestructRestLast);
        }
    }

    m_hasDeferredShorthandInitError = m_hasDeferredShorthandInitError || hasDeferredInitError;

    if (buildAST)
    {
        Assert(lastNodeRef);
        Assert(*lastNodeRef);
        pnodeList->ichLim = (*lastNodeRef)->ichLim;
    }

    return pnodeList;
}

BOOL Parser::WillDeferParse(Js::LocalFunctionId functionId)
{
    if ((m_grfscr & fscrWillDeferFncParse) != 0)
    {
        if (m_stoppedDeferredParse)
        {
            return false;
        }
        if (!PHASE_ENABLED_RAW(DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId))
        {
            return false;
        }
        if (PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, functionId)
#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
            || Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag)
#endif
            )
        {
            return true;
        }
#if ENABLE_PROFILE_INFO
#ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
        if (m_sourceContextInfo->sourceDynamicProfileManager != nullptr)
        {
            Js::ExecutionFlags flags = m_sourceContextInfo->sourceDynamicProfileManager->IsFunctionExecuted(functionId);
            return flags != Js::ExecutionFlags_Executed;
        }
#endif
#endif
        return true;
    }

    return false;
}

//
// Call this in ParseFncDecl only to check (and reset) if ParseFncDecl is re-parsing a deferred
// function body. If a deferred function is called and being re-parsed, it shouldn't be deferred again.
//
BOOL Parser::IsDeferredFnc()
{
    if (m_grfscr & fscrDeferredFnc)
    {
        m_grfscr &= ~fscrDeferredFnc;
        return true;
    }

    return false;
}

template<bool buildAST>
ParseNode * Parser::ParseFncDeclCheckScope(ushort flags, bool fAllowIn)
{
    ParseNodeBlock * pnodeFncBlockScope = nullptr;
    ParseNodePtr *ppnodeScopeSave = nullptr;
    ParseNodePtr *ppnodeExprScopeSave = nullptr;
    bool fDeclaration = flags & fFncDeclaration;
    bool noStmtContext = false;
    if (fDeclaration)
    {
        noStmtContext = m_pstmtCur->GetNop() != knopBlock;

        if (noStmtContext)
        {
            // We have a function declaration like "if (a) function f() {}". We didn't see
            // a block scope on the way in, so we need to pretend we did. Note that this is a syntax error
            // in strict mode.
            if (!this->FncDeclAllowedWithoutContext(flags))
            {
                Error(ERRsyntax);
            }
            pnodeFncBlockScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
            if (buildAST)
            {
                PushFuncBlockScope(pnodeFncBlockScope, &ppnodeScopeSave, &ppnodeExprScopeSave);
            }
        }
    }

    ParseNodeFnc * pnodeFnc = ParseFncDeclInternal<buildAST>(flags, nullptr, /* needsPIDOnRCurlyScan */ false, /* fUnaryOrParen */ false, noStmtContext, SuperRestrictionState::Disallowed, fAllowIn);

    if (pnodeFncBlockScope)
    {
        Assert(pnodeFncBlockScope->pnodeStmt == nullptr);
        pnodeFncBlockScope->pnodeStmt = pnodeFnc;
        if (buildAST)
        {
            PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
        }
        FinishParseBlock(pnodeFncBlockScope);
        return pnodeFncBlockScope;
    }

    return pnodeFnc;

}

template<bool buildAST>
ParseNodeFnc * Parser::ParseFncDeclNoCheckScope(ushort flags, SuperRestrictionState::State superRestrictionState, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool fAllowIn)
{
    Assert((flags & fFncDeclaration) == 0);
    return ParseFncDeclInternal<buildAST>(flags, pNameHint, needsPIDOnRCurlyScan, fUnaryOrParen, /* noStmtContext */ false, superRestrictionState, fAllowIn);
}

template<bool buildAST>
ParseNodeFnc * Parser::ParseFncDeclInternal(ushort flags, LPCOLESTR pNameHint, const bool needsPIDOnRCurlyScan, bool fUnaryOrParen, bool noStmtContext, SuperRestrictionState::State superRestrictionState, bool fAllowIn)
{
    ParseNodeFnc * pnodeFnc = nullptr;
    ParseNodePtr *ppnodeVarSave = nullptr;

    bool fDeclaration = flags & fFncDeclaration;
    bool fModule = (flags & fFncModule) != 0;
    bool fLambda = (flags & fFncLambda) != 0;
    charcount_t ichMin = this->GetScanner()->IchMinTok();
    bool wasInDeferredNestedFunc = false;

    uint tryCatchOrFinallyDepthSave = this->m_tryCatchOrFinallyDepth;
    this->m_tryCatchOrFinallyDepth = 0;

    if (this->m_arrayDepth)
    {
        this->m_funcInArrayDepth++; // Count function depth within array literal
    }

    // Update the count of functions nested in the current parent.
    Assert(m_pnestedCount || !buildAST);
    uint *pnestedCountSave = m_pnestedCount;
    if (buildAST || m_pnestedCount)
    {
        (*m_pnestedCount)++;
    }

    uint scopeCountNoAstSave = m_scopeCountNoAst;
    m_scopeCountNoAst = 0;

    // Create the node.
    pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
    pnodeFnc->SetDeclaration(fDeclaration);

    pnodeFnc->nestedFuncEscapes = false;
    pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
    pnodeFnc->cbStringMin = pnodeFnc->cbMin;
    pnodeFnc->functionId = (*m_nextFunctionId)++;
    pnodeFnc->superRestrictionState = superRestrictionState;


    // Push new parser state with this new function node
    AppendFunctionToScopeList(fDeclaration, pnodeFnc);

    // Start the argument list.
    ppnodeVarSave = m_ppnodeVar;

    if (buildAST)
    {
        pnodeFnc->lineNumber = this->GetScanner()->LineCur();
        pnodeFnc->columnNumber = CalculateFunctionColumnNumber();
        pnodeFnc->SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
        pnodeFnc->SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.

        m_pCurrentAstSize = &pnodeFnc->astSize;
    }
    else // if !buildAST
    {
        wasInDeferredNestedFunc = m_inDeferredNestedFunc;
        m_inDeferredNestedFunc = true;
    }

    m_pnestedCount = &pnodeFnc->nestedCount;

    AnalysisAssert(pnodeFnc);
    pnodeFnc->SetIsAsync((flags & fFncAsync) != 0);
    pnodeFnc->SetIsLambda(fLambda);
    pnodeFnc->SetIsMethod((flags & fFncMethod) != 0);
    pnodeFnc->SetIsClassMember((flags & fFncClassMember) != 0);
    pnodeFnc->SetIsModule(fModule);
    pnodeFnc->SetIsClassConstructor((flags & fFncClassConstructor) != 0);
    pnodeFnc->SetIsBaseClassConstructor((flags & fFncBaseClassConstructor) != 0);
    pnodeFnc->SetHomeObjLocation(Js::Constants::NoRegister);

    IdentPtr pFncNamePid = nullptr;
    bool needScanRCurly = true;
    ParseFncDeclHelper<buildAST>(pnodeFnc, pNameHint, flags, fUnaryOrParen, noStmtContext, &needScanRCurly, fModule, &pFncNamePid, fAllowIn);
    AddNestedCapturedNames(pnodeFnc);
  
    AnalysisAssert(pnodeFnc);

    *m_ppnodeVar = nullptr;
    m_ppnodeVar = ppnodeVarSave;

    if (m_currentNodeFunc && (pnodeFnc->CallsEval() || pnodeFnc->ChildCallsEval()))
    {
        GetCurrentFunctionNode()->SetChildCallsEval(true);
    }

    // Lambdas do not have "arguments" and instead capture their parent's
    // binding of "arguments.  To ensure the arguments object of the enclosing
    // non-lambda function is loaded propagate the UsesArguments flag up to
    // the parent function
    if (fLambda && (pnodeFnc->UsesArguments() || pnodeFnc->CallsEval()))
    {
        ParseNodeFnc * pnodeFncParent = GetCurrentFunctionNode();

        if (pnodeFncParent != nullptr)
        {
            pnodeFncParent->SetUsesArguments();
        }
        else
        {
            m_UsesArgumentsAtGlobal = true;
        }
    }

    if (needScanRCurly && !fModule)
    {
        // Consume the next token now that we're back in the enclosing function (whose strictness may be
        // different from the function we just finished).
#if DBG
        bool expectedTokenValid = m_token.tk == tkRCurly;
        AssertMsg(expectedTokenValid, "Invalid token expected for RCurly match");
#endif
        // The next token may need to have a PID created in !buildAST mode, as we may be parsing a method with a string name.
        if (needsPIDOnRCurlyScan)
        {
            this->GetScanner()->ScanForcingPid();
        }
        else
        {
            this->GetScanner()->Scan();
        }
    }

    m_pnestedCount = pnestedCountSave;
    Assert(!buildAST || !wasInDeferredNestedFunc);
    m_inDeferredNestedFunc = wasInDeferredNestedFunc;

    if (this->m_arrayDepth)
    {
        this->m_funcInArrayDepth--;
        if (this->m_funcInArrayDepth == 0)
        {
            // We disable deferred parsing if array literals dominate.
            // But don't do this if the array literal is dominated by function bodies.
            if (flags & (fFncMethod | fFncClassMember) && m_token.tk != tkSColon)
            {
                // Class member methods have optional separators. We need to check whether we are
                // getting the IchLim of the correct token.
                Assert(this->GetScanner()->m_tkPrevious == tkRCurly && needScanRCurly);

                this->m_funcInArray += this->GetScanner()->IchMinTok() - /*tkRCurly*/ 1 - ichMin;
            }
            else
            {
                this->m_funcInArray += this->GetScanner()->IchLimTok() - ichMin;
            }
        }
    }

    m_scopeCountNoAst = scopeCountNoAstSave;

    if (fDeclaration && !IsStrictMode())
    {
        if (pFncNamePid != nullptr &&
            GetCurrentBlock() &&
            GetCurrentBlock()->blockType == PnodeBlockType::Regular)
        {
            // Add a function-scoped VarDecl with the same name as the function for
            // back compat with pre-ES6 code that declares functions in blocks. The
            // idea is that the last executed declaration wins at the function scope
            // level and we accomplish this by having each block scoped function
            // declaration assign to both the block scoped "let" binding, as well
            // as the function scoped "var" binding.
            ParseNodeVar * vardecl = CreateVarDeclNode(pFncNamePid, STVariable, false, nullptr, false);
            vardecl->isBlockScopeFncDeclVar = true;
            if (GetCurrentFunctionNode() && vardecl->sym->GetIsFormal())
            {
                GetCurrentFunctionNode()->SetHasAnyWriteToFormals(true);
            }
        }
    }

    if (buildAST && fDeclaration)
    {
        Symbol* funcSym = pnodeFnc->GetFuncSymbol();
        if (funcSym->GetIsFormal())
        {
            GetCurrentFunctionNode()->SetHasAnyWriteToFormals(true);
        }
    }    this->m_tryCatchOrFinallyDepth = tryCatchOrFinallyDepthSave;

    return pnodeFnc;
}

bool Parser::FncDeclAllowedWithoutContext(ushort flags)
{
    // Statement context required for strict mode, async functions, and generators.
    // Note that generators aren't detected yet when this method is called; they're checked elsewhere.
    return !IsStrictMode() && !(flags & fFncAsync);
}

uint Parser::CalculateFunctionColumnNumber()
{
    uint columnNumber;

    charcount_t ichMinTok = this->GetScanner()->IchMinTok();
    charcount_t ichMinLine = this->GetScanner()->IchMinLine();
    if (ichMinTok >= ichMinLine)
    {
        // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
        columnNumber = ichMinTok - ichMinLine;
        if (m_functionBody != nullptr && m_functionBody->GetRelativeLineNumber() == this->GetScanner()->LineCur())
        {
            // Adjust the column if it falls on the first line, where the re-parse is happening.
            columnNumber += m_functionBody->GetRelativeColumnNumber();
        }
    }
    else if (m_currentNodeFunc)
    {
        // For the first line after defer parse, compute the column relative to the column number
        // of the lexically parent function.
        ULONG offsetFromCurrentFunction = ichMinTok - m_currentNodeFunc->ichMin;
        columnNumber = m_currentNodeFunc->columnNumber + offsetFromCurrentFunction;
    }
    else
    {
        // if there is no current function, lets give a default of 0.
        columnNumber = 0;
    }

    return columnNumber;
}

void Parser::AppendFunctionToScopeList(bool fDeclaration, ParseNodeFnc * pnodeFnc)
{
    if (!fDeclaration && m_ppnodeExprScope)
    {
        // We're tracking function expressions separately from declarations in this scope
        // (e.g., inside a catch scope in standards mode).
        Assert(*m_ppnodeExprScope == nullptr);
        *m_ppnodeExprScope = pnodeFnc;
        m_ppnodeExprScope = &pnodeFnc->pnodeNext;
    }
    else
    {
        Assert(*m_ppnodeScope == nullptr);
        *m_ppnodeScope = pnodeFnc;
        m_ppnodeScope = &pnodeFnc->pnodeNext;
    }
}

/***************************************************************************
Parse a function definition.
***************************************************************************/
template<bool buildAST>
void Parser::ParseFncDeclHelper(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, ushort flags, bool fUnaryOrParen, bool noStmtContext, bool *pNeedScanRCurly, bool skipFormals, IdentPtr* pFncNamePid, bool fAllowIn)
{
    Assert(pnodeFnc);
    ParseNodeFnc * pnodeFncParent = GetCurrentFunctionNode();
    // is the following correct? When buildAST is false, m_currentNodeDeferredFunc can be nullptr on transition to deferred parse from non-deferred
    ParseNodeFnc * pnodeFncSave = buildAST ? m_currentNodeFunc : m_currentNodeDeferredFunc;
    ParseNodeFnc * pnodeFncSaveNonLambda = buildAST ? m_currentNodeNonLambdaFunc : m_currentNodeNonLambdaDeferredFunc;
    int32* pAstSizeSave = m_pCurrentAstSize;

    bool fDeclaration = (flags & fFncDeclaration) != 0;
    bool fLambda = (flags & fFncLambda) != 0;
    bool fAsync = (flags & fFncAsync) != 0;
    bool fModule = (flags & fFncModule) != 0;
    bool fDeferred = false;
    StmtNest *pstmtSave;
    bool fFunctionInBlock = false;

    if (buildAST)
    {
        fFunctionInBlock = GetCurrentBlockInfo() != GetCurrentFunctionBlockInfo() &&
            (GetCurrentBlockInfo()->pnodeBlock->scope == nullptr ||
                GetCurrentBlockInfo()->pnodeBlock->scope->GetScopeType() != ScopeType_GlobalEvalBlock);
    }

    // Save the position of the scanner in case we need to inspect the name hint later
    RestorePoint beginNameHint;
    this->GetScanner()->Capture(&beginNameHint);

    ParseNodeBlock * pnodeFncExprScope = nullptr;
    Scope *fncExprScope = nullptr;
    if (!fDeclaration)
    {
        if (!fLambda)
        {
            pnodeFncExprScope = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FuncExpr);
            fncExprScope = pnodeFncExprScope->scope;
        }

        // Function expression: push the new function onto the stack now so that the name (if any) will be
        // local to the new function.

        this->UpdateCurrentNodeFunc<buildAST>(pnodeFnc, fLambda);
    }

    if (!fLambda && !fModule)
    {
        this->ParseFncName<buildAST>(pnodeFnc, flags, pFncNamePid);
    }

    if (fDeclaration)
    {
        // Declaration statement: push the new function now, after parsing the name, so the name is local to the
        // enclosing function.

        this->UpdateCurrentNodeFunc<buildAST>(pnodeFnc, fLambda);
    }

    if (noStmtContext && pnodeFnc->IsGenerator())
    {
        // Generator decl not allowed outside stmt context. (We have to wait until we've parsed the '*' to
        // detect generator.)
        Error(ERRsyntax, pnodeFnc);
    }

    // switch scanner to treat 'yield' as keyword in generator functions
    // or as an identifier in non-generator functions
    bool fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(pnodeFnc->IsGenerator());
    bool fPreviousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(fAsync);

    if (pnodeFnc->IsGenerator())
    {
        CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Generator, m_scriptContext);
    }

    if (fncExprScope && pnodeFnc->pnodeName == nullptr)
    {
        FinishParseBlock(pnodeFncExprScope);
        m_nextBlockId--;
        Adelete(&m_nodeAllocator, fncExprScope);
        fncExprScope = nullptr;
        pnodeFncExprScope = nullptr;
    }

    pnodeFnc->scope = fncExprScope;

    // Start a new statement stack.
    bool topLevelStmt =
        buildAST &&
        !fFunctionInBlock &&
        (this->m_pstmtCur == nullptr || this->m_pstmtCur->pnodeStmt->nop == knopBlock);

    pstmtSave = m_pstmtCur;
    SetCurrentStatement(nullptr);

    RestorePoint beginFormals;
    this->GetScanner()->Capture(&beginFormals);
    BOOL fWasAlreadyStrictMode = IsStrictMode();
    BOOL oldStrictMode = this->m_fUseStrictMode;

    if (fLambda)
    {
        CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Lambda, m_scriptContext);
    }

    uint uCanDeferSave = m_grfscr & fscrCanDeferFncParse;
    uint uDeferSave = m_grfscr & fscrWillDeferFncParse;
    if (flags & fFncClassMember)
    {
        // Disable deferral on class members or other construct with unusual text bounds
        // as these are usually trivial, and re-parsing is problematic.
        // NOTE: It is probably worth supporting these cases for memory and load-time purposes,
        // especially as they become more and more common.
        m_grfscr &= ~(fscrCanDeferFncParse | fscrWillDeferFncParse);
    }

    bool isTopLevelDeferredFunc = false;

#if ENABLE_BACKGROUND_PARSING
    struct AutoFastScanFlag {
        bool savedDoingFastScan;
        AutoFastScanFlag(Parser *parser) : m_parser(parser) { savedDoingFastScan = m_parser->m_doingFastScan; }
        ~AutoFastScanFlag() { m_parser->m_doingFastScan = savedDoingFastScan; }
        Parser *m_parser;
    } flag(this);
#endif

    bool doParallel = false;
#if ENABLE_BACKGROUND_PARSING
    bool parallelJobStarted = false;
#endif
    if (buildAST)
    {
        bool isLikelyIIFE = !fDeclaration && fUnaryOrParen;

        BOOL isDeferredFnc = IsDeferredFnc();
        // These are the conditions that prohibit upfront deferral *and* redeferral.
        isTopLevelDeferredFunc = 
                (m_grfscr & fscrCanDeferFncParse)
                && !m_InAsmMode
                // Don't defer a module function wrapper because we need to do export resolution at parse time
                && !fModule;

        pnodeFnc->SetCanBeDeferred(isTopLevelDeferredFunc && ParseNodeFnc::CanBeRedeferred(pnodeFnc->fncFlags));

        // These are heuristic conditions that prohibit upfront deferral but not redeferral.
        isTopLevelDeferredFunc = isTopLevelDeferredFunc && !isDeferredFnc && WillDeferParse(pnodeFnc->functionId) &&
            (!isLikelyIIFE || !topLevelStmt || PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId));

#if ENABLE_BACKGROUND_PARSING
        if (!fLambda &&
            !isDeferredFnc &&
            !isLikelyIIFE &&
            !this->IsBackgroundParser() &&
            !this->m_doingFastScan &&
            !(pnodeFncSave && m_currDeferredStub) &&
            !(this->m_parseType == ParseType_Deferred && this->m_functionBody && this->m_functionBody->GetScopeInfo() && !isTopLevelDeferredFunc))
        {
            doParallel = DoParallelParse(pnodeFnc);

            if (doParallel)
            {
                BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
                Assert(bgp);
                if (bgp->HasFailedBackgroundParseItem())
                {
                    Error(ERRsyntax);
                }
                doParallel = bgp->ParseBackgroundItem(this, pnodeFnc, isTopLevelDeferredFunc);
                if (doParallel)
                {
                    parallelJobStarted = true;
                    this->m_hasParallelJob = true;
                    this->m_doingFastScan = true;
                    doParallel = FastScanFormalsAndBody();
                    if (doParallel)
                    {
                        // Let the foreground thread take care of marking the limit on the function node,
                        // because in some cases this function's caller will want to change that limit,
                        // so we don't want the background thread to try and touch it.
                        pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
                        pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
                    }
                }
            }
        }
#endif
    }

    if (!doParallel)
    {
#if ENABLE_BACKGROUND_PARSING
        // We don't want to, or couldn't, let the main thread scan past this function body, so parse
        // it for real.
        ParseNodeFnc * pnodeRealFnc = pnodeFnc;
        if (parallelJobStarted)
        {
            // We have to deal with a failure to fast-scan the function (due to syntax error? "/"?) when
            // a background thread may already have begun to work on the job. Both threads can't be allowed to
            // operate on the same node.
            pnodeFnc = CreateDummyFuncNode(fDeclaration);
        }
#endif

        AnalysisAssert(pnodeFnc);
        ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
        AnalysisAssert(pnodeBlock != nullptr);
        pnodeFnc->pnodeScopes = pnodeBlock;
        m_ppnodeVar = &pnodeFnc->pnodeParams;
        pnodeFnc->pnodeVars = nullptr;
        ParseNodePtr* varNodesList = &pnodeFnc->pnodeVars;
        ParseNodeVar * argNode = nullptr;

        if (!fModule && !fLambda)
        {
            ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
            m_ppnodeVar = &pnodeFnc->pnodeVars;

            // Create the built-in arguments symbol
            argNode = this->AddArgumentsNodeToVars(pnodeFnc);

            // Save the updated var list
            varNodesList = m_ppnodeVar;
            m_ppnodeVar = ppnodeVarSave;
        }

        ParseNodePtr *ppnodeScopeSave = nullptr;
        ParseNodePtr *ppnodeExprScopeSave = nullptr;

        ppnodeScopeSave = m_ppnodeScope;
        if (pnodeBlock)
        {
            // This synthetic block scope will contain all the nested scopes.
            m_ppnodeScope = &pnodeBlock->pnodeScopes;
            pnodeBlock->pnodeStmt = pnodeFnc;
        }

        // Keep nested function declarations and expressions in the same list at function scope.
        // (Indicate this by nulling out the current function expressions list.)
        ppnodeExprScopeSave = m_ppnodeExprScope;
        m_ppnodeExprScope = nullptr;

        uint parenExprDepthSave = m_funcParenExprDepth;
        m_funcParenExprDepth = 0;

        if (!skipFormals)
        {
            bool fLambdaParamsSave = m_reparsingLambdaParams;
            if (fLambda)
            {
                m_reparsingLambdaParams = true;
            }

            uint savedStubCount = m_currDeferredStubCount;
            DeferredFunctionStub* savedStub = m_currDeferredStub;
            ShiftCurrDeferredStubToChildFunction(pnodeFnc, pnodeFncParent);

            this->ParseFncFormals<buildAST>(pnodeFnc, pnodeFncParent, flags, isTopLevelDeferredFunc);

            m_currDeferredStub = savedStub;
            m_currDeferredStubCount = savedStubCount;

            m_reparsingLambdaParams = fLambdaParamsSave;
        }

        // Create function body scope
        ParseNodeBlock * pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
        // Set the parameter block's child to the function body block.
        // The pnodeFnc->pnodeScopes list is constructed in such a way that it includes all the scopes in this list.
        // For example if the param scope has one function and body scope has one function then the list will look like below,
        // param scope block -> function decl from param scope -> body socpe block -> function decl from body scope.
        *m_ppnodeScope = pnodeInnerBlock;
        pnodeFnc->pnodeBodyScope = pnodeInnerBlock;

        // This synthetic block scope will contain all the nested scopes.
        m_ppnodeScope = &pnodeInnerBlock->pnodeScopes;
        pnodeInnerBlock->pnodeStmt = pnodeFnc;

        // DEFER: Begin deferral here (after names are parsed and name nodes created).
        // Create no more AST nodes until we're done.

        // Try to defer this func if all these are true:
        //  0. We are not already in deferred parsing (i.e. buildAST is true)
        //  1. We are not re-parsing a deferred func which is being invoked.
        //  2. Dynamic profile suggests this func can be deferred (and deferred parse is on).
        //  3. This func is top level or defer nested func is on.
        //  4. Optionally, the function is non-nested and not in eval, or the deferral decision was based on cached profile info,
        //     or the function is sufficiently long. (I.e., don't defer little nested functions unless we're
        //     confident they'll never be executed, because un-deferring nested functions is more expensive.)
        //     NOTE: I'm disabling #4 by default, because we've found other ways to reduce the cost of un-deferral,
        //           and we don't want to create function bodies aggressively for little functions.

        // We will also temporarily defer all asm.js functions, except for the asm.js
        // module itself, which we will never defer
        bool strictModeTurnedOn = false;

        if (isTopLevelDeferredFunc &&
            !(this->m_grfscr & fscrEvalCode) &&
            pnodeFnc->IsNested() &&
#ifndef DISABLE_DYNAMIC_PROFILE_DEFER_PARSE
            m_sourceContextInfo->sourceDynamicProfileManager == nullptr &&
#endif
            PHASE_ON_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId) &&
            (
                !PHASE_FORCE_RAW(Js::DeferParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId) ||
                PHASE_FORCE_RAW(Js::ScanAheadPhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId)
                ))
        {
            // Try to scan ahead to the end of the function. If we get there before we've scanned a minimum
            // number of tokens, don't bother deferring, because it's too small.
            if (this->ScanAheadToFunctionEnd(CONFIG_FLAG(MinDeferredFuncTokenCount)))
            {
                isTopLevelDeferredFunc = false;
            }
        }

        Scope* paramScope = pnodeFnc->pnodeScopes ? pnodeFnc->pnodeScopes->scope : nullptr;
        if (paramScope != nullptr)
        {
            if (CONFIG_FLAG(ForceSplitScope))
            {
                pnodeFnc->ResetBodyAndParamScopeMerged();
            }
            else if (pnodeFnc->HasNonSimpleParameterList() && pnodeFnc->IsBodyAndParamScopeMerged())
            {
                paramScope->ForEachSymbolUntil([this, paramScope, pnodeFnc](Symbol* sym) {
                    if (sym->GetPid()->GetTopRef()->GetFuncScopeId() > pnodeFnc->functionId)
                    {
                        // One of the symbol has non local reference. Mark the param scope as we can't merge it with body scope.
                        pnodeFnc->ResetBodyAndParamScopeMerged();
                        return true;
                    }
                    return false;
                });

                if (pnodeFnc->IsBodyAndParamScopeMerged() && !fDeclaration && pnodeFnc->pnodeName != nullptr)
                {
                    Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
                    Symbol* funcSym = pnodeFnc->pnodeName->sym;
                    if (funcSym->GetPid()->GetTopRef()->GetFuncScopeId() > pnodeFnc->functionId)
                    {
                        // This is a function expression with name captured in the param scope. In non-eval, non-split cases the function
                        // name symbol is added to the body scope to make it accessible in the body. But if there is a function or var
                        // declaration with the same name in the body then adding to the body will fail. So in this case we have to add
                        // the name symbol to the param scope by splitting it.
                        pnodeFnc->ResetBodyAndParamScopeMerged();
                    }
                }
            }
        }

        // If the param scope is merged with the body scope we want to use the param scope symbols in the body scope.
        // So add a pid ref for the body using the param scope symbol. Note that in this case the same symbol will occur twice
        // in the same pid ref stack.
        if (paramScope != nullptr && pnodeFnc->IsBodyAndParamScopeMerged())
        {
            paramScope->ForEachSymbol([this](Symbol* paramSym)
            {
                PidRefStack* ref = PushPidRef(paramSym->GetPid());
                ref->SetSym(paramSym);
            });
        }

        AssertMsg(m_funcParenExprDepth == 0, "Paren exprs should have been resolved by the time we finish function formals");

        if (fLambda)
        {
#ifdef ASMJS_PLAT
            if (m_InAsmMode && (isTopLevelDeferredFunc && m_deferAsmJs))
            {
                // asm.js doesn't support lambda functions
                Js::AsmJSCompiler::OutputError(m_scriptContext, _u("Lambda functions are not supported."));
                Js::AsmJSCompiler::OutputError(m_scriptContext, _u("Asm.js compilation failed."));
                throw Js::AsmJsParseException();
            }
#endif
        }

        if (m_token.tk == tkRParen)
        {
            this->GetScanner()->Scan();
        }

        if (fLambda)
        {
            BOOL hadNewLine = this->GetScanner()->FHadNewLine();

            // it can be the case we do not have a fat arrow here if there is a valid expression on the left hand side
            // of the fat arrow, but that expression does not parse as a parameter list.  E.g.
            //    a.x => { }
            // Therefore check for it and error if not found.
            ChkCurTok(tkDArrow, ERRnoDArrow);

            // Newline character between arrow parameters and fat arrow is a syntax error but we want to check for
            // this after verifying there was a => token. Otherwise we would throw the wrong error.
            if (hadNewLine)
            {
                Error(ERRValidIfFollowedBy, _u("Lambda parameter list"), _u("'=>' on the same line"));
            }
        }

        if (isTopLevelDeferredFunc || (m_InAsmMode && m_deferAsmJs))
        {
            fDeferred = true;

            this->ParseTopLevelDeferredFunc(pnodeFnc, pnodeFncSave, pNameHint, fLambda, pNeedScanRCurly, fAllowIn);
        }
        else
        {
            AnalysisAssert(pnodeFnc);

            // Shouldn't be any temps in the arg list.
            Assert(*m_ppnodeVar == nullptr);

            // Start the var list.
            m_ppnodeVar = varNodesList;

            if (!pnodeFnc->IsBodyAndParamScopeMerged())
            {
                OUTPUT_TRACE_DEBUGONLY(Js::ParsePhase, _u("The param and body scope of the function %s cannot be merged\n"), pnodeFnc->pnodeName ? pnodeFnc->pnodeName->pid->Psz() : _u("Anonymous function"));
            }

            // Keep nested function declarations and expressions in the same list at function scope.
            // (Indicate this by nulling out the current function expressions list.)
            m_ppnodeExprScope = nullptr;

            if (buildAST)
            {
                if (m_token.tk != tkLCurly && fLambda)
                {
                    *pNeedScanRCurly = false;
                }
                uint savedStubCount = m_currDeferredStubCount;
                DeferredFunctionStub* savedStub = m_currDeferredStub;
                ShiftCurrDeferredStubToChildFunction(pnodeFnc, pnodeFncSave);

                this->FinishFncDecl(pnodeFnc, pNameHint, fLambda, skipFormals, fAllowIn);

                m_currDeferredStub = savedStub;
                m_currDeferredStubCount = savedStubCount;
            }
            else
            {
                this->ParseNestedDeferredFunc(pnodeFnc, fLambda, pNeedScanRCurly, &strictModeTurnedOn, fAllowIn);
            }
        }

        // Restore the paren count for any outer spread/rest error checking.
        m_funcParenExprDepth = parenExprDepthSave;

        if (pnodeInnerBlock)
        {
            FinishParseBlock(pnodeInnerBlock, *pNeedScanRCurly);
        }

        if (!fModule && (m_token.tk == tkLCurly || !fLambda))
        {
            UpdateArgumentsNode(pnodeFnc, argNode);
        }

        CreateSpecialSymbolDeclarations(pnodeFnc);

        // Restore the lists of scopes that contain function expressions.

        Assert(m_ppnodeExprScope == nullptr || *m_ppnodeExprScope == nullptr);
        m_ppnodeExprScope = ppnodeExprScopeSave;

        Assert(m_ppnodeScope);
        Assert(nullptr == *m_ppnodeScope);
        m_ppnodeScope = ppnodeScopeSave;

        if (pnodeBlock)
        {
            FinishParseBlock(pnodeBlock, *pNeedScanRCurly);
        }

        if (IsStrictMode() || strictModeTurnedOn)
        {
            this->m_fUseStrictMode = TRUE; // Now we know this function is in strict mode

            if (!fWasAlreadyStrictMode)
            {
                // If this function turned on strict mode then we didn't check the formal
                // parameters or function name hint for future reserved word usage. So do that now.
                RestorePoint afterFnc;
                this->GetScanner()->Capture(&afterFnc);

                if (pnodeFnc->pnodeName != nullptr)
                {
                    // Rewind to the function name hint and check if the token is a reserved word.
                    this->GetScanner()->SeekTo(beginNameHint);
                    this->GetScanner()->Scan();
                    if (pnodeFnc->IsGenerator())
                    {
                        Assert(m_token.tk == tkStar);
                        Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
                        Assert(!(flags & fFncClassMember));
                        this->GetScanner()->Scan();
                    }
                    if (m_token.IsReservedWord())
                    {
                        IdentifierExpectedError(m_token);
                    }
                    CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(this->GetHashTbl()));
                }

                // Fast forward to formal parameter list, check for future reserved words,
                // then restore scanner as it was.
                this->GetScanner()->SeekToForcingPid(beginFormals);
                CheckStrictFormalParameters();
                this->GetScanner()->SeekTo(afterFnc);
            }

            if (buildAST)
            {
                if (pnodeFnc->pnodeName != nullptr)
                {
                    Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
                    CheckStrictModeEvalArgumentsUsage(pnodeFnc->pnodeName->pid, pnodeFnc->pnodeName);
                }
            }

            this->m_fUseStrictMode = oldStrictMode;
            CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, StrictModeFunction, m_scriptContext);
        }

        ProcessCapturedNames(pnodeFnc);

        if (fDeferred)
        {
            AnalysisAssert(pnodeFnc);
            pnodeFnc->pnodeVars = nullptr;
        }

#if ENABLE_BACKGROUND_PARSING
        if (parallelJobStarted)
        {
            pnodeFnc = pnodeRealFnc;
            m_currentNodeFunc = pnodeRealFnc;

            // Let the foreground thread take care of marking the limit on the function node,
            // because in some cases this function's caller will want to change that limit,
            // so we don't want the background thread to try and touch it.
            pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
            pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
        }
#endif
    }

    // after parsing asm.js module, we want to reset asm.js state before continuing
    AnalysisAssert(pnodeFnc);
    if (pnodeFnc->GetAsmjsMode())
    {
        m_InAsmMode = false;
    }

    // Restore the statement stack.
    Assert(nullptr == m_pstmtCur);
    SetCurrentStatement(pstmtSave);

    if (pnodeFncExprScope)
    {
        FinishParseFncExprScope(pnodeFnc, pnodeFncExprScope);
    }
    m_grfscr |= uCanDeferSave;
    if (!m_stoppedDeferredParse)
    {
        m_grfscr |= uDeferSave;
    }

    this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
    this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);

    // Restore the current function.
    if (buildAST)
    {
        Assert(pnodeFnc == m_currentNodeFunc);

        m_currentNodeFunc = pnodeFncSave;
        m_pCurrentAstSize = pAstSizeSave;

        if (!fLambda)
        {
            Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
            m_currentNodeNonLambdaFunc = pnodeFncSaveNonLambda;
        }
    }
    else
    {
        Assert(pnodeFnc == m_currentNodeDeferredFunc);
        if (!fLambda)
        {
            Assert(pnodeFnc == m_currentNodeNonLambdaDeferredFunc);
            m_currentNodeNonLambdaDeferredFunc = pnodeFncSaveNonLambda;
        }
        m_currentNodeDeferredFunc = pnodeFncSave;
    }

    if (m_currentNodeFunc && pnodeFnc->HasWithStmt())
    {
        GetCurrentFunctionNode()->SetHasWithStmt(true);
    }
}

template<bool buildAST>
void Parser::UpdateCurrentNodeFunc(ParseNodeFnc * pnodeFnc, bool fLambda)
{
    if (buildAST)
    {
        // Make this the current function and start its sub-function list.
        m_currentNodeFunc = pnodeFnc;

        Assert(m_currentNodeDeferredFunc == nullptr);

        if (!fLambda)
        {
            m_currentNodeNonLambdaFunc = pnodeFnc;
        }
    }
    else // if !buildAST
    {
        AnalysisAssert(pnodeFnc);

        if (!fLambda)
        {
            m_currentNodeNonLambdaDeferredFunc = pnodeFnc;
        }

        m_currentNodeDeferredFunc = pnodeFnc;
    }
}

void Parser::ParseTopLevelDeferredFunc(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeFncParent, LPCOLESTR pNameHint, bool fLambda, bool *pNeedScanRCurly, bool fAllowIn)
{
    // Parse a function body that is a transition point from building AST to doing fast syntax check.

    pnodeFnc->pnodeVars = nullptr;
    pnodeFnc->pnodeBody = nullptr;

    this->m_deferringAST = TRUE;

    // Put the scanner into "no hashing" mode.
    BYTE deferFlags = this->GetScanner()->SetDeferredParse(TRUE);

    if (!fLambda)
    {
        ChkCurTok(tkLCurly, ERRnoLcurly);
    }
    else
    {
        // Lambda may consist of a single expression instead of a block
        if (this->GetScanner()->m_ptoken->tk == tkLCurly)
        {
            this->GetScanner()->Scan();
        }
        else
        {
            *pNeedScanRCurly = false;
        }
    }

    ParseNodePtr *ppnodeVarSave = m_ppnodeVar;

    m_ppnodeVar = &pnodeFnc->pnodeVars;

    // Don't try and skip scanning nested deferred lambdas which have only a single expression in the body.
    // Their more-complicated text extents won't match the deferred-stub and the single expression should be fast to scan, anyway.
    if (fLambda && !*pNeedScanRCurly)
    {
        ParseExpressionLambdaBody<false>(pnodeFnc, fAllowIn);
    }
    else if (pnodeFncParent != nullptr && m_currDeferredStub != nullptr)
    {
        // We've already parsed this function body for syntax errors on the initial parse of the script.
        // We have information that allows us to skip it, so do so.

        Assert(pnodeFncParent->nestedCount != 0);
        DeferredFunctionStub *stub = m_currDeferredStub + (pnodeFncParent->nestedCount - 1);

        Assert(pnodeFnc->ichMin == stub->ichMin
            || (stub->fncFlags & kFunctionIsAsync) == kFunctionIsAsync
            || ((stub->fncFlags & kFunctionIsMethod) == kFunctionIsMethod && (
                   (stub->fncFlags & kFunctionIsAccessor) == kFunctionIsAccessor
                || (stub->fncFlags & kFunctionIsGenerator) == kFunctionIsGenerator
                || (stub->fncFlags & kFunctionHasComputedName) == kFunctionHasComputedName
                )));
        if (stub->fncFlags & kFunctionCallsEval)
        {
            this->MarkEvalCaller();
        }

        PHASE_PRINT_TRACE1(
            Js::SkipNestedDeferredPhase,
            _u("Skipping nested deferred function %d. %s: %d...%d\n"),
            pnodeFnc->functionId, GetFunctionName(pnodeFnc, pNameHint), pnodeFnc->ichMin, stub->restorePoint.m_ichMinTok);

        this->GetScanner()->SeekTo(stub->restorePoint, m_nextFunctionId);

        // If we already incremented m_nextFunctionId when we saw some functions in the parameter scope
        // (in default argument assignment, for example), we want to remove the count of those so the
        // function ids following the one we are skipping right now are correct.
        *m_nextFunctionId -= pnodeFnc->nestedCount;

        for (uint i = 0; i < stub->capturedNameCount; i++)
        {
            int stringId = stub->capturedNameSerializedIds[i];
            uint32 stringLength = 0;
            LPCWSTR stringVal = Js::ByteCodeSerializer::DeserializeString(stub, stringId, stringLength);

            OUTPUT_TRACE_DEBUGONLY(Js::SkipNestedDeferredPhase, _u("\tPushing a reference to '%s'\n"), stringVal);

            IdentPtr pid = this->GetHashTbl()->PidHashNameLen(stringVal, stringLength);
            PushPidRef(pid);
        }

        pnodeFnc->nestedCount = stub->nestedCount;
        pnodeFnc->deferredStub = stub->deferredStubs;
        pnodeFnc->fncFlags = (FncFlags)(pnodeFnc->fncFlags | stub->fncFlags);
    }
    else
    {
        ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */);
    }

    if (!fLambda || *pNeedScanRCurly)
    {
        pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
        pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
    }

    m_ppnodeVar = ppnodeVarSave;

    // Restore the scanner's default hashing mode.
    // Do this before we consume the next token.
    this->GetScanner()->SetDeferredParseFlags(deferFlags);

    if (*pNeedScanRCurly)
    {
        ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
    }

#if DBG
    pnodeFnc->deferredParseNextFunctionId = *this->m_nextFunctionId;
#endif
    this->m_deferringAST = FALSE;
}

bool Parser::DoParallelParse(ParseNodeFnc * pnodeFnc) const
{
#if ENABLE_BACKGROUND_PARSING
    if (!PHASE_ENABLED_RAW(ParallelParsePhase, m_sourceContextInfo->sourceContextId, pnodeFnc->functionId))
    {
        return false;
    }

    BackgroundParser *bgp = m_scriptContext->GetBackgroundParser();
    return bgp != nullptr;
#else
    return false;
#endif
}

bool Parser::ScanAheadToFunctionEnd(uint count)
{
    bool found = false;
    uint curlyDepth = 0;

    RestorePoint funcStart;
    this->GetScanner()->Capture(&funcStart);

    for (uint i = 0; i < count; i++)
    {
        switch (m_token.tk)
        {
        case tkStrTmplBegin:
        case tkStrTmplMid:
        case tkStrTmplEnd:
        case tkDiv:
        case tkAsgDiv:
        case tkScanError:
        case tkEOF:
            goto LEnd;

        case tkLCurly:
            UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
            break;

        case tkRCurly:
            if (curlyDepth == 1)
            {
                found = true;
                goto LEnd;
            }
            if (curlyDepth == 0)
            {
                goto LEnd;
            }
            curlyDepth--;
            break;
        }

        this->GetScanner()->ScanAhead();
    }

LEnd:
    this->GetScanner()->SeekTo(funcStart);
    return found;
}

#if ENABLE_BACKGROUND_PARSING
bool Parser::FastScanFormalsAndBody()
{
    // The scanner is currently pointing just past the name of a function.
    // The idea here is to find the end of the function body as quickly as possible,
    // by tokenizing and tracking {}'s if possible.
    // String templates require some extra logic but can be handled.

    // The real wrinkle is "/" and "/=", which may indicate either a RegExp literal or a division, depending
    // on the context.
    // To handle this with minimal work, keep track of the last ";" seen at each {} depth. If we see one of the
    // difficult tokens, rewind to the last ";" at the current {} depth and parse statements until we pass the
    // point where we had to rewind. This will process the "/" as required.

    RestorePoint funcStart;
    this->GetScanner()->Capture(&funcStart);

    const int maxRestorePointDepth = 16;
    struct FastScanRestorePoint
    {
        RestorePoint restorePoint;
        uint parenDepth;
        Js::LocalFunctionId functionId;
        int blockId;

        FastScanRestorePoint() : restorePoint(), parenDepth(0) {};
    };
    FastScanRestorePoint lastSColonAtCurlyDepth[maxRestorePointDepth];

    charcount_t ichStart = this->GetScanner()->IchMinTok();
    uint blockIdSave = m_nextBlockId;
    uint functionIdSave = *m_nextFunctionId;
    uint curlyDepth = 0;
    uint strTmplDepth = 0;
    for (;;)
    {
        switch (m_token.tk)
        {
        case tkStrTmplBegin:
            UInt32Math::Inc(strTmplDepth, Parser::OutOfMemory);
            // Fall through

        case tkStrTmplMid:
        case tkLCurly:
            UInt32Math::Inc(curlyDepth, Parser::OutOfMemory);
            Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
            break;

        case tkStrTmplEnd:
            // We can assert here, because the scanner will only return this token if we've told it we're
            // in a string template.
            Assert(strTmplDepth > 0);
            strTmplDepth--;
            break;

        case tkRCurly:
            if (curlyDepth == 1)
            {
                Assert(strTmplDepth == 0);
                if (PHASE_TRACE1(Js::ParallelParsePhase))
                {
                    Output::Print(_u("Finished fast seek: %d. %s -- %d...%d\n"),
                        m_currentNodeFunc->functionId,
                        GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->hint),
                        ichStart, this->GetScanner()->IchLimTok());
                }
                return true;
            }
            if (curlyDepth < maxRestorePointDepth)
            {
                lastSColonAtCurlyDepth[curlyDepth].restorePoint.m_ichMinTok = (uint)-1;
            }
            curlyDepth--;
            if (strTmplDepth > 0)
            {
                this->GetScanner()->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
            }
            break;

        case tkSColon:
            // Track the location of the ";" (if it's outside parens, as we don't, for instance, want
            // to track the ";"'s in a for-loop header. If we find it's important to rewind within a paren
            // expression, we can do something more sophisticated.)
            if (curlyDepth < maxRestorePointDepth && lastSColonAtCurlyDepth[curlyDepth].parenDepth == 0)
            {
                this->GetScanner()->Capture(&lastSColonAtCurlyDepth[curlyDepth].restorePoint);
                lastSColonAtCurlyDepth[curlyDepth].functionId = *this->m_nextFunctionId;
                lastSColonAtCurlyDepth[curlyDepth].blockId = m_nextBlockId;
            }
            break;

        case tkLParen:
            if (curlyDepth < maxRestorePointDepth)
            {
                UInt32Math::Inc(lastSColonAtCurlyDepth[curlyDepth].parenDepth);
            }
            break;

        case tkRParen:
            if (curlyDepth < maxRestorePointDepth)
            {
                Assert(lastSColonAtCurlyDepth[curlyDepth].parenDepth != 0);
                lastSColonAtCurlyDepth[curlyDepth].parenDepth--;
            }
            break;

        case tkID:
        {
            charcount_t tokLength = this->GetScanner()->IchLimTok() - this->GetScanner()->IchMinTok();
            // Detect the function and class keywords so we can track function ID's.
            // (In fast mode, the scanner doesn't distinguish keywords and doesn't point the token
            // to a PID.)
            // Detect try/catch/for to increment block count for them.
            switch (tokLength)
            {
            case 3:
                if (!memcmp(this->GetScanner()->PchMinTok(), "try", 3) || !memcmp(this->GetScanner()->PchMinTok(), "for", 3))
                {
                    Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
                }
                break;
            case 5:
                if (!memcmp(this->GetScanner()->PchMinTok(), "catch", 5))
                {
                    Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
                }
                else if (!memcmp(this->GetScanner()->PchMinTok(), "class", 5))
                {
                    Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
                    Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
                }
                break;
            case 8:
                if (!memcmp(this->GetScanner()->PchMinTok(), "function", 8))
                {
                    // Account for the possible func expr scope or dummy block for missing {}'s around a declaration
                    Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
                    Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
                }
                break;
            }
            break;
        }

        case tkDArrow:
            Int32Math::Inc(m_nextBlockId, &m_nextBlockId);
            Int32Math::Inc(*this->m_nextFunctionId, (int*)this->m_nextFunctionId);
            break;

        case tkDiv:
        case tkAsgDiv:
        {
            int opl;
            OpCode nop;
            tokens tkPrev = this->GetScanner()->m_tkPrevious;
            if ((this->GetHashTbl()->TokIsBinop(tkPrev, &opl, &nop) && nop != knopNone) ||
                (this->GetHashTbl()->TokIsUnop(tkPrev, &opl, &nop) &&
                    nop != knopNone &&
                    tkPrev != tkInc &&
                    tkPrev != tkDec) ||
                tkPrev == tkColon ||
                tkPrev == tkLParen ||
                tkPrev == tkLBrack ||
                tkPrev == tkRETURN)
            {
                // Previous token indicates that we're starting an expression here and can't have a
                // binary operator now.
                // Assume this is a RegExp.
                ParseRegExp<false>();
                break;
            }
            uint tempCurlyDepth = curlyDepth < maxRestorePointDepth ? curlyDepth : maxRestorePointDepth - 1;
            for (; tempCurlyDepth != (uint)-1; tempCurlyDepth--)
            {
                // We don't know whether we've got a RegExp or a divide. Rewind to the last safe ";"
                // if we can and parse statements until we pass this point.
                if (lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint.m_ichMinTok != -1)
                {
                    break;
                }
            }
            if (tempCurlyDepth != (uint)-1)
            {
                ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
                int32 *pastSizeSave = m_pCurrentAstSize;
                uint *pnestedCountSave = m_pnestedCount;
                ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
                ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;

                ParseNodeFnc * pnodeFnc = CreateDummyFuncNode(true);

                charcount_t ichStop = this->GetScanner()->IchLimTok();
                curlyDepth = tempCurlyDepth;
                this->GetScanner()->SeekTo(lastSColonAtCurlyDepth[tempCurlyDepth].restorePoint);
                m_nextBlockId = lastSColonAtCurlyDepth[tempCurlyDepth].blockId;
                *this->m_nextFunctionId = lastSColonAtCurlyDepth[tempCurlyDepth].functionId;

                ParseNodeBlock * pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
                pnodeFnc->pnodeScopes = pnodeBlock;
                m_ppnodeScope = &pnodeBlock->pnodeScopes;
                m_ppnodeExprScope = nullptr;
                this->GetScanner()->Scan();
                do
                {
                    ParseStatement<false>();
                } while (this->GetScanner()->IchMinTok() < ichStop);

                FinishParseBlock(pnodeBlock);

                m_currentNodeFunc = pnodeFncSave;
                m_pCurrentAstSize = pastSizeSave;
                m_pnestedCount = pnestedCountSave;
                m_ppnodeScope = ppnodeScopeSave;
                m_ppnodeExprScope = ppnodeExprScopeSave;

                // We've already consumed the first token of the next statement, so just continue
                // without a further scan.
                continue;
            }
        }

        // fall through to rewind to function start
        case tkScanError:
        case tkEOF:
            // Unexpected token.
            if (PHASE_TRACE1(Js::ParallelParsePhase))
            {
                Output::Print(_u("Failed fast seek: %d. %s -- %d...%d\n"),
                    m_currentNodeFunc->functionId,
                    GetFunctionName(m_currentNodeFunc, m_currentNodeFunc->hint),
                    ichStart, this->GetScanner()->IchLimTok());
            }
            m_nextBlockId = blockIdSave;
            *m_nextFunctionId = functionIdSave;
            this->GetScanner()->SeekTo(funcStart);
            return false;
        }

        this->GetScanner()->ScanNoKeywords();
    }
}
#endif

ParseNodeFnc * Parser::CreateDummyFuncNode(bool fDeclaration)
{
    // Create a dummy node and make it look like the current function declaration.
    // Do this in situations where we want to parse statements without impacting
    // the state of the "real" AST.

    ParseNodeFnc * pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
    pnodeFnc->SetDeclaration(fDeclaration);

    pnodeFnc->SetNested(m_currentNodeFunc != nullptr); // If there is a current function, then we're a nested function.
    pnodeFnc->SetStrictMode(IsStrictMode()); // Inherit current strict mode -- may be overridden by the function itself if it contains a strict mode directive.   

    m_pCurrentAstSize = &pnodeFnc->astSize;
    m_currentNodeFunc = pnodeFnc;
    m_pnestedCount = &pnodeFnc->nestedCount;

    return pnodeFnc;
}

void Parser::ParseNestedDeferredFunc(ParseNodeFnc * pnodeFnc, bool fLambda, bool *pNeedScanRCurly, bool *pStrictModeTurnedOn, bool fAllowIn)
{
    // Parse a function nested inside another deferred function.

    size_t lengthBeforeBody = this->GetSourceLength();

    if (m_token.tk != tkLCurly && fLambda)
    {
        ParseExpressionLambdaBody<false>(pnodeFnc, fAllowIn);
        *pNeedScanRCurly = false;
    }
    else
    {
        ChkCurTok(tkLCurly, ERRnoLcurly);

        bool* detectStrictModeOn = IsStrictMode() ? nullptr : pStrictModeTurnedOn;
        m_ppnodeVar = &m_currentNodeDeferredFunc->pnodeVars;

        ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true /* isSourceElementList */, detectStrictModeOn);

        ChkCurTokNoScan(tkRCurly, ERRnoRcurly);

        pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
        pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
    }

    if (*pStrictModeTurnedOn)
    {
        pnodeFnc->SetStrictMode(true);
    }

    if (!PHASE_OFF1(Js::SkipNestedDeferredPhase))
    {
        // Record the end of the function and the function ID increment that happens inside the function.
        // Byte code gen will use this to build stub information to allow us to skip this function when the
        // enclosing function is fully parsed.
        RestorePoint *restorePoint = Anew(&m_nodeAllocator, RestorePoint);
        this->GetScanner()->Capture(restorePoint,
            *m_nextFunctionId - pnodeFnc->functionId - 1,
            lengthBeforeBody - this->GetSourceLength());
        pnodeFnc->pRestorePoint = restorePoint;
    }
}

template<bool buildAST>
void Parser::ParseFncName(ParseNodeFnc * pnodeFnc, ushort flags, IdentPtr* pFncNamePid)
{
    Assert(pnodeFnc);
    BOOL fDeclaration = flags & fFncDeclaration;
    BOOL fIsAsync = flags & fFncAsync;
    
    this->GetScanner()->Scan();

    // If generators are enabled then we are in a recent enough version
    // that deferred parsing will create a parse node for pnodeFnc and
    // it is safe to assume it is not null.
    if (flags & fFncGenerator)
    {
        Assert(m_scriptContext->GetConfig()->IsES6GeneratorsEnabled());
        pnodeFnc->SetIsGenerator();
    }
    else if (m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
        m_token.tk == tkStar &&
        !(flags & fFncClassMember))
    {
        if (!fDeclaration)
        {
            bool fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(!fDeclaration);
            this->GetScanner()->Scan();
            this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
        }
        else
        {
            this->GetScanner()->Scan();
        }

        pnodeFnc->SetIsGenerator();
    }

    if (fIsAsync)
    {
        if (pnodeFnc->IsGenerator())
        {
            Error(ERRsyntax);
        }
        pnodeFnc->SetIsAsync();
    }

    pnodeFnc->pnodeName = nullptr;

    if ((m_token.tk != tkID || flags & fFncNoName)
        && (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(){});
        {
            IdentifierExpectedError(m_token);
        }
        return;
    }

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

    if (IsStrictMode())
    {
        CheckStrictModeEvalArgumentsUsage(m_token.GetIdentifier(this->GetHashTbl()));
    }


    IdentPtr pidBase = m_token.GetIdentifier(this->GetHashTbl());
    pnodeFnc->pnodeName = CreateDeclNode(knopVarDecl, pidBase, STFunction);
    pnodeFnc->pid = pnodeFnc->pnodeName->pid;

    if (pFncNamePid != nullptr)
    {
        *pFncNamePid = pidBase;
    }

    this->GetScanner()->Scan();
}

void Parser::ValidateFormals()
{
    ParseFncFormals<false>(this->GetCurrentFunctionNode(), nullptr, fFncNoFlgs);
    // Eat the tkRParen. The ParseFncDeclHelper caller expects to see it.
    this->GetScanner()->Scan();
}

void Parser::ValidateSourceElementList()
{
    ParseStmtList<false>(nullptr, nullptr, SM_NotUsed, true);
}

void Parser::UpdateOrCheckForDuplicateInFormals(IdentPtr pid, SList<IdentPtr> *formals)
{
    bool isStrictMode = IsStrictMode();
    if (isStrictMode)
    {
        CheckStrictModeEvalArgumentsUsage(pid);
    }

    if (formals->Has(pid))
    {
        if (isStrictMode)
        {
            Error(ERRES5ArgSame);
        }
        else
        {
            Error(ERRFormalSame);
        }
    }
    else
    {
        formals->Prepend(pid);
    }
}

template<bool buildAST>
void Parser::ParseFncFormals(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeParentFnc, ushort flags, bool isTopLevelDeferredFunc)
{
    bool fLambda = (flags & fFncLambda) != 0;
    bool fMethod = (flags & fFncMethod) != 0;
    bool fNoArg = (flags & fFncNoArg) != 0;
    bool fOneArg = (flags & fFncOneArg) != 0;
    bool fAsync = (flags & fFncAsync) != 0;

    bool fPreviousYieldIsKeyword = false;
    bool fPreviousAwaitIsKeyword = false;

    if (fLambda)
    {
        fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(pnodeParentFnc != nullptr && pnodeParentFnc->IsGenerator());
        fPreviousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(fAsync || (pnodeParentFnc != nullptr && pnodeParentFnc->IsAsync()));
    }

    Assert(!fNoArg || !fOneArg); // fNoArg and fOneArg can never be true at the same time.

    // strictFormals corresponds to the StrictFormalParameters grammar production
    // in the ES spec which just means duplicate names are not allowed
    bool fStrictFormals = IsStrictMode() || fLambda || fMethod;

    // When detecting duplicated formals pids are needed so force PID creation (unless the function should take 0 or 1 arg).
    bool forcePid = fStrictFormals && !fNoArg && !fOneArg;
    AutoTempForcePid autoForcePid(this->GetScanner(), forcePid);

    // Lambda's allow single formal specified by a single binding identifier without parentheses, special case it.
    if (fLambda && m_token.tk == tkID)
    {
        IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());

        CreateVarDeclNode(pid, STFormal, false, nullptr, false);
        CheckPidIsValid(pid);

        this->GetScanner()->Scan();

        if (m_token.tk != tkDArrow)
        {
            Error(ERRsyntax, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok());
        }

        if (fLambda)
        {
            this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
            this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
        }

        return;
    }
    else if (fLambda && m_token.tk == tkAWAIT)
    {
        // async await => {}
        IdentifierExpectedError(m_token);
    }

    // Otherwise, must have a parameter list within parens.
    ChkCurTok(tkLParen, ERRnoLparen);

    // Now parse the list of arguments, if present
    if (m_token.tk == tkRParen)
    {
        if (fOneArg)
        {
            Error(ERRSetterMustHaveOneParameter);
        }
    }
    else
    {
        if (fNoArg)
        {
            Error(ERRGetterMustHaveNoParameters);
        }
        SList<IdentPtr> formals(&m_nodeAllocator);
        ParseNodeVar * pnodeT = nullptr;
        bool seenRestParameter = false;
        bool isNonSimpleParameterList = false;
        for (Js::ArgSlot argPos = 0; ; ++argPos)
        {
            bool isBindingPattern = false;
            if (m_scriptContext->GetConfig()->IsES6RestEnabled() && m_token.tk == tkEllipsis)
            {
                // Possible rest parameter
                this->GetScanner()->Scan();
                seenRestParameter = true;
            }
            if (m_token.tk != tkID)
            {
                if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
                {
                    // Mark that the function has a non simple parameter list before parsing the pattern since the pattern can have function definitions.
                    this->GetCurrentFunctionNode()->SetHasNonSimpleParameterList();
                    this->GetCurrentFunctionNode()->SetHasDestructuredParams();

                    ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
                    m_ppnodeVar = &pnodeFnc->pnodeVars;

                    ParseNodePtr * ppNodeLex = m_currentBlockInfo->m_ppnodeLex;
                    Assert(ppNodeLex != nullptr);

                    ParseNodeParamPattern * paramPattern = nullptr;
                    ParseNode * pnodePattern = nullptr;
                    if (isTopLevelDeferredFunc)
                    {
                        pnodePattern = ParseDestructuredLiteral<false>(tkLET, true /*isDecl*/, false /*topLevel*/);
                    }
                    else
                    {
                        pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, false /*topLevel*/);
                    }

                    // Instead of passing the STFormal all the way on many methods, it seems it is better to change the symbol type afterward.
                    for (ParseNodePtr lexNode = *ppNodeLex; lexNode != nullptr; lexNode = lexNode->AsParseNodeVar()->pnodeNext)
                    {
                        Assert(lexNode->IsVarLetOrConst());
                        UpdateOrCheckForDuplicateInFormals(lexNode->AsParseNodeVar()->pid, &formals);
                        lexNode->AsParseNodeVar()->sym->SetSymbolType(STFormal);
                        if (lexNode->AsParseNodeVar()->pid == wellKnownPropertyPids.arguments)
                        {
                            GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenInParam;
                        }
                    }

                    m_ppnodeVar = ppnodeVarSave;

                    if (buildAST)
                    {
                        if (isTopLevelDeferredFunc)
                        {
                            Assert(pnodePattern == nullptr);
                            // Create a dummy pattern node as we need the node to be considered for the param count
                            paramPattern = CreateDummyParamPatternNode(this->GetScanner()->IchMinTok());
                        }
                        else
                        {
                            Assert(pnodePattern);
                            paramPattern = CreateParamPatternNode(pnodePattern);
                        }
                        // Linking the current formal parameter (which is pattern parameter) with other formals.
                        *m_ppnodeVar = paramPattern;
                        paramPattern->pnodeNext = nullptr;
                        m_ppnodeVar = &paramPattern->pnodeNext;
                    }

                    isBindingPattern = true;
                    isNonSimpleParameterList = true;
                }
                else
                {
                    IdentifierExpectedError(m_token);
                }
            }

            if (!isBindingPattern)
            {
                IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
                LPCOLESTR pNameHint = pid->Psz();
                uint32 nameHintLength = pid->Cch();
                uint32 nameHintOffset = 0;

                if (seenRestParameter)
                {
                    this->GetCurrentFunctionNode()->SetHasNonSimpleParameterList();
                    if (flags & fFncOneArg)
                    {
                        // The parameter of a setter cannot be a rest parameter.
                        Error(ERRUnexpectedEllipsis);
                    }
                    pnodeT = CreateDeclNode(knopVarDecl, pid, STFormal, false);
                    pnodeT->sym->SetIsNonSimpleParameter(true);
                    if (buildAST)
                    {
                        // When only validating formals, we won't have a function node.
                        pnodeFnc->pnodeRest = pnodeT;
                        if (!isNonSimpleParameterList)
                        {
                            // This is the first non-simple parameter we've seen. We need to go back
                            // and set the Symbols of all previous parameters.
                            MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->AsParseNodeVar()->sym->SetIsNonSimpleParameter(true); });
                        }
                    }

                    isNonSimpleParameterList = true;
                }
                else
                {
                    pnodeT = CreateVarDeclNode(pid, STFormal, false, nullptr, false);
                    if (isNonSimpleParameterList)
                    {
                        pnodeT->sym->SetIsNonSimpleParameter(true);
                    }
                }

                if (buildAST && pid == wellKnownPropertyPids.arguments)
                {
                    // This formal parameter overrides the built-in 'arguments' object
                    m_currentNodeFunc->grfpn |= PNodeFlags::fpnArguments_overriddenInParam;
                }

                if (fStrictFormals)
                {
                    UpdateOrCheckForDuplicateInFormals(pid, &formals);
                }

                this->GetScanner()->Scan();

                if (seenRestParameter && m_token.tk != tkRParen && m_token.tk != tkAsg)
                {
                    Error(ERRRestLastArg);
                }

                if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
                {
                    if (seenRestParameter && m_scriptContext->GetConfig()->IsES6RestEnabled())
                    {
                        Error(ERRRestWithDefault);
                    }

                    // In defer parse mode we have to flag the function node to indicate that it has default arguments
                    // so that it will be considered for any syntax error scenario.
                    // Also mark it before parsing the expression as it may contain functions.
                    ParseNodeFnc * currentFncNode = GetCurrentFunctionNode();
                    if (!currentFncNode->HasDefaultArguments())
                    {
                        currentFncNode->SetHasDefaultArguments();
                        currentFncNode->SetHasNonSimpleParameterList();
                        currentFncNode->firstDefaultArg = argPos;
                    }

                    this->GetScanner()->Scan();

                    ParseNodePtr pnodeInit;
                    if (isTopLevelDeferredFunc)
                    {
                        // Defer default expressions if the function will be deferred, since we know they can't be evaluated
                        // until the function is fully compiled, and generating code for a function nested inside a deferred function
                        // creates inconsistencies.
                        pnodeInit = ParseExpr<false>(koplCma, nullptr, TRUE, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
                    }
                    else
                    {
                        pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, TRUE, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
                    }

                    if (buildAST && pnodeInit && pnodeInit->nop == knopFncDecl)
                    {
                        Assert(nameHintLength >= nameHintOffset);
                        ParseNodeFnc * pnodeFncInit = pnodeInit->AsParseNodeFnc();
                        pnodeFncInit->hint = pNameHint;
                        pnodeFncInit->hintLength = nameHintLength;
                        pnodeFncInit->hintOffset = nameHintOffset;
                    }

                    AnalysisAssert(pnodeT);
                    pnodeT->sym->SetIsNonSimpleParameter(true);
                    if (!isNonSimpleParameterList)
                    {
                        if (buildAST)
                        {
                            // This is the first non-simple parameter we've seen. We need to go back
                            // and set the Symbols of all previous parameters.
                            MapFormalsWithoutRest(m_currentNodeFunc, [&](ParseNodePtr pnodeArg) { pnodeArg->AsParseNodeVar()->sym->SetIsNonSimpleParameter(true); });
                        }

                        // There may be previous parameters that need to be checked for duplicates.
                        isNonSimpleParameterList = true;
                    }

                    if (buildAST)
                    {
                        if (!m_currentNodeFunc->HasDefaultArguments())
                        {
                            CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, DefaultArgFunction, m_scriptContext);
                        }
                        pnodeT->pnodeInit = pnodeInit;
                        pnodeT->ichLim = this->GetScanner()->IchLimTok();
                    }
                }
            }

            if (isNonSimpleParameterList && m_currentScope->GetHasDuplicateFormals())
            {
                Error(ERRFormalSame);
            }

            if (flags & fFncOneArg)
            {
                if (m_token.tk != tkRParen)
                {
                    Error(ERRSetterMustHaveOneParameter);
                }
                break; //enforce only one arg
            }

            if (m_token.tk != tkComma)
            {
                break;
            }

            this->GetScanner()->Scan();

            if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
            {
                break;
            }
        }

        if (seenRestParameter)
        {
            CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Rest, m_scriptContext);
        }

        if (m_token.tk != tkRParen)
        {
            Error(ERRnoRparen);
        }

        if (this->GetCurrentFunctionNode()->CallsEval() || this->GetCurrentFunctionNode()->ChildCallsEval())
        {
            Assert(pnodeFnc->HasNonSimpleParameterList());
            pnodeFnc->ResetBodyAndParamScopeMerged();
        }
    }
    Assert(m_token.tk == tkRParen);

    if (fLambda)
    {
        this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
        this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
    }
}

template<bool buildAST>
ParseNodePtr Parser::GenerateModuleFunctionWrapper()
{
    ParseNodePtr pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fFncModule, SuperRestrictionState::Disallowed, nullptr, /* needsPIDOnRCurlyScan */ false, /* fUnaryOrParen */ true);
    ParseNodePtr callNode = CreateCallNode(knopCall, pnodeFnc, nullptr);

    return callNode;
}

template<bool buildAST>
ParseNodeFnc * Parser::GenerateEmptyConstructor(bool extends)
{
    ParseNodeFnc * pnodeFnc;

    // Create the node.
    pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
    pnodeFnc->SetNested(NULL != m_currentNodeFunc);
    pnodeFnc->SetStrictMode();
    pnodeFnc->SetDeclaration(TRUE);
    pnodeFnc->SetIsMethod(TRUE);
    pnodeFnc->SetIsClassMember(TRUE);
    pnodeFnc->SetIsClassConstructor(TRUE);
    pnodeFnc->SetIsBaseClassConstructor(!extends);
    pnodeFnc->SetHasNonThisStmt();
    pnodeFnc->SetIsGeneratedDefault(TRUE);
    pnodeFnc->SetHasComputedName();
    pnodeFnc->SetHasHomeObj();
    pnodeFnc->SetHomeObjLocation(Js::Constants::NoRegister);

    pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
    pnodeFnc->ichMin = this->GetScanner()->IchMinTok();
    pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
    pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
    pnodeFnc->cbStringMin = pnodeFnc->cbMin;
    pnodeFnc->lineNumber = this->GetScanner()->LineCur();

    pnodeFnc->functionId = (*m_nextFunctionId);

    // In order to (re-)defer the default constructor, we need to, for instance, track
    // deferred class expression the way we track function expression, since we lose the part of the source
    // that tells us which we have.
    Assert(!pnodeFnc->canBeDeferred);

#ifdef DBG
    pnodeFnc->deferredParseNextFunctionId = *(this->m_nextFunctionId);
#endif

    AppendFunctionToScopeList(true, pnodeFnc);

    if (m_nextFunctionId)
    {
        (*m_nextFunctionId)++;
    }

    // Update the count of functions nested in the current parent.
    if (m_pnestedCount)
    {
        (*m_pnestedCount)++;
    }

    if (this->GetScanner()->IchMinTok() >= this->GetScanner()->IchMinLine())
    {
        // In scenarios involving defer parse IchMinLine() can be incorrect for the first line after defer parse
        pnodeFnc->columnNumber = this->GetScanner()->IchMinTok() - this->GetScanner()->IchMinLine();
    }
    else if (m_currentNodeFunc)
    {
        // For the first line after defer parse, compute the column relative to the column number
        // of the lexically parent function.
        ULONG offsetFromCurrentFunction = this->GetScanner()->IchMinTok() - m_currentNodeFunc->ichMin;
        pnodeFnc->columnNumber = m_currentNodeFunc->columnNumber + offsetFromCurrentFunction;
    }
    else
    {
        // if there is no current function, lets give a default of 0.
        pnodeFnc->columnNumber = 0;
    }

    int32 * pAstSizeSave = m_pCurrentAstSize;
    m_pCurrentAstSize = &(pnodeFnc->astSize);

    // Make this the current function.
    ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
    m_currentNodeFunc = pnodeFnc;

    ParseNodeName * argsId = nullptr;
    ParseNodePtr *lastNodeRef = nullptr;
    ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);

    if (buildAST && extends)
    {
        // constructor(...args) { super(...args); }
        //             ^^^^^^^
        ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
        m_ppnodeVar = &pnodeFnc->pnodeVars;

        IdentPtr pidargs = this->GetHashTbl()->PidHashNameLen(_u("args"), sizeof("args") - 1);
        ParseNodeVar * pnodeT = CreateVarDeclNode(pidargs, STFormal);
        pnodeT->sym->SetIsNonSimpleParameter(true);
        pnodeFnc->pnodeRest = pnodeT;
        PidRefStack *ref = this->PushPidRef(pidargs);

        argsId = CreateNameNode(pidargs, ref, pnodeFnc->ichMin, pnodeFnc->ichLim);
        m_ppnodeVar = ppnodeVarSave;
    }

    ParseNodeBlock * pnodeInnerBlock = StartParseBlock<buildAST>(PnodeBlockType::Function, ScopeType_FunctionBody);
    pnodeBlock->pnodeScopes = pnodeInnerBlock;
    pnodeFnc->pnodeBodyScope = pnodeInnerBlock;
    pnodeFnc->pnodeScopes = pnodeBlock;

    if (buildAST)
    {
        if (extends)
        {
            // constructor(...args) { super(...args); }
            //                        ^^^^^^^^^^^^^^^
            Assert(argsId);
            ParseNodeUni * spreadArg = CreateUniNode(knopEllipsis, argsId, pnodeFnc->ichMin, pnodeFnc->ichLim);
            ParseNodeSpecialName * superRef = ReferenceSpecialName(wellKnownPropertyPids._superConstructor, pnodeFnc->ichMin, pnodeFnc->ichLim, true);
            pnodeFnc->SetHasSuperReference(TRUE);
            ParseNodeSuperCall * callNode = CreateSuperCallNode(superRef, spreadArg);

            callNode->pnodeThis = ReferenceSpecialName(wellKnownPropertyPids._this, pnodeFnc->ichMin, pnodeFnc->ichLim, true);
            callNode->pnodeNewTarget = ReferenceSpecialName(wellKnownPropertyPids._newTarget, pnodeFnc->ichMin, pnodeFnc->ichLim, true);
            callNode->spreadArgCount = 1;
            AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, callNode);
        }

        AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, CreateNodeForOpT<knopEndCode>());
    }

    FinishParseBlock(pnodeInnerBlock);

    CreateSpecialSymbolDeclarations(pnodeFnc);

    FinishParseBlock(pnodeBlock);

    m_currentNodeFunc = pnodeFncSave;
    m_pCurrentAstSize = pAstSizeSave;

    return pnodeFnc;
}

template<bool buildAST>
void Parser::ParseExpressionLambdaBody(ParseNodeFnc * pnodeLambda, bool fAllowIn)
{
    ParseNodePtr *lastNodeRef = nullptr;

    // The lambda body is a single expression, the result of which is the return value.
    ParseNodeReturn * pnodeRet = nullptr;

    if (buildAST)
    {
        pnodeRet = CreateNodeForOpT<knopReturn>();
        pnodeRet->grfpn |= PNodeFlags::fpnSyntheticNode;
        pnodeLambda->pnodeScopes->pnodeStmt = pnodeRet;
    }

    IdentToken token;
    charcount_t lastRParen = 0;

    // We need to disable deferred parse mode in the scanner because the lambda body doesn't end with a right paren.
    // The scanner needs to create a pid in the case of a string constant token immediately following the lambda body expression.
    // Otherwise, we'll save null for the string constant pid which will AV during ByteCode generation.
    BYTE fScanDeferredFlagsSave = this->GetScanner()->SetDeferredParse(FALSE);
    ParseNodePtr result = ParseExpr<buildAST>(koplAsg, nullptr, fAllowIn, FALSE, nullptr, nullptr, nullptr, &token, false, nullptr, &lastRParen);
    this->GetScanner()->SetDeferredParseFlags(fScanDeferredFlagsSave);

    this->MarkEscapingRef(result, &token);

    if (buildAST)
    {
        pnodeRet->pnodeExpr = result;

        pnodeRet->ichMin = pnodeRet->pnodeExpr->ichMin;
        pnodeRet->ichLim = pnodeRet->pnodeExpr->ichLim;

        // Pushing a statement node with PushStmt<>() normally does this initialization
        // but do it here manually since we know there is no outer statement node.
        pnodeRet->grfnop = 0;
        pnodeRet->pnodeOuter = nullptr;

        pnodeLambda->ichLim = max(pnodeRet->ichLim, lastRParen);
        pnodeLambda->cbLim = this->GetScanner()->IecpLimTokPrevious();
        pnodeLambda->pnodeScopes->ichLim = pnodeRet->ichLim;

        pnodeLambda->pnodeBody = nullptr;
        AddToNodeList(&pnodeLambda->pnodeBody, &lastNodeRef, pnodeRet);

        // Append an EndCode node.
        ParseNodePtr end = CreateNodeForOpT<knopEndCode>(pnodeRet->ichLim);
        end->ichLim = end->ichMin; // make end code zero width at the immediate end of lambda body
        AddToNodeList(&pnodeLambda->pnodeBody, &lastNodeRef, end);

        // Lambda's do not have arguments binding
        pnodeLambda->SetHasReferenceableBuiltInArguments(false);
    }
    else
    {
        pnodeLambda->ichLim = max(this->GetScanner()->IchLimTokPrevious(), lastRParen);
        pnodeLambda->cbLim = this->GetScanner()->IecpLimTokPrevious();
    }
}

void Parser::CheckStrictFormalParameters()
{
    if (m_token.tk == tkID)
    {
        // single parameter arrow function case
        IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
        CheckStrictModeEvalArgumentsUsage(pid);
        return;
    }

    Assert(m_token.tk == tkLParen);
    this->GetScanner()->ScanForcingPid();

    if (m_token.tk != tkRParen)
    {
        SList<IdentPtr> formals(&m_nodeAllocator);
        for (;;)
        {
            if (m_token.tk != tkID)
            {
                IdentifierExpectedError(m_token);
            }

            IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
            CheckStrictModeEvalArgumentsUsage(pid);
            if (formals.Has(pid))
            {
                Error(ERRES5ArgSame, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok());
            }
            else
            {
                formals.Prepend(pid);
            }

            this->GetScanner()->Scan();

            if (m_token.tk == tkAsg && m_scriptContext->GetConfig()->IsES6DefaultArgsEnabled())
            {
                this->GetScanner()->Scan();
                // We can avoid building the AST since we are just checking the default expression.
                ParseNodePtr pnodeInit = ParseExpr<false>(koplCma);
                Assert(pnodeInit == nullptr);
            }

            if (m_token.tk != tkComma)
            {
                break;
            }
            this->GetScanner()->ScanForcingPid();

            if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
            {
                break;
            }
        }
    }
    Assert(m_token.tk == tkRParen);
}

void Parser::FinishFncNode(ParseNodeFnc * pnodeFnc, bool fAllowIn)
{
    AnalysisAssert(pnodeFnc);

    // Finish the AST for a function that was deferred earlier, but which we decided
    // to finish after the fact.
    // We assume that the name(s) and arg(s) have already got parse nodes, so
    // we just have to do the function body.

    // Save the current next function Id, and resume from the old one.
    Js::LocalFunctionId * nextFunctionIdSave = m_nextFunctionId;
    Js::LocalFunctionId tempNextFunctionId = pnodeFnc->functionId + 1;
    this->m_nextFunctionId = &tempNextFunctionId;

    ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
    uint *pnestedCountSave = m_pnestedCount;
    int32* pAstSizeSave = m_pCurrentAstSize;

    m_currentNodeFunc = pnodeFnc;
    m_pCurrentAstSize = &(pnodeFnc->astSize);

    pnodeFnc->nestedCount = 0;
    m_pnestedCount = &pnodeFnc->nestedCount;

    bool fLambda = pnodeFnc->IsLambda();
    bool fMethod = pnodeFnc->IsMethod();

    // Cue up the parser to the start of the function body.
    if (pnodeFnc->pnodeName)
    {
        // Skip the name(s).
        this->GetScanner()->SetCurrentCharacter(pnodeFnc->pnodeName->ichLim, pnodeFnc->lineNumber);
    }
    else
    {
        this->GetScanner()->SetCurrentCharacter(pnodeFnc->ichMin, pnodeFnc->lineNumber);

        if (fMethod)
        {
            // Method. Skip identifier name, computed property name, "async", "get", "set", and '*' or '(' characters.
            for (;;)
            {
                this->GetScanner()->Scan();
                // '[' character indicates a computed property name for this method. We should consume it.
                if (m_token.tk == tkLBrack)
                {
                    // We don't care what the name expr is.
                    this->GetScanner()->Scan();
                    ParseExpr<false>();
                    Assert(m_token.tk == tkRBrack);
                    continue;
                }
                // Quit scanning ahead when we reach a '(' character which opens the arg list.
                if (m_token.tk == tkLParen)
                {
                    break;
                }
            }
        }
        else if (pnodeFnc->IsAccessor())
        {
            // Getter/setter. The node text starts with the name, so eat that.
            this->GetScanner()->ScanNoKeywords();
        }
        else if (!fLambda)
        {
            // Anonymous function. Skip "async", "function", and '(' or '*' characters.
            for (;;)
            {
                this->GetScanner()->Scan();
                if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async)
                {
                    Assert(pnodeFnc->IsAsync());
                    continue;
                }
                // Quit scanning ahead when we reach a 'function' keyword which precedes the arg list.
                if (m_token.tk == tkFUNCTION)
                {
                    break;
                }
                Assert(m_token.tk == tkLParen || m_token.tk == tkStar);
            }
        }
    }

    // switch scanner to treat 'yield' as keyword in generator functions
    // or as an identifier in non-generator functions
    bool fPreviousYieldIsKeyword = this->GetScanner()->SetYieldIsKeywordRegion(pnodeFnc && pnodeFnc->IsGenerator());
    bool fPreviousAwaitIsKeyword = this->GetScanner()->SetAwaitIsKeywordRegion(pnodeFnc && pnodeFnc->IsAsync());

    // Skip the arg list.
    if (!fMethod)
    {
        // If this is a method, we've already advanced to the '(' token.
        this->GetScanner()->Scan();
    }
    if (m_token.tk == tkStar)
    {
        Assert(pnodeFnc->IsGenerator());
        this->GetScanner()->ScanNoKeywords();
    }
    if (fLambda && m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async)
    {
        Assert(pnodeFnc->IsAsync());
        this->GetScanner()->ScanNoKeywords();
    }
    Assert(m_token.tk == tkLParen || (fLambda && m_token.tk == tkID));
    this->GetScanner()->ScanNoKeywords();

    if (m_token.tk != tkRParen && m_token.tk != tkDArrow)
    {
        for (;;)
        {
            if (m_token.tk == tkEllipsis)
            {
                this->GetScanner()->ScanNoKeywords();
            }

            if (m_token.tk == tkID)
            {
                this->GetScanner()->ScanNoKeywords();

                if (m_token.tk == tkAsg)
                {
                    // Eat the default expression
                    this->GetScanner()->Scan();
                    ParseExpr<false>(koplCma);
                }
            }
            else if (IsPossiblePatternStart())
            {
                ParseDestructuredLiteralWithScopeSave(tkLET, false/*isDecl*/, false /*topLevel*/);
            }
            else
            {
                AssertMsg(false, "Unexpected identifier prefix while fast-scanning formals");
            }

            if (m_token.tk != tkComma)
            {
                break;
            }
            this->GetScanner()->ScanNoKeywords();

            if (m_token.tk == tkRParen && m_scriptContext->GetConfig()->IsES7TrailingCommaEnabled())
            {
                break;
            }
        }
    }

    if (m_token.tk == tkRParen)
    {
        this->GetScanner()->Scan();
    }
    if (fLambda && m_token.tk == tkDArrow)
    {
        this->GetScanner()->Scan();
    }

    // Finish the function body.
    {
        // Note that in IE8- modes, surrounding parentheses are considered part of function body. e.g. "( function x(){} )".
        // We lose that context here since we start from middle of function body. So save and restore source range info.
        const charcount_t ichLim = pnodeFnc->ichLim;
        const size_t cbLim = pnodeFnc->cbLim;

        this->FinishFncDecl(pnodeFnc, NULL, fLambda, /* skipCurlyBraces */ false, fAllowIn);

#if DBG
        // The pnode extent may not match the original extent.
        // We expect this to happen only when there are trailing ")"'s.
        // Consume them and make sure that's all we've got.
        if (pnodeFnc->ichLim != ichLim)
        {
            Assert(pnodeFnc->ichLim < ichLim);
            this->GetScanner()->SetCurrentCharacter(pnodeFnc->ichLim);
            while (this->GetScanner()->IchLimTok() != ichLim)
            {
                this->GetScanner()->ScanNoKeywords();
                Assert(m_token.tk == tkRParen);
            }
        }
#endif
        pnodeFnc->ichLim = ichLim;
        pnodeFnc->cbLim = cbLim;
    }

    m_currentNodeFunc = pnodeFncSave;
    m_pCurrentAstSize = pAstSizeSave;
    m_pnestedCount = pnestedCountSave;
    Assert(m_pnestedCount);

    Assert(tempNextFunctionId == pnodeFnc->deferredParseNextFunctionId);
    this->m_nextFunctionId = nextFunctionIdSave;

    this->GetScanner()->SetYieldIsKeywordRegion(fPreviousYieldIsKeyword);
    this->GetScanner()->SetAwaitIsKeywordRegion(fPreviousAwaitIsKeyword);
}

void Parser::FinishFncDecl(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint, bool fLambda, bool skipCurlyBraces, bool fAllowIn)
{
    LPCOLESTR name = NULL;
    JS_ETW(int32 startAstSize = *m_pCurrentAstSize);
    if (IS_JS_ETW(EventEnabledJSCRIPT_PARSE_METHOD_START()) || PHASE_TRACE1(Js::DeferParsePhase))
    {
        name = GetFunctionName(pnodeFnc, pNameHint);
        m_functionBody = NULL;  // for nested functions we do not want to get the name of the top deferred function return name;
        JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->functionId, 0, m_parseType, name));
        OUTPUT_TRACE(Js::DeferParsePhase, _u("Parsing function (%s) : %s (%d)\n"), GetParseType(), name, pnodeFnc->functionId);
    }

    JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_FUNC(GetScriptContext(), pnodeFnc->functionId, /*Undefer*/FALSE));


    // Do the work of creating an AST for a function body.
    // This is common to the un-deferred case and the case in which we un-defer late in the game.

    Assert(pnodeFnc->nop == knopFncDecl);

    if (fLambda && m_token.tk != tkLCurly)
    {
        ParseExpressionLambdaBody<true>(pnodeFnc, fAllowIn);
    }
    else
    {
        if (!skipCurlyBraces)
        {
            ChkCurTok(tkLCurly, ERRnoLcurly);
        }

        ParseNodePtr * lastNodeRef = nullptr;
        ParseStmtList<true>(&pnodeFnc->pnodeBody, &lastNodeRef, SM_OnFunctionCode, true /* isSourceElementList */);
        // Append an EndCode node.
        AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, CreateNodeForOpT<knopEndCode>());

        if (!skipCurlyBraces)
        {
            ChkCurTokNoScan(tkRCurly, ERRnoRcurly);
        }

        pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
        pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
    }

#ifdef ENABLE_JS_ETW
    int32 astSize = *m_pCurrentAstSize - startAstSize;
    EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeFnc->functionId, astSize, m_parseType, name);
#endif
}

ParseNodeVar * Parser::CreateSpecialVarDeclNode(ParseNodeFnc * pnodeFnc, IdentPtr pid)
{
    ParseNodeVar * pnode = InsertVarAtBeginning(pnodeFnc, pid);

    pnode->grfpn |= fpnSpecialSymbol;
    // special symbol must not be global
    pnode->sym->SetIsGlobal(false);

    return pnode;
}

ParseNodeVar * Parser::InsertVarAtBeginning(ParseNodeFnc * pnodeFnc, IdentPtr pid)
{
    ParseNodeVar * pnode = nullptr;

    if (m_ppnodeVar == &pnodeFnc->pnodeVars)
    {
        pnode = CreateVarDeclNode(pid, STVariable, true, pnodeFnc);
    }
    else
    {
        ParseNodePtr * const ppnodeVarSave = m_ppnodeVar;
        m_ppnodeVar = &pnodeFnc->pnodeVars;
        pnode = CreateVarDeclNode(pid, STVariable, true, pnodeFnc);
        m_ppnodeVar = ppnodeVarSave;
    }

    Assert(pnode);
    return pnode;
}

ParseNodeVar * Parser::AddArgumentsNodeToVars(ParseNodeFnc * pnodeFnc)
{
    Assert(!GetCurrentFunctionNode()->IsLambda());

    ParseNodeVar * argNode = InsertVarAtBeginning(pnodeFnc, wellKnownPropertyPids.arguments);

    argNode->grfpn |= PNodeFlags::fpnArguments; // Flag this as the built-in arguments node

    return argNode;
}

void Parser::UpdateArgumentsNode(ParseNodeFnc * pnodeFnc, ParseNodeVar * argNode)
{
    if ((pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenInParam) || pnodeFnc->IsLambda())
    {
        // There is a parameter named arguments. So we don't have to create the built-in arguments.
        pnodeFnc->SetHasReferenceableBuiltInArguments(false);
    }
    else if ((pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenByDecl) && pnodeFnc->IsBodyAndParamScopeMerged())
    {
        // In non-split scope case there is a var or function definition named arguments in the body
        pnodeFnc->SetHasReferenceableBuiltInArguments(false);
    }
    else
    {
        pnodeFnc->SetHasReferenceableBuiltInArguments(true);
        Assert(argNode);
    }

    if (argNode != nullptr && !argNode->sym->IsArguments())
    {
        // A duplicate definition has updated the declaration node. Need to reset it back.
        argNode->grfpn |= PNodeFlags::fpnArguments;
        argNode->sym->SetDecl(argNode);
    }
}

LPCOLESTR Parser::GetFunctionName(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint)
{
    LPCOLESTR name = nullptr;
    if (pnodeFnc->pnodeName != nullptr)
    {
        Assert(pnodeFnc->pnodeName->nop == knopVarDecl);
        name = pnodeFnc->pnodeName->pid->Psz();
    }
    if (name == nullptr && pNameHint != nullptr)
    {
        name = pNameHint;
    }
    if (name == nullptr && (pnodeFnc->IsLambda() ||
        (!pnodeFnc->IsDeclaration() && !pnodeFnc->IsMethod())))
    {
        name = Js::Constants::AnonymousFunction;
    }
    if (name == nullptr && m_functionBody != nullptr)
    {
        name = m_functionBody->GetExternalDisplayName();
    }
    else if (name == nullptr)
    {
        name = Js::Constants::AnonymousFunction;
    }
    return name;
}

IdentPtr Parser::ParseClassPropertyName(IdentPtr * pidHint)
{
    if (m_token.tk == tkID || m_token.tk == tkStrCon || m_token.IsReservedWord())
    {
        IdentPtr pid;
        if (m_token.tk == tkStrCon)
        {
            if (this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
            {
                Error(ERRES5NoOctal);
            }

            pid = m_token.GetStr();
        }
        else
        {
            pid = m_token.GetIdentifier(this->GetHashTbl());
        }
        *pidHint = pid;
        return pid;
    }
    else if (m_token.tk == tkIntCon)
    {
        if (this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        return this->GetScanner()->PidFromLong(m_token.GetLong());
    }
    else if (m_token.tk == tkFltCon)
    {
        if (this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        return this->GetScanner()->PidFromDbl(m_token.GetDouble());
    }

    Error(ERRnoMemberIdent);
}

LPCOLESTR Parser::ConstructFinalHintNode(IdentPtr pClassName, IdentPtr pMemberName, IdentPtr pGetSet, bool isStatic, uint32* nameLength, uint32* pShortNameOffset, bool isComputedName, LPCOLESTR pMemberNameHint)
{
    if ((pMemberName == nullptr && !isComputedName) ||
        (pMemberNameHint == nullptr && isComputedName) ||
        !CONFIG_FLAG(UseFullName))
    {
        return nullptr;
    }

    LPCOLESTR pFinalName = isComputedName ? pMemberNameHint : pMemberName->Psz();
    uint32 fullNameHintLength = (uint32)wcslen(pFinalName);
    uint32 shortNameOffset = 0;
    if (!isStatic)
    {
        // Add prototype.
        pFinalName = AppendNameHints(wellKnownPropertyPids.prototype, pFinalName, &fullNameHintLength, &shortNameOffset);
    }

    if (pClassName)
    {
        uint32 classNameOffset = 0;
        pFinalName = AppendNameHints(pClassName, pFinalName, &fullNameHintLength, &classNameOffset);
        shortNameOffset += classNameOffset;
    }

    if (pGetSet)
    {
        // displays as get/set prototype.funcname
        uint32 getSetOffset = 0;
        pFinalName = AppendNameHints(pGetSet, pFinalName, &fullNameHintLength, &getSetOffset, true);
        shortNameOffset += getSetOffset;
    }

    *nameLength = fullNameHintLength;
    *pShortNameOffset = shortNameOffset;

    return pFinalName;
}

template<bool buildAST>
ParseNodeClass * Parser::ParseClassDecl(BOOL isDeclaration, LPCOLESTR pNameHint, uint32 *pHintLength, uint32 *pShortNameOffset)
{
    bool hasConstructor = false;
    bool hasExtends = false;
    IdentPtr name = nullptr;
    ParseNodeVar * pnodeName = nullptr;
    ParseNodeFnc * pnodeConstructor = nullptr;
    ParseNodePtr pnodeExtends = nullptr;
    ParseNodePtr pnodeMembers = nullptr;
    ParseNodePtr *lastMemberNodeRef = nullptr;
    ParseNodePtr pnodeStaticMembers = nullptr;
    ParseNodePtr *lastStaticMemberNodeRef = nullptr;
    uint32 nameHintLength = pHintLength ? *pHintLength : 0;
    uint32 nameHintOffset = pShortNameOffset ? *pShortNameOffset : 0;

    ArenaAllocator tempAllocator(_u("ClassMemberNames"), m_nodeAllocator.GetPageAllocator(), Parser::OutOfMemory);

    size_t cbMinConstructor = 0;
    ParseNodeClass * pnodeClass = nullptr;
    if (buildAST)
    {
        pnodeClass = CreateNodeForOpT<knopClassDecl>();

        CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Class, m_scriptContext);

        cbMinConstructor = this->GetScanner()->IecpMinTok();
    }

    this->GetScanner()->Scan();
    if (m_token.tk == tkID)
    {
        name = m_token.GetIdentifier(this->GetHashTbl());
        this->GetScanner()->Scan();
    }
    else if (isDeclaration)
    {
        IdentifierExpectedError(m_token);
    }

    if (isDeclaration && name == wellKnownPropertyPids.arguments && GetCurrentBlockInfo()->pnodeBlock->blockType == Function)
    {
        GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
    }

    BOOL strictSave = m_fUseStrictMode;
    m_fUseStrictMode = TRUE;

    ParseNodeVar * pnodeDeclName = nullptr;
    if (isDeclaration)
    {
        pnodeDeclName = CreateBlockScopedDeclNode(name, knopLetDecl);
    }

    ParseNodePtr *ppnodeScopeSave = nullptr;
    ParseNodePtr *ppnodeExprScopeSave = nullptr;

    ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
    if (buildAST)
    {
        PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
        pnodeClass->pnodeBlock = pnodeBlock;
    }

    if (name)
    {
        pnodeName = CreateBlockScopedDeclNode(name, knopConstDecl);
    }

    if (m_token.tk == tkEXTENDS)
    {
        this->GetScanner()->Scan();
        pnodeExtends = ParseTerm<buildAST>();
        hasExtends = true;
    }

    if (m_token.tk != tkLCurly)
    {
        Error(ERRnoLcurly);
    }

    OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, _u("Parsing class (%s) : %s\n"), GetParseType(), name ? name->Psz() : _u("anonymous class"));

    RestorePoint beginClass;
    this->GetScanner()->Capture(&beginClass);

    this->GetScanner()->ScanForcingPid();

    IdentPtr pClassNamePid = pnodeName ? pnodeName->pid : nullptr;

    for (;;)
    {
        if (m_token.tk == tkSColon)
        {
            this->GetScanner()->ScanForcingPid();
            continue;
        }
        if (m_token.tk == tkRCurly)
        {
            break;
        }

        bool isStatic = false;
        if (m_token.tk == tkSTATIC)
        {
            // 'static' can be used as an IdentifierName here, even in strict mode code. We need to see the next token before we know
            // if this is being used as a keyword. This is similar to the way we treat 'let' in some cases.
            // See https://tc39.github.io/ecma262/#sec-keywords for more info.

            RestorePoint beginStatic;
            this->GetScanner()->Capture(&beginStatic);

            this->GetScanner()->ScanForcingPid();

            if (m_token.tk == tkLParen)
            {
                this->GetScanner()->SeekTo(beginStatic);
            }
            else
            {
                isStatic = true;
            }
        }

        ushort fncDeclFlags = fFncNoName | fFncMethod | fFncClassMember;
        charcount_t ichMin = this->GetScanner()->IchMinTok();
        size_t iecpMin = this->GetScanner()->IecpMinTok();
        ParseNodePtr pnodeMemberName = nullptr;
        IdentPtr pidHint = nullptr;
        IdentPtr memberPid = nullptr;
        LPCOLESTR pMemberNameHint = nullptr;
        uint32     memberNameHintLength = 0;
        uint32     memberNameOffset = 0;
        bool isComputedName = false;
        bool isAsyncMethod = false;

        if (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
        {
            RestorePoint parsedAsync;
            this->GetScanner()->Capture(&parsedAsync);
            ichMin = this->GetScanner()->IchMinTok();
            iecpMin = this->GetScanner()->IecpMinTok();

            this->GetScanner()->Scan();
            if (m_token.tk == tkLParen || this->GetScanner()->FHadNewLine())
            {
                this->GetScanner()->SeekTo(parsedAsync);
            }
            else
            {
                isAsyncMethod = true;
            }
        }

        bool isGenerator = m_scriptContext->GetConfig()->IsES6GeneratorsEnabled() &&
            m_token.tk == tkStar;
        if (isGenerator)
        {
            fncDeclFlags |= fFncGenerator;
            this->GetScanner()->ScanForcingPid();
        }


        if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
        {
            // Computed member name: [expr] () { }
            LPCOLESTR emptyHint = nullptr;
            ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
            isComputedName = true;
        }
        else // not computed name
        {
            memberPid = this->ParseClassPropertyName(&pidHint);
            if (pidHint)
            {
                pMemberNameHint = pidHint->Psz();
                memberNameHintLength = pidHint->Cch();
            }
        }

        if (buildAST && memberPid)
        {
            pnodeMemberName = CreateStrNode(memberPid);
        }

        if (!isStatic && memberPid == wellKnownPropertyPids.constructor)
        {
            if (hasConstructor || isAsyncMethod)
            {
                Error(ERRsyntax);
            }
            hasConstructor = true;
            LPCOLESTR pConstructorName = nullptr;
            uint32  constructorNameLength = 0;
            uint32  constructorShortNameHintOffset = 0;
            if (pnodeName && pnodeName->pid)
            {
                pConstructorName = pnodeName->pid->Psz();
                constructorNameLength = pnodeName->pid->Cch();
            }
            else
            {
                pConstructorName = pNameHint;
                constructorNameLength = nameHintLength;
                constructorShortNameHintOffset = nameHintOffset;
            }

            {
                SuperRestrictionState::State state = hasExtends ? SuperRestrictionState::CallAndPropertyAllowed : SuperRestrictionState::PropertyAllowed;

                // Add the class constructor flag and base class constructor flag if pnodeExtends is nullptr
                fncDeclFlags |= fFncClassConstructor | (hasExtends ? kFunctionNone : fFncBaseClassConstructor);
                pnodeConstructor = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, state, pConstructorName, /* needsPIDOnRCurlyScan */ true);
            }

            if (pnodeConstructor->IsGenerator())
            {
                Error(ERRConstructorCannotBeGenerator);
            }

            Assert(constructorNameLength >= constructorShortNameHintOffset);
            // The constructor function will get the same name as class.
            pnodeConstructor->hint = pConstructorName;
            pnodeConstructor->hintLength = constructorNameLength;
            pnodeConstructor->hintOffset = constructorShortNameHintOffset;
            pnodeConstructor->pid = pnodeName && pnodeName->pid ? pnodeName->pid : wellKnownPropertyPids.constructor;
            pnodeConstructor->SetHasNonThisStmt();
            pnodeConstructor->SetHasComputedName();
            pnodeConstructor->SetHasHomeObj();
        }
        else
        {
            ParseNodePtr pnodeMember = nullptr;

            bool isMemberNamedGetOrSet = false;
            RestorePoint beginMethodName;
            this->GetScanner()->Capture(&beginMethodName);
            if (memberPid == wellKnownPropertyPids.get || memberPid == wellKnownPropertyPids.set)
            {
                this->GetScanner()->ScanForcingPid();
            }
            if (m_token.tk == tkLParen)
            {
                this->GetScanner()->SeekTo(beginMethodName);
                isMemberNamedGetOrSet = true;
            }

            if ((memberPid == wellKnownPropertyPids.get || memberPid == wellKnownPropertyPids.set) && !isMemberNamedGetOrSet)
            {
                bool isGetter = (memberPid == wellKnownPropertyPids.get);

                if (m_token.tk == tkLBrack && m_scriptContext->GetConfig()->IsES6ObjectLiteralsEnabled())
                {
                    // Computed get/set member name: get|set [expr] () { }
                    LPCOLESTR emptyHint = nullptr;
                    ParseComputedName<buildAST>(&pnodeMemberName, &emptyHint, &pMemberNameHint, &memberNameHintLength, &memberNameOffset);
                    isComputedName = true;
                }
                else // not computed name
                {
                    memberPid = this->ParseClassPropertyName(&pidHint);
                }

                if ((isStatic ? (memberPid == wellKnownPropertyPids.prototype) : (memberPid == wellKnownPropertyPids.constructor)) || isAsyncMethod)
                {
                    Error(ERRsyntax);
                }
                if (buildAST && memberPid && !isComputedName)
                {
                    pnodeMemberName = CreateStrNode(memberPid);
                }

                ParseNodeFnc * pnodeFnc = nullptr;
                {
                    pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags | (isGetter ? fFncNoArg : fFncOneArg),
                        SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
                }

                pnodeFnc->SetIsStaticMember(isStatic);
                if (isComputedName)
                {
                    pnodeFnc->SetHasComputedName();
                }
                pnodeFnc->SetHasHomeObj();

                if (buildAST)
                {
                    pnodeFnc->SetIsAccessor();
                    pnodeMember = CreateBinNode(isGetter ? knopGetMember : knopSetMember, pnodeMemberName, pnodeFnc);
                    pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint,
                        isGetter ? wellKnownPropertyPids.get : wellKnownPropertyPids.set, isStatic,
                        &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
                }
            }
            else
            {
                if (isStatic && (memberPid == wellKnownPropertyPids.prototype))
                {
                    Error(ERRsyntax);
                }

                ParseNodeFnc * pnodeFnc = nullptr;
                {
                    if (isAsyncMethod)
                    {
                        fncDeclFlags |= fFncAsync;
                    }
                    pnodeFnc = ParseFncDeclNoCheckScope<buildAST>(fncDeclFlags, SuperRestrictionState::PropertyAllowed, pidHint ? pidHint->Psz() : nullptr, /* needsPIDOnRCurlyScan */ true);
                    if (isAsyncMethod)
                    {
                        pnodeFnc->cbMin = iecpMin;
                        pnodeFnc->ichMin = ichMin;
                    }

                    if (isAsyncMethod || isGenerator || isComputedName)
                    {
                        pnodeFnc->cbStringMin = iecpMin;
                    }
                }
                pnodeFnc->SetIsStaticMember(isStatic);
                if (isComputedName)
                {
                    pnodeFnc->SetHasComputedName();
                }
                pnodeFnc->SetHasHomeObj();

                if (buildAST)
                {
                    pnodeMember = CreateBinNode(knopMember, pnodeMemberName, pnodeFnc);
                    pMemberNameHint = ConstructFinalHintNode(pClassNamePid, pidHint, nullptr /*pgetset*/, isStatic, &memberNameHintLength, &memberNameOffset, isComputedName, pMemberNameHint);
                }
            }

            if (buildAST)
            {
                Assert(memberNameHintLength >= memberNameOffset);
                pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->hint = pMemberNameHint; // Fully qualified name
                pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->hintLength = memberNameHintLength;
                pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->hintOffset = memberNameOffset;
                pnodeMember->AsParseNodeBin()->pnode2->AsParseNodeFnc()->pid = memberPid; // Short name

                AddToNodeList(isStatic ? &pnodeStaticMembers : &pnodeMembers, isStatic ? &lastStaticMemberNodeRef : &lastMemberNodeRef, pnodeMember);
            }
        }
    }

    size_t cbLimConstructor = 0;
    if (buildAST)
    {
        pnodeClass->ichLim = this->GetScanner()->IchLimTok();
        cbLimConstructor = this->GetScanner()->IecpLimTok();
    }

    if (!hasConstructor)
    {
        OUTPUT_TRACE_DEBUGONLY(Js::ES6VerboseFlag, _u("Generating constructor (%s) : %s\n"), GetParseType(), name ? name->Psz() : _u("anonymous class"));

        RestorePoint endClass;
        this->GetScanner()->Capture(&endClass);
        this->GetScanner()->SeekTo(beginClass);

        pnodeConstructor = GenerateEmptyConstructor<buildAST>(pnodeExtends != nullptr);

        if (buildAST)
        {
            if (pClassNamePid)
            {
                pnodeConstructor->hint = pClassNamePid->Psz();
                pnodeConstructor->hintLength = pClassNamePid->Cch();
                pnodeConstructor->hintOffset = 0;
            }
            else
            {
                Assert(nameHintLength >= nameHintOffset);
                pnodeConstructor->hint = pNameHint;
                pnodeConstructor->hintLength = nameHintLength;
                pnodeConstructor->hintOffset = nameHintOffset;
            }
            pnodeConstructor->pid = pClassNamePid;
        }

        this->GetScanner()->SeekTo(endClass);
    }

    if (buildAST)
    {
        pnodeConstructor->cbMin = cbMinConstructor;
        pnodeConstructor->cbStringMin = cbMinConstructor;
        pnodeConstructor->cbLim = cbLimConstructor;
        pnodeConstructor->ichMin = pnodeClass->ichMin;
        pnodeConstructor->ichLim = pnodeClass->ichLim;

        PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);

        pnodeClass->pnodeDeclName = pnodeDeclName;
        pnodeClass->pnodeName = pnodeName;
        pnodeClass->pnodeConstructor = pnodeConstructor;
        pnodeClass->pnodeExtends = pnodeExtends;
        pnodeClass->pnodeMembers = pnodeMembers;
        pnodeClass->pnodeStaticMembers = pnodeStaticMembers;
        pnodeClass->isDefaultModuleExport = false;
    }
    FinishParseBlock(pnodeBlock);

    m_fUseStrictMode = strictSave;

    this->GetScanner()->Scan();

    return pnodeClass;
}

template<bool buildAST>
ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
{
    ParseNodePtr pnodeStringLiterals = nullptr;
    ParseNodePtr* lastStringLiteralNodeRef = nullptr;
    ParseNodePtr pnodeRawStringLiterals = nullptr;
    ParseNodePtr* lastRawStringLiteralNodeRef = nullptr;
    ParseNodePtr pnodeSubstitutionExpressions = nullptr;
    ParseNodePtr* lastSubstitutionExpressionNodeRef = nullptr;
    ParseNodePtr pnodeTagFncArgs = nullptr;
    ParseNodePtr* lastTagFncArgNodeRef = nullptr;
    ParseNodeStr * stringLiteral = nullptr;
    ParseNodeStr * stringLiteralRaw = nullptr;
    ParseNodeStrTemplate * pnodeStringTemplate = nullptr;
    ParseNode * pnodeReturn = nullptr;
    bool templateClosed = false;
    const bool isTagged = pnodeTagFnc != nullptr;
    uint16 stringConstantCount = 0;
    charcount_t ichMin = 0;

    Assert(m_token.tk == tkStrTmplBasic || m_token.tk == tkStrTmplBegin);

    if (buildAST)
    {
        pnodeReturn = pnodeStringTemplate = CreateNodeForOpT<knopStrTemplate>();
        pnodeStringTemplate->countStringLiterals = 0;
        pnodeStringTemplate->isTaggedTemplate = isTagged ? TRUE : FALSE;

        // If this is a tagged string template, we need to start building the arg list for the call
        if (isTagged)
        {
            ichMin = pnodeTagFnc->ichMin;
            AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, pnodeStringTemplate);
        }

    }
    CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, StringTemplates, m_scriptContext);

    OUTPUT_TRACE_DEBUGONLY(
        Js::StringTemplateParsePhase,
        _u("Starting to parse a string template (%s)...\n\tis tagged = %s\n"),
        GetParseType(),
        isTagged ? _u("true") : _u("false (Raw and cooked strings will not differ!)"));

    // String template grammar
    // `...`   Simple string template
    // `...${  String template beginning
    // }...${  String template middle
    // }...`   String template end
    while (!templateClosed)
    {
        // First, extract the string constant part - we always have one
        if (IsStrictMode() && this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber())
        {
            Error(ERRES5NoOctal);
        }

        // We are not able to pass more than a ushort worth of arguments to the tag
        // so use that as a logical limit on the number of string constant pieces.
        if (stringConstantCount >= Js::Constants::MaxAllowedArgs)
        {
            Error(ERRTooManyArgs);
        }

        // Keep track of the string literal count (must be the same for raw strings)
        // We use this in code gen so we don't need to count the string literals list
        stringConstantCount++;

        // If we are not creating parse nodes, there is no need to create strings
        if (buildAST)
        {
            stringLiteral = CreateStrNode(m_token.GetStr());

            AddToNodeList(&pnodeStringLiterals, &lastStringLiteralNodeRef, stringLiteral);

            // We only need to collect a raw string when we are going to pass the string template to a tag
            if (isTagged)
            {
                // Make the scanner create a PID for the raw string constant for the preceding scan
                IdentPtr pid = this->GetScanner()->GetSecondaryBufferAsPid();

                stringLiteralRaw = CreateStrNode(pid);

                // Should have gotten a raw string literal above
                AddToNodeList(&pnodeRawStringLiterals, &lastRawStringLiteralNodeRef, stringLiteralRaw);
            }
            else
            {
#if DBG
                // Assign the raw string for debug tracing below
                stringLiteralRaw = stringLiteral;
#endif
            }

            OUTPUT_TRACE_DEBUGONLY(
                Js::StringTemplateParsePhase,
                _u("Parsed string constant: \n\tcooked = \"%s\" \n\traw = \"%s\" \n\tdiffer = %d\n"),
                stringLiteral->pid->Psz(),
                stringLiteralRaw->pid->Psz(),
                stringLiteral->pid->Psz() == stringLiteralRaw->pid->Psz() ? 0 : 1);
        }

        switch (m_token.tk)
        {
        case tkStrTmplEnd:
        case tkStrTmplBasic:
            // We do not need to parse an expression for either the end or basic string template tokens
            templateClosed = true;
            break;
        case tkStrTmplBegin:
        case tkStrTmplMid:
        {
            // In the middle or begin string template token case, we need to parse an expression next
            this->GetScanner()->Scan();

            // Parse the contents of the curly braces as an expression
            ParseNodePtr expression = ParseExpr<buildAST>(0);

            // After parsing expression, scan should leave us with an RCurly token.
            // Use the NoScan version so we do not automatically perform a scan - we need to
            // set the scan state before next scan but we don't want to set that state if
            // the token is not as expected since we'll error in that case.
            ChkCurTokNoScan(tkRCurly, ERRnoRcurly);

            // Notify the scanner that it should scan for a middle or end string template token
            this->GetScanner()->SetScanState(Scanner_t::ScanState::ScanStateStringTemplateMiddleOrEnd);
            this->GetScanner()->Scan();

            if (buildAST)
            {
                // If we are going to call the tag function, add this expression into the list of args
                if (isTagged)
                {
                    AddToNodeListEscapedUse(&pnodeTagFncArgs, &lastTagFncArgNodeRef, expression);
                }
                else
                {
                    // Otherwise add it to the substitution expression list
                    // TODO: Store the arguments and substitution expressions in a single list?
                    AddToNodeList(&pnodeSubstitutionExpressions, &lastSubstitutionExpressionNodeRef, expression);
                }
            }

            if (!(m_token.tk == tkStrTmplMid || m_token.tk == tkStrTmplEnd))
            {
                // Scan with ScanState ScanStateStringTemplateMiddleOrEnd should only return
                // tkStrTmpMid/End unless it is EOF or tkScanError
                Assert(m_token.tk == tkEOF || m_token.tk == tkScanError);
                Error(ERRsyntax);
            }

            OUTPUT_TRACE_DEBUGONLY(Js::StringTemplateParsePhase, _u("Parsed expression\n"));
        }
        break;
        default:
            Assert(false);
            break;
        }
    }

    if (buildAST)
    {
        pnodeStringTemplate->pnodeStringLiterals = pnodeStringLiterals;
        pnodeStringTemplate->pnodeStringRawLiterals = pnodeRawStringLiterals;
        pnodeStringTemplate->pnodeSubstitutionExpressions = pnodeSubstitutionExpressions;
        pnodeStringTemplate->countStringLiterals = stringConstantCount;

        // We should still have the last string literal.
        // Use the char offset of the end of that constant as the end of the string template.
        pnodeStringTemplate->ichLim = stringLiteral->ichLim;

        // If this is a tagged template, we now have the argument list and can construct a call node
        if (isTagged)
        {
            // Return the call node here and let the byte code generator Emit the string template automagically
            ParseNodeCall * pnodeCall;
            pnodeReturn = pnodeCall = CreateCallNode(knopCall, pnodeTagFnc, pnodeTagFncArgs, ichMin, pnodeStringTemplate->ichLim);

            // We need to set the arg count explicitly
            pnodeCall->argCount = stringConstantCount;
            pnodeCall->hasDestructuring = m_hasDestructuringPattern;
        }
    }

    this->GetScanner()->Scan();

    return pnodeReturn;
}

LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pNode, uint32 *fullNameHintLength, uint32 *pShortNameOffset)
{
    // propertyString could be null, such as 'this.foo' =
    // propertyString could be empty, found in pattern as in (-1)[""][(x = z)]

    OpCode op = pNode->nop;
    LPCOLESTR rightNode = nullptr;
    if (propertyString == nullptr)
    {
        propertyString = _u("");
    }

    if (op != knopInt && op != knopFlt && op != knopName && op != knopStr)
    {
        rightNode = _u("");
    }
    else if (op == knopStr)
    {
        return AppendNameHints(propertyString, pNode->AsParseNodeStr()->pid, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
    }
    else if (op == knopFlt)
    {
        rightNode = this->GetScanner()->StringFromDbl(pNode->AsParseNodeFloat()->dbl);
    }
    else
    {
        rightNode = op == knopInt ? this->GetScanner()->StringFromLong(pNode->AsParseNodeInt()->lw)
            : pNode->AsParseNodeName()->pid->Psz();
    }

    return AppendNameHints(propertyString, rightNode, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
}

LPCOLESTR Parser::ConstructNameHint(ParseNodeBin * pNode, uint32* fullNameHintLength, uint32 *pShortNameOffset)
{
    Assert(pNode != nullptr);
    Assert(pNode->nop == knopDot || pNode->nop == knopIndex);

    // This method recursively visits nodes in the AST and could cause an SOE crash for long knopDot chains.
    // Although this method could be made non-recursive, Emit (ByteCodeEmitter.cpp) hits a stack probe
    // for shorter chains than which cause SOE here, so add a stack probe to throw SOE rather than crash on SOE.
    // Because of that correspondence, use Js::Constants::MinStackByteCodeVisitor (which is used in Emit)
    // for the stack probe here. See OS#14711878.
    PROBE_STACK_NO_DISPOSE(this->m_scriptContext, Js::Constants::MinStackByteCodeVisitor);

    LPCOLESTR leftNode = nullptr;
    if (pNode->pnode1->nop == knopDot || pNode->pnode1->nop == knopIndex)
    {
        leftNode = ConstructNameHint(pNode->pnode1->AsParseNodeBin(), fullNameHintLength, pShortNameOffset);
    }
    else if (pNode->pnode1->nop == knopName && !pNode->pnode1->AsParseNodeName()->IsSpecialName())
    {
        // We need to skip special names like 'this' because those shouldn't be appended to the
        // name hint in the debugger stack trace.
        // function ctor() {
        //   this.func = function() {
        //     // If we break here, the stack should say we are in 'func' and not 'this.func'
        //   }
        // }

        IdentPtr pid = pNode->pnode1->AsParseNodeName()->pid;
        leftNode = pid->Psz();
        *fullNameHintLength = pid->Cch();
        *pShortNameOffset = 0;
    }

    if (pNode->nop == knopIndex)
    {
        return FormatPropertyString(
            leftNode ? leftNode : Js::Constants::AnonymousFunction, // e.g. f()[0] = function () {}
            pNode->pnode2, fullNameHintLength, pShortNameOffset);
    }

    Assert(pNode->pnode2->nop == knopDot || pNode->pnode2->nop == knopName);

    LPCOLESTR rightNode = nullptr;
    bool wrapWithBrackets = false;
    if (pNode->pnode2->nop == knopDot)
    {
        rightNode = ConstructNameHint(pNode->pnode2->AsParseNodeBin(), fullNameHintLength, pShortNameOffset);
    }
    else
    {
        rightNode = pNode->pnode2->AsParseNodeName()->pid->Psz();
        wrapWithBrackets = PNodeFlags::fpnIndexOperator == (pNode->grfpn & PNodeFlags::fpnIndexOperator);
    }
    Assert(rightNode != nullptr);
    return AppendNameHints(leftNode, rightNode, fullNameHintLength, pShortNameOffset, false, wrapWithBrackets);
}

LPCOLESTR Parser::AppendNameHints(LPCOLESTR leftStr, uint32 leftLen, LPCOLESTR rightStr, uint32 rightLen, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
{
    Assert(rightStr != nullptr);
    Assert(leftLen != 0 || wrapInBrackets);
    Assert(rightLen != 0 || wrapInBrackets);

    bool ignoreDot = rightStr[0] == _u('[') && !wrapInBrackets;//if we wrap in brackets it can be a string literal which can have brackets at the first char
    uint32 totalLength = leftLen + rightLen + ((ignoreDot) ? 1 : 2); // 1 (for dot or [) + 1 (for null termination)

    if (wrapInBrackets)
    {
        totalLength++; //1 for ']';
    }
    WCHAR * finalName = AllocateStringOfLength(totalLength);

    if (leftStr != nullptr && leftLen != 0)
    {
        wcscpy_s(finalName, leftLen + 1, leftStr);
    }

    if (ignoreAddDotWithSpace)
    {
        finalName[leftLen++] = (OLECHAR)_u(' ');
    }
    // mutually exclusive from ignoreAddDotWithSpace which is used for getters/setters

    else if (wrapInBrackets)
    {
        finalName[leftLen++] = (OLECHAR)_u('[');
        finalName[totalLength - 2] = (OLECHAR)_u(']');
    }
    else if (!ignoreDot)
    {
        finalName[leftLen++] = (OLECHAR)_u('.');
    }
    //ignore case falls through
    js_wmemcpy_s(finalName + leftLen, rightLen, rightStr, rightLen);
    finalName[totalLength - 1] = (OLECHAR)_u('\0');

    if (pNameLength != nullptr)
    {
        *pNameLength = totalLength - 1;
    }
    if (pShortNameOffset != nullptr)
    {
        *pShortNameOffset = leftLen;
    }

    return finalName;
}

WCHAR * Parser::AllocateStringOfLength(ULONG length)
{
    Assert(length > 0);
    ULONG totalBytes;
    if (ULongMult(length, sizeof(OLECHAR), &totalBytes) != S_OK)
    {
        Error(ERRnoMemory);
    }
    WCHAR* finalName = (WCHAR*)this->GetHashTbl()->GetAllocator()->Alloc(totalBytes);
    if (finalName == nullptr)
    {
        Error(ERRnoMemory);
    }
    return finalName;
}

LPCOLESTR Parser::AppendNameHints(IdentPtr left, IdentPtr right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
{
    if (pShortNameOffset != nullptr)
    {
        *pShortNameOffset = 0;
    }

    if (left == nullptr && !wrapInBrackets)
    {
        if (right)
        {
            *pNameLength = right->Cch();
            return right->Psz();
        }
        return nullptr;
    }

    uint32 leftLen = 0;
    LPCOLESTR leftStr = _u("");

    if (left != nullptr) // if wrapInBrackets is true
    {
        leftStr = left->Psz();
        leftLen = left->Cch();
    }

    if (right == nullptr)
    {
        *pNameLength = leftLen;
        return left->Psz();
    }
    uint32 rightLen = right->Cch();

    return AppendNameHints(leftStr, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
}

LPCOLESTR Parser::AppendNameHints(IdentPtr left, LPCOLESTR right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
{
    uint32 rightLen = (right == nullptr) ? 0 : (uint32)wcslen(right);

    if (pShortNameOffset != nullptr)
    {
        *pShortNameOffset = 0;
    }

    Assert(rightLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters

    if (left == nullptr && !wrapInBrackets)
    {
        *pNameLength = rightLen;
        return right;
    }

    LPCOLESTR leftStr = _u("");
    uint32 leftLen = 0;

    if (left != nullptr) // if wrapInBrackets is true
    {
        leftStr = left->Psz();
        leftLen = left->Cch();
    }

    if (rightLen == 0 && !wrapInBrackets)
    {
        *pNameLength = leftLen;
        return left->Psz();
    }

    return AppendNameHints(leftStr, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
}

LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, IdentPtr right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
{
    uint32 leftLen = (left == nullptr) ? 0 : (uint32)wcslen(left);

    if (pShortNameOffset != nullptr)
    {
        *pShortNameOffset = 0;
    }

    Assert(leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters

    if (left == nullptr || (leftLen == 0 && !wrapInBrackets))
    {
        if (right != nullptr)
        {
            *pNameLength = right->Cch();
            return right->Psz();
        }
        return nullptr;
    }

    if (right == nullptr)
    {
        *pNameLength = leftLen;
        return left;
    }
    uint32 rightLen = right->Cch();

    return AppendNameHints(left, leftLen, right->Psz(), rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
}


LPCOLESTR Parser::AppendNameHints(LPCOLESTR left, LPCOLESTR right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace, bool wrapInBrackets)
{
    uint32 leftLen = (left == nullptr) ? 0 : (uint32)wcslen(left);
    uint32 rightLen = (right == nullptr) ? 0 : (uint32)wcslen(right);
    if (pShortNameOffset != nullptr)
    {
        *pShortNameOffset = 0;
    }
    Assert(rightLen <= ULONG_MAX && leftLen <= ULONG_MAX); // name hints should not exceed ULONG_MAX characters

    if (leftLen == 0 && !wrapInBrackets)
    {
        *pNameLength = right ? rightLen : 0;
        return right;
    }

    if (rightLen == 0 && !wrapInBrackets)
    {
        *pNameLength = leftLen;
        return left;
    }

    return AppendNameHints(left, leftLen, right, rightLen, pNameLength, pShortNameOffset, ignoreAddDotWithSpace, wrapInBrackets);
}

/**
 * Emits a spread error if there is no ambiguity, or marks defers the error for
 * when we can determine if it is a rest error or a spread error.
 *
 * The ambiguity arises when we are parsing a lambda parameter list but we have
 * not seen the => token. At this point, we are either in a parenthesized
 * expression or a parameter list, and cannot issue an error until the matching
 * RParen has been scanned.
 *
 * The actual emission of the error happens in ParseExpr, when we first know if
 * the expression is a lambda parameter list or not.
 *
 */
void Parser::DeferOrEmitPotentialSpreadError(ParseNodePtr pnodeT)
{
    if (m_funcParenExprDepth > 0)
    {
        if (m_token.tk == tkRParen)
        {
            if (!m_deferEllipsisError)
            {
                // Capture only the first error instance. Because a lambda will cause a reparse in a formals context, we can assume
                // that this will be a spread error. Nested paren exprs will have their own error instance.
                this->GetScanner()->Capture(&m_deferEllipsisErrorLoc);
                m_deferEllipsisError = true;
            }
        }
        else
        {
            Error(ERRUnexpectedEllipsis);
        }
    }
    else
    {
        Error(ERRInvalidSpreadUse);
    }
}

bool Parser::IsTerminateToken(bool fAllowIn)
{
    return (m_token.tk == tkRCurly ||
        m_token.tk == tkRBrack ||
        m_token.tk == tkRParen ||
        m_token.tk == tkSColon ||
        m_token.tk == tkColon ||
        m_token.tk == tkComma ||
        m_token.tk == tkLimKwd ||
        (m_token.tk == tkIN && fAllowIn) ||
        this->GetScanner()->FHadNewLine());
}

/***************************************************************************
Parse an optional sub expression returning null if there was no expression.
Checks for no expression by looking for a token that can follow an
Expression grammar production.
***************************************************************************/
template<bool buildAST>
bool Parser::ParseOptionalExpr(ParseNodePtr* pnode, bool fUnaryOrParen, int oplMin, BOOL *pfCanAssign, BOOL fAllowIn, BOOL fAllowEllipsis, _Inout_opt_ IdentToken* pToken)
{
    *pnode = nullptr;
    if (IsTerminateToken(!fAllowIn))
    {
        return false;
    }

    IdentToken token;
    ParseNodePtr pnodeT = ParseExpr<buildAST>(oplMin, pfCanAssign, fAllowIn, fAllowEllipsis, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, fUnaryOrParen);
    // Detect nested function escapes of the pattern "return function(){...}" or "yield function(){...}".
    // Doing so in the parser allows us to disable stack-nested-functions in common cases where an escape
    // is not detected at byte code gen time because of deferred parsing.
    this->MarkEscapingRef(pnodeT, &token);
    if (pToken)
    {
        *pToken = token;
    }
    *pnode = pnodeT;
    return true;
}

/***************************************************************************
Parse a sub expression.
'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
expression ( it is not allowed in the context of the first expression in a  'for' loop).
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseExpr(int oplMin,
    BOOL *pfCanAssign,
    BOOL fAllowIn,
    BOOL fAllowEllipsis,
    LPCOLESTR pNameHint,
    uint32 *pHintLength,
    uint32 *pShortNameOffset,
    _Inout_opt_ IdentToken* pToken,
    bool fUnaryOrParen,
    _Inout_opt_ bool* pfLikelyPattern,
    _Inout_opt_ charcount_t *plastRParen)
{
    Assert(pToken == nullptr || pToken->tk == tkNone); // Must be empty initially
    int opl;
    OpCode nop;
    charcount_t ichMin;
    ParseNodePtr pnode = nullptr;
    ParseNodePtr pnodeT = nullptr;
    BOOL fCanAssign = TRUE;
    bool assignmentStmt = false;
    bool fIsDotOrIndex = false;
    IdentToken term;
    RestorePoint termStart;
    uint32 hintLength = 0;
    uint32 hintOffset = 0;
    BOOL fLikelyPattern = FALSE;

    ParserState parserState;

    if (pHintLength != nullptr)
    {
        hintLength = *pHintLength;
    }

    if (pShortNameOffset != nullptr)
    {
        hintOffset = *pShortNameOffset;
    }

    EnsureStackAvailable();

    // Storing the state here as we need to restore this state back when we need to reparse the grammar under lambda syntax.
    CaptureState(&parserState);

    this->GetScanner()->Capture(&termStart);

    bool savedDeferredInitError = m_hasDeferredShorthandInitError;
    m_hasDeferredShorthandInitError = false;

    // Is the current token a unary operator?
    if (this->GetHashTbl()->TokIsUnop(m_token.tk, &opl, &nop) && nop != knopNone)
    {
        IdentToken operandToken;
        ichMin = this->GetScanner()->IchMinTok();

        if (nop == knopYield)
        {
            if (!this->GetScanner()->YieldIsKeywordRegion() || oplMin > opl)
            {
                // The case where 'yield' is scanned as a keyword (tkYIELD) but the scanner
                // is not treating yield as a keyword (!this->GetScanner()->YieldIsKeywordRegion()) occurs
                // in strict mode non-generator function contexts.
                //
                // That is, 'yield' is a keyword because of strict mode, but YieldExpression
                // is not a grammar production outside of generator functions.
                //
                // Otherwise it is an error for a yield to appear in the context of a higher level
                // binding operator, be it unary or binary.
                Error(ERRsyntax);
            }
            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_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())
                // occurs in strict mode non-async function contexts.
                //
                // That is, 'await' is a keyword because of strict mode, but AwaitExpression
                // is not a grammar production outside of async functions.
                //
                // Further, await expressions are disallowed within parameter scopes.
                Error(ERRBadAwait);
            }
        }

        this->GetScanner()->Scan();

        if (m_token.tk == tkEllipsis) {
            // ... cannot have a unary prefix.
            Error(ERRUnexpectedEllipsis);
        }

        if (nop == knopYield && !this->GetScanner()->FHadNewLine() && m_token.tk == tkStar)
        {
            this->GetScanner()->Scan();
            nop = knopYieldStar;
        }

        if (nop == knopYield)
        {
            if (!ParseOptionalExpr<buildAST>(&pnodeT, false, opl, NULL, fAllowIn, fAllowEllipsis))
            {
                nop = knopYieldLeaf;
                if (buildAST)
                {
                    pnode = CreateNodeForOpT<knopYieldLeaf>(ichMin, this->GetScanner()->IchLimTok());
                }
            }
        }
        else if (nop == knopAwait && m_token.tk == tkColon)
        {
            Error(ERRAwaitAsLabelInAsync);
        }
        else
        {
            // Disallow spread after a unary operator.
            pnodeT = ParseExpr<buildAST>(opl, &fCanAssign, TRUE, FALSE, nullptr /*hint*/, nullptr /*hintLength*/, nullptr /*hintOffset*/, &operandToken, true, nullptr, plastRParen);
        }

        if (nop != knopYieldLeaf)
        {
            if ((nop == knopIncPre || nop == knopDecPre) && (m_token.tk != tkDArrow))
            {
                if (!fCanAssign && 
                    (m_sourceContextInfo 
                     ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
                     : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
                {
                    Error(JSERR_CantAssignTo);
                }
                TrackAssignment<buildAST>(pnodeT, &operandToken);
                if (buildAST)
                {
                    if (IsStrictMode() && pnodeT->nop == knopName)
                    {
                        CheckStrictModeEvalArgumentsUsage(pnodeT->AsParseNodeName()->pid);
                    }
                }
                else
                {
                    if (IsStrictMode() && operandToken.tk == tkID)
                    {
                        CheckStrictModeEvalArgumentsUsage(operandToken.pid);
                    }
                }
            }
            else if (nop == knopEllipsis)
            {
                if (!fAllowEllipsis)
                {
                    DeferOrEmitPotentialSpreadError(pnodeT);
                }
            }
            else if (m_token.tk == tkExpo)
            {
                //Unary operator on the left hand-side of ** is unexpected, except ++, -- or ...
                Error(ERRInvalidUseofExponentiationOperator);
            }

            if (buildAST)
            {
                //Do not do the folding for Asm in case of KnopPos as we need this to determine the type
                if (nop == knopPos && (pnodeT->nop == knopInt || pnodeT->nop == knopFlt) && !this->m_InAsmMode)
                {
                    // Fold away a unary '+' on a number.
                    pnode = pnodeT;
                }
                else if (nop == knopNeg &&
                    ((pnodeT->nop == knopInt && pnodeT->AsParseNodeInt()->lw != 0) ||
                    (pnodeT->nop == knopFlt && (pnodeT->AsParseNodeFloat()->dbl != 0 || this->m_InAsmMode)) ||
                    (pnodeT->nop == knopBigInt)))
                {
                    // Fold a unary '-' on a number into the value of the number itself.
                    pnode = pnodeT;
                    if (pnode->nop == knopInt)
                    {
                        pnode->AsParseNodeInt()->lw = -pnode->AsParseNodeInt()->lw;
                    }
                    else if (pnode->nop == knopBigInt)
                    {
                        pnode->AsParseNodeBigInt()->isNegative = true;
                    }
                    else 
                    {
                        pnode->AsParseNodeFloat()->dbl = -pnode->AsParseNodeFloat()->dbl;
                    }
                }
                else
                {
                    pnode = CreateUniNode(nop, pnodeT);
                    this->CheckArguments(pnode->AsParseNodeUni()->pnode1);
                }
                pnode->ichMin = ichMin;
            }

            if (nop == knopDelete)
            {
                if (IsStrictMode())
                {
                    if ((buildAST && pnode->AsParseNodeUni()->pnode1->IsUserIdentifier()) ||
                        (!buildAST && operandToken.tk == tkID && !this->IsSpecialName(operandToken.pid)))
                    {
                        Error(ERRInvalidDelete);
                    }
                }

                if (buildAST)
                {
                    ParseNodePtr pnode1 = pnode->AsParseNodeUni()->pnode1;
                    if (m_currentNodeFunc)
                    {
                        if (pnode1->nop == knopDot || pnode1->nop == knopIndex)
                        {
                            // If we delete an arguments property, use the conservative,
                            // heap-allocated arguments object.
                            this->CheckArguments(pnode1->AsParseNodeBin()->pnode1);
                        }
                    }
                }
            }
        }

        fCanAssign = FALSE;
    }
    else
    {
        ichMin = this->GetScanner()->IchMinTok();
        pnode = ParseTerm<buildAST>(TRUE, pNameHint, &hintLength, &hintOffset, &term, fUnaryOrParen, TRUE, &fCanAssign, IsES6DestructuringEnabled() ? &fLikelyPattern : nullptr, &fIsDotOrIndex, plastRParen);
        if (pfLikelyPattern != nullptr)
        {
            *pfLikelyPattern = !!fLikelyPattern;
        }

        if (m_token.tk == tkDArrow
            // If we have introduced shorthand error above in the ParseExpr, we need to reset if next token is the assignment.
            || (m_token.tk == tkAsg && oplMin <= koplAsg))
        {
            m_hasDeferredShorthandInitError = false;
        }

        if (m_token.tk == tkAsg && oplMin <= koplAsg && fLikelyPattern)
        {
            this->GetScanner()->SeekTo(termStart);

            // As we are reparsing from the beginning of the destructured literal we need to reset the Block IDs as well to make sure the Block IDs
            // on the pidref stack match.
            int saveNextBlockId = m_nextBlockId;
            m_nextBlockId = parserState.m_nextBlockId;

            ParseDestructuredLiteralWithScopeSave(tkLCurly, false/*isDecl*/, false /*topLevel*/, DIC_ShouldNotParseInitializer);

            // Restore the Block ID at the end of the reparsing so it matches the one at the end of the first pass. We need to do this 
            // because we don't parse initializers during reparse and there may be additional blocks (e.g. a class declaration)
            // in the initializers that will cause the next Block ID at the end of the reparsing to be different.
            m_nextBlockId = saveNextBlockId;

            if (buildAST)
            {
                this->SetHasDestructuringPattern(true);
                pnode = ConvertToPattern(pnode);
            }
        }

        if (buildAST)
        {
            pNameHint = NULL;
            if (pnode->nop == knopName)
            {
                IdentPtr pid = pnode->AsParseNodeName()->pid;
                pNameHint = pid->Psz();
                hintLength = pid->Cch();
                hintOffset = 0;
            }
            else if (pnode->nop == knopDot || pnode->nop == knopIndex)
            {
                if (CONFIG_FLAG(UseFullName))
                {
                    pNameHint = ConstructNameHint(pnode->AsParseNodeBin(), &hintLength, &hintOffset);
                }
                else
                {
                    ParseNodePtr pnodeName = pnode;
                    while (pnodeName->nop == knopDot)
                    {
                        pnodeName = pnodeName->AsParseNodeBin()->pnode2;
                    }

                    if (pnodeName->nop == knopName)
                    {
                        IdentPtr pid = pnode->AsParseNodeName()->pid;
                        pNameHint = pid->Psz();
                        hintLength = pid->Cch();
                        hintOffset = 0;
                    }
                }
            }
        }

        // Check for postfix unary operators.
        if (!this->GetScanner()->FHadNewLine() &&
            (tkInc == m_token.tk || tkDec == m_token.tk))
        {
            if (!fCanAssign && 
                (m_sourceContextInfo 
                 ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
                 : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
            {
                Error(JSERR_CantAssignTo);
            }
            TrackAssignment<buildAST>(pnode, &term);
            fCanAssign = FALSE;
            if (buildAST)
            {
                if (IsStrictMode() && pnode->nop == knopName)
                {
                    CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodeName()->pid);
                }
                this->CheckArguments(pnode);
                pnode = CreateUniNode(tkInc == m_token.tk ? knopIncPost : knopDecPost, pnode);
                pnode->ichLim = this->GetScanner()->IchLimTok();
            }
            else
            {
                if (IsStrictMode() && term.tk == tkID)
                {
                    CheckStrictModeEvalArgumentsUsage(term.pid);
                }
                // This expression is not an identifier
                term.tk = tkNone;
            }
            this->GetScanner()->Scan();
        }
    }

    // Process a sequence of operators and operands.
    for (;;)
    {
        if (!this->GetHashTbl()->TokIsBinop(m_token.tk, &opl, &nop) || nop == knopNone)
        {
            break;
        }
        if (!fAllowIn && nop == knopIn)
        {
            break;
        }
        Assert(opl != koplNo);

        if (opl == koplAsg)
        {
            if (m_token.tk != tkDArrow)
            {
                // Assignment operator. These are the only right associative
                // binary operators. We also need to special case the left
                // operand - it should only be a LeftHandSideExpression.
                Assert(ParseNode::Grfnop(nop) & fnopAsg || nop == knopFncDecl);
                TrackAssignment<buildAST>(pnode, &term);
                if (buildAST)
                {
                    if (IsStrictMode() && pnode->nop == knopName)
                    {
                        CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodeName()->pid);
                    }

                    // Assignment stmt of the form "this.<id> = <expr>"
                    if (nop == knopAsg
                        && pnode->nop == knopDot
                        && pnode->AsParseNodeBin()->pnode1->nop == knopName
                        && pnode->AsParseNodeBin()->pnode1->AsParseNodeName()->pid == wellKnownPropertyPids._this
                        && pnode->AsParseNodeBin()->pnode2->nop == knopName)
                    {
                        if (pnode->AsParseNodeBin()->pnode2->AsParseNodeName()->pid != wellKnownPropertyPids.__proto__)
                        {
                            assignmentStmt = true;
                        }
                    }
                }
                else
                {
                    if (IsStrictMode() && term.tk == tkID)
                    {
                        CheckStrictModeEvalArgumentsUsage(term.pid);
                    }
                }
            }

            if (opl < oplMin)
            {
                break;
            }
            if (m_token.tk != tkDArrow && !fCanAssign && 
                (m_sourceContextInfo 
                 ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
                 : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
            {
                Error(JSERR_CantAssignTo);
                // No recovery necessary since this is a semantic, not structural, error.
            }
        }
        else if (opl == koplExpo)
        {
            // ** operator is right associative
            if (opl < oplMin)
            {
                break;
            }

        }
        else if (opl <= oplMin)
        {
            break;
        }

        // This expression is not an identifier
        term.tk = tkNone;

        // Precedence is high enough. Consume the operator token.
        this->GetScanner()->Scan();
        fCanAssign = !!fLikelyPattern;

        // Special case the "?:" operator
        if (nop == knopQmark)
        {
            pnodeT = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn);
            ChkCurTok(tkColon, ERRnoColon);
            ParseNodePtr pnodeT2 = ParseExpr<buildAST>(koplAsg, NULL, fAllowIn, 0, nullptr, nullptr, nullptr, nullptr, false, nullptr, plastRParen);
            if (buildAST)
            {
                pnode = CreateTriNode(nop, pnode, pnodeT, pnodeT2);
                this->CheckArguments(pnode->AsParseNodeTri()->pnode2);
                this->CheckArguments(pnode->AsParseNodeTri()->pnode3);
            }
        }
        else if (nop == knopFncDecl)
        {
            ushort flags = fFncLambda;
            size_t iecpMin = 0;
            bool isAsyncMethod = false;

            RestoreStateFrom(&parserState);

            this->GetScanner()->SeekTo(termStart);
            if (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
            {
                ichMin = this->GetScanner()->IchMinTok();
                iecpMin = this->GetScanner()->IecpMinTok();

                this->GetScanner()->Scan();
                if ((m_token.tk == tkID || m_token.tk == tkLParen) && !this->GetScanner()->FHadNewLine())
                {
                    flags |= fFncAsync;
                    isAsyncMethod = true;
                }
                else
                {
                    this->GetScanner()->SeekTo(termStart);
                }
            }
            pnode = ParseFncDeclNoCheckScope<buildAST>(flags, SuperRestrictionState::Disallowed, nullptr, /* needsPIDOnRCurlyScan = */false, /* fUnaryOrParen = */ false, fAllowIn);
            if (isAsyncMethod)
            {
                pnode->AsParseNodeFnc()->cbStringMin = iecpMin;
            }

            // ArrowFunction/AsyncArrowFunction is part of AssignmentExpression, which should terminate the expression unless followed by a comma
            if (m_token.tk != tkComma && m_token.tk != tkIN)
            {
                if (!(IsTerminateToken(false)))
                {
                    Error(ERRnoSemic);
                }
                break;
            }
        }
        else // a binary operator
        {
            if (nop == knopComma && m_token.tk == tkRParen)
            {
                // Trailing comma
                this->GetScanner()->Capture(&m_deferCommaErrorLoc);
                m_deferCommaError = true;
                break;
            }

            ParseNode* pnode1 = pnode;

            // Parse the operand, make a new node, and look for more
            IdentToken token;
            ParseNode* pnode2 = ParseExpr<buildAST>(
                opl, nullptr, fAllowIn, FALSE, pNameHint, &hintLength, &hintOffset, &token, false, nullptr, plastRParen);

            // Detect nested function escapes of the pattern "o.f = function(){...}" or "o[s] = function(){...}".
            // Doing so in the parser allows us to disable stack-nested-functions in common cases where an escape
            // is not detected at byte code gen time because of deferred parsing.
            if (fIsDotOrIndex && nop == knopAsg)
            {
                this->MarkEscapingRef(pnodeT, &token);
            }

            if (buildAST)
            {
                Assert(pnode2 != nullptr);
                if (pnode2->nop == knopFncDecl)
                {
                    Assert(hintLength >= hintOffset);
                    pnode2->AsParseNodeFnc()->hint = pNameHint;
                    pnode2->AsParseNodeFnc()->hintLength = hintLength;
                    pnode2->AsParseNodeFnc()->hintOffset = hintOffset;

                    if (pnode1->nop == knopDot)
                    {
                        pnode2->AsParseNodeFnc()->isNameIdentifierRef = false;
                    }
                    else if (pnode1->nop == knopName)
                    {
                        PidRefStack *pidRef = pnode1->AsParseNodeName()->pid->GetTopRef();
                        pidRef->isFuncAssignment = true;
                    }
                }
                else if (pnode2->nop == knopClassDecl && pnode1->nop == knopDot)
                {
                    Assert(pnode2->AsParseNodeClass()->pnodeConstructor);

                    if (!pnode2->AsParseNodeClass()->pnodeConstructor->pid)
                    {
                        pnode2->AsParseNodeClass()->pnodeConstructor->isNameIdentifierRef = false;
                    }
                }
                else if (pnode1->nop == knopName && nop == knopIn)
                {
                    PidRefStack* pidRef = pnode1->AsParseNodeName()->pid->GetTopRef();
                    pidRef->SetIsUsedInLdElem(true);
                }

                pnode = CreateBinNode(nop, pnode1, pnode2);
            }
            pNameHint = nullptr;
        }
    }

    if (buildAST)
    {
        if (!assignmentStmt)
        {
            // Don't set the flag for following nodes
            switch (pnode->nop)
            {
            case knopName:
            case knopInt:
            case knopBigInt:
            case knopFlt:
            case knopStr:
            case knopRegExp:
            case knopNull:
            case knopFalse:
            case knopTrue:
                break;
            default:
                if (m_currentNodeFunc)
                {
                    m_currentNodeFunc->SetHasNonThisStmt();
                }
                else if (m_currentNodeProg)
                {
                    m_currentNodeProg->SetHasNonThisStmt();
                }
            }
        }
    }

    m_hasDeferredShorthandInitError = m_hasDeferredShorthandInitError || savedDeferredInitError;

    if (NULL != pfCanAssign)
    {
        *pfCanAssign = fCanAssign;
    }

    // Pass back identifier if requested
    if (pToken && term.tk == tkID)
    {
        *pToken = term;
    }

    //Track "obj.a" assignment patterns here - Promote the Assignment state for the property's PID.
    // This includes =, += etc.
    if (pnode != NULL)
    {
        uint nodeType = ParseNode::Grfnop(pnode->nop);
        if (nodeType & fnopAsg)
        {
            if (nodeType & fnopBin)
            {
                ParseNodePtr lhs = pnode->AsParseNodeBin()->pnode1;

                Assert(lhs);
                if (lhs->nop == knopDot)
                {
                    ParseNodePtr propertyNode = lhs->AsParseNodeBin()->pnode2;
                    if (propertyNode->nop == knopName)
                    {
                        propertyNode->AsParseNodeName()->pid->PromoteAssignmentState();
                    }
                }
            }
            else if (nodeType & fnopUni)
            {
                // cases like obj.a++, ++obj.a
                ParseNodePtr lhs = pnode->AsParseNodeUni()->pnode1;
                if (lhs->nop == knopDot)
                {
                    ParseNodePtr propertyNode = lhs->AsParseNodeBin()->pnode2;
                    if (propertyNode->nop == knopName)
                    {
                        propertyNode->AsParseNodeName()->pid->PromoteAssignmentState();
                    }
                }
            }
        }
    }
    return pnode;
}

template<bool buildAST>
void Parser::TrackAssignment(ParseNodePtr pnodeT, IdentToken* pToken)
{
    if (buildAST)
    {
        Assert(pnodeT != nullptr);
        if (pnodeT->nop == knopName)
        {
            PidRefStack *ref = pnodeT->AsParseNodeName()->pid->GetTopRef();
            Assert(ref);
            ref->isAsg = true;
        }
    }
    else
    {
        Assert(pToken != nullptr);
        if (pToken->tk == tkID)
        {
            PidRefStack *ref = pToken->pid->GetTopRef();
            Assert(ref);
            ref->isAsg = true;
        }
    }
}

PidRefStack* Parser::PushPidRef(IdentPtr pid)
{
    ParseNodeFnc* currentFnc = GetCurrentFunctionNode();

    if (this->IsCreatingStateCache())
    {
        IdentPtrSet* capturedNames = currentFnc->EnsureCapturedNames(&m_nodeAllocator);
        capturedNames->AddNew(pid);
    }

    if (PHASE_ON1(Js::ParallelParsePhase))
    {
        // NOTE: the phase check is here to protect perf. See OSG 1020424.
        // In some LS AST-rewrite cases we lose a lot of perf searching the PID ref stack rather
        // than just pushing on the top. This hasn't shown up as a perf issue in non-LS benchmarks.
        return pid->FindOrAddPidRef(&m_nodeAllocator, GetCurrentBlock()->blockId, currentFnc->functionId);
    }

    Assert(GetCurrentBlock() != nullptr);
    AssertMsg(pid != nullptr, "PID should be created");
    PidRefStack *ref = pid->GetTopRef(m_nextBlockId - 1);
    int blockId = GetCurrentBlock()->blockId;
    int funcId = currentFnc->functionId;
    if (!ref || (ref->GetScopeId() < blockId))
    {
        ref = Anew(&m_nodeAllocator, PidRefStack);
        if (ref == nullptr)
        {
            Error(ERRnoMemory);
        }
        pid->PushPidRef(blockId, funcId, ref);
    }
    else if (m_reparsingLambdaParams)
    {
        // If we're reparsing params, then we may have pid refs left behind from the first pass. Make sure we're
        // working with the right ref at this point.
        ref = this->FindOrAddPidRef(pid, blockId, funcId);
        // Fix up the function ID if we're reparsing lambda parameters.
        ref->funcId = funcId;
    }

    return ref;
}

PidRefStack* Parser::FindOrAddPidRef(IdentPtr pid, int scopeId, Js::LocalFunctionId funcId)
{
    PidRefStack *ref = pid->FindOrAddPidRef(&m_nodeAllocator, scopeId, funcId);
    if (ref == NULL)
    {
        Error(ERRnoMemory);
    }
    return ref;
}

void Parser::RemovePrevPidRef(IdentPtr pid, PidRefStack *ref)
{
    PidRefStack *prevRef = pid->RemovePrevPidRef(ref);
    Assert(prevRef);
    if (prevRef->GetSym() == nullptr)
    {
        AllocatorDelete(ArenaAllocator, &m_nodeAllocator, prevRef);
    }
}

void Parser::SetPidRefsInScopeDynamic(IdentPtr pid, int blockId)
{
    PidRefStack *ref = pid->GetTopRef();
    while (ref && ref->GetScopeId() >= blockId)
    {
        ref->SetDynamicBinding();
        ref = ref->prev;
    }
}

ParseNodeBlock* Parser::GetFunctionBlock()
{
    Assert(m_currentBlockInfo != nullptr);
    return m_currentBlockInfo->pBlockInfoFunction->pnodeBlock;
}


ParseNodeBlock* Parser::GetCurrentBlock()
{
    return m_currentBlockInfo != nullptr ? m_currentBlockInfo->pnodeBlock : nullptr;
}

BlockInfoStack* Parser::GetCurrentBlockInfo()
{
    return m_currentBlockInfo;
}

BlockInfoStack* Parser::GetCurrentFunctionBlockInfo()
{
    return m_currentBlockInfo->pBlockInfoFunction;
}

/***************************************************************************
Parse a variable declaration.
'fAllowIn' indicates if the 'in' operator should be allowed in the initializing
expression ( it is not allowed in the context of the first expression in a  'for' loop).
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseVariableDeclaration(
    tokens declarationType, charcount_t ichMin,
    BOOL fAllowIn/* = TRUE*/,
    BOOL* pfForInOk/* = nullptr*/,
    BOOL singleDefOnly/* = FALSE*/,
    BOOL allowInit/* = TRUE*/,
    BOOL isTopVarParse/* = TRUE*/,
    BOOL isFor/* = FALSE*/,
    BOOL* nativeForOk /*= nullptr*/)
{
    ParseNodePtr pnodeThis = nullptr;
    ParseNodePtr pnodeInit;
    ParseNodePtr pnodeList = nullptr;
    ParseNodePtr *lastNodeRef = nullptr;
    LPCOLESTR pNameHint = nullptr;
    uint32     nameHintLength = 0;
    uint32     nameHintOffset = 0;
    Assert(declarationType == tkVAR || declarationType == tkCONST || declarationType == tkLET);

    for (;;)
    {
        if (IsES6DestructuringEnabled() && IsPossiblePatternStart())
        {
            pnodeThis = ParseDestructuredLiteral<buildAST>(declarationType, true, !!isTopVarParse, DIC_None, !!fAllowIn, pfForInOk, nativeForOk);
            if (pnodeThis != nullptr)
            {
                pnodeThis->ichMin = ichMin;
                pnodeThis->SetIsPatternDeclaration();
            }
        }
        else
        {
            if (m_token.tk != tkID)
            {
                IdentifierExpectedError(m_token);
            }

            IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
            Assert(pid);
            pNameHint = pid->Psz();
            nameHintLength = pid->Cch();
            nameHintOffset = 0;

            if (pid == wellKnownPropertyPids.let && (declarationType == tkCONST || declarationType == tkLET))
            {
                Error(ERRLetIDInLexicalDecl, pnodeThis);
            }

            if (declarationType == tkVAR)
            {
                pnodeThis = CreateVarDeclNode(pid, STVariable);
            }
            else if (declarationType == tkCONST)
            {
                pnodeThis = CreateBlockScopedDeclNode(pid, knopConstDecl);
                CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Const, m_scriptContext);
            }
            else
            {
                pnodeThis = CreateBlockScopedDeclNode(pid, knopLetDecl);
                CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Let, m_scriptContext);
            }

            if (pid == wellKnownPropertyPids.arguments)
            {
                // This var declaration may change the way an 'arguments' identifier in the function is resolved
                if (declarationType == tkVAR)
                {
                    GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_varDeclaration;
                }
                else
                {
                    if (GetCurrentBlockInfo()->pnodeBlock->blockType == Function)
                    {
                        // Only override arguments if we are at the function block level.
                        GetCurrentFunctionNode()->grfpn |= PNodeFlags::fpnArguments_overriddenByDecl;
                    }
                }
            }

            if (pnodeThis)
            {
                pnodeThis->ichMin = ichMin;
            }

            this->GetScanner()->Scan();

            if (m_token.tk == tkAsg)
            {
                if (!allowInit)
                {
                    Error(ERRUnexpectedDefault);
                }
                if (pfForInOk && (declarationType == tkLET || declarationType == tkCONST || IsStrictMode()))
                {
                    *pfForInOk = FALSE;
                }

                this->GetScanner()->Scan();
                pnodeInit = ParseExpr<buildAST>(koplCma, nullptr, fAllowIn, FALSE, pNameHint, &nameHintLength, &nameHintOffset);
                if (buildAST)
                {
                    AnalysisAssert(pnodeThis);
                    pnodeThis->AsParseNodeVar()->pnodeInit = pnodeInit;
                    pnodeThis->ichLim = pnodeInit->ichLim;

                    if (pnodeInit->nop == knopFncDecl)
                    {
                        Assert(nameHintLength >= nameHintOffset);
                        pnodeInit->AsParseNodeFnc()->hint = pNameHint;
                        pnodeInit->AsParseNodeFnc()->hintLength = nameHintLength;
                        pnodeInit->AsParseNodeFnc()->hintOffset = nameHintOffset;
                        pnodeThis->AsParseNodeVar()->pid->GetTopRef()->isFuncAssignment = true;
                    }
                    else
                    {
                        this->CheckArguments(pnodeInit);
                    }
                    pNameHint = nullptr;
                }

                //Track var a =, let a= , const a =
                // This is for FixedFields Constant Heuristics
                if (pnodeThis && pnodeThis->AsParseNodeVar()->pnodeInit != nullptr)
                {
                    pnodeThis->AsParseNodeVar()->sym->PromoteAssignmentState();
                }
            }
            else if (declarationType == tkCONST /*pnodeThis->nop == knopConstDecl*/
                && !singleDefOnly
                && !(isFor && TokIsForInOrForOf()))
            {
                Error(ERRUninitializedConst);
            }

            if (m_currentNodeFunc && pnodeThis && pnodeThis->AsParseNodeVar()->sym->GetIsFormal())
            {
                m_currentNodeFunc->SetHasAnyWriteToFormals(true);
            }
        }

        if (singleDefOnly)
        {
            return pnodeThis;
        }

        if (buildAST)
        {
            AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeThis);
        }

        if (m_token.tk != tkComma)
        {
            return pnodeList;
        }

        if (pfForInOk)
        {
            // don't allow "for (var a, b in c)"
            *pfForInOk = FALSE;
        }
        this->GetScanner()->Scan();
        ichMin = this->GetScanner()->IchMinTok();
    }
}

/***************************************************************************
Parse try-catch-finally statement
***************************************************************************/

// The try-catch-finally tree nests the try-catch within a try-finally.
// This matches the new runtime implementation.
template<bool buildAST>
ParseNodeStmt * Parser::ParseTryCatchFinally()
{
    this->m_tryCatchOrFinallyDepth++;

    ParseNodeTry * pnodeT = ParseTry<buildAST>();
    ParseNodeTryCatch * pnodeTC = nullptr;
    StmtNest stmt;
    bool hasCatch = false;

    if (tkCATCH == m_token.tk)
    {
        hasCatch = true;
        if (buildAST)
        {
            pnodeTC = CreateNodeForOpT<knopTryCatch>();
            pnodeT->pnodeOuter = pnodeTC;
            pnodeTC->pnodeTry = pnodeT;
        }
        PushStmt<buildAST>(&stmt, pnodeTC, knopTryCatch, nullptr);

        ParseNodeCatch * pnodeCatch = ParseCatch<buildAST>();
        if (buildAST)
        {
            pnodeTC->pnodeCatch = pnodeCatch;
        }
        PopStmt(&stmt);
    }
    if (tkFINALLY != m_token.tk)
    {
        if (!hasCatch)
        {
            Error(ERRnoCatch);
        }
        Assert(!buildAST || pnodeTC);
        this->m_tryCatchOrFinallyDepth--;
        return pnodeTC;
    }

    ParseNodeTryFinally * pnodeTF = nullptr;
    if (buildAST)
    {
        pnodeTF = CreateNodeForOpT<knopTryFinally>();
    }
    PushStmt<buildAST>(&stmt, pnodeTF, knopTryFinally, nullptr);
    ParseNodeFinally * pnodeFinally = ParseFinally<buildAST>();
    if (buildAST)
    {
        if (!hasCatch)
        {
            pnodeTF->pnodeTry = pnodeT;
            pnodeT->pnodeOuter = pnodeTF;
        }
        else
        {
            pnodeTF->pnodeTry = CreateNodeForOpT<knopTry>();
            pnodeTF->pnodeTry->pnodeOuter = pnodeTF;
            pnodeTF->pnodeTry->pnodeBody = pnodeTC;
            pnodeTC->pnodeOuter = pnodeTF->pnodeTry;
        }
        pnodeTF->pnodeFinally = pnodeFinally;
    }
    PopStmt(&stmt);
    this->m_tryCatchOrFinallyDepth--;
    return pnodeTF;
}

template<bool buildAST>
ParseNodeTry * Parser::ParseTry()
{
    ParseNodeTry * pnode = nullptr;
    StmtNest stmt;
    Assert(tkTRY == m_token.tk);
    if (buildAST)
    {
        pnode = CreateNodeForOpT<knopTry>();
    }
    this->GetScanner()->Scan();
    if (tkLCurly != m_token.tk)
    {
        Error(ERRnoLcurly);
    }

    PushStmt<buildAST>(&stmt, pnode, knopTry, nullptr);
    ParseNodePtr pnodeBody = ParseStatement<buildAST>();
    if (buildAST)
    {
        pnode->pnodeBody = pnodeBody;
        if (pnode->pnodeBody)
            pnode->ichLim = pnode->pnodeBody->ichLim;
    }
    PopStmt(&stmt);
    return pnode;
}

template<bool buildAST>
ParseNodeFinally * Parser::ParseFinally()
{
    ParseNodeFinally * pnode = nullptr;
    StmtNest stmt;
    Assert(tkFINALLY == m_token.tk);
    if (buildAST)
    {
        pnode = CreateNodeForOpT<knopFinally>();
    }
    this->GetScanner()->Scan();
    if (tkLCurly != m_token.tk)
    {
        Error(ERRnoLcurly);
    }

    PushStmt<buildAST>(&stmt, pnode, knopFinally, nullptr);
    ParseNodePtr pnodeBody = ParseStatement<buildAST>();
    if (buildAST)
    {
        pnode->pnodeBody = pnodeBody;
        if (!pnode->pnodeBody)
            // Will only occur due to error correction.
            pnode->pnodeBody = CreateNodeForOpT<knopEmpty>();
        else
            pnode->ichLim = pnode->pnodeBody->ichLim;
    }
    PopStmt(&stmt);

    return pnode;
}

template<bool buildAST>
ParseNodeCatch * Parser::ParseCatch()
{
    ParseNodePtr *ppnodeExprScopeSave = nullptr;
    ParseNodeCatch * pnode = nullptr;
    ParseNodeBlock * pnodeCatchScope = nullptr;
    StmtNest stmt;
    IdentPtr pidCatch = nullptr;

    if (tkCATCH == m_token.tk)
    {
        charcount_t ichMin;
        if (buildAST)
        {
            ichMin = this->GetScanner()->IchMinTok();
        }
        this->GetScanner()->Scan(); //catch

        bool isPattern = false;
        bool hasParam = false;

        if (tkLParen == m_token.tk)
        {
            hasParam = true;
            this->GetScanner()->Scan(); //catch(
            if (tkID != m_token.tk)
            {
                isPattern = IsES6DestructuringEnabled() && IsPossiblePatternStart();
                if (!isPattern)
                {
                    IdentifierExpectedError(m_token);
                }
            }
        }

        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopCatch>(ichMin);
            pnode->pnodeNext = nullptr;
            PushStmt<buildAST>(&stmt, pnode, knopCatch, nullptr);
        }

        pnodeCatchScope = StartParseBlock<buildAST>(PnodeBlockType::Regular, isPattern ? ScopeType_CatchParamPattern : ScopeType_Catch);

        if (buildAST)
        {
            // Add this catch to the current scope list.

            if (m_ppnodeExprScope)
            {
                Assert(*m_ppnodeExprScope == nullptr);
                *m_ppnodeExprScope = pnode;
                m_ppnodeExprScope = &pnode->pnodeNext;
            }
            else
            {
                Assert(m_ppnodeScope);
                Assert(*m_ppnodeScope == nullptr);
                *m_ppnodeScope = pnode;
                m_ppnodeScope = &pnode->pnodeNext;
            }

            // Keep a list of function expressions (not declarations) at this scope.

            ppnodeExprScopeSave = m_ppnodeExprScope;
            m_ppnodeExprScope = &pnode->pnodeScopes;
            pnode->pnodeScopes = nullptr;
        }

        if (isPattern)
        {
            ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, true /*topLevel*/, DIC_ForceErrorOnInitializer);
            if (buildAST)
            {
                pnode->SetParam(CreateParamPatternNode(pnodePattern));
                Scope *scope = pnodeCatchScope->scope;
                pnode->scope = scope;
            }
        }
        else if (hasParam)
        {
            if (IsStrictMode())
            {
                IdentPtr pid = m_token.GetIdentifier(this->GetHashTbl());
                if (pid == wellKnownPropertyPids.eval)
                {
                    Error(ERREvalUsage);
                }
                else if (pid == wellKnownPropertyPids.arguments)
                {
                    Error(ERRArgsUsage);
                }
            }

            pidCatch = m_token.GetIdentifier(this->GetHashTbl());
            PidRefStack *ref = this->FindOrAddPidRef(pidCatch, GetCurrentBlock()->blockId, GetCurrentFunctionNode()->functionId);

            ParseNodeName * pnodeParam = CreateNameNode(pidCatch);
            pnodeParam->SetSymRef(ref);

            const char16 *name = reinterpret_cast<const char16*>(pidCatch->Psz());
            int nameLength = pidCatch->Cch();
            SymbolName const symName(name, nameLength);
            Symbol *sym = Anew(&m_nodeAllocator, Symbol, symName, pnodeParam, STVariable);
            if (sym == nullptr)
            {
                Error(ERRnoMemory);
            }
            sym->SetPid(pidCatch);
            Assert(ref->GetSym() == nullptr);
            ref->SetSym(sym);

            Scope *scope = pnodeCatchScope->scope;
            scope->AddNewSymbol(sym);

            if (buildAST)
            {
                pnode->SetParam(pnodeParam);
                pnode->scope = scope;
            }

            this->GetScanner()->Scan();
        }
        else
        {
            if (buildAST)
            {
                pnode->scope = pnodeCatchScope->scope;
            }
        }

        charcount_t ichLim;
        if (buildAST)
        {
            ichLim = this->GetScanner()->IchLimTok();
        }

        if (hasParam)
        {
            ChkCurTok(tkRParen, ERRnoRparen); //catch(id[:expr])
        }

        if (tkLCurly != m_token.tk)
        {
            Error(ERRnoLcurly);
        }

        ParseNodePtr pnodeBody = ParseStatement<buildAST>();  //catch(id[:expr]) {block}
        if (buildAST)
        {
            pnode->pnodeBody = pnodeBody;
            pnode->ichLim = ichLim;
        }

        if (pnodeCatchScope != nullptr)
        {
            FinishParseBlock(pnodeCatchScope);
        }

        if (pnodeCatchScope->GetCallsEval() || pnodeCatchScope->GetChildCallsEval())
        {
            GetCurrentBlock()->SetChildCallsEval(true);
        }

        if (buildAST)
        {
            PopStmt(&stmt);

            // Restore the lists of function expression scopes.

            Assert(m_ppnodeExprScope);
            Assert(*m_ppnodeExprScope == nullptr);
            m_ppnodeExprScope = ppnodeExprScopeSave;
        }
    }
    return pnode;
}

template<bool buildAST>
ParseNodeCase * Parser::ParseCase(ParseNodePtr *ppnodeBody)
{
    ParseNodeCase * pnodeT = nullptr;

    charcount_t ichMinT = this->GetScanner()->IchMinTok();
    this->GetScanner()->Scan();
    ParseNodePtr pnodeExpr = ParseExpr<buildAST>();
    charcount_t ichLim = this->GetScanner()->IchLimTok();

    ChkCurTok(tkColon, ERRnoColon);

    if (buildAST)
    {
        pnodeT = CreateNodeForOpT<knopCase>(ichMinT);
        pnodeT->pnodeExpr = pnodeExpr;
        pnodeT->ichLim = ichLim;
    }
    ParseStmtList<buildAST>(ppnodeBody);

    return pnodeT;
}

/***************************************************************************
Parse a single statement. Digest a trailing semicolon.
***************************************************************************/
template<bool buildAST>
ParseNodePtr Parser::ParseStatement()
{
    ParseNodePtr pnode = nullptr;
    LabelId* pLabelIdList = nullptr;
    charcount_t ichMin = 0;
    size_t iecpMin = 0;
    StmtNest stmt;
    StmtNest *pstmt;
    BOOL fForInOrOfOkay;
    BOOL fCanAssign;
    IdentPtr pid;
    uint fnop;
    bool expressionStmt = false;
    bool isAsyncMethod = false;
    bool labelledStatement = false;
    tokens tok;
#if EXCEPTION_RECOVERY
    ParseNodeTryCatch * pParentTryCatch = nullptr;
    ParseNodeBlock * pTryBlock = nullptr;
    ParseNodeTry * pTry = nullptr;
    ParseNodeBlock * pParentTryCatchBlock = nullptr;

    StmtNest stmtTryCatchBlock;
    StmtNest stmtTryCatch;
    StmtNest stmtTry;
    StmtNest stmtTryBlock;
#endif

    if (buildAST)
    {
#if EXCEPTION_RECOVERY
        if (Js::Configuration::Global.flags.SwallowExceptions)
        {
            // If we're swallowing exceptions, surround this statement with a try/catch block:
            //
            //   Before: x.y = 3;
            //   After:  try { x.y = 3; } catch(__ehobj) { }
            //
            // This is done to force the runtime to recover from exceptions at the most granular
            // possible point.  Recovering from EH dramatically improves coverage of testing via
            // fault injection.


            // create and push the try-catch node
            pParentTryCatchBlock = CreateBlockNode();
            PushStmt<buildAST>(&stmtTryCatchBlock, pParentTryCatchBlock, knopBlock, nullptr);
            pParentTryCatch = CreateNodeForOpT<knopTryCatch>();
            PushStmt<buildAST>(&stmtTryCatch, pParentTryCatch, knopTryCatch, nullptr);

            // create and push a try node
            pTry = CreateNodeForOpT<knopTry>();
            PushStmt<buildAST>(&stmtTry, pTry, knopTry, nullptr);
            pTryBlock = CreateBlockNode();
            PushStmt<buildAST>(&stmtTryBlock, pTryBlock, knopBlock, nullptr);
            // these nodes will be closed after the statement is parsed.
        }
#endif // EXCEPTION_RECOVERY
    }

    EnsureStackAvailable();

LRestart:
    tok = m_token.tk;

    switch (tok)
    {
    case tkEOF:
        if (labelledStatement)
        {
            Error(ERRLabelFollowedByEOF);
        }
        if (buildAST)
        {
            pnode = nullptr;
        }
        break;

    case tkFUNCTION:
    {
    LFunctionStatement:
        if (m_grfscr & fscrDeferredFncExpression)
        {
            // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
            // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
            // first time we see it.
            m_grfscr &= ~fscrDeferredFncExpression;
            pnode = ParseFncDeclNoCheckScope<buildAST>(isAsyncMethod ? fFncAsync : fFncNoFlgs);
        }
        else
        {
            pnode = ParseFncDeclCheckScope<buildAST>(fFncDeclaration | (isAsyncMethod ? fFncAsync : fFncNoFlgs));
        }

        Assert(pnode != nullptr);

        if (labelledStatement)
        {
            if (IsStrictMode())
            {
                Error(ERRFunctionAfterLabelInStrict);
            }
            // #sec-with-statement-static-semantics-early-errors states that the Statement of
            // a WithStatement throws a Syntax Error if the Statement is a LabelledFunction.
            else if (m_pstmtCur && m_pstmtCur->pnodeStmt && m_pstmtCur->GetNop() == knopWith)
            {
                Error(ERRStmtOfWithIsLabelledFunc);
            }

            ParseNodeFnc* pNodeFnc = nullptr;

            // pnode can be a knopBlock due to ParseFncDeclCheckScope, which
            // can return a ParseNodeBlock that contains a ParseNodeFnc.
            if (pnode->nop == knopBlock)
            {
                ParseNodeBlock* pNodeBlock = pnode->AsParseNodeBlock();
                if (pNodeBlock->pnodeStmt && pNodeBlock->pnodeStmt->nop == knopFncDecl)
                {
                    pNodeFnc = pNodeBlock->pnodeStmt->AsParseNodeFnc();
                }
            }
            if (pNodeFnc == nullptr)
            {
                pNodeFnc = pnode->AsParseNodeFnc();
            }

            if (pNodeFnc->IsAsync())
            {
                Error(ERRLabelBeforeAsyncFncDeclaration);
            }
            else if (pNodeFnc->IsGenerator())
            {
                Error(ERRLabelBeforeGeneratorDeclaration);
            }
        }
        
        if (isAsyncMethod)
        {
            pnode->AsParseNodeFnc()->cbStringMin = iecpMin;
        }
        break;
    }

    case tkCLASS:
        if (labelledStatement)
        {
            Error(ERRLabelBeforeClassDeclaration);
        }
        else if (m_scriptContext->GetConfig()->IsES6ClassAndExtendsEnabled())
        {
            pnode = ParseClassDecl<buildAST>(TRUE, nullptr, nullptr, nullptr);
        }
        else
        {
            goto LDefaultToken;
        }
        break;

    case tkID:
    case tkLET:
        if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.let)
        {
            // We see "let" at the start of a statement. This could either be a declaration or an identifier
            // reference. The next token determines which.
            RestorePoint parsedLet;
            this->GetScanner()->Capture(&parsedLet);
            ichMin = this->GetScanner()->IchMinTok();

            this->GetScanner()->Scan();
            if (labelledStatement)
            {
                if (!this->GetScanner()->FHadNewLine() || m_token.tk == tkLBrack)
                {
                    // In the case where a label is followed by a let, we want to fail when parsing if there is no new line after let, 
                    // otherwise fail at runtime as let will be viewed as undefined. A left bracket after a let signifies a syntax error regardless.
                    Error(ERRLabelBeforeLexicalDeclaration); 
                }
            }
            else if (this->NextTokenConfirmsLetDecl())
            {
                pnode = ParseVariableDeclaration<buildAST>(tkLET, ichMin);
                goto LNeedTerminator;
            }
            this->GetScanner()->SeekTo(parsedLet);
        }
        else if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.async && m_scriptContext->GetConfig()->IsES7AsyncAndAwaitEnabled())
        {
            RestorePoint parsedAsync;
            this->GetScanner()->Capture(&parsedAsync);
            ichMin = this->GetScanner()->IchMinTok();
            iecpMin = this->GetScanner()->IecpMinTok();

            this->GetScanner()->Scan();
            if (m_token.tk == tkFUNCTION && !this->GetScanner()->FHadNewLine())
            {
                isAsyncMethod = true;
                goto LFunctionStatement;
            }
            this->GetScanner()->SeekTo(parsedAsync);
        }
        goto LDefaultToken;

    case tkCONST:
        if (labelledStatement)
        {
            Error(ERRLabelBeforeLexicalDeclaration);
        }
        ichMin = this->GetScanner()->IchMinTok();

        this->GetScanner()->Scan();
        pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
        goto LNeedTerminator;

    case tkVAR:
        ichMin = this->GetScanner()->IchMinTok();

        this->GetScanner()->Scan();
        pnode = ParseVariableDeclaration<buildAST>(tok, ichMin);
        goto LNeedTerminator;

    case tkFOR:
    {
        ParseNodeBlock * pnodeBlock = nullptr;
        ParseNodePtr *ppnodeScopeSave = nullptr;
        ParseNodePtr *ppnodeExprScopeSave = nullptr;

        ichMin = this->GetScanner()->IchMinTok();
        ChkNxtTok(tkLParen, ERRnoLparen);
        pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);
        if (buildAST)
        {
            PushFuncBlockScope(pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);
        }

        RestorePoint startExprOrIdentifier;
        fForInOrOfOkay = TRUE;
        fCanAssign = TRUE;
        tok = m_token.tk;
        BOOL nativeForOkay = TRUE;

        ParseNodePtr pnodeT;
        switch (tok)
        {
        case tkID:
            if (m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.let)
            {
                // We see "let" in the init part of a for loop. This could either be a declaration or an identifier
                // reference. The next token determines which.
                RestorePoint parsedLet;
                this->GetScanner()->Capture(&parsedLet);
                auto ichMinInner = this->GetScanner()->IchMinTok();

                this->GetScanner()->Scan();
                if (IsPossiblePatternStart())
                {
                    this->GetScanner()->Capture(&startExprOrIdentifier);
                }
                if (this->NextTokenConfirmsLetDecl() && m_token.tk != tkIN)
                {
                    pnodeT = ParseVariableDeclaration<buildAST>(tkLET, ichMinInner
                        , /*fAllowIn = */FALSE
                        , /*pfForInOk = */&fForInOrOfOkay
                        , /*singleDefOnly*/FALSE
                        , /*allowInit*/TRUE
                        , /*isTopVarParse*/TRUE
                        , /*isFor*/TRUE
                        , &nativeForOkay);
                    break;
                }
                this->GetScanner()->SeekTo(parsedLet);
            }
            goto LDefaultTokenFor;
        case tkLET:
        case tkCONST:
        case tkVAR:
        {
            auto ichMinInner = this->GetScanner()->IchMinTok();

            this->GetScanner()->Scan();
            if (IsPossiblePatternStart())
            {
                this->GetScanner()->Capture(&startExprOrIdentifier);
            }
            pnodeT = ParseVariableDeclaration<buildAST>(tok, ichMinInner
                , /*fAllowIn = */FALSE
                , /*pfForInOk = */&fForInOrOfOkay
                , /*singleDefOnly*/FALSE
                , /*allowInit*/TRUE
                , /*isTopVarParse*/TRUE
                , /*isFor*/TRUE
                , &nativeForOkay);
        }
        break;
        case tkSColon:
            pnodeT = nullptr;
            fForInOrOfOkay = FALSE;
            break;
        default:
        {
        LDefaultTokenFor:
            RestorePoint exprStart;
            tokens beforeToken = tok;
            this->GetScanner()->Capture(&exprStart);
            if (IsPossiblePatternStart())
            {
                this->GetScanner()->Capture(&startExprOrIdentifier);
            }
            bool fLikelyPattern = false;
            if (IsES6DestructuringEnabled() && (beforeToken == tkLBrack || beforeToken == tkLCurly))
            {
                pnodeT = ParseExpr<buildAST>(koplNo,
                    &fCanAssign,
                    /*fAllowIn = */FALSE,
                    /*fAllowEllipsis*/FALSE,
                    /*pHint*/nullptr,
                    /*pHintLength*/nullptr,
                    /*pShortNameOffset*/nullptr,
                    /*pToken*/nullptr,
                    /**fUnaryOrParen*/false,
                    &fLikelyPattern);
            }
            else
            {
                IdentToken token;
                pnodeT = ParseExpr<buildAST>(koplNo, &fCanAssign, /*fAllowIn = */FALSE, FALSE, NULL, nullptr, nullptr, &token);
                TrackAssignment<buildAST>(pnodeT, &token);
            }

            // We would veryfiy the grammar as destructuring grammar only when  for..in/of case. As in the native for loop case the above ParseExpr call
            // has already converted them appropriately.
            if (fLikelyPattern && TokIsForInOrForOf())
            {
                this->GetScanner()->SeekTo(exprStart);
                ParseDestructuredLiteralWithScopeSave(tkNone, false/*isDecl*/, false /*topLevel*/, DIC_None, false /*allowIn*/);

                if (buildAST)
                {
                    pnodeT = ConvertToPattern(pnodeT);
                }
            }
            if (buildAST)
            {
                Assert(pnodeT);
                pnodeT->isUsed = false;
            }
        }
        break;
        }

        if (TokIsForInOrForOf())
        {
            bool isForOf = (m_token.tk != tkIN);
            Assert(!isForOf || (m_token.tk == tkID && m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.of));

            if ((buildAST && nullptr == pnodeT) || !fForInOrOfOkay)
            {
                if (isForOf)
                {
                    Error(ERRForOfNoInitAllowed);
                }
                else
                {
                    Error(ERRForInNoInitAllowed);
                }
            }
            if (!fCanAssign && 
                (m_sourceContextInfo 
                 ? !PHASE_OFF_RAW(Js::EarlyReferenceErrorsPhase, m_sourceContextInfo->sourceContextId, GetCurrentFunctionNode()->functionId)
                 : !PHASE_OFF1(Js::EarlyReferenceErrorsPhase)))
            {
                Error(ERRInvalidLHSInFor);
            }

            this->GetScanner()->Scan();
            ParseNodePtr pnodeObj = ParseExpr<buildAST>(isForOf ? koplCma : koplNo);
            charcount_t ichLim = this->GetScanner()->IchLimTok();
            ChkCurTok(tkRParen, ERRnoRparen);

            ParseNodeForInOrForOf * pnodeForInOrForOf = nullptr;
            if (buildAST)
            {
                if (isForOf)
                {
                    pnodeForInOrForOf = CreateNodeForOpT<knopForOf>(ichMin);
                }
                else
                {
                    pnodeForInOrForOf = CreateNodeForOpT<knopForIn>(ichMin);
                }
                pnodeForInOrForOf->pnodeBlock = pnodeBlock;
                pnodeForInOrForOf->pnodeLval = pnodeT;
                pnodeForInOrForOf->pnodeObj = pnodeObj;
                pnodeForInOrForOf->ichLim = ichLim;

                TrackAssignment<true>(pnodeT, nullptr);
            }
            PushStmt<buildAST>(&stmt, pnodeForInOrForOf, isForOf ? knopForOf : knopForIn, pLabelIdList);
            ParseNodePtr pnodeBody = ParseStatement<buildAST>();

            if (buildAST)
            {
                pnodeForInOrForOf->pnodeBody = pnodeBody;
                pnode = pnodeForInOrForOf;
            }
            PopStmt(&stmt);
        }
        else
        {
            if (!nativeForOkay)
            {
                Error(ERRDestructInit);
            }

            ChkCurTok(tkSColon, ERRnoSemic);
            ParseNodePtr pnodeCond = nullptr;
            if (m_token.tk != tkSColon)
            {
                pnodeCond = ParseExpr<buildAST>();
                if (m_token.tk != tkSColon)
                {
                    Error(ERRnoSemic);
                }
            }

            tokens tk;
            tk = this->GetScanner()->Scan();

            ParseNodePtr pnodeIncr = nullptr;
            if (tk != tkRParen)
            {
                pnodeIncr = ParseExpr<buildAST>();
                if (pnodeIncr)
                {
                    pnodeIncr->isUsed = false;
                }
            }

            charcount_t ichLim = this->GetScanner()->IchLimTok();

            ChkCurTok(tkRParen, ERRnoRparen);

            ParseNodeFor * pnodeFor = nullptr;
            if (buildAST)
            {
                pnodeFor = CreateNodeForOpT<knopFor>(ichMin);
                pnodeFor->pnodeBlock = pnodeBlock;
                pnodeFor->pnodeInverted = nullptr;
                pnodeFor->pnodeInit = pnodeT;
                pnodeFor->pnodeCond = pnodeCond;
                pnodeFor->pnodeIncr = pnodeIncr;
                pnodeFor->ichLim = ichLim;
            }
            PushStmt<buildAST>(&stmt, pnodeFor, knopFor, pLabelIdList);
            ParseNodePtr pnodeBody = ParseStatement<buildAST>();
            if (buildAST)
            {
                pnodeFor->pnodeBody = pnodeBody;
                pnode = pnodeFor;
            }
            PopStmt(&stmt);
        }

        if (buildAST)
        {
            PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
        }

        FinishParseBlock(pnodeBlock);

        break;
    }

    case tkSWITCH:
    {
        BOOL fSeenDefault = FALSE;
        ParseNodeBlock * pnodeBlock = nullptr;
        ParseNodePtr *ppnodeScopeSave = nullptr;
        ParseNodePtr *ppnodeExprScopeSave = nullptr;

        ichMin = this->GetScanner()->IchMinTok();
        ChkNxtTok(tkLParen, ERRnoLparen);
        ParseNodePtr pnodeVal = ParseExpr<buildAST>();
        charcount_t ichLim = this->GetScanner()->IchLimTok();

        ChkCurTok(tkRParen, ERRnoRparen);
        ChkCurTok(tkLCurly, ERRnoLcurly);

        ParseNodeSwitch * pnodeSwitch = nullptr;
        if (buildAST)
        {
            pnodeSwitch = CreateNodeForOpT<knopSwitch>(ichMin);
        }
        PushStmt<buildAST>(&stmt, pnodeSwitch, knopSwitch, pLabelIdList);
        pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Regular, ScopeType_Block);

        ParseNodeCase ** ppnodeCase = nullptr;
        if (buildAST)
        {
            pnodeSwitch->pnodeVal = pnodeVal;
            pnodeSwitch->pnodeBlock = pnodeBlock;
            pnodeSwitch->ichLim = ichLim;
            PushFuncBlockScope(pnodeSwitch->pnodeBlock, &ppnodeScopeSave, &ppnodeExprScopeSave);

            pnodeSwitch->pnodeDefault = nullptr;
            ppnodeCase = &pnodeSwitch->pnodeCases;
            pnode = pnodeSwitch;
        }

        for (;;)
        {
            ParseNodeCase * pnodeCase;
            ParseNodePtr pnodeBody = nullptr;
            switch (m_token.tk)
            {
            default:
                goto LEndSwitch;
            case tkCASE:
            {
                pnodeCase = this->ParseCase<buildAST>(&pnodeBody);
                break;
            }
            case tkDEFAULT:
                if (fSeenDefault)
                {
                    Error(ERRdupDefault);
                    // No recovery necessary since this is a semantic, not structural, error
                }
                fSeenDefault = TRUE;
                charcount_t ichMinT = this->GetScanner()->IchMinTok();
                this->GetScanner()->Scan();
                charcount_t ichMinInner = this->GetScanner()->IchLimTok();
                ChkCurTok(tkColon, ERRnoColon);
                if (buildAST)
                {
                    pnodeCase = CreateNodeForOpT<knopCase>(ichMinT);
                    pnodeSwitch->pnodeDefault = pnodeCase;
                    pnodeCase->ichLim = ichMinInner;
                    pnodeCase->pnodeExpr = nullptr;
                }
                ParseStmtList<buildAST>(&pnodeBody);
                break;
            }
            // Create a block node to contain the statement list for this case.
            // This helps us insert byte code to return the right value from
            // global/eval code.
            ParseNodeBlock * pnodeFakeBlock = CreateBlockNode();
            if (buildAST)
            {
                if (pnodeBody)
                {
                    pnodeFakeBlock->ichMin = pnodeCase->ichMin;
                    pnodeFakeBlock->ichLim = pnodeCase->ichLim;
                    pnodeCase->pnodeBody = pnodeFakeBlock;
                    pnodeCase->pnodeBody->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
                    pnodeCase->pnodeBody->pnodeStmt = pnodeBody;
                }
                else
                {
                    pnodeCase->pnodeBody = nullptr;
                }
                *ppnodeCase = pnodeCase;
                ppnodeCase = &pnodeCase->pnodeNext;
            }
        }
    LEndSwitch:
        ChkCurTok(tkRCurly, ERRnoRcurly);
        if (buildAST)
        {
            *ppnodeCase = nullptr;
            PopFuncBlockScope(ppnodeScopeSave, ppnodeExprScopeSave);
            FinishParseBlock(pnode->AsParseNodeSwitch()->pnodeBlock);
        }
        else
        {
            FinishParseBlock(pnodeBlock);
        }
        PopStmt(&stmt);

        break;
    }

    case tkWHILE:
    {
        ichMin = this->GetScanner()->IchMinTok();
        ChkNxtTok(tkLParen, ERRnoLparen);
        ParseNodePtr pnodeCond = ParseExpr<buildAST>();
        charcount_t ichLim = this->GetScanner()->IchLimTok();
        ChkCurTok(tkRParen, ERRnoRparen);

        ParseNodeWhile * pnodeWhile = nullptr;
        if (buildAST)
        {
            pnodeWhile = CreateNodeForOpT<knopWhile>(ichMin);
            pnodeWhile->pnodeCond = pnodeCond;
            pnodeWhile->ichLim = ichLim;
        }
        bool stashedDisallowImportExportStmt = m_disallowImportExportStmt;
        m_disallowImportExportStmt = true;
        PushStmt<buildAST>(&stmt, pnodeWhile, knopWhile, pLabelIdList);
        ParseNodePtr pnodeBody = ParseStatement<buildAST>();
        PopStmt(&stmt);

        if (buildAST)
        {
            pnodeWhile->pnodeBody = pnodeBody;
            pnode = pnodeWhile;
        }
        m_disallowImportExportStmt = stashedDisallowImportExportStmt;
        break;
    }

    case tkDO:
    {
        ParseNodeWhile * pnodeWhile = nullptr;
        if (buildAST)
        {
            pnodeWhile = CreateNodeForOpT<knopDoWhile>();
        }
        PushStmt<buildAST>(&stmt, pnodeWhile, knopDoWhile, pLabelIdList);
        this->GetScanner()->Scan();
        bool stashedDisallowImportExportStmt = m_disallowImportExportStmt;
        m_disallowImportExportStmt = true;
        ParseNodePtr pnodeBody = ParseStatement<buildAST>();
        m_disallowImportExportStmt = stashedDisallowImportExportStmt;
        PopStmt(&stmt);
        charcount_t ichMinT = this->GetScanner()->IchMinTok();

        ChkCurTok(tkWHILE, ERRnoWhile);
        ChkCurTok(tkLParen, ERRnoLparen);

        ParseNodePtr pnodeCond = ParseExpr<buildAST>();
        charcount_t ichLim = this->GetScanner()->IchLimTok();
        ChkCurTok(tkRParen, ERRnoRparen);

        if (buildAST)
        {
            pnodeWhile->pnodeBody = pnodeBody;
            pnodeWhile->pnodeCond = pnodeCond;
            pnodeWhile->ichLim = ichLim;
            pnodeWhile->ichMin = ichMinT;
            pnode = pnodeWhile;
        }

        // REVIEW: Allow do...while statements to be embedded in other compound statements like if..else, or do..while?
        //      goto LNeedTerminator;

        // For now just eat the trailing semicolon if present.
        if (m_token.tk == tkSColon)
        {
            if (pnode)
            {
                pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
            }
            this->GetScanner()->Scan();
        }
        else if (pnode)
        {
            pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
        }

        break;
    }

    case tkIF:
    {
        ichMin = this->GetScanner()->IchMinTok();
        ChkNxtTok(tkLParen, ERRnoLparen);
        ParseNodePtr pnodeCond = ParseExpr<buildAST>();
        ParseNodeIf * pnodeIf = nullptr;
        if (buildAST)
        {
            pnodeIf = CreateNodeForOpT<knopIf>(ichMin);
            pnodeIf->ichLim = this->GetScanner()->IchLimTok();
            pnodeIf->pnodeCond = pnodeCond;
        }
        ChkCurTok(tkRParen, ERRnoRparen);

        bool stashedDisallowImportExportStmt = m_disallowImportExportStmt;
        m_disallowImportExportStmt = true;
        PushStmt<buildAST>(&stmt, pnodeIf, knopIf, pLabelIdList);
        ParseNodePtr pnodeTrue = ParseStatement<buildAST>();
        ParseNodePtr pnodeFalse = nullptr;
        if (m_token.tk == tkELSE)
        {
            this->GetScanner()->Scan();
            pnodeFalse = ParseStatement<buildAST>();
        }
        if (buildAST)
        {
            pnodeIf->pnodeTrue = pnodeTrue;
            pnodeIf->pnodeFalse = pnodeFalse;
            pnode = pnodeIf;
        }
        PopStmt(&stmt);
        m_disallowImportExportStmt = stashedDisallowImportExportStmt;
        break;
    }

    case tkTRY:
    {
        ParseNodeBlock * pnodeBlock = CreateBlockNode();
        pnodeBlock->grfpn |= PNodeFlags::fpnSyntheticNode; // block is not a user specifier block
        PushStmt<buildAST>(&stmt, pnodeBlock, knopBlock, pLabelIdList);
        ParseNodePtr pnodeStmt = ParseTryCatchFinally<buildAST>();
        if (buildAST)
        {
            pnodeBlock->pnodeStmt = pnodeStmt;
        }
        PopStmt(&stmt);
        pnode = pnodeBlock;
        break;
    }

    case tkWITH:
    {
        if (IsStrictMode())
        {
            Error(ERRES5NoWith);
        }
        if (m_currentNodeFunc)
        {
            GetCurrentFunctionNode()->SetHasWithStmt(); // Used by DeferNested
        }

        ichMin = this->GetScanner()->IchMinTok();
        ChkNxtTok(tkLParen, ERRnoLparen);
        ParseNodePtr pnodeObj = ParseExpr<buildAST>();
        if (!buildAST)
        {
            m_scopeCountNoAst++;
        }
        charcount_t ichLim = this->GetScanner()->IchLimTok();
        ChkCurTok(tkRParen, ERRnoRparen);

        ParseNodeWith * pnodeWith = nullptr;
        if (buildAST)
        {
            pnodeWith = CreateNodeForOpT<knopWith>(ichMin);
        }
        PushStmt<buildAST>(&stmt, pnodeWith, knopWith, pLabelIdList);

        ParseNodePtr *ppnodeExprScopeSave = nullptr;
        if (buildAST)
        {
            pnodeWith->pnodeObj = pnodeObj;
            this->CheckArguments(pnodeWith->pnodeObj);

            if (m_ppnodeExprScope)
            {
                Assert(*m_ppnodeExprScope == nullptr);
                *m_ppnodeExprScope = pnodeWith;
                m_ppnodeExprScope = &pnodeWith->pnodeNext;
            }
            else
            {
                Assert(m_ppnodeScope);
                Assert(*m_ppnodeScope == nullptr);
                *m_ppnodeScope = pnodeWith;
                m_ppnodeScope = &pnodeWith->pnodeNext;
            }
            pnodeWith->pnodeNext = nullptr;
            pnodeWith->scope = nullptr;

            ppnodeExprScopeSave = m_ppnodeExprScope;
            m_ppnodeExprScope = &pnodeWith->pnodeScopes;
            pnodeWith->pnodeScopes = nullptr;

            pnodeWith->ichLim = ichLim;
            pnode = pnodeWith;
        }

        PushBlockInfo(CreateBlockNode());
        PushDynamicBlock();

        ParseNodePtr pnodeBody = ParseStatement<buildAST>();
        if (buildAST)
        {
            pnode->AsParseNodeWith()->pnodeBody = pnodeBody;
            m_ppnodeExprScope = ppnodeExprScopeSave;
        }
        else
        {
            m_scopeCountNoAst--;
        }

        // The dynamic block is not stored in the actual parse tree and so will not
        // be visited by the byte code generator.  Grab the callsEval flag off it and
        // pass on to outer block in case of:
        // with (...) eval(...); // i.e. blockless form of with
        bool callsEval = GetCurrentBlock()->GetCallsEval();
        PopBlockInfo();
        if (callsEval)
        {
            // be careful not to overwrite an existing true with false
            GetCurrentBlock()->SetCallsEval(true);
        }

        PopStmt(&stmt);
        break;
    }

    case tkLCurly:
        pnode = ParseBlock<buildAST>(pLabelIdList);
        break;

    case tkSColon:
        pnode = nullptr;
        this->GetScanner()->Scan();
        break;

    case tkBREAK:
        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopBreak>();
        }
        fnop = fnopBreak;
        goto LGetJumpStatement;

    case tkCONTINUE:
        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopContinue>();
        }
        fnop = fnopContinue;

    LGetJumpStatement:
        this->GetScanner()->ScanForcingPid();
        if (tkID == m_token.tk && !this->GetScanner()->FHadNewLine())
        {
            // Labeled break or continue.
            pid = m_token.GetIdentifier(this->GetHashTbl());
            if (buildAST)
            {
                ParseNodeJump * pnodeJump = pnode->AsParseNodeJump();
                pnodeJump->hasExplicitTarget = true;
                pnodeJump->ichLim = this->GetScanner()->IchLimTok();

                this->GetScanner()->Scan();
                PushStmt<buildAST>(&stmt, pnodeJump, pnodeJump->nop, pLabelIdList);
                Assert(pnodeJump->grfnop == 0);
                for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
                {
                    for (LabelId* label = pstmt->pLabelId; label != nullptr; label = label->next)
                    {
                        if (pid == label->pid)
                        {
                            // Found the label. Make sure we can use it. We can
                            // break out of any statement, but we can only
                            // continue loops.
                            if (fnop == fnopContinue &&
                                !(pstmt->pnodeStmt->Grfnop() & fnop))
                            {
                                Error(ERRbadContinue);
                            }
                            else
                            {
                                pstmt->pnodeStmt->grfnop |= fnop;
                                pnodeJump->pnodeTarget = pstmt->pnodeStmt;
                            }
                            PopStmt(&stmt);
                            goto LNeedTerminator;
                        }
                    }
                    pnodeJump->grfnop |=
                        (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
                }
            }
            else
            {
                this->GetScanner()->Scan();
                // Check if label is found within the current label id list.
                auto checkLabelList = [&](LabelId* list, StmtNest* checkStmtOp)
                {
                    for (LabelId* pLabelId = list; pLabelId; pLabelId = pLabelId->next)
                    {
                        if (pid == pLabelId->pid)
                        {
                            // Found the label. Make sure we can use it. We can
                            // break out of any statement, but we can only
                            // continue loops.
                            if (fnop == fnopContinue &&
                                !(ParseNode::Grfnop(checkStmtOp->op) & fnop))
                            {
                                Error(ERRbadContinue);
                            }
                            return true;
                        }
                    }
                    return false;
                };

                if (checkLabelList(pLabelIdList, m_pstmtCur)) goto LNeedTerminator;

                for (pstmt = m_pstmtCur; pstmt; pstmt = pstmt->pstmtOuter)
                {
                    if (checkLabelList(pstmt->pLabelId, pstmt)) goto LNeedTerminator;
                }
            }
            Error(ERRnoLabel);
        }
        else
        {
            // If we're doing a fast scan, we're not tracking labels, so we can't accurately do this analysis.
            // Let the thread that's doing the full parse detect the error, if there is one.
            if (!this->IsDoingFastScan())
            {
                // Unlabeled break or continue.
                ParseNodeJump * pnodeJump = nullptr;
                if (buildAST)
                {
                    pnodeJump = pnode->AsParseNodeJump();
                    pnodeJump->hasExplicitTarget = false;
                    PushStmt<buildAST>(&stmt, pnodeJump, pnodeJump->nop, pLabelIdList);
                    Assert(pnodeJump->grfnop == 0);
                }

                for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
                {
                    if (buildAST)
                    {
                        AnalysisAssert(pstmt->pnodeStmt);
                        if (pstmt->pnodeStmt->Grfnop() & fnop)
                        {
                            pstmt->pnodeStmt->grfnop |= fnop;
                            pnodeJump->pnodeTarget = pstmt->pnodeStmt;
                            PopStmt(&stmt);
                            goto LNeedTerminator;
                        }
                        pnodeJump->grfnop |=
                            (pstmt->pnodeStmt->Grfnop() & fnopCleanup);
                    }
                    else
                    {
                        if (ParseNode::Grfnop(pstmt->GetNop()) & fnop)
                        {
                            if (!pstmt->isDeferred)
                            {
                                AnalysisAssert(pstmt->pnodeStmt);
                                pstmt->pnodeStmt->grfnop |= fnop;
                            }
                            goto LNeedTerminator;
                        }
                    }
                }
                Error(fnop == fnopBreak ? ERRbadBreak : ERRbadContinue);
            }
            goto LNeedTerminator;
        }

    case tkRETURN:
    {
        ParseNodeReturn * pnodeReturn;
        if (buildAST)
        {
            if (nullptr == m_currentNodeFunc || IsTopLevelModuleFunc())
            {
                Error(ERRbadReturn);
            }
            pnodeReturn = CreateNodeForOpT<knopReturn>();
        }
        this->GetScanner()->Scan();
        ParseNodePtr pnodeExpr = nullptr;
        ParseOptionalExpr<buildAST>(&pnodeExpr, true);

        // Class constructors have special semantics regarding return statements.
        // This might require a reference to 'this'
        if (GetCurrentFunctionNode()->IsClassConstructor())
        {
            ReferenceSpecialName(wellKnownPropertyPids._this);
        }

        if (buildAST)
        {
            pnodeReturn->pnodeExpr = pnodeExpr;
            if (pnodeExpr)
            {
                this->CheckArguments(pnodeReturn->pnodeExpr);
                pnodeReturn->ichLim = pnodeReturn->pnodeExpr->ichLim;
            }
            // See if return should call finally
            PushStmt<buildAST>(&stmt, pnodeReturn, knopReturn, pLabelIdList);
            Assert(pnodeReturn->grfnop == 0);
            for (pstmt = m_pstmtCur; nullptr != pstmt; pstmt = pstmt->pstmtOuter)
            {
                if (pstmt->pnodeStmt->Grfnop() & fnopCleanup)
                {
                    pnodeReturn->grfnop |= fnopCleanup;
                    break;
                }
            }
            PopStmt(&stmt);
            pnode = pnodeReturn;
        }
        goto LNeedTerminator;
    }

    case tkTHROW:
    {
        if (buildAST)
        {
            pnode = CreateUniNode(knopThrow, nullptr);
        }
        this->GetScanner()->Scan();
        ParseNodePtr pnode1 = nullptr;
        if (m_token.tk != tkSColon &&
            m_token.tk != tkRCurly &&
            !this->GetScanner()->FHadNewLine())
        {
            pnode1 = ParseExpr<buildAST>();
        }
        else
        {
            Error(ERRdanglingThrow);
        }

        if (buildAST)
        {
            pnode->AsParseNodeUni()->pnode1 = pnode1;
            if (pnode1)
            {
                this->CheckArguments(pnode->AsParseNodeUni()->pnode1);
                pnode->ichLim = pnode->AsParseNodeUni()->pnode1->ichLim;
            }
        }
        goto LNeedTerminator;
    }

    case tkDEBUGGER:
        if (buildAST)
        {
            pnode = CreateNodeForOpT<knopDebugger>();
        }
        this->GetScanner()->Scan();
        goto LNeedTerminator;

    case tkIMPORT:
        pnode = ParseImport<buildAST>();

        goto LNeedTerminator;

    case tkEXPORT:
    {
        if (!(m_grfscr & fscrIsModuleCode))
        {
            goto LDefaultToken;
        }

        bool needTerminator = false;
        pnode = ParseExportDeclaration<buildAST>(&needTerminator);

        if (needTerminator)
        {
            goto LNeedTerminator;
        }
        else
        {
            break;
        }
    }

LDefaultToken:
    default:
    {
        // First check for a label via lookahead. If not found,
        // rewind and reparse as expression statement.
        if (m_token.tk == tkID)
        {
            RestorePoint idStart;
            this->GetScanner()->Capture(&idStart);

            IdentPtr pidInner = m_token.GetIdentifier(this->GetHashTbl());

            this->GetScanner()->Scan();

            if (m_token.tk == tkColon)
            {
                // We have a label.
                if (LabelExists(pidInner, pLabelIdList))
                {
                    Error(ERRbadLabel);
                }
                LabelId* pLabelId = CreateLabelId(pidInner);
                pLabelId->next = pLabelIdList;
                pLabelIdList = pLabelId;
                this->GetScanner()->Scan();
                labelledStatement = true;
                goto LRestart;
            }

            // No label, rewind back to the tkID and parse an expression
            this->GetScanner()->SeekTo(idStart);
        }

        // Must be an expression statement.
        pnode = ParseExpr<buildAST>();

        if (m_hasDeferredShorthandInitError)
        {
            Error(ERRnoColon);
        }

        if (buildAST)
        {
            expressionStmt = true;

            AnalysisAssert(pnode);
            pnode->isUsed = false;
        }
    }

LNeedTerminator:
    // Need a semicolon, new-line, } or end-of-file.
    // We digest a semicolon if it's there.
    switch (m_token.tk)
    {
    case tkSColon:
        this->GetScanner()->Scan();
        if (pnode != nullptr) pnode->grfpn |= PNodeFlags::fpnExplicitSemicolon;
        break;
    case tkEOF:
    case tkRCurly:
        if (pnode != nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
        break;
    default:
        if (!this->GetScanner()->FHadNewLine())
        {
            Error(ERRnoSemic);
        }
        else
        {
            if (pnode != nullptr) pnode->grfpn |= PNodeFlags::fpnAutomaticSemicolon;
        }
        break;
    }
    break;
    }

    if (m_hasDeferredShorthandInitError)
    {
        Error(ERRnoColon);
    }

    if (buildAST)
    {
        // All non expression statements excluded from the "this.x" optimization
        // Another check while parsing expressions
        if (!expressionStmt)
        {
            if (m_currentNodeFunc)
            {
                m_currentNodeFunc->SetHasNonThisStmt();
            }
            else if (m_currentNodeProg)
            {
                m_currentNodeProg->SetHasNonThisStmt();
            }
        }

#if EXCEPTION_RECOVERY
        // close the try/catch block
        if (Js::Configuration::Global.flags.SwallowExceptions)
        {
            // pop the try block and fill in the body
            PopStmt(&stmtTryBlock);
            pTryBlock->pnodeStmt = pnode;
            PopStmt(&stmtTry);
            if (pnode != nullptr)
            {
                pTry->ichLim = pnode->ichLim;
            }
            pTry->pnodeBody = pTryBlock;


            // create a catch block with an empty body
            StmtNest stmtCatch;
            ParseNodeCatch * pCatch;
            pCatch = CreateNodeForOpT<knopCatch>();
            PushStmt<buildAST>(&stmtCatch, pCatch, knopCatch, nullptr);
            pCatch->pnodeBody = nullptr;
            if (pnode != nullptr)
            {
                pCatch->ichLim = pnode->ichLim;
            }
            pCatch->grfnop = 0;
            pCatch->pnodeNext = nullptr;

            // create a fake name for the catch var.
            const WCHAR *uniqueNameStr = _u("__ehobj");
            IdentPtr uniqueName = this->GetHashTbl()->PidHashNameLen(uniqueNameStr, static_cast<int32>(wcslen(uniqueNameStr)));

            pCatch->SetParam(CreateNameNode(uniqueName));

            // Add this catch to the current list. We don't bother adjusting the catch and function expression
            // lists here because the catch is just an empty statement.

            if (m_ppnodeExprScope)
            {
                Assert(*m_ppnodeExprScope == nullptr);
                *m_ppnodeExprScope = pCatch;
                m_ppnodeExprScope = &pCatch->pnodeNext;
            }
            else
            {
                Assert(m_ppnodeScope);
                Assert(*m_ppnodeScope == nullptr);
                *m_ppnodeScope = pCatch;
                m_ppnodeScope = &pCatch->pnodeNext;
            }

            pCatch->pnodeScopes = nullptr;

            PopStmt(&stmtCatch);

            // fill in and pop the try-catch
            pParentTryCatch->pnodeTry = pTry;
            pParentTryCatch->pnodeCatch = pCatch;
            PopStmt(&stmtTryCatch);
            PopStmt(&stmtTryCatchBlock);

            // replace the node that's being returned
            pParentTryCatchBlock->pnodeStmt = pParentTryCatch;
            pnode = pParentTryCatchBlock;
        }
#endif // EXCEPTION_RECOVERY

    }

    return pnode;
}

BOOL
Parser::TokIsForInOrForOf()
{
    return m_token.tk == tkIN ||
        (m_token.tk == tkID &&
            m_token.GetIdentifier(this->GetHashTbl()) == wellKnownPropertyPids.of);
}

/***************************************************************************
Parse a sequence of statements.
***************************************************************************/
template<bool buildAST>
void Parser::ParseStmtList(ParseNodePtr *ppnodeList, ParseNodePtr **pppnodeLast, StrictModeEnvironment smEnvironment, const bool isSourceElementList, bool* strictModeOn)
{
    BOOL doneDirectives = !isSourceElementList; // directives may only exist in a SourceElementList, not a StatementList
    BOOL seenDirectiveContainingOctal = false; // Have we seen an octal directive before a use strict directive?

    BOOL old_UseStrictMode = m_fUseStrictMode;

    ParseNodePtr pnodeStmt;
    ParseNodePtr *lastNodeRef = nullptr;

    if (buildAST)
    {
        Assert(ppnodeList);
        *ppnodeList = nullptr;
    }

    if (CONFIG_FLAG(ForceStrictMode))
    {
        m_fUseStrictMode = TRUE;
    }

    for (;;)
    {
        switch (m_token.tk)
        {
        case tkCASE:
        case tkDEFAULT:
        case tkRCurly:
        case tkEOF:
            if (buildAST && nullptr != pppnodeLast)
            {
                *pppnodeLast = lastNodeRef;
            }
            if (!buildAST)
            {
                m_fUseStrictMode = old_UseStrictMode;
            }
            return;
        }

        if (doneDirectives == FALSE)
        {
            bool isOctalInString = false;
            bool isUseStrictDirective = false;
            bool isUseAsmDirective = false;
            if (smEnvironment != SM_NotUsed && CheckForDirective(&isUseStrictDirective, &isUseAsmDirective, &isOctalInString))
            {
                // Ignore "use asm" statement when not building the AST
                isUseAsmDirective &= buildAST;

                if (isUseStrictDirective)
                {
                    // Functions with non-simple parameter list cannot be made strict mode
                    if (GetCurrentFunctionNode()->HasNonSimpleParameterList())
                    {
                        Error(ERRNonSimpleParamListInStrictMode);
                    }

                    if (seenDirectiveContainingOctal)
                    {
                        // Directives seen before a "use strict" cannot contain an octal.
                        Error(ERRES5NoOctal);
                    }
                    if (!buildAST)
                    {
                        // Turning on strict mode in deferred code.
                        m_fUseStrictMode = TRUE;
                        if (!m_inDeferredNestedFunc)
                        {
                            // Top-level deferred function, so there's a parse node
                            Assert(m_currentNodeFunc != nullptr);
                            m_currentNodeFunc->SetStrictMode();
                        }
                        else if (strictModeOn)
                        {
                            // This turns on strict mode in a deferred function, we need to go back
                            // and re-check duplicated formals.
                            *strictModeOn = true;
                        }
                    }
                    else
                    {
                        if (smEnvironment == SM_OnGlobalCode)
                        {
                            // Turning on strict mode at the top level
                            m_fUseStrictMode = TRUE;
                        }
                        else
                        {
                            // i.e. smEnvironment == SM_OnFunctionCode
                            Assert(m_currentNodeFunc != nullptr);
                            m_currentNodeFunc->SetStrictMode();
                        }
                    }
                }
                else if (isUseAsmDirective)
                {
                    if (smEnvironment != SM_OnGlobalCode) //Top level use asm doesn't mean anything.
                    {
                        // i.e. smEnvironment == SM_OnFunctionCode
                        Assert(m_currentNodeFunc != nullptr);
                        m_currentNodeFunc->SetAsmjsMode();
                        m_currentNodeFunc->SetCanBeDeferred(false);
                        m_InAsmMode = true;

                        CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, AsmJSFunction, m_scriptContext);
                    }
                }
                else if (isOctalInString)
                {
                    seenDirectiveContainingOctal = TRUE;
                }
            }
            else
            {
                // The first time we see anything other than a directive we can have no more directives.
                doneDirectives = TRUE;
            }
        }

        if (nullptr != (pnodeStmt = ParseStatement<buildAST>()))
        {
            if (buildAST)
            {
                AddToNodeList(ppnodeList, &lastNodeRef, pnodeStmt);
            }
        }
    }
}

template <class Fn>
void Parser::FinishFunctionsInScope(ParseNodePtr pnodeScopeList, Fn fn)
{
    Scope * scope;
    Scope * origCurrentScope = this->m_currentScope;
    ParseNodePtr pnodeScope;
    ParseNodeBlock * pnodeBlock;
    for (pnodeScope = pnodeScopeList; pnodeScope;)
    {
        switch (pnodeScope->nop)
        {
        case knopBlock:
        {
            ParseNodeBlock * pnodeBlockScope = pnodeScope->AsParseNodeBlock();
            m_nextBlockId = pnodeBlockScope->blockId + 1;
            PushBlockInfo(pnodeBlockScope);
            scope = pnodeBlockScope->scope;
            if (scope && scope != origCurrentScope)
            {
                PushScope(scope);
            }
            FinishFunctionsInScope(pnodeBlockScope->pnodeScopes, fn);
            if (scope && scope != origCurrentScope)
            {
                BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
                PopScope(scope);
            }
            PopBlockInfo();
            pnodeScope = pnodeBlockScope->pnodeNext;
            break;
        }
        case knopFncDecl:
            fn(pnodeScope->AsParseNodeFnc());
            pnodeScope = pnodeScope->AsParseNodeFnc()->pnodeNext;
            break;

        case knopCatch:
            scope = pnodeScope->AsParseNodeCatch()->scope;
            if (scope)
            {
                PushScope(scope);
            }
            pnodeBlock = CreateBlockNode(PnodeBlockType::Regular);
            pnodeBlock->scope = scope;
            PushBlockInfo(pnodeBlock);
            FinishFunctionsInScope(pnodeScope->AsParseNodeCatch()->pnodeScopes, fn);
            if (scope)
            {
                BindPidRefs<false>(GetCurrentBlockInfo(), m_nextBlockId - 1);
                PopScope(scope);
            }
            PopBlockInfo();
            pnodeScope = pnodeScope->AsParseNodeCatch()->pnodeNext;
            break;

        case knopWith:
            PushBlockInfo(CreateBlockNode());
            PushDynamicBlock();
            FinishFunctionsInScope(pnodeScope->AsParseNodeWith()->pnodeScopes, fn);
            PopBlockInfo();
            pnodeScope = pnodeScope->AsParseNodeWith()->pnodeNext;
            break;

        default:
            AssertMsg(false, "Unexpected node with scope list");
            return;
        }
    }
}

// Scripts above this size (minus string literals and comments) will have parsing of
// function bodies deferred.
ULONG Parser::GetDeferralThreshold(bool isProfileLoaded)
{
#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
    if (CONFIG_FLAG(ForceDeferParse) ||
        PHASE_FORCE1(Js::DeferParsePhase) ||
        Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
    {
        return 0;
    }
    else if (Js::Configuration::Global.flags.IsEnabled(Js::DeferParseFlag))
    {
        return Js::Configuration::Global.flags.DeferParse;
    }
    else
#endif
    {
        if (isProfileLoaded)
        {
            return DEFAULT_CONFIG_ProfileBasedDeferParseThreshold;
        }
        return DEFAULT_CONFIG_DeferParseThreshold;
    }
}

void Parser::FinishDeferredFunction(ParseNodeBlock * pnodeScopeList)
{
    ParseContext parseContext;
    this->CaptureContext(&parseContext);

    m_nextBlockId = pnodeScopeList->blockId + 1;

    FinishFunctionsInScope(pnodeScopeList,
        [this, &parseContext](ParseNodeFnc * pnodeFnc)
    {
        Assert(pnodeFnc->nop == knopFncDecl);

        // We need to scan this function based on the already known limits of the function declaration as some of
        // the state such as fAllowIn may not be available at this point. Some of this state depends on the context
        // of the function declaration. For example, a function declaration may be inside a for..in statement's var
        // declaration. It may not be appropriate/possible to try and save all such context information. Functions
        // that actually get deferred achieve this by going through the ParseSourceWithOffset code path.
        this->GetScanner()->Clear();
        this->GetScanner()->SetText(parseContext.pszSrc, pnodeFnc->cbMin /*+ this->m_scan.m_cMinTokMultiUnits*/, pnodeFnc->LengthInBytes(), pnodeFnc->ichMin, parseContext.isUtf8, parseContext.grfscr, pnodeFnc->lineNumber);
        this->GetScanner()->Scan();

        // Non-simple params (such as default) require a good amount of logic to put vars on appropriate scopes. ParseFncDecl handles it
        // properly (both on defer and non-defer case). This is to avoid write duplicated logic here as well. Function with non-simple-param
        // will remain deferred until they are called.
        if (pnodeFnc->pnodeBody == nullptr && !pnodeFnc->HasNonSimpleParameterList())
        {
            // Go back and generate an AST for this function.
            JS_ETW_INTERNAL(EventWriteJSCRIPT_PARSE_FUNC(this->GetScriptContext(), pnodeFnc->functionId, /*Undefer*/TRUE));

            ParseNodeFnc * pnodeFncSave = this->m_currentNodeFunc;
            this->m_currentNodeFunc = pnodeFnc;

            ParseNodeBlock * pnodeFncExprBlock = nullptr;
            ParseNodePtr pnodeName = pnodeFnc->pnodeName;
            if (pnodeName)
            {
                Assert(pnodeName->nop == knopVarDecl);
                ParseNodeVar * pnodeVarName = pnodeName->AsParseNodeVar();
                Assert(pnodeVarName->pnodeNext == nullptr);

                if (!pnodeFnc->IsDeclaration())
                {
                    // Set up the named function expression symbol so references inside the function can be bound.
                    pnodeFncExprBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FuncExpr);
                    PidRefStack *ref = this->PushPidRef(pnodeVarName->pid);
                    pnodeVarName->symRef = ref->GetSymRef();
                    ref->SetSym(pnodeVarName->sym);

                    Scope *fncExprScope = pnodeFncExprBlock->scope;
                    fncExprScope->AddNewSymbol(pnodeVarName->sym);
                    pnodeFnc->scope = fncExprScope;
                }
            }

            ParseNodeBlock * pnodeBlock = this->StartParseBlock<true>(PnodeBlockType::Parameter, ScopeType_Parameter);
            pnodeFnc->pnodeScopes = pnodeBlock;
            m_ppnodeScope = &pnodeBlock->pnodeScopes;
            pnodeBlock->pnodeStmt = pnodeFnc;

            ParseNodePtr * varNodesList = &pnodeFnc->pnodeVars;
            ParseNodeVar * argNode = nullptr;
            if (!pnodeFnc->IsModule() && !pnodeFnc->IsLambda() && !(pnodeFnc->grfpn & PNodeFlags::fpnArguments_overriddenInParam))
            {
                ParseNodePtr *const ppnodeVarSave = m_ppnodeVar;
                m_ppnodeVar = &pnodeFnc->pnodeVars;

                argNode = this->AddArgumentsNodeToVars(pnodeFnc);

                varNodesList = m_ppnodeVar;
                m_ppnodeVar = ppnodeVarSave;
            }

            // Add the args to the scope, since we won't re-parse those.
            Scope *scope = pnodeBlock->scope;
            uint blockId = GetCurrentBlock()->blockId;
            uint funcId = GetCurrentFunctionNode()->functionId;
            auto addArgsToScope = [&](ParseNodePtr pnodeArg) {
                if (pnodeArg->IsVarLetOrConst())
                {
                    ParseNodeVar * pnodeVarArg = pnodeArg->AsParseNodeVar();

                    PidRefStack *ref = this->FindOrAddPidRef(pnodeVarArg->pid, blockId, funcId);
                    pnodeVarArg->symRef = ref->GetSymRef();
                    if (ref->GetSym() != nullptr)
                    {
                        // Duplicate parameter in a configuration that allows them.
                        // The symbol is already in the scope, just point it to the right declaration.
                        Assert(ref->GetSym() == pnodeVarArg->sym);
                        ref->GetSym()->SetDecl(pnodeVarArg);
                    }
                    else
                    {
                        ref->SetSym(pnodeArg->AsParseNodeVar()->sym);
                        scope->AddNewSymbol(pnodeVarArg->sym);
                    }
                }
            };

            MapFormals(pnodeFnc, addArgsToScope);
            MapFormalsFromPattern(pnodeFnc, addArgsToScope);

            ParseNodeBlock * pnodeInnerBlock = this->StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
            pnodeFnc->pnodeBodyScope = pnodeInnerBlock;

            // Set the parameter block's child to the function body block.
            *m_ppnodeScope = pnodeInnerBlock;

            ParseNodePtr *ppnodeScopeSave = nullptr;
            ParseNodePtr *ppnodeExprScopeSave = nullptr;

            ppnodeScopeSave = m_ppnodeScope;

            // This synthetic block scope will contain all the nested scopes.
            m_ppnodeScope = &pnodeInnerBlock->pnodeScopes;
            pnodeInnerBlock->pnodeStmt = pnodeFnc;

            // Keep nested function declarations and expressions in the same list at function scope.
            // (Indicate this by nulling out the current function expressions list.)
            ppnodeExprScopeSave = m_ppnodeExprScope;
            m_ppnodeExprScope = nullptr;

            // Shouldn't be any temps in the arg list.
            Assert(*m_ppnodeVar == nullptr);

            // Start the var list.
            m_ppnodeVar = varNodesList;

            if (scope != nullptr)
            {
                Assert(pnodeFnc->IsBodyAndParamScopeMerged());
                blockId = GetCurrentBlock()->blockId;
                funcId = GetCurrentFunctionNode()->functionId;
                scope->ForEachSymbol([this, blockId, funcId](Symbol* paramSym)
                {
                    PidRefStack* ref = this->FindOrAddPidRef(paramSym->GetPid(), blockId, funcId);
                    ref->SetSym(paramSym);
                });
            }

            Assert(m_currentNodeNonLambdaFunc == nullptr);
            m_currentNodeNonLambdaFunc = pnodeFnc;

            this->FinishFncNode(pnodeFnc);

            Assert(pnodeFnc == m_currentNodeNonLambdaFunc);
            m_currentNodeNonLambdaFunc = nullptr;

            m_ppnodeExprScope = ppnodeExprScopeSave;

            Assert(m_ppnodeScope);
            Assert(nullptr == *m_ppnodeScope);
            m_ppnodeScope = ppnodeScopeSave;

            this->FinishParseBlock(pnodeInnerBlock);

            if (!pnodeFnc->IsModule() && (m_token.tk == tkLCurly || !pnodeFnc->IsLambda()))
            {
                UpdateArgumentsNode(pnodeFnc, argNode);
            }

            CreateSpecialSymbolDeclarations(pnodeFnc);

            this->FinishParseBlock(pnodeBlock);
            if (pnodeFncExprBlock)
            {
                this->FinishParseBlock(pnodeFncExprBlock);
            }

            this->m_currentNodeFunc = pnodeFncSave;
        }
    });

    this->RestoreContext(&parseContext);
}

void Parser::InitPids()
{
    wellKnownPropertyPids.arguments = this->GetHashTbl()->PidHashNameLen(g_ssym_arguments.sz, g_ssym_arguments.cch);
    wellKnownPropertyPids.async = this->GetHashTbl()->PidHashNameLen(g_ssym_async.sz, g_ssym_async.cch);
    wellKnownPropertyPids.eval = this->GetHashTbl()->PidHashNameLen(g_ssym_eval.sz, g_ssym_eval.cch);
    wellKnownPropertyPids.get = this->GetHashTbl()->PidHashNameLen(g_ssym_get.sz, g_ssym_get.cch);
    wellKnownPropertyPids.set = this->GetHashTbl()->PidHashNameLen(g_ssym_set.sz, g_ssym_set.cch);
    wellKnownPropertyPids.let = this->GetHashTbl()->PidHashNameLen(g_ssym_let.sz, g_ssym_let.cch);
    wellKnownPropertyPids.constructor = this->GetHashTbl()->PidHashNameLen(g_ssym_constructor.sz, g_ssym_constructor.cch);
    wellKnownPropertyPids.prototype = this->GetHashTbl()->PidHashNameLen(g_ssym_prototype.sz, g_ssym_prototype.cch);
    wellKnownPropertyPids.__proto__ = this->GetHashTbl()->PidHashNameLen(_u("__proto__"), sizeof("__proto__") - 1);
    wellKnownPropertyPids.of = this->GetHashTbl()->PidHashNameLen(_u("of"), sizeof("of") - 1);
    wellKnownPropertyPids.target = this->GetHashTbl()->PidHashNameLen(_u("target"), sizeof("target") - 1);
    wellKnownPropertyPids.as = this->GetHashTbl()->PidHashNameLen(_u("as"), sizeof("as") - 1);
    wellKnownPropertyPids.from = this->GetHashTbl()->PidHashNameLen(_u("from"), sizeof("from") - 1);
    wellKnownPropertyPids._default = this->GetHashTbl()->PidHashNameLen(_u("default"), sizeof("default") - 1);
    wellKnownPropertyPids._star = this->GetHashTbl()->PidHashNameLen(_u("*"), sizeof("*") - 1);
    wellKnownPropertyPids._this = this->GetHashTbl()->PidHashNameLen(_u("*this*"), sizeof("*this*") - 1);
    wellKnownPropertyPids._newTarget = this->GetHashTbl()->PidHashNameLen(_u("*new.target*"), sizeof("*new.target*") - 1);
    wellKnownPropertyPids._super = this->GetHashTbl()->PidHashNameLen(_u("*super*"), sizeof("*super*") - 1);
    wellKnownPropertyPids._superConstructor = this->GetHashTbl()->PidHashNameLen(_u("*superconstructor*"), sizeof("*superconstructor*") - 1);
}

void Parser::RestoreScopeInfo(Js::ScopeInfo * scopeInfo)
{
    if (!scopeInfo)
    {
        return;
    }

    PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);

    RestoreScopeInfo(scopeInfo->GetParentScopeInfo()); // Recursively restore outer func scope info

    scopeInfo->SetScopeId(m_nextBlockId);
    ParseNodeBlock * pnodeScope = nullptr;
    ScopeType scopeType = scopeInfo->GetScopeType();
    PnodeBlockType blockType;
    switch (scopeType)
    {
    case ScopeType_With:
        PushDynamicBlock();
        // fall through
    case ScopeType_Block:
    case ScopeType_Catch:
    case ScopeType_CatchParamPattern:
    case ScopeType_GlobalEvalBlock:
        blockType = PnodeBlockType::Regular;
        break;

    case ScopeType_FunctionBody:
    case ScopeType_FuncExpr:
        blockType = PnodeBlockType::Function;
        break;

    case ScopeType_Parameter:
        blockType = PnodeBlockType::Parameter;
        break;


    default:
        Assert(0);
        return;
    }

    pnodeScope = StartParseBlockWithCapacity<true>(blockType, scopeType, scopeInfo->GetSymbolCount());
    Scope *scope = pnodeScope->scope;
    scope->SetScopeInfo(scopeInfo);
    scopeInfo->ExtractScopeInfo(this, /*nullptr, nullptr,*/ scope);
}

void Parser::FinishScopeInfo(Js::ScopeInfo * scopeInfo)
{
    PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackByteCodeVisitor);

    for (; scopeInfo != nullptr; scopeInfo = scopeInfo->GetParentScopeInfo())
    {
        int scopeId = scopeInfo->GetScopeId();

        scopeInfo->GetScope()->ForEachSymbol([this, scopeId](Symbol *sym)
        {
            this->BindPidRefsInScope(sym->GetPid(), sym, scopeId);
        });
        PopScope(scopeInfo->GetScope());
        PopStmt(&m_currentBlockInfo->pstmt);
        PopBlockInfo();
    }
}

/***************************************************************************
Parse the code.
***************************************************************************/
ParseNodeProg * Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcount_t charOffset, bool isUtf8, ULONG grfscr, ULONG lineNumber, Js::LocalFunctionId * nextFunctionId, CompileScriptException *pse)
{
    ParseNodeProg * pnodeProg;
    ParseNodePtr *lastNodeRef = nullptr;

    m_nextBlockId = 0;

    bool isDeferred = (grfscr & fscrDeferredFnc) != 0;
    bool isModuleSource = (grfscr & fscrIsModuleCode) != 0;
    bool isGlobalCode = (grfscr & fscrGlobalCode) != 0;

    if (this->m_scriptContext->IsScriptContextInDebugMode()
#ifdef ENABLE_PREJIT
        || Js::Configuration::Global.flags.Prejit
#endif
        || ((grfscr & fscrNoDeferParse) != 0)
        )
    {
        // Don't do deferred parsing if debugger is attached or feature is disabled
        // by command-line switch.
        grfscr &= ~fscrWillDeferFncParse;
    }
    else if (!isGlobalCode &&
        (
            PHASE_OFF1(Js::Phase::DeferEventHandlersPhase) ||
            this->m_scriptContext->IsScriptContextInSourceRundownOrDebugMode()
            )
        )
    {
        // Don't defer event handlers in debug/rundown mode, because we need to register the document,
        // so we need to create a full FunctionBody for the script body.
        grfscr &= ~fscrWillDeferFncParse;
    }

    m_grfscr = grfscr;
    m_length = length;
    m_originalLength = length;
    m_nextFunctionId = nextFunctionId;

    if (m_parseType != ParseType_Deferred)
    {
        JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_START(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), *m_nextFunctionId, 0, m_parseType, Js::Constants::GlobalFunction));
        OUTPUT_TRACE(Js::DeferParsePhase, _u("Parsing function (%s) : %s (%d)\n"), GetParseType(), Js::Constants::GlobalFunction, *m_nextFunctionId);
    }

    // Give the scanner the source and get the first token
    this->GetScanner()->SetText(pszSrc, offset, length, charOffset, isUtf8, grfscr, lineNumber);
    this->GetScanner()->Scan();

    // Make the main 'knopProg' node
    int32 initSize = 0;
    m_pCurrentAstSize = &initSize;
    pnodeProg = CreateProgNode(isModuleSource, lineNumber);

    if (!isDeferred || (isDeferred && isGlobalCode))
    {
        // In the deferred case, if the global function is deferred parse (which is in no-refresh case),
        // we will re-use the same function body, so start with the correct functionId.
        pnodeProg->functionId = (*m_nextFunctionId)++;
    }

    if (isModuleSource)
    {
        Assert(m_scriptContext->GetConfig()->IsES6ModuleEnabled());

        pnodeProg->AsParseNodeModule()->localExportEntries = nullptr;
        pnodeProg->AsParseNodeModule()->indirectExportEntries = nullptr;
        pnodeProg->AsParseNodeModule()->starExportEntries = nullptr;
        pnodeProg->AsParseNodeModule()->importEntries = nullptr;
        pnodeProg->AsParseNodeModule()->requestedModules = nullptr;
    }

    m_pCurrentAstSize = &(pnodeProg->astSize);

    // initialize parsing variables
    m_currentNodeFunc = nullptr;
    m_currentNodeDeferredFunc = nullptr;
    m_currentNodeProg = pnodeProg;
    m_cactIdentToNodeLookup = 1;

    m_pnestedCount = &pnodeProg->nestedCount;
    m_inDeferredNestedFunc = false;
    m_ppnodeVar = &pnodeProg->pnodeVars;
    SetCurrentStatement(nullptr);
    AssertMsg(m_pstmtCur == nullptr, "Statement stack should be empty when we start parse global code");

    // Create block for const's and let's
    ParseNodeBlock * pnodeGlobalBlock = StartParseBlock<true>(PnodeBlockType::Global, ScopeType_Global);
    pnodeProg->scope = pnodeGlobalBlock->scope;
    ParseNodeBlock * pnodeGlobalEvalBlock = nullptr;

    // Don't track function expressions separately from declarations at global scope.
    m_ppnodeExprScope = nullptr;

    // This synthetic block scope will contain all the nested scopes.    
    pnodeProg->pnodeScopes = pnodeGlobalBlock;
    m_ppnodeScope = &pnodeGlobalBlock->pnodeScopes;

    if ((this->m_grfscr & fscrEvalCode) &&
        !(this->m_functionBody && this->m_functionBody->GetScopeInfo()))
    {
        pnodeGlobalEvalBlock = StartParseBlock<true>(PnodeBlockType::Regular, ScopeType_GlobalEvalBlock);
        pnodeProg->pnodeScopes = pnodeGlobalEvalBlock;
        m_ppnodeScope = &pnodeGlobalEvalBlock->pnodeScopes;
    }

    Js::ScopeInfo *scopeInfo = nullptr;
    if (m_parseType == ParseType_Deferred && m_functionBody)
    {
        // this->m_functionBody can be cleared during parsing, but we need access to the scope info later.
        scopeInfo = m_functionBody->GetScopeInfo();
        if (scopeInfo)
        {
            // Create an enclosing function context.
            m_currentNodeFunc = CreateNodeForOpT<knopFncDecl>();
            m_currentNodeFunc->functionId = m_functionBody->GetLocalFunctionId();
            m_currentNodeFunc->nestedCount = m_functionBody->GetNestedCount();
            m_currentNodeFunc->SetStrictMode(!!this->m_fUseStrictMode);

            this->RestoreScopeInfo(scopeInfo);

            m_currentNodeFunc->SetIsGenerator(scopeInfo->IsGeneratorFunctionBody());
            m_currentNodeFunc->SetIsAsync(scopeInfo->IsAsyncFunctionBody());
        }
    }

    // It's possible for the module global to be defer-parsed in debug scenarios.
    if (isModuleSource && (!isDeferred || (isDeferred && isGlobalCode)))
    {
        ParseNodePtr moduleFunction = GenerateModuleFunctionWrapper<true>();
        pnodeProg->pnodeBody = nullptr;
        AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef, moduleFunction);
    }
    else
    {
        if (isDeferred && !isGlobalCode)
        {
            // Defer parse for a single function should just parse that one function - there are no other statements.
            ushort flags = fFncNoFlgs;
            bool isAsync = false;
            bool isGenerator = false;
            bool isMethod = false;

            // The top-level deferred function body was defined by a function expression whose parsing was deferred. We are now
            // parsing it, so unset the flag so that any nested functions are parsed normally. This flag is only applicable the
            // first time we see it.
            //
            // Normally, deferred functions will be parsed in ParseStatement upon encountering the 'function' token. The first
            // token of the source code of the function may not be a 'function' token though, so we still need to reset this flag
            // for the first function we parse. This can happen in compat modes, for instance, for a function expression enclosed
            // in parentheses, where the legacy behavior was to include the parentheses in the function's source code.
            if (m_grfscr & fscrDeferredFncExpression)
            {
                m_grfscr &= ~fscrDeferredFncExpression;
            }
            else
            {
                flags |= fFncDeclaration;
            }

            if (m_grfscr & fscrDeferredFncIsMethod)
            {
                m_grfscr &= ~fscrDeferredFncIsMethod;
                isMethod = true;
                flags |= fFncNoName | fFncMethod;

                if (m_grfscr & fscrDeferredFncIsGenerator)
                {
                    m_grfscr &= ~fscrDeferredFncIsGenerator;
                    isGenerator = true;
                    flags |= fFncGenerator;
                }

                if (m_token.tk == tkStar && m_scriptContext->GetConfig()->IsES6GeneratorsEnabled())
                {
                    Assert(isGenerator && !isMethod);
                    this->GetScanner()->Scan();
                }
            }

            if (m_grfscr & fscrDeferredFncIsAsync)
            {
                m_grfscr &= ~fscrDeferredFncIsAsync;
                isAsync = true;
                flags |= fFncAsync;
            }


#if DBG
            if (isMethod && m_token.tk == tkID)
            {
                RestorePoint atPid;
                IdentPtr pidHint = m_token.GetIdentifier(this->GetHashTbl());
                this->GetScanner()->Capture(&atPid);
                this->GetScanner()->Scan();
                if ((pidHint == wellKnownPropertyPids.get || pidHint == wellKnownPropertyPids.set) && NextTokenIsPropertyNameStart())
                {
                    // Getter/setter
                    // Skip the get/set keyword and continue normally
                    AssertMsg(false, "We should not be re-parsing the get/set part of member accessor functions");
                }
                else
                {
                    // Not a getter/setter; rewind and treat the token as a name.
                    this->GetScanner()->SeekTo(atPid);
                }
            }
#endif

            // Ensure this isn't a computed name
            AssertMsg(!(m_token.tk == tkLBrack && isMethod), "Can't defer parse a computed name expression, we should have started after this");

            if (!isMethod && (m_token.tk == tkID || m_token.tk == tkLParen))
            {
                // If first token of the function is tkID or tkLParen, this is a lambda.
                flags |= fFncLambda;
            }

            ParseNode * pnodeFnc = ParseFncDeclCheckScope<true>(flags);
            pnodeProg->pnodeBody = nullptr;
            AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef, pnodeFnc);

            // No need to update the cbStringMin property since no ParseableFunctionInfo will be created from this defer-parsed pnodeFnc
        }
        else
        {
            // Process a sequence of statements/declarations
            ParseStmtList<true>(
                &pnodeProg->pnodeBody,
                &lastNodeRef,
                SM_OnGlobalCode,
                !(m_grfscr & fscrDeferredFncExpression) /* isSourceElementList */);
        }
    }

    if (m_parseType == ParseType_Deferred)
    {
        if (scopeInfo)
        {
            this->FinishScopeInfo(scopeInfo);
        }
    }

    pnodeProg->m_UsesArgumentsAtGlobal = m_UsesArgumentsAtGlobal;

    if (IsStrictMode())
    {
        pnodeProg->SetStrictMode();
    }

#if DEBUG
    if (m_grfscr & fscrEnforceJSON && !IsJSONValid(pnodeProg->pnodeBody))
    {
        Error(ERRsyntax);
    }
#endif

    if (tkEOF != m_token.tk)
        Error(ERRsyntax);

    // Append an EndCode node.
    AddToNodeList(&pnodeProg->pnodeBody, &lastNodeRef,
        CreateNodeForOpT<knopEndCode>());
    Assert(lastNodeRef);
    Assert(*lastNodeRef);
    Assert((*lastNodeRef)->nop == knopEndCode);
    (*lastNodeRef)->ichMin = 0;
    (*lastNodeRef)->ichLim = 0;

    // Get the extent of the code.
    pnodeProg->ichLim = this->GetScanner()->IchLimTok();
    pnodeProg->cbLim = this->GetScanner()->IecpLimTok();

    // Terminate the local list
    *m_ppnodeVar = nullptr;

    Assert(nullptr == *m_ppnodeScope);
    Assert(nullptr == pnodeProg->pnodeNext);

#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
    if (Js::Configuration::Global.flags.IsEnabled(Js::ForceUndoDeferFlag))
    {
        m_stoppedDeferredParse = true;
    }
#endif

    if (m_stoppedDeferredParse)
    {
#if ENABLE_BACKGROUND_PARSING
        if (this->m_hasParallelJob)
        {
            BackgroundParser *bgp = static_cast<BackgroundParser*>(m_scriptContext->GetBackgroundParser());
            Assert(bgp);
            this->WaitForBackgroundJobs(bgp, pse);
        }
#endif

        // Do any remaining bindings of globals referenced in non-deferred functions.
        if (pnodeGlobalEvalBlock)
        {
            FinishParseBlock(pnodeGlobalEvalBlock);
        }

        FinishParseBlock(pnodeGlobalBlock);

        // Clear out references to undeclared identifiers.
        this->GetHashTbl()->VisitPids([&](IdentPtr pid) { pid->SetTopRef(nullptr); });

        // Restore global scope and blockinfo stacks preparatory to reparsing deferred functions.
        PushScope(pnodeGlobalBlock->scope);
        BlockInfoStack *newBlockInfo = PushBlockInfo(pnodeGlobalBlock);
        PushStmt<true>(&newBlockInfo->pstmt, pnodeGlobalBlock, knopBlock, nullptr);

        if (pnodeGlobalEvalBlock)
        {
            PushScope(pnodeGlobalEvalBlock->scope);
            newBlockInfo = PushBlockInfo(pnodeGlobalEvalBlock);
            PushStmt<true>(&newBlockInfo->pstmt, pnodeGlobalEvalBlock, knopBlock, nullptr);
        }

        // Finally, see if there are any function bodies we now want to generate because we
        // decided to stop deferring.
        FinishDeferredFunction(pnodeProg->pnodeScopes);
    }

    if (pnodeGlobalEvalBlock)
    {
        FinishParseBlock(pnodeGlobalEvalBlock);
    }
    // Append block as body of pnodeProg
    FinishParseBlock(pnodeGlobalBlock);

    m_scriptContext->AddSourceSize(m_length);

    if (m_parseType != ParseType_Deferred)
    {
        JS_ETW(EventWriteJSCRIPT_PARSE_METHOD_STOP(m_sourceContextInfo->dwHostSourceContext, GetScriptContext(), pnodeProg->functionId, *m_pCurrentAstSize, false, Js::Constants::GlobalFunction));
    }

    if (isModuleSource)
    {
        // verify that any local module exports are defined
        VerifyModuleLocalExportEntries();
    }

    return pnodeProg;
}


bool Parser::CheckForDirective(bool* pIsUseStrict, bool *pIsUseAsm, bool* pIsOctalInString)
{
    // A directive is a string constant followed by a statement terminating token
    if (m_token.tk != tkStrCon)
        return false;

    // Careful, need to check for octal before calling this->GetScanner()->Scan()
    // because Scan() clears the "had octal" flag on the scanner and
    // this->GetScanner()->Restore() does not restore this flag.
    if (pIsOctalInString != nullptr)
    {
        *pIsOctalInString = this->GetScanner()->IsOctOrLeadingZeroOnLastTKNumber();
    }

    Ident* pidDirective = m_token.GetStr();
    RestorePoint start;
    this->GetScanner()->Capture(&start);
    this->GetScanner()->Scan();

    bool isDirective = true;

    switch (m_token.tk)
    {
    case tkSColon:
    case tkEOF:
    case tkLCurly:
    case tkRCurly:
        break;
    default:
        if (!this->GetScanner()->FHadNewLine())
        {
            isDirective = false;
        }
        break;
    }

    if (isDirective)
    {
        if (pIsUseStrict != nullptr)
        {
            *pIsUseStrict = CheckStrictModeStrPid(pidDirective);
        }
        if (pIsUseAsm != nullptr)
        {
            *pIsUseAsm = CheckAsmjsModeStrPid(pidDirective);
        }
    }

    this->GetScanner()->SeekTo(start);
    return isDirective;
}

bool Parser::CheckStrictModeStrPid(IdentPtr pid)
{
#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
    if (Js::Configuration::Global.flags.NoStrictMode)
        return false;
#endif

    return pid != nullptr &&
        pid->Cch() == 10 &&
        !this->GetScanner()->IsEscapeOnLastTkStrCon() &&
        wcsncmp(pid->Psz(), _u("use strict"), 10) == 0;
}

bool Parser::CheckAsmjsModeStrPid(IdentPtr pid)
{
#ifdef ASMJS_PLAT
    if (!CONFIG_FLAG(AsmJs))
    {
        return false;
    }

    bool isAsmCandidate = (pid != nullptr &&
        AutoSystemInfo::Data.SSE2Available() &&
        pid->Cch() == 7 &&
        !this->GetScanner()->IsEscapeOnLastTkStrCon() &&
        wcsncmp(pid->Psz(), _u("use asm"), 10) == 0);

#ifdef ENABLE_SCRIPT_DEBUGGING
    if (isAsmCandidate && m_scriptContext->IsScriptContextInDebugMode())
    {
        // We would like to report this to debugger - they may choose to disable debugging.
        // TODO : localization of the string?
        m_scriptContext->RaiseMessageToDebugger(DEIT_ASMJS_IN_DEBUGGING, _u("AsmJs initialization error - AsmJs disabled due to script debugger"), m_sourceContextInfo && !m_sourceContextInfo->IsDynamic() ? m_sourceContextInfo->url : nullptr);
        return false;
    }
#endif

    return isAsmCandidate && !(m_grfscr & fscrNoAsmJs);
#else
    return false;
#endif
}

HRESULT Parser::ParseUtf8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
    Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
{
    m_functionBody = nullptr;
    m_parseType = ParseType_Upfront;
    return ParseSourceInternal(parseTree, pSrc, 0, length, 0, true, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
}

HRESULT Parser::ParseCesu8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
    Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
{
    m_functionBody = nullptr;
    m_parseType = ParseType_Upfront;
    return ParseSourceInternal(parseTree, pSrc, 0, length, 0, false, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
}

#if ENABLE_BACKGROUND_PARSING
void Parser::PrepareForBackgroundParse()
{
    this->GetScanner()->PrepareForBackgroundParse(m_scriptContext);
}

void Parser::AddBackgroundParseItem(BackgroundParseItem *const item)
{
    if (currBackgroundParseItem == nullptr)
    {
        backgroundParseItems = item;
    }
    else
    {
        currBackgroundParseItem->SetNext(item);
    }
    currBackgroundParseItem = item;
}

void Parser::AddFastScannedRegExpNode(ParseNodePtr const pnode)
{
    Assert(!IsBackgroundParser());
    Assert(m_doingFastScan);

    if (fastScannedRegExpNodes == nullptr)
    {
        fastScannedRegExpNodes = Anew(&m_nodeAllocator, NodeDList, &m_nodeAllocator);
    }
    fastScannedRegExpNodes->Append(pnode);
}

void Parser::AddBackgroundRegExpNode(ParseNodePtr const pnode)
{
    Assert(IsBackgroundParser());
    Assert(currBackgroundParseItem != nullptr);

    currBackgroundParseItem->AddRegExpNode(pnode, &m_nodeAllocator);
}

HRESULT Parser::ParseFunctionInBackground(ParseNodeFnc * pnodeFnc, ParseContext *parseContext, bool topLevelDeferred, CompileScriptException *pse)
{
    m_functionBody = nullptr;
    m_parseType = ParseType_Upfront;
    HRESULT hr = S_OK;
    SmartFPUControl smartFpuControl;
    uint nextFunctionId = pnodeFnc->functionId + 1;

    this->RestoreContext(parseContext);
    m_nextFunctionId = &nextFunctionId;
    m_deferringAST = topLevelDeferred;
    m_inDeferredNestedFunc = false;
    m_scopeCountNoAst = 0;

    SetCurrentStatement(nullptr);

    pnodeFnc->pnodeVars = nullptr;
    pnodeFnc->pnodeParams = nullptr;
    pnodeFnc->pnodeBody = nullptr;
    pnodeFnc->nestedCount = 0;

    ParseNodeFnc * pnodeParentFnc = GetCurrentFunctionNode();
    m_currentNodeFunc = pnodeFnc;
    m_currentNodeDeferredFunc = nullptr;
    m_ppnodeScope = nullptr;
    m_ppnodeExprScope = nullptr;

    m_pnestedCount = &pnodeFnc->nestedCount;
    m_pCurrentAstSize = &pnodeFnc->astSize;

    ParseNodeBlock * pnodeBlock = StartParseBlock<true>(PnodeBlockType::Function, ScopeType_FunctionBody);
    pnodeFnc->pnodeScopes = pnodeBlock;
    m_ppnodeScope = &pnodeBlock->pnodeScopes;
    bool handled = false;

    uint uDeferSave = m_grfscr & (fscrCanDeferFncParse | fscrWillDeferFncParse);

    try
    {
        this->GetScanner()->Scan();

        m_ppnodeVar = &pnodeFnc->pnodeParams;
        this->ParseFncFormals<true>(pnodeFnc, pnodeParentFnc, fFncNoFlgs);

        if (m_token.tk == tkRParen)
        {
            this->GetScanner()->Scan();
        }

        ChkCurTok(tkLCurly, ERRnoLcurly);

        m_ppnodeVar = &pnodeFnc->pnodeVars;

        // Put the scanner into "no hashing" mode.
        BYTE deferFlags = this->GetScanner()->SetDeferredParse(topLevelDeferred);

        // Process a sequence of statements/declarations
        if (topLevelDeferred)
        {
            ParseStmtList<false>(nullptr, nullptr, SM_DeferredParse, true);
        }
        else
        {
            ParseNodePtr *lastNodeRef = nullptr;
            ParseStmtList<true>(&pnodeFnc->pnodeBody, &lastNodeRef, SM_OnFunctionCode, true);
            AddArgumentsNodeToVars(pnodeFnc);
            // Append an EndCode node.
            AddToNodeList(&pnodeFnc->pnodeBody, &lastNodeRef, CreateNodeForOpT<knopEndCode>());
        }

        // Restore the scanner's default hashing mode.
        this->GetScanner()->SetDeferredParseFlags(deferFlags);

#if DBG
        pnodeFnc->deferredParseNextFunctionId = *this->m_nextFunctionId;
#endif
        this->m_deferringAST = FALSE;

        // Append block as body of pnodeProg
        FinishParseBlock(pnodeBlock);
    }
    catch (ParseExceptionObject& e)
    {
        hr = e.GetError();
        hr = pse->ProcessError(this->GetScanner(), hr, nullptr, e.GetStringOne(), e.GetStringTwo());
        handled = true;
    }

    if (handled == false && FAILED(hr))
    {
        hr = pse->ProcessError(this->GetScanner(), hr, nullptr);
    }

    if (IsStrictMode())
    {
        pnodeFnc->SetStrictMode();
    }

    if (topLevelDeferred)
    {
        pnodeFnc->pnodeVars = nullptr;
    }

    m_grfscr |= uDeferSave;

    Assert(nullptr == *m_ppnodeScope);

    return hr;
}

#endif

HRESULT Parser::ParseSourceWithOffset(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
    bool isCesu8, ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo,
    Js::ParseableFunctionInfo* functionInfo)
{
    m_functionBody = functionInfo;
    if (m_functionBody)
    {
        m_currDeferredStub = m_functionBody->GetDeferredStubs();
        m_currDeferredStubCount = m_currDeferredStub != nullptr ? m_functionBody->GetNestedCount() : 0;
        m_InAsmMode = grfscr & fscrNoAsmJs ? false : m_functionBody->GetIsAsmjsMode();
    }
    m_deferAsmJs = !m_InAsmMode;
    m_parseType = ParseType_Deferred;
    return ParseSourceInternal(parseTree, pSrc, offset, cbLength, cchOffset, !isCesu8, grfscr, pse, nextFunctionId, lineNumber, sourceContextInfo);
}

bool Parser::IsStrictMode() const
{
    return (m_fUseStrictMode ||
        (m_currentNodeFunc != nullptr && m_currentNodeFunc->GetStrictMode()));
}

BOOL Parser::ExpectingExternalSource()
{
    return m_fExpectExternalSource;
}

Symbol *ParseNodeFnc::GetFuncSymbol()
{
    if (pnodeName)
    {
        Assert(pnodeName->nop == knopVarDecl);
        return pnodeName->sym;
    }
    return nullptr;
}

void ParseNodeFnc::SetFuncSymbol(Symbol *sym)
{
    Assert(pnodeName);
    Assert(pnodeName->nop == knopVarDecl);
    pnodeName->sym = sym;
}

ParseNodePtr ParseNodeFnc::GetParamScope() const
{
    if (this->pnodeScopes == nullptr)
    {
        return nullptr;
    }
    Assert(this->pnodeScopes->nop == knopBlock &&
        this->pnodeScopes->pnodeNext == nullptr);
    return this->pnodeScopes->pnodeScopes;
}

ParseNodePtr ParseNodeFnc::GetBodyScope() const
{
    if (this->pnodeBodyScope == nullptr)
    {
        return nullptr;
    }
    Assert(this->pnodeBodyScope->nop == knopBlock &&
        this->pnodeBodyScope->pnodeNext == nullptr);
    return this->pnodeBodyScope->pnodeScopes;
}

bool ParseNodeBlock::HasBlockScopedContent() const
{
    // A block has its own content if a let, const, or function is declared there.

    if (this->pnodeLexVars != nullptr || this->blockType == Parameter)
    {
        return true;
    }

    // The enclosing scopes can contain functions and other things, so walk the list
    // looking specifically for functions.

    for (ParseNodePtr pnode = this->pnodeScopes; pnode;)
    {
        switch (pnode->nop) {

        case knopFncDecl:
            return true;

        case knopBlock:
            pnode = pnode->AsParseNodeBlock()->pnodeNext;
            break;

        case knopCatch:
            pnode = pnode->AsParseNodeCatch()->pnodeNext;
            break;

        case knopWith:
            pnode = pnode->AsParseNodeWith()->pnodeNext;
            break;

        default:
            Assert(UNREACHED);
            return true;
        }
    }

    return false;
}

class ByteCodeGenerator;

// Copy AST; this works mostly on expressions for now
ParseNode* Parser::CopyPnode(ParseNode *pnode) {
    if (pnode == NULL)
        return NULL;
    switch (pnode->nop) {
        //PTNODE(knopName       , "name"        ,None    ,Pid  ,fnopLeaf)
    case knopName: {
        ParseNodeName * nameNode = CreateNameNode(pnode->AsParseNodeName()->pid);
        nameNode->ichMin = pnode->ichMin;
        nameNode->ichLim = pnode->ichLim;
        nameNode->sym = pnode->AsParseNodeName()->sym;
        return nameNode;
    }
                   //PTNODE(knopInt        , "int const"    ,None    ,Int  ,fnopLeaf|fnopConst)
    case knopInt:
        return pnode;
        //PTNODE(knopBigInt        , "bigint const"    ,None    ,BigInt  ,fnopLeaf|fnopConst)
    case knopBigInt:
        return pnode;
        //PTNODE(knopFlt        , "flt const"    ,None    ,Flt  ,fnopLeaf|fnopConst)
    case knopFlt:
        return pnode;
        //PTNODE(knopStr        , "str const"    ,None    ,Pid  ,fnopLeaf|fnopConst)
    case knopStr:
        return pnode;
        //PTNODE(knopRegExp     , "reg expr"    ,None    ,Pid  ,fnopLeaf|fnopConst)
    case knopRegExp:
        return pnode;
        break;
        //PTNODE(knopNull       , "null"        ,Null    ,None ,fnopLeaf)
    case knopNull:
        return pnode;
        //PTNODE(knopFalse      , "false"        ,False   ,None ,fnopLeaf)
    case knopFalse:
    {
        ParseNode* ret = CreateNodeForOpT<knopFalse>(pnode->ichMin, pnode->ichLim);
        ret->location = pnode->location;
        return ret;
    }
    //PTNODE(knopTrue       , "true"        ,True    ,None ,fnopLeaf)
    case knopTrue:
    {
        ParseNode* ret = CreateNodeForOpT<knopTrue>(pnode->ichMin, pnode->ichLim);
        ret->location = pnode->location;
        return ret;
    }
    //PTNODE(knopEmpty      , "empty"        ,Empty   ,None ,fnopLeaf)
    case knopEmpty:
        return CreateNodeForOpT<knopEmpty>(pnode->ichMin, pnode->ichLim);
        // Unary operators.
        //PTNODE(knopNot        , "~"            ,BitNot  ,Uni  ,fnopUni)
        //PTNODE(knopNeg        , "unary -"    ,Neg     ,Uni  ,fnopUni)
        //PTNODE(knopPos        , "unary +"    ,Pos     ,Uni  ,fnopUni)
        //PTNODE(knopLogNot     , "!"            ,LogNot  ,Uni  ,fnopUni)
        //PTNODE(knopEllipsis     , "..."       ,Spread  ,Uni    , fnopUni)
        //PTNODE(knopDecPost    , "-- post"    ,Dec     ,Uni  ,fnopUni|fnopAsg)
        //PTNODE(knopIncPre     , "++ pre"    ,Inc     ,Uni  ,fnopUni|fnopAsg)
        //PTNODE(knopDecPre     , "-- pre"    ,Dec     ,Uni  ,fnopUni|fnopAsg)
        //PTNODE(knopTypeof     , "typeof"    ,None    ,Uni  ,fnopUni)
        //PTNODE(knopVoid       , "void"        ,Void    ,Uni  ,fnopUni)
        //PTNODE(knopDelete     , "delete"    ,None    ,Uni  ,fnopUni)
    case knopNot:
    case knopNeg:
    case knopPos:
    case knopLogNot:
    case knopEllipsis:
    case knopIncPost:
    case knopDecPost:
    case knopIncPre:
    case knopDecPre:
    case knopTypeof:
    case knopVoid:
    case knopDelete:
        return CreateUniNode(pnode->nop, CopyPnode(pnode->AsParseNodeUni()->pnode1), pnode->ichMin, pnode->ichLim);
        //PTNODE(knopArray      , "arr cnst"    ,None    ,Uni  ,fnopUni)
        //PTNODE(knopObject     , "obj cnst"    ,None    ,Uni  ,fnopUni)
    case knopArray:
    case knopObject:
        // TODO: need to copy arr
        Assert(false);
        break;
        // Binary operators
        //PTNODE(knopAdd        , "+"            ,Add     ,Bin  ,fnopBin)
        //PTNODE(knopSub        , "-"            ,Sub     ,Bin  ,fnopBin)
        //PTNODE(knopMul        , "*"            ,Mul     ,Bin  ,fnopBin)
        //PTNODE(knopExpo       , "**"           ,Expo     ,Bin  ,fnopBin)
        //PTNODE(knopDiv        , "/"            ,Div     ,Bin  ,fnopBin)
        //PTNODE(knopMod        , "%"            ,Mod     ,Bin  ,fnopBin)
        //PTNODE(knopOr         , "|"            ,BitOr   ,Bin  ,fnopBin)
        //PTNODE(knopXor        , "^"            ,BitXor  ,Bin  ,fnopBin)
        //PTNODE(knopAnd        , "&"            ,BitAnd  ,Bin  ,fnopBin)
        //PTNODE(knopEq         , "=="        ,EQ      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopNe         , "!="        ,NE      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopLt         , "<"            ,LT      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopLe         , "<="        ,LE      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopGe         , ">="        ,GE      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopGt         , ">"            ,GT      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopEqv        , "==="        ,Eqv     ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopIn         , "in"        ,In      ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopInstOf     , "instanceof",InstOf  ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopNEqv       , "!=="        ,NEqv    ,Bin  ,fnopBin|fnopRel)
        //PTNODE(knopComma      , ","            ,None    ,Bin  ,fnopBin)
        //PTNODE(knopLogOr      , "||"        ,None    ,Bin  ,fnopBin)
        //PTNODE(knopLogAnd     , "&&"        ,None    ,Bin  ,fnopBin)
        //PTNODE(knopLsh        , "<<"        ,Lsh     ,Bin  ,fnopBin)
        //PTNODE(knopRsh        , ">>"        ,Rsh     ,Bin  ,fnopBin)
        //PTNODE(knopRs2        , ">>>"        ,Rs2     ,Bin  ,fnopBin)
    case knopAdd:
    case knopSub:
    case knopMul:
    case knopExpo:
    case knopDiv:
    case knopMod:
    case knopOr:
    case knopXor:
    case knopAnd:
    case knopEq:
    case knopNe:
    case knopLt:
    case knopLe:
    case knopGe:
    case knopGt:
    case knopEqv:
    case knopIn:
    case knopInstOf:
    case knopNEqv:
    case knopComma:
    case knopLogOr:
    case knopLogAnd:
    case knopLsh:
    case knopRsh:
    case knopRs2:
        //PTNODE(knopAsg        , "="            ,None    ,Bin  ,fnopBin|fnopAsg)
    case knopAsg:
        //PTNODE(knopDot        , "."            ,None    ,Bin  ,fnopBin)
    case knopDot:
        //PTNODE(knopAsgAdd     , "+="        ,Add     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgAdd:
        //PTNODE(knopAsgSub     , "-="        ,Sub     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgSub:
        //PTNODE(knopAsgMul     , "*="        ,Mul     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgMul:
        //PTNODE(knopAsgDiv     , "/="        ,Div     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgExpo:
        //PTNODE(knopAsgExpo    , "**="       ,Expo    ,Bin  ,fnopBin|fnopAsg)
    case knopAsgDiv:
        //PTNODE(knopAsgMod     , "%="        ,Mod     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgMod:
        //PTNODE(knopAsgAnd     , "&="        ,BitAnd  ,Bin  ,fnopBin|fnopAsg)
    case knopAsgAnd:
        //PTNODE(knopAsgXor     , "^="        ,BitXor  ,Bin  ,fnopBin|fnopAsg)
    case knopAsgXor:
        //PTNODE(knopAsgOr      , "|="        ,BitOr   ,Bin  ,fnopBin|fnopAsg)
    case knopAsgOr:
        //PTNODE(knopAsgLsh     , "<<="        ,Lsh     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgLsh:
        //PTNODE(knopAsgRsh     , ">>="        ,Rsh     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgRsh:
        //PTNODE(knopAsgRs2     , ">>>="        ,Rs2     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgRs2:
        //PTNODE(knopMember     , ":"            ,None    ,Bin  ,fnopBin)
    case knopMember:
    case knopMemberShort:
        //PTNODE(knopIndex      , "[]"        ,None    ,Bin  ,fnopBin)
        //PTNODE(knopList       , "<list>"    ,None    ,Bin  ,fnopNone)

    case knopIndex:
    case knopList:
        return CreateBinNode(pnode->nop, CopyPnode(pnode->AsParseNodeBin()->pnode1),
            CopyPnode(pnode->AsParseNodeBin()->pnode2), pnode->ichMin, pnode->ichLim);

        //PTNODE(knopCall       , "()"        ,None    ,Bin  ,fnopBin)
        //PTNODE(knopNew        , "new"        ,None    ,Bin  ,fnopBin)
    case knopNew:
    case knopCall:
        return CreateCallNode(pnode->nop, CopyPnode(pnode->AsParseNodeCall()->pnodeTarget),
            CopyPnode(pnode->AsParseNodeCall()->pnodeArgs), pnode->ichMin, pnode->ichLim);
        //PTNODE(knopQmark      , "?"            ,None    ,Tri  ,fnopBin)
    case knopQmark:
        return CreateTriNode(pnode->nop, CopyPnode(pnode->AsParseNodeTri()->pnode1),
            CopyPnode(pnode->AsParseNodeTri()->pnode2), CopyPnode(pnode->AsParseNodeTri()->pnode3),
            pnode->ichMin, pnode->ichLim);
        // General nodes.
        //PTNODE(knopVarDecl    , "varDcl"    ,None    ,Var  ,fnopNone)
    case knopVarDecl: {
        ParseNodeVar* copyNode = Anew(&m_nodeAllocator, ParseNodeVar, knopVarDecl, pnode->ichMin, pnode->ichLim, nullptr);
        copyNode->pnodeInit = CopyPnode(pnode->AsParseNodeVar()->pnodeInit);
        copyNode->sym = pnode->AsParseNodeVar()->sym;
        // TODO: mult-decl
        Assert(pnode->AsParseNodeVar()->pnodeNext == NULL);
        copyNode->pnodeNext = NULL;
        return copyNode;
    }
                      //PTNODE(knopFncDecl    , "fncDcl"    ,None    ,Fnc  ,fnopLeaf)
                      //PTNODE(knopProg       , "program"    ,None    ,Fnc  ,fnopNone)
    case knopFncDecl:
    case knopProg:
        Assert(false);
        break;
        //PTNODE(knopEndCode    , "<endcode>"    ,None    ,None ,fnopNone)
    case knopEndCode:
        break;
        //PTNODE(knopDebugger   , "debugger"    ,None    ,None ,fnopNone)
    case knopDebugger:
        break;
        //PTNODE(knopFor        , "for"        ,None    ,For  ,fnopBreak|fnopContinue)
    case knopFor: {
        ParseNode* copyNode = CreateNodeForOpT<knopFor>(pnode->ichMin, pnode->ichLim);
        copyNode->AsParseNodeFor()->pnodeInverted = NULL;
        copyNode->AsParseNodeFor()->pnodeInit = CopyPnode(pnode->AsParseNodeFor()->pnodeInit);
        copyNode->AsParseNodeFor()->pnodeCond = CopyPnode(pnode->AsParseNodeFor()->pnodeCond);
        copyNode->AsParseNodeFor()->pnodeIncr = CopyPnode(pnode->AsParseNodeFor()->pnodeIncr);
        copyNode->AsParseNodeFor()->pnodeBody = CopyPnode(pnode->AsParseNodeFor()->pnodeBody);
        return copyNode;
    }
                  //PTNODE(knopIf         , "if"        ,None    ,If   ,fnopNone)
    case knopIf:
        Assert(false);
        break;
        //PTNODE(knopWhile      , "while"        ,None    ,While,fnopBreak|fnopContinue)
    case knopWhile:
        Assert(false);
        break;
        //PTNODE(knopDoWhile    , "do-while"    ,None    ,While,fnopBreak|fnopContinue)
    case knopDoWhile:
        Assert(false);
        break;
        //PTNODE(knopForIn      , "for in"    ,None    ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
    case knopForIn:
        Assert(false);
        break;
    case knopForOf:
        Assert(false);
        break;
        //PTNODE(knopReturn     , "return"    ,None    ,Uni  ,fnopNone)
    case knopReturn: {
        ParseNode* copyNode = CreateNodeForOpT<knopReturn>(pnode->ichMin, pnode->ichLim);
        copyNode->AsParseNodeReturn()->pnodeExpr = CopyPnode(pnode->AsParseNodeReturn()->pnodeExpr);
        return copyNode;
    }
                     //PTNODE(knopBlock      , "{}"        ,None    ,Block,fnopNone)
    case knopBlock: {
        ParseNodeBlock* copyNode = CreateBlockNode(pnode->ichMin, pnode->ichLim, pnode->AsParseNodeBlock()->blockType);
        if (pnode->grfpn & PNodeFlags::fpnSyntheticNode) {
            // fpnSyntheticNode is sometimes set on PnodeBlockType::Regular blocks which
            // CreateBlockNode() will not automatically set for us, so set it here if it's
            // specified on the source node.
            copyNode->grfpn |= PNodeFlags::fpnSyntheticNode;
        }
        copyNode->pnodeStmt = CopyPnode(pnode->AsParseNodeBlock()->pnodeStmt);
        return copyNode;
    }
                    //PTNODE(knopWith       , "with"        ,None    ,With ,fnopCleanup)
    case knopWith:
        Assert(false);
        break;
        //PTNODE(knopBreak      , "break"        ,None    ,Jump ,fnopNone)
    case knopBreak:
        Assert(false);
        break;
        //PTNODE(knopContinue   , "continue"    ,None    ,Jump ,fnopNone)
    case knopContinue:
        Assert(false);
        break;
        //PTNODE(knopSwitch     , "switch"    ,None    ,Switch,fnopBreak)
    case knopSwitch:
        Assert(false);
        break;
        //PTNODE(knopCase       , "case"        ,None    ,Case ,fnopNone)
    case knopCase:
        Assert(false);
        break;
        //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
    case knopTryFinally:
        Assert(false);
        break;
    case knopFinally:
        Assert(false);
        break;
        //PTNODE(knopCatch      , "catch"     ,None    ,Catch,fnopNone)
    case knopCatch:
        Assert(false);
        break;
        //PTNODE(knopTryCatch      , "try-catch" ,None    ,TryCatch  ,fnopCleanup)
    case knopTryCatch:
        Assert(false);
        break;
        //PTNODE(knopTry        , "try"       ,None    ,Try  ,fnopCleanup)
    case knopTry:
        Assert(false);
        break;
        //PTNODE(knopThrow      , "throw"     ,None    ,Uni  ,fnopNone)
    case knopThrow:
        Assert(false);
        break;
    default:
        Assert(false);
        break;
    }
    return NULL;
}

// Returns true when str is string for Nan, Infinity or -Infinity.
// Does not check for double number value being in NaN/Infinity range.
// static
template<bool CheckForNegativeInfinity>
inline bool Parser::IsNaNOrInfinityLiteral(LPCOLESTR str)
{
    // Note: wcscmp crashes when one of the parameters is NULL.
    return str &&
        (wcscmp(_u("NaN"), str) == 0 ||
            wcscmp(_u("Infinity"), str) == 0 ||
            (CheckForNegativeInfinity && wcscmp(_u("-Infinity"), str) == 0));
}

template <bool buildAST>
IdentPtr Parser::ParseSuper(bool fAllowCall)
{
    ParseNodeFnc * currentNodeFunc = GetCurrentFunctionNode();
    ParseNodeFnc * currentNonLambdaFunc = GetCurrentNonLambdaFunctionNode();
    IdentPtr superPid = nullptr;

    switch (m_token.tk)
    {
    case tkDot:     // super.prop
    case tkLBrack:  // super[foo]
        superPid = wellKnownPropertyPids._super;
        break;
    case tkLParen:  // super(args)
        superPid = wellKnownPropertyPids._superConstructor;
        break;

    default:
        Error(ERRInvalidSuper);
        break;
    }

    currentNodeFunc->SetHasSuperReference(TRUE);
    CHAKRATEL_LANGSTATS_INC_LANGFEATURECOUNT(ES6, Super, m_scriptContext);

    // If we are defer parsing, we can skip verifying that the super reference is valid.
    // If it wasn't the parser would have thrown during upfront parsing and we wouldn't be defer parsing the function.
    if (m_parseType == ParseType_Deferred)
    {
        return superPid;
    }

    if (!fAllowCall && (m_token.tk == tkLParen))
    {
        Error(ERRInvalidSuper); // new super() is not allowed
    }
    else if ((currentNodeFunc->IsConstructor() && currentNodeFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed)
                || (currentNonLambdaFunc != nullptr && currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::CallAndPropertyAllowed))
    {
        // Any super access is good within a class constructor
    }
    else if ((this->m_grfscr & fscrEval) == fscrEval || (currentNonLambdaFunc != nullptr && currentNonLambdaFunc->superRestrictionState == SuperRestrictionState::PropertyAllowed))
    {
        // Currently for eval cases during compile time we use propertyallowed and throw during runtime for error cases
        if (m_token.tk == tkLParen)
        {
            if ((this->m_grfscr & fscrEval) == fscrNil)
            {
                // Cannot call super within a class member
                Error(ERRInvalidSuper);
            }
            else
            {
                Js::JavascriptFunction * caller = nullptr;
                if (Js::JavascriptStackWalker::GetCaller(&caller, m_scriptContext))
                {
                    Js::FunctionBody * callerBody = caller->GetFunctionBody();
                    Assert(callerBody);
                    if (!callerBody->GetFunctionInfo()->GetAllowDirectSuper())
                    {
                        Error(ERRInvalidSuper);
                    }
                }
            }
        }
    }
    else
    {
        // Anything else is an error
        Error(ERRInvalidSuper);
    }

    return superPid;
}

void Parser::AppendToList(ParseNodePtr *node, ParseNodePtr nodeToAppend)
{
    Assert(nodeToAppend);
    ParseNodePtr* lastPtr = node;
    while ((*lastPtr) && (*lastPtr)->nop == knopList)
    {
        lastPtr = &(*lastPtr)->AsParseNodeBin()->pnode2;
    }
    auto last = (*lastPtr);
    if (last)
    {
        *lastPtr = CreateBinNode(knopList, last, nodeToAppend, last->ichMin, nodeToAppend->ichLim);
    }
    else
    {
        *lastPtr = nodeToAppend;
    }
}

ParseNodePtr Parser::ConvertArrayToArrayPattern(ParseNodePtr pnode)
{
    Assert(pnode->nop == knopArray);
    pnode->nop = knopArrayPattern;

    ForEachItemRefInList(&pnode->AsParseNodeArrLit()->pnode1, [&](ParseNodePtr *itemRef) {
        ParseNodePtr item = *itemRef;
        if (item->nop == knopEllipsis)
        {
            itemRef = &item->AsParseNodeUni()->pnode1;
            item = *itemRef;
            if (!(item->nop == knopName
                || item->nop == knopDot
                || item->nop == knopIndex
                || item->nop == knopArray
                || item->nop == knopObject))
            {
                Error(ERRInvalidAssignmentTarget);
            }
        }
        else if (item->nop == knopAsg)
        {
            itemRef = &item->AsParseNodeBin()->pnode1;
            item = *itemRef;
        }

        if (item->nop == knopArray)
        {
            ConvertArrayToArrayPattern(item);
        }
        else if (item->nop == knopObject)
        {
            *itemRef = ConvertObjectToObjectPattern(item);
        }
    });

    return pnode;
}

ParseNodeUni * Parser::ConvertObjectToObjectPattern(ParseNodePtr pnodeMemberList)
{
    charcount_t ichMin = this->GetScanner()->IchMinTok();
    charcount_t ichLim = this->GetScanner()->IchLimTok();
    if (pnodeMemberList != nullptr && pnodeMemberList->nop == knopObject)
    {
        ichMin = pnodeMemberList->ichMin;
        ichLim = pnodeMemberList->ichLim;
        pnodeMemberList = pnodeMemberList->AsParseNodeUni()->pnode1;
    }

    ParseNodeObjLit * objectPatternNode = CreateObjectPatternNode(pnodeMemberList, ichMin, ichLim, true/*convertToPattern*/);
    return objectPatternNode;
}

ParseNodePtr Parser::GetRightSideNodeFromPattern(ParseNodePtr pnode)
{
    Assert(pnode != nullptr);
    ParseNodePtr rightNode = nullptr;
    OpCode op = pnode->nop;
    if (op == knopObject)
    {
        rightNode = ConvertObjectToObjectPattern(pnode);
    }
    else if (op == knopArray)
    {
        rightNode = ConvertArrayToArrayPattern(pnode);
    }
    else
    {
        rightNode = pnode;
        if (op == knopAsg)
        {
            TrackAssignment<true>(pnode->AsParseNodeBin()->pnode1, nullptr);
        }
    }

    return rightNode;
}

ParseNodePtr Parser::ConvertMemberToMemberPattern(ParseNodePtr pnodeMember)
{
    if (pnodeMember->nop == knopObjectPatternMember || pnodeMember->nop == knopEllipsis)
    {
        return pnodeMember;
    }

    Assert(pnodeMember->nop == knopMember || pnodeMember->nop == knopMemberShort);

    ParseNodePtr rightNode = GetRightSideNodeFromPattern(pnodeMember->AsParseNodeBin()->pnode2);
    ParseNodePtr resultNode = CreateBinNode(knopObjectPatternMember, pnodeMember->AsParseNodeBin()->pnode1, rightNode);
    resultNode->ichMin = pnodeMember->ichMin;
    resultNode->ichLim = pnodeMember->ichLim;
    return resultNode;
}

ParseNodePtr Parser::ConvertToPattern(ParseNodePtr pnode)
{
    if (pnode != nullptr)
    {
        if (pnode->nop == knopArray)
        {
            ConvertArrayToArrayPattern(pnode);
        }
        else if (pnode->nop == knopObject)
        {
            pnode = ConvertObjectToObjectPattern(pnode);
        }
    }
    return pnode;
}

// This essentially be called for verifying the structure of the current tree with satisfying the destructuring grammar.
void Parser::ParseDestructuredLiteralWithScopeSave(tokens declarationType,
    bool isDecl,
    bool topLevel,
    DestructuringInitializerContext initializerContext/* = DIC_None*/,
    bool allowIn /*= true*/)
{
    // We are going to parse the text again to validate the current grammar as Destructuring. Saving some scopes and
    // AST related information before the validation parsing and later they will be restored.

    ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
    ParseNodeFnc * pnodeDeferredFncSave = m_currentNodeDeferredFunc;
    if (m_currentNodeDeferredFunc == nullptr)
    {
        m_currentNodeDeferredFunc = m_currentNodeFunc;
    }
    int32 *pAstSizeSave = m_pCurrentAstSize;
    uint *pNestedCountSave = m_pnestedCount;
    ParseNodePtr *ppnodeScopeSave = m_ppnodeScope;
    ParseNodePtr *ppnodeExprScopeSave = m_ppnodeExprScope;

    ParseNodePtr newTempScope = nullptr;
    m_ppnodeScope = &newTempScope;

    int32 newTempAstSize = 0;
    m_pCurrentAstSize = &newTempAstSize;

    uint newTempNestedCount = 0;
    m_pnestedCount = &newTempNestedCount;

    m_ppnodeExprScope = nullptr;

    charcount_t funcInArraySave = m_funcInArray;
    uint funcInArrayDepthSave = m_funcInArrayDepth;

    // we need to reset this as we are going to parse the grammar again.
    m_hasDeferredShorthandInitError = false;

    ParseDestructuredLiteral<false>(declarationType, isDecl, topLevel, initializerContext, allowIn);

    m_currentNodeFunc = pnodeFncSave;
    m_currentNodeDeferredFunc = pnodeDeferredFncSave;
    m_pCurrentAstSize = pAstSizeSave;
    m_pnestedCount = pNestedCountSave;
    m_ppnodeScope = ppnodeScopeSave;
    m_ppnodeExprScope = ppnodeExprScopeSave;
    m_funcInArray = funcInArraySave;
    m_funcInArrayDepth = funcInArrayDepthSave;
}

template <bool buildAST>
ParseNodePtr Parser::ParseDestructuredLiteral(tokens declarationType,
    bool isDecl,
    bool topLevel/* = true*/,
    DestructuringInitializerContext initializerContext/* = DIC_None*/,
    bool allowIn/* = true*/,
    BOOL *forInOfOkay/* = nullptr*/,
    BOOL *nativeForOkay/* = nullptr*/)
{
    ParseNodeUni * pnode = nullptr;
    Assert(IsPossiblePatternStart());

    PROBE_STACK_NO_DISPOSE(m_scriptContext, Js::Constants::MinStackDefault);

    if (m_token.tk == tkLCurly)
    {
        pnode = ParseDestructuredObjectLiteral<buildAST>(declarationType, isDecl, topLevel);
    }
    else
    {
        pnode = ParseDestructuredArrayLiteral<buildAST>(declarationType, isDecl, topLevel);
    }

    return ParseDestructuredInitializer<buildAST>(pnode, isDecl, topLevel, initializerContext, allowIn, forInOfOkay, nativeForOkay);
}

template <bool buildAST>
ParseNodePtr Parser::ParseDestructuredInitializer(ParseNodeUni * lhsNode,
    bool isDecl,
    bool topLevel,
    DestructuringInitializerContext initializerContext,
    bool allowIn,
    BOOL *forInOfOkay,
    BOOL *nativeForOkay)
{
    this->GetScanner()->Scan();
    if (topLevel && nativeForOkay == nullptr)
    {
        if (initializerContext != DIC_ForceErrorOnInitializer && m_token.tk != tkAsg)
        {
            // e.g. var {x};
            Error(ERRDestructInit);
        }
        else if (initializerContext == DIC_ForceErrorOnInitializer && m_token.tk == tkAsg)
        {
            // e.g. catch([x] = [0])
            Error(ERRDestructNotInit);
        }
    }

    if (m_token.tk != tkAsg || initializerContext == DIC_ShouldNotParseInitializer)
    {
        if (topLevel && nativeForOkay != nullptr)
        {
            // Native loop should have destructuring initializer
            *nativeForOkay = FALSE;
        }

        return lhsNode;
    }

    if (forInOfOkay)
    {
        *forInOfOkay = FALSE;
    }

    this->GetScanner()->Scan();


    bool alreadyHasInitError = m_hasDeferredShorthandInitError;

    ParseNodePtr pnodeDefault = ParseExpr<buildAST>(koplCma, nullptr, allowIn);

    if (m_hasDeferredShorthandInitError && !alreadyHasInitError)
    {
        Error(ERRnoColon);
    }

    ParseNodeBin * pnodeDestructAsg = nullptr;
    if (buildAST)
    {
        Assert(lhsNode != nullptr);

        pnodeDestructAsg = CreateBinNode(knopAsg, lhsNode, pnodeDefault, lhsNode->ichMin, pnodeDefault->ichLim);
    }
    return pnodeDestructAsg;
}

template <bool buildAST>
ParseNodeUni * Parser::ParseDestructuredObjectLiteral(tokens declarationType, bool isDecl, bool topLevel/* = true*/)
{
    Assert(m_token.tk == tkLCurly);
    charcount_t ichMin = this->GetScanner()->IchMinTok();
    this->GetScanner()->Scan();

    if (!isDecl)
    {
        declarationType = tkLCurly;
    }
    ParseNodePtr pnodeMemberList = ParseMemberList<buildAST>(nullptr/*pNameHint*/, nullptr/*pHintLength*/, declarationType);

    charcount_t ichLim = this->GetScanner()->IchLimTok();

    ParseNodeObjLit * objectPatternNode = buildAST ? CreateObjectPatternNode(pnodeMemberList, ichMin, ichLim) : nullptr;

    Assert(m_token.tk == tkRCurly);
    return objectPatternNode;
}



template <bool buildAST>
ParseNodePtr Parser::ParseDestructuredVarDecl(tokens declarationType, bool isDecl, bool *hasSeenRest, bool topLevel/* = true*/, bool allowEmptyExpression/* = true*/, bool isObjectPattern/* =false*/)
{
    ParseNodePtr pnodeElem = nullptr;
    int parenCount = 0;
    bool seenRest = false;
    IdentToken token;

    // Save the Block ID prior to the increments, so we can restore it back.
    int originalCurrentBlockId = GetCurrentBlock()->blockId;

    // Eat the left parentheses only when its not a declaration. This will make sure we throw syntax errors early.
    if (!isDecl)
    {
        while (m_token.tk == tkLParen)
        {
            this->GetScanner()->Scan();
            ++parenCount;

            // Match the block increment we do upon entering parenthetical expressions
            // so that the block ID's will match on reparsing of parameters.
            GetCurrentBlock()->blockId = m_nextBlockId++;
        }
    }

    if (m_token.tk == tkEllipsis)
    {
        // As per ES 2015 : Rest can have left-hand-side-expression when on assignment expression, but under declaration only binding identifier is allowed
        // But spec is going to change for this one to allow LHS-expression both on expression and declaration - so making that happen early.

        seenRest = true;
        this->GetScanner()->Scan();

        // Eat the left parentheses only when its not a declaration. This will make sure we throw syntax errors early.
        if (!isDecl)
        {
            while (m_token.tk == tkLParen)
            {
                this->GetScanner()->Scan();
                ++parenCount;

                // Match the block increment we do upon entering parenthetical expressions
                // so that the block ID's will match on reparsing of parameters.
                GetCurrentBlock()->blockId = m_nextBlockId++;
            }
        }

        
        if (m_token.tk != tkID && m_token.tk != tkTHIS && m_token.tk != tkSUPER)
        {
            bool nestedDestructuring = m_token.tk == tkLCurly || m_token.tk == tkLBrack;
            if ((isObjectPattern && nestedDestructuring) || (!isObjectPattern && !nestedDestructuring))
            {
                if (isDecl)
                {
                    Error(ERRnoIdent);
                }
                else
                {
                    Error(ERRInvalidAssignmentTarget);
                }
            }
        }
    }

    if (IsPossiblePatternStart())
    {
        // For the possible pattern start we do not allow the parens before
        if (parenCount != 0)
        {
            Error(ERRDestructIDRef);
        }

        // Go recursively
        pnodeElem = ParseDestructuredLiteral<buildAST>(declarationType, isDecl, false /*topLevel*/, seenRest ? DIC_ShouldNotParseInitializer : DIC_None);
        if (!isDecl)
        {
            BOOL fCanAssign;
            // Look for postfix operator
            pnodeElem = ParsePostfixOperators<buildAST>(pnodeElem, TRUE, FALSE, FALSE, TRUE, &fCanAssign, &token);
        }
    }
    else if (m_token.tk == tkSUPER || m_token.tk == tkID || m_token.tk == tkTHIS)
    {
        if (isDecl)
        {
            charcount_t ichMin = this->GetScanner()->IchMinTok();
            pnodeElem = ParseVariableDeclaration<buildAST>(declarationType, ichMin
                ,/* fAllowIn */false, /* pfForInOk */nullptr, /* singleDefOnly */true, /* allowInit */!seenRest, false /*topLevelParse*/);

        }
        else
        {
            BOOL fCanAssign;
            // We aren't declaring anything, so scan the ID reference manually.
            pnodeElem = ParseTerm<buildAST>(/* fAllowCall */ m_token.tk != tkSUPER, nullptr /*pNameHint*/, nullptr /*pHintLength*/, nullptr /*pShortNameOffset*/, &token, false,
                FALSE, &fCanAssign);

            // In this destructuring case we can force error here as we cannot assign.

            if (!fCanAssign)
            {
                Error(ERRInvalidAssignmentTarget);
            }

            if (buildAST)
            {
                TrackAssignment<buildAST>(pnodeElem, nullptr);
            }

            if (buildAST)
            {
                if (IsStrictMode() && pnodeElem != nullptr && pnodeElem->nop == knopName)
                {
                    CheckStrictModeEvalArgumentsUsage(pnodeElem->AsParseNodeName()->pid);
                }
            }
            else
            {
                if (IsStrictMode() && token.tk == tkID)
                {
                    CheckStrictModeEvalArgumentsUsage(token.pid);
                }
            }
        }
    }
    else if (!((m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly) && allowEmptyExpression))
    {
        if (m_token.IsOperator())
        {
            Error(ERRDestructNoOper);
        }
        Error(ERRDestructIDRef);
    }

    // Swallow RParens before a default expression, if any.
    // We eat the left parentheses only when its not a declaration. This will make sure we throw syntax errors early. We need to do the same for right parentheses.
    if (!isDecl)
    {
        while (m_token.tk == tkRParen)
        {
            this->GetScanner()->Scan();
            --parenCount;
        }

        // Restore the Block ID of the current block after the parsing of destructured variable declarations and initializers.
        GetCurrentBlock()->blockId = originalCurrentBlockId;
    }

    if (parenCount != 0)
    {
        Error(ERRnoRparen);
    }

    if (hasSeenRest != nullptr)
    {
        *hasSeenRest = seenRest;
    }

    if (m_token.tk == tkAsg)
    {
        // Parse the initializer.
        if (seenRest)
        {
            Error(ERRRestWithDefault);
        }
        this->GetScanner()->Scan();

        bool alreadyHasInitError = m_hasDeferredShorthandInitError;
        ParseNodePtr pnodeInit = ParseExpr<buildAST>(koplCma);

        if (m_hasDeferredShorthandInitError && !alreadyHasInitError)
        {
            Error(ERRnoColon);
        }

        if (buildAST)
        {
            pnodeElem = CreateBinNode(knopAsg, pnodeElem, pnodeInit);
        }
    }

    if (buildAST && seenRest)
    {
        ParseNodePtr pnodeRest = CreateUniNode(knopEllipsis, pnodeElem);
        pnodeElem = pnodeRest;
    }

    if (!(m_token.tk == tkComma || m_token.tk == tkRBrack || m_token.tk == tkRCurly))
    {
        if (m_token.IsOperator())
        {
            Error(ERRDestructNoOper);
        }
        Error(ERRsyntax);
    }

    if (!buildAST && token.tk == tkID)
    {
        TrackAssignment<buildAST>(nullptr, &token);
    }

    return pnodeElem;
}

template <bool buildAST>
ParseNodeUni * Parser::ParseDestructuredArrayLiteral(tokens declarationType, bool isDecl, bool topLevel)
{
    Assert(m_token.tk == tkLBrack);
    charcount_t ichMin = this->GetScanner()->IchMinTok();

    this->GetScanner()->Scan();

    ParseNodeArrLit * pnodeDestructArr = nullptr;
    ParseNodePtr pnodeList = nullptr;
    ParseNodePtr *lastNodeRef = nullptr;
    uint count = 0;
    bool hasMissingValues = false;
    bool seenRest = false;

    if (m_token.tk != tkRBrack)
    {
        while (true)
        {
            ParseNodePtr pnodeElem = ParseDestructuredVarDecl<buildAST>(declarationType, isDecl, &seenRest, topLevel);
            if (buildAST)
            {
                if (pnodeElem == nullptr && buildAST)
                {
                    pnodeElem = CreateNodeForOpT<knopEmpty>();
                    hasMissingValues = true;
                }
                AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeElem);
            }
            count++;

            if (m_token.tk == tkRBrack)
            {
                break;
            }

            if (m_token.tk != tkComma)
            {
                Error(ERRDestructNoOper);
            }

            if (seenRest) // Rest must be in the last position.
            {
                Error(ERRDestructRestLast);
            }

            this->GetScanner()->Scan();

            // break if we have the trailing comma as well, eg. [a,]
            if (m_token.tk == tkRBrack)
            {
                break;
            }
        }
    }

    if (buildAST)
    {
        pnodeDestructArr = CreateNodeForOpT<knopArrayPattern>(ichMin);
        pnodeDestructArr->pnode1 = pnodeList;
        pnodeDestructArr->arrayOfTaggedInts = false;
        pnodeDestructArr->arrayOfInts = false;
        pnodeDestructArr->arrayOfNumbers = false;
        pnodeDestructArr->hasMissingValues = hasMissingValues;
        pnodeDestructArr->count = count;
        pnodeDestructArr->spreadCount = seenRest ? 1 : 0;

        if (pnodeDestructArr->pnode1)
        {
            this->CheckArguments(pnodeDestructArr->pnode1);
        }
    }

    return pnodeDestructArr;
}

void Parser::CaptureContext(ParseContext *parseContext) const
{
    parseContext->pszSrc = this->GetScanner()->PchBase();
    parseContext->length = this->m_originalLength;
    parseContext->characterOffset = this->GetScanner()->IchMinTok();
    parseContext->offset = parseContext->characterOffset + this->GetScanner()->m_cMultiUnits;
    parseContext->grfscr = this->m_grfscr;
    parseContext->lineNumber = this->GetScanner()->LineCur();

    parseContext->pnodeProg = this->m_currentNodeProg;
    parseContext->isUtf8 = this->GetScanner()->IsUtf8();
    parseContext->strictMode = this->IsStrictMode();
    parseContext->sourceContextInfo = this->m_sourceContextInfo;
    parseContext->currentBlockInfo = this->m_currentBlockInfo;
    parseContext->nextBlockId = this->m_nextBlockId;
}

void Parser::RestoreContext(ParseContext *const parseContext)
{
    m_sourceContextInfo = parseContext->sourceContextInfo;
    m_currentBlockInfo = parseContext->currentBlockInfo;
    m_nextBlockId = parseContext->nextBlockId;
    m_grfscr = parseContext->grfscr;
    m_length = parseContext->length;
    this->GetScanner()->SetText(parseContext->pszSrc, parseContext->offset, parseContext->length, parseContext->characterOffset, parseContext->isUtf8, parseContext->grfscr, parseContext->lineNumber);
    m_currentNodeProg = parseContext->pnodeProg;
    m_fUseStrictMode = parseContext->strictMode;
}

class ByteCodeGenerator;
#if DBG_DUMP

#define INDENT_SIZE 2

void PrintPnodeListWIndent(ParseNode *pnode, int indentAmt);
void PrintFormalsWIndent(ParseNode *pnode, int indentAmt);


void Indent(int indentAmt) {
    for (int i = 0; i < indentAmt; i++) {
        Output::Print(_u(" "));
    }
}

void PrintBlockType(PnodeBlockType type)
{
    switch (type)
    {
    case Global:
        Output::Print(_u("(Global)"));
        break;
    case Function:
        Output::Print(_u("(Function)"));
        break;
    case Regular:
        Output::Print(_u("(Regular)"));
        break;
    case Parameter:
        Output::Print(_u("(Parameter)"));
        break;
    default:
        Output::Print(_u("(unknown blocktype)"));
        break;
    }
}

void PrintScopesWIndent(ParseNode *pnode, int indentAmt) {
    ParseNode *scope = nullptr;
    bool firstOnly = false;
    switch (pnode->nop)
    {
    case knopProg:
    case knopFncDecl: scope = pnode->AsParseNodeFnc()->pnodeScopes; break;
    case knopBlock: scope = pnode->AsParseNodeBlock()->pnodeScopes; break;
    case knopCatch: scope = pnode->AsParseNodeCatch()->pnodeScopes; break;
    case knopWith: scope = pnode->AsParseNodeWith()->pnodeScopes; break;
    case knopSwitch: scope = pnode->AsParseNodeSwitch()->pnodeBlock; firstOnly = true; break;
    case knopFor: scope = pnode->AsParseNodeFor()->pnodeBlock; firstOnly = true; break;
    case knopForIn: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
    case knopForOf: scope = pnode->AsParseNodeForInOrForOf()->pnodeBlock; firstOnly = true; break;
    }
    if (scope) {
        Output::Print(_u("[%4d, %4d): "), scope->ichMin, scope->ichLim);
        Indent(indentAmt);
        Output::Print(_u("Scopes: "));
        ParseNode *next = nullptr;
        ParseNode *syntheticBlock = nullptr;
        while (scope) {
            switch (scope->nop) {
            case knopFncDecl: Output::Print(_u("knopFncDecl")); next = scope->AsParseNodeFnc()->pnodeNext; break;
            case knopBlock: Output::Print(_u("knopBlock")); PrintBlockType(scope->AsParseNodeBlock()->blockType); next = scope->AsParseNodeBlock()->pnodeNext; break;
            case knopCatch: Output::Print(_u("knopCatch")); next = scope->AsParseNodeCatch()->pnodeNext; break;
            case knopWith: Output::Print(_u("knopWith")); next = scope->AsParseNodeWith()->pnodeNext; break;
            default: Output::Print(_u("unknown")); break;
            }
            if (firstOnly) {
                next = nullptr;
                syntheticBlock = scope;
            }
            if (scope->grfpn & fpnSyntheticNode) {
                Output::Print(_u(" synthetic"));
                if (scope->nop == knopBlock)
                    syntheticBlock = scope;
            }
            Output::Print(_u(" (%d-%d)"), scope->ichMin, scope->ichLim);
            if (next) Output::Print(_u(", "));
            scope = next;
        }
        Output::Print(_u("\n"));
        if (syntheticBlock || firstOnly) {
            PrintScopesWIndent(syntheticBlock, indentAmt + INDENT_SIZE);
        }
    }
}

void PrintPnodeWIndent(ParseNode *pnode, int indentAmt) {
    if (pnode == NULL)
        return;

    Output::Print(_u("[%4d, %4d): "), pnode->ichMin, pnode->ichLim);
    switch (pnode->nop) {
        //PTNODE(knopName       , "name"        ,None    ,Pid  ,fnopLeaf)
    case knopName:
        Indent(indentAmt);
        if (pnode->AsParseNodeName()->pid != NULL) {
            Output::Print(_u("id: %s\n"), pnode->AsParseNodeName()->pid->Psz());
        }
        else {
            Output::Print(_u("name node\n"));
        }
        break;
        //PTNODE(knopInt        , "int const"    ,None    ,Int  ,fnopLeaf|fnopConst)
    case knopInt:
        Indent(indentAmt);
        Output::Print(_u("%d\n"), pnode->AsParseNodeInt()->lw);
        break;
        //PTNODE(knopInt        , "int const"    ,None    ,Int  ,fnopLeaf|fnopConst)
    case knopBigInt:
        Indent(indentAmt);
        Output::Print(_u("%s%s\n"), pnode->AsParseNodeBigInt()->isNegative? "-" : "", pnode->AsParseNodeBigInt()->pid->Psz());
        break;
        //PTNODE(knopFlt        , "flt const"    ,None    ,Flt  ,fnopLeaf|fnopConst)
    case knopFlt:
        Indent(indentAmt);
        Output::Print(_u("%lf\n"), pnode->AsParseNodeFloat()->dbl);
        break;
        //PTNODE(knopStr        , "str const"    ,None    ,Pid  ,fnopLeaf|fnopConst)
    case knopStr:
        Indent(indentAmt);
        Output::Print(_u("\"%s\"\n"), pnode->AsParseNodeStr()->pid->Psz());
        break;
        //PTNODE(knopRegExp     , "reg expr"    ,None    ,Pid  ,fnopLeaf|fnopConst)
    case knopRegExp:
        Indent(indentAmt);
        Output::Print(_u("/%x/\n"), pnode->AsParseNodeRegExp()->regexPattern);
        break;
        //PTNODE(knopNull       , "null"        ,Null    ,None ,fnopLeaf)
    case knopNull:
        Indent(indentAmt);
        Output::Print(_u("null\n"));
        break;
        //PTNODE(knopFalse      , "false"        ,False   ,None ,fnopLeaf)
    case knopFalse:
        Indent(indentAmt);
        Output::Print(_u("false\n"));
        break;
        //PTNODE(knopTrue       , "true"        ,True    ,None ,fnopLeaf)
    case knopTrue:
        Indent(indentAmt);
        Output::Print(_u("true\n"));
        break;
        //PTNODE(knopEmpty      , "empty"        ,Empty   ,None ,fnopLeaf)
    case knopEmpty:
        Indent(indentAmt);
        Output::Print(_u("empty\n"));
        break;
        // Unary operators.
        //PTNODE(knopNot        , "~"            ,BitNot  ,Uni  ,fnopUni)
    case knopNot:
        Indent(indentAmt);
        Output::Print(_u("~\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopNeg        , "unary -"    ,Neg     ,Uni  ,fnopUni)
    case knopNeg:
        Indent(indentAmt);
        Output::Print(_u("U-\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopPos        , "unary +"    ,Pos     ,Uni  ,fnopUni)
    case knopPos:
        Indent(indentAmt);
        Output::Print(_u("U+\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopLogNot     , "!"            ,LogNot  ,Uni  ,fnopUni)
    case knopLogNot:
        Indent(indentAmt);
        Output::Print(_u("!\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopEllipsis     , "..."       ,Spread  ,Uni    , fnopUni)
    case knopEllipsis:
        Indent(indentAmt);
        Output::Print(_u("...<expr>\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopIncPost    , "++ post"    ,Inc     ,Uni  ,fnopUni|fnopAsg)
    case knopIncPost:
        Indent(indentAmt);
        Output::Print(_u("<expr>++\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopDecPost    , "-- post"    ,Dec     ,Uni  ,fnopUni|fnopAsg)
    case knopDecPost:
        Indent(indentAmt);
        Output::Print(_u("<expr>--\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopIncPre     , "++ pre"    ,Inc     ,Uni  ,fnopUni|fnopAsg)
    case knopIncPre:
        Indent(indentAmt);
        Output::Print(_u("++<expr>\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopDecPre     , "-- pre"    ,Dec     ,Uni  ,fnopUni|fnopAsg)
    case knopDecPre:
        Indent(indentAmt);
        Output::Print(_u("--<expr>\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopTypeof     , "typeof"    ,None    ,Uni  ,fnopUni)
    case knopTypeof:
        Indent(indentAmt);
        Output::Print(_u("typeof\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopVoid       , "void"        ,Void    ,Uni  ,fnopUni)
    case knopVoid:
        Indent(indentAmt);
        Output::Print(_u("void\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopDelete     , "delete"    ,None    ,Uni  ,fnopUni)
    case knopDelete:
        Indent(indentAmt);
        Output::Print(_u("delete\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopArray      , "arr cnst"    ,None    ,Uni  ,fnopUni)

    case knopArrayPattern:
        Indent(indentAmt);
        Output::Print(_u("Array Pattern\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;

    case knopObjectPattern:
        Indent(indentAmt);
        Output::Print(_u("Object Pattern\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;

    case knopArray:
        Indent(indentAmt);
        Output::Print(_u("Array Literal\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopObject     , "obj cnst"    ,None    ,Uni  ,fnopUni)
    case knopObject:
        Indent(indentAmt);
        Output::Print(_u("Object Literal\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        // Binary and Ternary Operators
        //PTNODE(knopAdd        , "+"            ,Add     ,Bin  ,fnopBin)
    case knopAdd:
        Indent(indentAmt);
        Output::Print(_u("+\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopSub        , "-"            ,Sub     ,Bin  ,fnopBin)
    case knopSub:
        Indent(indentAmt);
        Output::Print(_u("-\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopMul        , "*"            ,Mul     ,Bin  ,fnopBin)
    case knopMul:
        Indent(indentAmt);
        Output::Print(_u("*\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopDiv        , "/"            ,Div     ,Bin  ,fnopBin)
    case knopExpo:
        Indent(indentAmt);
        Output::Print(_u("**\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopExpo        , "**"            ,Expo     ,Bin  ,fnopBin)

    case knopDiv:
        Indent(indentAmt);
        Output::Print(_u("/\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopMod        , "%"            ,Mod     ,Bin  ,fnopBin)
    case knopMod:
        Indent(indentAmt);
        Output::Print(_u("%%\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopOr         , "|"            ,BitOr   ,Bin  ,fnopBin)
    case knopOr:
        Indent(indentAmt);
        Output::Print(_u("|\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopXor        , "^"            ,BitXor  ,Bin  ,fnopBin)
    case knopXor:
        Indent(indentAmt);
        Output::Print(_u("^\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAnd        , "&"            ,BitAnd  ,Bin  ,fnopBin)
    case knopAnd:
        Indent(indentAmt);
        Output::Print(_u("&\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopEq         , "=="        ,EQ      ,Bin  ,fnopBin|fnopRel)
    case knopEq:
        Indent(indentAmt);
        Output::Print(_u("==\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopNe         , "!="        ,NE      ,Bin  ,fnopBin|fnopRel)
    case knopNe:
        Indent(indentAmt);
        Output::Print(_u("!=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopLt         , "<"            ,LT      ,Bin  ,fnopBin|fnopRel)
    case knopLt:
        Indent(indentAmt);
        Output::Print(_u("<\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopLe         , "<="        ,LE      ,Bin  ,fnopBin|fnopRel)
    case knopLe:
        Indent(indentAmt);
        Output::Print(_u("<=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopGe         , ">="        ,GE      ,Bin  ,fnopBin|fnopRel)
    case knopGe:
        Indent(indentAmt);
        Output::Print(_u(">=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopGt         , ">"            ,GT      ,Bin  ,fnopBin|fnopRel)
    case knopGt:
        Indent(indentAmt);
        Output::Print(_u(">\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopCall       , "()"        ,None    ,Bin  ,fnopBin)
    case knopCall:
        Indent(indentAmt);
        Output::Print(_u("Call\n"));
        PrintPnodeWIndent(pnode->AsParseNodeCall()->pnodeTarget, indentAmt + INDENT_SIZE);
        PrintPnodeListWIndent(pnode->AsParseNodeCall()->pnodeArgs, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopDot        , "."            ,None    ,Bin  ,fnopBin)
    case knopDot:
        Indent(indentAmt);
        Output::Print(_u(".\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsg        , "="            ,None    ,Bin  ,fnopBin|fnopAsg)
    case knopAsg:
        Indent(indentAmt);
        Output::Print(_u("=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopInstOf     , "instanceof",InstOf  ,Bin  ,fnopBin|fnopRel)
    case knopInstOf:
        Indent(indentAmt);
        Output::Print(_u("instanceof\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopIn         , "in"        ,In      ,Bin  ,fnopBin|fnopRel)
    case knopIn:
        Indent(indentAmt);
        Output::Print(_u("in\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopEqv        , "==="        ,Eqv     ,Bin  ,fnopBin|fnopRel)
    case knopEqv:
        Indent(indentAmt);
        Output::Print(_u("===\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopNEqv       , "!=="        ,NEqv    ,Bin  ,fnopBin|fnopRel)
    case knopNEqv:
        Indent(indentAmt);
        Output::Print(_u("!==\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopComma      , ","            ,None    ,Bin  ,fnopBin)
    case knopComma:
        Indent(indentAmt);
        Output::Print(_u(",\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopLogOr      , "||"        ,None    ,Bin  ,fnopBin)
    case knopLogOr:
        Indent(indentAmt);
        Output::Print(_u("||\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopLogAnd     , "&&"        ,None    ,Bin  ,fnopBin)
    case knopLogAnd:
        Indent(indentAmt);
        Output::Print(_u("&&\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopLsh        , "<<"        ,Lsh     ,Bin  ,fnopBin)
    case knopLsh:
        Indent(indentAmt);
        Output::Print(_u("<<\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopRsh        , ">>"        ,Rsh     ,Bin  ,fnopBin)
    case knopRsh:
        Indent(indentAmt);
        Output::Print(_u(">>\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopRs2        , ">>>"        ,Rs2     ,Bin  ,fnopBin)
    case knopRs2:
        Indent(indentAmt);
        Output::Print(_u(">>>\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopNew        , "new"        ,None    ,Bin  ,fnopBin)
    case knopNew:
        Indent(indentAmt);
        Output::Print(_u("new\n"));
        PrintPnodeWIndent(pnode->AsParseNodeCall()->pnodeTarget, indentAmt + INDENT_SIZE);
        PrintPnodeListWIndent(pnode->AsParseNodeCall()->pnodeArgs, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopIndex      , "[]"        ,None    ,Bin  ,fnopBin)
    case knopIndex:
        Indent(indentAmt);
        Output::Print(_u("[]\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeListWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopQmark      , "?"            ,None    ,Tri  ,fnopBin)
    case knopQmark:
        Indent(indentAmt);
        Output::Print(_u("?:\n"));
        PrintPnodeWIndent(pnode->AsParseNodeTri()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeTri()->pnode2, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeTri()->pnode3, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgAdd     , "+="        ,Add     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgAdd:
        Indent(indentAmt);
        Output::Print(_u("+=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgSub     , "-="        ,Sub     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgSub:
        Indent(indentAmt);
        Output::Print(_u("-=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgMul     , "*="        ,Mul     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgMul:
        Indent(indentAmt);
        Output::Print(_u("*=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgDiv     , "/="        ,Div     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgExpo:
        Indent(indentAmt);
        Output::Print(_u("**=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgExpo     , "**="       ,Expo     ,Bin  ,fnopBin|fnopAsg)

    case knopAsgDiv:
        Indent(indentAmt);
        Output::Print(_u("/=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgMod     , "%="        ,Mod     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgMod:
        Indent(indentAmt);
        Output::Print(_u("%=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgAnd     , "&="        ,BitAnd  ,Bin  ,fnopBin|fnopAsg)
    case knopAsgAnd:
        Indent(indentAmt);
        Output::Print(_u("&=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgXor     , "^="        ,BitXor  ,Bin  ,fnopBin|fnopAsg)
    case knopAsgXor:
        Indent(indentAmt);
        Output::Print(_u("^=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgOr      , "|="        ,BitOr   ,Bin  ,fnopBin|fnopAsg)
    case knopAsgOr:
        Indent(indentAmt);
        Output::Print(_u("|=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgLsh     , "<<="        ,Lsh     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgLsh:
        Indent(indentAmt);
        Output::Print(_u("<<=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgRsh     , ">>="        ,Rsh     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgRsh:
        Indent(indentAmt);
        Output::Print(_u(">>=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopAsgRs2     , ">>>="        ,Rs2     ,Bin  ,fnopBin|fnopAsg)
    case knopAsgRs2:
        Indent(indentAmt);
        Output::Print(_u(">>>=\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;

    case knopComputedName:
        Indent(indentAmt);
        Output::Print(_u("ComputedProperty\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
    case knopParamPattern:
        PrintPnodeWIndent(pnode->AsParseNodeParamPattern()->pnode1, indentAmt);
        break;
        //PTNODE(knopMember     , ":"            ,None    ,Bin  ,fnopBin)
    case knopMember:
    case knopMemberShort:
    case knopObjectPatternMember:
        Indent(indentAmt);
        Output::Print(_u(":\n"));
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode2, indentAmt + INDENT_SIZE);
        break;
        // General nodes.
        //PTNODE(knopList       , "<list>"    ,None    ,Bin  ,fnopNone)
    case knopList:
        Indent(indentAmt);
        Output::Print(_u("List\n"));
        PrintPnodeListWIndent(pnode, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopVarDecl    , "varDcl"    ,None    ,Var  ,fnopNone)
    case knopVarDecl:
        Indent(indentAmt);
        Output::Print(_u("var %s\n"), pnode->AsParseNodeVar()->pid->Psz());
        if (pnode->AsParseNodeVar()->pnodeInit != NULL)
            PrintPnodeWIndent(pnode->AsParseNodeVar()->pnodeInit, indentAmt + INDENT_SIZE);
        break;
    case knopConstDecl:
        Indent(indentAmt);
        Output::Print(_u("const %s\n"), pnode->AsParseNodeVar()->pid->Psz());
        if (pnode->AsParseNodeVar()->pnodeInit != NULL)
            PrintPnodeWIndent(pnode->AsParseNodeVar()->pnodeInit, indentAmt + INDENT_SIZE);
        break;
    case knopLetDecl:
        Indent(indentAmt);
        Output::Print(_u("let %s\n"), pnode->AsParseNodeVar()->pid->Psz());
        if (pnode->AsParseNodeVar()->pnodeInit != NULL)
            PrintPnodeWIndent(pnode->AsParseNodeVar()->pnodeInit, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopFncDecl    , "fncDcl"    ,None    ,Fnc  ,fnopLeaf)
    case knopFncDecl:
        Indent(indentAmt);
        if (pnode->AsParseNodeFnc()->pid != NULL)
        {
            Output::Print(_u("fn decl %d nested %d name %s (%d-%d)\n"), pnode->AsParseNodeFnc()->IsDeclaration(), pnode->AsParseNodeFnc()->IsNested(),
                pnode->AsParseNodeFnc()->pid->Psz(), pnode->ichMin, pnode->ichLim);
        }
        else
        {
            Output::Print(_u("fn decl %d nested %d anonymous (%d-%d)\n"), pnode->AsParseNodeFnc()->IsDeclaration(), pnode->AsParseNodeFnc()->IsNested(), pnode->ichMin, pnode->ichLim);
        }
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintFormalsWIndent(pnode->AsParseNodeFnc()->pnodeParams, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeFnc()->pnodeRest, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeFnc()->pnodeBody, indentAmt + INDENT_SIZE);
        if (pnode->AsParseNodeFnc()->pnodeBody == nullptr)
        {
            Output::Print(_u("[%4d, %4d): "), pnode->ichMin, pnode->ichLim);
            Indent(indentAmt + INDENT_SIZE);
            Output::Print(_u("<parse deferred body>\n"));
        }
        break;
        //PTNODE(knopProg       , "program"    ,None    ,Fnc  ,fnopNone)
    case knopProg:
        Indent(indentAmt);
        Output::Print(_u("program\n"));
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintPnodeListWIndent(pnode->AsParseNodeFnc()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopEndCode    , "<endcode>"    ,None    ,None ,fnopNone)
    case knopEndCode:
        Indent(indentAmt);
        Output::Print(_u("<endcode>\n"));
        break;
        //PTNODE(knopDebugger   , "debugger"    ,None    ,None ,fnopNone)
    case knopDebugger:
        Indent(indentAmt);
        Output::Print(_u("<debugger>\n"));
        break;
        //PTNODE(knopFor        , "for"        ,None    ,For  ,fnopBreak|fnopContinue)
    case knopFor:
        Indent(indentAmt);
        Output::Print(_u("for\n"));
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeInit, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeCond, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeIncr, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeFor()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopIf         , "if"        ,None    ,If   ,fnopNone)
    case knopIf:
        Indent(indentAmt);
        Output::Print(_u("if\n"));
        PrintPnodeWIndent(pnode->AsParseNodeIf()->pnodeCond, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeIf()->pnodeTrue, indentAmt + INDENT_SIZE);
        if (pnode->AsParseNodeIf()->pnodeFalse != NULL)
            PrintPnodeWIndent(pnode->AsParseNodeIf()->pnodeFalse, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopWhile      , "while"        ,None    ,While,fnopBreak|fnopContinue)
    case knopWhile:
        Indent(indentAmt);
        Output::Print(_u("while\n"));
        PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeCond, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopDoWhile    , "do-while"    ,None    ,While,fnopBreak|fnopContinue)
    case knopDoWhile:
        Indent(indentAmt);
        Output::Print(_u("do\n"));
        PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeCond, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeWhile()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopForIn      , "for in"    ,None    ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
    case knopForIn:
        Indent(indentAmt);
        Output::Print(_u("forIn\n"));
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeLval, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeObj, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
    case knopForOf:
        Indent(indentAmt);
        Output::Print(_u("forOf\n"));
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeLval, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeObj, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeForInOrForOf()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopReturn     , "return"    ,None    ,Uni  ,fnopNone)
    case knopReturn:
        Indent(indentAmt);
        Output::Print(_u("return\n"));
        if (pnode->AsParseNodeReturn()->pnodeExpr != NULL)
            PrintPnodeWIndent(pnode->AsParseNodeReturn()->pnodeExpr, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopBlock      , "{}"        ,None    ,Block,fnopNone)
    case knopBlock:
        Indent(indentAmt);
        Output::Print(_u("block "));
        if (pnode->grfpn & fpnSyntheticNode)
            Output::Print(_u("synthetic "));
        PrintBlockType(pnode->AsParseNodeBlock()->blockType);
        Output::Print(_u("(%d-%d)\n"), pnode->ichMin, pnode->ichLim);
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        if (pnode->AsParseNodeBlock()->pnodeStmt != NULL)
            PrintPnodeWIndent(pnode->AsParseNodeBlock()->pnodeStmt, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopWith       , "with"        ,None    ,With ,fnopCleanup)
    case knopWith:
        Indent(indentAmt);
        Output::Print(_u("with (%d-%d)\n"), pnode->ichMin, pnode->ichLim);
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeWith()->pnodeObj, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeWith()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopBreak      , "break"        ,None    ,Jump ,fnopNone)
    case knopBreak:
        Indent(indentAmt);
        Output::Print(_u("break\n"));
        // TODO: some representation of target
        break;
        //PTNODE(knopContinue   , "continue"    ,None    ,Jump ,fnopNone)
    case knopContinue:
        Indent(indentAmt);
        Output::Print(_u("continue\n"));
        // TODO: some representation of target
        break;
        //PTNODE(knopSwitch     , "switch"    ,None    ,Switch,fnopBreak)
    case knopSwitch:
        Indent(indentAmt);
        Output::Print(_u("switch\n"));
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        for (ParseNodeCase *pnodeT = pnode->AsParseNodeSwitch()->pnodeCases; NULL != pnodeT; pnodeT = pnodeT->pnodeNext) {
            PrintPnodeWIndent(pnodeT, indentAmt + 2);
        }
        break;
        //PTNODE(knopCase       , "case"        ,None    ,Case ,fnopNone)
    case knopCase:
        Indent(indentAmt);
        Output::Print(_u("case\n"));
        PrintPnodeWIndent(pnode->AsParseNodeCase()->pnodeExpr, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeCase()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
    case knopTryFinally:
        PrintPnodeWIndent(pnode->AsParseNodeTryFinally()->pnodeTry, indentAmt);
        PrintPnodeWIndent(pnode->AsParseNodeTryFinally()->pnodeFinally, indentAmt);
        break;
    case knopFinally:
        Indent(indentAmt);
        Output::Print(_u("finally\n"));
        PrintPnodeWIndent(pnode->AsParseNodeFinally()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopCatch      , "catch"     ,None    ,Catch,fnopNone)
    case knopCatch:
        Indent(indentAmt);
        Output::Print(_u("catch (%d-%d)\n"), pnode->ichMin, pnode->ichLim);
        PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeCatch()->GetParam(), indentAmt + INDENT_SIZE);
        //      if (pnode->AsParseNodeCatch()->pnodeGuard!=NULL)
        //          PrintPnodeWIndent(pnode->AsParseNodeCatch()->pnodeGuard,indentAmt+INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeCatch()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopTryCatch      , "try-catch" ,None    ,TryCatch  ,fnopCleanup)
    case knopTryCatch:
        PrintPnodeWIndent(pnode->AsParseNodeTryCatch()->pnodeTry, indentAmt);
        PrintPnodeWIndent(pnode->AsParseNodeTryCatch()->pnodeCatch, indentAmt);
        break;
        //PTNODE(knopTry        , "try"       ,None    ,Try  ,fnopCleanup)
    case knopTry:
        Indent(indentAmt);
        Output::Print(_u("try\n"));
        PrintPnodeWIndent(pnode->AsParseNodeTry()->pnodeBody, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopThrow      , "throw"     ,None    ,Uni  ,fnopNone)
    case knopThrow:
        Indent(indentAmt);
        Output::Print(_u("throw\n"));
        PrintPnodeWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
        //PTNODE(knopClassDecl, "classDecl", None , Class, fnopLeaf)
    case knopClassDecl:
        Indent(indentAmt);
        Output::Print(_u("class %s"), pnode->AsParseNodeClass()->pnodeName->pid->Psz());
        if (pnode->AsParseNodeClass()->pnodeExtends != nullptr)
        {
            Output::Print(_u(" extends "));
            PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeExtends, 0);
        }
        else {
            Output::Print(_u("\n"));
        }

        PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeConstructor, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeMembers, indentAmt + INDENT_SIZE);
        PrintPnodeWIndent(pnode->AsParseNodeClass()->pnodeStaticMembers, indentAmt + INDENT_SIZE);
        break;
    case knopStrTemplate:
        Indent(indentAmt);
        Output::Print(_u("string template\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeStrTemplate()->pnodeSubstitutionExpressions, indentAmt + INDENT_SIZE);
        break;
    case knopYieldStar:
        Indent(indentAmt);
        Output::Print(_u("yield*\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
    case knopYield:
    case knopYieldLeaf:
        Indent(indentAmt);
        Output::Print(_u("yield\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
    case knopAwait:
        Indent(indentAmt);
        Output::Print(_u("await\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeUni()->pnode1, indentAmt + INDENT_SIZE);
        break;
    case knopExportDefault:
        Indent(indentAmt);
        Output::Print(_u("export default\n"));
        PrintPnodeListWIndent(pnode->AsParseNodeExportDefault()->pnodeExpr, indentAmt + INDENT_SIZE);
        break;
    default:
        Output::Print(_u("unhandled pnode op %d\n"), pnode->nop);
        break;
    }
}

void PrintPnodeListWIndent(ParseNode *pnode, int indentAmt) {
    if (pnode != NULL) {
        while (pnode->nop == knopList) {
            PrintPnodeWIndent(pnode->AsParseNodeBin()->pnode1, indentAmt);
            pnode = pnode->AsParseNodeBin()->pnode2;
        }
        PrintPnodeWIndent(pnode, indentAmt);
    }
}

void PrintFormalsWIndent(ParseNode *pnodeArgs, int indentAmt)
{
    for (ParseNode *pnode = pnodeArgs; pnode != nullptr; pnode = pnode->GetFormalNext())
    {
        PrintPnodeWIndent(pnode, indentAmt);
    }
}

void PrintPnode(ParseNode *pnode) {
    PrintPnodeWIndent(pnode, 0);
}

void ParseNode::Dump()
{
    switch (nop)
    {
    case knopFncDecl:
    case knopProg:
        LPCOLESTR name = Js::Constants::AnonymousFunction;
        if (this->AsParseNodeFnc()->pnodeName)
        {
            Assert(this->AsParseNodeFnc()->pnodeName->nop == knopVarDecl);
            name = this->AsParseNodeFnc()->pnodeName->pid->Psz();
        }

        Output::Print(_u("%s (%d) [%d, %d]:\n"), name, this->AsParseNodeFnc()->functionId, this->AsParseNodeFnc()->lineNumber, this->AsParseNodeFnc()->columnNumber);
        Output::Print(_u("hasArguments: %s callsEval:%s childCallsEval:%s HasReferenceableBuiltInArguments:%s ArgumentsObjectEscapes:%s HasWith:%s HasOnlyThis:%s \n"),
            IsTrueOrFalse(this->AsParseNodeFnc()->HasHeapArguments()),
            IsTrueOrFalse(this->AsParseNodeFnc()->CallsEval()),
            IsTrueOrFalse(this->AsParseNodeFnc()->ChildCallsEval()),
            IsTrueOrFalse(this->AsParseNodeFnc()->HasReferenceableBuiltInArguments()),
            IsTrueOrFalse(this->AsParseNodeFnc()->GetArgumentsObjectEscapes()),
            IsTrueOrFalse(this->AsParseNodeFnc()->HasWithStmt()),
            IsTrueOrFalse(this->AsParseNodeFnc()->HasOnlyThisStmts()));
        if (this->AsParseNodeFnc()->funcInfo)
        {
            this->AsParseNodeFnc()->funcInfo->Dump();
        }
        break;
    }
}

void DumpCapturedNames(ParseNodeFnc* pnodeFnc, IdentPtrSet* capturedNames, ArenaAllocator* alloc)
{
    auto sortedNames = JsUtil::List<IdentPtr, ArenaAllocator>::New(alloc);

    capturedNames->Map([=](const IdentPtr& pid) -> void {
        sortedNames->Add(pid);
    });

    sortedNames->Sort([](void* context, const void* left, const void* right) -> int {
        const IdentPtr leftIdentPtr = *(const IdentPtr*)(left);
        const IdentPtr rightIdentPtr = *(const IdentPtr*)(right);
        return ::wcscmp(leftIdentPtr->Psz(), rightIdentPtr->Psz());
    }, nullptr);

    sortedNames->Map([=](int index, const IdentPtr pid) -> void {
        OUTPUT_TRACE_DEBUGONLY(Js::CreateParserStatePhase, _u(" Function %u captured name \"%s\"\n"), pnodeFnc->functionId, pid->Psz());
    });
}
#endif

void Parser::AddNestedCapturedNames(ParseNodeFnc* pnodeChildFnc)
{
    if (m_currentNodeFunc && this->IsCreatingStateCache() && pnodeChildFnc->HasAnyCapturedNames())
    {
        IdentPtrSet* parentCapturedNames = GetCurrentFunctionNode()->EnsureCapturedNames(&m_nodeAllocator);
        IdentPtrSet* childCaptureNames = pnodeChildFnc->GetCapturedNames();

        auto iter = childCaptureNames->GetIterator();

        while (iter.IsValid())
        {
            parentCapturedNames->AddNew(iter.CurrentValue());
            iter.MoveNext();
        }
    }
}

void Parser::ProcessCapturedNames(ParseNodeFnc* pnodeFnc)
{
    if (this->IsCreatingStateCache() && pnodeFnc->HasAnyCapturedNames())
    {
        IdentPtrSet* capturedNames = pnodeFnc->GetCapturedNames();
        auto iter = capturedNames->GetIteratorWithRemovalSupport();

        while (iter.IsValid())
        {
            const IdentPtr& pid = iter.CurrentValueReference();
            PidRefStack* ref = pid->GetTopRef();

            // If the pid has no refs left in our function's scope after binding, we didn't capture it.
            if (!ref || ref->GetFuncScopeId() < pnodeFnc->functionId)
            {
                iter.RemoveCurrent();
            }

            iter.MoveNext();
        }

#if DBG_DUMP
        if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::CreateParserStatePhase))
        {
            DumpCapturedNames(pnodeFnc, capturedNames, &this->m_nodeAllocator);
            fflush(stdout);
        }
#endif
    }
}

void Parser::ReleaseTemporaryGuestArena()
{
    // In case of modules the Parser lives longer than the temporary Guest Arena. We may have already released the arena explicitly.
    if (!m_tempGuestArenaReleased)
    {
        // The regex patterns list has references to the temporary Guest Arena. Reset it first.
        m_registeredRegexPatterns.Reset();

        if (this->m_scriptContext != nullptr)
        {
            this->m_scriptContext->ReleaseTemporaryGuestAllocator(m_tempGuestArena);
            m_tempGuestArena.Unroot();
        }

        m_tempGuestArenaReleased = true;
    }
}

bool Parser::IsCreatingStateCache()
{
    return (((this->m_grfscr & fscrCreateParserState) == fscrCreateParserState)
        && this->m_functionBody == nullptr
        && CONFIG_FLAG(ParserStateCache));
}

void Parser::ShiftCurrDeferredStubToChildFunction(ParseNodeFnc* pnodeFnc, ParseNodeFnc* pnodeFncParent)
{
    // Goal here is to shift the current deferred stub to point to the stubs for pnodeFnc
    // so we may continue parsing pnodeFnc using the correct set of stubs instead of the
    // stubs for pnodeFncParent.
    // This function assumes we are in the middle of parsing pnodeFnc which is a child
    // nested in pnodeFncParent.
    if (pnodeFnc->IsNested() && pnodeFncParent != nullptr && m_currDeferredStub != nullptr && pnodeFncParent->ichMin != pnodeFnc->ichMin)
    {
        AssertOrFailFast(pnodeFncParent->nestedCount > 0);

        DeferredFunctionStub* childStub = m_currDeferredStub + (pnodeFncParent->nestedCount - 1);
        m_currDeferredStubCount = childStub->nestedCount;
        m_currDeferredStub = childStub->deferredStubs;
    }
}

uint Parser::BuildDeferredStubTreeHelper(ParseNodeBlock* pnodeBlock, DeferredFunctionStub* deferredStubs, uint currentStubIndex, uint deferredStubCount, Recycler *recycler)
{
    Assert(pnodeBlock != nullptr
        && (pnodeBlock->blockType == PnodeBlockType::Function
            || pnodeBlock->blockType == PnodeBlockType::Parameter));

    ParseNodePtr pnodeChild = pnodeBlock->pnodeScopes;

    while (pnodeChild != nullptr)
    {
        if (pnodeChild->nop != knopFncDecl)
        {
            // We only expect to find a function body block in a parameter scope block.
            Assert(pnodeChild->nop == knopBlock
                && (pnodeBlock->blockType == PnodeBlockType::Parameter
                    || pnodeChild->AsParseNodeBlock()->blockType == PnodeBlockType::Function));
            pnodeChild = pnodeChild->AsParseNodeBlock()->pnodeNext;
            continue;
        }

        ParseNodeFnc* pnodeFncChild = pnodeChild->AsParseNodeFnc();
        AnalysisAssertOrFailFast(currentStubIndex < deferredStubCount);
        Assert(pnodeFncChild->pnodeBody == nullptr);

        if (pnodeFncChild->IsGeneratedDefault())
        {
            ++currentStubIndex;
            pnodeChild = pnodeFncChild->pnodeNext;
            continue;
        }

        deferredStubs[currentStubIndex].fncFlags = pnodeFncChild->fncFlags;
        deferredStubs[currentStubIndex].nestedCount = pnodeFncChild->nestedCount;
        deferredStubs[currentStubIndex].restorePoint = *pnodeFncChild->pRestorePoint;
        deferredStubs[currentStubIndex].deferredStubs = BuildDeferredStubTree(pnodeFncChild, recycler);
        deferredStubs[currentStubIndex].ichMin = pnodeChild->ichMin;

        // Save the set of captured names onto the deferred stub.
        // Since this set is allocated in the Parser arena, we'll have to convert these
        // into indices in a string table which will survive when the parser goes away.
        deferredStubs[currentStubIndex].capturedNamePointers = pnodeFncChild->GetCapturedNames();

        ++currentStubIndex;
        pnodeChild = pnodeFncChild->pnodeNext;
    }

    return currentStubIndex;
}

DeferredFunctionStub * Parser::BuildDeferredStubTree(ParseNodeFnc *pnodeFnc, Recycler *recycler)
{
    Assert(CONFIG_FLAG(ParserStateCache));

    uint nestedCount = pnodeFnc->nestedCount;
    if (nestedCount == 0)
    {
        return nullptr;
    }

    if (pnodeFnc->deferredStub)
    {
        return pnodeFnc->deferredStub;
    }

    DeferredFunctionStub* deferredStubs = RecyclerNewArray(recycler, DeferredFunctionStub, nestedCount);

    uint currentStubIndex = BuildDeferredStubTreeHelper(pnodeFnc->pnodeScopes, deferredStubs, 0, nestedCount, recycler);
    currentStubIndex = BuildDeferredStubTreeHelper(pnodeFnc->pnodeBodyScope, deferredStubs, currentStubIndex, nestedCount, recycler);

    Assert(currentStubIndex == nestedCount);

    pnodeFnc->deferredStub = deferredStubs;
    return deferredStubs;
}
