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

Parser refactor: More use stronger type instead of casting from ParseNode

Also updated the ParseNodeFnc and ParseNodeProg constructor to initialize its field with default values
Remove unused fields in ParseNodeBin and ParseNodeTri
Reconfigure fields in ParseNode to save space.  ParseNode is not 8 byte smaller, and ParseNodeBin is 16 bytes smaller on 64-bit.
Curtis Man 8 лет назад
Родитель
Сommit
a4058ce9b6

+ 8 - 0
lib/Parser/Hash.cpp

@@ -206,6 +206,14 @@ void Ident::SetTk(tokens token, ushort grfid)
     }
 }
 
+void Ident::TrySetIsUsedInLdElem(ParseNode * pnode)
+{
+    if (pnode && pnode->nop == knopStr)
+    {
+        pnode->AsParseNodePid()->pid->SetIsUsedInLdElem(true);
+    }
+}
+
 IdentPtr HashTbl::PidFromTk(tokens token)
 {
     Assert(token > tkNone && token < tkID);

+ 1 - 7
lib/Parser/Hash.h

@@ -172,13 +172,7 @@ public:
         this->isUsedInLdElem = is;
     }
 
-    static void TrySetIsUsedInLdElem(ParseNode * pnode)
-    {
-        if (pnode && pnode->nop == knopStr)
-        {
-            pnode->AsParseNodePid()->pid->SetIsUsedInLdElem(true);
-        }
-    }
+    static void TrySetIsUsedInLdElem(ParseNode * pnode);
 
     bool IsSingleAssignment()
     {

Разница между файлами не показана из-за своего большого размера
+ 184 - 223
lib/Parser/Parse.cpp


+ 13 - 11
lib/Parser/Parse.h

@@ -272,19 +272,19 @@ private:
     ParseNodePid * CreateNameNode(IdentPtr pid);
     ParseNodePid * 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, ParseNodePtr pnode1, ParseNodePtr pnode2);
-    ParseNodeProg * CreateProgNode(bool isModuleSource);
+    ParseNodeSuperReference * CreateSuperReferenceNode(OpCode nop, ParseNodeSpecialName * pnode1, ParseNodePtr pnode2);
+    ParseNodeProg * CreateProgNode(bool isModuleSource, ULONG lineNumber);
 
     ParseNodeCall * CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2);
     ParseNodeCall * CreateCallNode(OpCode nop, ParseNodePtr pnode1, ParseNodePtr pnode2, charcount_t ichMin, charcount_t ichLim);
-    ParseNodeSuperCall * CreateSuperCallNode(ParseNodePtr pnode1, ParseNodePtr pnode2);
+    ParseNodeSuperCall * CreateSuperCallNode(ParseNodeSpecialName * pnode1, ParseNodePtr pnode2);
        
     ParseNodeFnc * CreateDummyFuncNode(bool fDeclaration);
 
     ParseNodeParamPattern * CreateParamPatternNode(ParseNodePtr pnode1);
     ParseNodeParamPattern * CreateDummyParamPatternNode(charcount_t ichMin);
 
-    Symbol*      AddDeclForPid(ParseNodePtr pnode, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl);
+    Symbol*      AddDeclForPid(ParseNodeVar * pnode, IdentPtr pid, SymbolType symbolType, bool errorOnRedecl);
     void         CheckRedeclarationErrorForBlockId(IdentPtr pid, int blockId);
 
 public:
@@ -431,12 +431,12 @@ private:
     bool NextTokenIsPropertyNameStart() const { return m_token.tk == tkID || m_token.tk == tkStrCon || m_token.tk == tkIntCon || m_token.tk == tkFltCon || m_token.tk == tkLBrack || m_token.IsReservedWord(); }
 
     template<bool buildAST>
-    void PushStmt(StmtNest *pStmt, ParseNodePtr pnode, OpCode op, LabelId* pLabelIdList)
+    void PushStmt(StmtNest *pStmt, ParseNodeStmt * pnode, OpCode op, LabelId* pLabelIdList)
     {
         if (buildAST)
         {
-            pnode->AsParseNodeStmt()->grfnop = 0;
-            pnode->AsParseNodeStmt()->pnodeOuter = (NULL == m_pstmtCur) ? NULL : m_pstmtCur->pnodeStmt;
+            pnode->grfnop = 0;
+            pnode->pnodeOuter = (NULL == m_pstmtCur) ? NULL : m_pstmtCur->pnodeStmt;
 
             pStmt->pnodeStmt = pnode;
         }
@@ -662,7 +662,9 @@ private:
         StrictModeEnvironment smEnvironment = SM_NotUsed,
         const bool isSourceElementList = false,
         bool* strictModeOn = NULL);
+#if ENABLE_BACKGROUND_PARSING
     bool FastScanFormalsAndBody();
+#endif
     bool ScanAheadToFunctionEnd(uint count);
 
     bool DoParallelParse(ParseNodeFnc * pnodeFnc) const;
@@ -730,10 +732,10 @@ private:
     void ParseTopLevelDeferredFunc(ParseNodeFnc * pnodeFnc, ParseNodeFnc * pnodeFncParent, LPCOLESTR pNameHint, bool fLambda, bool *pNeedScanRCurly = nullptr);
     void ParseNestedDeferredFunc(ParseNodeFnc * pnodeFnc, bool fLambda, bool *pNeedScanRCurly, bool *pStrictModeTurnedOn);
     void CheckStrictFormalParameters();
-    ParseNodePtr AddArgumentsNodeToVars(ParseNodeFnc * pnodeFnc);
+    ParseNodeVar * AddArgumentsNodeToVars(ParseNodeFnc * pnodeFnc);
     ParseNodeVar * InsertVarAtBeginning(ParseNodeFnc * pnodeFnc, IdentPtr pid);
     ParseNodeVar * CreateSpecialVarDeclNode(ParseNodeFnc * pnodeFnc, IdentPtr pid);
-    void UpdateArgumentsNode(ParseNodeFnc * pnodeFnc, ParseNodePtr argNode);
+    void UpdateArgumentsNode(ParseNodeFnc * pnodeFnc, ParseNodeVar * argNode);
     void UpdateOrCheckForDuplicateInFormals(IdentPtr pid, SList<IdentPtr> *formals);
 
     LPCOLESTR GetFunctionName(ParseNodeFnc * pnodeFnc, LPCOLESTR pNameHint);
@@ -753,7 +755,7 @@ private:
 
     // Construct the name from the parse node.
     LPCOLESTR FormatPropertyString(LPCOLESTR propertyString, ParseNodePtr pNode, uint32 *fullNameHintLength, uint32 *pShortNameOffset);
-    LPCOLESTR ConstructNameHint(ParseNodePtr pNode, uint32* fullNameHintLength, uint32 *pShortNameOffset);
+    LPCOLESTR ConstructNameHint(ParseNodeBin * pNode, uint32* fullNameHintLength, uint32 *pShortNameOffset);
     LPCOLESTR AppendNameHints(IdentPtr  left, IdentPtr  right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace = false, bool wrapInBrackets = false);
     LPCOLESTR AppendNameHints(IdentPtr  left, LPCOLESTR right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace = false, bool wrapInBrackets = false);
     LPCOLESTR AppendNameHints(LPCOLESTR left, IdentPtr  right, uint32 *pNameLength, uint32 *pShortNameOffset, bool ignoreAddDotWithSpace = false, bool wrapInBrackets = false);
@@ -966,7 +968,7 @@ private:
 
     template <class Fn>
     void FinishFunctionsInScope(ParseNodePtr pnodeScopeList, Fn fn);
