Changeset 28973

Show
Ignore:
Timestamp:
12/24/07 02:13:00 (11 months ago)
Author:
mjs@apple.com
Message:

Reviewed by Eric.


3.5% speedup on SunSpider.

var statements now result in either assignments or empty statements.


This allows a couple of optimization opportunities:

  • No need to branch at runtime to check if there is an initializer
  • EmptyStatementNodes can be removed entirely (also done in this patch)
  • Assignment expressions get properly optimized for local variables


This patch also includes some code cleanup:

  • Most of the old VarStatement/VarDecl logic is now only used for const declarations, thus it is renamed appropriately
  • AssignExprNode is gone


  • JavaScriptCore.exp:
  • kjs/NodeInfo.h:
  • kjs/grammar.y:
  • kjs/nodes.cpp: (KJS::SourceElements::append): (KJS::ConstDeclNode::ConstDeclNode): (KJS::ConstDeclNode::optimizeVariableAccess): (KJS::ConstDeclNode::handleSlowCase): (KJS::ConstDeclNode::evaluateSingle): (KJS::ConstDeclNode::evaluate): (KJS::ConstStatementNode::optimizeVariableAccess): (KJS::ConstStatementNode::execute): (KJS::VarStatementNode::optimizeVariableAccess): (KJS::VarStatementNode::execute): (KJS::ForInNode::ForInNode): (KJS::ForInNode::optimizeVariableAccess): (KJS::ForInNode::execute): (KJS::FunctionBodyNode::initializeSymbolTable): (KJS::ProgramNode::initializeSymbolTable): (KJS::FunctionBodyNode::processDeclarations): (KJS::ProgramNode::processDeclarations): (KJS::EvalNode::processDeclarations):
  • kjs/nodes.h: (KJS::DeclarationStacks::): (KJS::StatementNode::): (KJS::ConstDeclNode::): (KJS::ConstStatementNode::): (KJS::EmptyStatementNode::): (KJS::VarStatementNode::): (KJS::ForNode::):
  • kjs/nodes2string.cpp: (KJS::ConstDeclNode::streamTo): (KJS::ConstStatementNode::streamTo): (KJS::ScopeNode::streamTo): (KJS::VarStatementNode::streamTo): (KJS::ForNode::streamTo): (KJS::ForInNode::streamTo):
