Reviewed by Eric Seidel.
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2007 22:59:29 +0000 (22:59 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2007 22:59:29 +0000 (22:59 +0000)
        Cleaned up the JavaScript grammar a bit.

        1. Changed BlockNode to always hold a child vector (which may be empty),
        eliminating a few NULL-check branches in the common execution case.

        2. Changed the Block production to correctly report its starting and
        ending line numbers to the debugger. (It used to report its ending line
        as its starting line.) Also, removed duplicate line-reporting code
        inside the BlockNode constructor.

        3. Moved curly braces up from FunctionBody production into parent
        productions. (I had to move the line number reporting code, too, since
        it depends on the location of the curly braces.) This matches the ECMA
        spec more closely, and makes some future changes I plan easier.

        4. Fixed statementList* convenience functions to deal appropriately with
        empty Vectors.

        SunSpider reports a small and statistically insignificant speedup.

        * kjs/grammar.y:
        * kjs/nodes.cpp:
        (KJS::statementListPushFIFO):
        (KJS::statementListGetDeclarations):
        (KJS::statementListInitializeDeclarationStack):
        (KJS::statementListInitializeVariableAccessStack):
        (KJS::BlockNode::BlockNode):
        (KJS::BlockNode::optimizeVariableAccess):
        (KJS::BlockNode::getDeclarations):
        (KJS::BlockNode::execute):
        (KJS::FunctionBodyNode::initializeDeclarationStacks):
        (KJS::FunctionBodyNode::optimizeVariableAccess):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@27799 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/grammar.y
JavaScriptCore/kjs/nodes.cpp

index bef48d2411b8d0ac498b13ea3ccb0a4846572a59..d2cb8f3a453ec0f2b346454351f765151df6770f 100644 (file)
@@ -1,3 +1,40 @@
+2007-11-14  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Eric Seidel.
+        
+        Cleaned up the JavaScript grammar a bit.
+        
+        1. Changed BlockNode to always hold a child vector (which may be empty),
+        eliminating a few NULL-check branches in the common execution case.
+        
+        2. Changed the Block production to correctly report its starting and 
+        ending line numbers to the debugger. (It used to report its ending line
+        as its starting line.) Also, removed duplicate line-reporting code
+        inside the BlockNode constructor.
+        
+        3. Moved curly braces up from FunctionBody production into parent
+        productions. (I had to move the line number reporting code, too, since
+        it depends on the location of the curly braces.) This matches the ECMA
+        spec more closely, and makes some future changes I plan easier.
+        
+        4. Fixed statementList* convenience functions to deal appropriately with
+        empty Vectors.
+
+        SunSpider reports a small and statistically insignificant speedup.
+
+        * kjs/grammar.y:
+        * kjs/nodes.cpp:
+        (KJS::statementListPushFIFO):
+        (KJS::statementListGetDeclarations):
+        (KJS::statementListInitializeDeclarationStack):
+        (KJS::statementListInitializeVariableAccessStack):
+        (KJS::BlockNode::BlockNode):
+        (KJS::BlockNode::optimizeVariableAccess):
+        (KJS::BlockNode::getDeclarations):
+        (KJS::BlockNode::execute):
+        (KJS::FunctionBodyNode::initializeDeclarationStacks):
+        (KJS::FunctionBodyNode::optimizeVariableAccess):
+
 2007-11-13  Anders Carlsson  <andersca@apple.com>
 
         Add RefCounted.h (And remove Shared.h)
index 1ab252b55dc540e663b3af831347e859a0844a42..311bdc0ac8286d38e02f938699763d8493818749 100644 (file)
@@ -235,9 +235,9 @@ Property:
     IDENT ':' AssignmentExpr            { $$ = new PropertyNode(*$1, $3, PropertyNode::Constant); }
   | STRING ':' AssignmentExpr           { $$ = new PropertyNode(Identifier(*$1), $3, PropertyNode::Constant); }
   | NUMBER ':' AssignmentExpr           { $$ = new PropertyNode(Identifier(UString::from($1)), $3, PropertyNode::Constant); }
-  | IDENT IDENT '(' ')' FunctionBody    { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, 0, $5); if (!$$) YYABORT; }
-  | IDENT IDENT '(' FormalParameterList ')' FunctionBody
-                                        { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, $4.head, $6); if (!$$) YYABORT; }
+  | IDENT IDENT '(' ')' '{' FunctionBody '}'    { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, 0, $6); DBG($6, @5, @7); if (!$$) YYABORT; }
+  | IDENT IDENT '(' FormalParameterList ')' '{' FunctionBody '}'
+                                        { $$ = makeGetterOrSetterPropertyNode(*$1, *$2, $4.head, $7); DBG($7, @6, @8); if (!$$) YYABORT; }
 ;
 
 PropertyList:
@@ -659,8 +659,8 @@ Statement:
 ;
 
 Block:
-    '{' '}'                             { $$ = new BlockNode(0); DBG($$, @2, @2); }
-  | '{' SourceElements '}'              { $$ = new BlockNode($2); DBG($$, @3, @3); }
+    '{' '}'                             { $$ = new BlockNode(new SourceElements); DBG($$, @1, @2); }
+  | '{' SourceElements '}'              { $$ = new BlockNode($2); DBG($$, @1, @3); }
 ;
 
 VariableStatement:
@@ -851,18 +851,16 @@ DebuggerStatement:
 ;
 
 FunctionDeclaration:
-    FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncDeclNode(*$2, $5); }
-  | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
-                                        { $$ = new FuncDeclNode(*$2, $4.head, $6); }
+    FUNCTION IDENT '(' ')' '{' FunctionBody '}' { $$ = new FuncDeclNode(*$2, $6); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}'
+                                        { $$ = new FuncDeclNode(*$2, $4.head, $7); DBG($7, @6, @8); }
 ;
 
 FunctionExpr:
-    FUNCTION '(' ')' FunctionBody       { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $4); }
-  | FUNCTION '(' FormalParameterList ')' FunctionBody
-                                        { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5, $3.head); }
-  | FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncExprNode(*$2, $5); }
-  | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
-                                        { $$ = new FuncExprNode(*$2, $6, $4.head); }
+    FUNCTION '(' ')' '{' FunctionBody '}' { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5); DBG($5, @4, @6); }
+  | FUNCTION '(' FormalParameterList ')' '{' FunctionBody '}' { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $6, $3.head); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' ')' '{' FunctionBody '}' { $$ = new FuncExprNode(*$2, $6); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}' { $$ = new FuncExprNode(*$2, $7, $4.head); DBG($7, @6, @8); }
 ;
 
 FormalParameterList:
@@ -873,18 +871,17 @@ FormalParameterList:
 ;
 
 FunctionBody:
-    '{' '}' /* not in spec */           { $$ = new FunctionBodyNode(0); DBG($$, @1, @2); }
-  | '{' SourceElements '}'              { $$ = new FunctionBodyNode($2); DBG($$, @1, @3); }
+    /* not in spec */           { $$ = new FunctionBodyNode(new SourceElements); }
+  | SourceElements              { $$ = new FunctionBodyNode($1); }
 ;
 
 Program:
-    /* not in spec */                   { Parser::accept(new ProgramNode(0)); }
+    /* not in spec */                   { Parser::accept(new ProgramNode(new SourceElements)); }
     | SourceElements                    { Parser::accept(new ProgramNode($1)); }
 ;
 
 SourceElements:
-    SourceElement                       { $$ = new Vector<RefPtr<StatementNode> >();
-                                          $$->append($1); }
+    SourceElement                       { $$ = new SourceElements; $$->append($1); }
   | SourceElements SourceElement        { $$->append($2); }
 ;
 
index 618e370502f3d274b8a75af6fe33e6106cf7e6a0..4b97e553798e811fbd848d74a21313f37d0ab60e 100644 (file)
@@ -3596,24 +3596,41 @@ void VarStatementNode::getDeclarations(DeclarationStacks& stacks)
 
 static inline void statementListPushFIFO(SourceElements& statements, DeclarationStacks::NodeStack& stack)
 {
-    for (SourceElements::iterator ptr = statements.end() - 1; ptr >= statements.begin(); --ptr)
-        stack.append((*ptr).get());
+    SourceElements::iterator it = statements.end();
+    SourceElements::iterator begin = statements.begin();
+    while (it != begin) {
+        --it;
+        stack.append((*it).get());
+    }
 }
 
 static inline void statementListGetDeclarations(SourceElements& statements, DeclarationStacks& stacks)
 {
-    for (SourceElements::iterator ptr = statements.end() - 1; ptr >= statements.begin(); --ptr)
-        if ((*ptr)->mayHaveDeclarations())
-            stacks.nodeStack.append((*ptr).get());
+    SourceElements::iterator it = statements.end();
+    SourceElements::iterator begin = statements.begin();
+    while (it != begin) {
+        --it;
+        if ((*it)->mayHaveDeclarations())
+            stacks.nodeStack.append((*it).get());
+    }
 }
 