-    void FinishDeferredFunction(ParseNodePtr pnodeScopeList);
+    void FinishDeferredFunction(ParseNodeBlock * pnodeScopeList);
 
     /***********************************************************************
     Misc

+ 111 - 112
lib/Parser/pnodewalk.h

@@ -83,136 +83,135 @@ private:
         return WalkNode(pnode, context);
     }
 
-    ResultType WalkPreUnary(ParseNode *pnode, Context context)
+    ResultType WalkPreUnary(ParseNodeUni *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result) && pnode->AsParseNodeUni()->pnode1) result = WalkFirstChild(pnode->AsParseNodeUni()->pnode1, context);
+        if (ContinueWalk(result) && pnode->pnode1) result = WalkFirstChild(pnode->pnode1, context);
         return result;
     }
 
-    ResultType WalkPostUnary(ParseNode *pnode, Context context)
+    ResultType WalkPostUnary(ParseNodeUni *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeUni()->pnode1, context);
+        ResultType result = WalkFirstChild(pnode->pnode1, context);
         if (ContinueWalk(result)) result = WalkNode(pnode, context);
         return result;
     }
 
-    ResultType WalkBinary(ParseNode *pnode, Context context)
+    ResultType WalkBinary(ParseNodeBin *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeBin()->pnode1, context);
+        ResultType result = WalkFirstChild(pnode->pnode1, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeBin()->pnode2, context);
+            if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnode2, context);
         }
         return result;
     }
 
-    ResultType WalkTernary(ParseNode *pnode, Context context)
+    ResultType WalkTernary(ParseNodeTri *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeTri()->pnode1, context);
+        ResultType result = WalkFirstChild(pnode->pnode1, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
             if (ContinueWalk(result))
             {
-                result = WalkSecondChild(pnode->AsParseNodeTri()->pnode2, context);
-                if (ContinueWalk(result)) result = WalkNthChild(pnode, pnode->AsParseNodeTri()->pnode3, context);
+                result = WalkSecondChild(pnode->pnode2, context);
+                if (ContinueWalk(result)) result = WalkNthChild(pnode, pnode->pnode3, context);
             }
         }
         return result;
     }
 
-    ResultType WalkCall(ParseNode *pnode, Context context)
+    ResultType WalkCall(ParseNodeCall *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeCall()->pnodeTarget, context);
+        ResultType result = WalkFirstChild(pnode->pnodeTarget, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkList(pnode, pnode->AsParseNodeCall()->pnodeArgs, context);
+            if (ContinueWalk(result)) result = WalkList(pnode, pnode->pnodeArgs, context);
         }
         return result;
     }
 
-    ResultType WalkStringTemplate(ParseNode *pnode, Context context)
+    ResultType WalkStringTemplate(ParseNodeStrTemplate *pnode, Context context)
     {
         ResultType result;
 
-        if (!pnode->AsParseNodeStrTemplate()->isTaggedTemplate)
+        if (!pnode->isTaggedTemplate)
         {
-            if (pnode->AsParseNodeStrTemplate()->pnodeSubstitutionExpressions == nullptr)
+            if (pnode->pnodeSubstitutionExpressions == nullptr)
             {
                 // If we don't have any substitution expressions, then we should only have one string literal and not a list
-                result = WalkNode(pnode->AsParseNodeStrTemplate()->pnodeStringLiterals, context);
+                result = WalkNode(pnode->pnodeStringLiterals, context);
             }
             else
             {
-                result = WalkList(pnode, pnode->AsParseNodeStrTemplate()->pnodeSubstitutionExpressions, context);
+                result = WalkList(pnode, pnode->pnodeSubstitutionExpressions, context);
                 if (ContinueWalk(result))
                 {
-                    result = WalkList(pnode, pnode->AsParseNodeStrTemplate()->pnodeStringLiterals, context);
+                    result = WalkList(pnode, pnode->pnodeStringLiterals, context);
                 }
             }
         }
         else
         {
-            // Tagged template nodes are call nodes
-            result = WalkCall(pnode, context);
+            result = WalkList(pnode, pnode->pnodeStringLiterals, context);
         }
 
         return result;
     }
 
-    ResultType WalkVar(ParseNode *pnode, Context context)
+    ResultType WalkVar(ParseNodeVar *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result) && pnode->AsParseNodeVar()->pnodeInit) result = WalkFirstChild(pnode->AsParseNodeVar()->pnodeInit, context);
+        if (ContinueWalk(result) && pnode->pnodeInit) result = WalkFirstChild(pnode->pnodeInit, context);
         return result;
     }
 
-    ResultType WalkFnc(ParseNode *pnode, Context context)
+    ResultType WalkFnc(ParseNodeFnc *pnode, Context context)
     {
         ResultType result;
         // For ordering, arguments are considered prior to the function and the body after.
-        for (ParseNodePtr* argNode = &(pnode->AsParseNodeFnc()->pnodeParams); *argNode != nullptr; argNode = &((*argNode)->AsParseNodeVar()->pnodeNext))
+        for (ParseNodePtr* argNode = &(pnode->pnodeParams); *argNode != nullptr; argNode = &((*argNode)->AsParseNodeVar()->pnodeNext))
         {
-            result = *argNode == pnode->AsParseNodeFnc()->pnodeParams ? WalkFirstChild(*argNode, context) : WalkNthChild(pnode, *argNode, context);
+            result = *argNode == pnode->pnodeParams ? WalkFirstChild(*argNode, context) : WalkNthChild(pnode, *argNode, context);
             if (!ContinueWalk(result)) return result;
         }
 
-        if (pnode->AsParseNodeFnc()->pnodeRest != nullptr)
+        if (pnode->pnodeRest != nullptr)
         {
-            result = WalkSecondChild(pnode->AsParseNodeFnc()->pnodeRest, context);
+            result = WalkSecondChild(pnode->pnodeRest, context);
             if (!ContinueWalk(result))  return result;
         }
 
         result = WalkNode(pnode, context);
-        if (ContinueWalk(result)) result = WalkNthChild(pnode, pnode->AsParseNodeFnc()->pnodeBody, context);
+        if (ContinueWalk(result)) result = WalkNthChild(pnode, pnode->pnodeBody, context);
         return result;
     }
 
-    ResultType WalkProg(ParseNode *pnode, Context context)
+    ResultType WalkProg(ParseNodeProg *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result)) result = WalkList(pnode, pnode->AsParseNodeFnc()->pnodeBody, context);
+        if (ContinueWalk(result)) result = WalkList(pnode, pnode->pnodeBody, context);
         return result;
     }
 
-    ResultType WalkFor(ParseNode *pnode, Context context)
+    ResultType WalkFor(ParseNodeFor *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeFor()->pnodeInit, context);
+        ResultType result = WalkFirstChild(pnode->pnodeInit, context);
         if (ContinueWalk(result))
         {
-            result = WalkNthChild(pnode, pnode->AsParseNodeFor()->pnodeCond, context);
+            result = WalkNthChild(pnode, pnode->pnodeCond, context);
             if (ContinueWalk(result))
             {
-                result = WalkNthChild(pnode, pnode->AsParseNodeFor()->pnodeIncr, context);
+                result = WalkNthChild(pnode, pnode->pnodeIncr, context);
                 if (ContinueWalk(result))
                 {
                     result = WalkNode(pnode, context);
                     if (ContinueWalk(result))
                     {
-                        result = WalkSecondChild(pnode->AsParseNodeFor()->pnodeBody, context);
+                        result = WalkSecondChild(pnode->pnodeBody, context);
                     }
                 }
             }
@@ -220,99 +219,99 @@ private:
         return result;
     }
 
-    ResultType WalkIf(ParseNode *pnode, Context context)
+    ResultType WalkIf(ParseNodeIf *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeIf()->pnodeCond, context);
+        ResultType result = WalkFirstChild(pnode->pnodeCond, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
             if (ContinueWalk(result))
             {
-                result = WalkSecondChild(pnode->AsParseNodeIf()->pnodeTrue, context);
-                if (ContinueWalk(result) && pnode->AsParseNodeIf()->pnodeFalse)
-                    result = WalkNthChild(pnode, pnode->AsParseNodeIf()->pnodeFalse, context);
+                result = WalkSecondChild(pnode->pnodeTrue, context);
+                if (ContinueWalk(result) && pnode->pnodeFalse)
+                    result = WalkNthChild(pnode, pnode->pnodeFalse, context);
             }
         }
         return result;
     }
 
-    ResultType WalkWhile(ParseNode *pnode, Context context)
+    ResultType WalkWhile(ParseNodeWhile *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeWhile()->pnodeCond, context);
+        ResultType result = WalkFirstChild(pnode->pnodeCond, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeWhile()->pnodeBody, context);
+            if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnodeBody, context);
         }
         return result;
     }
 
-    ResultType WalkDoWhile(ParseNode *pnode, Context context)
+    ResultType WalkDoWhile(ParseNodeWhile *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeWhile()->pnodeBody, context);
+        ResultType result = WalkFirstChild(pnode->pnodeBody, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
             if (ContinueWalk(result))
             {
-                result = WalkSecondChild(pnode->AsParseNodeWhile()->pnodeCond, context);
+                result = WalkSecondChild(pnode->pnodeCond, context);
             }
         }
         return result;
     }
 
-    ResultType WalkForInOrForOf(ParseNode *pnode, Context context)
+    ResultType WalkForInOrForOf(ParseNodeForInOrForOf *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeForInOrForOf()->pnodeLval, context);
+        ResultType result = WalkFirstChild(pnode->pnodeLval, context);
         if (ContinueWalk(result))
         {
-            result = WalkNthChild(pnode, pnode->AsParseNodeForInOrForOf()->pnodeObj, context);
+            result = WalkNthChild(pnode, pnode->pnodeObj, context);
             if (ContinueWalk(result))
             {
                 result = WalkNode(pnode, context);
-                if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeForInOrForOf()->pnodeBody, context);
+                if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnodeBody, context);
             }
         }
         return result;
     }
 
-    ResultType WalkReturn(ParseNode *pnode, Context context)
+    ResultType WalkReturn(ParseNodeReturn *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result) && pnode->AsParseNodeReturn()->pnodeExpr) result = WalkFirstChild(pnode->AsParseNodeReturn()->pnodeExpr, context);
+        if (ContinueWalk(result) && pnode->pnodeExpr) result = WalkFirstChild(pnode->pnodeExpr, context);
         return result;
     }
 
-    ResultType WalkBlock(ParseNode *pnode, Context context)
+    ResultType WalkBlock(ParseNodeBlock *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result) && pnode->AsParseNodeBlock()->pnodeStmt)
-            result = WalkList(pnode, pnode->AsParseNodeBlock()->pnodeStmt, context);
+        if (ContinueWalk(result) && pnode->pnodeStmt)
+            result = WalkList(pnode, pnode->pnodeStmt, context);
         return result;
     }
 
-    ResultType WalkWith(ParseNode *pnode, Context context)
+    ResultType WalkWith(ParseNodeWith *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeWith()->pnodeObj, context);
+        ResultType result = WalkFirstChild(pnode->pnodeObj, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
             if (ContinueWalk(result))
             {
-                result = WalkSecondChild(pnode->AsParseNodeWith()->pnodeBody, context);
+                result = WalkSecondChild(pnode->pnodeBody, context);
             }
         }
         return result;
     }
 
-    ResultType WalkSwitch(ParseNode *pnode, Context context)
+    ResultType WalkSwitch(ParseNodeSwitch *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeSwitch()->pnodeVal, context);
+        ResultType result = WalkFirstChild(pnode->pnodeVal, context);
         if (ContinueWalk(result))
         {
-            for (ParseNode** caseNode = &(pnode->AsParseNodeSwitch()->pnodeCases); *caseNode != nullptr; caseNode = &((*caseNode)->AsParseNodeCase()->pnodeNext))
+            for (ParseNodeCase** caseNode = &(pnode->pnodeCases); *caseNode != nullptr; caseNode = &((*caseNode)->pnodeNext))
             {
-                result = *caseNode == pnode->AsParseNodeSwitch()->pnodeCases ? WalkFirstChild(*caseNode, context) : WalkNthChild(pnode, *caseNode, context);
+                result = *caseNode == pnode->pnodeCases ? WalkFirstChild(*caseNode, context) : WalkNthChild(pnode, *caseNode, context);
                 if (!ContinueWalk(result)) return result;
             }
             result = WalkNode(pnode, context);
@@ -320,80 +319,80 @@ private:
         return result;
     }
 
-    ResultType WalkCase(ParseNode *pnode, Context context)
+    ResultType WalkCase(ParseNodeCase *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeCase()->pnodeExpr, context);
+        ResultType result = WalkFirstChild(pnode->pnodeExpr, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeCase()->pnodeBody, context);
+            if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnodeBody, context);
         }
         return result;
     }
 
-    ResultType WalkTryFinally(ParseNode *pnode, Context context)
+    ResultType WalkTryFinally(ParseNodeTryFinally *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeTryFinally()->pnodeTry, context);
+        ResultType result = WalkFirstChild(pnode->pnodeTry, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeTryFinally()->pnodeFinally, context);
+            if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnodeFinally, context);
         }
         return result;
     }
 
-    ResultType WalkFinally(ParseNode *pnode, Context context)
+    ResultType WalkFinally(ParseNodeFinally *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result)) result = WalkFirstChild(pnode->AsParseNodeFinally()->pnodeBody, context);
+        if (ContinueWalk(result)) result = WalkFirstChild(pnode->pnodeBody, context);
         return result;
     }
 
-    ResultType WalkCatch(ParseNode *pnode, Context context)
+    ResultType WalkCatch(ParseNodeCatch *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeCatch()->pnodeParam, context);
+        ResultType result = WalkFirstChild(pnode->pnodeParam, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeCatch()->pnodeBody, context);
+            if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnodeBody, context);
         }
         return result;
     }
 
-    ResultType WalkTryCatch(ParseNode *pnode, Context context)
+    ResultType WalkTryCatch(ParseNodeTryCatch *pnode, Context context)
     {
-        ResultType result = WalkFirstChild(pnode->AsParseNodeTryCatch()->pnodeTry, context);
+        ResultType result = WalkFirstChild(pnode->pnodeTry, context);
         if (ContinueWalk(result))
         {
             result = WalkNode(pnode, context);
-            if (ContinueWalk(result)) result = WalkSecondChild(pnode->AsParseNodeTryCatch()->pnodeCatch, context);
+            if (ContinueWalk(result)) result = WalkSecondChild(pnode->pnodeCatch, context);
         }
         return result;
     }
 
-    ResultType WalkTry(ParseNode *pnode, Context context)
+    ResultType WalkTry(ParseNodeTry *pnode, Context context)
     {
         ResultType result = WalkNode(pnode, context);
-        if (ContinueWalk(result)) result = WalkFirstChild(pnode->AsParseNodeTry()->pnodeBody, context);
+        if (ContinueWalk(result)) result = WalkFirstChild(pnode->pnodeBody, context);
         return result;
     }
 
-    ResultType WalkClass(ParseNode *pnode, Context context)
+    ResultType WalkClass(ParseNodeClass *pnode, Context context)
     {
         // First walk the class node itself
         ResultType result = WalkNode(pnode, context);
         if (!ContinueWalk(result)) return result;
         // Walk extends expr
-        result = WalkFirstChild(pnode->AsParseNodeClass()->pnodeExtends, context);
+        result = WalkFirstChild(pnode->pnodeExtends, context);
         if (!ContinueWalk(result)) return result;
         // Walk the constructor
-        result = WalkNthChild(pnode, pnode->AsParseNodeClass()->pnodeConstructor, context);
+        result = WalkNthChild(pnode, pnode->pnodeConstructor, context);
         if (!ContinueWalk(result)) return result;
         // Walk all non-static members
-        result = WalkList(pnode, pnode->AsParseNodeClass()->pnodeMembers, context);
+        result = WalkList(pnode, pnode->pnodeMembers, context);
         if (!ContinueWalk(result)) return result;
         // Walk all static members
-        result = WalkList(pnode, pnode->AsParseNodeClass()->pnodeStaticMembers, context);
+        result = WalkList(pnode, pnode->pnodeStaticMembers, context);
         return result;
     }
 
@@ -410,19 +409,19 @@ private:
         //PTNODE(knopDecPost    , "-- post"    ,Dec     ,Uni  ,fnopUni|fnopAsg)
         case knopIncPost:
         case knopDecPost:
-            return WalkPostUnary(pnode, context);
+            return WalkPostUnary(pnode->AsParseNodeUni(), context);
 
         // Call and call like
         //PTNODE(knopCall       , "()"        ,None    ,Bin  ,fnopBin)
         //PTNODE(knopNew        , "new"        ,None    ,Bin  ,fnopBin)
         case knopCall:
         case knopNew:
-            return WalkCall(pnode, context);
+            return WalkCall(pnode->AsParseNodeCall(), context);
 
         // Ternary operator
         //PTNODE(knopQmark      , "?"            ,None    ,Tri  ,fnopBin)
         case knopQmark:
-            return WalkTernary(pnode, context);
+            return WalkTernary(pnode->AsParseNodeTri(), context);
 
         // General nodes.
         //PTNODE(knopList       , "<list>"    ,None    ,Bin  ,fnopNone)
@@ -434,88 +433,88 @@ private:
         case knopConstDecl:
         case knopLetDecl:
         case knopTemp:
-            return WalkVar(pnode, context);
+            return WalkVar(pnode->AsParseNodeVar(), context);
 
         //PTNODE(knopFncDecl    , "fncDcl"    ,None    ,Fnc  ,fnopLeaf)
         case knopFncDecl:
-            return WalkFnc(pnode, context);
+            return WalkFnc(pnode->AsParseNodeFnc(), context);
 
         //PTNODE(knopProg       , "program"    ,None    ,Fnc  ,fnopNone)
         case knopProg:
-            return WalkProg(pnode, context);
+            return WalkProg(pnode->AsParseNodeProg(), context);
 
         //PTNODE(knopFor        , "for"        ,None    ,For  ,fnopBreak|fnopContinue)
         case knopFor:
-            return WalkFor(pnode, context);
+            return WalkFor(pnode->AsParseNodeFor(), context);
 
         //PTNODE(knopIf         , "if"        ,None    ,If   ,fnopNone)
         case knopIf:
-            return WalkIf(pnode, context);
+            return WalkIf(pnode->AsParseNodeIf(), context);
 
         //PTNODE(knopWhile      , "while"        ,None    ,While,fnopBreak|fnopContinue)
         case knopWhile:
-            return WalkWhile(pnode, context);
+            return WalkWhile(pnode->AsParseNodeWhile(), context);
 
          //PTNODE(knopDoWhile    , "do-while"    ,None    ,While,fnopBreak|fnopContinue)
         case knopDoWhile:
-            return WalkDoWhile(pnode, context);
+            return WalkDoWhile(pnode->AsParseNodeWhile(), context);
 
         //PTNODE(knopForIn      , "for in"    ,None    ,ForIn,fnopBreak|fnopContinue|fnopCleanup)
         case knopForIn:
-            return WalkForInOrForOf(pnode, context);
+            return WalkForInOrForOf(pnode->AsParseNodeForInOrForOf(), context);
 
         case knopForOf:
-            return WalkForInOrForOf(pnode, context);
+            return WalkForInOrForOf(pnode->AsParseNodeForInOrForOf(), context);
 
         //PTNODE(knopReturn     , "return"    ,None    ,Uni  ,fnopNone)
         case knopReturn:
-            return WalkReturn(pnode, context);
+            return WalkReturn(pnode->AsParseNodeReturn(), context);
 
         //PTNODE(knopBlock      , "{}"        ,None    ,Block,fnopNone)
         case knopBlock:
-            return WalkBlock(pnode, context);
+            return WalkBlock(pnode->AsParseNodeBlock(), context);
 
         //PTNODE(knopWith       , "with"        ,None    ,With ,fnopCleanup)
         case knopWith:
-            return WalkWith(pnode, context);
+            return WalkWith(pnode->AsParseNodeWith(), context);
 
         //PTNODE(knopSwitch     , "switch"    ,None    ,Switch,fnopBreak)
         case knopSwitch:
-            return WalkSwitch(pnode, context);
+            return WalkSwitch(pnode->AsParseNodeSwitch(), context);
 
         //PTNODE(knopCase       , "case"        ,None    ,Case ,fnopNone)
         case knopCase:
-            return WalkCase(pnode, context);
+            return WalkCase(pnode->AsParseNodeCase(), context);
 
         //PTNODE(knopTryFinally,"try-finally",None,TryFinally,fnopCleanup)
         case knopTryFinally:
-            return WalkTryFinally(pnode, context);
+            return WalkTryFinally(pnode->AsParseNodeTryFinally(), context);
 
        case knopFinally:
-           return WalkFinally(pnode, context);
+           return WalkFinally(pnode->AsParseNodeFinally(), context);
 
         //PTNODE(knopCatch      , "catch"     ,None    ,Catch,fnopNone)
         case knopCatch:
-            return WalkCatch(pnode, context);
+            return WalkCatch(pnode->AsParseNodeCatch(), context);
 
         //PTNODE(knopTryCatch      , "try-catch" ,None    ,TryCatch  ,fnopCleanup)
         case knopTryCatch:
-            return WalkTryCatch(pnode, context);
+            return WalkTryCatch(pnode->AsParseNodeTryCatch(), context);
 
         //PTNODE(knopTry        , "try"       ,None    ,Try  ,fnopCleanup)
         case knopTry:
-            return WalkTry(pnode, context);
+            return WalkTry(pnode->AsParseNodeTry(), context);
 
         //PTNODE(knopThrow      , "throw"     ,None    ,Uni  ,fnopNone)
         case knopThrow:
-            return WalkPostUnary(pnode, context);
+            return WalkPostUnary(pnode->AsParseNodeUni(), context);
 
         case knopStrTemplate:
-            return WalkStringTemplate(pnode, context);
+            return WalkStringTemplate(pnode->AsParseNodeStrTemplate(), context);
 
         //PTNODE(knopClassDecl  , "classDecl" ,None    ,Class       ,fnopLeaf)
         case knopClassDecl:
-            return WalkClass(pnode, context);
+            return WalkClass(pnode->AsParseNodeClass(), context);
 
         case knopExportDefault:
             return Walk(pnode->AsParseNodeExportDefault()->pnodeExpr, context);
@@ -530,12 +529,12 @@ private:
             }
             else if (fnop & fnopBin)
             {
-                return WalkBinary(pnode, context);
+                return WalkBinary(pnode->AsParseNodeBin(), context);
             }
             else if (fnop & fnopUni)
             {
                 // Prefix unary operators.
-                return WalkPreUnary(pnode, context);
+                return WalkPreUnary(pnode->AsParseNodeUni(), context);
             }
 
             // Some node types are both fnopNotExprStmt and something else. Try the above cases first and fall back to this one.

+ 48 - 7
lib/Parser/ptree.cpp

@@ -9,12 +9,10 @@ ParseNode::ParseNode(OpCode nop, charcount_t ichMin, charcount_t ichLim)
     this->nop = nop;
     this->grfpn = PNodeFlags::fpnNone;
     this->location = Js::Constants::NoRegister;
-    this->emitLabels = false;
     this->isUsed = true;
     this->notEscapedUse = false;
     this->isInList = false;
     this->isCallApplyTargetLoad = false;
-    this->isSpecialName = false;
     this->ichMin = ichMin;
     this->ichLim = ichLim;
 }
@@ -69,7 +67,7 @@ ParseNodePid * ParseNode::AsParseNodePid()
 
 ParseNodeSpecialName * ParseNode::AsParseNodeSpecialName()
 {
-    Assert(this->nop == knopName && this->isSpecialName);
+    Assert(this->nop == knopName && this->AsParseNodePid()->IsSpecialName());
     return reinterpret_cast<ParseNodeSpecialName *>(this);
 }
 
@@ -88,7 +86,7 @@ ParseNodeStrTemplate * ParseNode::AsParseNodeStrTemplate()
 ParseNodeSuperReference * ParseNode::AsParseNodeSuperReference()
 {
     Assert(this->nop == knopDot || this->nop == knopIndex);
-    Assert(this->AsParseNodeBin()->pnode1 && this->AsParseNodeBin()->pnode1->isSpecialName && this->AsParseNodeBin()->pnode1->AsParseNodeSpecialName()->isSuper);
+    Assert(this->AsParseNodeBin()->pnode1 && this->AsParseNodeBin()->pnode1->AsParseNodeSpecialName()->isSuper);
     return reinterpret_cast<ParseNodeSuperReference*>(this);
 }
 
@@ -274,6 +272,11 @@ ParseNodePtr ParseNode::GetFormalNext()
     return pnodeNext;
 }
 
+bool ParseNode::IsUserIdentifier()
+{
+    return this->nop == knopName && !this->AsParseNodePid()->IsSpecialName();
+}
+
 ParseNodeUni::ParseNodeUni(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1)
     : ParseNode(nop, ichMin, ichLim)
 {
@@ -283,7 +286,6 @@ 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)
 {
-    this->pnodeNext = nullptr;
     this->pnode1 = pnode1;
     this->pnode2 = pnode2;
 
@@ -330,6 +332,7 @@ ParseNodePid::ParseNodePid(OpCode nop, charcount_t ichMin, charcount_t ichLim, I
     this->pid = pid;
     this->sym = nullptr;
     this->symRef = nullptr;
+    this->isSpecialName = false;
 }
 
 ParseNodeVar::ParseNodeVar(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr name)
@@ -354,6 +357,42 @@ ParseNodeArrLit::ParseNodeArrLit(OpCode nop, charcount_t ichMin, charcount_t ich
 ParseNodeFnc::ParseNodeFnc(OpCode nop, charcount_t ichMin, charcount_t ichLim)
     : ParseNode(nop, ichMin, ichLim)
 {
+    this->ClearFlags();     // Initialize fncFlags, canBeDeferred and isBodyAndParamScopeMerged
+    this->SetDeclaration(false);
+    this->pnodeNext = nullptr;
+    this->pnodeName = nullptr;
+    this->pid = nullptr;
+    this->hint = nullptr;
+    this->hintOffset = 0;
+    this->hintLength = 0;
+    this->isNameIdentifierRef = true;
+    this->nestedFuncEscapes = false;
+    this->pnodeScopes = nullptr;
+    this->pnodeBodyScope = nullptr;
+    this->pnodeParams = nullptr;
+    this->pnodeVars = nullptr;
+    this->pnodeBody = nullptr;
+    this->pnodeRest = nullptr;
+    
+    this->funcInfo = nullptr;
+    this->scope = nullptr;
+    this->nestedCount = 0;
+    this->nestedIndex = (uint)-1;
+    this->firstDefaultArg = 0;
+
+    this->astSize = 0;
+    this->cbMin = 0;
+    this->cbLim = 0;
+    this->lineNumber = 0;
+    this->columnNumber = 0;
+    this->functionId = 0;
+#if DBG
+    this->deferredParseNextFunctionId = Js::Constants::NoFunctionId;
+#endif
+    this->pRestorePoint = nullptr;
+    this->deferredStub = nullptr;
+
+    
 }
 
 ParseNodeClass::ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim)
@@ -374,6 +413,8 @@ ParseNodeStrTemplate::ParseNodeStrTemplate(OpCode nop, charcount_t ichMin, charc
 ParseNodeProg::ParseNodeProg(OpCode nop, charcount_t ichMin, charcount_t ichLim)
     : ParseNodeFnc(nop, ichMin, ichLim)
 {
+    this->pnodeLastValStmt = nullptr;
+    this->m_UsesArgumentsAtGlobal = false;
 }
 
 ParseNodeModule::ParseNodeModule(OpCode nop, charcount_t ichMin, charcount_t ichLim)
@@ -398,7 +439,7 @@ ParseNodeCall::ParseNodeCall(OpCode nop, charcount_t ichMin, charcount_t ichLim,
 ParseNodeStmt::ParseNodeStmt(OpCode nop, charcount_t ichMin, charcount_t ichLim)
     : ParseNode(nop, ichMin, ichLim)
 {
-
+    this->emitLabels = false;
 }
 
 ParseNodeBlock::ParseNodeBlock(charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType)
@@ -506,7 +547,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)
 {
-    this->isSpecialName = true;
+    this->SetIsSpecialName();
     this->isThis = false;
     this->isSuper = false;
 }

+ 48 - 40
lib/Parser/ptree.h

@@ -206,15 +206,9 @@ public:
     bool CanFlattenConcatExpr() const { return !!(this->grfpn & PNodeFlags::fpnCanFlattenConcatExpr); }
 
     bool IsCallApplyTargetLoad() { return isCallApplyTargetLoad; }
-    void SetIsCallApplyTargetLoad() { isCallApplyTargetLoad = true; }
+    void SetIsCallApplyTargetLoad() { isCallApplyTargetLoad = true; }    
 
-    bool IsSpecialName() { return isSpecialName; }
-    void SetIsSpecialName() { isSpecialName = true; }
-
-    bool IsUserIdentifier() const
-    {
-        return this->nop == knopName && !this->isSpecialName;
-    }
+    bool IsUserIdentifier();
 
     bool IsVarLetOrConst() const
     {
@@ -231,20 +225,27 @@ public:
 #if DBG_DUMP
     void Dump();
 #endif
+
 public:
     static const uint mpnopgrfnop[knopLim];
 
     OpCode nop;
+
+    bool isUsed : 1;                // indicates whether an expression such as x++ is used
+
+private:
+    bool isInList : 1;
+    // Use by byte code generator
+    bool notEscapedUse : 1;         // Currently, only used by child of knopComma
+    bool isCallApplyTargetLoad : 1;
+
+public:
     ushort grfpn;
+
     charcount_t ichMin;         // start offset into the original source buffer
     charcount_t ichLim;         // end offset into the original source buffer
     Js::RegSlot location;
-    bool isUsed;                // indicates whether an expression such as x++ is used
-    bool emitLabels;
-    bool notEscapedUse;         // Use by byte code generator.  Currently, only used by child of knopComma
-    bool isInList;
-    bool isCallApplyTargetLoad;
-    bool isSpecialName;         // indicates a PnPid (knopName) is a special name like 'this' or 'super'
+
 #ifdef EDIT_AND_CONTINUE
     ParseNodePtr parent;
 #endif
@@ -268,7 +269,6 @@ class ParseNodeBin : public ParseNode
 public:
     ParseNodeBin(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
 
-    ParseNodePtr pnodeNext;
     ParseNodePtr pnode1;
     ParseNodePtr pnode2;
 
@@ -281,7 +281,6 @@ class ParseNodeTri : public ParseNode
 public:
     ParseNodeTri(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
-    ParseNodePtr pnodeNext;
     ParseNodePtr pnode1;
     ParseNodePtr pnode2;
     ParseNodePtr pnode3;
@@ -339,7 +338,15 @@ public:
     Symbol **GetSymRef() const { return symRef; }
     Js::PropertyId PropertyIdFromNameNode() const;
 
+    bool IsSpecialName() { return isSpecialName; }
+
     DISABLE_SELF_CAST(ParseNodePid);
+
+protected:
+    void SetIsSpecialName() { isSpecialName = true; }
+
+private:
+    bool isSpecialName;         // indicates a PnPid (knopName) is a special name like 'this' or 'super'
 };
 
 // variable declaration
@@ -439,8 +446,8 @@ public:
     uint32 hintOffset;
     bool  isNameIdentifierRef;
     bool  nestedFuncEscapes;
-    ParseNodePtr pnodeScopes;
-    ParseNodePtr pnodeBodyScope;
+    ParseNodeBlock * pnodeScopes;
+    ParseNodeBlock * pnodeBodyScope;
     ParseNodePtr pnodeParams;
     ParseNodePtr pnodeVars;
     ParseNodePtr pnodeBody;
@@ -450,7 +457,7 @@ public:
     Scope *scope;
 
     uint nestedCount; // Nested function count (valid until children have been processed)
-    uint nestedIndex; // Index within the parent function
+    uint nestedIndex; // Index within the parent function (Used by ByteCodeGenerator)
 
     uint16 firstDefaultArg; // Position of the first default argument, if any
 
@@ -610,10 +617,10 @@ public:
     template<typename Fn>
     void MapContainerScopes(Fn fn)
     {
-        fn(this->pnodeScopes->AsParseNodeBlock()->pnodeScopes);
+        fn(this->pnodeScopes->pnodeScopes);
         if (this->pnodeBodyScope != nullptr)
         {
-            fn(this->pnodeBodyScope->AsParseNodeBlock()->pnodeScopes);
+            fn(this->pnodeBodyScope->pnodeScopes);
         }
     }
 
@@ -626,9 +633,9 @@ class ParseNodeClass : public ParseNode
 public:
     ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
-    ParseNodePtr pnodeName;
-    ParseNodePtr pnodeDeclName;
-    ParseNodePtr pnodeBlock;
+    ParseNodeVar * pnodeName;
+    ParseNodeVar * pnodeDeclName;
+    ParseNodeBlock * pnodeBlock;
     ParseNodePtr pnodeConstructor;
     ParseNodePtr pnodeMembers;
     ParseNodePtr pnodeStaticMembers;
@@ -674,7 +681,7 @@ class ParseNodeProg : public ParseNodeFnc
 public:
     ParseNodeProg(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
-    ParseNodePtr pnodeLastValStmt;
+    ParseNodePtr pnodeLastValStmt;  // Used by ByteCodeGenerator
     bool m_UsesArgumentsAtGlobal;
 
     DISABLE_SELF_CAST(ParseNodeProg);
@@ -701,7 +708,6 @@ class ParseNodeCall : public ParseNode
 public:
     ParseNodeCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNodePtr pnodeTarget, ParseNodePtr pnodeArgs);
 
-    ParseNodePtr pnodeNext;
     ParseNodePtr pnodeTarget;
     ParseNodePtr pnodeArgs;
     uint16 argCount;
@@ -730,6 +736,8 @@ public:
     Js::ByteCodeLabel breakLabel;
     Js::ByteCodeLabel continueLabel;
 
+    bool emitLabels;
+
     DISABLE_SELF_CAST(ParseNodeStmt);
 };
 
@@ -746,7 +754,7 @@ public:
     ParseNodePtr pnodeNext;
     Scope        *scope;
 
-    ParseNodePtr enclosingBlock;
+    ParseNodeBlock * enclosingBlock;
     int blockId;
     PnodeBlockType blockType:2;
     BYTE         callsEval:1;
@@ -758,8 +766,8 @@ public:
     void SetChildCallsEval(bool does) { childCallsEval = does; }
     bool GetChildCallsEval() const { return childCallsEval; }
 
-    void SetEnclosingBlock(ParseNodePtr pnode) { enclosingBlock = pnode; }
-    ParseNodePtr GetEnclosingBlock() const { return enclosingBlock; }
+    void SetEnclosingBlock(ParseNodeBlock * pnode) { enclosingBlock = pnode; }
+    ParseNodeBlock * GetEnclosingBlock() const { return enclosingBlock; }
 
     bool HasBlockScopedContent() const;
 
@@ -772,7 +780,7 @@ class ParseNodeJump : public ParseNodeStmt
 public:
     ParseNodeJump(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
-    ParseNodePtr pnodeTarget;
+    ParseNodeStmt * pnodeTarget;
     bool hasExplicitTarget;
 
     DISABLE_SELF_CAST(ParseNodeJump);
@@ -853,7 +861,7 @@ public:
     ParseNodePtr pnodeObj;
     ParseNodePtr pnodeBody;
     ParseNodePtr pnodeLval;
-    ParseNodePtr pnodeBlock;
+    ParseNodeBlock * pnodeBlock;
     Js::RegSlot itemLocation;
 
     DISABLE_SELF_CAST(ParseNodeForInOrForOf);
@@ -869,8 +877,8 @@ public:
     ParseNodePtr pnodeBody;
     ParseNodePtr pnodeInit;
     ParseNodePtr pnodeIncr;
-    ParseNodePtr pnodeBlock;
-    ParseNodePtr pnodeInverted;
+    ParseNodeBlock * pnodeBlock;
+    ParseNodeFor * pnodeInverted;
 
     DISABLE_SELF_CAST(ParseNodeFor);
 };
@@ -882,8 +890,8 @@ public:
     ParseNodeSwitch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
     ParseNodePtr pnodeVal;
-    ParseNodePtr pnodeCases;
-    ParseNodePtr pnodeDefault;
+    ParseNodeCase * pnodeCases;
+    ParseNodeCase * pnodeDefault;
     ParseNodeBlock * pnodeBlock;
 
     DISABLE_SELF_CAST(ParseNodeSwitch);
@@ -895,9 +903,9 @@ class ParseNodeCase : public ParseNodeStmt
 public:
     ParseNodeCase(OpCode nop, charcount_t ichMin, charcount_t ichLim);
 
-    ParseNodePtr pnodeNext;
+    ParseNodeCase * pnodeNext;
     ParseNodePtr pnodeExpr; // nullptr for default
-    ParseNodePtr pnodeBody;
+    ParseNodeBlock * pnodeBody;
     Js::ByteCodeLabel labelCase;
 
 
@@ -994,7 +1002,7 @@ class ParseNodeSuperReference : public ParseNodeBin
 public:
     ParseNodeSuperReference(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
 
-    ParseNodePtr pnodeThis;
+    ParseNodeSpecialName * pnodeThis;
 
     DISABLE_SELF_CAST(ParseNodeSuperReference);
 };
@@ -1005,8 +1013,8 @@ class ParseNodeSuperCall : public ParseNodeCall
 public:
     ParseNodeSuperCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnodeTarget, ParseNode * pnodeArgs);
 
-    ParseNodePtr pnodeThis;
-    ParseNodePtr pnodeNewTarget;
+    ParseNodeSpecialName * pnodeThis;
+    ParseNodeSpecialName * pnodeNewTarget;
 
     DISABLE_SELF_CAST(ParseNodeSuperCall);
 };

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


+ 67 - 65
lib/Runtime/ByteCode/ByteCodeGenerator.cpp

@@ -6,8 +6,8 @@
 #include "FormalsUtil.h"
 #include "Library/StackScriptFunction.h"
 
-void PreVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator);
-void PostVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator);
+void PreVisitBlock(ParseNodeBlock *pnodeBlock, ByteCodeGenerator *byteCodeGenerator);
+void PostVisitBlock(ParseNodeBlock *pnodeBlock, ByteCodeGenerator *byteCodeGenerator);
 
 bool IsCallOfConstants(ParseNode *pnode)
 {
@@ -81,19 +81,19 @@ void VisitWithStmt(ParseNode *pnode, Js::RegSlot loc, ByteCodeGenerator* byteCod
     byteCodeGenerator->PopScope();
 }
 
-bool BlockHasOwnScope(ParseNode* pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
+bool BlockHasOwnScope(ParseNodeBlock* pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
 {
     Assert(pnodeBlock->nop == knopBlock);
-    return pnodeBlock->AsParseNodeBlock()->scope != nullptr &&
+    return pnodeBlock->scope != nullptr &&
         (!(pnodeBlock->grfpn & fpnSyntheticNode) ||
-            (pnodeBlock->AsParseNodeBlock()->blockType == PnodeBlockType::Global && byteCodeGenerator->IsEvalWithNoParentScopeInfo()));
+            (pnodeBlock->blockType == PnodeBlockType::Global && byteCodeGenerator->IsEvalWithNoParentScopeInfo()));
 }
 
-void BeginVisitBlock(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
+void BeginVisitBlock(ParseNodeBlock *pnode, ByteCodeGenerator *byteCodeGenerator)
 {
     if (BlockHasOwnScope(pnode, byteCodeGenerator))
     {
-        Scope *scope = pnode->AsParseNodeBlock()->scope;
+        Scope *scope = pnode->scope;
         FuncInfo *func = scope->GetFunc();
 
         if (scope->IsInnerScope())
@@ -104,15 +104,15 @@ void BeginVisitBlock(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
         }
 
         byteCodeGenerator->PushBlock(pnode);
-        byteCodeGenerator->PushScope(pnode->AsParseNodeBlock()->scope);
+        byteCodeGenerator->PushScope(pnode->scope);
     }
 }
 
-void EndVisitBlock(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
+void EndVisitBlock(ParseNodeBlock *pnode, ByteCodeGenerator *byteCodeGenerator)
 {
     if (BlockHasOwnScope(pnode, byteCodeGenerator))
     {
-        Scope *scope = pnode->AsParseNodeBlock()->scope;
+        Scope *scope = pnode->scope;
         FuncInfo *func = scope->GetFunc();
 
         if (!byteCodeGenerator->IsInDebugMode() &&
@@ -389,15 +389,16 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
     // PTNODE(knopBlock      , "{}"        ,None    ,Block,fnopNone)
     case knopBlock:
     {
-        if (pnode->AsParseNodeBlock()->pnodeStmt != nullptr)
+        ParseNodeBlock * pnodeBlock = pnode->AsParseNodeBlock();
+        if (pnodeBlock->pnodeStmt != nullptr)
         {
-            BeginVisitBlock(pnode, byteCodeGenerator);
-            pnode->AsParseNodeBlock()->pnodeLastValStmt = VisitBlock(pnode->AsParseNodeBlock()->pnodeStmt, byteCodeGenerator, prefix, postfix, pnode);
-            EndVisitBlock(pnode, byteCodeGenerator);
+            BeginVisitBlock(pnodeBlock, byteCodeGenerator);
+            pnodeBlock->pnodeLastValStmt = VisitBlock(pnodeBlock->pnodeStmt, byteCodeGenerator, prefix, postfix, pnode);
+            EndVisitBlock(pnodeBlock, byteCodeGenerator);
         }
         else
         {
-            pnode->AsParseNodeBlock()->pnodeLastValStmt = nullptr;
+            pnodeBlock->pnodeLastValStmt = nullptr;
         }
         break;
     }
@@ -418,7 +419,7 @@ void Visit(ParseNode *pnode, ByteCodeGenerator* byteCodeGenerator, PrefixFn pref
     case knopSwitch:
         Visit(pnode->AsParseNodeSwitch()->pnodeVal, byteCodeGenerator, prefix, postfix);
         BeginVisitBlock(pnode->AsParseNodeSwitch()->pnodeBlock, byteCodeGenerator);
-        for (ParseNode *pnodeT = pnode->AsParseNodeSwitch()->pnodeCases; nullptr != pnodeT; pnodeT = pnodeT->AsParseNodeCase()->pnodeNext)
+        for (ParseNodeCase *pnodeT = pnode->AsParseNodeSwitch()->pnodeCases; nullptr != pnodeT; pnodeT = pnodeT->pnodeNext)
         {
             Visit(pnodeT, byteCodeGenerator, prefix, postfix, pnode);
         }
@@ -651,12 +652,12 @@ bool MustProduceValue(ParseNode *pnode, const Js::ScriptContext *const scriptCon
                     // Can't guarantee that any code is executed.
                 return false;
                 }
-                ParseNode *pnodeCase;
-                for (pnodeCase = pnode->AsParseNodeSwitch()->pnodeCases; pnodeCase; pnodeCase = pnodeCase->AsParseNodeCase()->pnodeNext)
+                ParseNodeCase *pnodeCase;
+                for (pnodeCase = pnode->AsParseNodeSwitch()->pnodeCases; pnodeCase; pnodeCase = pnodeCase->pnodeNext)
                 {
-                    if (pnodeCase->AsParseNodeCase()->pnodeBody == nullptr)
+                    if (pnodeCase->pnodeBody == nullptr)
                     {
-                        if (pnodeCase->AsParseNodeCase()->pnodeNext == nullptr)
+                        if (pnodeCase->pnodeNext == nullptr)
                         {
                             // Last case has no code to execute.
                         return false;
@@ -665,7 +666,7 @@ bool MustProduceValue(ParseNode *pnode, const Js::ScriptContext *const scriptCon
                     }
                     else
                     {
-                        if (!MustProduceValue(pnodeCase->AsParseNodeCase()->pnodeBody, scriptContext))
+                        if (!MustProduceValue(pnodeCase->pnodeBody, scriptContext))
                         {
                         return false;
                         }
@@ -762,13 +763,13 @@ bool ByteCodeGenerator::IsFalse(ParseNode* node)
 /* static */
 bool ByteCodeGenerator::IsThis(ParseNode* pnode)
 {
-    return pnode->nop == knopName && pnode->IsSpecialName() && pnode->AsParseNodeSpecialName()->isThis;
+    return pnode->nop == knopName && pnode->AsParseNodePid()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isThis;
 }
 
 /* static */
 bool ByteCodeGenerator::IsSuper(ParseNode* pnode)
 {
-    return pnode->nop == knopName && pnode->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper;
+    return pnode->nop == knopName && pnode->AsParseNodePid()->IsSpecialName() && pnode->AsParseNodeSpecialName()->isSuper;
 }
 
 bool ByteCodeGenerator::IsES6DestructuringEnabled() const