Location:
trunk/JavaScriptCore
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r28950 r28973  
     12007-12-24  Maciej Stachowiak  <mjs@apple.com> 
     2 
     3        Reviewed by Eric. 
     4 
     5        - Optimize variable declarations 
     6        http://bugs.webkit.org/show_bug.cgi?id=16585 
     7         
     8        3.5% speedup on SunSpider. 
     9 
     10        var statements now result in either assignments or empty statements. 
     11         
     12        This allows a couple of optimization opportunities: 
     13        - No need to branch at runtime to check if there is an initializer 
     14        - EmptyStatementNodes can be removed entirely (also done in this patch) 
     15        - Assignment expressions get properly optimized for local variables 
     16         
     17        This patch also includes some code cleanup: 
     18        - Most of the old VarStatement/VarDecl logic is now only used for const declarations,  
     19          thus it is renamed appropriately 
     20        - AssignExprNode is gone 
     21         
     22        * JavaScriptCore.exp: 
     23        * kjs/NodeInfo.h: 
     24        * kjs/grammar.y: 
     25        * kjs/nodes.cpp: 
     26        (KJS::SourceElements::append): 
     27        (KJS::ConstDeclNode::ConstDeclNode): 
     28        (KJS::ConstDeclNode::optimizeVariableAccess): 
     29        (KJS::ConstDeclNode::handleSlowCase): 
     30        (KJS::ConstDeclNode::evaluateSingle): 
     31        (KJS::ConstDeclNode::evaluate): 
     32        (KJS::ConstStatementNode::optimizeVariableAccess): 
     33        (KJS::ConstStatementNode::execute): 
     34        (KJS::VarStatementNode::optimizeVariableAccess): 
     35        (KJS::VarStatementNode::execute): 
     36        (KJS::ForInNode::ForInNode): 
     37        (KJS::ForInNode::optimizeVariableAccess): 
     38        (KJS::ForInNode::execute): 
     39        (KJS::FunctionBodyNode::initializeSymbolTable): 
     40        (KJS::ProgramNode::initializeSymbolTable): 
     41        (KJS::FunctionBodyNode::processDeclarations): 
     42        (KJS::ProgramNode::processDeclarations): 
     43        (KJS::EvalNode::processDeclarations): 
     44        * kjs/nodes.h: 
     45        (KJS::DeclarationStacks::): 
     46        (KJS::StatementNode::): 
     47        (KJS::ConstDeclNode::): 
     48        (KJS::ConstStatementNode::): 
     49        (KJS::EmptyStatementNode::): 
     50        (KJS::VarStatementNode::): 
     51        (KJS::ForNode::): 
     52        * kjs/nodes2string.cpp: 
     53        (KJS::ConstDeclNode::streamTo): 
     54        (KJS::ConstStatementNode::streamTo): 
     55        (KJS::ScopeNode::streamTo): 
     56        (KJS::VarStatementNode::streamTo): 
     57        (KJS::ForNode::streamTo): 
     58        (KJS::ForInNode::streamTo): 
     59 
    1602007-12-21  Mark Rowe  <mrowe@apple.com> 
    261 
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r28950 r28973  
    121121__ZN3KJS11JSImmediate8toObjectEPKNS_7JSValueEPNS_9ExecStateE 
    122122__ZN3KJS11JSImmediate8toStringEPKNS_7JSValueE 
    123 __ZN3KJS11ProgramNodeC1EPNS_14SourceElementsEPN3WTF6VectorIPNS_11VarDeclNodeELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE 
     123__ZN3KJS11ProgramNodeC1EPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE 
    124124__ZN3KJS11PropertyMap11getLocationERKNS_10IdentifierE 
    125125__ZN3KJS11PropertyMap5clearEv 
  • trunk/JavaScriptCore/kjs/NodeInfo.h

    r28937 r28973  
    3737typedef NodeInfo<SourceElements*> SourceElementsInfo; 
    3838typedef NodeInfo<ClauseList> ClauseListInfo; 
    39 typedef NodeInfo<VarDeclList> VarDeclListInfo; 
     39typedef NodeInfo<ExpressionNode*> VarDeclListInfo; 
     40typedef NodeInfo<ConstDeclList> ConstDeclListInfo; 
    4041 
    4142} // namespace KJS 
  • trunk/JavaScriptCore/kjs/grammar.y

    r28937 r28973  
    7171static ExpressionNode* makeNegateNode(ExpressionNode*); 
    7272static NumberNode* makeNumberNode(double); 
     73static StatementNode* makeVarStatementNode(ExpressionNode*); 
     74static ExpressionNode* combineVarInitializers(ExpressionNode* list, AssignResolveNode* init); 
     75 
    7376 
    7477#if COMPILER(MSVC) 
     
    112115} 
    113116 
    114 static void appendToVarDeclarationList(ParserRefCountedData<DeclarationStacks::VarStack>*& varDecls, VarDeclNode* decl) 
     117static void appendToVarDeclarationList(ParserRefCountedData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs) 
    115118{ 
    116119    if (!varDecls) 
    117120        varDecls = new ParserRefCountedData<DeclarationStacks::VarStack>; 
    118     varDecls->data.append(decl); 
     121 
     122    varDecls->data.append(make_pair(ident, attrs)); 
     123 
     124} 
     125 
     126static inline void appendToVarDeclarationList(ParserRefCountedData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl) 
     127{ 
     128    unsigned attrs = DeclarationStacks::IsConstant; 
     129    if (decl->init) 
     130        attrs |= DeclarationStacks::HasInitializer;         
     131    appendToVarDeclarationList(varDecls, decl->ident, attrs); 
    119132} 
    120133 
     
    132145    PropertyNode*       propertyNode; 
    133146    ArgumentsNode*      argumentsNode; 
    134     VarDeclNode*        varDeclNode; 
     147    ConstDeclNode*      constDeclNode; 
    135148    CaseBlockNodeInfo   caseBlockNode; 
    136149    CaseClauseNodeInfo  caseClauseNode; 
    137150    FuncExprNode*       funcExprNode; 
    138     AssignExprNode*     assignExprNode; 
    139151 
    140152    // statement nodes 
     
    147159    ArgumentList        argumentList; 
    148160    VarDeclListInfo     varDeclList; 
     161    ConstDeclListInfo   constDeclList; 
    149162    ClauseListInfo      clauseList; 
    150163    ElementList         elementList; 
     
    229242%type <statementNode>   SourceElement 
    230243 
    231 %type <assignExprNode>  Initializer InitializerNoIn 
     244%type <expressionNode>  Initializer InitializerNoIn 
    232245%type <funcDeclNode>    FunctionDeclaration 
    233246%type <funcExprNode>    FunctionExpr 
     
    238251%type <argumentsNode>   Arguments 
    239252%type <argumentList>    ArgumentList 
    240 %type <varDeclList>     VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList 
    241 %type <varDeclNode>     VariableDeclaration VariableDeclarationNoIn ConstDeclaration 
     253%type <varDeclList>     VariableDeclarationList VariableDeclarationListNoIn 
     254%type <constDeclList>   ConstDeclarationList 
     255%type <constDeclNode>   ConstDeclaration 
    242256%type <caseBlockNode>   CaseBlock 
    243257%type <caseClauseNode>  CaseClause DefaultClause 
     
    704718 
    705719VariableStatement: 
    706     VAR VariableDeclarationList ';'     { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 
     720    VAR VariableDeclarationList ';'     { $$ = createNodeInfo<StatementNode*>(makeVarStatementNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations); 
    707721                                          DBG($$.m_node, @1, @3); } 
    708   | VAR VariableDeclarationList error   { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 
     722  | VAR VariableDeclarationList error   { $$ = createNodeInfo<StatementNode*>(makeVarStatementNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations); 
    709723                                          DBG($$.m_node, @1, @2); 
    710724                                          AUTO_SEMICOLON; } 
     
    712726 
    713727VariableDeclarationList: 
    714     VariableDeclaration                 { $$.m_node.head = $1; 
    715                                           $$.m_node.tail = $$.m_node.head; 
     728    IDENT                               { $$.m_node = 0; 
    716729                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 
    717                                           $$.m_varDeclarations->data.append($1); 
     730                                          appendToVarDeclarationList($$.m_varDeclarations, *$1, 0); 
    718731                                          $$.m_funcDeclarations = 0; 
    719732                                        } 
    720   | VariableDeclarationList ',' VariableDeclaration 
    721                                         { $$.m_node.head = $1.m_node.head; 
    722                                           $1.m_node.tail->next = $3; 
    723                                           $$.m_node.tail = $3; 
     733  | IDENT Initializer                   { $$.m_node = new AssignResolveNode(*$1, $2); 
     734                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 
     735                                          appendToVarDeclarationList($$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); 
     736                                          $$.m_funcDeclarations = 0; 
     737                                        } 
     738  | VariableDeclarationList ',' IDENT 
     739                                        { $$.m_node = $1.m_node; 
    724740                                          $$.m_varDeclarations = $1.m_varDeclarations; 
    725                                           $$.m_varDeclarations->data.append($3); 
     741                                          appendToVarDeclarationList($$.m_varDeclarations, *$3, 0); 
    726742                                          $$.m_funcDeclarations = 0; 
    727743                                        } 
     744  | VariableDeclarationList ',' IDENT Initializer 
     745                                        { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4)); 
     746                                          $$.m_varDeclarations = $1.m_varDeclarations; 
     747                                          appendToVarDeclarationList($$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); 
     748                                          $$.m_funcDeclarations = 0; 
     749                                        } 
    728750; 
    729751 
    730752VariableDeclarationListNoIn: 
    731     VariableDeclarationNoIn             { $$.m_node.head = $1;  
    732                                           $$.m_node.tail = $$.m_node.head; 
     753    IDENT                               { $$.m_node = 0; 
    733754                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 
    734                                           $$.m_varDeclarations->data.append($1); 
    735                                           $$.m_funcDeclarations = 0; } 
    736   | VariableDeclarationListNoIn ',' VariableDeclarationNoIn 
    737                                         { $$.m_node.head = $1.m_node.head; 
    738                                           $1.m_node.tail->next = $3; 
    739                                           $$.m_node.tail = $3;  
     755                                          appendToVarDeclarationList($$.m_varDeclarations, *$1, 0); 
     756                                          $$.m_funcDeclarations = 0; 
     757                                        } 
     758  | IDENT InitializerNoIn               { $$.m_node = new AssignResolveNode(*$1, $2); 
     759                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 
     760                                          appendToVarDeclarationList($$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); 
     761                                          $$.m_funcDeclarations = 0; 
     762                                        } 
     763  | VariableDeclarationListNoIn ',' IDENT 
     764                                        { $$.m_node = $1.m_node; 
    740765                                          $$.m_varDeclarations = $1.m_varDeclarations; 
    741                                           $$.m_varDeclarations->data.append($3); 
    742                                           $$.m_funcDeclarations = 0; } 
    743 ; 
    744  
    745 VariableDeclaration: 
    746     IDENT                               { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); } 
    747   | IDENT Initializer                   { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); } 
    748 ; 
    749  
    750 VariableDeclarationNoIn: 
    751     IDENT                               { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); } 
    752   | IDENT InitializerNoIn               { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); } 
     766                                          appendToVarDeclarationList($$.m_varDeclarations, *$3, 0); 
     767                                          $$.m_funcDeclarations = 0; 
     768                                        } 
     769  | VariableDeclarationListNoIn ',' IDENT InitializerNoIn 
     770                                        { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4)); 
     771                                          $$.m_varDeclarations = $1.m_varDeclarations; 
     772                                          appendToVarDeclarationList($$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); 
     773                                          $$.m_funcDeclarations = 0; 
     774                                        } 
    753775; 
    754776 
    755777ConstStatement: 
    756     CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 
     778    CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeInfo<StatementNode*>(new ConstStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 
    757779                                          DBG($$.m_node, @1, @3); } 
    758780  | CONSTTOKEN ConstDeclarationList error 
    759                                         { $$ = createNodeInfo<StatementNode*>(new VarStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 
     781                                        { $$ = createNodeInfo<StatementNode*>(new ConstStatementNode($2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations); 
    760782                                          DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } 
    761783; 
     
    765787                                          $$.m_node.tail = $$.m_node.head; 
    766788                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 
    767                                           $$.m_varDeclarations->data.append($1); 
     789                                          appendToVarDeclarationList($$.m_varDeclarations, $1); 
    768790                                          $$.m_funcDeclarations = 0; } 
    769791  | ConstDeclarationList ',' ConstDeclaration 
     
    772794                                          $$.m_node.tail = $3; 
    773795                                          $$.m_varDeclarations = $1.m_varDeclarations; 
    774                                           $$.m_varDeclarations->data.append($3); 
     796                                          appendToVarDeclarationList($$.m_varDeclarations, $3); 
    775797                                          $$.m_funcDeclarations = 0; } 
    776798; 
    777799 
    778800ConstDeclaration: 
    779     IDENT                               { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Constant); } 
    780   | IDENT Initializer                   { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Constant); } 
     801    IDENT                               { $$ = new ConstDeclNode(*$1, 0); } 
     802  | IDENT Initializer                   { $$ = new ConstDeclNode(*$1, $2); } 
    781803; 
    782804 
    783805Initializer: 
    784     '=' AssignmentExpr                  { $$ = new AssignExprNode($2); } 
     806    '=' AssignmentExpr                  { $$ = $2; } 
    785807; 
    786808 
    787809InitializerNoIn: 
    788     '=' AssignmentExprNoIn              { $$ = new AssignExprNode($2); } 
     810    '=' AssignmentExprNoIn              { $$ = $2; } 
    789811; 
    790812 
     
    817839                                          DBG($$.m_node, @1, @4); } 
    818840  | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement 
    819                                         { $$ = createNodeInfo<StatementNode*>(new ForNode($3, $5, $7, $9.m_node), $9.m_varDeclarations, $9.m_funcDeclarations); 
     841                                        { $$ = createNodeInfo<StatementNode*>(new ForNode($3, $5, $7, $9.m_node, false), $9.m_varDeclarations, $9.m_funcDeclarations); 
    820842                                          DBG($$.m_node, @1, @8);  
    821843                                        } 
    822844  | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement 
    823                                         { $$ = createNodeInfo<StatementNode*>(new ForNode($4.m_node.head, $6, $8, $10.m_node), 
     845                                                                            { $$ = createNodeInfo<StatementNode*>(new ForNode($4.m_node, $6, $8, $10.m_node, true), 
    824846                                                                              mergeDeclarationLists($4.m_varDeclarations, $10.m_varDeclarations), 
    825847                                                                              mergeDeclarationLists($4.m_funcDeclarations, $10.m_funcDeclarations)); 
     
    835857  | FOR '(' VAR IDENT INTOKEN Expr ')' Statement 
    836858                                        { ForInNode *forIn = new ForInNode(*$4, 0, $6, $8.m_node); 
    837                                           appendToVarDeclarationList($8.m_varDeclarations, forIn->getVarDecl()); 
     859                                          appendToVarDeclarationList($8.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); 
    838860                                          $$ = createNodeInfo<StatementNode*>(forIn, $8.m_varDeclarations, $8.m_funcDeclarations); 
    839861                                          DBG($$.m_node, @1, @7); } 
    840862  | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement 
    841863                                        { ForInNode *forIn = new ForInNode(*$4, $5, $7, $9.m_node); 
    842                                           appendToVarDeclarationList($9.m_varDeclarations, forIn->getVarDecl()); 
     864                                          appendToVarDeclarationList($9.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); 
    843865                                          $$ = createNodeInfo<StatementNode*>(forIn, $9.m_varDeclarations, $9.m_funcDeclarations); 
    844866                                          DBG($$.m_node, @1, @8); } 
     
    9811003    /* not in spec */           { $$ = new FunctionBodyNode(0, 0, 0); } 
    9821004  | SourceElements              { $$ = new FunctionBodyNode($1.m_node, $1.m_varDeclarations ? &$1.m_varDeclarations->data : 0,  
    983                                                                                   $1.m_funcDeclarations ? &$1.m_funcDeclarations->data : 0); 
     1005                                                            $1.m_funcDeclarations ? &$1.m_funcDeclarations->data : 0); 
    9841006                                  // As in mergeDeclarationLists() we have to ref/deref to safely get rid of 
    9851007                                  // the declaration lists. 
     
    12191241    return yychar == '}' || yychar == 0 || lexer().prevTerminator(); 
    12201242} 
     1243 
     1244static ExpressionNode* combineVarInitializers(ExpressionNode* list, AssignResolveNode* init) 
     1245{ 
     1246    if (!list) 
     1247        return init; 
     1248    return new CommaNode(list, init); 
     1249} 
     1250 
     1251// We turn variable declarations into either assignments or empty 
     1252// statements (which later get stripped out), because the actual 
     1253// declaration work is hoisted up to the start of the function body 
     1254static StatementNode* makeVarStatementNode(ExpressionNode* expr) 
     1255{ 
     1256    if (!expr) 
     1257        return new EmptyStatementNode(); 
     1258    return new VarStatementNode(expr); 
     1259} 
     1260 
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r28937 r28973  
    381381void SourceElements::append(PassRefPtr<StatementNode> statement) 
    382382{ 
     383    if (statement->isEmptyStatement()) 
     384        return; 
     385 
    383386    if (Debugger::debuggersPresent) 
    384387        m_statements.append(new BreakpointCheckStatement(statement)); 
     
    34203423} 
    34213424 
    3422 // ------------------------------ AssignExprNode ------------------------------- 
    3423  
    3424 void AssignExprNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack) 
    3425 { 
    3426     nodeStack.append(expr.get()); 
    3427 } 
    3428  
    3429 // ECMA 12.2 
    3430 JSValue* AssignExprNode::evaluate(ExecState* exec) 
    3431 { 
    3432     return expr->evaluate(exec); 
    3433 } 
    3434  
    3435 bool AssignExprNode::evaluateToBoolean(ExecState* exec) 
    3436 { 
    3437     return expr->evaluateToBoolean(exec); 
    3438 } 
    3439  
    3440 double AssignExprNode::evaluateToNumber(ExecState* exec) 
    3441 { 
    3442     return expr->evaluateToNumber(exec); 
    3443 } 
    3444  
    3445 int32_t AssignExprNode::evaluateToInt32(ExecState* exec) 
    3446 { 
    3447     return expr->evaluateToInt32(exec); 
    3448 } 
    3449  
    3450 uint32_t AssignExprNode::evaluateToUInt32(ExecState* exec) 
    3451 { 
    3452     return expr->evaluateToInt32(exec); 
    3453 } 
    3454  
    3455 // ------------------------------ VarDeclNode ---------------------------------- 
    3456  
    3457 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) 
    3458     : varType(t) 
    3459     , ident(id) 
     3425// ------------------------------ ConstDeclNode ---------------------------------- 
     3426 
     3427ConstDeclNode::ConstDeclNode(const Identifier& id, ExpressionNode* in) 
     3428    : ident(id) 
    34603429    , init(in) 
    34613430{ 
    34623431} 
    34633432 
    3464 void VarDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack) 
     3433void ConstDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack) 
    34653434{ 
    34663435    if (next) 
     
    34703439} 
    34713440 
    3472 void VarDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val) 
     3441void ConstDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val) 
    34733442{ 
    34743443    ScopeChainIterator iter = chain.begin(); 
     
    34913460    unsigned flags = 0; 
    34923461    base->getPropertyAttributes(ident, flags); 
    3493     if (varType == VarDeclNode::Constant) 
    3494         flags |= ReadOnly; 
     3462    flags |= ReadOnly; 
    34953463     
    34963464    base->put(exec, ident, val, flags); 
     
    34983466 
    34993467// ECMA 12.2 
    3500 inline void VarDeclNode::evaluateSingle(ExecState* exec) 
     3468inline void ConstDeclNode::evaluateSingle(ExecState* exec) 
    35013469{ 
    35023470    ASSERT(exec->variableObject()->hasOwnProperty(exec, ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations. 
     
    35143482            if (exec->codeType() != EvalCode) 
    35153483                flags |= DontDelete; 
    3516             if (varType == VarDeclNode::Constant) 
    3517                 flags |= ReadOnly; 
     3484            flags |= ReadOnly; 
    35183485            variableObject->put(exec, ident, val, flags); 
    35193486        } else { 
     
    35293496            unsigned flags = 0; 
    35303497            variableObject->getPropertyAttributes(ident, flags); 
    3531             if (varType == VarDeclNode::Constant) 
    3532                 flags |= ReadOnly; 
     3498            flags |= ReadOnly; 
    35333499             
    35343500            variableObject->put(exec, ident, val, flags); 
     
    35373503} 
    35383504 
    3539 JSValue* VarDeclNode::evaluate(ExecState* exec) 
     3505JSValue* ConstDeclNode::evaluate(ExecState* exec) 
    35403506{ 
    35413507    evaluateSingle(exec); 
    35423508 
    3543     if (VarDeclNode* n = next.get()) { 
     3509    if (ConstDeclNode* n = next.get()) { 
    35443510        do { 
    35453511            n->evaluateSingle(exec); 
     
    35513517} 
    35523518 
    3553 // ------------------------------ VarStatementNode ----------------------------- 
    3554  
    3555 void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack) 
     3519// ------------------------------ ConstStatementNode ----------------------------- 
     3520 
     3521void ConstStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack) 
    35563522{ 
    35573523    ASSERT(next); 
     
    35603526 
    35613527// ECMA 12.2 
    3562 JSValue* VarStatementNode::execute(ExecState* exec) 
     3528JSValue* ConstStatementNode::execute(ExecState* exec) 
    35633529{ 
    35643530    next->evaluate(exec); 
     
    36553621} 
    36563622 
     3623// ------------------------------ VarStatementNode ---------------------------- 
     3624 
     3625void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack) 
     3626{ 
     3627    ASSERT(expr); 
     3628    nodeStack.append(expr.get()); 
     3629} 
     3630 
     3631JSValue* VarStatementNode::execute(ExecState* exec) 
     3632{ 
     3633    expr->evaluate(exec); 
     3634    KJS_CHECKEXCEPTION 
     3635 
     3636    return exec->setNormalCompletion(); 
     3637} 
     3638 
    36573639// ------------------------------ IfNode --------------------------------------- 
    36583640 
     
    38273809 
    38283810ForInNode::ForInNode(ExpressionNode* l, ExpressionNode* e, StatementNode* s) 
    3829   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s) 
    3830 { 
    3831 } 
    3832  
    3833 ForInNode::ForInNode(const Identifier& i, AssignExprNode* in, ExpressionNode* e, StatementNode* s) 
    3834   : ident(i), init(in), expr(e), statement(s) 
    3835 { 
     3811    : init(0L), lexpr(l), expr(e), statement(s), identIsVarDecl(false) 
     3812{ 
     3813} 
     3814 
     3815ForInNode::ForInNode(const Identifier& i, ExpressionNode* in, ExpressionNode* e, StatementNode* s) 
     3816    : ident(i), lexpr(new ResolveNode(i)), expr(e), statement(s), identIsVarDecl(true) 
     3817{ 
     3818  if (in) 
     3819      init = new AssignResolveNode(i, in); 
    38363820  // for( var foo = bar in baz ) 
    3837   varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable); 
    3838   lexpr = new ResolveNode(ident); 
    38393821} 
    38403822 
     
    38443826    nodeStack.append(expr.get()); 
    38453827    nodeStack.append(lexpr.get()); 
    3846     if (varDecl) 
    3847         nodeStack.append(varDecl.get()); 
     3828    if (init) 
     3829        nodeStack.append(init.get()); 
    38483830} 
    38493831 
     
    38533835  JSValue* value = 0; 
    38543836 
    3855   if (varDecl) { 
    3856     varDecl->evaluate(exec); 
     3837  if (init) { 
     3838    init->evaluate(exec); 
    38573839    KJS_CHECKEXCEPTION 
    38583840  } 
     
    42684250 
    42694251    for (size_t i = 0, size = m_varStack.size(); i < size; ++i, ++localStorageIndex) { 
    4270         Identifier& ident = m_varStack[i]->ident; 
     4252        Identifier& ident = m_varStack[i].first; 
    42714253        if (ident == exec->propertyNames().arguments) 
    42724254            continue;