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

JavaScriptCore:

Reviewed by Oliver.

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

Test: fast/js/const.html

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

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

LayoutTests:

Reviewed by Oliver.

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

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/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
Note: See TracChangeset for help on using the changeset viewer.