@@ -868,7 +869,7 @@ void ByteCodeGenerator::AssignRegister(Symbol *sym)
     }
 }
 
-void ByteCodeGenerator::AddTargetStmt(ParseNode *pnodeStmt)
+void ByteCodeGenerator::AddTargetStmt(ParseNodeStmt *pnodeStmt)
 {
     FuncInfo *top = funcInfoStack->Top();
     top->AddTargetStmt(pnodeStmt);
@@ -1430,15 +1431,15 @@ FuncInfo * ByteCodeGenerator::StartBindFunction(const char16 *name, uint nameLen
         }
     }
 
-    Scope *paramScope = pnodeFnc->pnodeScopes ? pnodeFnc->pnodeScopes->AsParseNodeBlock()->scope : nullptr;
-    Scope *bodyScope = pnodeFnc->pnodeBodyScope ? pnodeFnc->pnodeBodyScope->AsParseNodeBlock()->scope : nullptr;
+    Scope *paramScope = pnodeFnc->pnodeScopes ? pnodeFnc->pnodeScopes->scope : nullptr;
+    Scope *bodyScope = pnodeFnc->pnodeBodyScope ? pnodeFnc->pnodeBodyScope->scope : nullptr;
     Assert(paramScope != nullptr || !pnodeFnc->pnodeScopes);
     if (paramScope == nullptr)
     {
         paramScope = Anew(alloc, Scope, alloc, ScopeType_Parameter, true);
         if (pnodeFnc->pnodeScopes)
         {
-            pnodeFnc->pnodeScopes->AsParseNodeBlock()->scope = paramScope;
+            pnodeFnc->pnodeScopes->scope = paramScope;
         }
     }
     if (bodyScope == nullptr)
