Просмотр исходного кода

[MERGE #4969 @curtisman] Parser Refactor: Use different ParseNode kind for knopStr and knopName and enforce child node type for some operations

Merge pull request #4969 from curtisman:ctor

And even more use stronger type instead of casting from ParseNode
Curtis Man 8 лет назад
Родитель
Сommit
e4c1bd449b

+ 8 - 8
lib/Parser/FormalsUtil.h

@@ -4,34 +4,34 @@
 //-------------------------------------------------------------------------------------------------------
 #pragma once
 template <class Fn, bool mapRest>
-void MapFormalsImpl(ParseNode *pnodeFunc, Fn fn)
+void MapFormalsImpl(ParseNodeFnc *pnodeFunc, Fn fn)
 {
-    for (ParseNode *pnode = pnodeFunc->AsParseNodeFnc()->pnodeParams; pnode != nullptr; pnode = pnode->GetFormalNext())
+    for (ParseNode *pnode = pnodeFunc->pnodeParams; pnode != nullptr; pnode = pnode->GetFormalNext())
     {
         fn(pnode);
     }
-    if (mapRest && pnodeFunc->AsParseNodeFnc()->pnodeRest != nullptr)
+    if (mapRest && pnodeFunc->pnodeRest != nullptr)
     {
-        fn(pnodeFunc->AsParseNodeFnc()->pnodeRest);
+        fn(pnodeFunc->pnodeRest);
     }
 }
 
 template <class Fn>
-void MapFormalsWithoutRest(ParseNode *pnodeFunc, Fn fn)
+void MapFormalsWithoutRest(ParseNodeFnc *pnodeFunc, Fn fn)
 {
     return MapFormalsImpl<Fn, false>(pnodeFunc, fn);
 }
 
 template <class Fn>
-void MapFormals(ParseNode *pnodeFunc, Fn fn)
+void MapFormals(ParseNodeFnc *pnodeFunc, Fn fn)
 {
     return MapFormalsImpl<Fn, true>(pnodeFunc, fn);
 }
 
 template <class Fn>
-void MapFormalsFromPattern(ParseNode *pnodeFunc, Fn fn)
+void MapFormalsFromPattern(ParseNodeFnc *pnodeFunc, Fn fn)
 {
-    for (ParseNode *pnode = pnodeFunc->AsParseNodeFnc()->pnodeParams; pnode != nullptr; pnode = pnode->GetFormalNext())
+    for (ParseNode *pnode = pnodeFunc->pnodeParams; pnode != nullptr; pnode = pnode->GetFormalNext())
     {
         if (pnode->nop == knopParamPattern)
         {

+ 1 - 1
lib/Parser/Hash.cpp

@@ -210,7 +210,7 @@ void Ident::TrySetIsUsedInLdElem(ParseNode * pnode)
 {
     if (pnode && pnode->nop == knopStr)
     {
-        pnode->AsParseNodePid()->pid->SetIsUsedInLdElem(true);
+        pnode->AsParseNodeStr()->pid->SetIsUsedInLdElem(true);
     }
 }
 

+ 111 - 149
lib/Parser/Parse.cpp

@@ -331,7 +331,7 @@ HRESULT Parser::ValidateSyntax(LPCUTF8 pszSrc, size_t encodedCharCount, bool isG
 }
 
 HRESULT Parser::ParseSourceInternal(
-    __out ParseNodePtr* parseTree, LPCUTF8 pszSrc, size_t offsetInBytes, size_t encodedCharCount, charcount_t offsetInChars,
+    __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);
@@ -357,7 +357,7 @@ HRESULT Parser::ParseSourceInternal(
     m_grfscr = grfscr;
     m_sourceContextInfo = sourceContextInfo;
 
-    ParseNodePtr pnodeBase = NULL;
+    ParseNodeProg * pnodeBase = NULL;
     HRESULT hr;
     SmartFPUControl smartFpuControl;
 
@@ -917,27 +917,27 @@ ParseNodeInt * Parser::CreateIntNode(int32 lw)
     return pnode;
 }
 
-ParseNodePid * Parser::CreateStrNode(IdentPtr pid)
+ParseNodeStr * Parser::CreateStrNode(IdentPtr pid)
 {
     Assert(!this->m_deferringAST);
-    ParseNodePid * pnode = Anew(&m_nodeAllocator, ParseNodePid, knopStr, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
+    ParseNodeStr * pnode = Anew(&m_nodeAllocator, ParseNodeStr, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
     pnode->grfpn |= PNodeFlags::fpnCanFlattenConcatExpr;
-    AddAstSize(sizeof(ParseNodePid));
+    AddAstSize(sizeof(ParseNodeStr));
     return pnode;
 }
 
-ParseNodePid * Parser::CreateNameNode(IdentPtr pid)
+ParseNodeName * Parser::CreateNameNode(IdentPtr pid)
 {
-    ParseNodePid * pnode = Anew(&m_nodeAllocator, ParseNodePid, knopName, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
-    AddAstSizeAllowDefer(sizeof(ParseNodePid));
+    ParseNodeName * pnode = Anew(&m_nodeAllocator, ParseNodeName, this->GetScanner()->IchMinTok(), this->GetScanner()->IchLimTok(), pid);
+    AddAstSizeAllowDefer(sizeof(ParseNodeName));
     return pnode;
 }
 
-ParseNodePid * Parser::CreateNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim)
+ParseNodeName * Parser::CreateNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim)
 {
-    ParseNodePid * pnode = Anew(&m_nodeAllocator, ParseNodePid, knopName, ichMin, ichLim, pid);
+    ParseNodeName * pnode = Anew(&m_nodeAllocator, ParseNodeName, ichMin, ichLim, pid);
     pnode->SetSymRef(ref);
-    AddAstSize(sizeof(ParseNodePid));
+    AddAstSize(sizeof(ParseNodeName));
     return pnode;
 }
 
@@ -946,7 +946,6 @@ ParseNodeSpecialName * Parser::CreateSpecialNameNode(IdentPtr pid, PidRefStack *
     Assert(!this->m_deferringAST);
     ParseNodeSpecialName * pnode = Anew(&m_nodeAllocator, ParseNodeSpecialName, ichMin, ichLim, pid);
     pnode->SetSymRef(ref);
-
     if (pid == wellKnownPropertyPids._this)
     {
         pnode->isThis = true;
@@ -1283,33 +1282,6 @@ void Parser::RestorePidRefForSym(Symbol *sym)
     ref->SetSym(sym);
 }
 
-IdentPtr Parser::PidFromNode(ParseNodePtr pnode)
-{
-    for (;;)
-    {
-        switch (pnode->nop)
-        {
-        case knopName:
-            return pnode->AsParseNodePid()->pid;
-
-        case knopVarDecl:
-            return pnode->AsParseNodeVar()->pid;
-
-        case knopDot:
-            Assert(pnode->AsParseNodeBin()->pnode2->nop == knopName);
-            return pnode->AsParseNodeBin()->pnode2->AsParseNodePid()->pid;
-
-        case knopComma:
-            // Advance to the RHS and iterate.
-            pnode = pnode->AsParseNodeBin()->pnode2;
-            break;
-
-        default:
-            return nullptr;
-        }
-    }
-}
-
 void Parser::CheckPidIsValid(IdentPtr pid, bool autoArgumentsObject)
 {
     if (IsStrictMode())
@@ -1710,7 +1682,7 @@ void Parser::BindPidRefs(BlockInfoStack *blockInfo, uint maxBlockId)
                 this->BindPidRefsInScope(pid, sym, blockId, maxBlockId);
                 break;
             case knopName:
-                pid = pnode->AsParseNodePid()->pid;
+                pid = pnode->AsParseNodeName()->pid;
                 if (backgroundPidRef)
                 {
                     pid = this->GetHashTbl()->FindExistingPid(pid->Psz(), pid->Psz() + pid->Cch(), pid->Cch(), pid->Hash(), nullptr, nullptr
@@ -2474,12 +2446,12 @@ void Parser::ParseImportClause(ModuleImportOrExportEntryList* importEntryList, b
 
 bool Parser::IsImportOrExportStatementValidHere()
 {
-    ParseNodePtr curFunc = GetCurrentFunctionNode();
+    ParseNodeFnc * curFunc = GetCurrentFunctionNode();
 
     // Import must be located in the top scope of the module body.
     return curFunc->nop == knopFncDecl
-        && curFunc->AsParseNodeFnc()->IsModule()
-        && this->m_currentBlockInfo->pnodeBlock == curFunc->AsParseNodeFnc()->pnodeBodyScope
+        && curFunc->IsModule()
+        && this->m_currentBlockInfo->pnodeBlock == curFunc->pnodeBodyScope
         && (this->m_grfscr & fscrEvalCode) != fscrEvalCode
         && this->m_tryCatchOrFinallyDepth == 0
         && !this->m_disallowImportExportStmt;
@@ -2487,8 +2459,8 @@ bool Parser::IsImportOrExportStatementValidHere()
 
 bool Parser::IsTopLevelModuleFunc()
 {
-    ParseNodePtr curFunc = GetCurrentFunctionNode();
-    return curFunc->nop == knopFncDecl && curFunc->AsParseNodeFnc()->IsModule();
+    ParseNodeFnc * curFunc = GetCurrentFunctionNode();
+    return curFunc->nop == knopFncDecl && curFunc->IsModule();
 }
 
 template<bool buildAST> ParseNodePtr Parser::ParseImportCall()
@@ -2639,14 +2611,15 @@ ParseNodePtr Parser::ParseDefaultExportClause()
         }
 
         this->GetScanner()->SeekTo(parsedClass);
-        pnode = ParseClassDecl<buildAST>(classHasName, nullptr, nullptr, nullptr);
+        ParseNodeClass * pnodeClass;
+        pnode = pnodeClass = ParseClassDecl<buildAST>(classHasName, nullptr, nullptr, nullptr);
 
         if (buildAST)
         {
             AnalysisAssert(pnode != nullptr);
             Assert(pnode->nop == knopClassDecl);
 
-            pnode->AsParseNodeClass()->SetIsDefaultModuleExport(true);
+            pnodeClass->SetIsDefaultModuleExport(true);
         }
 
         break;
@@ -2732,7 +2705,8 @@ ParseNodePtr Parser::ParseDefaultExportClause()
 
             // 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.
-            pnode = CreateNodeForOpT<knopExportDefault>();
+            ParseNodeExportDefault * pnodeExportDefault;
+            pnode = pnodeExportDefault = CreateNodeForOpT<knopExportDefault>();
             pnode->AsParseNodeExportDefault()->pnodeExpr = pnodeExpression;
         }
         break;
@@ -2915,8 +2889,9 @@ ParseNodePtr Parser::ParseExportDeclaration(bool *needTerminator)
             {
                 Assert(pnode->nop == knopFncDecl);
 
-                pnode->AsParseNodeFnc()->GetFuncSymbol()->SetIsModuleExportStorage(true);
-                localName = pnode->AsParseNodeFnc()->pid;
+                ParseNodeFnc * pnodeFnc = pnode->AsParseNodeFnc();
+                pnodeFnc->GetFuncSymbol()->SetIsModuleExportStorage(true);
+                localName = pnodeFnc->pid;
             }
             Assert(localName != nullptr);
 
@@ -3024,7 +2999,7 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
         isSpecialName = false;
 
     LIdentifier:
-        PidRefStack *ref = nullptr;
+        PidRefStack * ref = nullptr;
 
         // Don't push a reference if this is a single lambda parameter, because we'll reparse with
         // a correct function ID.
@@ -3189,9 +3164,10 @@ ParseNodePtr Parser::ParseTerm(BOOL fAllowCall,
 
         if (buildAST)
         {
-            pnode = CreateNodeForOpT<knopFlt>();
-            pnode->AsParseNodeFloat()->dbl = m_token.GetDouble();
-            pnode->AsParseNodeFloat()->maybeInt = m_token.GetDoubleMayBeInt();
+            ParseNodeFloat * pnodeFloat;
+            pnode = pnodeFloat = CreateNodeForOpT<knopFlt>();
+            pnodeFloat->dbl = m_token.GetDouble();
+            pnodeFloat->maybeInt = m_token.GetDoubleMayBeInt();
         }
         fCanAssign = FALSE;
         this->GetScanner()->Scan();
@@ -3504,19 +3480,19 @@ ParseNodeRegExp * Parser::ParseRegExp()
 BOOL Parser::NodeIsEvalName(ParseNodePtr pnode)
 {
     //WOOB 1107758 Special case of indirect eval binds to local scope in standards mode
-    return pnode->nop == knopName && (pnode->AsParseNodePid()->pid == wellKnownPropertyPids.eval);
+    return pnode->nop == knopName && (pnode->AsParseNodeName()->pid == wellKnownPropertyPids.eval);
 }
 
 BOOL Parser::NodeIsSuperName(ParseNodePtr pnode)
 {
-    return pnode->nop == knopName && (pnode->AsParseNodePid()->pid == wellKnownPropertyPids._superConstructor);
+    return pnode->nop == knopName && (pnode->AsParseNodeName()->pid == wellKnownPropertyPids._superConstructor);
 }
 
 BOOL Parser::NodeEqualsName(ParseNodePtr pnode, LPCOLESTR sz, uint32 cch)
 {
     return pnode->nop == knopName &&
-        pnode->AsParseNodePid()->pid->Cch() == cch &&
-        !wmemcmp(pnode->AsParseNodePid()->pid->Psz(), sz, cch);
+        pnode->AsParseNodeName()->pid->Cch() == cch &&
+        !wmemcmp(pnode->AsParseNodeName()->pid->Psz(), sz, cch);
 }
 
 BOOL Parser::NodeIsIdent(ParseNodePtr pnode, IdentPtr pid)
@@ -3526,7 +3502,7 @@ BOOL Parser::NodeIsIdent(ParseNodePtr pnode, IdentPtr pid)
         switch (pnode->nop)
         {
         case knopName:
-            return (pnode->AsParseNodePid()->pid == pid);
+            return (pnode->AsParseNodeName()->pid == pid);
 
         case knopComma:
             pnode = pnode->AsParseNodeBin()->pnode2;
@@ -3702,7 +3678,8 @@ ParseNodePtr Parser::ParsePostfixOperators(
             ParseNodePtr pnodeExpr = ParseExpr<buildAST>(0, FALSE, TRUE, FALSE, nullptr, nullptr, nullptr, &tok);
             if (buildAST)
             {
-                if (pnode && pnode->nop == knopName && pnode->AsParseNodePid()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper)
+                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);
@@ -3735,7 +3712,7 @@ ParseNodePtr Parser::ParsePostfixOperators(
             {
                 if (pnodeExpr && pnodeExpr->nop == knopName)
                 {
-                    topPidRef = pnodeExpr->AsParseNodePid()->pid->GetTopRef();
+                    topPidRef = pnodeExpr->AsParseNodeName()->pid->GetTopRef();
                 }
             }
             else if (tok.tk == tkID)
@@ -3756,18 +3733,18 @@ ParseNodePtr Parser::ParsePostfixOperators(
             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->AsParseNodePid()->pid->Cch() > 0 && !this->GetScanner()->IsEscapeOnLastTkStrCon();
+                shouldConvertToDot = pnode->AsParseNodeBin()->pnode2->AsParseNodeStr()->pid->Cch() > 0 && !this->GetScanner()->IsEscapeOnLastTkStrCon();
             }
 
             if (shouldConvertToDot)
             {
-                LPCOLESTR str = pnode->AsParseNodeBin()->pnode2->AsParseNodePid()->pid->Psz();
+                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->AsParseNodePid()->pid->Cch(),
+                    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
                 {
@@ -3794,7 +3771,10 @@ ParseNodePtr Parser::ParsePostfixOperators(
 
                     if (doConvertToProperty)
                     {
-                        pnode->AsParseNodeBin()->pnode2->nop = knopName;
+                        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;
                     }
@@ -3837,7 +3817,7 @@ ParseNodePtr Parser::ParsePostfixOperators(
                     Assert(opCode == knopIndex);
                     name = CreateStrNode(m_token.GetIdentifier(this->GetHashTbl()));
                 }
-                if (pnode && pnode->nop == knopName && pnode->AsParseNodePid()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper)
+                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);
@@ -4608,7 +4588,7 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
                 pnodeArg = CreateBinNode(isObjectPattern ? knopObjectPatternMember : knopMember, pnodeName, pnodeExpr);
                 if (pnodeArg->pnode1->nop == knopStr)
                 {
-                    pnodeArg->pnode1->AsParseNodePid()->pid->PromoteAssignmentState();
+                    pnodeArg->pnode1->AsParseNodeStr()->pid->PromoteAssignmentState();
                 }
             }
         }
@@ -4747,9 +4727,10 @@ ParseNodePtr Parser::ParseMemberList(LPCOLESTR pNameHint, uint32* pNameHintLengt
             if (pnodeArg->pnode2->nop == knopFncDecl)
             {
                 Assert(fullNameHintLength >= shortNameOffset);
-                pnodeArg->pnode2->AsParseNodeFnc()->hint = pFullNameHint;
-                pnodeArg->pnode2->AsParseNodeFnc()->hintLength = fullNameHintLength;
-                pnodeArg->pnode2->AsParseNodeFnc()->hintOffset = shortNameOffset;
+                ParseNodeFnc * pnodeFunc = pnodeArg->pnode2->AsParseNodeFnc();
+                pnodeFunc->hint = pFullNameHint;
+                pnodeFunc->hintLength = fullNameHintLength;
+                pnodeFunc->hintOffset = shortNameOffset;
             }
             AddToNodeListEscapedUse(&pnodeList, &lastNodeRef, pnodeArg);
         }
@@ -4895,11 +4876,11 @@ ParseNode * Parser::ParseFncDecl(ushort flags, LPCOLESTR pNameHint, const bool n
     // Create the node.
     pnodeFnc = CreateAllowDeferNodeForOpT<knopFncDecl>();
     pnodeFnc->SetDeclaration(fDeclaration);
-        
-    pnodeFnc->nestedFuncEscapes = false;    
+
+    pnodeFnc->nestedFuncEscapes = false;
     pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
     pnodeFnc->functionId = (*m_nextFunctionId)++;
-    
+
 
     // Push new parser state with this new function node
 
@@ -6189,7 +6170,7 @@ ParseNodeFnc * Parser::CreateDummyFuncNode(bool fDeclaration)
 
     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.   
 
@@ -6782,11 +6763,11 @@ ParseNodeFnc * Parser::GenerateEmptyConstructor(bool extends)
     pnodeFnc->ichLim = this->GetScanner()->IchLimTok();
     pnodeFnc->ichMin = this->GetScanner()->IchMinTok();
     pnodeFnc->cbLim = this->GetScanner()->IecpLimTok();
-    pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();   
+    pnodeFnc->cbMin = this->GetScanner()->IecpMinTok();
     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.
@@ -6834,7 +6815,7 @@ ParseNodeFnc * Parser::GenerateEmptyConstructor(bool extends)
     ParseNodeFnc * pnodeFncSave = m_currentNodeFunc;
     m_currentNodeFunc = pnodeFnc;
 
-    ParseNodePid * argsId = nullptr;
+    ParseNodeName * argsId = nullptr;
     ParseNodePtr *lastNodeRef = nullptr;
     ParseNodeBlock * pnodeBlock = StartParseBlock<buildAST>(PnodeBlockType::Parameter, ScopeType_Parameter);
 
@@ -7450,7 +7431,7 @@ public:
         this->m_parser->m_parsingSuperRestrictionState = m_originalParsingSuperRestrictionState;
     }
 private:
-    Parser* m_parser;
+    Parser * m_parser;
     int m_originalParsingSuperRestrictionState;
 };
 
@@ -7864,9 +7845,10 @@ ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
     ParseNodePtr* lastSubstitutionExpressionNodeRef = nullptr;
     ParseNodePtr pnodeTagFncArgs = nullptr;
     ParseNodePtr* lastTagFncArgNodeRef = nullptr;
-    ParseNodePid * stringLiteral = nullptr;
-    ParseNodePid * stringLiteralRaw = nullptr;
-    ParseNodePtr pnodeStringTemplate = nullptr;
+    ParseNodeStr * stringLiteral = nullptr;
+    ParseNodeStr * stringLiteralRaw = nullptr;
+    ParseNodeStrTemplate * pnodeStringTemplate = nullptr;
+    ParseNode * pnodeReturn = nullptr;
     bool templateClosed = false;
     const bool isTagged = pnodeTagFnc != nullptr;
     uint16 stringConstantCount = 0;
@@ -7876,9 +7858,9 @@ ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
 
     if (buildAST)
     {
-        pnodeStringTemplate = CreateNodeForOpT<knopStrTemplate>();
-        pnodeStringTemplate->AsParseNodeStrTemplate()->countStringLiterals = 0;
-        pnodeStringTemplate->AsParseNodeStrTemplate()->isTaggedTemplate = isTagged ? TRUE : FALSE;
+        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)
@@ -8014,10 +7996,10 @@ ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
 
     if (buildAST)
     {
-        pnodeStringTemplate->AsParseNodeStrTemplate()->pnodeStringLiterals = pnodeStringLiterals;
-        pnodeStringTemplate->AsParseNodeStrTemplate()->pnodeStringRawLiterals = pnodeRawStringLiterals;
-        pnodeStringTemplate->AsParseNodeStrTemplate()->pnodeSubstitutionExpressions = pnodeSubstitutionExpressions;
-        pnodeStringTemplate->AsParseNodeStrTemplate()->countStringLiterals = stringConstantCount;
+        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.
@@ -8027,17 +8009,18 @@ ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
         if (isTagged)
         {
             // Return the call node here and let the byte code generator Emit the string template automagically
-            pnodeStringTemplate = CreateCallNode(knopCall, pnodeTagFnc, pnodeTagFncArgs, ichMin, pnodeStringTemplate->ichLim);
+            ParseNodeCall * pnodeCall;
+            pnodeReturn = pnodeCall = CreateCallNode(knopCall, pnodeTagFnc, pnodeTagFncArgs, ichMin, pnodeStringTemplate->ichLim);
 
             // We need to set the arg count explicitly
-            pnodeStringTemplate->AsParseNodeCall()->argCount = stringConstantCount;
-            pnodeStringTemplate->AsParseNodeCall()->hasDestructuring = m_hasDestructuringPattern;
+            pnodeCall->argCount = stringConstantCount;
+            pnodeCall->hasDestructuring = m_hasDestructuringPattern;
         }
     }
 
     this->GetScanner()->Scan();
 
-    return pnodeStringTemplate;
+    return pnodeReturn;
 }
 
 LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pNode, uint32 *fullNameHintLength, uint32 *pShortNameOffset)
@@ -8058,7 +8041,7 @@ LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pN
     }
     else if (op == knopStr)
     {
-        return AppendNameHints(propertyString, pNode->AsParseNodePid()->pid, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
+        return AppendNameHints(propertyString, pNode->AsParseNodeStr()->pid, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
     }
     else if (op == knopFlt)
     {
@@ -8067,7 +8050,7 @@ LPCOLESTR Parser::FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pN
     else
     {
         rightNode = op == knopInt ? this->GetScanner()->StringFromLong(pNode->AsParseNodeInt()->lw)
-            : pNode->AsParseNodePid()->pid->Psz();
+            : pNode->AsParseNodeName()->pid->Psz();
     }
 
     return AppendNameHints(propertyString, rightNode, fullNameHintLength, pShortNameOffset, false, true/*add brackets*/);
@@ -8090,7 +8073,7 @@ LPCOLESTR Parser::ConstructNameHint(ParseNodeBin * pNode, uint32* fullNameHintLe
     {
         leftNode = ConstructNameHint(pNode->pnode1->AsParseNodeBin(), fullNameHintLength, pShortNameOffset);
     }
-    else if (pNode->pnode1->nop == knopName && !pNode->pnode1->AsParseNodePid()->IsSpecialName())
+    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.
@@ -8100,7 +8083,7 @@ LPCOLESTR Parser::ConstructNameHint(ParseNodeBin * pNode, uint32* fullNameHintLe
         //   }
         // }
 
-        IdentPtr pid = pNode->pnode1->AsParseNodePid()->pid;
+        IdentPtr pid = pNode->pnode1->AsParseNodeName()->pid;
         leftNode = pid->Psz();
         *fullNameHintLength = pid->Cch();
         *pShortNameOffset = 0;
@@ -8123,7 +8106,7 @@ LPCOLESTR Parser::ConstructNameHint(ParseNodeBin * pNode, uint32* fullNameHintLe
     }
     else
     {
-        rightNode = pNode->pnode2->AsParseNodePid()->pid->Psz();
+        rightNode = pNode->pnode2->AsParseNodeName()->pid->Psz();
         wrapWithBrackets = PNodeFlags::fpnIndexOperator == (pNode->grfpn & PNodeFlags::fpnIndexOperator);
     }
     Assert(rightNode != nullptr);
@@ -8544,7 +8527,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
                 {
                     if (IsStrictMode() && pnodeT->nop == knopName)
                     {
-                        CheckStrictModeEvalArgumentsUsage(pnodeT->AsParseNodePid()->pid);
+                        CheckStrictModeEvalArgumentsUsage(pnodeT->AsParseNodeName()->pid);
                     }
                 }
                 else
@@ -8671,7 +8654,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
             pNameHint = NULL;
             if (pnode->nop == knopName)
             {
-                IdentPtr pid = pnode->AsParseNodePid()->pid;
+                IdentPtr pid = pnode->AsParseNodeName()->pid;
                 pNameHint = pid->Psz();
                 hintLength = pid->Cch();
                 hintOffset = 0;
@@ -8680,7 +8663,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
             {
                 if (CONFIG_FLAG(UseFullName))
                 {
-                    pNameHint = ConstructNameHint(pnode->AsParseNodeBin() , &hintLength, &hintOffset);
+                    pNameHint = ConstructNameHint(pnode->AsParseNodeBin(), &hintLength, &hintOffset);
                 }
                 else
                 {
@@ -8692,7 +8675,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
 
                     if (pnodeName->nop == knopName)
                     {
-                        IdentPtr pid = pnode->AsParseNodePid()->pid;
+                        IdentPtr pid = pnode->AsParseNodeName()->pid;
                         pNameHint = pid->Psz();
                         hintLength = pid->Cch();
                         hintOffset = 0;
@@ -8715,7 +8698,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
             {
                 if (IsStrictMode() && pnode->nop == knopName)
                 {
-                    CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodePid()->pid);
+                    CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodeName()->pid);
                 }
                 this->CheckArguments(pnode);
                 pnode = CreateUniNode(tkInc == m_token.tk ? knopIncPost : knopDecPost, pnode);
@@ -8762,17 +8745,17 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
                 {
                     if (IsStrictMode() && pnode->nop == knopName)
                     {
-                        CheckStrictModeEvalArgumentsUsage(pnode->AsParseNodePid()->pid);
+                        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->AsParseNodePid()->pid == wellKnownPropertyPids._this
+                        && pnode->AsParseNodeBin()->pnode1->AsParseNodeName()->pid == wellKnownPropertyPids._this
                         && pnode->AsParseNodeBin()->pnode2->nop == knopName)
                     {
-                        if (pnode->AsParseNodeBin()->pnode2->AsParseNodePid()->pid != wellKnownPropertyPids.__proto__)
+                        if (pnode->AsParseNodeBin()->pnode2->AsParseNodeName()->pid != wellKnownPropertyPids.__proto__)
                         {
                             assignmentStmt = true;
                         }
@@ -8904,7 +8887,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
                     }
                     else if (pnode->AsParseNodeBin()->pnode1->nop == knopName)
                     {
-                        PidRefStack *pidRef = pnode->AsParseNodeBin()->pnode1->AsParseNodePid()->pid->GetTopRef();
+                        PidRefStack *pidRef = pnode->AsParseNodeBin()->pnode1->AsParseNodeName()->pid->GetTopRef();
                         pidRef->isFuncAssignment = true;
                     }
                 }
@@ -8988,7 +8971,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
                     ParseNodePtr propertyNode = lhs->AsParseNodeBin()->pnode2;
                     if (propertyNode->nop == knopName)
                     {
-                        propertyNode->AsParseNodePid()->pid->PromoteAssignmentState();
+                        propertyNode->AsParseNodeName()->pid->PromoteAssignmentState();
                     }
                 }
             }
@@ -9001,7 +8984,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
                     ParseNodePtr propertyNode = lhs->AsParseNodeBin()->pnode2;
                     if (propertyNode->nop == knopName)
                     {
-                        propertyNode->AsParseNodePid()->pid->PromoteAssignmentState();
+                        propertyNode->AsParseNodeName()->pid->PromoteAssignmentState();
                     }
                 }
             }
@@ -9018,7 +9001,7 @@ void Parser::TrackAssignment(ParseNodePtr pnodeT, IdentToken* pToken)
         Assert(pnodeT != nullptr);
         if (pnodeT->nop == knopName)
         {
-            PidRefStack *ref = pnodeT->AsParseNodePid()->pid->GetTopRef();
+            PidRefStack *ref = pnodeT->AsParseNodeName()->pid->GetTopRef();
             Assert(ref);
             ref->isAsg = true;
         }
@@ -9035,27 +9018,6 @@ void Parser::TrackAssignment(ParseNodePtr pnodeT, IdentToken* pToken)
     }
 }
 
-void ParseNodePid::SetSymRef(PidRefStack *ref)
-{
-    Assert(symRef == nullptr);
-    this->symRef = ref->GetSymRef();
-}
-
-Js::PropertyId ParseNodePid::PropertyIdFromNameNode() const
-{
-    Js::PropertyId propertyId;
-    Symbol *sym = this->sym;
-    if (sym)
-    {
-        propertyId = sym->GetPosition();
-    }
-    else
-    {
-        propertyId = this->pid->GetPropertyId();
-    }
-    return propertyId;
-}
-
 PidRefStack* Parser::PushPidRef(IdentPtr pid)
 {
     if (PHASE_ON1(Js::ParallelParsePhase))
@@ -9516,7 +9478,7 @@ ParseNodeCatch * Parser::ParseCatch()
             ParseNodePtr pnodePattern = ParseDestructuredLiteral<buildAST>(tkLET, true /*isDecl*/, true /*topLevel*/, DIC_ForceErrorOnInitializer);
             if (buildAST)
             {
-                pnode->pnodeParam = CreateParamPatternNode(pnodePattern);
+                pnode->SetParam(CreateParamPatternNode(pnodePattern));
                 Scope *scope = pnodeCatchScope->scope;
                 pnode->scope = scope;
             }
@@ -9539,8 +9501,8 @@ ParseNodeCatch * Parser::ParseCatch()
             pidCatch = m_token.GetIdentifier(this->GetHashTbl());
             PidRefStack *ref = this->FindOrAddPidRef(pidCatch, GetCurrentBlock()->blockId, GetCurrentFunctionNode()->functionId);
 
-            ParseNodePid * pnodeParam = CreateNameNode(pidCatch);
-            pnodeParam->symRef = ref->GetSymRef();
+            ParseNodeName * pnodeParam = CreateNameNode(pidCatch);
+            pnodeParam->SetSymRef(ref);
 
             const char16 *name = reinterpret_cast<const char16*>(pidCatch->Psz());
             int nameLength = pidCatch->Cch();
@@ -9559,7 +9521,7 @@ ParseNodeCatch * Parser::ParseCatch()
 
             if (buildAST)
             {
-                pnode->pnodeParam = pnodeParam;
+                pnode->SetParam(pnodeParam);
                 pnode->scope = scope;
             }
 
@@ -10748,7 +10710,7 @@ LNeedTerminator:
             const WCHAR *uniqueNameStr = _u("__ehobj");
             IdentPtr uniqueName = this->GetHashTbl()->PidHashNameLen(uniqueNameStr, static_cast<int32>(wcslen(uniqueNameStr)));
 
-            pCatch->pnodeParam = CreateNameNode(uniqueName);
+            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.
@@ -11283,7 +11245,7 @@ void Parser::FinishScopeInfo(Js::ScopeInfo * scopeInfo)
 /***************************************************************************
 Parse the code.
 ***************************************************************************/
-ParseNodePtr 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 * 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;
@@ -11399,7 +11361,7 @@ ParseNodePtr Parser::Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcou
         if (scopeInfo)
         {
             // Create an enclosing function context.
-            m_currentNodeFunc = CreateNodeForOpT<knopFncDecl>();            
+            m_currentNodeFunc = CreateNodeForOpT<knopFncDecl>();
             m_currentNodeFunc->functionId = m_functionBody->GetLocalFunctionId();
             m_currentNodeFunc->nestedCount = m_functionBody->GetNestedCount();
             m_currentNodeFunc->SetStrictMode(!!this->m_fUseStrictMode);
@@ -11732,7 +11694,7 @@ bool Parser::CheckAsmjsModeStrPid(IdentPtr pid)
 #endif
 }
 
-HRESULT Parser::ParseUtf8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
+HRESULT Parser::ParseUtf8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
     Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
 {
     m_functionBody = nullptr;
@@ -11740,7 +11702,7 @@ HRESULT Parser::ParseUtf8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, siz
     return ParseSourceInternal(parseTree, pSrc, 0, length, 0, true, grfsrc, pse, nextFunctionId, 0, sourceContextInfo);
 }
 
-HRESULT Parser::ParseCesu8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
+HRESULT Parser::ParseCesu8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
     Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo)
 {
     m_functionBody = nullptr;
@@ -11896,7 +11858,7 @@ HRESULT Parser::ParseFunctionInBackground(ParseNodeFnc * pnodeFnc, ParseContext
 
 #endif
 
-HRESULT Parser::ParseSourceWithOffset(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
+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)
 {
@@ -12010,10 +11972,10 @@ ParseNode* Parser::CopyPnode(ParseNode *pnode) {
     switch (pnode->nop) {
         //PTNODE(knopName       , "name"        ,None    ,Pid  ,fnopLeaf)
     case knopName: {
-        ParseNodePid * nameNode = CreateNameNode(pnode->AsParseNodePid()->pid);
+        ParseNodeName * nameNode = CreateNameNode(pnode->AsParseNodeName()->pid);
         nameNode->ichMin = pnode->ichMin;
         nameNode->ichLim = pnode->ichLim;
-        nameNode->sym = pnode->AsParseNodePid()->sym;
+        nameNode->sym = pnode->AsParseNodeName()->sym;
         return nameNode;
     }
                    //PTNODE(knopInt        , "int const"    ,None    ,Int  ,fnopLeaf|fnopConst)
@@ -12318,7 +12280,7 @@ inline bool Parser::IsNaNOrInfinityLiteral(LPCOLESTR str)
 template <bool buildAST>
 IdentPtr Parser::ParseSuper(bool fAllowCall)
 {
-    ParseNodePtr currentNodeFunc = GetCurrentFunctionNode();
+    ParseNodeFnc * currentNodeFunc = GetCurrentFunctionNode();
     IdentPtr superPid = nullptr;
 
     switch (m_token.tk)
@@ -12336,7 +12298,7 @@ IdentPtr Parser::ParseSuper(bool fAllowCall)
         break;
     }
 
-    currentNodeFunc->AsParseNodeFnc()->SetHasSuperReference(TRUE);
+    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.
@@ -12793,7 +12755,7 @@ ParseNodePtr Parser::ParseDestructuredVarDecl(tokens declarationType, bool isDec
             {
                 if (IsStrictMode() && pnodeElem != nullptr && pnodeElem->nop == knopName)
                 {
-                    CheckStrictModeEvalArgumentsUsage(pnodeElem->AsParseNodePid()->pid);
+                    CheckStrictModeEvalArgumentsUsage(pnodeElem->AsParseNodeName()->pid);
                 }
             }
             else
@@ -13080,8 +13042,8 @@ void PrintPnodeWIndent(ParseNode *pnode, int indentAmt) {
         //PTNODE(knopName       , "name"        ,None    ,Pid  ,fnopLeaf)
     case knopName:
         Indent(indentAmt);
-        if (pnode->AsParseNodePid()->pid != NULL) {
-            Output::Print(_u("id: %s\n"), pnode->AsParseNodePid()->pid->Psz());
+        if (pnode->AsParseNodeName()->pid != NULL) {
+            Output::Print(_u("id: %s\n"), pnode->AsParseNodeName()->pid->Psz());
         }
         else {
             Output::Print(_u("name node\n"));
@@ -13100,7 +13062,7 @@ void PrintPnodeWIndent(ParseNode *pnode, int indentAmt) {
         //PTNODE(knopStr        , "str const"    ,None    ,Pid  ,fnopLeaf|fnopConst)
     case knopStr:
         Indent(indentAmt);
-        Output::Print(_u("\"%s\"\n"), pnode->AsParseNodePid()->pid->Psz());
+        Output::Print(_u("\"%s\"\n"), pnode->AsParseNodeStr()->pid->Psz());
         break;
         //PTNODE(knopRegExp     , "reg expr"    ,None    ,Pid  ,fnopLeaf|fnopConst)
     case knopRegExp:
@@ -13732,7 +13694,7 @@ void PrintPnodeWIndent(ParseNode *pnode, int indentAmt) {
         Indent(indentAmt);
         Output::Print(_u("catch (%d-%d)\n"), pnode->ichMin, pnode->ichLim);
         PrintScopesWIndent(pnode, indentAmt + INDENT_SIZE);
-        PrintPnodeWIndent(pnode->AsParseNodeCatch()->pnodeParam, 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);

+ 9 - 11
lib/Parser/Parse.h

@@ -129,9 +129,7 @@ public:
     void SetIsInParsingArgList(bool set) { m_isInParsingArgList = set; }
 
     bool GetHasDestructuringPattern() const { return m_hasDestructuringPattern; }
-    void SetHasDestructuringPattern(bool set) { m_hasDestructuringPattern = set; }
-
-    static IdentPtr PidFromNode(ParseNodePtr pnode);
+    void SetHasDestructuringPattern(bool set) { m_hasDestructuringPattern = set; }    
 
     ParseNode* CopyPnode(ParseNode* pnode);
 
@@ -154,27 +152,27 @@ public:
     // the UTF-16 characters pre-canonicalization. Converting this UTF-16 with invalid sequences to valid UTF-8 and back would cause
     // all invalid UTF-16 sequences to be replaced by one or more Unicode replacement characters (0xFFFD), losing the original
     // invalid sequences.
-    HRESULT ParseCesu8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
+    HRESULT ParseCesu8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
         Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo);
 
     // Should be called when the source is UTF-8 and invalid UTF-8 sequences should be replaced with the unicode replacement character
     // (0xFFFD). Security concerns require externally produced UTF-8 only allow valid UTF-8 otherwise an attacker could use invalid
     // UTF-8 sequences to fool a filter and cause Javascript to be executed that might otherwise have been rejected.
-    HRESULT ParseUtf8Source(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
+    HRESULT ParseUtf8Source(__out ParseNodeProg ** parseTree, LPCUTF8 pSrc, size_t length, ULONG grfsrc, CompileScriptException *pse,
         Js::LocalFunctionId * nextFunctionId, SourceContextInfo * sourceContextInfo);
 
     // Used by deferred parsing to parse a deferred function.
-    HRESULT ParseSourceWithOffset(__out ParseNodePtr* parseTree, LPCUTF8 pSrc, size_t offset, size_t cbLength, charcount_t cchOffset,
+    HRESULT 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);
 
 protected:
     HRESULT ParseSourceInternal(
-        __out ParseNodePtr* parseTree, LPCUTF8 pszSrc, size_t offsetInBytes,
+        __out ParseNodeProg ** parseTree, LPCUTF8 pszSrc, size_t offsetInBytes,
         size_t lengthInCodePoints, charcount_t offsetInChars, bool isUtf8,
         ULONG grfscr, CompileScriptException *pse, Js::LocalFunctionId * nextFunctionId, ULONG lineNumber, SourceContextInfo * sourceContextInfo);
 
-    ParseNodePtr Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcount_t charOffset, bool isUtf8, ULONG grfscr, ULONG lineNumber,
+    ParseNodeProg * Parse(LPCUTF8 pszSrc, size_t offset, size_t length, charcount_t charOffset, bool isUtf8, ULONG grfscr, ULONG lineNumber,
         Js::LocalFunctionId * nextFunctionId, CompileScriptException *pse);
 
 private:
@@ -268,9 +266,9 @@ private:
     ParseNodeVar * CreateDeclNode(OpCode nop, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl = true);
 
     ParseNodeInt * CreateIntNode(int32 lw);
-    ParseNodePid * CreateStrNode(IdentPtr pid);
-    ParseNodePid * CreateNameNode(IdentPtr pid);
-    ParseNodePid * CreateNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim);
+    ParseNodeStr * CreateStrNode(IdentPtr pid);
+    ParseNodeName * CreateNameNode(IdentPtr pid);
+    ParseNodeName * CreateNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim);
     ParseNodeSpecialName * CreateSpecialNameNode(IdentPtr pid, PidRefStack * ref, charcount_t ichMin, charcount_t ichLim);
     ParseNodeSuperReference * CreateSuperReferenceNode(OpCode nop, ParseNodeSpecialName * pnode1, ParseNodePtr pnode2);
     ParseNodeProg * CreateProgNode(bool isModuleSource, ULONG lineNumber);

+ 7 - 3
lib/Parser/ParseTreeComparer.h

@@ -172,8 +172,10 @@ namespace Js
             switch (left->nop)
             {
             case knopName:
+                return ComputeDistance(left->AsParseNodeName()->pid, right->AsParseNodeName()->pid);
+
             case knopStr:
-                return ComputeDistance(left->AsParseNodePid()->pid, right->AsParseNodePid()->pid);
+                return ComputeDistance(left->AsParseNodeStr()->pid, right->AsParseNodeStr()->pid);
 
             case knopInt:
                 return left->AsParseNodeInt()->lw == right->AsParseNodeInt()->lw ? ExactMatchDistance : 1.0;
@@ -181,7 +183,7 @@ namespace Js
             case knopFlt:
                 return left->AsParseNodeFloat()->dbl == right->AsParseNodeFloat()->dbl ? ExactMatchDistance : 1.0;
 
-            case knopRegExp: //TODO: AsParseNodePid()->regexPattern
+            case knopRegExp: //TODO: AsParseNodeRegExp()->regexPattern
                 break;
             }
 
@@ -406,8 +408,10 @@ namespace Js
             switch (left->nop)
             {
             case knopName:
+                return AreEquivalent(left->AsParseNodeName()->pid, right->AsParseNodeName()->pid);
+
             case knopStr:
-                return AreEquivalent(left->AsParseNodePid()->pid, right->AsParseNodePid()->pid);
+                return AreEquivalent(left->AsParseNodeStr()->pid, right->AsParseNodeStr()->pid);
 
             case knopInt:
                 return left->AsParseNodeInt()->lw == right->AsParseNodeInt()->lw;

+ 1 - 1
lib/Parser/pnodewalk.h

@@ -367,7 +367,7 @@ private:
 
     ResultType WalkCatch(ParseNodeCatch *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->pnodeParam, context);
+        ResultType result = WalkFirstChild(pnode->GetParam(), context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);

+ 2 - 2
lib/Parser/ptlist.h

@@ -21,11 +21,11 @@ PTNODE(knopNone       , "<none>"           , Nop      , None        , fnopNone
 /***************************************************************************
     Leaf nodes.
 ***************************************************************************/
-PTNODE(knopName       , "name"             , Nop      , Pid         , fnopLeaf|fnopAllowDefer, "NameExpr"                       )
+PTNODE(knopName       , "name"             , Nop      , Name        , fnopLeaf|fnopAllowDefer, "NameExpr"                       )
 PTNODE(knopInt        , "int const"        , Nop      , Int         , fnopLeaf|fnopConst    , "NumberLit"                      )
 PTNODE(knopImport     , "import"           , Nop      , None        , fnopLeaf              , "ImportExpr"                     )
 PTNODE(knopFlt        , "flt const"        , Nop      , Float       , fnopLeaf|fnopConst    , "NumberLit"                      )
-PTNODE(knopStr        , "str const"        , Nop      , Pid         , fnopLeaf|fnopConst    , "StringLit"                      )
+PTNODE(knopStr        , "str const"        , Nop      , Str         , fnopLeaf|fnopConst    , "StringLit"                      )
 PTNODE(knopRegExp     , "reg expr"         , Nop      , RegExp      , fnopLeaf|fnopConst    , "RegExprLit"                     )
 PTNODE(knopNull       , "null"             , Nop      , None        , fnopLeaf              , "NullLit"                        )
 PTNODE(knopFalse      , "false"            , Nop      , None        , fnopLeaf              , "FalseLit"                       )

+ 55 - 14
lib/Parser/ptree.cpp

@@ -59,15 +59,21 @@ ParseNodeVar * ParseNode::AsParseNodeVar()
     return reinterpret_cast<ParseNodeVar *>(this);
 }
 
-ParseNodePid * ParseNode::AsParseNodePid()
+ParseNodeStr * ParseNode::AsParseNodeStr()
 {
-    Assert(this->nop == knopName || this->nop == knopStr);
-    return reinterpret_cast<ParseNodePid *>(this);
+    Assert(this->nop == knopStr);
+    return reinterpret_cast<ParseNodeStr *>(this);
+}
+
+ParseNodeName * ParseNode::AsParseNodeName()
+{
+    Assert(this->nop == knopName);
+    return reinterpret_cast<ParseNodeName *>(this);
 }
 
 ParseNodeSpecialName * ParseNode::AsParseNodeSpecialName()
 {
-    Assert(this->nop == knopName && this->AsParseNodePid()->IsSpecialName());
+    Assert(this->nop == knopName && this->AsParseNodeName()->IsSpecialName());
     return reinterpret_cast<ParseNodeSpecialName *>(this);
 }
 
@@ -245,9 +251,13 @@ ParseNodeModule * ParseNode::AsParseNodeModule()
 
 IdentPtr ParseNode::name()
 {
-    if (this->nop == knopName || this->nop == knopStr)
+    if (this->nop == knopStr)
     {
-        return this->AsParseNodePid()->pid;
+        return this->AsParseNodeStr()->pid;
+    }
+    else if (this->nop == knopName)
+    {
+        return this->AsParseNodeName()->pid;
     }
     else if (this->nop == knopVarDecl || this->nop == knopConstDecl)
     {
@@ -274,7 +284,7 @@ ParseNodePtr ParseNode::GetFormalNext()
 
 bool ParseNode::IsUserIdentifier()
 {
-    return this->nop == knopName && !this->AsParseNodePid()->IsSpecialName();
+    return this->nop == knopName && !this->AsParseNodeName()->IsSpecialName();
 }
 
 ParseNodeUni::ParseNodeUni(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1)
@@ -286,6 +296,13 @@ ParseNodeUni::ParseNodeUni(OpCode nop, charcount_t ichMin, charcount_t ichLim, P
 ParseNodeBin::ParseNodeBin(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2)
     : ParseNode(nop, ichMin, ichLim)
 {
+    // Member name is either a string or a computed name
+    Assert((nop != knopMember && nop != knopMemberShort && nop != knopObjectPatternMember && nop != knopGetMember && nop != knopSetMember) 
+        || (pnode1->nop == knopStr || pnode1->nop == knopComputedName));
+
+    // Dot's rhs has to be a name;
+    Assert(nop != knopDot || pnode2->nop == knopName);
+
     this->pnode1 = pnode1;
     this->pnode2 = pnode2;
 
@@ -326,21 +343,45 @@ ParseNodeRegExp::ParseNodeRegExp(OpCode nop, charcount_t ichMin, charcount_t ich
     this->regexPatternIndex = 0;
 }
 
-ParseNodePid::ParseNodePid(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr pid)
-    : ParseNode(nop, ichMin, ichLim)
+ParseNodeStr::ParseNodeStr(charcount_t ichMin, charcount_t ichLim, IdentPtr name)
+    : ParseNode(knopStr, ichMin, ichLim), pid(name)
 {
-    this->pid = pid;
-    this->sym = nullptr;
+}
+
+ParseNodeName::ParseNodeName(charcount_t ichMin, charcount_t ichLim, IdentPtr name)
+    : ParseNode(knopName, ichMin, ichLim), pid(name)
+{     
+    this->sym = nullptr;    
     this->symRef = nullptr;
     this->isSpecialName = false;
 }
 
+void ParseNodeName::SetSymRef(PidRefStack * ref)
+{
+    Assert(this->symRef == nullptr);
+    this->symRef = ref->GetSymRef();
+}
+
+Js::PropertyId ParseNodeName::PropertyIdFromNameNode() const
+{
+    Js::PropertyId propertyId;
+    Symbol *sym = this->sym;
+    if (sym)
+    {
+        propertyId = sym->GetPosition();
+    }
+    else
+    {
+        propertyId = this->pid->GetPropertyId();
+    }
+    return propertyId;
+}
+
 ParseNodeVar::ParseNodeVar(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr name)
-    : ParseNode(nop, ichMin, ichLim)
+    : ParseNode(nop, ichMin, ichLim), pid(name)
 {
     Assert(nop == knopVarDecl || nop == knopConstDecl || nop == knopLetDecl || nop == knopTemp);
 
-    this->pid = name;
     this->pnodeInit = nullptr;
     this->pnodeNext = nullptr;
     this->sym = nullptr;
@@ -545,7 +586,7 @@ ParseNodeFinally::ParseNodeFinally(OpCode nop, charcount_t ichMin, charcount_t i
 }
 
 ParseNodeSpecialName::ParseNodeSpecialName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid)
-    : ParseNodePid(knopName, ichMin, ichLim, pid)
+    : ParseNodeName(ichMin, ichLim, pid)
 {
     this->SetIsSpecialName();
     this->isThis = false;

+ 34 - 10
lib/Parser/ptree.h

@@ -74,7 +74,8 @@ class ParseNodeTri;
 class ParseNodeInt;
 class ParseNodeFloat;
 class ParseNodeRegExp;
-class ParseNodePid;
+class ParseNodeStr;
+class ParseNodeName;
 class ParseNodeVar;
 class ParseNodeCall;
 class ParseNodeSuperCall;
@@ -120,7 +121,8 @@ public:
     ParseNodeFloat * AsParseNodeFloat();
     ParseNodeRegExp * AsParseNodeRegExp();
     ParseNodeVar * AsParseNodeVar();
-    ParseNodePid * AsParseNodePid();
+    ParseNodeStr * AsParseNodeStr();
+    ParseNodeName * AsParseNodeName();
 
     ParseNodeSpecialName * AsParseNodeSpecialName();
     ParseNodeExportDefault * AsParseNodeExportDefault();
@@ -323,24 +325,39 @@ public:
 };
 
 // identifier or string
+
+class ParseNodeStr : public ParseNode
+{
+public:
+    ParseNodeStr(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
+
+    IdentPtr const pid;
+
+    DISABLE_SELF_CAST(ParseNodeStr);
+
+};
+
 class Symbol;
 struct PidRefStack;
-class ParseNodePid : public ParseNode
+class ParseNodeName : public ParseNode
 {
 public:
-    ParseNodePid(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
+    ParseNodeName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
 
-    IdentPtr pid;
+    IdentPtr const pid;
+private:
     Symbol **symRef;
+public:
     Symbol *sym;
 
     void SetSymRef(PidRefStack *ref);
+    void ClearSymRef() { symRef = nullptr; }
     Symbol **GetSymRef() const { return symRef; }
     Js::PropertyId PropertyIdFromNameNode() const;
 
     bool IsSpecialName() { return isSpecialName; }
 
-    DISABLE_SELF_CAST(ParseNodePid);
+    DISABLE_SELF_CAST(ParseNodeName);
 
 protected:
     void SetIsSpecialName() { isSpecialName = true; }
@@ -356,7 +373,7 @@ public:
     ParseNodeVar(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr name);
 
     ParseNodePtr pnodeNext;
-    IdentPtr pid;
+    IdentPtr const pid;
     Symbol *sym;
     Symbol **symRef;
     ParseNodePtr pnodeInit;
@@ -727,7 +744,7 @@ class ParseNodeStmt : public ParseNode
 public:
     ParseNodeStmt(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
-    ParseNodePtr pnodeOuter;
+    ParseNodeStmt * pnodeOuter;
 
     // Set by parsing code, used by code gen.
     uint grfnop;
@@ -962,8 +979,15 @@ class ParseNodeCatch : public ParseNodeStmt
 public:
     ParseNodeCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
+    ParseNodePtr GetParam() { return pnodeParam; }
+    void SetParam(ParseNodeName * pnode) { pnodeParam = pnode;  }
+    void SetParam(ParseNodeParamPattern * pnode) { pnodeParam = pnode; }    
+
     ParseNodePtr pnodeNext;
-    ParseNodePtr pnodeParam;
+
+private:
+    ParseNode *  pnodeParam;   // Name or ParamPattern
+public:
     ParseNodePtr pnodeBody;
     ParseNodePtr pnodeScopes;
     Scope        *scope;
@@ -983,7 +1007,7 @@ public:
 };
 
 // special name like 'this'
-class ParseNodeSpecialName : public ParseNodePid
+class ParseNodeSpecialName : public ParseNodeName
 {
 public:
     ParseNodeSpecialName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);

+ 2 - 2
lib/Runtime/Base/FunctionBody.cpp

@@ -2384,7 +2384,7 @@ namespace Js
                     {
                         CompileScriptException se;
                         Parser ps(m_scriptContext, funcBody->GetIsStrictMode() ? TRUE : FALSE);
-                        ParseNodePtr parseTree = nullptr;
+                        ParseNodeProg * parseTree = nullptr;
 
                         uint nextFunctionId = funcBody->GetLocalFunctionId();
                         hrParser = ps.ParseSourceWithOffset(&parseTree, pszStart, offset, length, charOffset, isCesu8, grfscr, &se,
@@ -2491,7 +2491,7 @@ namespace Js
     }
 
 #ifdef ASMJS_PLAT
-    FunctionBody* ParseableFunctionInfo::ParseAsmJs(Parser * ps, __out CompileScriptException * se, __out ParseNodePtr * parseTree)
+    FunctionBody* ParseableFunctionInfo::ParseAsmJs(Parser * ps, __out CompileScriptException * se, __out ParseNodeProg ** parseTree)
     {
         Assert(IsDeferredParseFunction());
         Assert(m_isAsmjsMode);

+ 1 - 1
lib/Runtime/Base/FunctionBody.h

@@ -1701,7 +1701,7 @@ namespace Js
         DEFINE_VTABLE_CTOR_NO_REGISTER(ParseableFunctionInfo, FunctionProxy);
         FunctionBody* Parse(ScriptFunction ** functionRef = nullptr, bool isByteCodeDeserialization = false);
 #ifdef ASMJS_PLAT
-        FunctionBody* ParseAsmJs(Parser * p, __out CompileScriptException * se, __out ParseNodePtr * ptree);
+        FunctionBody* ParseAsmJs(Parser * p, __out CompileScriptException * se, __out ParseNodeProg ** ptree);
 #endif
 
         FunctionBodyFlags GetFlags() const { return flags; }

+ 4 - 4
lib/Runtime/Base/ScriptContext.cpp

@@ -1919,7 +1919,7 @@ namespace Js
         Js::JavascriptError::MapAndThrowError(this, E_FAIL);
     }
 
-    ParseNode* ScriptContext::ParseScript(Parser* parser,
+    ParseNodeProg * ScriptContext::ParseScript(Parser* parser,
         const byte* script,
         size_t cb,
         SRCINFO const * pSrcInfo,
@@ -2043,7 +2043,7 @@ namespace Js
             grfscr |= fscrIsLibraryCode;
         }
 
-        ParseNodePtr parseTree;
+        ParseNodeProg * parseTree;
         if((loadScriptFlag & LoadScriptFlag_Utf8Source) == LoadScriptFlag_Utf8Source)
         {
             hr = parser->ParseUtf8Source(&parseTree, script, cb, grfscr, pse,
@@ -2092,7 +2092,7 @@ namespace Js
             uint sourceIndex;
             JavascriptFunction * pFunction = nullptr;
 
-            ParseNodePtr parseTree = ParseScript(&parser, script, cb, pSrcInfo,
+            ParseNodeProg * parseTree = ParseScript(&parser, script, cb, pSrcInfo,
                 pse, ppSourceInfo, rootDisplayName, loadScriptFlag,
                 &sourceIndex, scriptSource);
 
@@ -2134,7 +2134,7 @@ namespace Js
         return nullptr;
     }
 
-    JavascriptFunction* ScriptContext::GenerateRootFunction(ParseNodePtr parseTree, uint sourceIndex, Parser* parser, uint32 grfscr, CompileScriptException * pse, const char16 *rootDisplayName)
+    JavascriptFunction* ScriptContext::GenerateRootFunction(ParseNodeProg * parseTree, uint sourceIndex, Parser* parser, uint32 grfscr, CompileScriptException * pse, const char16 *rootDisplayName)
     {
         HRESULT hr;
 

+ 2 - 2
lib/Runtime/Base/ScriptContext.h

@@ -555,7 +555,7 @@ namespace Js
 
     private:
 
-        JavascriptFunction* GenerateRootFunction(ParseNodePtr parseTree, uint sourceIndex, Parser* parser, uint32 grfscr, CompileScriptException * pse, const char16 *rootDisplayName);
+        JavascriptFunction* GenerateRootFunction(ParseNodeProg * parseTree, uint sourceIndex, Parser* parser, uint32 grfscr, CompileScriptException * pse, const char16 *rootDisplayName);
 
         typedef void (*EventHandler)(ScriptContext *);
         ScriptContext ** registeredPrototypeChainEnsuredToHaveOnlyWritableDataPropertiesScriptContext;
@@ -1263,7 +1263,7 @@ private:
         bool IsWellKnownHostType(Js::TypeId typeId) { return threadContext->IsWellKnownHostType<wellKnownType>(typeId); }
         void SetWellKnownHostTypeId(WellKnownHostType wellKnownType, Js::TypeId typeId) { threadContext->SetWellKnownHostTypeId(wellKnownType, typeId); }
 
-        ParseNodePtr ParseScript(Parser* parser, const byte* script,
+        ParseNodeProg * ParseScript(Parser* parser, const byte* script,
             size_t cb, SRCINFO const * pSrcInfo,
             CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo,
             const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag,

+ 1 - 1
lib/Runtime/ByteCode/ByteCodeApi.h

@@ -4,7 +4,7 @@
 //-------------------------------------------------------------------------------------------------------
 #pragma once
 
-HRESULT GenerateByteCode(__in ParseNode *pnode, __in uint32 grfscr, __in Js::ScriptContext* scriptContext, __inout Js::ParseableFunctionInfo ** ppRootFunc,
+HRESULT GenerateByteCode(__in ParseNodeProg *pnode, __in uint32 grfscr, __in Js::ScriptContext* scriptContext, __inout Js::ParseableFunctionInfo ** ppRootFunc,
                          __in uint sourceIndex, __in bool forceNoNative, __in Parser* parser, __in CompileScriptException *pse, Js::ScopeInfo* parentScopeInfo = nullptr,
                          Js::ScriptFunction ** functionRef = nullptr);
 

Разница между файлами не показана из-за своего большого размера
+ 180 - 163
lib/Runtime/ByteCode/ByteCodeEmitter.cpp


+ 106 - 104
lib/Runtime/ByteCode/ByteCodeGenerator.cpp

@@ -454,7 +454,7 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
         break;
     case knopCatch:
         BeginVisitCatch(pnode, byteCodeGenerator);
-        Visit(pnode->AsParseNodeCatch()->pnodeParam, byteCodeGenerator, prefix, postfix);
+        Visit(pnode->AsParseNodeCatch()->GetParam(), byteCodeGenerator, prefix, postfix);
         Visit(pnode->AsParseNodeCatch()->pnodeBody, byteCodeGenerator, prefix, postfix, pnode);
         EndVisitCatch(pnode, byteCodeGenerator);
         break;
@@ -767,13 +767,13 @@ bool ByteCodeGenerator::IsFalse(ParseNode* node)
 /* static */
 bool ByteCodeGenerator::IsThis(ParseNode* pnode)
 {
-    return pnode->nop == knopName && pnode->AsParseNodePid()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isThis;
+    return pnode->nop == knopName && pnode->AsParseNodeName()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isThis;
 }
 
 /* static */
 bool ByteCodeGenerator::IsSuper(ParseNode* pnode)
 {
-    return pnode->nop == knopName && pnode->AsParseNodePid()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper;
+    return pnode->nop == knopName && pnode->AsParseNodeName()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper;
 }
 
 bool ByteCodeGenerator::IsES6DestructuringEnabled() const
@@ -1758,8 +1758,8 @@ Symbol * ByteCodeGenerator::AddSymbolToScope(Scope *scope, const char16 *key, in
         sym = varDecl->AsParseNodeVar()->sym;
         break;
     case knopName:
-        AnalysisAssert(varDecl->AsParseNodePid()->symRef);
-        sym = *varDecl->AsParseNodePid()->symRef;
+        AnalysisAssert(varDecl->AsParseNodeName()->GetSymRef());
+        sym = *varDecl->AsParseNodeName()->GetSymRef();
         break;
     default:
         AnalysisAssert(0);
@@ -1941,7 +1941,7 @@ bool ByteCodeGenerator::DoJitLoopBodies(FuncInfo *funcInfo) const
     return functionBody->ForceJITLoopBody() || funcInfo->byteCodeFunction->IsJitLoopBodyPhaseEnabled();
 }
 
-void ByteCodeGenerator::Generate(__in ParseNode *pnode, uint32 grfscr, __in ByteCodeGenerator* byteCodeGenerator,
+void ByteCodeGenerator::Generate(__in ParseNodeProg *pnodeProg, uint32 grfscr, __in ByteCodeGenerator* byteCodeGenerator,
     __inout Js::ParseableFunctionInfo ** ppRootFunc, __in uint sourceIndex,
     __in bool forceNoNative, __in Parser* parser, Js::ScriptFunction **functionRef)
 {
@@ -1953,7 +1953,7 @@ void ByteCodeGenerator::Generate(__in ParseNode *pnode, uint32 grfscr, __in Byte
     };
     ParseNodeWalker<WalkerPolicyTest> walker;
     // Just walk the ast to see if our walker encounters any problems
-    walker.Walk(pnode, &walker);
+    walker.Walk(pnodeProg, &walker);
 #endif
     Js::ScriptContext * scriptContext = byteCodeGenerator->scriptContext;
 
@@ -1969,7 +1969,7 @@ void ByteCodeGenerator::Generate(__in ParseNode *pnode, uint32 grfscr, __in Byte
     // For dynamic code, just provide a small number since that source info should have very few functions
     // For static code, the nextLocalFunctionId is a good guess of the initial size of the array to minimize reallocs
     SourceContextInfo * sourceContextInfo = utf8SourceInfo->GetSrcInfo()->sourceContextInfo;
-    utf8SourceInfo->EnsureInitialized((grfscr & fscrDynamicCode) ? 4 : (sourceContextInfo->nextLocalFunctionId - pnode->AsParseNodeFnc()->functionId));
+    utf8SourceInfo->EnsureInitialized((grfscr & fscrDynamicCode) ? 4 : (sourceContextInfo->nextLocalFunctionId - pnodeProg->functionId));
     sourceContextInfo->EnsureInitialized();
 
     ArenaAllocator localAlloc(_u("ByteCode"), threadContext->GetPageAllocator(), Js::Throw::OutOfMemory);
@@ -1990,16 +1990,16 @@ void ByteCodeGenerator::Generate(__in ParseNode *pnode, uint32 grfscr, __in Byte
     byteCodeGenerator->SetCurrentSourceIndex(sourceIndex);
     byteCodeGenerator->Begin(&localAlloc, grfscr, *ppRootFunc);
     byteCodeGenerator->functionRef = functionRef;
-    Visit(pnode, byteCodeGenerator, Bind, AssignRegisters);
+    Visit(pnodeProg, byteCodeGenerator, Bind, AssignRegisters);
 
     byteCodeGenerator->forceNoNative = forceNoNative;
-    byteCodeGenerator->EmitProgram(pnode);
+    byteCodeGenerator->EmitProgram(pnodeProg);
 
     if (byteCodeGenerator->flags & fscrEval)
     {
         // The eval caller's frame always escapes if eval refers to the caller's arguments.
         byteCodeGenerator->GetRootFunc()->GetFunctionBody()->SetFuncEscapes(
-            byteCodeGenerator->funcEscapes || pnode->AsParseNodeProg()->m_UsesArgumentsAtGlobal);
+            byteCodeGenerator->funcEscapes || pnodeProg->m_UsesArgumentsAtGlobal);
     }
 
 #ifdef IR_VIEWER
@@ -2175,7 +2175,7 @@ void ByteCodeGenerator::Begin(
     }
 }
 
-HRESULT GenerateByteCode(__in ParseNode *pnode, __in uint32 grfscr, __in Js::ScriptContext* scriptContext, __inout Js::ParseableFunctionInfo ** ppRootFunc,
+HRESULT GenerateByteCode(__in ParseNodeProg *pnode, __in uint32 grfscr, __in Js::ScriptContext* scriptContext, __inout Js::ParseableFunctionInfo ** ppRootFunc,
                          __in uint sourceIndex, __in bool forceNoNative, __in Parser* parser, __in CompileScriptException *pse, Js::ScopeInfo* parentScopeInfo,
                         Js::ScriptFunction ** functionRef)
 {
@@ -2202,11 +2202,10 @@ void BindInstAndMember(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
 
     BindReference(pnode, byteCodeGenerator);
 
-    ParseNode *right = pnode->AsParseNodeBin()->pnode2;
-    Assert(right->nop == knopName);
-    byteCodeGenerator->AssignPropertyId(right->AsParseNodePid()->pid);
-    right->AsParseNodePid()->sym = nullptr;
-    right->AsParseNodePid()->symRef = nullptr;
+    ParseNodeName *right = pnode->AsParseNodeBin()->pnode2->AsParseNodeName();    
+    byteCodeGenerator->AssignPropertyId(right->pid);
+    right->sym = nullptr;
+    right->ClearSymRef();
     right->grfpn |= fpnMemberReference;
 }
 
@@ -2241,16 +2240,17 @@ void BindReference(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
 
     if (pnode->nop == knopName)
     {
-        pnode->AsParseNodePid()->sym = byteCodeGenerator->FindSymbol(pnode->AsParseNodePid()->symRef, pnode->AsParseNodePid()->pid, isCallNode);
+        ParseNodeName * pnodeName = pnode->AsParseNodeName();
+        pnodeName->sym = byteCodeGenerator->FindSymbol(pnodeName->GetSymRef(), pnodeName->pid, isCallNode);
 
         if (funcEscapes &&
-            pnode->AsParseNodePid()->sym &&
-            pnode->AsParseNodePid()->sym->GetSymbolType() == STFunction &&
-            (!pnode->AsParseNodePid()->sym->GetIsGlobal() || (byteCodeGenerator->GetFlags() & fscrEval)))
+            pnodeName->sym &&
+            pnodeName->sym->GetSymbolType() == STFunction &&
+            (!pnodeName->sym->GetIsGlobal() || (byteCodeGenerator->GetFlags() & fscrEval)))
         {
             // Dot, index, and scope ops can cause a local function on the LHS to escape.
             // Make sure scopes are not cached in this case.
-            byteCodeGenerator->FuncEscapes(pnode->AsParseNodePid()->sym->GetScope());
+            byteCodeGenerator->FuncEscapes(pnodeName->sym->GetScope());
         }
     }
 }
@@ -2267,20 +2267,21 @@ void MarkFormal(ByteCodeGenerator *byteCodeGenerator, Symbol *formal, bool assig
     }
 }
 
-void AddArgsToScope(ParseNodePtr pnode, ByteCodeGenerator *byteCodeGenerator, bool assignLocation)
+void AddArgsToScope(ParseNodeFnc * pnodeFnc, ByteCodeGenerator *byteCodeGenerator, bool assignLocation)
 {
     Assert(byteCodeGenerator->TopFuncInfo()->varRegsCount == 0);
     Js::ArgSlot pos = 1;
-    bool isNonSimpleParameterList = pnode->AsParseNodeFnc()->HasNonSimpleParameterList();
+    bool isNonSimpleParameterList = pnodeFnc->HasNonSimpleParameterList();
 
     auto addArgToScope = [&](ParseNode *arg)
     {
         if (arg->IsVarLetOrConst())
         {
+            ParseNodeVar * pnodeVarArg = arg->AsParseNodeVar();
             Symbol *formal = byteCodeGenerator->AddSymbolToScope(byteCodeGenerator->TopFuncInfo()->GetParamScope(),
-                reinterpret_cast<const char16*>(arg->AsParseNodeVar()->pid->Psz()),
-                arg->AsParseNodeVar()->pid->Cch(),
-                arg,
+                reinterpret_cast<const char16*>(pnodeVarArg->pid->Psz()),
+                pnodeVarArg->pid->Cch(),
+                pnodeVarArg,
                 STFormal);
 #if DBG_DUMP
             if (byteCodeGenerator->Trace())
@@ -2294,7 +2295,7 @@ void AddArgsToScope(ParseNodePtr pnode, ByteCodeGenerator *byteCodeGenerator, bo
                 formal->SetIsNonSimpleParameter(true);
             }
 
-            arg->AsParseNodeVar()->sym = formal;
+            pnodeVarArg->sym = formal;
             MarkFormal(byteCodeGenerator, formal, assignLocation || isNonSimpleParameterList, isNonSimpleParameterList);
         }
         else if (arg->nop == knopParamPattern)
@@ -2309,22 +2310,22 @@ void AddArgsToScope(ParseNodePtr pnode, ByteCodeGenerator *byteCodeGenerator, bo
     };
 
     // We process rest separately because the number of in args needs to exclude rest.
-    MapFormalsWithoutRest(pnode, addArgToScope);
+    MapFormalsWithoutRest(pnodeFnc, addArgToScope);
     byteCodeGenerator->SetNumberOfInArgs(pos);
 
-    if (pnode->AsParseNodeFnc()->pnodeRest != nullptr)
+    if (pnodeFnc->pnodeRest != nullptr)
     {
         // The rest parameter will always be in a register, regardless of whether it is in a scope slot.
         // We save the assignLocation value for the assert condition below.
         bool assignLocationSave = assignLocation;
         assignLocation = true;
 
-        addArgToScope(pnode->AsParseNodeFnc()->pnodeRest);
+        addArgToScope(pnodeFnc->pnodeRest);
 
         assignLocation = assignLocationSave;
     }
 
-    MapFormalsFromPattern(pnode, addArgToScope);
+    MapFormalsFromPattern(pnodeFnc, addArgToScope);
 
     Assert(!assignLocation || byteCodeGenerator->TopFuncInfo()->varRegsCount + 1 == pos);
 }
@@ -3172,7 +3173,7 @@ void MarkInit(ParseNode* pnode)
         }
         else if (pnode->nop == knopAsg && pnode->AsParseNodeBin()->pnode1->nop == knopName)
         {
-            sym = pnode->AsParseNodeBin()->pnode1->AsParseNodePid()->sym;
+            sym = pnode->AsParseNodeBin()->pnode1->AsParseNodeName()->sym;
             pnodeInit = pnode->AsParseNodeBin()->pnode2;
         }
 
@@ -3433,21 +3434,22 @@ void VisitNestedScopes(ParseNode* pnodeScopeList, ParseNode* pnodeParent, ByteCo
 
         case knopCatch:
         {
-            PreVisitCatch(pnodeScope, byteCodeGenerator);
+            ParseNodeCatch * pnodeCatchScope = pnodeScope->AsParseNodeCatch();
+            PreVisitCatch(pnodeCatchScope, byteCodeGenerator);
 
-            if (pnodeScope->AsParseNodeCatch()->pnodeParam->nop != knopParamPattern)
+            if (pnodeCatchScope->GetParam()->nop != knopParamPattern)
             {
-                Visit(pnodeScope->AsParseNodeCatch()->pnodeParam, byteCodeGenerator, prefix, postfix);
+                Visit(pnodeCatchScope->GetParam(), byteCodeGenerator, prefix, postfix);
             }
 
             bool isMergedScope;
-            parentFuncInfo->OnStartVisitScope(pnodeScope->AsParseNodeCatch()->scope, &isMergedScope);
-            VisitNestedScopes(pnodeScope->AsParseNodeCatch()->pnodeScopes, pnodeParent, byteCodeGenerator, prefix, postfix, pIndex);
+            parentFuncInfo->OnStartVisitScope(pnodeCatchScope->scope, &isMergedScope);
+            VisitNestedScopes(pnodeCatchScope->pnodeScopes, pnodeParent, byteCodeGenerator, prefix, postfix, pIndex);
 
-            parentFuncInfo->OnEndVisitScope(pnodeScope->AsParseNodeCatch()->scope, isMergedScope);
-            PostVisitCatch(pnodeScope, byteCodeGenerator);
+            parentFuncInfo->OnEndVisitScope(pnodeCatchScope->scope, isMergedScope);
+            PostVisitCatch(pnodeCatchScope, byteCodeGenerator);
 
-            pnodeScope = pnodeScope->AsParseNodeCatch()->pnodeNext;
+            pnodeScope = pnodeCatchScope->pnodeNext;
             break;
         }
 
@@ -3612,13 +3614,16 @@ void PostVisitBlock(ParseNodeBlock *pnodeBlock, ByteCodeGenerator *byteCodeGener
     }
 }
 
-void PreVisitCatch(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
+void PreVisitCatch(ParseNodeCatch *pnodeCatch, ByteCodeGenerator *byteCodeGenerator)
 {
     // Push the catch scope and add the catch expression to it.
-    byteCodeGenerator->StartBindCatch(pnode);
-    if (pnode->AsParseNodeCatch()->pnodeParam->nop == knopParamPattern)
+    byteCodeGenerator->StartBindCatch(pnodeCatch);
+
+    ParseNode * pnodeParam = pnodeCatch->GetParam();
+    if (pnodeParam->nop == knopParamPattern)
     {
-        Parser::MapBindIdentifier(pnode->AsParseNodeCatch()->pnodeParam->AsParseNodeParamPattern()->pnode1, [&](ParseNodePtr item)
+        ParseNodeParamPattern * pnodeParamPattern = pnodeParam->AsParseNodeParamPattern();
+        Parser::MapBindIdentifier(pnodeParamPattern->pnode1, [&](ParseNodePtr item)
         {
             Symbol *sym = item->AsParseNodeVar()->sym;
 #if DBG_DUMP
@@ -3634,20 +3639,21 @@ void PreVisitCatch(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
     }
     else
     {
-        Symbol *sym = *pnode->AsParseNodeCatch()->pnodeParam->AsParseNodePid()->symRef;
-        Assert(sym->GetScope() == pnode->AsParseNodeCatch()->scope);
+        ParseNodeName * pnodeName = pnodeParam->AsParseNodeName();
+        Symbol *sym = *pnodeName->GetSymRef();
+        Assert(sym->GetScope() == pnodeCatch->scope);
 #if DBG_DUMP
         if (byteCodeGenerator->Trace())
         {
             Output::Print(_u("current context has declared catch var %s of type %s\n"),
-                pnode->AsParseNodeCatch()->pnodeParam->AsParseNodePid()->pid->Psz(), sym->GetSymbolTypeName());
+                pnodeName->pid->Psz(), sym->GetSymbolTypeName());
         }
 #endif
         sym->SetIsCatch(true);
-        pnode->AsParseNodeCatch()->pnodeParam->AsParseNodePid()->sym = sym;
+        pnodeName->sym = sym;
     }
     // This call will actually add the nested function symbols to the enclosing function scope (which is what we want).
-    AddFunctionsToScope(pnode->AsParseNodeCatch()->pnodeScopes, byteCodeGenerator);
+    AddFunctionsToScope(pnodeCatch->pnodeScopes, byteCodeGenerator);
 }
 
 void PostVisitCatch(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
@@ -3689,10 +3695,10 @@ bool IsLibraryFunction(ParseNode* expr, Js::ScriptContext* scriptContext)
         ParseNode* rhs = expr->AsParseNodeBin()->pnode2;
         if ((lhs != nullptr) && (rhs != nullptr) && (lhs->nop == knopName) && (rhs->nop == knopName))
         {
-            Symbol* lsym = lhs->AsParseNodePid()->sym;
-            if ((lsym == nullptr || lsym->GetIsGlobal()) && lhs->AsParseNodePid()->PropertyIdFromNameNode() == Js::PropertyIds::Math)
+            Symbol* lsym = lhs->AsParseNodeName()->sym;
+            if ((lsym == nullptr || lsym->GetIsGlobal()) && lhs->AsParseNodeName()->PropertyIdFromNameNode() == Js::PropertyIds::Math)
             {
-                return IsMathLibraryId(rhs->AsParseNodePid()->PropertyIdFromNameNode());
+                return IsMathLibraryId(rhs->AsParseNodeName()->PropertyIdFromNameNode());
             }
         }
     }
@@ -3750,7 +3756,7 @@ void CheckInvertableExpr(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator,
         switch (pnode->nop)
         {
         case knopName:
-            if (symCheck->MatchSymbol(pnode->AsParseNodePid()->sym))
+            if (symCheck->MatchSymbol(pnode->AsParseNodeName()->sym))
             {
                 symCheck->result = false;
             }
@@ -3762,7 +3768,7 @@ void CheckInvertableExpr(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator,
             {
                 if (callTarget->nop == knopName)
                 {
-                    Symbol* sym = callTarget->AsParseNodePid()->sym;
+                    Symbol* sym = callTarget->AsParseNodeName()->sym;
                     if (sym && sym->SingleDef())
                     {
                         ParseNode* decl = sym->GetDecl();
@@ -3849,7 +3855,7 @@ void CheckLocalVarDef(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
         ParseNode *lhs = pnode->AsParseNodeBin()->pnode1;
         if (lhs->nop == knopName)
         {
-            Symbol *sym = lhs->AsParseNodePid()->sym;
+            Symbol *sym = lhs->AsParseNodeName()->sym;
             if (sym != nullptr)
             {
                 sym->RecordDef();
@@ -3868,9 +3874,9 @@ ParseNode* ConstructInvertedStatement(ParseNode* stmt, ByteCodeGenerator* byteCo
     if (stmt == nullptr)
     {
             return nullptr;
-        }
+    }
 
-        ParseNode * cStmt;
+    ParseNode * cStmt;
     if ((stmt->nop == knopAsg) || (stmt->nop == knopVarDecl))
     {
         ParseNode * rhs = nullptr;
@@ -3880,55 +3886,55 @@ ParseNode* ConstructInvertedStatement(ParseNode* stmt, ByteCodeGenerator* byteCo
         {
             rhs = stmt->AsParseNodeBin()->pnode2;
             lhs = stmt->AsParseNodeBin()->pnode1;
-            }
+        }
         else if (stmt->nop == knopVarDecl)
         {
             rhs = stmt->AsParseNodeVar()->pnodeInit;
-            }
+        }
         ArenaAllocator * alloc = byteCodeGenerator->GetAllocator();
         ParseNodeVar * loopInvar = Parser::StaticCreateTempNode(rhs, alloc);
         loopInvar->location = funcInfo->NextVarRegister();
 
-            // Can't use a temp register here because the inversion happens at the parse tree level without generating
+        // Can't use a temp register here because the inversion happens at the parse tree level without generating
         // any bytecode yet. All local non-temp registers need to be initialized for jitted loop bodies, and since this is
-            // not a user variable, track this register separately to have it be initialized at the top of the function.
-            funcInfo->nonUserNonTempRegistersToInitialize.Add(loopInvar->location);
+        // not a user variable, track this register separately to have it be initialized at the top of the function.
+        funcInfo->nonUserNonTempRegistersToInitialize.Add(loopInvar->location);
 
             // add temp node to list of initializers for new outer loop
         if ((*outerStmtRef)->pnode1 == nullptr)
         {
             (*outerStmtRef)->pnode1 = loopInvar;
-            }
+        }
         else
         {
             ParseNodeBin * listNode = Parser::StaticCreateBinNode(knopList, nullptr, nullptr, alloc);
             (*outerStmtRef)->pnode2 = listNode;
             listNode->pnode1 = loopInvar;
             *outerStmtRef = listNode;
-            }
+        }
 
         ParseNodeUni * tempName = Parser::StaticCreateTempRef(loopInvar, alloc);
 
         if (lhs != nullptr)
         {
             cStmt = Parser::StaticCreateBinNode(knopAsg, lhs, tempName, alloc);
-            }
+        }
         else
         {
-                // Use AddVarDeclNode to add the var to the function.
-                // Do not use CreateVarDeclNode which is meant to be used while parsing. It assumes that
-                // parser's internal data structures (m_ppnodeVar in particular) is at the "current" location.
+            // Use AddVarDeclNode to add the var to the function.
+            // Do not use CreateVarDeclNode which is meant to be used while parsing. It assumes that
+            // parser's internal data structures (m_ppnodeVar in particular) is at the "current" location.
             cStmt = byteCodeGenerator->GetParser()->AddVarDeclNode(stmt->AsParseNodeVar()->pid, funcInfo->root);
             cStmt->AsParseNodeVar()->pnodeInit = tempName;
             cStmt->AsParseNodeVar()->sym = stmt->AsParseNodeVar()->sym;
-            }
         }
+    }
     else
     {
         cStmt = byteCodeGenerator->GetParser()->CopyPnode(stmt);
-        }
+    }
 
-        return cStmt;
+    return cStmt;
 }
 
 ParseNodeFor* ConstructInvertedLoop(ParseNode* innerLoop, ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo)
@@ -4020,7 +4026,7 @@ bool InvertableStmt(ParseNode* stmt, Symbol* outerVar, ParseNode* innerLoop, Par
 
             if (lhs->nop == knopName)
             {
-                if ((lhs->AsParseNodePid()->sym != nullptr) && (lhs->AsParseNodePid()->sym->GetIsGlobal()))
+                if ((lhs->AsParseNodeName()->sym != nullptr) && (lhs->AsParseNodeName()->sym->GetIsGlobal()))
                 {
                     return false;
                 }
@@ -4035,7 +4041,7 @@ bool InvertableStmt(ParseNode* stmt, Symbol* outerVar, ParseNode* innerLoop, Par
                     return false;
                 }
 
-                if ((indexed->nop != knopName) || (indexed->AsParseNodePid()->sym == nullptr))
+                if ((indexed->nop != knopName) || (indexed->AsParseNodeName()->sym == nullptr))
                 {
                     return false;
                 }
@@ -4093,13 +4099,14 @@ bool GatherInversionSyms(ParseNode* stmt, Symbol* outerVar, ParseNode* innerLoop
 
             if (lhs->nop == knopName)
             {
-                if ((lhs->AsParseNodePid()->sym == nullptr) || (lhs->AsParseNodePid()->sym->GetIsGlobal()))
+                ParseNodeName * pnodeNameLhs = lhs->AsParseNodeName();
+                if ((pnodeNameLhs->sym == nullptr) || (pnodeNameLhs->sym->GetIsGlobal()))
                 {
                     return false;
                 }
                 else
                 {
-                    auxSym = lhs->AsParseNodePid()->sym;
+                    auxSym = pnodeNameLhs->sym;
                 }
             }
         }
@@ -4211,7 +4218,7 @@ ParseNodeFor* InvertLoop(ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenera
                 (outerLoop->AsParseNodeFor()->pnodeIncr != nullptr) &&
                 ((outerLoop->AsParseNodeFor()->pnodeIncr->nop == knopIncPre) || (outerLoop->AsParseNodeFor()->pnodeIncr->nop == knopIncPost)) &&
                 (outerLoop->AsParseNodeFor()->pnodeIncr->AsParseNodeUni()->pnode1->nop == knopName) &&
-                (outerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->pid == outerLoop->AsParseNodeFor()->pnodeIncr->AsParseNodeUni()->pnode1->AsParseNodePid()->pid) &&
+                (outerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->pid == outerLoop->AsParseNodeFor()->pnodeIncr->AsParseNodeUni()->pnode1->AsParseNodeName()->pid) &&
                 (innerLoop->AsParseNodeFor()->pnodeIncr != nullptr) &&
                 ((innerLoop->AsParseNodeFor()->pnodeIncr->nop == knopIncPre) || (innerLoop->AsParseNodeFor()->pnodeIncr->nop == knopIncPost)) &&
                 (innerLoop->AsParseNodeFor()->pnodeInit != nullptr) &&
@@ -4219,7 +4226,7 @@ ParseNodeFor* InvertLoop(ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenera
                 (innerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->pnodeInit != nullptr) &&
                 (innerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->pnodeInit->nop == knopInt) &&
                 (innerLoop->AsParseNodeFor()->pnodeIncr->AsParseNodeUni()->pnode1->nop == knopName) &&
-                (innerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->pid == innerLoop->AsParseNodeFor()->pnodeIncr->AsParseNodeUni()->pnode1->AsParseNodePid()->pid))
+                (innerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->pid == innerLoop->AsParseNodeFor()->pnodeIncr->AsParseNodeUni()->pnode1->AsParseNodeName()->pid))
             {
                 Symbol* outerVar = outerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->sym;
                 Symbol* innerVar = innerLoop->AsParseNodeFor()->pnodeInit->AsParseNodeVar()->sym;
@@ -4351,24 +4358,25 @@ void Bind(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
         break;
     case knopName:
     {
-        if (pnode->AsParseNodePid()->sym == nullptr)
+        ParseNodeName * pnodeName = pnode->AsParseNodeName();
+        if (pnodeName->sym == nullptr)
         {
-            if (pnode->grfpn & fpnMemberReference)
+            if (pnodeName->grfpn & fpnMemberReference)
             {
                 // This is a member name. No binding.
                 break;
             }
 
-            Symbol *sym = byteCodeGenerator->FindSymbol(pnode->AsParseNodePid()->symRef, pnode->AsParseNodePid()->pid);
+            Symbol *sym = byteCodeGenerator->FindSymbol(pnodeName->GetSymRef(), pnodeName->pid);
             if (sym)
             {
                 // This is a named load, not just a reference, so if it's a nested function note that all
                 // the nested scopes escape.
-                Assert(!sym->GetDecl() || (pnode->AsParseNodePid()->symRef && *pnode->AsParseNodePid()->symRef));
-                Assert(!sym->GetDecl() || ((*pnode->AsParseNodePid()->symRef)->GetDecl() == sym->GetDecl()) ||
-                       ((*pnode->AsParseNodePid()->symRef)->GetFuncScopeVarSym() == sym));
+                Assert(!sym->GetDecl() || (pnodeName->GetSymRef() && *pnodeName->GetSymRef()));
+                Assert(!sym->GetDecl() || ((*pnodeName->GetSymRef())->GetDecl() == sym->GetDecl()) ||
+                       ((*pnodeName->GetSymRef())->GetFuncScopeVarSym() == sym));
 
-                pnode->AsParseNodePid()->sym = sym;
+                pnodeName->sym = sym;
                 if (sym->GetSymbolType() == STFunction &&
                     (!sym->GetIsGlobal() || (byteCodeGenerator->GetFlags() & fscrEval)))
                 {
@@ -4377,9 +4385,9 @@ void Bind(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
             }
         }
 
-        if (pnode->AsParseNodePid()->sym)
+        if (pnodeName->sym)
         {
-            pnode->AsParseNodePid()->sym->SetIsUsed(true);
+            pnodeName->sym->SetIsUsed(true);
         }
 
         break;
@@ -4387,26 +4395,20 @@ void Bind(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
     case knopMember:
     case knopMemberShort:
     case knopObjectPatternMember:
-        if (pnode->AsParseNodeBin()->pnode1->nop == knopComputedName)
-        {
-            // Computed property name - cannot bind yet
-            break;
-        }
-        // fall through
     case knopGetMember:
     case knopSetMember:
+
         {
             // lhs is knopStr, rhs is expr
-        ParseNode *id = pnode->AsParseNodeBin()->pnode1;
-            if (id->nop == knopStr || id->nop == knopName)
+            ParseNode *id = pnode->AsParseNodeBin()->pnode1;
+            if (id->nop == knopStr)
             {
-                byteCodeGenerator->AssignPropertyId(id->AsParseNodePid()->pid);
-                id->AsParseNodePid()->sym = nullptr;
-                id->AsParseNodePid()->symRef = nullptr;
+                byteCodeGenerator->AssignPropertyId(id->AsParseNodeStr()->pid);
                 id->grfpn |= fpnMemberReference;
             }
             break;
         }
+
         // TODO: convert index over string to Get/Put Value
     case knopIndex:
         BindReference(pnode, byteCodeGenerator);
@@ -4574,9 +4576,9 @@ void CheckMaybeEscapedUse(ParseNode * pnode, ByteCodeGenerator * byteCodeGenerat
         if (!isCall)
         {
             // Mark the name has having escaped use
-            if (pnode->AsParseNodePid()->sym)
+            if (pnode->AsParseNodeName()->sym)
             {
-                pnode->AsParseNodePid()->sym->SetHasMaybeEscapedUse(byteCodeGenerator);
+                pnode->AsParseNodeName()->sym->SetHasMaybeEscapedUse(byteCodeGenerator);
             }
         }
         break;
@@ -4712,7 +4714,7 @@ void AssignRegisters(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
 
     case knopAsg:
         {
-            Symbol * symName = pnode->AsParseNodeBin()->pnode1->nop == knopName ? pnode->AsParseNodeBin()->pnode1->AsParseNodePid()->sym : nullptr;
+            Symbol * symName = pnode->AsParseNodeBin()->pnode1->nop == knopName ? pnode->AsParseNodeBin()->pnode1->AsParseNodeName()->sym : nullptr;
             CheckFuncAssignment(symName, pnode->AsParseNodeBin()->pnode2, byteCodeGenerator);
 
             if (pnode->IsInList())
@@ -4923,7 +4925,7 @@ void AssignRegisters(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
         break;
     }
     case knopStr:
-        pnode->location = byteCodeGenerator->EnregisterStringConstant(pnode->AsParseNodePid()->pid);
+        pnode->location = byteCodeGenerator->EnregisterStringConstant(pnode->AsParseNodeStr()->pid);
         break;
     case knopVarDecl:
     case knopConstDecl:
@@ -5010,10 +5012,10 @@ void AssignRegisters(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
         break;
 
     case knopName:
-        sym = pnode->AsParseNodePid()->sym;
+        sym = pnode->AsParseNodeName()->sym;
         if (sym == nullptr)
         {
-            Assert(pnode->AsParseNodePid()->pid->GetPropertyId() != Js::Constants::NoProperty);
+            Assert(pnode->AsParseNodeName()->pid->GetPropertyId() != Js::Constants::NoProperty);
 
             // Referring to 'this' with no var decl needs to load 'this' root value via LdThis from null
             if (ByteCodeGenerator::IsThis(pnode) && !byteCodeGenerator->TopFuncInfo()->GetThisSymbol() && !(byteCodeGenerator->GetFlags() & fscrEval))

+ 12 - 12
lib/Runtime/ByteCode/ByteCodeGenerator.h

@@ -231,8 +231,8 @@ public:
     void StartBindCatch(ParseNode *pnode);
 
     // Block scopes related functions
-    template<class Fn> void IterateBlockScopedVariables(ParseNode *pnodeBlock, Fn fn);
-    void InitBlockScopedContent(ParseNode *pnodeBlock, Js::DebuggerScope *debuggerScope, FuncInfo *funcInfo);
+    template<class Fn> void IterateBlockScopedVariables(ParseNodeBlock *pnodeBlock, Fn fn);
+    void InitBlockScopedContent(ParseNodeBlock *pnodeBlock, Js::DebuggerScope *debuggerScope, FuncInfo *funcInfo);
 
     Js::DebuggerScope* RecordStartScopeObject(ParseNode *pnodeBlock, Js::DiagExtraScopesType scopeType, Js::RegSlot scopeLocation = Js::Constants::NoRegister, int* index = nullptr);
     void RecordEndScopeObject(ParseNode *pnodeBlock);
@@ -242,8 +242,8 @@ public:
     void EndEmitFunction(ParseNodeFnc *pnodeFnc);
     void StartEmitBlock(ParseNodeBlock *pnodeBlock);
     void EndEmitBlock(ParseNodeBlock *pnodeBlock);
-    void StartEmitCatch(ParseNode *pnodeCatch);
-    void EndEmitCatch(ParseNode *pnodeCatch);
+    void StartEmitCatch(ParseNodeCatch *pnodeCatch);
+    void EndEmitCatch(ParseNodeCatch *pnodeCatch);
     void StartEmitWith(ParseNode *pnodeWith);
     void EndEmitWith(ParseNode *pnodeWith);
     void EnsureFncScopeSlots(ParseNode *pnode, FuncInfo *funcInfo);
@@ -291,12 +291,12 @@ public:
     void EmitLoadFormalIntoRegister(ParseNode *pnodeFormal, Js::RegSlot pos, FuncInfo *funcInfo);
     void HomeArguments(FuncInfo *funcInfo);
 
-    void EnsureNoRedeclarations(ParseNode *pnodeBlock, FuncInfo *funcInfo);
+    void EnsureNoRedeclarations(ParseNodeBlock *pnodeBlock, FuncInfo *funcInfo);
 
     void DefineLabels(FuncInfo *funcInfo);
-    void EmitProgram(ParseNode *pnodeProg);
+    void EmitProgram(ParseNodeProg *pnodeProg);
     void EmitScopeList(ParseNode *pnode, ParseNode *breakOnBodyScopeNode = nullptr);
-    void EmitDefaultArgs(FuncInfo *funcInfo, ParseNode *pnode);
+    void EmitDefaultArgs(FuncInfo *funcInfo, ParseNodeFnc *pnode);
     void EmitOneFunction(ParseNodeFnc *pnodeFnc);
     void EmitGlobalFncDeclInit(Js::RegSlot rhsLocation, Js::PropertyId propertyId, FuncInfo * funcInfo);
     void EmitLocalPropInit(Js::RegSlot rhsLocation, Symbol *sym, FuncInfo *funcInfo);
@@ -308,7 +308,7 @@ public:
 
     bool ShouldLoadConstThis(FuncInfo* funcInfo);
 
-    void EmitPropLoadThis(Js::RegSlot lhsLocation, ParseNode *pnode, FuncInfo *funcInfo, bool chkUndecl);
+    void EmitPropLoadThis(Js::RegSlot lhsLocation, ParseNodeSpecialName *pnode, FuncInfo *funcInfo, bool chkUndecl);
     void EmitPropStoreForSpecialSymbol(Js::RegSlot rhsLocation, Symbol *sym, IdentPtr pid, FuncInfo *funcInfo, bool init);
 
     void EmitLoadInstance(Symbol *sym, IdentPtr pid, Js::RegSlot *pThisLocation, Js::RegSlot *pTargetLocation, FuncInfo *funcInfo);
@@ -354,7 +354,7 @@ public:
 
     bool DoJitLoopBodies(FuncInfo *funcInfo) const;
 
-    static void Generate(__in ParseNode *pnode, uint32 grfscr, __in ByteCodeGenerator* byteCodeGenerator, __inout Js::ParseableFunctionInfo ** ppRootFunc, __in uint sourceIndex, __in bool forceNoNative, __in Parser* parser, Js::ScriptFunction ** functionRef);
+    static void Generate(__in ParseNodeProg *pnode, uint32 grfscr, __in ByteCodeGenerator* byteCodeGenerator, __inout Js::ParseableFunctionInfo ** ppRootFunc, __in uint sourceIndex, __in bool forceNoNative, __in Parser* parser, Js::ScriptFunction ** functionRef);
     void Begin(
         __in ArenaAllocator *alloc,
         __in uint32 grfscr,
@@ -386,7 +386,7 @@ public:
     void TrackFunctionDeclarationPropertyForDebugger(Symbol *functionDeclarationSymbol, FuncInfo *funcInfoParent);
     void UpdateDebuggerPropertyInitializationOffset(Js::RegSlot location, Js::PropertyId propertyId, bool shouldConsumeRegister = true);
 
-    void PopulateFormalsScope(uint beginOffset, FuncInfo *funcInfo, ParseNode *pnode);
+    void PopulateFormalsScope(uint beginOffset, FuncInfo *funcInfo, ParseNodeFnc *pnodeFnc);
     void InsertPropertyToDebuggerScope(FuncInfo* funcInfo, Js::DebuggerScope* debuggerScope, Symbol* sym);
     FuncInfo *FindEnclosingNonLambda();
 
@@ -415,10 +415,10 @@ private:
     Js::OpCode ToChkUndeclOp(Js::OpCode op) const;
 };
 
-template<class Fn> void ByteCodeGenerator::IterateBlockScopedVariables(ParseNode *pnodeBlock, Fn fn)
+template<class Fn> void ByteCodeGenerator::IterateBlockScopedVariables(ParseNodeBlock *pnodeBlock, Fn fn)
 {
     Assert(pnodeBlock->nop == knopBlock);
-    for (auto lexvar = pnodeBlock->AsParseNodeBlock()->pnodeLexVars; lexvar; lexvar = lexvar->AsParseNodeVar()->pnodeNext)
+    for (auto lexvar = pnodeBlock->pnodeLexVars; lexvar; lexvar = lexvar->AsParseNodeVar()->pnodeNext)
     {
         fn(lexvar);
     }

+ 2 - 2
lib/Runtime/Language/AsmJsModule.cpp

@@ -562,7 +562,7 @@ namespace Js
         PageAllocator tempPageAlloc(NULL, Js::Configuration::Global.flags);
         Parser ps(GetScriptContext(), FALSE, &tempPageAlloc);
         FunctionBody * funcBody;
-        ParseNodePtr parseTree;
+        ParseNodeProg * parseTree;
 
         CompileScriptException se;
         funcBody = deferParseFunction->ParseAsmJs(&ps, &se, &parseTree);
@@ -571,7 +571,7 @@ namespace Js
         TRACE_BYTECODE(_u("\nDeferred parse %s\n"), funcBody->GetDisplayName());
         if (parseTree && parseTree->nop == knopProg)
         {
-            auto body = parseTree->AsParseNodeProg()->pnodeBody;
+            auto body = parseTree->pnodeBody;
             if (body && body->nop == knopList)
             {
                 auto fncDecl = body->AsParseNodeBin()->pnode1;

+ 1 - 1
lib/Runtime/Language/SourceTextModuleRecord.h

@@ -121,7 +121,7 @@ namespace Js
         Field(bool) parentsNotified;
         Field(bool) isRootModule;
         Field(bool) hadNotifyHostReady;
-        Field(ParseNodePtr) parseTree;
+        Field(ParseNodeProg *) parseTree;
         Field(Utf8SourceInfo*) pSourceInfo;
         Field(uint) sourceIndex;
         FieldNoBarrier(Parser*) parser;  // we'll need to keep the parser around till we are done with bytecode gen.

+ 2 - 2
lib/Runtime/Library/GlobalObject.cpp

@@ -897,7 +897,7 @@ namespace Js
             Parser parser(scriptContext, strictMode);
             bool forceNoNative = false;
 
-            ParseNodePtr parseTree = nullptr;
+            ParseNodeProg * parseTree = nullptr;
 
             SourceContextInfo * sourceContextInfo = pSrcInfo->sourceContextInfo;
             ULONG deferParseThreshold = Parser::GetDeferralThreshold(sourceContextInfo->IsSourceProfileLoaded());
@@ -926,7 +926,7 @@ namespace Js
                 // TODO: Handle strict mode.
                 if (isIndirect &&
                     !strictMode &&
-                    !parseTree->AsParseNodeFnc()->GetStrictMode())
+                    !parseTree->GetStrictMode())
                 {
                     grfscr &= ~fscrEval;
                 }

+ 8 - 8
lib/Runtime/Library/JavascriptLibrary.cpp

@@ -5279,7 +5279,7 @@ namespace Js
             Assert(x->nop == knopList);
             Assert(x->AsParseNodeBin()->pnode1->nop == knopStr);
 
-            pid = x->AsParseNodeBin()->pnode1->AsParseNodePid()->pid;
+            pid = x->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid;
 
             // If strings have different length, they aren't equal
             if (pid->Cch() != str->GetLength())
@@ -5303,7 +5303,7 @@ namespace Js
         str = Js::JavascriptString::FromVar(element);
 
         Assert(x->nop == knopStr);
-        pid = x->AsParseNodePid()->pid;
+        pid = x->AsParseNodeStr()->pid;
 
         // If strings have different length, they aren't equal
         if (pid->Cch() != str->GetLength())
@@ -5355,8 +5355,8 @@ namespace Js
             Assert(x->AsParseNodeBin()->pnode1->nop == knopStr);
             Assert(y->AsParseNodeBin()->pnode1->nop == knopStr);
 
-            pid_x = x->AsParseNodeBin()->pnode1->AsParseNodePid()->pid->Psz();
-            pid_y = y->AsParseNodeBin()->pnode1->AsParseNodePid()->pid->Psz();
+            pid_x = x->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->Psz();
+            pid_y = y->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->Psz();
 
             // If the pid values of each raw string don't match each other, these are different.
             if (!DefaultComparer<const char16*>::Equals(pid_x, pid_y))
@@ -5376,8 +5376,8 @@ namespace Js
 
         Assert(x->nop == knopStr);
 
-        pid_x = x->AsParseNodePid()->pid->Psz();
-        pid_y = y->AsParseNodePid()->pid->Psz();
+        pid_x = x->AsParseNodeStr()->pid->Psz();
+        pid_y = y->AsParseNodeStr()->pid->Psz();
 
         // This is the final string in the raw literals list. Return true if they are equal.
         return DefaultComparer<const char16*>::Equals(pid_x, pid_y);
@@ -5398,7 +5398,7 @@ namespace Js
         {
             Assert(i->AsParseNodeBin()->pnode1->nop == knopStr);
 
-            pid = i->AsParseNodeBin()->pnode1->AsParseNodePid()->pid->Psz();
+            pid = i->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->Psz();
 
             hash ^= DefaultComparer<const char16*>::GetHashCode(pid);
             hash ^= DefaultComparer<const char16*>::GetHashCode(_u("${}"));
@@ -5408,7 +5408,7 @@ namespace Js
 
         Assert(i->nop == knopStr);
 
-        pid = i->AsParseNodePid()->pid->Psz();
+        pid = i->AsParseNodeStr()->pid->Psz();
 
         hash ^= DefaultComparer<const char16*>::GetHashCode(pid);
 

Некоторые файлы не были показаны из-за большого количества измененных файлов