Changeset 29818 in webkit for trunk/JavaScriptCore/kjs


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.
Location:
trunk/JavaScriptCore/kjs
Files:
6 edited

Legend:

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

    r29810 r29818  
    154154void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
    155155{
    156     if (symbolTablePut(propertyName, value, attr))
     156    if (symbolTablePut(propertyName, value, !(attr & ~DontDelete)))
    157157        return;
    158158    return JSVariableObject::put(exec, propertyName, value, attr);
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r29663 r29818  
    8383
    8484        bool symbolTableGet(const Identifier&, PropertySlot&);
    85         bool symbolTablePut(const Identifier&, JSValue*, int attr);
     85        bool symbolTablePut(const Identifier&, JSValue*, bool checkReadOnly);
    8686
    8787        JSVariableObjectData* d;
     
    111111    }
    112112
    113     inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value, int attr)
     113    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value, bool checkReadOnly)
    114114    {
    115115        size_t index = symbolTable().get(propertyName.ustring().rep());
    116         if (index != missingSymbolMarker()) {
    117             LocalStorageEntry& entry = d->localStorage[index];
    118             entry.value = value;
    119             entry.attributes = attr;
     116        if (index == missingSymbolMarker())
     117            return false;
     118        LocalStorageEntry& entry = d->localStorage[index];
     119        if (checkReadOnly && (entry.attributes & ReadOnly))
    120120            return true;
    121         }
    122 
    123         return false;
     121        entry.value = value;
     122        return true;
    124123    }
    125124
  • trunk/JavaScriptCore/kjs/function.cpp

    r29810 r29818  
    420420void ActivationImp::put(ExecState*, const Identifier& propertyName, JSValue* value, int attr)
    421421{
    422     if (symbolTablePut(propertyName, value, attr))
     422    // If any bits other than DontDelete are set, then we bypass the read-only check.
     423    bool checkReadOnly = !(attr & ~DontDelete);
     424    if (symbolTablePut(propertyName, value, checkReadOnly))
    423425        return;
    424426
     
    427429    // expose in the activation object.
    428430    ASSERT(!_prop.hasGetterSetterProperties());
    429     _prop.put(propertyName, value, attr, (attr == None || attr == DontDelete));
     431    _prop.put(propertyName, value, attr, checkReadOnly);
    430432}
    431433
  • 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);
  • trunk/JavaScriptCore/kjs/nodes.h

    r29815 r29818  
    9090  struct DeclarationStacks {
    9191      typedef Vector<Node*, 16> NodeStack;
    92       enum { IsConstant, HasInitializer } VarAttrs;
     92      enum { IsConstant = 1, HasInitializer = 2 } VarAttrs;
    9393      typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
    9494      typedef Vector<FuncDeclNode*, 16> FunctionStack;
     
    125125  class Node : public ParserRefCounted {
    126126  public:
     127    typedef DeclarationStacks::NodeStack NodeStack;
     128    typedef DeclarationStacks::VarStack VarStack;
     129    typedef DeclarationStacks::FunctionStack FunctionStack;
     130
    127131    Node() KJS_FAST_CALL;
    128132    Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL
     
    138142
    139143    // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
    140     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
     144    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { }
    141145
    142146  protected:
     
    324328    }
    325329
    326     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     330    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    327331
    328332    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    369373    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    370374    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    371     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     375    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    372376
    373377    PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
     
    389393    ArrayNode(int eli, ElementNode* ele) KJS_FAST_CALL
    390394      : element(ele), elision(eli), opt(true) { }
    391     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     395    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    392396    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    393397    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    404408    PropertyNode(const Identifier& n, ExpressionNode* a, Type t) KJS_FAST_CALL
    405409      : m_name(n), assign(a), type(t) { }
    406     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     410    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    407411    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    408412    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    424428    PropertyListNode(PropertyNode* n, PropertyListNode* l) KJS_FAST_CALL
    425429      : node(n) { l->next = this; }
    426     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     430    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    427431    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    428432    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    441445    ObjectLiteralNode() KJS_FAST_CALL { }
    442446    ObjectLiteralNode(PropertyListNode* l) KJS_FAST_CALL : list(l) { }
    443     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     447    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    444448    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    445449    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    453457  public:
    454458    BracketAccessorNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
    455     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     459    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    456460    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    457461    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    476480  public:
    477481    DotAccessorNode(ExpressionNode* e, const Identifier& s) KJS_FAST_CALL : expr(e), ident(s) { }
    478     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     482    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    479483    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    480484    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    501505    ArgumentListNode(ArgumentListNode* l, ExpressionNode* e) KJS_FAST_CALL
    502506      : expr(e) { l->next = this; }
    503     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     507    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    504508    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    505509    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    519523    ArgumentsNode(ArgumentListNode* l) KJS_FAST_CALL
    520524      : listNode(l) { }
    521     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     525    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    522526    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    523527    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    533537    NewExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
    534538    NewExprNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
    535     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     539    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    536540    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    537541    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    550554  public:
    551555    FunctionCallValueNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
    552     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     556    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    553557    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    554558    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    574578    }
    575579
    576     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     580    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    577581    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    578582    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    611615  public:
    612616    FunctionCallBracketNode(ExpressionNode* b, ExpressionNode* s, ArgumentsNode* a) KJS_FAST_CALL : base(b), subscript(s), args(a) {}
    613     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     617    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    614618    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    615619    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    624628  public:
    625629    FunctionCallDotNode(ExpressionNode* b, const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
    626     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     630    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    627631    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    628632    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    663667    }
    664668
    665     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     669    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    666670    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    667671    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    668672    virtual Precedence precedence() const { return PrecPostfix; }
    669673    virtual void optimizeForUnnecessaryResult();
    670 
    671674  };
    672675
     
    684687  };
    685688
     689  class PostIncConstNode : public PostIncResolveNode {
     690  public:
     691    PostIncConstNode(size_t i) KJS_FAST_CALL
     692        : PostIncResolveNode(PlacementNewAdopt)
     693    {
     694        ASSERT(i != missingSymbolMarker());
     695        m_index = i;
     696    }
     697    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     698  };
     699
    686700  class PostDecResolveNode : public PrePostResolveNode {
    687701  public:
     
    693707    }
    694708
    695     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     709    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    696710    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    697711    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    719733  };
    720734
     735  class PostDecConstNode : public PostDecResolveNode {
     736  public:
     737    PostDecConstNode(size_t i) KJS_FAST_CALL
     738        : PostDecResolveNode(PlacementNewAdopt)
     739    {
     740        ASSERT(i != missingSymbolMarker());
     741        m_index = i;
     742    }
     743    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     744  };
     745
    721746  class PostfixBracketNode : public ExpressionNode {
    722747  public:
    723748    PostfixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
    724     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     749    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    725750    virtual Precedence precedence() const { return PrecPostfix; }
    726751  protected:
     
    746771  public:
    747772    PostfixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
    748     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     773    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    749774    virtual Precedence precedence() const { return PrecPostfix; }
    750775  protected:
     
    787812    }
    788813
    789     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     814    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    790815    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    791816    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    808833  public:
    809834    DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL : m_base(base), m_subscript(subscript) {}
    810     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     835    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    811836    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    812837    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    820845  public:
    821846    DeleteDotNode(ExpressionNode* base, const Identifier& i) KJS_FAST_CALL : m_base(base), m_ident(i) {}
    822     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     847    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    823848    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    824849    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    832857  public:
    833858    DeleteValueNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) {}
    834     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     859    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    835860    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    836861    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    843868  public:
    844869    VoidNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
    845     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     870    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    846871    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    847872    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    863888    }
    864889
    865     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     890    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    866891   
    867892    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    892917  public:
    893918    TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {}
    894     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     919    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    895920    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    896921    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    912937    }
    913938   
    914     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     939    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    915940
    916941    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    931956  };
    932957 
     958  class PreIncConstNode : public PreIncResolveNode {
     959  public:
     960    PreIncConstNode(size_t i) KJS_FAST_CALL
     961        : PreIncResolveNode(PlacementNewAdopt)
     962    {
     963        ASSERT(i != missingSymbolMarker());
     964        m_index = i;
     965    }
     966    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     967  };
     968
    933969  class PreDecResolveNode : public PrePostResolveNode {
    934970  public:
     
    943979    }
    944980   
    945     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     981    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    946982
    947983    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    962998  };
    963999 
     1000  class PreDecConstNode : public PreDecResolveNode {
     1001  public:
     1002    PreDecConstNode(size_t i) KJS_FAST_CALL
     1003        : PreDecResolveNode(PlacementNewAdopt)
     1004    {
     1005        ASSERT(i != missingSymbolMarker());
     1006        m_index = i;
     1007    }
     1008    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1009  };
     1010
    9641011  class PrefixBracketNode : public ExpressionNode {
    9651012  public:
    9661013    PrefixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
    9671014   
    968     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1015    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    9691016    virtual Precedence precedence() const { return PrecUnary; }
    9701017  protected:
     
    9901037  public:
    9911038    PrefixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
    992     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1039    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    9931040    virtual Precedence precedence() const { return PrecPostfix; }
    9941041  protected:
     
    10251072  public:
    10261073    UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
    1027     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1074    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    10281075    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    10291076    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    10401087  public:
    10411088    NegateNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
    1042     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1089    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    10431090    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    10441091    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    10521099  public:
    10531100    BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
    1054     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1101    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    10551102    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    10561103    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    10681115  public:
    10691116    LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(BooleanType), expr(e) {}
    1070     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1117    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    10711118    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    10721119    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    10801127  public:
    10811128      MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1082       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1129      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    10831130      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    10841131      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    10971144  public:
    10981145      DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1099       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1146      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    11001147      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    11011148      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    11131160  public:
    11141161      ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1115       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1162      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    11161163      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    11171164      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    11301177  public:
    11311178    AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    1132     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1179    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    11331180    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    11341181    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    11771224  public:
    11781225      SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1179       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1226      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    11801227      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    11811228      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    11941241    LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
    11951242      : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1196     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1243    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    11971244    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    11981245    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    12111258    RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
    12121259      : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1213     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1260    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    12141261    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    12151262    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    12281275    UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
    12291276      : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    1230     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1277    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    12311278    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    12321279    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    12451292    LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    12461293      : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1247     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1294    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    12481295    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    12491296    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    12811328    GreaterNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    12821329      expr1(e1), expr2(e2) {}
    1283     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1330    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    12841331    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    12851332    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    12961343    LessEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    12971344      expr1(e1), expr2(e2) {}
    1298     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1345    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    12991346    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13001347    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13111358    GreaterEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    13121359      expr1(e1), expr2(e2) {}
    1313     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1360    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    13141361    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13151362    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13261373    InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    13271374        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1328     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1375    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    13291376    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13301377    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13401387    InNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    13411388      expr1(e1), expr2(e2) {}
    1342     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1389    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    13431390    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13441391    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13541401    EqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    13551402        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1356     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1403    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    13571404    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13581405    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13691416    NotEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    13701417        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1371     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1418    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    13721419    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13731420    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13841431    StrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    13851432        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1386     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1433    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    13871434    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    13881435    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    13991446    NotStrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    14001447        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1401     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1448    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14021449    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    14031450    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    14141461    BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    14151462        : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
    1416     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1463    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14171464    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    14181465    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    14321479    BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    14331480        : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
    1434     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1481    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14351482    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    14361483    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    14501497    BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    14511498        : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
    1452     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1499    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14531500    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    14541501    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    14711518    LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    14721519        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1473     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1520    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14741521    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    14751522    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    14861533    LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    14871534        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    1488     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1535    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14891536    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    14901537    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    15041551    ConditionalNode(ExpressionNode*  l, ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    15051552      logical(l), expr1(e1), expr2(e2) {}
    1506     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1553    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    15071554    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    15081555    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     
    15341581    }
    15351582
    1536     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1583    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    15371584    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    15381585    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    15571604  };
    15581605
     1606  class ReadModifyConstNode : public ReadModifyResolveNode {
     1607  public:
     1608    ReadModifyConstNode(size_t i) KJS_FAST_CALL
     1609        : ReadModifyResolveNode(PlacementNewAdopt)
     1610    {
     1611        ASSERT(i != missingSymbolMarker());
     1612        m_index = i;
     1613    }
     1614    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1615  };
     1616
    15591617    class AssignResolveNode : public ExpressionNode {
    15601618  public:
     
    15721630    }
    15731631
    1574     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1632    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    15751633    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    15761634    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    15941652  };
    15951653
     1654  class AssignConstNode : public AssignResolveNode {
     1655  public:
     1656    AssignConstNode() KJS_FAST_CALL
     1657        : AssignResolveNode(PlacementNewAdopt)
     1658    {
     1659    }   
     1660    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1661  };
     1662
    15961663    class ReadModifyBracketNode : public ExpressionNode {
    15971664  public:
    15981665    ReadModifyBracketNode(ExpressionNode*  base, ExpressionNode*  subscript, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
    15991666      : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
    1600     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1667    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    16011668    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    16021669    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    16131680    AssignBracketNode(ExpressionNode*  base, ExpressionNode*  subscript, ExpressionNode*  right) KJS_FAST_CALL
    16141681      : m_base(base), m_subscript(subscript), m_right(right) {}
    1615     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1682    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    16161683    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    16171684    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    16271694    AssignDotNode(ExpressionNode*  base, const Identifier& ident, ExpressionNode*  right) KJS_FAST_CALL
    16281695      : m_base(base), m_ident(ident), m_right(right) {}
    1629     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1696    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    16301697    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    16311698    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    16411708    ReadModifyDotNode(ExpressionNode*  base, const Identifier& ident, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
    16421709      : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
    1643     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1710    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    16441711    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    16451712    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    16711738        e1->optimizeForUnnecessaryResult();
    16721739    }
    1673     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1740    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    16741741    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    16751742    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    16831750  public:
    16841751    ConstDeclNode(const Identifier& id, ExpressionNode* in) KJS_FAST_CALL;
    1685     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1752    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    16861753    virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    16871754    void evaluateSingle(ExecState*) KJS_FAST_CALL;
     
    17001767  public:
    17011768    ConstStatementNode(ConstDeclNode* l) KJS_FAST_CALL : next(l) { }
    1702     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1769    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17031770    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17041771    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17241791  public:
    17251792    BlockNode(SourceElements* children) KJS_FAST_CALL;
    1726     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1793    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17271794    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17281795    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17421809  public:
    17431810    ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
    1744     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1811    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17451812    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17461813    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17521819  public:
    17531820    VarStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
    1754     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1821    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17551822    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17561823    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17631830    IfNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL
    17641831      : m_condition(e), m_ifBlock(s) { }
    1765     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1832    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17661833    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17671834    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17751842        IfElseNode(ExpressionNode* e, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL
    17761843            : IfNode(e, ifBlock), m_elseBlock(elseBlock) { }
    1777         virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1844        virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17781845        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17791846        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17851852  public:
    17861853    DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { }
    1787     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1854    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17881855    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    17891856    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    17961863  public:
    17971864    WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { }
    1798     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1865    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    17991866    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    18001867    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    18221889    }
    18231890
    1824     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1891    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    18251892    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    18261893    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    18371904    ForInNode(ExpressionNode*  l, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
    18381905    ForInNode(const Identifier &i, ExpressionNode *in, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
    1839     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1906    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    18401907    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    18411908    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    18721939  public:
    18731940    ReturnNode(ExpressionNode* v) KJS_FAST_CALL : value(v) {}
    1874     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1941    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    18751942    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    18761943    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    18821949  public:
    18831950    WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { }
    1884     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1951    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    18851952    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    18861953    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    18931960  public:
    18941961    LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { }
    1895     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1962    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    18961963    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    18971964    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    19041971  public:
    19051972    ThrowNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
    1906     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1973    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    19071974    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    19081975    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    19151982    TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
    19161983      : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
    1917     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1984    virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    19181985    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    19191986    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    19442011  class ScopeNode : public BlockNode {
    19452012  public:
    1946     ScopeNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2013    ScopeNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    19472014
    19482015    int sourceId() const KJS_FAST_CALL { return m_sourceId; }
     
    19532020    void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
    19542021
    1955     DeclarationStacks::VarStack m_varStack;
    1956     DeclarationStacks::FunctionStack m_functionStack;
     2022    VarStack m_varStack;
     2023    FunctionStack m_functionStack;
    19572024
    19582025  private:
     
    19632030  class ProgramNode : public ScopeNode {
    19642031  public:
    1965     static ProgramNode* create(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2032    static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    19662033    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    19672034   
    19682035  private:
    1969     ProgramNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2036    ProgramNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    19702037    void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
    19712038    ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
     
    19772044  class EvalNode : public ScopeNode {
    19782045  public:
    1979     static EvalNode* create(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2046    static EvalNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    19802047    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    19812048   
    19822049  private:
    1983     EvalNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2050    EvalNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    19842051    ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
    19852052  };
     
    19872054  class FunctionBodyNode : public ScopeNode {
    19882055  public:
    1989     static FunctionBodyNode* create(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2056    static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    19902057
    19912058    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     
    19972064
    19982065  protected:
    1999     FunctionBodyNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
     2066    FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*) KJS_FAST_CALL;
    20002067
    20012068  private:
     
    20462113      CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL
    20472114      : expr(e) { if (children) children->releaseContentsIntoVector(m_children); }
    2048       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     2115      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    20492116      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    20502117      virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    20632130      ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
    20642131      : clause(c) { n->next = this; }
    2065       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     2132      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    20662133      CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
    20672134      ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
     
    20782145  public:
    20792146      CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
    2080       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     2147      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    20812148      JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
    20822149      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    20912158  public:
    20922159      SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { }
    2093       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     2160      virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    20942161      virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    20952162      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    21042171        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
    21052172        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    2106         virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     2173        virtual void optimizeVariableAccess(const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    21072174    private:
    21082175        RefPtr<StatementNode> m_statement;
  • trunk/JavaScriptCore/kjs/object.cpp

    r29067 r29818  
    209209  ASSERT(value);
    210210
    211   // non-standard netscape extension
    212211  if (propertyName == exec->propertyNames().underscoreProto) {
    213212    JSObject* proto = value->getObject();
     
    222221  }
    223222
    224   /* TODO: check for write permissions directly w/o this call */
    225   /* Doesn't look very easy with the PropertyMap API - David */
    226   // putValue() is used for JS assignemnts. It passes no attribute.
    227   // Assume that a C++ implementation knows what it is doing
    228   // and let it override the canPut() check.
    229   bool checkReadOnly = !(attr & (ReadOnly | DontEnum | Internal | Function | GetterSetter));
     223  // The put calls from JavaScript execution either have no attributes set, or in some cases
     224  // have DontDelete set. For those calls, respect the ReadOnly flag.
     225  bool checkReadOnly = !(attr & ~DontDelete);
     226
    230227  // Check if there are any setters or getters in the prototype chain
    231228  JSObject *obj = this;
Note: See TracChangeset for help on using the changeset viewer.