Changeset 28854 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Dec 18, 2007, 11:42:29 PM (17 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/Parser.cpp
r28604 r28854 61 61 lexer.clear(); 62 62 63 Node::clearNewNodes();63 ParserRefCounted::deleteNewObjects(); 64 64 65 65 if (parseError || lexError) { -
trunk/JavaScriptCore/kjs/Parser.h
r28604 r28854 29 29 #include <wtf/Noncopyable.h> 30 30 #include <wtf/OwnPtr.h> 31 #include <wtf/RefPtr.h> 31 32 #include "nodes.h" 32 33 … … 38 39 39 40 struct UChar; 41 42 template <typename T> struct ParserRefCountedData : ParserRefCounted { 43 T data; 44 }; 40 45 41 46 class Parser : Noncopyable { … … 49 54 int sourceId() const { return m_sourceId; } 50 55 51 void didFinishParsing(SourceElements* sourceElements, int lastLine) 56 void didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack, 57 ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, int lastLine) 52 58 { 53 59 m_sourceElements.set(sourceElements); 60 m_varDeclarations = varStack; 61 m_funcDeclarations = funcStack; 54 62 m_lastLine = lastLine; 55 63 } … … 65 73 int m_sourceId; 66 74 OwnPtr<SourceElements> m_sourceElements; 75 RefPtr<ParserRefCountedData<DeclarationStacks::VarStack> > m_varDeclarations; 76 RefPtr<ParserRefCountedData<DeclarationStacks::FunctionStack> > m_funcDeclarations; 67 77 int m_lastLine; 68 78 }; … … 81 91 return 0; 82 92 } 83 RefPtr<ParsedNode> node = new ParsedNode(m_sourceElements.release()); 93 RefPtr<ParsedNode> node = new ParsedNode(m_sourceElements.release(), 94 m_varDeclarations ? &m_varDeclarations->data : 0, 95 m_funcDeclarations ? &m_funcDeclarations->data : 0); 96 m_varDeclarations = 0; 97 m_funcDeclarations = 0; 84 98 m_sourceURL = UString(); 85 99 node->setLoc(startingLineNumber, m_lastLine); -
trunk/JavaScriptCore/kjs/grammar.y
r28581 r28854 85 85 #endif 86 86 87 template <typename T> struct NodeInfo { 88 T m_node; 89 ParserRefCountedData<DeclarationStacks::VarStack>* m_varDeclarations; 90 ParserRefCountedData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 91 }; 92 93 template <typename T> NodeInfo<T> createNodeInfo(T node, ParserRefCountedData<DeclarationStacks::VarStack>* varDecls, 94 ParserRefCountedData<DeclarationStacks::FunctionStack>* funcDecls) 95 { 96 NodeInfo<T> result = {node, varDecls, funcDecls}; 97 return result; 98 } 99 100 template <typename T> T mergeDeclarationLists(T decls1, T decls2) 101 { 102 // decls1 or both are null 103 if (!decls1) 104 return decls2; 105 // only decls1 is non-null 106 if (!decls2) 107 return decls1; 108 109 // Both are non-null 110 decls1->data.append(decls2->data); 111 112 // We manually release the declaration lists to avoid accumulating many many 113 // unused heap allocated vectors 114 decls2->ref(); 115 decls2->deref(); 116 return decls1; 117 } 118 119 void appendToVarDeclarationList(ParserRefCountedData<DeclarationStacks::VarStack>*& varDecls, VarDeclNode* decl) 120 { 121 if (!varDecls) 122 varDecls = new ParserRefCountedData<DeclarationStacks::VarStack>; 123 varDecls->data.append(decl); 124 } 125 126 typedef NodeInfo<StatementNode*> StatementNodeInfo; 127 typedef NodeInfo<CaseBlockNode*> CaseBlockNodeInfo; 128 typedef NodeInfo<CaseClauseNode*> CaseClauseNodeInfo; 129 typedef NodeInfo<SourceElementsStub*> SourceElementsInfo; 130 typedef NodeInfo<ClauseList> ClauseListInfo; 131 typedef NodeInfo<VarDeclList> VarDeclListInfo; 87 132 %} 88 133 … … 99 144 ArgumentsNode* argumentsNode; 100 145 VarDeclNode* varDeclNode; 101 CaseBlockNode *caseBlockNode;102 CaseClauseNode *caseClauseNode;146 CaseBlockNodeInfo caseBlockNode; 147 CaseClauseNodeInfo caseClauseNode; 103 148 FuncExprNode* funcExprNode; 104 149 AssignExprNode* assignExprNode; 105 150 106 151 // statement nodes 107 StatementNode *statementNode;152 StatementNodeInfo statementNode; 108 153 FunctionBodyNode* functionBodyNode; 109 154 ProgramNode* programNode; 110 155 111 SourceElements Stub*sourceElements;156 SourceElementsInfo sourceElements; 112 157 PropertyList propertyList; 113 158 ArgumentList argumentList; 114 VarDeclList 115 ClauseList 159 VarDeclListInfo varDeclList; 160 ClauseListInfo clauseList; 116 161 ElementList elementList; 117 162 ParameterList parameterList; … … 663 708 664 709 Block: 665 '{' '}' { $$ = new BlockNode(new SourceElements); DBG($$, @1, @2); } 666 | '{' SourceElements '}' { $$ = new BlockNode($2->release()); DBG($$, @1, @3); } 710 '{' '}' { $$ = createNodeInfo<StatementNode*>(new BlockNode(new SourceElements), 0, 0); 711 DBG($$.m_node, @1, @2); } 712 | '{' SourceElements '}' { $$ = createNodeInfo<StatementNode*>(new BlockNode($2.m_node->release()), $2.m_varDeclarations, $2.m_funcDeclarations); 713 DBG($$.m_node, @1, @3); } 667 714 ; 668 715 669 716 VariableStatement: 670 VAR VariableDeclarationList ';' { $$ = new VarStatementNode($2.head); DBG($$, @1, @3); } 671 | VAR VariableDeclarationList error { $$ = new VarStatementNode($2.head); DBG($$, @1, @2); AUTO_SEMICOLON; } 717 VAR VariableDeclarationList ';' { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 718 DBG($$.m_node, @1, @3); } 719 | VAR VariableDeclarationList error { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 720 DBG($$.m_node, @1, @2); 721 AUTO_SEMICOLON; } 672 722 ; 673 723 674 724 VariableDeclarationList: 675 VariableDeclaration { $$.head = $1; 676 $$.tail = $$.head; } 725 VariableDeclaration { $$.m_node.head = $1; 726 $$.m_node.tail = $$.m_node.head; 727 $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 728 $$.m_varDeclarations->data.append($1); 729 $$.m_funcDeclarations = 0; 730 } 677 731 | VariableDeclarationList ',' VariableDeclaration 678 { $$.head = $1.head; 679 $1.tail->next = $3; 680 $$.tail = $3; } 732 { $$.m_node.head = $1.m_node.head; 733 $1.m_node.tail->next = $3; 734 $$.m_node.tail = $3; 735 $$.m_varDeclarations = $1.m_varDeclarations; 736 $$.m_varDeclarations->data.append($3); 737 $$.m_funcDeclarations = 0; 738 } 681 739 ; 682 740 683 741 VariableDeclarationListNoIn: 684 VariableDeclarationNoIn { $$.head = $1; 685 $$.tail = $$.head; } 742 VariableDeclarationNoIn { $$.m_node.head = $1; 743 $$.m_node.tail = $$.m_node.head; 744 $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 745 $$.m_varDeclarations->data.append($1); 746 $$.m_funcDeclarations = 0; } 686 747 | VariableDeclarationListNoIn ',' VariableDeclarationNoIn 687 { $$.head = $1.head; 688 $1.tail->next = $3; 689 $$.tail = $3; } 748 { $$.m_node.head = $1.m_node.head; 749 $1.m_node.tail->next = $3; 750 $$.m_node.tail = $3; 751 $$.m_varDeclarations = $1.m_varDeclarations; 752 $$.m_varDeclarations->data.append($3); 753 $$.m_funcDeclarations = 0; } 690 754 ; 691 755 … … 701 765 702 766 ConstStatement: 703 CONSTTOKEN ConstDeclarationList ';' { $$ = new VarStatementNode($2.head); DBG($$, @1, @3); } 767 CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 768 DBG($$.m_node, @1, @3); } 704 769 | CONSTTOKEN ConstDeclarationList error 705 { $$ = new VarStatementNode($2.head); DBG($$, @1, @2); AUTO_SEMICOLON; } 770 { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 771 DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } 706 772 ; 707 773 708 774 ConstDeclarationList: 709 ConstDeclaration { $$.head = $1; 710 $$.tail = $$.head; } 775 ConstDeclaration { $$.m_node.head = $1; 776 $$.m_node.tail = $$.m_node.head; 777 $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 778 $$.m_varDeclarations->data.append($1); 779 $$.m_funcDeclarations = 0; } 711 780 | ConstDeclarationList ',' ConstDeclaration 712 { $$.head = $1.head; 713 $1.tail->next = $3; 714 $$.tail = $3; } 781 { $$.m_node.head = $1.m_node.head; 782 $1.m_node.tail->next = $3; 783 $$.m_node.tail = $3; 784 $$.m_varDeclarations = $1.m_varDeclarations; 785 $$.m_varDeclarations->data.append($3); 786 $$.m_funcDeclarations = 0; } 715 787 ; 716 788 … … 729 801 730 802 EmptyStatement: 731 ';' { $$ = new EmptyStatementNode(); }803 ';' { $$ = createNodeInfo<StatementNode*>(new EmptyStatementNode(), 0, 0); } 732 804 ; 733 805 734 806 ExprStatement: 735 ExprNoBF ';' { $$ = new ExprStatementNode($1); DBG($$, @1, @2); } 736 | ExprNoBF error { $$ = new ExprStatementNode($1); DBG($$, @1, @1); AUTO_SEMICOLON; } 807 ExprNoBF ';' { $$ = createNodeInfo<StatementNode*>(new ExprStatementNode($1), 0, 0); 808 DBG($$.m_node, @1, @2); } 809 | ExprNoBF error { $$ = createNodeInfo<StatementNode*>(new ExprStatementNode($1), 0, 0); 810 DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } 737 811 ; 738 812 739 813 IfStatement: 740 814 IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE 741 { $$ = new IfNode($3, $5, 0); DBG($$, @1, @4); } 815 { $$ = createNodeInfo<StatementNode*>(new IfNode($3, $5.m_node, 0), $5.m_varDeclarations, $5.m_funcDeclarations); 816 DBG($$.m_node, @1, @4); } 742 817 | IF '(' Expr ')' Statement ELSE Statement 743 { $$ = new IfNode($3, $5, $7); DBG($$, @1, @4); } 818 { $$ = createNodeInfo<StatementNode*>(new IfNode($3, $5.m_node, $7.m_node), mergeDeclarationLists($5.m_varDeclarations, $7.m_varDeclarations), mergeDeclarationLists($5.m_funcDeclarations, $7.m_funcDeclarations)); 819 DBG($$.m_node, @1, @4); } 744 820 ; 745 821 746 822 IterationStatement: 747 DO Statement WHILE '(' Expr ')' ';' { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3); } 748 | DO Statement WHILE '(' Expr ')' error { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3); } // Always performs automatic semicolon insertion. 749 | WHILE '(' Expr ')' Statement { $$ = new WhileNode($3, $5); DBG($$, @1, @4); } 823 DO Statement WHILE '(' Expr ')' ';' { $$ = createNodeInfo<StatementNode*>(new DoWhileNode($2.m_node, $5), $2.m_varDeclarations, $2.m_funcDeclarations); 824 DBG($$.m_node, @1, @3); } 825 | DO Statement WHILE '(' Expr ')' error { $$ = createNodeInfo<StatementNode*>(new DoWhileNode($2.m_node, $5), $2.m_varDeclarations, $2.m_funcDeclarations); 826 DBG($$.m_node, @1, @3); } // Always performs automatic semicolon insertion. 827 | WHILE '(' Expr ')' Statement { $$ = createNodeInfo<StatementNode*>(new WhileNode($3, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations); 828 DBG($$.m_node, @1, @4); } 750 829 | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement 751 { $$ = new ForNode($3, $5, $7, $9); DBG($$, @1, @8); } 830 { $$ = createNodeInfo<StatementNode*>(new ForNode($3, $5, $7, $9.m_node), $9.m_varDeclarations, $9.m_funcDeclarations); 831 DBG($$.m_node, @1, @8); 832 } 752 833 | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement 753 { $$ = new ForNode($4.head, $6, $8, $10); DBG($$, @1, @9); } 834 { $$ = createNodeInfo<StatementNode*>(new ForNode($4.m_node.head, $6, $8, $10.m_node), 835 mergeDeclarationLists($4.m_varDeclarations, $10.m_varDeclarations), 836 mergeDeclarationLists($4.m_funcDeclarations, $10.m_funcDeclarations)); 837 DBG($$.m_node, @1, @9); } 754 838 | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement 755 839 { … … 757 841 if (!n->isLocation()) 758 842 YYABORT; 759 $$ = new ForInNode(n, $5, $7);760 DBG($$ , @1, @6);843 $$ = createNodeInfo<StatementNode*>(new ForInNode(n, $5, $7.m_node), $7.m_varDeclarations, $7.m_funcDeclarations); 844 DBG($$.m_node, @1, @6); 761 845 } 762 846 | FOR '(' VAR IDENT INTOKEN Expr ')' Statement 763 { $$ = new ForInNode(*$4, 0, $6, $8); DBG($$, @1, @7); } 847 { ForInNode *forIn = new ForInNode(*$4, 0, $6, $8.m_node); 848 appendToVarDeclarationList($8.m_varDeclarations, forIn->getVarDecl()); 849 $$ = createNodeInfo<StatementNode*>(forIn, $8.m_varDeclarations, $8.m_funcDeclarations); 850 DBG($$.m_node, @1, @7); } 764 851 | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement 765 { $$ = new ForInNode(*$4, $5, $7, $9); DBG($$, @1, @8); } 852 { ForInNode *forIn = new ForInNode(*$4, $5, $7, $9.m_node); 853 appendToVarDeclarationList($9.m_varDeclarations, forIn->getVarDecl()); 854 $$ = createNodeInfo<StatementNode*>(forIn, $9.m_varDeclarations, $9.m_funcDeclarations); 855 DBG($$.m_node, @1, @8); } 766 856 ; 767 857 … … 777 867 778 868 ContinueStatement: 779 CONTINUE ';' { $$ = new ContinueNode(); DBG($$, @1, @2); } 780 | CONTINUE error { $$ = new ContinueNode(); DBG($$, @1, @1); AUTO_SEMICOLON; } 781 | CONTINUE IDENT ';' { $$ = new ContinueNode(*$2); DBG($$, @1, @3); } 782 | CONTINUE IDENT error { $$ = new ContinueNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; } 869 CONTINUE ';' { $$ = createNodeInfo<StatementNode*>(new ContinueNode(), 0, 0); 870 DBG($$.m_node, @1, @2); } 871 | CONTINUE error { $$ = createNodeInfo<StatementNode*>(new ContinueNode(), 0, 0); 872 DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } 873 | CONTINUE IDENT ';' { $$ = createNodeInfo<StatementNode*>(new ContinueNode(*$2), 0, 0); 874 DBG($$.m_node, @1, @3); } 875 | CONTINUE IDENT error { $$ = createNodeInfo<StatementNode*>(new ContinueNode(*$2), 0, 0); 876 DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } 783 877 ; 784 878 785 879 BreakStatement: 786 BREAK ';' { $$ = new BreakNode(); DBG($$, @1, @2); }787 | BREAK error { $$ = new BreakNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }788 | BREAK IDENT ';' { $$ = new BreakNode(*$2); DBG($$, @1, @3); }789 | BREAK IDENT error { $$ = new BreakNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; }880 BREAK ';' { $$ = createNodeInfo<StatementNode*>(new BreakNode(), 0, 0); DBG($$.m_node, @1, @2); } 881 | BREAK error { $$ = createNodeInfo<StatementNode*>(new BreakNode(), 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } 882 | BREAK IDENT ';' { $$ = createNodeInfo<StatementNode*>(new BreakNode(*$2), 0, 0); DBG($$.m_node, @1, @3); } 883 | BREAK IDENT error { $$ = createNodeInfo<StatementNode*>(new BreakNode(*$2), 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } 790 884 ; 791 885 792 886 ReturnStatement: 793 RETURN ';' { $$ = new ReturnNode(0); DBG($$, @1, @2); }794 | RETURN error { $$ = new ReturnNode(0); DBG($$, @1, @1); AUTO_SEMICOLON; }795 | RETURN Expr ';' { $$ = new ReturnNode($2); DBG($$, @1, @3); }796 | RETURN Expr error { $$ = new ReturnNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }887 RETURN ';' { $$ = createNodeInfo<StatementNode*>(new ReturnNode(0), 0, 0); DBG($$.m_node, @1, @2); } 888 | RETURN error { $$ = createNodeInfo<StatementNode*>(new ReturnNode(0), 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } 889 | RETURN Expr ';' { $$ = createNodeInfo<StatementNode*>(new ReturnNode($2), 0, 0); DBG($$.m_node, @1, @3); } 890 | RETURN Expr error { $$ = createNodeInfo<StatementNode*>(new ReturnNode($2), 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } 797 891 ; 798 892 799 893 WithStatement: 800 WITH '(' Expr ')' Statement { $$ = new WithNode($3, $5); DBG($$, @1, @4); } 894 WITH '(' Expr ')' Statement { $$ = createNodeInfo<StatementNode*>(new WithNode($3, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations); 895 DBG($$.m_node, @1, @4); } 801 896 ; 802 897 803 898 SwitchStatement: 804 SWITCH '(' Expr ')' CaseBlock { $$ = new SwitchNode($3, $5); DBG($$, @1, @4); } 899 SWITCH '(' Expr ')' CaseBlock { $$ = createNodeInfo<StatementNode*>(new SwitchNode($3, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations); 900 DBG($$.m_node, @1, @4); } 805 901 ; 806 902 807 903 CaseBlock: 808 '{' CaseClausesOpt '}' { $$ = new CaseBlockNode($2.head, 0, 0); }904 '{' CaseClausesOpt '}' { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations); } 809 905 | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}' 810 { $$ = new CaseBlockNode($2.head, $3, $4.head); } 906 { $$ = createNodeInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, $3.m_node, $4.m_node.head), 907 mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $3.m_varDeclarations), $4.m_varDeclarations), 908 mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $3.m_funcDeclarations), $4.m_funcDeclarations)); } 811 909 ; 812 910 813 911 CaseClausesOpt: 814 /* nothing */ { $$. head = 0; $$.tail= 0; }912 /* nothing */ { $$.m_node.head = 0; $$.m_node.tail = 0; $$.m_varDeclarations = 0; $$.m_funcDeclarations = 0; } 815 913 | CaseClauses 816 914 ; 817 915 818 916 CaseClauses: 819 CaseClause { $$.head = new ClauseListNode($1); 820 $$.tail = $$.head; } 821 | CaseClauses CaseClause { $$.head = $1.head; 822 $$.tail = new ClauseListNode($1.tail, $2); } 917 CaseClause { $$.m_node.head = new ClauseListNode($1.m_node); 918 $$.m_node.tail = $$.m_node.head; 919 $$.m_varDeclarations = $1.m_varDeclarations; 920 $$.m_funcDeclarations = $1.m_funcDeclarations; } 921 | CaseClauses CaseClause { $$.m_node.head = $1.m_node.head; 922 $$.m_node.tail = new ClauseListNode($1.m_node.tail, $2.m_node); 923 $$.m_varDeclarations = mergeDeclarationLists($1.m_varDeclarations, $2.m_varDeclarations); 924 $$.m_funcDeclarations = mergeDeclarationLists($1.m_funcDeclarations, $2.m_funcDeclarations); 925 } 823 926 ; 824 927 825 928 CaseClause: 826 CASE Expr ':' { $$ = new CaseClauseNode($2); }827 | CASE Expr ':' SourceElements { $$ = new CaseClauseNode($2, $4->release()); }929 CASE Expr ':' { $$ = createNodeInfo<CaseClauseNode*>(new CaseClauseNode($2), 0, 0); } 930 | CASE Expr ':' SourceElements { $$ = createNodeInfo<CaseClauseNode*>(new CaseClauseNode($2, $4.m_node->release()), $4.m_varDeclarations, $4.m_funcDeclarations); } 828 931 ; 829 932 830 933 DefaultClause: 831 DEFAULT ':' { $$ = new CaseClauseNode(0); }832 | DEFAULT ':' SourceElements { $$ = new CaseClauseNode(0, $3->release()); }934 DEFAULT ':' { $$ = createNodeInfo<CaseClauseNode*>(new CaseClauseNode(0), 0, 0); } 935 | DEFAULT ':' SourceElements { $$ = createNodeInfo<CaseClauseNode*>(new CaseClauseNode(0, $3.m_node->release()), $3.m_varDeclarations, $3.m_funcDeclarations); } 833 936 ; 834 937 835 938 LabelledStatement: 836 IDENT ':' Statement { $3->pushLabel(*$1); $$ = new LabelNode(*$1, $3); } 939 IDENT ':' Statement { $3.m_node->pushLabel(*$1); 940 $$ = createNodeInfo<StatementNode*>(new LabelNode(*$1, $3.m_node), $3.m_varDeclarations, $3.m_funcDeclarations); } 837 941 ; 838 942 839 943 ThrowStatement: 840 THROW Expr ';' { $$ = new ThrowNode($2); DBG($$, @1, @3); }841 | THROW Expr error { $$ = new ThrowNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }944 THROW Expr ';' { $$ = createNodeInfo<StatementNode*>(new ThrowNode($2), 0, 0); DBG($$.m_node, @1, @3); } 945 | THROW Expr error { $$ = createNodeInfo<StatementNode*>(new ThrowNode($2), 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } 842 946 ; 843 947 844 948 TryStatement: 845 TRY Block FINALLY Block { $$ = new TryNode($2, CommonIdentifiers::shared()->nullIdentifier, 0, $4); DBG($$, @1, @2); } 846 | TRY Block CATCH '(' IDENT ')' Block { $$ = new TryNode($2, *$5, $7, 0); DBG($$, @1, @2); } 949 TRY Block FINALLY Block { $$ = createNodeInfo<StatementNode*>(new TryNode($2.m_node, CommonIdentifiers::shared()->nullIdentifier, 0, $4.m_node), 950 mergeDeclarationLists($2.m_varDeclarations, $4.m_varDeclarations), 951 mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations)); 952 DBG($$.m_node, @1, @2); } 953 | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeInfo<StatementNode*>(new TryNode($2.m_node, *$5, $7.m_node, 0), 954 mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), 955 mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations)); 956 DBG($$.m_node, @1, @2); } 847 957 | TRY Block CATCH '(' IDENT ')' Block FINALLY Block 848 { $$ = new TryNode($2, *$5, $7, $9); DBG($$, @1, @2); } 958 { $$ = createNodeInfo<StatementNode*>(new TryNode($2.m_node, *$5, $7.m_node, $9.m_node), 959 mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), $9.m_varDeclarations), 960 mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $9.m_funcDeclarations)); 961 DBG($$.m_node, @1, @2); } 849 962 ; 850 963 851 964 DebuggerStatement: 852 DEBUGGER ';' { $$ = new EmptyStatementNode(); DBG($$, @1, @2); } 853 | DEBUGGER error { $$ = new EmptyStatementNode(); DBG($$, @1, @1); AUTO_SEMICOLON; } 965 DEBUGGER ';' { $$ = createNodeInfo<StatementNode*>(new EmptyStatementNode(), 0, 0); 966 DBG($$.m_node, @1, @2); } 967 | DEBUGGER error { $$ = createNodeInfo<StatementNode*>(new EmptyStatementNode(), 0, 0); 968 DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } 854 969 ; 855 970 … … 875 990 876 991 FunctionBody: 877 /* not in spec */ { $$ = new FunctionBodyNode(new SourceElements); } 878 | SourceElements { $$ = new FunctionBodyNode($1->release()); } 992 /* not in spec */ { $$ = new FunctionBodyNode(new SourceElements, 0, 0); } 993 | SourceElements { $$ = new FunctionBodyNode($1.m_node->release(), $1.m_varDeclarations ? &$1.m_varDeclarations->data : 0, 994 $1.m_funcDeclarations ? &$1.m_funcDeclarations->data : 0); 995 // As in mergeDeclarationLists() we have to ref/deref to safely get rid of 996 // the declaration lists. 997 if ($1.m_varDeclarations) { 998 $1.m_varDeclarations->ref(); 999 $1.m_varDeclarations->deref(); 1000 } 1001 if ($1.m_funcDeclarations) { 1002 $1.m_funcDeclarations->ref(); 1003 $1.m_funcDeclarations->deref(); 1004 } 1005 } 879 1006 ; 880 1007 881 1008 Program: 882 /* not in spec */ { parser().didFinishParsing(new SourceElements, @0.last_line); }883 | SourceElements { parser().didFinishParsing($1 ->release(), @1.last_line); }1009 /* not in spec */ { parser().didFinishParsing(new SourceElements, 0, 0, @0.last_line); } 1010 | SourceElements { parser().didFinishParsing($1.m_node->release(), $1.m_varDeclarations, $1.m_funcDeclarations, @1.last_line); } 884 1011 ; 885 1012 886 1013 SourceElements: 887 SourceElement { $$ = new SourceElementsStub; $$->append($1); } 888 | SourceElements SourceElement { $$->append($2); } 1014 SourceElement { $$.m_node = new SourceElementsStub; 1015 $$.m_node->append($1.m_node); 1016 $$.m_varDeclarations = $1.m_varDeclarations; 1017 $$.m_funcDeclarations = $1.m_funcDeclarations; 1018 } 1019 | SourceElements SourceElement { $$.m_node->append($2.m_node); 1020 $$.m_varDeclarations = mergeDeclarationLists($1.m_varDeclarations, $2.m_varDeclarations); 1021 $$.m_funcDeclarations = mergeDeclarationLists($1.m_funcDeclarations, $2.m_funcDeclarations); 1022 } 889 1023 ; 890 1024 891 1025 SourceElement: 892 FunctionDeclaration { $$ = $1; }1026 FunctionDeclaration { $$ = createNodeInfo<StatementNode*>($1, 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>); $$.m_funcDeclarations->data.append($1); } 893 1027 | Statement { $$ = $1; } 894 1028 ; -
trunk/JavaScriptCore/kjs/nodes.cpp
r28608 r28854 111 111 static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn }; 112 112 113 struct NodeCounter {113 struct ParserRefCountedCounter { 114 114 static unsigned count; 115 ~NodeCounter()115 ParserRefCountedCounter() 116 116 { 117 117 if (count) … … 119 119 } 120 120 }; 121 unsigned NodeCounter::count = 0;122 static NodeCounter nodeCounter;121 unsigned ParserRefCountedCounter::count = 0; 122 static ParserRefCountedCounter parserRefCountedCounter; 123 123 #endif 124 124 125 static HashSet<Node*>* newNodes; 126 static HashCountedSet<Node*>* nodeExtraRefCounts; 125 static HashSet<ParserRefCounted*>* newTrackedObjects; 126 static HashCountedSet<ParserRefCounted*>* trackedObjectExtraRefCounts; 127 128 ParserRefCounted::ParserRefCounted() 129 { 130 #ifndef NDEBUG 131 ++ParserRefCountedCounter::count; 132 #endif 133 if (!newTrackedObjects) 134 newTrackedObjects = new HashSet<ParserRefCounted*>; 135 newTrackedObjects->add(this); 136 ASSERT(newTrackedObjects->contains(this)); 137 } 138 139 ParserRefCounted::~ParserRefCounted() 140 { 141 #ifndef NDEBUG 142 --ParserRefCountedCounter::count; 143 #endif 144 } 145 146 void ParserRefCounted::ref() 147 { 148 // bumping from 0 to 1 is just removing from the new nodes set 149 if (newTrackedObjects) { 150 HashSet<ParserRefCounted*>::iterator it = newTrackedObjects->find(this); 151 if (it != newTrackedObjects->end()) { 152 newTrackedObjects->remove(it); 153 ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(this)); 154 return; 155 } 156 } 157 158 ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this)); 159 160 if (!trackedObjectExtraRefCounts) 161 trackedObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>; 162 trackedObjectExtraRefCounts->add(this); 163 } 164 165 void ParserRefCounted::deref() 166 { 167 ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this)); 168 169 if (!trackedObjectExtraRefCounts) { 170 delete this; 171 return; 172 } 173 174 HashCountedSet<ParserRefCounted*>::iterator it = trackedObjectExtraRefCounts->find(this); 175 if (it == trackedObjectExtraRefCounts->end()) 176 delete this; 177 else 178 trackedObjectExtraRefCounts->remove(it); 179 } 180 181 unsigned ParserRefCounted::refcount() 182 { 183 if (newTrackedObjects && newTrackedObjects->contains(this)) { 184 ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(this)); 185 return 0; 186 } 187 188 ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this)); 189 190 if (!trackedObjectExtraRefCounts) 191 return 1; 192 193 return 1 + trackedObjectExtraRefCounts->count(this); 194 } 195 196 void ParserRefCounted::deleteNewObjects() 197 { 198 if (!newTrackedObjects) 199 return; 200 201 #ifndef NDEBUG 202 HashSet<ParserRefCounted*>::iterator end = newTrackedObjects->end(); 203 for (HashSet<ParserRefCounted*>::iterator it = newTrackedObjects->begin(); it != end; ++it) 204 ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(*it)); 205 #endif 206 deleteAllValues(*newTrackedObjects); 207 delete newTrackedObjects; 208 newTrackedObjects = 0; 209 } 127 210 128 211 Node::Node() … … 130 213 , m_expectedReturnType(ObjectType) 131 214 { 132 #ifndef NDEBUG133 ++NodeCounter::count;134 #endif135 215 m_line = lexer().lineNo(); 136 if (!newNodes)137 newNodes = new HashSet<Node*>;138 newNodes->add(this);139 216 } 140 217 … … 143 220 , m_expectedReturnType(expectedReturn) 144 221 { 145 #ifndef NDEBUG146 ++NodeCounter::count;147 #endif148 222 m_line = lexer().lineNo(); 149 if (!newNodes)150 newNodes = new HashSet<Node*>;151 newNodes->add(this);152 }153 154 Node::~Node()155 {156 #ifndef NDEBUG157 --NodeCounter::count;158 #endif159 }160 161 void Node::ref()162 {163 // bumping from 0 to 1 is just removing from the new nodes set164 if (newNodes) {165 HashSet<Node*>::iterator it = newNodes->find(this);166 if (it != newNodes->end()) {167 newNodes->remove(it);168 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));169 return;170 }171 }172 173 ASSERT(!newNodes || !newNodes->contains(this));174 175 if (!nodeExtraRefCounts)176 nodeExtraRefCounts = new HashCountedSet<Node*>;177 nodeExtraRefCounts->add(this);178 }179 180 void Node::deref()181 {182 ASSERT(!newNodes || !newNodes->contains(this));183 184 if (!nodeExtraRefCounts) {185 delete this;186 return;187 }188 189 HashCountedSet<Node*>::iterator it = nodeExtraRefCounts->find(this);190 if (it == nodeExtraRefCounts->end())191 delete this;192 else193 nodeExtraRefCounts->remove(it);194 }195 196 unsigned Node::refcount()197 {198 if (newNodes && newNodes->contains(this)) {199 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));200 return 0;201 }202 203 ASSERT(!newNodes || !newNodes->contains(this));204 205 if (!nodeExtraRefCounts)206 return 1;207 208 return 1 + nodeExtraRefCounts->count(this);209 }210 211 void Node::clearNewNodes()212 {213 if (!newNodes)214 return;215 216 #ifndef NDEBUG217 HashSet<Node*>::iterator end = newNodes->end();218 for (HashSet<Node*>::iterator it = newNodes->begin(); it != end; ++it)219 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));220 #endif221 deleteAllValues(*newNodes);222 delete newNodes;223 newNodes = 0;224 223 } 225 224 … … 4401 4400 // ------------------------------ FunctionBodyNode ----------------------------- 4402 4401 4403 ScopeNode::ScopeNode(SourceElements* children )4402 ScopeNode::ScopeNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack) 4404 4403 : BlockNode(children) 4405 4404 , m_sourceURL(parser().sourceURL()) 4406 4405 , m_sourceId(parser().sourceId()) 4407 4406 { 4408 } 4409 4410 ProgramNode::ProgramNode(SourceElements* children) 4411 : ScopeNode(children) 4412 { 4413 } 4414 4415 EvalNode::EvalNode(SourceElements* children) 4416 : ScopeNode(children) 4417 { 4418 } 4419 4420 FunctionBodyNode::FunctionBodyNode(SourceElements* children) 4421 : ScopeNode(children) 4407 if (varStack) 4408 m_varStack = *varStack; 4409 4410 if (funcStack) 4411 m_functionStack = *funcStack; 4412 } 4413 4414 ProgramNode::ProgramNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack) 4415 : ScopeNode(children, varStack, funcStack) 4416 { 4417 } 4418 4419 EvalNode::EvalNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack) 4420 : ScopeNode(children, varStack, funcStack) 4421 { 4422 } 4423 4424 FunctionBodyNode::FunctionBodyNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack) 4425 : ScopeNode(children, varStack, funcStack) 4422 4426 , m_initialized(false) 4423 4427 { 4424 4428 } 4425 4429 4426 void ScopeNode::initializeDeclarationStacks(ExecState* exec) 4427 { 4428 DeclarationStacks::NodeStack nodeStack; 4429 DeclarationStacks stacks(exec, nodeStack, m_varStack, m_functionStack); 4430 Node* node = statementListInitializeDeclarationStack(*m_children, nodeStack); 4431 if (!node) 4432 return; 4433 4434 while (true) { 4435 ASSERT(node->mayHaveDeclarations()); // Otherwise, we wasted time putting an irrelevant node on the stack. 4436 node->getDeclarations(stacks); 4437 4438 size_t size = nodeStack.size(); 4439 if (!size) 4440 break; 4441 --size; 4442 node = nodeStack[size]; 4443 nodeStack.shrink(size); 4444 } 4445 } 4446 4447 void FunctionBodyNode::initializeSymbolTable() 4430 void FunctionBodyNode::initializeSymbolTable(ExecState* exec) 4448 4431 { 4449 4432 size_t i, size; … … 4451 4434 4452 4435 // The order of additions here implicitly enforces the mutual exclusion described in ECMA 10.1.3. 4453 for (i = 0, size = m_varStack.size(); i < size; ++i) 4454 m_symbolTable.set(m_varStack[i]->ident.ustring().rep(), count++); 4436 for (i = 0, size = m_varStack.size(); i < size; ++i) { 4437 if (m_varStack[i]->ident != exec->propertyNames().arguments) 4438 m_symbolTable.set(m_varStack[i]->ident.ustring().rep(), count); 4439 count++; 4440 } 4455 4441 4456 4442 for (i = 0, size = m_parameters.size(); i < size; ++i) … … 4483 4469 { 4484 4470 if (!m_initialized) { 4485 initializeDeclarationStacks(exec); 4486 initializeSymbolTable(); 4471 initializeSymbolTable(exec); 4487 4472 optimizeVariableAccess(); 4488 4473 … … 4521 4506 void ProgramNode::processDeclarations(ExecState* exec) 4522 4507 { 4523 initializeDeclarationStacks(exec);4524 4525 4508 size_t i, size; 4526 4509 … … 4547 4530 void EvalNode::processDeclarations(ExecState* exec) 4548 4531 { 4549 initializeDeclarationStacks(exec);4550 4551 4532 size_t i, size; 4552 4533 -
trunk/JavaScriptCore/kjs/nodes.h
r28608 r28854 112 112 }; 113 113 114 class Node : Noncopyable { 115 public: 116 Node() KJS_FAST_CALL; 117 Node(PlacementNewAdoptType) KJS_FAST_CALL { } 118 virtual ~Node(); 119 120 UString toString() const KJS_FAST_CALL; 121 int lineNo() const KJS_FAST_CALL { return m_line; } 114 class ParserRefCounted : Noncopyable { 115 protected: 116 ParserRefCounted() KJS_FAST_CALL; 117 ParserRefCounted(PlacementNewAdoptType) KJS_FAST_CALL { } 118 119 public: 122 120 void ref() KJS_FAST_CALL; 123 121 void deref() KJS_FAST_CALL; 124 122 unsigned refcount() KJS_FAST_CALL; 125 static void clearNewNodes() KJS_FAST_CALL; 123 124 static void deleteNewObjects() KJS_FAST_CALL; 125 126 virtual ~ParserRefCounted(); 127 }; 128 129 class Node : public ParserRefCounted { 130 public: 131 Node() KJS_FAST_CALL; 132 Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL 133 : ParserRefCounted(placementAdopt) { } 134 135 UString toString() const KJS_FAST_CALL; 136 int lineNo() const KJS_FAST_CALL { return m_line; } 126 137 127 138 // Serialization. … … 1845 1856 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1846 1857 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL; 1858 VarDeclNode* getVarDecl() { return varDecl.get(); } 1847 1859 private: 1848 1860 Identifier ident; … … 1952 1964 class ScopeNode : public BlockNode { 1953 1965 public: 1954 ScopeNode(SourceElements* ) KJS_FAST_CALL;1966 ScopeNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL; 1955 1967 1956 1968 int sourceId() KJS_FAST_CALL { return m_sourceId; } … … 1958 1970 1959 1971 protected: 1960 void initializeDeclarationStacks(ExecState*) KJS_FAST_CALL;1961 1972 1962 1973 DeclarationStacks::VarStack m_varStack; … … 1970 1981 class ProgramNode : public ScopeNode { 1971 1982 public: 1972 ProgramNode(SourceElements* ) KJS_FAST_CALL;1983 ProgramNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL; 1973 1984 virtual Completion execute(ExecState*) KJS_FAST_CALL; 1974 1985 … … 1979 1990 class EvalNode : public ScopeNode { 1980 1991 public: 1981 EvalNode(SourceElements* ) KJS_FAST_CALL;1992 EvalNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL; 1982 1993 virtual Completion execute(ExecState*) KJS_FAST_CALL; 1983 1994 … … 1988 1999 class FunctionBodyNode : public ScopeNode { 1989 2000 public: 1990 FunctionBodyNode(SourceElements* ) KJS_FAST_CALL;2001 FunctionBodyNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL; 1991 2002 1992 2003 virtual Completion execute(ExecState*) KJS_FAST_CALL; … … 1998 2009 1999 2010 private: 2000 void initializeSymbolTable( ) KJS_FAST_CALL;2011 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 2001 2012 void optimizeVariableAccess() KJS_FAST_CALL; 2002 2013 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
Note:
See TracChangeset
for help on using the changeset viewer.