-static inline Node* statementListInitializeDeclarationStacks(SourceElements& statements, DeclarationStacks::NodeStack& stack)
+static inline Node* statementListInitializeDeclarationStack(SourceElements& statements, DeclarationStacks::NodeStack& stack)
 {
-    for (SourceElements::iterator ptr = statements.end() - 1; ptr >= statements.begin(); --ptr)
-        if ((*ptr)->mayHaveDeclarations())
-             stack.append((*ptr).get());
+    ASSERT(!stack.size()); // Otherwise, the removeLast() call might remove someone else's node.
+    
+    SourceElements::iterator it = statements.end();
+    SourceElements::iterator begin = statements.begin();
+    
+    while (it != begin) {
+        --it;
+        if ((*it)->mayHaveDeclarations())
+             stack.append((*it).get());
+    }
+
     if (!stack.size())
         return 0;
+
     Node* n = stack.last();
     stack.removeLast();
     return n;
@@ -3621,9 +3638,19 @@ static inline Node* statementListInitializeDeclarationStacks(SourceElements& sta
 
 static inline Node* statementListInitializeVariableAccessStack(SourceElements& statements, DeclarationStacks::NodeStack& stack)
 {
-    for (SourceElements::iterator ptr = statements.end() - 1; ptr != statements.begin(); --ptr)
-        stack.append((*ptr).get());
-    return statements[0].get();
+    if (!statements.size())
+        return 0;
+
+    SourceElements::iterator it = statements.end();
+    SourceElements::iterator begin = statements.begin();
+    SourceElements::iterator beginPlusOne = begin + 1;
+    
+    while (it != beginPlusOne) {
+        --it;
+        stack.append((*it).get());
+    }
+
+    return (*begin).get();
 }
 
 static inline Completion statementListExecute(SourceElements& statements, ExecState* exec)
@@ -3646,34 +3673,27 @@ static inline Completion statementListExecute(SourceElements& statements, ExecSt
     
 // ------------------------------ BlockNode ------------------------------------
 
-void BlockNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
-{
-    if (m_children)
-        statementListPushFIFO(*m_children, nodeStack);
-}
-
 BlockNode::BlockNode(SourceElements* children)
 {
-  if (children) {
+    ASSERT(children);
     m_mayHaveDeclarations = true; 
     m_children.set(children);
-    setLoc(children->at(0)->firstLine(), children->at(children->size() - 1)->lastLine());
-  }
+}
+
+void BlockNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
+{
+    statementListPushFIFO(*m_children, nodeStack);
 }
 
 void BlockNode::getDeclarations(DeclarationStacks& stacks)
 { 
-    ASSERT(m_children);
     statementListGetDeclarations(*m_children, stacks);
 }
 
 // ECMA 12.1
 Completion BlockNode::execute(ExecState *exec)
 {
-  if (!m_children)
-    return Completion(Normal);
-
-  return statementListExecute(*m_children, exec);
+    return statementListExecute(*m_children, exec);
 }
 
 // ------------------------------ EmptyStatementNode ---------------------------
@@ -4403,12 +4423,9 @@ FunctionBodyNode::FunctionBodyNode(SourceElements* children)
 
 void FunctionBodyNode::initializeDeclarationStacks(ExecState* exec)
 {
-    if (!m_children)
-        return;
-
     DeclarationStacks::NodeStack nodeStack;
     DeclarationStacks stacks(exec, nodeStack, m_varStack, m_functionStack);
-    Node* node = statementListInitializeDeclarationStacks(*m_children, nodeStack);
+    Node* node = statementListInitializeDeclarationStack(*m_children, nodeStack);
     if (!node)
         return;
     
@@ -4447,9 +4464,6 @@ void FunctionBodyNode::initializeSymbolTable()
 
 void FunctionBodyNode::optimizeVariableAccess()
 {
-    if (!m_children)
-        return;
-
     DeclarationStacks::NodeStack nodeStack;
     Node* node = statementListInitializeVariableAccessStack(*m_children, nodeStack);
     if (!node)