@@ -1446,7 +1447,7 @@ FuncInfo * ByteCodeGenerator::StartBindFunction(const char16 *name, uint nameLen
         bodyScope = Anew(alloc, Scope, alloc, ScopeType_FunctionBody, true);
         if (pnodeFnc->pnodeBodyScope)
         {
-            pnodeFnc->pnodeBodyScope->AsParseNodeBlock()->scope = bodyScope;
+            pnodeFnc->pnodeBodyScope->scope = bodyScope;
         }
     }
 
@@ -1604,15 +1605,15 @@ void ByteCodeGenerator::PopScope()
     currentScope = currentScope->GetEnclosingScope();
 }
 
-void ByteCodeGenerator::PushBlock(ParseNode *pnode)
+void ByteCodeGenerator::PushBlock(ParseNodeBlock *pnode)
 {
-    pnode->AsParseNodeBlock()->SetEnclosingBlock(currentBlock);
+    pnode->SetEnclosingBlock(currentBlock);
     currentBlock = pnode;
 }
 
 void ByteCodeGenerator::PopBlock()
 {
-    currentBlock = currentBlock->AsParseNodeBlock()->GetEnclosingBlock();
+    currentBlock = currentBlock->GetEnclosingBlock();
 }
 
 void ByteCodeGenerator::PushFuncInfo(char16 const * location, FuncInfo* funcInfo)
