Changeset 29818 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp


Ignore:
Timestamp:
Jan 27, 2008, 1:38:01 AM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

Reviewed by Oliver.

  • fix <rdar://problem/5657450> REGRESSION: const is broken

Test: fast/js/const.html

SunSpider said this was 0.3% slower. And I saw some Shark samples in
JSGlobalObject::put -- not a lot but a few. We may be able to regain the
speed, but for now we will take that small hit for correctness sake.

  • kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::put): Pass the checkReadOnly flag in to symbolTablePut instead of passing attributes.
  • kjs/JSVariableObject.h: (KJS::JSVariableObject::symbolTablePut): Removed the code to set attributes here, since we only set attributes when creating a property. Added the code to check read-only here, since we need that to implement const!
  • kjs/function.cpp: (KJS::ActivationImp::put): Pass the checkReadOnly flag in to symbolTablePut instead of passing attributes.
  • kjs/nodes.cpp: (KJS::isConstant): Added. (KJS::PostIncResolveNode::optimizeVariableAccess): Create a PostIncConstNode if optimizing for a local variable and the variable is constant. (KJS::PostDecResolveNode::optimizeVariableAccess): Ditto. But PostDecConstNode. (KJS::PreIncResolveNode::optimizeVariableAccess): Ditto. But PreIncConstNode. (KJS::PreDecResolveNode::optimizeVariableAccess): Ditto. But PreDecConstNode. (KJS::PreIncConstNode::evaluate): Return the value + 1. (KJS::PreDecConstNode::evaluate): Return the value - 1. (KJS::PostIncConstNode::evaluate): Return the value converted to a number. (KJS::PostDecConstNode::evaluate): Ditto. (KJS::ReadModifyResolveNode::optimizeVariableAccess): Create a ReadModifyConstNode if optimizing for a local variable and the variable is constant. (KJS::AssignResolveNode::optimizeVariableAccess): Ditto. But AssignConstNode. (KJS::ScopeNode::optimizeVariableAccess): Pass the local storage to the node optimizeVariableAccess functions, since that's where we need to look to figure out if a variable is constant. (KJS::FunctionBodyNode::processDeclarations): Moved the call to optimizeVariableAccess until after localStorage is set up. (KJS::ProgramNode::processDeclarations): Ditto.
  • kjs/nodes.h: Fixed the IsConstant and HasInitializer values. They are used as flag masks, so a value of 0 will not work for IsConstant. Changed the first parameter to optimizeVariableAccess to be a const reference to a symbol table and added a const reference to local storage. Added classes for const versions of local variable access: PostIncConstNode, PostDecConstNode, PreIncConstNode, PreDecConstNode, ReadModifyConstNode, and AssignConstNode.
  • kjs/object.cpp: (KJS::JSObject::put): Tweaked comments a bit, and changed the checkReadOnly expression to match the form used at the two other call sites.

LayoutTests:

Reviewed by Oliver.

  • tests for <rdar://problem/5657450> REGRESSION: const is broken
  • fast/js/const-expected.txt: Updated with results that express success rather than failure, and to include the many new tests I added.
  • fast/js/kde/const-expected.txt: Ditto.
  • fast/js/resources/const.js: Added many new tests, covering the various cases of const in globals, function locals, the slow case inside eval, the different node types, and the values of the expressions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r29810 r29818  
    4747    class FunctionBodyNodeWithDebuggerHooks : public FunctionBodyNode {
    4848    public:
    49         FunctionBodyNodeWithDebuggerHooks(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     49        FunctionBodyNodeWithDebuggerHooks(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    5050        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    5151    };
     
    9898}
    9999#endif
     100
     101static inline bool isConstant(const LocalStorage& localStorage, size_t index)
     102{
     103    ASSERT(index < localStorage.size());
     104    return localStorage[index].attributes & ReadOnly;
     105}
    100106
    101107// ------------------------------ Node -----------------------------------------
     
    417423}
    418424
    419 void BreakpointCheckStatement::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     425void BreakpointCheckStatement::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    420426{
    421427    nodeStack.append(m_statement.get());
     
    585591}
    586592
    587 void ResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     593void ResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
    588594{
    589595    size_t index = symbolTable.get(ident.ustring().rep());
     
    625631// ------------------------------ ElementNode ----------------------------------
    626632
    627 void ElementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     633void ElementNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    628634{
    629635    if (next)
     
    649655// ------------------------------ ArrayNode ------------------------------------
    650656
    651 void ArrayNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     657void ArrayNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    652658{
    653659    if (element)
     
    680686// ------------------------------ ObjectLiteralNode ----------------------------
    681687
    682 void ObjectLiteralNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     688void ObjectLiteralNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    683689{
    684690    if (list)
     
    697703// ------------------------------ PropertyListNode -----------------------------
    698704
    699 void PropertyListNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     705void PropertyListNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    700706{
    701707    if (next)
     
    733739// ------------------------------ PropertyNode -----------------------------
    734740
    735 void PropertyNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     741void PropertyNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    736742{
    737743    nodeStack.append(assign.get());
     
    747753// ------------------------------ BracketAccessorNode --------------------------------
    748754
    749 void BracketAccessorNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     755void BracketAccessorNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    750756{
    751757    nodeStack.append(expr2.get());
     
    802808// ------------------------------ DotAccessorNode --------------------------------
    803809
    804 void DotAccessorNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     810void DotAccessorNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    805811{
    806812    nodeStack.append(expr.get());
     
    850856// ------------------------------ ArgumentListNode -----------------------------
    851857
    852 void ArgumentListNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     858void ArgumentListNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    853859{
    854860    if (next)
     
    870876// ------------------------------ ArgumentsNode --------------------------------
    871877
    872 void ArgumentsNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     878void ArgumentsNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    873879{
    874880    if (listNode)
     
    878884// ------------------------------ NewExprNode ----------------------------------
    879885
    880 void NewExprNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     886void NewExprNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    881887{
    882888    if (args)
     
    941947}   
    942948
    943 void FunctionCallValueNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     949void FunctionCallValueNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    944950{
    945951    nodeStack.append(args.get());
     
    972978}
    973979
    974 void FunctionCallResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack& nodeStack)
     980void FunctionCallResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage&, NodeStack& nodeStack)
    975981{
    976982    nodeStack.append(args.get());
     
    11181124}
    11191125
    1120 void FunctionCallBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1126void FunctionCallBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    11211127{
    11221128    nodeStack.append(args.get());
     
    11871193}
    11881194
    1189 void FunctionCallDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1195void FunctionCallDotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    11901196{
    11911197    nodeStack.append(args.get());
     
    12621268
    12631269// Increment
    1264 void PostIncResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     1270void PostIncResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    12651271{
    12661272    size_t index = symbolTable.get(m_ident.ustring().rep());
    1267     if (index != missingSymbolMarker())
    1268         new (this) PostIncLocalVarNode(index);
     1273    if (index != missingSymbolMarker()) {
     1274        if (isConstant(localStorage, index))
     1275            new (this) PostIncConstNode(index);
     1276        else
     1277            new (this) PostIncLocalVarNode(index);
     1278    }
    12691279}
    12701280
     
    13201330
    13211331// Decrement
    1322 void PostDecResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     1332void PostDecResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    13231333{
    13241334    size_t index = symbolTable.get(m_ident.ustring().rep());
    1325     if (index != missingSymbolMarker())
    1326         new (this) PostDecLocalVarNode(index);
     1335    if (index != missingSymbolMarker()) {
     1336        if (isConstant(localStorage, index))
     1337            new (this) PostDecConstNode(index);
     1338        else
     1339            new (this) PostDecLocalVarNode(index);
     1340    }
    13271341}
    13281342
     
    14081422// ------------------------------ PostfixBracketNode ----------------------------------
    14091423
    1410 void PostfixBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1424void PostfixBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    14111425{
    14121426    nodeStack.append(m_subscript.get());
     
    14771491// ------------------------------ PostfixDotNode ----------------------------------
    14781492
    1479 void PostfixDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1493void PostfixDotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    14801494{
    14811495    nodeStack.append(m_base.get());
     
    15241538// ------------------------------ DeleteResolveNode -----------------------------------
    15251539
    1526 void DeleteResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     1540void DeleteResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
    15271541{
    15281542    size_t index = symbolTable.get(m_ident.ustring().rep());
     
    15661580// ------------------------------ DeleteBracketNode -----------------------------------
    15671581
    1568 void DeleteBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1582void DeleteBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    15691583{
    15701584    nodeStack.append(m_subscript.get());
     
    15911605// ------------------------------ DeleteDotNode -----------------------------------
    15921606
    1593 void DeleteDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1607void DeleteDotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    15941608{
    15951609    nodeStack.append(m_base.get());
     
    16071621// ------------------------------ DeleteValueNode -----------------------------------
    16081622
    1609 void DeleteValueNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1623void DeleteValueNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    16101624{
    16111625    nodeStack.append(m_expr.get());
     
    16231637// ------------------------------ VoidNode -------------------------------------
    16241638
    1625 void VoidNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1639void VoidNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    16261640{
    16271641    nodeStack.append(expr.get());
     
    16411655// ------------------------------ TypeOfValueNode -----------------------------------
    16421656
    1643 void TypeOfValueNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1657void TypeOfValueNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    16441658{
    16451659    nodeStack.append(m_expr.get());
     
    16741688}
    16751689
    1676 void TypeOfResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     1690void TypeOfResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
    16771691{
    16781692    size_t index = symbolTable.get(m_ident.ustring().rep());
     
    17261740// ------------------------------ PrefixResolveNode ----------------------------------
    17271741
    1728 void PreIncResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     1742void PreIncResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    17291743{
    17301744    size_t index = symbolTable.get(m_ident.ustring().rep());
    1731     if (index != missingSymbolMarker())
    1732         new (this) PreIncLocalVarNode(index);
     1745    if (index != missingSymbolMarker()) {
     1746        if (isConstant(localStorage, index))
     1747            new (this) PreIncConstNode(index);
     1748        else
     1749            new (this) PreIncLocalVarNode(index);
     1750    }
    17331751}
    17341752
     
    17741792}
    17751793
    1776 void PreDecResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
     1794void PreDecResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    17771795{
    17781796    size_t index = symbolTable.get(m_ident.ustring().rep());
    1779     if (index != missingSymbolMarker())
    1780         new (this) PreDecLocalVarNode(index);
     1797    if (index != missingSymbolMarker()) {
     1798        if (isConstant(localStorage, index))
     1799            new (this) PreDecConstNode(index);
     1800        else
     1801            new (this) PreDecLocalVarNode(index);
     1802    }
    17811803}
    17821804
     
    18221844}
    18231845
     1846// ------------------------------ PreIncConstNode ----------------------------------
     1847
     1848JSValue* PreIncConstNode::evaluate(ExecState* exec)
     1849{
     1850    ASSERT(exec->variableObject() == exec->scopeChain().top());
     1851    return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) + 1);
     1852}
     1853
     1854// ------------------------------ PreDecConstNode ----------------------------------
     1855
     1856JSValue* PreDecConstNode::evaluate(ExecState* exec)
     1857{
     1858    ASSERT(exec->variableObject() == exec->scopeChain().top());
     1859    return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) - 1);
     1860}
     1861
     1862// ------------------------------ PostIncConstNode ----------------------------------
     1863
     1864JSValue* PostIncConstNode::evaluate(ExecState* exec)
     1865{
     1866    ASSERT(exec->variableObject() == exec->scopeChain().top());
     1867    return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
     1868}
     1869
     1870// ------------------------------ PostDecConstNode ----------------------------------
     1871
     1872JSValue* PostDecConstNode::evaluate(ExecState* exec)
     1873{
     1874    ASSERT(exec->variableObject() == exec->scopeChain().top());
     1875    return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
     1876}
     1877
    18241878// ------------------------------ PrefixBracketNode ----------------------------------
    18251879
    1826 void PrefixBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1880void PrefixBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    18271881{
    18281882    nodeStack.append(m_subscript.get());
     
    18961950// ------------------------------ PrefixDotNode ----------------------------------
    18971951
    1898 void PrefixDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     1952void PrefixDotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    18991953{
    19001954    nodeStack.append(m_base.get());
     
    19472001// ------------------------------ UnaryPlusNode --------------------------------
    19482002
    1949 void UnaryPlusNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2003void UnaryPlusNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    19502004{
    19512005    nodeStack.append(m_expr.get());
     
    19822036// ------------------------------ NegateNode -----------------------------------
    19832037
    1984 void NegateNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2038void NegateNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    19852039{
    19862040    nodeStack.append(expr.get());
     
    20022056// ------------------------------ BitwiseNotNode -------------------------------
    20032057
    2004 void BitwiseNotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2058void BitwiseNotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    20052059{
    20062060    nodeStack.append(expr.get());
     
    20402094// ------------------------------ LogicalNotNode -------------------------------
    20412095
    2042 void LogicalNotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2096void LogicalNotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    20432097{
    20442098    nodeStack.append(expr.get());
     
    20582112// ------------------------------ Multiplicative Nodes -----------------------------------
    20592113
    2060 void MultNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2114void MultNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    20612115{
    20622116    nodeStack.append(term1.get());
     
    20982152}
    20992153
    2100 void DivNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2154void DivNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    21012155{
    21022156    nodeStack.append(term1.get());
     
    21332187}
    21342188
    2135 void ModNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2189void ModNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    21362190{
    21372191    nodeStack.append(term1.get());
     
    22702324}
    22712325
    2272 void AddNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2326void AddNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    22732327{
    22742328    nodeStack.append(term1.get());
     
    23772431}
    23782432
    2379 void SubNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2433void SubNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    23802434{
    23812435    nodeStack.append(term1.get());
     
    24142468// ------------------------------ Shift Nodes ------------------------------------
    24152469
    2416 void LeftShiftNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2470void LeftShiftNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    24172471{
    24182472    nodeStack.append(term1.get());
     
    24492503}
    24502504
    2451 void RightShiftNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2505void RightShiftNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    24522506{
    24532507    nodeStack.append(term1.get());
     
    24842538}
    24852539
    2486 void UnsignedRightShiftNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2540void UnsignedRightShiftNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    24872541{
    24882542    nodeStack.append(term1.get());
     
    25512605}
    25522606
    2553 void LessNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2607void LessNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    25542608{
    25552609    nodeStack.append(expr2.get());
     
    26132667}
    26142668
    2615 void GreaterNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2669void GreaterNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    26162670{
    26172671    nodeStack.append(expr2.get());
     
    26392693}
    26402694
    2641 void LessEqNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2695void LessEqNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    26422696{
    26432697    nodeStack.append(expr2.get());
     
    26652719}
    26662720
    2667 void GreaterEqNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2721void GreaterEqNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    26682722{
    26692723    nodeStack.append(expr2.get());
     
    26912745}
    26922746
    2693 void InstanceOfNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2747void InstanceOfNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    26942748{
    26952749    nodeStack.append(expr2.get());
     
    27442798}
    27452799
    2746 void InNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2800void InNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    27472801{
    27482802    nodeStack.append(expr2.get());
     
    27812835// ------------------------------ Equality Nodes ------------------------------------
    27822836
    2783 void EqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2837void EqualNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    27842838{
    27852839    nodeStack.append(expr2.get());
     
    28082862}
    28092863
    2810 void NotEqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2864void NotEqualNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    28112865{
    28122866    nodeStack.append(expr2.get());
     
    28352889}
    28362890
    2837 void StrictEqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2891void StrictEqualNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    28382892{
    28392893    nodeStack.append(expr2.get());
     
    28622916}
    28632917
    2864 void NotStrictEqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2918void NotStrictEqualNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    28652919{
    28662920    nodeStack.append(expr2.get());
     
    28912945// ------------------------------ Bit Operation Nodes ----------------------------------
    28922946
    2893 void BitAndNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2947void BitAndNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    28942948{
    28952949    nodeStack.append(expr2.get());
     
    29362990}
    29372991
    2938 void BitXOrNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     2992void BitXOrNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    29392993{
    29402994    nodeStack.append(expr2.get());
     
    29753029}
    29763030
    2977 void BitOrNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3031void BitOrNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    29783032{
    29793033    nodeStack.append(expr2.get());
     
    30163070// ------------------------------ Binary Logical Nodes ----------------------------
    30173071
    3018 void LogicalAndNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3072void LogicalAndNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    30193073{
    30203074    nodeStack.append(expr2.get());
     
    30433097}
    30443098
    3045 void LogicalOrNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3099void LogicalOrNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    30463100{
    30473101    nodeStack.append(expr2.get());
     
    30673121// ------------------------------ ConditionalNode ------------------------------
    30683122
    3069 void ConditionalNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3123void ConditionalNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    30703124{
    30713125    nodeStack.append(expr2.get());
     
    31783232// ------------------------------ ReadModifyResolveNode -----------------------------------
    31793233
    3180 void ReadModifyResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack& nodeStack)
     3234void ReadModifyResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
    31813235{
    31823236    nodeStack.append(m_right.get());
    31833237    size_t index = symbolTable.get(m_ident.ustring().rep());
    3184     if (index != missingSymbolMarker())
    3185         new (this) ReadModifyLocalVarNode(index);
    3186 }
    3187 
    3188 void AssignResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack& nodeStack)
     3238    if (index != missingSymbolMarker()) {
     3239        if (isConstant(localStorage, index))
     3240            new (this) ReadModifyConstNode(index);
     3241        else
     3242            new (this) ReadModifyLocalVarNode(index);
     3243    }
     3244}
     3245
     3246// ------------------------------ AssignResolveNode -----------------------------------
     3247
     3248void AssignResolveNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
    31893249{
    31903250    nodeStack.append(m_right.get());
    31913251    size_t index = symbolTable.get(m_ident.ustring().rep());
    3192     if (index != missingSymbolMarker())
    3193         new (this) AssignLocalVarNode(index);
    3194 }
     3252    if (index != missingSymbolMarker()) {
     3253        if (isConstant(localStorage, index))
     3254            new (this) AssignConstNode;
     3255        else
     3256            new (this) AssignLocalVarNode(index);
     3257    }
     3258}
     3259
     3260// ------------------------------ ReadModifyLocalVarNode -----------------------------------
    31953261
    31963262JSValue* ReadModifyLocalVarNode::evaluate(ExecState* exec)
     
    32073273    return v;
    32083274}
     3275
     3276// ------------------------------ AssignLocalVarNode -----------------------------------
    32093277
    32103278JSValue* AssignLocalVarNode::evaluate(ExecState* exec)
     
    32183286   
    32193287    return v;
     3288}
     3289
     3290// ------------------------------ ReadModifyConstNode -----------------------------------
     3291
     3292JSValue* ReadModifyConstNode::evaluate(ExecState* exec)
     3293{
     3294    ASSERT(exec->variableObject() == exec->scopeChain().top());
     3295    JSValue* left = exec->localStorage()[m_index].value;
     3296    ASSERT(m_oper != OpEqual);
     3297    JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_oper);
     3298    KJS_CHECKEXCEPTIONVALUE
     3299    return result;
     3300}
     3301
     3302// ------------------------------ AssignConstNode -----------------------------------
     3303
     3304JSValue* AssignConstNode::evaluate(ExecState* exec)
     3305{
     3306    return m_right->evaluate(exec);
    32203307}
    32213308
     
    32953382// ------------------------------ ReadModifyDotNode -----------------------------------
    32963383
    3297 void AssignDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3384void AssignDotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    32983385{
    32993386    nodeStack.append(m_right.get());
     
    33153402}
    33163403
    3317 void ReadModifyDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3404void ReadModifyDotNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    33183405{
    33193406    nodeStack.append(m_right.get());
     
    33523439// ------------------------------ AssignBracketNode -----------------------------------
    33533440
    3354 void AssignBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3441void AssignBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    33553442{
    33563443    nodeStack.append(m_right.get());
     
    33843471  return v;
    33853472}
    3386 void ReadModifyBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3473void ReadModifyBracketNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    33873474{
    33883475    nodeStack.append(m_right.get());
     
    34323519// ------------------------------ CommaNode ------------------------------------
    34333520
    3434 void CommaNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3521void CommaNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    34353522{
    34363523    nodeStack.append(expr2.get());
     
    34543541}
    34553542
    3456 void ConstDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3543void ConstDeclNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    34573544{
    34583545    if (next)
     
    35423629// ------------------------------ ConstStatementNode -----------------------------
    35433630
    3544 void ConstStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3631void ConstStatementNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    35453632{
    35463633    ASSERT(next);
     
    36083695}
    36093696
    3610 void BlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3697void BlockNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    36113698{
    36123699    statementListPushFIFO(m_children, nodeStack);
     
    36293716// ------------------------------ ExprStatementNode ----------------------------
    36303717
    3631 void ExprStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3718void ExprStatementNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    36323719{
    36333720    ASSERT(expr);
     
    36463733// ------------------------------ VarStatementNode ----------------------------
    36473734
    3648 void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3735void VarStatementNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    36493736{
    36503737    ASSERT(expr);
     
    36623749// ------------------------------ IfNode ---------------------------------------
    36633750
    3664 void IfNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3751void IfNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    36653752{
    36663753    nodeStack.append(m_ifBlock.get());
     
    36793766}
    36803767
    3681 void IfElseNode::optimizeVariableAccess(SymbolTable& table, DeclarationStacks::NodeStack& nodeStack)
     3768void IfElseNode::optimizeVariableAccess(const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
    36823769{
    36833770    nodeStack.append(m_elseBlock.get());
    3684     IfNode::optimizeVariableAccess(table, nodeStack);
     3771    IfNode::optimizeVariableAccess(symbolTable, localStorage, nodeStack);
    36853772}
    36863773
     
    36993786// ------------------------------ DoWhileNode ----------------------------------
    37003787
    3701 void DoWhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3788void DoWhileNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    37023789{
    37033790    nodeStack.append(statement.get());
     
    37413828// ------------------------------ WhileNode ------------------------------------
    37423829
    3743 void WhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3830void WhileNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    37443831{
    37453832    nodeStack.append(statement.get());
     
    37823869// ------------------------------ ForNode --------------------------------------
    37833870
    3784 void ForNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3871void ForNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    37853872{
    37863873    nodeStack.append(statement.get());
     
    38443931}
    38453932
    3846 void ForInNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     3933void ForInNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    38473934{
    38483935    nodeStack.append(statement.get());
     
    39734060// ------------------------------ ReturnNode -----------------------------------
    39744061
    3975 void ReturnNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4062void ReturnNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    39764063{
    39774064    if (value)
     
    39974084// ------------------------------ WithNode -------------------------------------
    39984085
    3999 void WithNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4086void WithNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    40004087{
    40014088    // Can't optimize within statement because "with" introduces a dynamic scope.
     
    40204107// ------------------------------ CaseClauseNode -------------------------------
    40214108
    4022 void CaseClauseNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4109void CaseClauseNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    40234110{
    40244111    if (expr)
     
    40444131// ------------------------------ ClauseListNode -------------------------------
    40454132
    4046 void ClauseListNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4133void ClauseListNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    40474134{
    40484135    if (next)
     
    40604147}
    40614148 
    4062 void CaseBlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4149void CaseBlockNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    40634150{
    40644151    if (list2)
     
    41304217// ------------------------------ SwitchNode -----------------------------------
    41314218
    4132 void SwitchNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4219void SwitchNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    41334220{
    41344221    nodeStack.append(block.get());
     
    41534240// ------------------------------ LabelNode ------------------------------------
    41544241
    4155 void LabelNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4242void LabelNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    41564243{
    41574244    nodeStack.append(statement.get());
     
    41734260// ------------------------------ ThrowNode ------------------------------------
    41744261
    4175 void ThrowNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4262void ThrowNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    41764263{
    41774264    nodeStack.append(expr.get());
     
    41904277// ------------------------------ TryNode --------------------------------------
    41914278
    4192 void TryNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
     4279void TryNode::optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    41934280{
    41944281    // Can't optimize within catchBlock because "catch" introduces a dynamic scope.
     
    42294316// ------------------------------ FunctionBodyNode -----------------------------
    42304317
    4231 ScopeNode::ScopeNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4318ScopeNode::ScopeNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42324319    : BlockNode(children)
    42334320    , m_sourceURL(parser().sourceURL())
     
    42364323    if (varStack)
    42374324        m_varStack = *varStack;
    4238 
    42394325    if (funcStack)
    42404326        m_functionStack = *funcStack;
    42414327}
    42424328
    4243 ProgramNode::ProgramNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4329// ------------------------------ ProgramNode -----------------------------
     4330
     4331ProgramNode::ProgramNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42444332    : ScopeNode(children, varStack, funcStack)
    42454333{
    42464334}
    42474335
    4248 ProgramNode* ProgramNode::create(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4336ProgramNode* ProgramNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42494337{
    42504338    return new ProgramNode(children, varStack, funcStack);
    42514339}
    42524340
    4253 EvalNode::EvalNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4341// ------------------------------ EvalNode -----------------------------
     4342
     4343EvalNode::EvalNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42544344    : ScopeNode(children, varStack, funcStack)
    42554345{
    42564346}
    42574347
    4258 EvalNode* EvalNode::create(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4348EvalNode* EvalNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42594349{
    42604350    return new EvalNode(children, varStack, funcStack);
    42614351}
    42624352
    4263 FunctionBodyNode::FunctionBodyNode(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4353// ------------------------------ FunctionBodyNode -----------------------------
     4354
     4355FunctionBodyNode::FunctionBodyNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42644356    : ScopeNode(children, varStack, funcStack)
    42654357    , m_initialized(false)
     
    42674359}
    42684360
    4269 FunctionBodyNode* FunctionBodyNode::create(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack)
     4361FunctionBodyNode* FunctionBodyNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack)
    42704362{
    42714363    if (Debugger::debuggersPresent)
     
    42804372
    42814373    size_t localStorageIndex = 0;
     4374
     4375    // Order must match the order in processDeclarations.
    42824376
    42834377    for (size_t i = 0, size = m_parameters.size(); i < size; ++i, ++localStorageIndex) {
     
    43124406    size_t localStorageIndex = symbolTable.size();
    43134407    size_t size;
     4408
     4409    // Order must match the order in processDeclarations.
    43144410   
    43154411    size = m_functionStack.size();
     
    43384434            continue;
    43394435        }
     4436
    43404437        m_varIndexes[i] = result.first->second;
    43414438        ++localStorageIndex;
     
    43454442void ScopeNode::optimizeVariableAccess(ExecState* exec)
    43464443{
    4347     DeclarationStacks::NodeStack nodeStack;
     4444    NodeStack nodeStack;
    43484445    Node* node = statementListInitializeVariableAccessStack(m_children, nodeStack);
    43494446    if (!node)
    43504447        return;
    43514448   
    4352     SymbolTable& symbolTable = exec->variableObject()->symbolTable();
     4449    const SymbolTable& symbolTable = exec->variableObject()->symbolTable();
     4450    const LocalStorage& localStorage = exec->variableObject()->localStorage();
    43534451    while (true) {
    4354         node->optimizeVariableAccess(symbolTable, nodeStack);
     4452        node->optimizeVariableAccess(symbolTable, localStorage, nodeStack);
    43554453       
    43564454        size_t size = nodeStack.size();
     
    43654463void FunctionBodyNode::processDeclarations(ExecState* exec)
    43664464{
    4367     if (!m_initialized) {
     4465    if (!m_initialized)
    43684466        initializeSymbolTable(exec);
    4369         optimizeVariableAccess(exec);
    4370        
    4371         m_initialized = true;
    4372     }
    43734467
    43744468    if (m_functionStack.size() != 0)
    4375       exec->dynamicGlobalObject()->tearOffActivation(exec);
     4469        exec->dynamicGlobalObject()->tearOffActivation(exec);
    43764470
    43774471    LocalStorage& localStorage = exec->variableObject()->localStorage();
     
    43984492
    43994493    for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
    4400         bool isConstant = m_varStack[i].second & DeclarationStacks::IsConstant;
    44014494        int attributes = minAttributes;
    4402         if (isConstant)
     4495        if (m_varStack[i].second & DeclarationStacks::IsConstant)
    44034496            attributes |= ReadOnly;
    44044497        localStorage.uncheckedAppend(LocalStorageEntry(jsUndefined(), attributes));
     4498    }
     4499
     4500    if (!m_initialized) {
     4501        optimizeVariableAccess(exec);       
     4502        m_initialized = true;
    44054503    }
    44064504}
     
    44194517   
    44204518    initializeSymbolTable(exec);
    4421     optimizeVariableAccess(exec);
    44224519
    44234520    LocalStorage& localStorage = exec->variableObject()->localStorage();
     
    44504547            continue;
    44514548
    4452         bool isConstant = m_varStack[i].second & DeclarationStacks::IsConstant;
    44534549        int attributes = minAttributes;
    4454         if (isConstant)
     4550        if (m_varStack[i].second & DeclarationStacks::IsConstant)
    44554551            attributes |= ReadOnly;
    44564552        LocalStorageEntry entry = LocalStorageEntry(jsUndefined(), attributes);
     
    44594555        localStorage.uncheckedAppend(entry);
    44604556    }
     4557
     4558    optimizeVariableAccess(exec);
    44614559}
    44624560
     
    44744572    for (i = 0, size = m_varStack.size(); i < size; ++i) {
    44754573        Identifier& ident = m_varStack[i].first;
    4476         bool isConstant = m_varStack[i].second & DeclarationStacks::IsConstant;
    44774574        if (variableObject->hasProperty(exec, ident))
    44784575            continue;
    44794576        int attributes = minAttributes;
    4480         if (isConstant)
     4577        if (m_varStack[i].second & DeclarationStacks::IsConstant)
    44814578            attributes |= ReadOnly;
    44824579        variableObject->put(exec, ident, jsUndefined(), attributes);
Note: See TracChangeset for help on using the changeset viewer.