Преглед изворни кода

Parser Refactor: Use different ParseNode kind for knopStr and knopName and enforce child node type for some operations

Curtis Man пре 8 година
родитељ
комит
ad53e643d7

+ 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);
     }
 }
 

+ 58 - 103
lib/Parser/Parse.cpp

@@ -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
@@ -3508,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)
@@ -3530,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;
@@ -3706,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);
@@ -3739,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)
@@ -3760,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
                 {
@@ -3798,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;
                     }
@@ -3841,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);
@@ -4612,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();
                 }
             }
         }
@@ -6839,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);
 
@@ -7869,8 +7845,8 @@ ParseNodePtr Parser::ParseStringTemplateDecl(ParseNodePtr pnodeTagFnc)
     ParseNodePtr* lastSubstitutionExpressionNodeRef = nullptr;
     ParseNodePtr pnodeTagFncArgs = nullptr;
     ParseNodePtr* lastTagFncArgNodeRef = nullptr;
-    ParseNodePid * stringLiteral = nullptr;
-    ParseNodePid * stringLiteralRaw = nullptr;
+    ParseNodeStr * stringLiteral = nullptr;
+    ParseNodeStr * stringLiteralRaw = nullptr;
     ParseNodeStrTemplate * pnodeStringTemplate = nullptr;
     ParseNode * pnodeReturn = nullptr;
     bool templateClosed = false;
@@ -8065,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)
     {
@@ -8074,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*/);
@@ -8097,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.
@@ -8107,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;
@@ -8130,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);
@@ -8551,7 +8527,7 @@ ParseNodePtr Parser::ParseExpr(int oplMin,
                 {
                     if (IsStrictMode() && pnodeT->nop == knopName)
                     {
-                        CheckStrictModeEvalArgumentsUsage(pnodeT->AsParseNodePid()->pid);
+                        CheckStrictModeEvalArgumentsUsage(pnodeT->AsParseNodeName()->pid);
                     }
                 }
                 else
@@ -8678,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;
@@ -8699,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;
@@ -8722,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);
@@ -8769,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;
                         }
@@ -8911,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;
                     }
                 }
@@ -8995,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();
                     }
                 }
             }
@@ -9008,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();
                     }
                 }
             }
@@ -9025,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;
         }
@@ -9042,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))
@@ -9523,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;
             }
@@ -9546,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();
@@ -9566,7 +9521,7 @@ ParseNodeCatch * Parser::ParseCatch()
 
             if (buildAST)
             {
-                pnode->pnodeParam = pnodeParam;
+                pnode->SetParam(pnodeParam);
                 pnode->scope = scope;
             }
 
@@ -10755,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.
@@ -12017,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)
@@ -12800,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
@@ -13087,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"));
@@ -13107,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:
@@ -13739,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);

+ 4 - 6
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);
 
@@ -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;

+ 33 - 9
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;
@@ -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);

+ 93 - 87
lib/Runtime/ByteCode/ByteCodeEmitter.cpp