@@ -2979,11 +2980,11 @@ FuncInfo* PostVisitFunction(ParseNodeFnc* pnodeFnc, ByteCodeGenerator* byteCodeG
     if (top->GetCallsEval() || top->GetChildCallsEval())
     {
         parentFunc->SetChildCallsEval(true);
-        ParseNode *currentBlock = byteCodeGenerator->GetCurrentBlock();
+        ParseNodeBlock *currentBlock = byteCodeGenerator->GetCurrentBlock();
         if (currentBlock)
         {
             Assert(currentBlock->nop == knopBlock);
-            currentBlock->AsParseNodeBlock()->SetChildCallsEval(true);
+            currentBlock->SetChildCallsEval(true);
         }
         parentFunc->SetHasHeapArguments(true);
         setHasNonLocalReference = true;
@@ -3345,8 +3346,8 @@ void VisitNestedScopes(ParseNode* pnodeScopeList, ParseNode* pnodeParent, ByteCo
 
                     if (!funcInfo->IsBodyAndParamScopeMerged())
                     {
-                        Assert(pnodeFnc->pnodeBodyScope->AsParseNodeBlock()->scope);
-                        VisitNestedScopes(pnodeFnc->pnodeBodyScope->AsParseNodeBlock()->pnodeScopes, pnodeFnc, byteCodeGenerator, prefix, postfix, &i);
+                        Assert(pnodeFnc->pnodeBodyScope->scope);
+                        VisitNestedScopes(pnodeFnc->pnodeBodyScope->pnodeScopes, pnodeFnc, byteCodeGenerator, prefix, postfix, &i);
                     }
                 }
 
@@ -3404,12 +3405,13 @@ void VisitNestedScopes(ParseNode* pnodeScopeList, ParseNode* pnodeParent, ByteCo
 
         case knopBlock:
         {
-            PreVisitBlock(pnodeScope, byteCodeGenerator);
+            ParseNodeBlock * pnodeBlockScope = pnodeScope->AsParseNodeBlock();
+            PreVisitBlock(pnodeBlockScope, byteCodeGenerator);
             bool isMergedScope;
-            parentFuncInfo->OnStartVisitScope(pnodeScope->AsParseNodeBlock()->scope, &isMergedScope);
-            VisitNestedScopes(pnodeScope->AsParseNodeBlock()->pnodeScopes, pnodeParent, byteCodeGenerator, prefix, postfix, pIndex);
-            parentFuncInfo->OnEndVisitScope(pnodeScope->AsParseNodeBlock()->scope, isMergedScope);
-            PostVisitBlock(pnodeScope, byteCodeGenerator);
+            parentFuncInfo->OnStartVisitScope(pnodeBlockScope->scope, &isMergedScope);
+            VisitNestedScopes(pnodeBlockScope->pnodeScopes, pnodeParent, byteCodeGenerator, prefix, postfix, pIndex);
+            parentFuncInfo->OnEndVisitScope(pnodeBlockScope->scope, isMergedScope);
+            PostVisitBlock(pnodeBlockScope, byteCodeGenerator);
 
             pnodeScope = pnodeScope->AsParseNodeBlock()->pnodeNext;
             break;
@@ -3454,11 +3456,11 @@ void VisitNestedScopes(ParseNode* pnodeScopeList, ParseNode* pnodeParent, ByteCo
     }
 }
 
-void PreVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
+void PreVisitBlock(ParseNodeBlock *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
 {
-    if (!pnodeBlock->AsParseNodeBlock()->scope &&
-        !pnodeBlock->AsParseNodeBlock()->HasBlockScopedContent() &&
-        !pnodeBlock->AsParseNodeBlock()->GetCallsEval())
+    if (!pnodeBlock->scope &&
+        !pnodeBlock->HasBlockScopedContent() &&
+        !pnodeBlock->GetCallsEval())
     {
         // Do nothing here if the block doesn't declare anything or call eval (which may declare something).
         return;
@@ -3472,36 +3474,36 @@ void PreVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
     {
         isGlobalEvalBlockScope = true;
     }
-    Assert(!pnodeBlock->AsParseNodeBlock()->scope ||
-           isGlobalEvalBlockScope == (pnodeBlock->AsParseNodeBlock()->scope->GetScopeType() == ScopeType_GlobalEvalBlock));
+    Assert(!pnodeBlock->scope ||
+           isGlobalEvalBlockScope == (pnodeBlock->scope->GetScopeType() == ScopeType_GlobalEvalBlock));
 
     ArenaAllocator *alloc = byteCodeGenerator->GetAllocator();
     Scope *scope;
 
-    if ((pnodeBlock->AsParseNodeBlock()->blockType == PnodeBlockType::Global && !byteCodeGenerator->IsEvalWithNoParentScopeInfo()) || pnodeBlock->AsParseNodeBlock()->blockType == PnodeBlockType::Function)
+    if ((pnodeBlock->blockType == PnodeBlockType::Global && !byteCodeGenerator->IsEvalWithNoParentScopeInfo()) || pnodeBlock->blockType == PnodeBlockType::Function)
     {
         scope = byteCodeGenerator->GetCurrentScope();
 
-        if (pnodeBlock->AsParseNodeBlock()->blockType == PnodeBlockType::Function)
+        if (pnodeBlock->blockType == PnodeBlockType::Function)
         {
-            AnalysisAssert(pnodeBlock->AsParseNodeBlock()->scope);
-            if (pnodeBlock->AsParseNodeBlock()->scope->GetScopeType() == ScopeType_Parameter
+            AnalysisAssert(pnodeBlock->scope);
+            if (pnodeBlock->scope->GetScopeType() == ScopeType_Parameter
                 && scope->GetScopeType() == ScopeType_FunctionBody)
             {
                 scope = scope->GetEnclosingScope();
             }
         }
 
-        pnodeBlock->AsParseNodeBlock()->scope = scope;
+        pnodeBlock->scope = scope;
     }
     else if (!(pnodeBlock->grfpn & fpnSyntheticNode) || isGlobalEvalBlockScope)
     {
-        scope = pnodeBlock->AsParseNodeBlock()->scope;
+        scope = pnodeBlock->scope;
         if (!scope)
         {
             scope = Anew(alloc, Scope, alloc,
                          isGlobalEvalBlockScope? ScopeType_GlobalEvalBlock : ScopeType_Block, true);
-            pnodeBlock->AsParseNodeBlock()->scope = scope;
+            pnodeBlock->scope = scope;
         }
         scope->SetFunc(byteCodeGenerator->TopFuncInfo());
         // For now, prevent block scope from being merged with enclosing function scope.
@@ -3521,7 +3523,7 @@ void PreVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
         return;
     }
 
-    Assert(scope && scope == pnodeBlock->AsParseNodeBlock()->scope);
+    Assert(scope && scope == pnodeBlock->scope);
 
     bool isGlobalScope = (scope->GetEnclosingScope() == nullptr);
     Assert(!isGlobalScope || (pnodeBlock->grfpn & fpnSyntheticNode));
@@ -3530,7 +3532,7 @@ void PreVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
     // They should already declared in the global function's scope.
     if (!isGlobalEvalBlockScope && !isGlobalScope)
     {
-        AddFunctionsToScope(pnodeBlock->AsParseNodeBlock()->pnodeScopes, byteCodeGenerator);
+        AddFunctionsToScope(pnodeBlock->pnodeScopes, byteCodeGenerator);
     }
 
     // We can skip this check by not creating the GlobalEvalBlock above and in Parser::Parse for console eval but that seems to break couple of places
@@ -3564,16 +3566,16 @@ void PreVisitBlock(ParseNode *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
     byteCodeGenerator->IterateBlockScopedVariables(pnodeBlock, addSymbolToScope);
 }
 
-void PostVisitBlock(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
+void PostVisitBlock(ParseNodeBlock *pnodeBlock, ByteCodeGenerator *byteCodeGenerator)
 {
-    if (!BlockHasOwnScope(pnode, byteCodeGenerator))
+    if (!BlockHasOwnScope(pnodeBlock, byteCodeGenerator))
     {
         return;
     }
 
-    Scope *scope = pnode->AsParseNodeBlock()->scope;
+    Scope *scope = pnodeBlock->scope;
 
-    if (pnode->AsParseNodeBlock()->GetCallsEval() || pnode->AsParseNodeBlock()->GetChildCallsEval() || (byteCodeGenerator->GetFlags() & (fscrEval | fscrImplicitThis | fscrImplicitParents)))
+    if (pnodeBlock->GetCallsEval() || pnodeBlock->GetChildCallsEval() || (byteCodeGenerator->GetFlags() & (fscrEval | fscrImplicitThis | fscrImplicitParents)))
     {
         bool scopeIsEmpty = scope->IsEmpty();
         scope->SetIsObject();
@@ -3589,10 +3591,10 @@ void PostVisitBlock(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
     byteCodeGenerator->PopScope();
     byteCodeGenerator->PopBlock();
 
-    ParseNode *currentBlock = byteCodeGenerator->GetCurrentBlock();
-    if (currentBlock && (pnode->AsParseNodeBlock()->GetCallsEval() || pnode->AsParseNodeBlock()->GetChildCallsEval()))
+    ParseNodeBlock *currentBlock = byteCodeGenerator->GetCurrentBlock();
+    if (currentBlock && (pnodeBlock->GetCallsEval() || pnodeBlock->GetChildCallsEval()))
     {
-        currentBlock->AsParseNodeBlock()->SetChildCallsEval(true);
+        currentBlock->SetChildCallsEval(true);
     }
 }
 
@@ -3915,7 +3917,7 @@ ParseNode* ConstructInvertedStatement(ParseNode* stmt, ByteCodeGenerator* byteCo
         return cStmt;
 }
 
-ParseNode* ConstructInvertedLoop(ParseNode* innerLoop, ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo)
+ParseNodeFor* ConstructInvertedLoop(ParseNode* innerLoop, ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo)
 {
     ArenaAllocator* alloc = byteCodeGenerator->GetAllocator();
     ParseNodeFor * outerLoopC = Parser::StaticCreateNodeT<knopFor>(alloc);
@@ -4164,7 +4166,7 @@ bool InvertableBlock(ParseNode* block, Symbol* outerVar, ParseNode* innerLoop, P
 // side effects level, if any that guards the new AST (old AST will be
 // used if guard fails).
 // Should only be called with loopNode representing top-level statement.
-ParseNode* InvertLoop(ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo)
+ParseNodeFor* InvertLoop(ParseNode* outerLoop, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo)
 {
     if (byteCodeGenerator->GetScriptContext()->optimizationOverrides.GetSideEffects() != Js::SideEffects_None)
     {
@@ -4403,7 +4405,7 @@ void Bind(ParseNode *pnode, ByteCodeGenerator *byteCodeGenerator)
     case knopTryCatch:
         byteCodeGenerator->SetHasTry(true);
         byteCodeGenerator->TopFuncInfo()->byteCodeFunction->SetDontInline(true);
-        byteCodeGenerator->AddTargetStmt(pnode);
+        byteCodeGenerator->AddTargetStmt(pnode->AsParseNodeStmt());
         break;
     case knopAsg:
         BindReference(pnode, byteCodeGenerator);

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

@@ -16,7 +16,7 @@ private:
     uint32 flags;
     Js::PropertyRecordList* propertyRecords;
     SList<FuncInfo*> *funcInfoStack;
-    ParseNode *currentBlock;
+    ParseNodeBlock *currentBlock;
     ParseNode *currentTopStatement;
     Scope *currentScope;
     Scope *globalScope; // the global members will be in this scope
@@ -84,8 +84,8 @@ public:
 
     Scope *GetCurrentScope() const { return currentScope; }
 
-    void SetCurrentBlock(ParseNode *pnode) { currentBlock = pnode; }
-    ParseNode *GetCurrentBlock() const { return currentBlock; }
+    void SetCurrentBlock(ParseNodeBlock *pnode) { currentBlock = pnode; }
+    ParseNodeBlock *GetCurrentBlock() const { return currentBlock; }
 
     void SetCurrentTopStatement(ParseNode *pnode) { currentTopStatement = pnode; }
     ParseNode *GetCurrentTopStatement() const { return currentTopStatement; }
@@ -165,7 +165,7 @@ public:
     BOOL IsInLoop() const { return loopDepth > 0; }
     // TODO: per-function register assignment for env and global symbols
     void AssignRegister(Symbol *sym);
-    void AddTargetStmt(ParseNode *pnodeStmt);
+    void AddTargetStmt(ParseNodeStmt *pnodeStmt);
     Js::RegSlot AssignNullConstRegister();
     Js::RegSlot AssignUndefinedConstRegister();
     Js::RegSlot AssignTrueConstRegister();
@@ -247,14 +247,14 @@ public:
     void StartEmitWith(ParseNode *pnodeWith);
     void EndEmitWith(ParseNode *pnodeWith);
     void EnsureFncScopeSlots(ParseNode *pnode, FuncInfo *funcInfo);
-    void EnsureLetConstScopeSlots(ParseNode *pnodeBlock, FuncInfo *funcInfo);
+    void EnsureLetConstScopeSlots(ParseNodeBlock *pnodeBlock, FuncInfo *funcInfo);
     bool EnsureSymbolModuleSlots(Symbol* sym, FuncInfo* funcInfo);
     void EmitAssignmentToDefaultModuleExport(ParseNode* pnode, FuncInfo* funcInfo);
     void EmitModuleExportAccess(Symbol* sym, Js::OpCode opcode, Js::RegSlot location, FuncInfo* funcInfo);
 
     void PushScope(Scope *innerScope);
     void PopScope();
-    void PushBlock(ParseNode *pnode);
+    void PushBlock(ParseNodeBlock *pnode);
     void PopBlock();
 
     void PushFuncInfo(char16 const * location, FuncInfo* funcInfo);
@@ -266,7 +266,7 @@ public:
     Symbol *AddSymbolToFunctionScope(const char16 *key, int keyLength, ParseNode *varDecl, SymbolType symbolType);
     void FuncEscapes(Scope *scope);
     void EmitTopLevelStatement(ParseNode *stmt, FuncInfo *funcInfo, BOOL fReturnValue);
-    void EmitInvertedLoop(ParseNode* outerLoop,ParseNode* invertedLoop,FuncInfo* funcInfo);
+    void EmitInvertedLoop(ParseNodeLoop* outerLoop,ParseNodeFor* invertedLoop,FuncInfo* funcInfo);
     void DefineFunctions(FuncInfo *funcInfoParent);
     Js::RegSlot DefineOneFunction(ParseNodeFnc *pnodeFnc, FuncInfo *funcInfoParent, bool generateAssignment=true, Js::RegSlot regEnv = Js::Constants::NoRegister, Js::RegSlot frameDisplayTemp = Js::Constants::NoRegister);
     void DefineCachedFunctions(FuncInfo *funcInfoParent);
@@ -283,7 +283,7 @@ public:
     void LoadNewTargetObject(FuncInfo *funcInfo);
     void LoadSuperObject(FuncInfo *funcInfo);
     void LoadSuperConstructorObject(FuncInfo *funcInfo);
-    void EmitSuperCall(FuncInfo* funcInfo, ParseNode* pnode, BOOL fReturnValue);
+    void EmitSuperCall(FuncInfo* funcInfo, ParseNodeSuperCall * pnodeSuperCall, BOOL fReturnValue);
     void EmitClassConstructorEndCode(FuncInfo *funcInfo);
     void EmitBaseClassConstructorThisObject(FuncInfo *funcInfo);
 

+ 1 - 1
lib/Runtime/ByteCode/FuncInfo.cpp

@@ -173,7 +173,7 @@ Scope *
 FuncInfo::GetGlobalBlockScope() const
 {
     Assert(this->IsGlobalFunction());
-    Scope * scope = this->root->pnodeScopes->AsParseNodeBlock()->scope;
+    Scope * scope = this->root->pnodeScopes->scope;
     Assert(scope == nullptr || scope == this->GetBodyScope() || scope->GetEnclosingScope() == this->GetBodyScope());
     return scope;
 }

+ 3 - 3
lib/Runtime/ByteCode/FuncInfo.h

@@ -154,7 +154,7 @@ public:
     Scope *funcExprScope;
     ParseNodeFnc *root; // top-level AST for function
     Js::ParseableFunctionInfo* byteCodeFunction; // reference to generated bytecode function (could be defer parsed or actually parsed)
-    SList<ParseNode*> targetStatements; // statements that are targets of jumps (break or continue)
+    SList<ParseNodeStmt*> targetStatements; // statements that are targets of jumps (break or continue)
     Js::ByteCodeLabel singleExit;
     typedef SList<InlineCacheUnit> InlineCacheList;
     typedef JsUtil::BaseDictionary<Js::PropertyId, InlineCacheList*, ArenaAllocator, PowerOf2SizePolicy> InlineCacheIdMap;
@@ -468,11 +468,11 @@ public:
     BOOL IsBaseClassConstructor() const;
     BOOL IsDerivedClassConstructor() const;
 
-    void RemoveTargetStmt(ParseNode* pnodeStmt) {
+    void RemoveTargetStmt(ParseNodeStmt* pnodeStmt) {
         targetStatements.Remove(pnodeStmt);
     }
 
-    void AddTargetStmt(ParseNode *pnodeStmt) {
+    void AddTargetStmt(ParseNodeStmt *pnodeStmt) {
         targetStatements.Prepend(pnodeStmt);
     }
 

+ 8 - 8
lib/Runtime/ByteCode/Scope.cpp

@@ -77,11 +77,11 @@ void Scope::SetIsObject()
     }
 }
 
-void Scope::MergeParamAndBodyScopes(ParseNode *pnodeScope)
+void Scope::MergeParamAndBodyScopes(ParseNodeFnc *pnodeScope)
 {
-    Assert(pnodeScope->AsParseNodeFnc()->funcInfo);
-    Scope *paramScope = pnodeScope->AsParseNodeFnc()->pnodeScopes->AsParseNodeBlock()->scope;
-    Scope *bodyScope = pnodeScope->AsParseNodeFnc()->pnodeBodyScope->AsParseNodeBlock()->scope;
+    Assert(pnodeScope->funcInfo);
+    Scope *paramScope = pnodeScope->pnodeScopes->scope;
+    Scope *bodyScope = pnodeScope->pnodeBodyScope->scope;
 
     if (paramScope->Count() == 0)
     {
@@ -108,11 +108,11 @@ void Scope::MergeParamAndBodyScopes(ParseNode *pnodeScope)
     }
 }
 
-void Scope::RemoveParamScope(ParseNode *pnodeScope)
+void Scope::RemoveParamScope(ParseNodeFnc *pnodeScope)
 {
-    Assert(pnodeScope->AsParseNodeFnc()->funcInfo);
-    Scope *paramScope = pnodeScope->AsParseNodeFnc()->pnodeScopes->AsParseNodeBlock()->scope;
-    Scope *bodyScope = pnodeScope->AsParseNodeFnc()->pnodeBodyScope->AsParseNodeBlock()->scope;
+    Assert(pnodeScope->funcInfo);
+    Scope *paramScope = pnodeScope->pnodeScopes->scope;
+    Scope *bodyScope = pnodeScope->pnodeBodyScope->scope;
 
     // Once the scopes are merged, there's no reason to instantiate the param scope.
     paramScope->SetMustInstantiate(false);

+ 2 - 2
lib/Runtime/ByteCode/Scope.h

@@ -255,6 +255,6 @@ public:
 
     bool IsGlobalEvalBlockScope() const;
 
-    static void MergeParamAndBodyScopes(ParseNode *pnodeScope);
-    static void RemoveParamScope(ParseNode *pnodeScope);
+    static void MergeParamAndBodyScopes(ParseNodeFnc *pnodeScope);
+    static void RemoveParamScope(ParseNodeFnc *pnodeScope);
 };

+ 66 - 55
lib/Runtime/Language/AsmJsByteCodeGenerator.cpp

@@ -295,12 +295,12 @@ namespace Js
     void AsmJSByteCodeGenerator::DefineLabels()
     {
         mInfo->singleExit=mWriter.DefineLabel();
-        SList<ParseNode *>::Iterator iter(&mInfo->targetStatements);
+        SList<ParseNodeStmt *>::Iterator iter(&mInfo->targetStatements);
         while (iter.Next())
         {
-            ParseNode * node = iter.Data();
-            node->AsParseNodeStmt()->breakLabel=mWriter.DefineLabel();
-            node->AsParseNodeStmt()->continueLabel=mWriter.DefineLabel();
+            ParseNodeStmt * node = iter.Data();
+            node->breakLabel=mWriter.DefineLabel();
+            node->continueLabel=mWriter.DefineLabel();
             node->emitLabels=true;
         }
     }
@@ -445,10 +445,11 @@ namespace Js
         }
         case knopBlock:
         {
-            EmitExpressionInfo info = Emit(pnode->AsParseNodeBlock()->pnodeStmt);
-            if (pnode->emitLabels)
+            ParseNodeBlock * pnodeBlock = pnode->AsParseNodeBlock();
+            EmitExpressionInfo info = Emit(pnodeBlock->pnodeStmt);
+            if (pnodeBlock->emitLabels)
             {
-                mWriter.MarkAsmJsLabel(pnode->AsParseNodeStmt()->breakLabel);
+                mWriter.MarkAsmJsLabel(pnodeBlock->breakLabel);
             }
             return info;
         }
@@ -536,47 +537,57 @@ namespace Js
                 return EmitExpressionInfo(mFunction->GetConstRegister<int>(pnode->AsParseNodeInt()->lw), AsmJsType::Fixnum);
             }
         case knopIf:
-            return EmitIf( pnode );
+            return EmitIf( pnode->AsParseNodeIf() );
         case knopQmark:
             return EmitQMark( pnode );
         case knopSwitch:
-            return EmitSwitch( pnode );
+            return EmitSwitch( pnode->AsParseNodeSwitch() );
         case knopFor:
             MaybeTodo( pnode->AsParseNodeFor()->pnodeInverted != NULL );
             {
-                const EmitExpressionInfo& initInfo = Emit( pnode->AsParseNodeFor()->pnodeInit );
+                ParseNodeFor * pnodeFor = pnode->AsParseNodeFor();
+                const EmitExpressionInfo& initInfo = Emit(pnodeFor->pnodeInit );
                 mFunction->ReleaseLocationGeneric( &initInfo );
-                return EmitLoop( pnode,
-                          pnode->AsParseNodeFor()->pnodeCond,
-                          pnode->AsParseNodeFor()->pnodeBody,
-                          pnode->AsParseNodeFor()->pnodeIncr);
+                return EmitLoop( pnodeFor,
+                          pnodeFor->pnodeCond,
+                          pnodeFor->pnodeBody,
+                          pnodeFor->pnodeIncr);
             }
             break;
         case knopWhile:
-            return EmitLoop( pnode,
-                      pnode->AsParseNodeWhile()->pnodeCond,
-                      pnode->AsParseNodeWhile()->pnodeBody,
+        {
+            ParseNodeWhile * pnodeWhile = pnode->AsParseNodeWhile();
+            return EmitLoop( pnodeWhile,
+                      pnodeWhile->pnodeCond,
+                      pnodeWhile->pnodeBody,
                       nullptr);
+        }
         case knopDoWhile:
-            return EmitLoop( pnode,
-                      pnode->AsParseNodeWhile()->pnodeCond,
-                      pnode->AsParseNodeWhile()->pnodeBody,
+        {
+            ParseNodeWhile * pnodeWhile = pnode->AsParseNodeWhile();
+            return EmitLoop( pnodeWhile,
+                      pnodeWhile->pnodeCond,
+                      pnodeWhile->pnodeBody,
                       NULL,
                       true );
+        }
         case knopBreak:
-            Assert( pnode->AsParseNodeJump()->pnodeTarget->emitLabels );
-            StartStatement(pnode);
-            mWriter.AsmBr( pnode->AsParseNodeJump()->pnodeTarget->AsParseNodeStmt()->breakLabel );
-            if( pnode->emitLabels )
+        {
+            ParseNodeJump * pnodeJump = pnode->AsParseNodeJump();
+            Assert(pnodeJump->pnodeTarget->emitLabels);
+            StartStatement(pnodeJump);
+            mWriter.AsmBr(pnodeJump->pnodeTarget->breakLabel);
+            if (pnodeJump->emitLabels)
             {
-                mWriter.MarkAsmJsLabel( pnode->AsParseNodeStmt()->breakLabel );
+                mWriter.MarkAsmJsLabel(pnodeJump->breakLabel);
             }
-            EndStatement(pnode);
+            EndStatement(pnodeJump);
             break;
+        }
         case knopContinue:
             Assert( pnode->AsParseNodeJump()->pnodeTarget->emitLabels );
             StartStatement(pnode);
-            mWriter.AsmBr( pnode->AsParseNodeJump()->pnodeTarget->AsParseNodeStmt()->continueLabel );
+            mWriter.AsmBr( pnode->AsParseNodeJump()->pnodeTarget->continueLabel );
             EndStatement(pnode);
             break;
         case knopVarDecl:
@@ -2133,20 +2144,20 @@ namespace Js
         }
     }
 
-    EmitExpressionInfo AsmJSByteCodeGenerator::EmitIf( ParseNode * pnode )
+    EmitExpressionInfo AsmJSByteCodeGenerator::EmitIf( ParseNodeIf * pnode )
     {
         Js::ByteCodeLabel trueLabel = mWriter.DefineLabel();
         Js::ByteCodeLabel falseLabel = mWriter.DefineLabel();
-        const EmitExpressionInfo& boolInfo = EmitBooleanExpression( pnode->AsParseNodeIf()->pnodeCond, trueLabel, falseLabel );
+        const EmitExpressionInfo& boolInfo = EmitBooleanExpression( pnode->pnodeCond, trueLabel, falseLabel );
         mFunction->ReleaseLocation<int>( &boolInfo );
 
 
         mWriter.MarkAsmJsLabel( trueLabel );
 
-        const EmitExpressionInfo& trueInfo = Emit( pnode->AsParseNodeIf()->pnodeTrue );
+        const EmitExpressionInfo& trueInfo = Emit( pnode->pnodeTrue );
         mFunction->ReleaseLocationGeneric( &trueInfo );
 
-        if( pnode->AsParseNodeIf()->pnodeFalse != nullptr )
+        if( pnode->pnodeFalse != nullptr )
         {
             // has else clause
             Js::ByteCodeLabel skipLabel = mWriter.DefineLabel();
@@ -2159,7 +2170,7 @@ namespace Js
             // generate code for else clause
             mWriter.MarkAsmJsLabel( falseLabel );
 
-            const EmitExpressionInfo& falseInfo = Emit( pnode->AsParseNodeIf()->pnodeFalse );
+            const EmitExpressionInfo& falseInfo = Emit( pnode->pnodeFalse );
             mFunction->ReleaseLocationGeneric( &falseInfo );
 
             mWriter.MarkAsmJsLabel( skipLabel );
@@ -2171,12 +2182,12 @@ namespace Js
         }
         if( pnode->emitLabels )
         {
-            mWriter.MarkAsmJsLabel( pnode->AsParseNodeStmt()->breakLabel );
+            mWriter.MarkAsmJsLabel( pnode->breakLabel );
         }
         return EmitExpressionInfo( AsmJsType::Void );
     }
 
-    Js::EmitExpressionInfo AsmJSByteCodeGenerator::EmitLoop( ParseNode *loopNode, ParseNode *cond, ParseNode *body, ParseNode *incr, BOOL doWhile /*= false */ )
+    Js::EmitExpressionInfo AsmJSByteCodeGenerator::EmitLoop( ParseNodeLoop *loopNode, ParseNode *cond, ParseNode *body, ParseNode *incr, BOOL doWhile /*= false */ )
     {
         // Need to increment loop count whether we are going to profile or not for HasLoop()
         StartStatement(loopNode);
@@ -2184,7 +2195,7 @@ namespace Js
         Js::ByteCodeLabel continuePastLoop = mWriter.DefineLabel();
 
         uint loopId = mWriter.EnterLoop( loopEntrance );
-        loopNode->AsParseNodeLoop()->loopId = loopId;
+        loopNode->loopId = loopId;
         EndStatement(loopNode);
         if( doWhile )
         {
@@ -2193,7 +2204,7 @@ namespace Js
 
             if( loopNode->emitLabels )
             {
-                mWriter.MarkAsmJsLabel( loopNode->AsParseNodeStmt()->continueLabel );
+                mWriter.MarkAsmJsLabel( loopNode->continueLabel );
             }
             if( !ByteCodeGenerator::IsFalse( cond ) )
             {
@@ -2215,7 +2226,7 @@ namespace Js
 
             if( loopNode->emitLabels )
             {
-                mWriter.MarkAsmJsLabel( loopNode->AsParseNodeStmt()->continueLabel );
+                mWriter.MarkAsmJsLabel( loopNode->continueLabel );
             }
             if( incr != NULL )
             {
@@ -2227,7 +2238,7 @@ namespace Js
         mWriter.MarkAsmJsLabel( continuePastLoop );
         if( loopNode->emitLabels )
         {
-            mWriter.MarkAsmJsLabel( loopNode->AsParseNodeStmt()->breakLabel );
+            mWriter.MarkAsmJsLabel( loopNode->breakLabel );
         }
 
         mWriter.ExitLoop( loopId );
@@ -2328,11 +2339,11 @@ namespace Js
         return emitInfo;
     }
 
-    EmitExpressionInfo AsmJSByteCodeGenerator::EmitSwitch( ParseNode * pnode )
+    EmitExpressionInfo AsmJSByteCodeGenerator::EmitSwitch( ParseNodeSwitch * pnode )
     {
         BOOL fHasDefault = false;
-        Assert( pnode->AsParseNodeSwitch()->pnodeVal != NULL );
-        const EmitExpressionInfo& valInfo = Emit( pnode->AsParseNodeSwitch()->pnodeVal );
+        Assert( pnode->pnodeVal != NULL );
+        const EmitExpressionInfo& valInfo = Emit( pnode->pnodeVal );
 
         if( !valInfo.type.isSigned() )
         {
@@ -2347,46 +2358,46 @@ namespace Js
         // TODO: if all cases are compile-time constants, emit a switch statement in the byte
         // code so the BE can optimize it.
 
-        ParseNode *pnodeCase;
-        for( pnodeCase = pnode->AsParseNodeSwitch()->pnodeCases; pnodeCase; pnodeCase = pnodeCase->AsParseNodeCase()->pnodeNext )
+        ParseNodeCase *pnodeCase;
+        for( pnodeCase = pnode->pnodeCases; pnodeCase; pnodeCase = pnodeCase->pnodeNext )
         {
             // Jump to the first case body if this one doesn't match. Make sure any side-effects of the case
             // expression take place regardless.
-            pnodeCase->AsParseNodeCase()->labelCase = mWriter.DefineLabel();
-            if( pnodeCase == pnode->AsParseNodeSwitch()->pnodeDefault )
+            pnodeCase->labelCase = mWriter.DefineLabel();
+            if( pnodeCase == pnode->pnodeDefault )
             {
                 fHasDefault = true;
                 continue;
             }
-            ParseNode* caseExpr = pnodeCase->AsParseNodeCase()->pnodeExpr;
+            ParseNode* caseExpr = pnodeCase->pnodeExpr;
             if ((caseExpr->nop != knopInt || (caseExpr->AsParseNodeInt()->lw >> 31) > 1) && !ParserWrapper::IsMinInt(caseExpr))
             {
                 throw AsmJsCompilationException( _u("Switch case value must be int in the range [-2^31, 2^31)") );
             }
 
-            const EmitExpressionInfo& caseExprInfo = Emit( pnodeCase->AsParseNodeCase()->pnodeExpr );
-            mWriter.AsmBrReg2( OpCodeAsmJs::Case_Int, pnodeCase->AsParseNodeCase()->labelCase, regVal, caseExprInfo.location );
+            const EmitExpressionInfo& caseExprInfo = Emit( pnodeCase->pnodeExpr );
+            mWriter.AsmBrReg2( OpCodeAsmJs::Case_Int, pnodeCase->labelCase, regVal, caseExprInfo.location );
             // do not need to release location because int constants cannot be released
         }
 
         // No explicit case value matches. Jump to the default arm (if any) or break out altogether.
         if( fHasDefault )
         {
-            mWriter.AsmBr( pnode->AsParseNodeSwitch()->pnodeDefault->AsParseNodeCase()->labelCase, OpCodeAsmJs::EndSwitch_Int );
+            mWriter.AsmBr( pnode->pnodeDefault->labelCase, OpCodeAsmJs::EndSwitch_Int );
         }
         else
         {
             if( !pnode->emitLabels )
             {
-                pnode->AsParseNodeStmt()->breakLabel = mWriter.DefineLabel();
+                pnode->breakLabel = mWriter.DefineLabel();
             }
-            mWriter.AsmBr( pnode->AsParseNodeStmt()->breakLabel, OpCodeAsmJs::EndSwitch_Int );
+            mWriter.AsmBr( pnode->breakLabel, OpCodeAsmJs::EndSwitch_Int );
         }
         // Now emit the case arms to which we jump on matching a case value.
-        for( pnodeCase = pnode->AsParseNodeSwitch()->pnodeCases; pnodeCase; pnodeCase = pnodeCase->AsParseNodeCase()->pnodeNext )
+        for( pnodeCase = pnode->pnodeCases; pnodeCase; pnodeCase = pnodeCase->pnodeNext )
         {
-            mWriter.MarkAsmJsLabel( pnodeCase->AsParseNodeCase()->labelCase );
-            const EmitExpressionInfo& caseBodyInfo = Emit( pnodeCase->AsParseNodeCase()->pnodeBody );
+            mWriter.MarkAsmJsLabel( pnodeCase->labelCase );
+            const EmitExpressionInfo& caseBodyInfo = Emit( pnodeCase->pnodeBody );
             mFunction->ReleaseLocationGeneric( &caseBodyInfo );
         }
 
@@ -2394,7 +2405,7 @@ namespace Js
 
         if( !fHasDefault || pnode->emitLabels )
         {
-            mWriter.MarkAsmJsLabel( pnode->AsParseNodeStmt()->breakLabel );
+            mWriter.MarkAsmJsLabel( pnode->breakLabel );
         }
 
         return EmitExpressionInfo( AsmJsType::Void );

+ 3 - 3
lib/Runtime/Language/AsmJsByteCodeGenerator.h

@@ -94,10 +94,10 @@ namespace Js
         EmitExpressionInfo EmitBinaryMultiType( ParseNode * pnode, EBinaryMathOpCodes op );
         EmitExpressionInfo EmitBinaryInt( ParseNode * pnode, OpCodeAsmJs op );
         EmitExpressionInfo EmitQMark( ParseNode * pnode );
-        EmitExpressionInfo EmitSwitch( ParseNode * pnode );
+        EmitExpressionInfo EmitSwitch( ParseNodeSwitch * pnode );
         EmitExpressionInfo EmitBinaryComparator( ParseNode * pnode, EBinaryComparatorOpCodes op);
-        EmitExpressionInfo EmitLoop( ParseNode *loopNode, ParseNode *cond, ParseNode *body, ParseNode *incr, BOOL doWhile = false );
-        EmitExpressionInfo EmitIf( ParseNode * pnode );
+        EmitExpressionInfo EmitLoop( ParseNodeLoop *loopNode, ParseNode *cond, ParseNode *body, ParseNode *incr, BOOL doWhile = false );
+        EmitExpressionInfo EmitIf( ParseNodeIf * pnode );
         EmitExpressionInfo EmitBooleanExpression( ParseNode* pnodeCond, Js::ByteCodeLabel trueLabel, Js::ByteCodeLabel falseLabel );
 
         void FinalizeRegisters( FunctionBody* byteCodeFunction );

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

@@ -468,7 +468,7 @@ namespace Js
             break;
         case knopSwitch:
             ASTPrepass(pnode->AsParseNodeSwitch()->pnodeVal, func);
-            for (ParseNode *pnodeT = pnode->AsParseNodeSwitch()->pnodeCases; NULL != pnodeT; pnodeT = pnodeT->AsParseNodeCase()->pnodeNext)
+            for (ParseNodeCase *pnodeT = pnode->AsParseNodeSwitch()->pnodeCases; NULL != pnodeT; pnodeT = pnodeT->pnodeNext)
             {
                 ASTPrepass(pnodeT, func);
             }

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