@@ -19,7 +19,7 @@ void VisitClearTmpRegs(ParseNode * pnode, ByteCodeGenerator * byteCodeGenerator,
 
 bool CallTargetIsArray(ParseNode *pnode)
 {
-    return pnode->nop == knopName && pnode->AsParseNodePid()->PropertyIdFromNameNode() == Js::PropertyIds::Array;
+    return pnode->nop == knopName && pnode->AsParseNodeName()->PropertyIdFromNameNode() == Js::PropertyIds::Array;
 }
 
 #define STARTSTATEMENET_IFTOPLEVEL(isTopLevel, pnode) \
@@ -113,7 +113,7 @@ bool IsArguments(ParseNode *pnode)
         switch (pnode->nop)
         {
         case knopName:
-            return pnode->AsParseNodePid()->sym && pnode->AsParseNodePid()->sym->IsArguments();
+            return pnode->AsParseNodeName()->sym && pnode->AsParseNodeName()->sym->IsArguments();
 
         case knopCall:
         case knopNew:
@@ -575,7 +575,7 @@ Js::JavascriptArray* ByteCodeGenerator::BuildArrayFromStringList(ParseNode* stri
     {
         Assert(stringNodeList->AsParseNodeBin()->pnode1->nop == knopStr);
 
-        pid = stringNodeList->AsParseNodeBin()->pnode1->AsParseNodePid()->pid;
+        pid = stringNodeList->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid;
         str = Js::JavascriptString::NewCopyBuffer(pid->Psz(), pid->Cch(), scriptContext);
         pArr->SetItemWithAttributes(index, str, PropertyEnumerable);
 
@@ -585,7 +585,7 @@ Js::JavascriptArray* ByteCodeGenerator::BuildArrayFromStringList(ParseNode* stri
 
     Assert(stringNodeList->nop == knopStr);
 
-    pid = stringNodeList->AsParseNodePid()->pid;
+    pid = stringNodeList->AsParseNodeStr()->pid;
     str = Js::JavascriptString::NewCopyBuffer(pid->Psz(), pid->Cch(), scriptContext);
     pArr->SetItemWithAttributes(index, str, PropertyEnumerable);
 
@@ -3990,12 +3990,13 @@ void ByteCodeGenerator::StartEmitCatch(ParseNodeCatch *pnodeCatch)
         scope->SetIsObject();
     }
 
-    if (pnodeCatch->pnodeParam->nop == knopParamPattern)
+    ParseNode * pnodeParam = pnodeCatch->GetParam();
+    if (pnodeParam->nop == knopParamPattern)
     {
         scope->SetCapturesAll(funcInfo->GetCallsEval() || funcInfo->GetChildCallsEval());
         scope->SetMustInstantiate(scope->Count() > 0 && (scope->GetMustInstantiate() || scope->GetCapturesAll() || funcInfo->IsGlobalFunction()));
 
-        Parser::MapBindIdentifier(pnodeCatch->pnodeParam->AsParseNodeParamPattern()->pnode1, [&](ParseNodePtr item)
+        Parser::MapBindIdentifier(pnodeParam->AsParseNodeParamPattern()->pnode1, [&](ParseNodePtr item)
         {
             Symbol *sym = item->AsParseNodeVar()->sym;
             if (funcInfo->IsGlobalFunction())
@@ -4015,7 +4016,7 @@ void ByteCodeGenerator::StartEmitCatch(ParseNodeCatch *pnodeCatch)
     }
     else
     {
-        Symbol *sym = pnodeCatch->pnodeParam->AsParseNodePid()->sym;
+        Symbol *sym = pnodeParam->AsParseNodeName()->sym;
 
         // Catch object is stored in the catch scope if there may be an ambiguous lookup or a var declaration that hides it.
         scope->SetCapturesAll(funcInfo->GetCallsEval() || funcInfo->GetChildCallsEval() || sym->GetHasNonLocalReference());
@@ -4909,9 +4910,9 @@ bool ByteCodeGenerator::ShouldLoadConstThis(FuncInfo* funcInfo)
     return funcInfo->thisConstantRegister != Js::Constants::NoRegister;
 }
 
-void ByteCodeGenerator::EmitPropLoadThis(Js::RegSlot lhsLocation, ParseNode *pnode, FuncInfo *funcInfo, bool chkUndecl)
+void ByteCodeGenerator::EmitPropLoadThis(Js::RegSlot lhsLocation, ParseNodeSpecialName *pnodeSpecialName, FuncInfo *funcInfo, bool chkUndecl)
 {
-    Symbol* sym = pnode->AsParseNodePid()->sym;
+    Symbol* sym = pnodeSpecialName->sym;
 
     if (!sym && this->ShouldLoadConstThis(funcInfo))
     {
@@ -4919,7 +4920,7 @@ void ByteCodeGenerator::EmitPropLoadThis(Js::RegSlot lhsLocation, ParseNode *pno
     }
     else
     {
-        this->EmitPropLoad(lhsLocation, pnode->AsParseNodePid()->sym, pnode->AsParseNodePid()->pid, funcInfo, true);
+        this->EmitPropLoad(lhsLocation, pnodeSpecialName->sym, pnodeSpecialName->pid, funcInfo, true);
 
         if ((!sym || sym->GetNeedDeclaration()) && chkUndecl)
         {
@@ -5670,10 +5671,10 @@ void ByteCodeGenerator::RecordAllStringTemplateCallsiteConstants(FuncInfo* funcI
     });
 }
 
-bool IsApplyArgs(ParseNode* callNode)
+bool IsApplyArgs(ParseNodeCall* callNode)
 {
-    ParseNode* target = callNode->AsParseNodeCall()->pnodeTarget;
-    ParseNode* args = callNode->AsParseNodeCall()->pnodeArgs;
+    ParseNode* target = callNode->pnodeTarget;
+    ParseNode* args = callNode->pnodeArgs;
     if ((target != nullptr) && (target->nop == knopDot))
     {
         ParseNode* lhsNode = target->AsParseNodeBin()->pnode1;
@@ -5682,14 +5683,14 @@ bool IsApplyArgs(ParseNode* callNode)
             ParseNode* nameNode = target->AsParseNodeBin()->pnode2;
             if (nameNode != nullptr)
             {
-                bool nameIsApply = nameNode->AsParseNodePid()->PropertyIdFromNameNode() == Js::PropertyIds::apply;
+                bool nameIsApply = nameNode->AsParseNodeName()->PropertyIdFromNameNode() == Js::PropertyIds::apply;
                 if (nameIsApply && args != nullptr && args->nop == knopList)
                 {
                     ParseNode* arg1 = args->AsParseNodeBin()->pnode1;
                     ParseNode* arg2 = args->AsParseNodeBin()->pnode2;
-                    if ((arg1 != nullptr) && ByteCodeGenerator::IsThis(arg1) && (arg2 != nullptr) && (arg2->nop == knopName) && (arg2->AsParseNodePid()->sym != nullptr))
+                    if ((arg1 != nullptr) && ByteCodeGenerator::IsThis(arg1) && (arg2 != nullptr) && (arg2->nop == knopName) && (arg2->AsParseNodeName()->sym != nullptr))
                     {
-                        return arg2->AsParseNodePid()->sym->IsArguments();
+                        return arg2->AsParseNodeName()->sym->IsArguments();
                     }
                 }
             }
@@ -5707,7 +5708,7 @@ void PostCheckApplyEnclosesArgs(ParseNode* pnode, ByteCodeGenerator* byteCodeGen
 
     if (pnode->nop == knopCall)
     {
-        if ((!pnode->isUsed) && IsApplyArgs(pnode))
+        if ((!pnode->isUsed) && IsApplyArgs(pnode->AsParseNodeCall()))
         {
             if (!applyCheck->insideApplyCall)
             {
@@ -5729,7 +5730,7 @@ void CheckApplyEnclosesArgs(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerat
     {
     case knopName:
     {
-        Symbol* sym = pnode->AsParseNodePid()->sym;
+        Symbol* sym = pnode->AsParseNodeName()->sym;
         if (sym != nullptr)
         {
             if (sym->IsArguments())
@@ -5744,7 +5745,7 @@ void CheckApplyEnclosesArgs(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerat
     }
 
     case knopCall:
-        if ((!pnode->isUsed) && IsApplyArgs(pnode))
+        if ((!pnode->isUsed) && IsApplyArgs(pnode->AsParseNodeCall()))
         {
             // no nested apply calls
             if (applyCheck->insideApplyCall)
@@ -5805,14 +5806,14 @@ void SaveOpndValue(ParseNode *pnode, FuncInfo *funcInfo)
     Symbol *sym = nullptr;
     if (pnode->nop == knopName)
     {
-        sym = pnode->AsParseNodePid()->sym;
+        sym = pnode->AsParseNodeName()->sym;
     }
     else if (pnode->nop == knopComputedName)
     {
         ParseNode *pnode1 = pnode->AsParseNodeUni()->pnode1;
         if (pnode1->nop == knopName)
         {
-            sym = pnode1->AsParseNodePid()->sym;
+            sym = pnode1->AsParseNodeName()->sym;
         }
     }
 
@@ -5890,7 +5891,7 @@ void EmitReference(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncI
 
         case knopName:
         {
-            Symbol *sym = pnode->AsParseNodeCall()->pnodeTarget->AsParseNodePid()->sym;
+            Symbol *sym = pnode->AsParseNodeCall()->pnodeTarget->AsParseNodeName()->sym;
             if (!sym || sym->GetLocation() == Js::Constants::NoRegister)
             {
                 funcInfo->AcquireLoc(pnode->AsParseNodeCall()->pnodeTarget);
@@ -5905,7 +5906,7 @@ void EmitReference(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncI
                 // EmitLoad will check for needsDeclaration and emit the Use Before Declaration error
                 // bytecode op as necessary, but EmitReference does not check this (by design). So we
                 // must manually check here.
-                EmitUseBeforeDeclaration(pnode->AsParseNodeCall()->pnodeTarget->AsParseNodePid()->sym, byteCodeGenerator, funcInfo);
+                EmitUseBeforeDeclaration(pnode->AsParseNodeCall()->pnodeTarget->AsParseNodeName()->sym, byteCodeGenerator, funcInfo);
                 EmitReference(pnode->AsParseNodeCall()->pnodeTarget, byteCodeGenerator, funcInfo);
             }
             break;
@@ -6613,9 +6614,8 @@ void EmitNameInvoke(Js::RegSlot lhsLocation,
     }
     else
     {
-        Assert(nameNode->nop == knopName || nameNode->nop == knopStr);
-        Symbol *sym = nameNode->AsParseNodePid()->sym;
-        Js::PropertyId propertyId = sym ? sym->EnsurePosition(byteCodeGenerator) : nameNode->AsParseNodePid()->pid->GetPropertyId();
+        Assert(nameNode->nop == knopStr);
+        Js::PropertyId propertyId = nameNode->AsParseNodeStr()->pid->GetPropertyId();
 
         uint cacheId = funcInfo->FindOrAddInlineCacheId(objectLocation, propertyId, false/*isLoadMethod*/, false/*isStore*/);
         byteCodeGenerator->Writer()->PatchableProperty(Js::OpCode::LdFld, lhsLocation, objectLocation, cacheId);
@@ -6766,14 +6766,14 @@ void EmitAssignment(
     case knopName:
     {
         // Special names like 'this' or 'new.target' cannot be assigned to
-        ParseNodePid * pnodePidLhs = lhs->AsParseNodePid();
-        if (pnodePidLhs->IsSpecialName())
+        ParseNodeName * pnodeNameLhs = lhs->AsParseNodeName();
+        if (pnodeNameLhs->IsSpecialName())
         {
             byteCodeGenerator->Writer()->W1(Js::OpCode::RuntimeReferenceError, SCODE_CODE(JSERR_CantAssignTo));
         }
         else
         {
-            byteCodeGenerator->EmitPropStore(rhsLocation, pnodePidLhs->sym, pnodePidLhs->pid, funcInfo);
+            byteCodeGenerator->EmitPropStore(rhsLocation, pnodeNameLhs->sym, pnodeNameLhs->pid, funcInfo);
         }
         break;
     }
@@ -6782,7 +6782,7 @@ void EmitAssignment(
     case knopDot:
     {
         // PutValue(x, "y", rhs)
-        Js::PropertyId propertyId = lhs->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+        Js::PropertyId propertyId = lhs->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
 
         if (ByteCodeGenerator::IsSuper(lhs->AsParseNodeBin()->pnode1))
         {
@@ -6885,7 +6885,7 @@ void EmitLoad(
     case knopName:
     {
         funcInfo->AcquireLoc(lhs);
-        byteCodeGenerator->EmitPropLoad(lhs->location, lhs->AsParseNodePid()->sym, lhs->AsParseNodePid()->pid, funcInfo);
+        byteCodeGenerator->EmitPropLoad(lhs->location, lhs->AsParseNodeName()->sym, lhs->AsParseNodeName()->pid, funcInfo);
         break;
     }
 
@@ -6893,7 +6893,7 @@ void EmitLoad(
     case knopDot:
     {
         // get field id for "y"
-        Js::PropertyId propertyId = lhs->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+        Js::PropertyId propertyId = lhs->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
         funcInfo->AcquireLoc(lhs);
         EmitReference(lhs, byteCodeGenerator, funcInfo);
         uint cacheId = funcInfo->FindOrAddInlineCacheId(lhs->AsParseNodeBin()->pnode1->location, propertyId, false, false);
@@ -7440,7 +7440,7 @@ void EmitMethodFld(ParseNode *pnode, Js::RegSlot callObjLocation, Js::PropertyId
 {
     // Load a call target of the form x.y(). (Call target may be a plain knopName if we're getting it from
     // the global object, etc.)
-    bool isRoot = pnode->nop == knopName && (pnode->AsParseNodePid()->sym == nullptr || pnode->AsParseNodePid()->sym->GetIsGlobal());
+    bool isRoot = pnode->nop == knopName && (pnode->AsParseNodeName()->sym == nullptr || pnode->AsParseNodeName()->sym->GetIsGlobal());
     bool isScoped = (byteCodeGenerator->GetFlags() & fscrEval) != 0 ||
         (isRoot && callObjLocation != ByteCodeGenerator::RootObjectRegister);
 
@@ -7464,7 +7464,7 @@ void EmitApplyCall(ParseNodeCall* pnodeCall, ByteCodeGenerator* byteCodeGenerato
     Emit(funcNode, byteCodeGenerator, funcInfo, false);
 
     funcInfo->AcquireLoc(applyNode);
-    Js::PropertyId propertyId = applyNode->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+    Js::PropertyId propertyId = applyNode->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
 
     // As we won't be emitting a call instruction for apply, no need to register the cacheId for apply
     // load to be associated with the call. This is also required, as in the absence of a corresponding
@@ -7559,7 +7559,7 @@ void EmitCallTargetNoEvalComponents(
 
     case knopName:
         // If the call target is a name, do some extra work to get its instance and the "this" pointer.
-        byteCodeGenerator->EmitLoadInstance(pnodeTarget->AsParseNodePid()->sym, pnodeTarget->AsParseNodePid()->pid, thisLocation, callObjLocation, funcInfo);
+        byteCodeGenerator->EmitLoadInstance(pnodeTarget->AsParseNodeName()->sym, pnodeTarget->AsParseNodeName()->pid, thisLocation, callObjLocation, funcInfo);
         if (*thisLocation == Js::Constants::NoRegister)
         {
             *thisLocation = funcInfo->undefinedConstantRegister;
@@ -7597,42 +7597,44 @@ void EmitCallTarget(
     {
     case knopDot:
     {
-        funcInfo->AcquireLoc(pnodeTarget);
+        ParseNodeBin * pnodeBinTarget = pnodeTarget->AsParseNodeBin();
+        funcInfo->AcquireLoc(pnodeBinTarget);
         // Assign the call target operand(s), putting them into expression temps if necessary to protect
         // them from side-effects.
         if (fSideEffectArgs)
         {
             // Though we're done with target evaluation after this point, still protect opnd1 from
             // arg side-effects as it's the "this" pointer.
-            SaveOpndValue(pnodeTarget->AsParseNodeBin()->pnode1, funcInfo);
+            SaveOpndValue(pnodeBinTarget->pnode1, funcInfo);
         }
 
-        if ((pnodeTarget->AsParseNodeBin()->pnode2->nop == knopName) && ((pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode() == Js::PropertyIds::apply) || (pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode() == Js::PropertyIds::call)))
+        Assert(pnodeBinTarget->pnode2->nop == knopName);
+        if ((pnodeBinTarget->pnode2->AsParseNodeName()->PropertyIdFromNameNode() == Js::PropertyIds::apply) || (pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode() == Js::PropertyIds::call))
         {
-            pnodeTarget->AsParseNodeBin()->pnode1->SetIsCallApplyTargetLoad();
+            pnodeBinTarget->pnode1->SetIsCallApplyTargetLoad();
         }
 
-        Emit(pnodeTarget->AsParseNodeBin()->pnode1, byteCodeGenerator, funcInfo, false);
-        Js::PropertyId propertyId = pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
-        Js::RegSlot protoLocation = pnodeTarget->AsParseNodeBin()->pnode1->location;
+        Emit(pnodeBinTarget->pnode1, byteCodeGenerator, funcInfo, false);
+        Js::PropertyId propertyId = pnodeBinTarget->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
+        Js::RegSlot protoLocation = pnodeBinTarget->pnode1->location;
 
-        if (ByteCodeGenerator::IsSuper(pnodeTarget->AsParseNodeBin()->pnode1))
+        if (ByteCodeGenerator::IsSuper(pnodeBinTarget->pnode1))
         {
-            Emit(pnodeTarget->AsParseNodeSuperReference()->pnodeThis, byteCodeGenerator, funcInfo, false);
+            Emit(pnodeBinTarget->AsParseNodeSuperReference()->pnodeThis, byteCodeGenerator, funcInfo, false);
             protoLocation = byteCodeGenerator->EmitLdObjProto(Js::OpCode::LdHomeObjProto, protoLocation, funcInfo);
-            funcInfo->ReleaseLoc(pnodeTarget->AsParseNodeSuperReference()->pnodeThis);
-            funcInfo->ReleaseLoc(pnodeTarget->AsParseNodeBin()->pnode1);
+            funcInfo->ReleaseLoc(pnodeBinTarget->AsParseNodeSuperReference()->pnodeThis);
+            funcInfo->ReleaseLoc(pnodeBinTarget->pnode1);
 
             // Function calls on the 'super' object should maintain current 'this' pointer
-            *thisLocation = pnodeTarget->AsParseNodeSuperReference()->pnodeThis->location;
+            *thisLocation = pnodeBinTarget->AsParseNodeSuperReference()->pnodeThis->location;
             *releaseThisLocation = false;
         }
         else
         {
-            *thisLocation = pnodeTarget->AsParseNodeBin()->pnode1->location;
+            *thisLocation = pnodeBinTarget->pnode1->location;
         }
 
-        EmitMethodFld(pnodeTarget, protoLocation, propertyId, byteCodeGenerator, funcInfo);
+        EmitMethodFld(pnodeBinTarget, protoLocation, propertyId, byteCodeGenerator, funcInfo);
         break;
     }
 
@@ -7681,22 +7683,22 @@ void EmitCallTarget(
 
     case knopName:
     {
-        ParseNodePid * pnodePidTarget = pnodeTarget->AsParseNodePid();
-        if (!pnodePidTarget->IsSpecialName())
+        ParseNodeName * pnodeNameTarget = pnodeTarget->AsParseNodeName();
+        if (!pnodeNameTarget->IsSpecialName())
         {
-            funcInfo->AcquireLoc(pnodePidTarget);
+            funcInfo->AcquireLoc(pnodeNameTarget);
             // Assign the call target operand(s), putting them into expression temps if necessary to protect
             // them from side-effects.
             if (fSideEffectArgs)
             {
-                SaveOpndValue(pnodePidTarget, funcInfo);
+                SaveOpndValue(pnodeNameTarget, funcInfo);
             }
-            byteCodeGenerator->EmitLoadInstance(pnodePidTarget->sym, pnodePidTarget->pid, thisLocation, callObjLocation, funcInfo);
+            byteCodeGenerator->EmitLoadInstance(pnodeNameTarget->sym, pnodeNameTarget->pid, thisLocation, callObjLocation, funcInfo);
             if (*callObjLocation != Js::Constants::NoRegister)
             {
                 // Load the call target as a property of the instance.
-                Js::PropertyId propertyId = pnodePidTarget->PropertyIdFromNameNode();
-                EmitMethodFld(pnodePidTarget, *callObjLocation, propertyId, byteCodeGenerator, funcInfo);
+                Js::PropertyId propertyId = pnodeNameTarget->PropertyIdFromNameNode();
+                EmitMethodFld(pnodeNameTarget, *callObjLocation, propertyId, byteCodeGenerator, funcInfo);
                 break;
             }
         }
@@ -7849,7 +7851,7 @@ void EmitCallInstrNoEvalComponents(
     case knopDot:
     {
         Assert(pnodeTarget->AsParseNodeBin()->pnode2->nop == knopName);
-        Js::PropertyId propertyId = pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+        Js::PropertyId propertyId = pnodeTarget->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
 
         EmitMethodFld(pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
         EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, /*fHasNewTarget*/ FALSE, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
@@ -7874,7 +7876,7 @@ void EmitCallInstrNoEvalComponents(
             }
             funcInfo->ReleaseTmpRegister(callObjLocation);
 
-            Js::PropertyId propertyId = pnodeTarget->AsParseNodePid()->PropertyIdFromNameNode();
+            Js::PropertyId propertyId = pnodeTarget->AsParseNodeName()->PropertyIdFromNameNode();
             EmitMethodFld(pnodeTarget, callObjLocation, propertyId, byteCodeGenerator, funcInfo);
             EmitCallI(pnodeCall, /*fEvaluateComponents*/ FALSE, fIsEval, /*fHasNewTarget*/ FALSE, actualArgCount, byteCodeGenerator, funcInfo, callSiteId, spreadIndices);
             break;
@@ -8252,7 +8254,7 @@ void EmitMemberNode(ParseNode *memberNode, Js::RegSlot objectLocation, ByteCodeG
     }
 
     Emit(exprNode, byteCodeGenerator, funcInfo, false);
-    Js::PropertyId propertyId = nameNode->AsParseNodePid()->PropertyIdFromNameNode();
+    Js::PropertyId propertyId = nameNode->AsParseNodeStr()->pid->GetPropertyId();
 
     if (Js::PropertyIds::name == propertyId
         && exprNode->nop == knopFncDecl
@@ -8367,7 +8369,7 @@ void EmitObjectInitializers(ParseNode *memberList, Js::RegSlot objectLocation, B
                 break;
             }
 
-            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodeBin()->pnode1->AsParseNodePid()->PropertyIdFromNameNode();
+            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->GetPropertyId();
             if (!byteCodeGenerator->GetScriptContext()->IsNumericPropertyId(propertyId, &value))
             {
                 propertyIds->Item(propertyId);
@@ -8378,7 +8380,7 @@ void EmitObjectInitializers(ParseNode *memberList, Js::RegSlot objectLocation, B
 
         if (memberList->AsParseNodeBin()->pnode1->nop != knopComputedName && !hasComputedName)
         {
-            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodePid()->PropertyIdFromNameNode();
+            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->GetPropertyId();
             if (!byteCodeGenerator->GetScriptContext()->IsNumericPropertyId(propertyId, &value))
             {
                 propertyIds->Item(propertyId);
@@ -8413,7 +8415,7 @@ void EmitObjectInitializers(ParseNode *memberList, Js::RegSlot objectLocation, B
             {
                 break;
             }
-            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodeBin()->pnode1->AsParseNodePid()->PropertyIdFromNameNode();
+            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->GetPropertyId();
             if (!byteCodeGenerator->GetScriptContext()->IsNumericPropertyId(propertyId, &value) && propertyIds->Remove(propertyId))
             {
                 propIds->elements[argIndex] = propertyId;
@@ -8424,7 +8426,7 @@ void EmitObjectInitializers(ParseNode *memberList, Js::RegSlot objectLocation, B
 
         if (memberList->AsParseNodeBin()->pnode1->nop != knopComputedName && !hasComputedName)
         {
-            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodePid()->PropertyIdFromNameNode();
+            propertyId = memberList->AsParseNodeBin()->pnode1->AsParseNodeStr()->pid->GetPropertyId();
             if (!byteCodeGenerator->GetScriptContext()->IsNumericPropertyId(propertyId, &value) && propertyIds->Remove(propertyId))
             {
                 propIds->elements[argIndex] = propertyId;
@@ -9648,7 +9650,7 @@ bool CollectConcat(ParseNode *pnodeAdd, DListCounted<ParseNode *, ArenaAllocator
 
             // Detect if there are any string larger then the append size limit.
             // If there are, we can do concat; otherwise, still use add so we will not lose the AddLeftDead opportunities.
-            doConcatString = doConcatString || !Js::CompoundString::ShouldAppendChars(pnode->AsParseNodePid()->pid->Cch());
+            doConcatString = doConcatString || !Js::CompoundString::ShouldAppendChars(pnode->AsParseNodeStr()->pid->Cch());
         }
         else
         {
@@ -9978,7 +9980,7 @@ void TrackMemberNodesInObjectForIntConstants(ByteCodeGenerator *byteCodeGenerato
 
         if (memberNameNode->nop != knopComputedName && memberValNode->nop == knopInt)
         {
-            Js::PropertyId propertyId = memberNameNode->AsParseNodePid()->PropertyIdFromNameNode();
+            Js::PropertyId propertyId = memberNameNode->AsParseNodeStr()->pid->GetPropertyId();
             TrackIntConstantsOnGlobalUserObject(byteCodeGenerator, true, propertyId);
         }
 
@@ -9991,7 +9993,7 @@ void TrackGlobalIntAssignmentsForknopDotProps(ParseNodePtr knopDotNode, ByteCode
     Assert(knopDotNode->nop == knopDot);
 
     ParseNodePtr objectNode = knopDotNode->AsParseNodeBin()->pnode1;
-    ParseNodePtr propertyNode = knopDotNode->AsParseNodeBin()->pnode2;
+    ParseNodeName * propertyNode = knopDotNode->AsParseNodeBin()->pnode2->AsParseNodeName();
     bool isSymGlobalAndSingleAssignment = false;
 
     if (objectNode->nop == knopName)
@@ -10000,15 +10002,15 @@ void TrackGlobalIntAssignmentsForknopDotProps(ParseNodePtr knopDotNode, ByteCode
         {
             // Assume 'this' always refer to GlobalObject
             // Cases like "this.a = "
-            isSymGlobalAndSingleAssignment = propertyNode->AsParseNodePid()->pid->IsSingleAssignment();
-            Js::PropertyId propertyId = propertyNode->AsParseNodePid()->PropertyIdFromNameNode();
+            isSymGlobalAndSingleAssignment = propertyNode->pid->IsSingleAssignment();
+            Js::PropertyId propertyId = propertyNode->PropertyIdFromNameNode();
             TrackIntConstantsOnGlobalObject(byteCodeGenerator, isSymGlobalAndSingleAssignment, propertyId);
         }
         else
         {
-            Symbol * sym = objectNode->AsParseNodePid()->sym;
-            isSymGlobalAndSingleAssignment = sym && sym->GetIsGlobal() && sym->IsAssignedOnce() && propertyNode->AsParseNodePid()->pid->IsSingleAssignment();
-            Js::PropertyId propertyId = propertyNode->AsParseNodePid()->PropertyIdFromNameNode();
+            Symbol * sym = objectNode->AsParseNodeName()->sym;
+            isSymGlobalAndSingleAssignment = sym && sym->GetIsGlobal() && sym->IsAssignedOnce() && propertyNode->pid->IsSingleAssignment();
+            Js::PropertyId propertyId = propertyNode->PropertyIdFromNameNode();
             TrackIntConstantsOnGlobalUserObject(byteCodeGenerator, isSymGlobalAndSingleAssignment, propertyId);
         }
     }
@@ -10041,7 +10043,7 @@ void TrackGlobalIntAssignments(ParseNodePtr pnode, ByteCodeGenerator * byteCodeG
             if (lhs->nop == knopName)
             {
                 // Handle "a = <Integer>" cases here
-                Symbol * sym = lhs->AsParseNodePid()->sym;
+                Symbol * sym = lhs->AsParseNodeName()->sym;
                 TrackIntConstantsOnGlobalObject(byteCodeGenerator, sym);
             }
             else if (lhs->nop == knopDot && lhs->AsParseNodeBin()->pnode2->nop == knopName)
@@ -10057,7 +10059,7 @@ void TrackGlobalIntAssignments(ParseNodePtr pnode, ByteCodeGenerator * byteCodeG
             if (lhs->nop == knopName)
             {
                 // Cases like "a++"
-                Symbol * sym = lhs->AsParseNodePid()->sym;
+                Symbol * sym = lhs->AsParseNodeName()->sym;
                 TrackIntConstantsOnGlobalObject(byteCodeGenerator, sym);
             }
             else if (lhs->nop == knopDot && lhs->AsParseNodeBin()->pnode2->nop == knopName)
@@ -10293,7 +10295,7 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         case knopDot:
         {
             Emit(pnodeOpnd->AsParseNodeBin()->pnode1, byteCodeGenerator, funcInfo, false);
-            Js::PropertyId propertyId = pnodeOpnd->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+            Js::PropertyId propertyId = pnodeOpnd->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
             Assert(pnodeOpnd->AsParseNodeBin()->pnode2->nop == knopName);
             funcInfo->ReleaseLoc(pnodeOpnd->AsParseNodeBin()->pnode1);
             funcInfo->AcquireLoc(pnode);
@@ -10313,10 +10315,11 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         }
         case knopName:
         {
-            if (pnodeOpnd->IsUserIdentifier())
+            ParseNodeName * pnodeNameOpnd = pnodeOpnd->AsParseNodeName();
+            if (pnodeNameOpnd->IsUserIdentifier())
             {
                 funcInfo->AcquireLoc(pnode);
-                byteCodeGenerator->EmitPropTypeof(pnode->location, pnodeOpnd->AsParseNodePid()->sym, pnodeOpnd->AsParseNodePid()->pid, funcInfo);
+                byteCodeGenerator->EmitPropTypeof(pnode->location, pnodeNameOpnd->sym, pnodeNameOpnd->pid, funcInfo);
                 break;
             }
             // Special names should fallthrough to default case
@@ -10428,7 +10431,8 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         {
         case knopName:
         {
-            if (pexpr->AsParseNodePid()->IsSpecialName())
+            ParseNodeName * pnodeName = pexpr->AsParseNodeName();
+            if (pnodeName->IsSpecialName())
             {
                 funcInfo->AcquireLoc(pnode);
                 byteCodeGenerator->Writer()->Reg1(Js::OpCode::LdTrue, pnode->location);
@@ -10436,7 +10440,7 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
             else
             {
                 funcInfo->AcquireLoc(pnode);
-                byteCodeGenerator->EmitPropDelete(pnode->location, pexpr->AsParseNodePid()->sym, pexpr->AsParseNodePid()->pid, funcInfo);
+                byteCodeGenerator->EmitPropDelete(pnode->location, pnodeName->sym, pnodeName->pid, funcInfo);
             }
             break;
         }
@@ -10454,7 +10458,7 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
                 Emit(pexpr->AsParseNodeBin()->pnode1, byteCodeGenerator, funcInfo, false);
 
                 funcInfo->ReleaseLoc(pexpr->AsParseNodeBin()->pnode1);
-                Js::PropertyId propertyId = pexpr->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+                Js::PropertyId propertyId = pexpr->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
                 funcInfo->AcquireLoc(pnode);
                 byteCodeGenerator->Writer()->Property(Js::OpCode::DeleteFld, pnode->location, pexpr->AsParseNodeBin()->pnode1->location,
                     funcInfo->FindOrAddReferencedPropertyId(propertyId));
@@ -10549,7 +10553,7 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         Emit(pnode->AsParseNodeBin()->pnode1, byteCodeGenerator, funcInfo, false);
         funcInfo->ReleaseLoc(pnode->AsParseNodeBin()->pnode1);
         funcInfo->AcquireLoc(pnode);
-        Js::PropertyId propertyId = pnode->AsParseNodeBin()->pnode2->AsParseNodePid()->PropertyIdFromNameNode();
+        Js::PropertyId propertyId = pnode->AsParseNodeBin()->pnode2->AsParseNodeName()->PropertyIdFromNameNode();
 
         Js::RegSlot callObjLocation = pnode->AsParseNodeBin()->pnode1->location;
         Js::RegSlot protoLocation = callObjLocation;
@@ -10623,11 +10627,11 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
 
         if (ByteCodeGenerator::IsThis(pnode))
         {
-            byteCodeGenerator->EmitPropLoadThis(pnode->location, pnode, funcInfo, true);
+            byteCodeGenerator->EmitPropLoadThis(pnode->location, pnode->AsParseNodeSpecialName(), funcInfo, true);
         }
         else
         {
-            byteCodeGenerator->EmitPropLoad(pnode->location, pnode->AsParseNodePid()->sym, pnode->AsParseNodePid()->pid, funcInfo);
+            byteCodeGenerator->EmitPropLoad(pnode->location, pnode->AsParseNodeName()->sym, pnode->AsParseNodeName()->pid, funcInfo);
         }
         break;
 
@@ -11366,8 +11370,10 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         byteCodeGenerator->Writer()->Empty(Js::OpCode::Leave);
         byteCodeGenerator->Writer()->Br(pnodeTryCatch->breakLabel);
         byteCodeGenerator->Writer()->MarkLabel(catchLabel);
-        Assert(pnodeCatch->pnodeParam);
-        ParseNode *pnodeObj = pnodeCatch->pnodeParam;
+        
+        ParseNode *pnodeObj = pnodeCatch->GetParam();
+        Assert(pnodeObj);
+
         Js::RegSlot location;
 
         bool acquiredTempLocation = false;
@@ -11383,7 +11389,7 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         }
         else
         {
-            location = pnodeObj->AsParseNodePid()->sym->GetLocation();
+            location = pnodeObj->AsParseNodeName()->sym->GetLocation();
         }
 
         if (location == Js::Constants::NoRegister)
@@ -11494,10 +11500,10 @@ void Emit(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator, FuncInfo *func
         }
         else
         {
-            ParamTrackAndInitialization(pnodeObj->AsParseNodePid()->sym, true /*initializeParam*/, location);
+            ParamTrackAndInitialization(pnodeObj->AsParseNodeName()->sym, true /*initializeParam*/, location);
             if (scope->GetMustInstantiate())
             {
-                pnodeObj->AsParseNodePid()->sym->SetIsGlobalCatch(true);
+                pnodeObj->AsParseNodeName()->sym->SetIsGlobalCatch(true);
             }
             byteCodeGenerator->Writer()->RecordCrossFrameEntryExitRecord(true);
 

+ 93 - 91
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);
@@ -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());
         }
     }
 }
@@ -2277,10 +2277,11 @@ void AddArgsToScope(ParseNodeFnc * pnodeFnc, ByteCodeGenerator *byteCodeGenerato
     {
         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(ParseNodeFnc * pnodeFnc, ByteCodeGenerator *byteCodeGenerato
                 formal->SetIsNonSimpleParameter(true);
             }
 
-            arg->AsParseNodeVar()->sym = formal;
+            pnodeVarArg->sym = formal;
             MarkFormal(byteCodeGenerator, formal, assignLocation || isNonSimpleParameterList, isNonSimpleParameterList);
         }
         else if (arg->nop == knopParamPattern)
@@ -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))

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

@@ -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);

+ 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);