Changeset 34355 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Jun 3, 2008, 5:40:47 PM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2008-06-03 Darin Adler <Darin Adler>

Reviewed by Geoff.

Makes standalone SunSpider 1.025x as fast as before.

The getOwnPropertySlot virtual function now takes care of the toObject call
for get. Similarly, the put function (and later deleteProperty) does the
same for those operations. To do this, the virtual functions were moved from
the JSObject class to the JSCell class. Also, since the caller no longer knows
the identity of the "original object", which is used by JavaScript-function
based getters, changed the PropertySlot class so the original object is
already stored in the slot when getOwnPropertySlot is called, if the caller
intends to call getValue.

This affected the old interpreter code enough that the easiest thing for me
was to just delete it. While I am not certain the mysterious slowdown is not
still occurring, the net change is definitely a significant speedup.

  • VM/Machine.cpp: Moved the UNLIKELY macro into AlwaysInline.h. (KJS::resolve): Set up the originalObject in the PropertySlot before calling getPropertySlot. Also removed the originalObject argument from getValue. (KJS::resolve_skip): Ditto. (KJS::resolveBaseAndProperty): Ditto. (KJS::resolveBaseAndFunc): Ditto. (KJS::Machine::privateExecute): Removed the toObject calls from the get and put functions where possible, instead calling directly with JSValue and letting the JSValue and JSCell calls handle toObject. Same for toThisObject.
  • kjs/ExecState.h: Removed OldInterpreterExecState.
  • API/JSBase.cpp: Updated includes.
  • kjs/LocalStorageEntry.h: Removed contents. Later we can remove the file too.
  • kjs/array_instance.cpp: (KJS::ArrayInstance::lengthGetter): Removed originalObject argumet. (KJS::ArrayInstance::inlineGetOwnPropertySlot): Don't pass a base value to setValueSlot. Also use UNLIKELY around the "getting elements past the end of the array" code path; less common than successfully getting an element.
  • kjs/array_object.cpp: (KJS::getProperty): Initialize the PropertySlot with the original object. Don't pass the original object to the get function. (KJS::arrayProtoFuncFilter): Ditto. (KJS::arrayProtoFuncMap): Ditto. (KJS::arrayProtoFuncEvery): Ditto. (KJS::arrayProtoFuncForEach): Ditto. (KJS::arrayProtoFuncSome): Ditto.
  • kjs/function_object.cpp: (KJS::FunctionObjectImp::construct): Removed an obsolete comment.
  • kjs/grammar.y: Eliminated support for some of the node types that were used to optimize executing from the syntax tree.
  • kjs/internal.cpp: (KJS::StringImp::toThisObject): Added. Same as toObject. (KJS::NumberImp::toThisObject): Ditto. (KJS::GetterSetterImp::getOwnPropertySlot): Added. Not reached. (KJS::GetterSetterImp::put): Ditto. (KJS::GetterSetterImp::toThisObject): Ditto.
  • kjs/internal.h: Added toThisObject to NumberImp for speed.
  • kjs/lexer.cpp: (KJS::Lexer::shift): Changed shift to just do a single character, to unroll the loop and especially to make the one character case faster. (KJS::Lexer::setCode): Call shift multiple times instead of passing a number. (KJS::Lexer::lex): Ditto. (KJS::Lexer::matchPunctuator): Ditto. Also removed unneeded elses after returns. (KJS::Lexer::scanRegExp): Ditto.
  • kjs/lexer.h: Removed the count argument from shift.
  • kjs/math_object.cpp: (KJS::mathProtoFuncPow): Call jsNaN instead of jsNumber(NaN).
  • kjs/nodes.cpp: Removed some of the things needed only for the pre-SquirrelFish execution model. (KJS::ForNode::emitCode): Handle cases where some expressions are missing by not emitting any code at all. The old way was to emit code for "true", but this is an unnecessary remnant of the old way of doing things.
  • kjs/nodes.h: Removed some of the things needed only for the pre-SquirrelFish execution model.
  • kjs/object.cpp: (KJS::JSObject::fillGetterPropertySlot): Changed to only pass in the getter function. The old code passed in a base, but it was never used when actually getting the property; the toThisObject call was pointless. Also changed to not pass a base for setUndefined.
  • kjs/object.h: Added the new JSCell operations to GetterSetterImp. Never called. (KJS::JSObject::get): Initialize the object in the PropertySlot and don't pass it in getValue. (KJS::JSObject::getOwnPropertySlotForWrite): Removed the base argument in calls to setValueSlot. (KJS::JSObject::getOwnPropertySlot): Ditto. (KJS::JSValue::get): Added. Here because it calls through to JSObject. A version of JSObject::get that also handles the other types of JSValue by creating the appropriate wrapper. Saves the virtual call to toObject. (KJS::JSValue::put): Ditto. (KJS::JSValue::deleteProperty): Ditto.
  • kjs/property_slot.cpp: (KJS::PropertySlot::undefinedGetter): Removed the originalObject argument. (KJS::PropertySlot::ungettableGetter): Ditto. (KJS::PropertySlot::functionGetter): Ditto. Use the value in the base as the "this" object, which will be set to the original object by the new PropertySlot initialization code. Also call toThisObject. The old code did not do this, but needed to so we can properly handle the activation object like the other similar code paths.
  • kjs/property_slot.h: (KJS::PropertySlot::PropertySlot): Added a constructor that takes a base object. In debug builds, set the base to 0 if you don't pass one. (KJS::PropertySlot::getValue): Don't take or pass the originalObject. (KJS::PropertySlot::setValueSlot): Don't take a base object, and clear the base object in debug builds. (KJS::PropertySlot::setGetterSlot): Ditto. (KJS::PropertySlot::setUndefined): Ditto. (KJS::PropertySlot::setUngettable): Ditto. (KJS::PropertySlot::slotBase): Assert that a base object is present. This will fire if someone actually calls the get function without having passed in a base object and the getter needs it. (KJS::PropertySlot::setBase): Added. Used by the code that implements toObject so it can supply the original object after the fact. (KJS::PropertySlot::clearBase): Added. Clears the base, but is debug-only code because it's an error to fetch the base if you don't have a guarantee it was set.
  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h: (KJS::JSCallbackObject::cachedValueGetter): (KJS::JSCallbackObject::staticValueGetter): (KJS::JSCallbackObject::staticFunctionGetter): (KJS::JSCallbackObject::callbackGetter):
  • kjs/JSActivation.cpp: (KJS::JSActivation::getOwnPropertySlot): (KJS::JSActivation::argumentsGetter):
  • kjs/JSActivation.h:
  • kjs/JSVariableObject.h: (KJS::JSVariableObject::symbolTableGet):
  • kjs/array_instance.h:
  • kjs/function.cpp: (KJS::FunctionImp::argumentsGetter): (KJS::FunctionImp::callerGetter): (KJS::FunctionImp::lengthGetter): (KJS::Arguments::mappedIndexGetter):
  • kjs/function.h:
  • kjs/lookup.h: (KJS::staticFunctionGetter): (KJS::staticValueGetter):
  • kjs/string_object.cpp: (KJS::StringInstance::lengthGetter): (KJS::StringInstance::indexGetter): (KJS::stringInstanceNumericPropertyGetter):
  • kjs/string_object.h: Removed originalObject arguments from getters. Don't pass base values to the various PropertySlot functions that no longer take them.
  • kjs/value.cpp: (KJS::JSCell::getOwnPropertySlot): Added. Calls toObject and then sets the slot. This function has to always return true, because the caller can't walk the prototype chain. Because of that, we do a getPropertySlot, not getOwnPropertySlot, which works for the caller. This is private, only called by getOwnPropertySlotInternal. (KJS::JSCell::put): Added. Calls toObject and then put. (KJS::JSCell::toThisObject): Added. Calls toObject.
  • kjs/value.h: Added get, put, and toThisObject to both JSValue and JSCell. These take care of the toObject operation without an additional virtual function call, and so make the common "already an object" case faster.
  • wtf/AlwaysInline.h: Moved the UNLIKELY macro here for now. Maybe we can find a better place later, or rename this header.

JavaScriptGlue:

2008-06-03 Darin Adler <Darin Adler>

  • UserObjectImp.cpp: (UserObjectImp::userObjectGetter): Removed originalObject argument.
  • UserObjectImp.h: Ditto.

WebCore:

2008-06-03 Justin Garcia <[email protected]>

Reviewed by John.

<rdar://problem/5763082> GMail: Hang when removing indent from nested list
<rdar://problem/5775449> In Gmail and GoogleDocs, a hang occurs when I attempt to apply a list style to a large selection of text
<rdar://problem/5937624> 9D32: Hang in Safari. Using 100% of processor

  • editing/InsertListCommand.cpp: (WebCore::InsertListCommand::modifyRange): doApply() may operate on and remove the last paragraph of the selection from the document if it's in the same list item as startOfCurrentParagraph. Return early to avoid an infinite loop and because there is no more work to be done. Added a FIXME (<rdar://problem/5983974>) about the incorrect endingSelection()s.
Location:
trunk/JavaScriptCore/kjs
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/ExecState.h

    r34071 r34355  
    105105
    106106    private:
    107         // Default constructor required for OldInterpreterExecState with gcc 3.
    108         ExecState() {};
     107        // Default constructor required for gcc 3.
     108        ExecState() { }
    109109
    110110        ExecState(ExecState*, Machine*, RegisterFile*, ScopeChainNode*, int callFrameOffset);
     
    127127    };
    128128
    129     // This code is now defunct:
    130 
    131129    enum CodeType { GlobalCode, EvalCode, FunctionCode };
    132     class OldInterpreterExecState : public ExecState {
    133     public:
    134         void pushSwitch() { m_switchDepth++; }
    135         void popSwitch() { m_switchDepth--; }
    136         bool inSwitch() const { return (m_switchDepth > 0); }
    137 
    138         // These are only valid right after calling execute().
    139         ComplType completionType() const { return m_completionType; }
    140         const Identifier& breakOrContinueTarget() const
    141         {
    142             ASSERT(m_completionType == Break || m_completionType == Continue);
    143             return *m_breakOrContinueTarget;
    144         }
    145 
    146         // Only for use in the implementation of execute().
    147         void setCompletionType(ComplType type)
    148         {
    149             ASSERT(type != Break);
    150             ASSERT(type != Continue);
    151             m_completionType = type;
    152         }
    153         JSValue* setNormalCompletion()
    154         {
    155             ASSERT(!hadException());
    156             m_completionType = Normal;
    157             return 0;
    158         }
    159         JSValue* setNormalCompletion(JSValue* value)
    160         {
    161             ASSERT(!hadException());
    162             m_completionType = Normal;
    163             return value;
    164         }
    165         JSValue* setBreakCompletion(const Identifier* target)
    166         {
    167             ASSERT(!hadException());
    168             m_completionType = Break;
    169             m_breakOrContinueTarget = target;
    170             return 0;
    171         }
    172         JSValue* setContinueCompletion(const Identifier* target)
    173         {
    174             ASSERT(!hadException());
    175             m_completionType = Continue;
    176             m_breakOrContinueTarget = target;
    177             return 0;
    178         }
    179         JSValue* setReturnValueCompletion(JSValue* returnValue)
    180         {
    181             ASSERT(!hadException());
    182             ASSERT(returnValue);
    183             m_completionType = ReturnValue;
    184             return returnValue;
    185         }
    186         JSValue* setThrowCompletion(JSValue* exception)
    187         {
    188             ASSERT(!hadException());
    189             ASSERT(exception);
    190             m_completionType = Throw;
    191             return exception;
    192         }
    193         JSValue* setInterruptedCompletion()
    194         {
    195             ASSERT(!hadException());
    196             m_completionType = Interrupted;
    197             return 0;
    198         }
    199         CodeType codeType() { return m_codeType; }
    200         void pushIteration() { m_iterationDepth++; }
    201         void popIteration() { m_iterationDepth--; }
    202         bool inIteration() const { return (m_iterationDepth > 0); }
    203         LabelStack& seenLabels() { return m_labelStack; }
    204         void pushScope(JSObject* s) { m_scopeChain.push(s); }
    205         void popScope() { m_scopeChain.pop(); }
    206         JSVariableObject* variableObject() const { ASSERT_NOT_REACHED(); return m_variableObject; }
    207         void setVariableObject(JSVariableObject* v) { m_variableObject = v; }
    208         ExecState* callingExecState() { return m_callingExec; }
    209         ScopeNode* scopeNode() { return m_scopeNode; }
    210         const List* arguments() const { return m_arguments; }
    211         FunctionImp* function() const { return m_function; }
    212         LocalStorage& localStorage() { ASSERT_NOT_REACHED(); return *(LocalStorage*)0; }
    213         void setLocalStorage(LocalStorage*) { ASSERT_NOT_REACHED(); }
    214         ScopeChain& scopeChain() { return m_scopeChain; }
    215         JSObject* thisValue() const { return m_thisValue; }
    216        
    217         ComplType m_completionType;
    218         const Identifier* m_breakOrContinueTarget;
    219         int m_switchDepth;
    220         CodeType m_codeType;
    221         int m_iterationDepth;
    222         LabelStack m_labelStack;
    223         ScopeChainNode m_inlineScopeChainNode;
    224         ScopeChain m_scopeChain;
    225         JSVariableObject* m_variableObject;
    226         ScopeNode* m_scopeNode;
    227         const List* m_arguments;
    228         FunctionImp* m_function;
    229         ExecState* m_callingExec;
    230         JSObject* m_thisValue;
    231     };
    232130
    233131} // namespace KJS
  • trunk/JavaScriptCore/kjs/JSActivation.cpp

    r34095 r34355  
    7575
    7676    if (JSValue** location = getDirectLocation(propertyName)) {
    77         slot.setValueSlot(this, location);
     77        slot.setValueSlot(location);
    7878        return true;
    7979    }
     
    161161}
    162162
    163 JSValue* JSActivation::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
     163JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    164164{
    165165    JSActivation* thisObj = static_cast<JSActivation*>(slot.slotBase());
  • trunk/JavaScriptCore/kjs/JSActivation.h

    r33979 r34355  
    7777        };
    7878       
    79         static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
     79        static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
    8080        NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
    8181        NEVER_INLINE JSObject* createArgumentsObject(ExecState*);
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r33979 r34355  
    101101        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
    102102        if (!entry.isEmpty()) {
    103             slot.setValueSlot(this, &valueAt(entry.getIndex()));
     103            slot.setValueSlot(&valueAt(entry.getIndex()));
    104104            return true;
    105105        }
     
    111111        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
    112112        if (!entry.isEmpty()) {
    113             slot.setValueSlot(this, &valueAt(entry.getIndex()));
     113            slot.setValueSlot(&valueAt(entry.getIndex()));
    114114            slotIsWriteable = !entry.isReadOnly();
    115115            return true;
  • trunk/JavaScriptCore/kjs/array_instance.cpp

    r34334 r34355  
    131131}
    132132
    133 JSValue* ArrayInstance::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
     133JSValue* ArrayInstance::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
    134134{
    135135    return jsNumber(static_cast<ArrayInstance*>(slot.slotBase())->m_length);
     
    140140    ArrayStorage* storage = m_storage;
    141141
    142     if (i >= m_length) {
     142    if (UNLIKELY(i >= m_length)) {
    143143        if (i > maxArrayIndex)
    144144            return getOwnPropertySlot(exec, Identifier::from(i), slot);
     
    149149        JSValue*& valueSlot = storage->m_vector[i];
    150150        if (valueSlot) {
    151             slot.setValueSlot(this, &valueSlot);
     151            slot.setValueSlot(&valueSlot);
    152152            return true;
    153153        }
     
    156156            SparseArrayValueMap::iterator it = map->find(i);
    157157            if (it != map->end()) {
    158                 slot.setValueSlot(this, &it->second);
     158                slot.setValueSlot(&it->second);
    159159                return true;
    160160            }
  • trunk/JavaScriptCore/kjs/array_instance.h

    r34118 r34355  
    5959
    6060  private:
    61     static JSValue* lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
     61    static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    6262    bool inlineGetOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    6363
  • trunk/JavaScriptCore/kjs/array_object.cpp

    r34334 r34355  
    8383static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
    8484{
    85     PropertySlot slot;
     85    PropertySlot slot(obj);
    8686    if (!obj->getPropertySlot(exec, index, slot))
    8787        return 0;
    88     return slot.getValue(exec, obj, index);
     88    return slot.getValue(exec, index);
    8989}
    9090
     
    514514    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    515515    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
    516         PropertySlot slot;
     516        PropertySlot slot(thisObj);
    517517
    518518        if (!thisObj->getPropertySlot(exec, k, slot))
    519519            continue;
    520520
    521         JSValue* v = slot.getValue(exec, thisObj, k);
     521        JSValue* v = slot.getValue(exec, k);
    522522
    523523        List eachArguments;
     
    550550
    551551    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
    552         PropertySlot slot;
     552        PropertySlot slot(thisObj);
    553553        if (!thisObj->getPropertySlot(exec, k, slot))
    554554            continue;
    555555
    556         JSValue* v = slot.getValue(exec, thisObj, k);
     556        JSValue* v = slot.getValue(exec, k);
    557557
    558558        List eachArguments;
     
    587587    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    588588    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
    589         PropertySlot slot;
     589        PropertySlot slot(thisObj);
    590590
    591591        if (!thisObj->getPropertySlot(exec, k, slot))
     
    594594        List eachArguments;
    595595
    596         eachArguments.append(slot.getValue(exec, thisObj, k));
     596        eachArguments.append(slot.getValue(exec, k));
    597597        eachArguments.append(jsNumber(k));
    598598        eachArguments.append(thisObj);
     
    620620    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    621621    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
    622         PropertySlot slot;
     622        PropertySlot slot(thisObj);
    623623        if (!thisObj->getPropertySlot(exec, k, slot))
    624624            continue;
    625625
    626626        List eachArguments;
    627         eachArguments.append(slot.getValue(exec, thisObj, k));
     627        eachArguments.append(slot.getValue(exec, k));
    628628        eachArguments.append(jsNumber(k));
    629629        eachArguments.append(thisObj);
     
    647647    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    648648    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
    649         PropertySlot slot;
     649        PropertySlot slot(thisObj);
    650650        if (!thisObj->getPropertySlot(exec, k, slot))
    651651            continue;
    652652
    653653        List eachArguments;
    654         eachArguments.append(slot.getValue(exec, thisObj, k));
     654        eachArguments.append(slot.getValue(exec, k));
    655655        eachArguments.append(jsNumber(k));
    656656        eachArguments.append(thisObj);
  • trunk/JavaScriptCore/kjs/function.cpp

    r34273 r34355  
    100100}
    101101
    102 JSValue* FunctionImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
     102JSValue* FunctionImp::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    103103{
    104104    FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
     
    107107}
    108108
    109 JSValue* FunctionImp::callerGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
     109JSValue* FunctionImp::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    110110{
    111111    FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
     
    114114}
    115115
    116 JSValue* FunctionImp::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
     116JSValue* FunctionImp::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
    117117{
    118118    FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
     
    303303}
    304304
    305 JSValue* Arguments::mappedIndexGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     305JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    306306{
    307307  Arguments* thisObj = static_cast<Arguments*>(slot.slotBase());
  • trunk/JavaScriptCore/kjs/function.h

    r33979 r34355  
    8787    ScopeChain _scope;
    8888
    89     static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    90     static JSValue* callerGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    91     static JSValue* lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
     89    static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
     90    static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
     91    static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
    9292  };
    9393
     
    116116    static const ClassInfo info;
    117117  private:
    118     static JSValue* mappedIndexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
     118    static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot);
    119119
    120120    JSActivation* _activationObject;
  • trunk/JavaScriptCore/kjs/grammar.y

    r34351 r34355  
    10951095static AddNode* makeAddNode(ExpressionNode* left, ExpressionNode* right)
    10961096{
    1097     JSType t1 = left->expectedReturnType();
    1098     JSType t2 = right->expectedReturnType();
    1099 
    1100     if (t1 == NumberType && t2 == NumberType)
    1101         return new AddNumbersNode(left, right);
    1102     if (t1 == StringType && t2 == StringType)
    1103         return new AddStringsNode(left, right);
    1104     if (t1 == StringType)
    1105         return new AddStringLeftNode(left, right);
    1106     if (t2 == StringType)
    1107         return new AddStringRightNode(left, right);
    11081097    return new AddNode(left, right);
    11091098}
     
    11111100static LessNode* makeLessNode(ExpressionNode* left, ExpressionNode* right)
    11121101{
    1113     JSType t1 = left->expectedReturnType();
    1114     JSType t2 = right->expectedReturnType();
    1115    
    1116     if (t1 == StringType && t2 == StringType)
    1117         return new LessStringsNode(left, right);
    1118 
    1119     // There are certainly more efficient ways to do this type check if necessary
    1120     if (t1 == NumberType || t1 == BooleanType || t1 == UndefinedType || t1 == NullType ||
    1121         t2 == NumberType || t2 == BooleanType || t2 == UndefinedType || t2 == NullType)
    1122         return new LessNumbersNode(left, right);
    1123 
    1124     // Neither is certain to be a number, nor were both certain to be strings, so we use the default (slow) implementation.
    11251102    return new LessNode(left, right);
    11261103}
  • trunk/JavaScriptCore/kjs/internal.cpp

    r33979 r34355  
    8484}
    8585
     86JSObject* StringImp::toThisObject(ExecState* exec) const
     87{
     88    return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this));
     89}
     90
    8691// ------------------------------ NumberImp ------------------------------------
    8792
     
    125130  args.append(const_cast<NumberImp*>(this));
    126131  return static_cast<JSObject *>(exec->lexicalGlobalObject()->numberConstructor()->construct(exec,args));
     132}
     133
     134JSObject* NumberImp::toThisObject(ExecState* exec) const
     135{
     136    List args;
     137    args.append(const_cast<NumberImp*>(this));
     138    return static_cast<JSObject*>(exec->lexicalGlobalObject()->numberConstructor()->construct(exec, args));
    127139}
    128140
     
    198210}
    199211
     212bool GetterSetterImp::getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&)
     213{
     214    ASSERT_NOT_REACHED();
     215    return false;
     216}
     217
     218bool GetterSetterImp::getOwnPropertySlot(ExecState*, unsigned, PropertySlot&)
     219{
     220    ASSERT_NOT_REACHED();
     221    return false;
     222}
     223
     224void GetterSetterImp::put(ExecState*, const Identifier&, JSValue*)
     225{
     226    ASSERT_NOT_REACHED();
     227}
     228
     229void GetterSetterImp::put(ExecState*, unsigned, JSValue*)
     230{
     231    ASSERT_NOT_REACHED();
     232}
     233
     234JSObject* GetterSetterImp::toThisObject(ExecState*) const
     235{
     236    ASSERT_NOT_REACHED();
     237    return 0;
     238}
     239
    200240// ------------------------------ LabelStack -----------------------------------
    201241
  • trunk/JavaScriptCore/kjs/internal.h

    r33979 r34355  
    6060    virtual JSObject *toObject(ExecState *exec) const;
    6161    virtual UString toString(ExecState*) const;
    62    
     62    virtual JSObject* toThisObject(ExecState*) const;
     63
    6364    UString val;
    6465  };
  • trunk/JavaScriptCore/kjs/lookup.h

    r33038 r34355  
    8484   * Helper for getStaticFunctionSlot and getStaticPropertySlot
    8585   */
    86   inline JSValue* staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     86  inline JSValue* staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
    8787  {
    8888      // Look for cached value in dynamic map of properties (in JSObject)
     
    103103   */
    104104  template <class ThisImp>
    105   inline JSValue* staticValueGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
     105  inline JSValue* staticValueGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    106106  {
    107107      ThisImp* thisObj = static_cast<ThisImp*>(slot.slotBase());
  • trunk/JavaScriptCore/kjs/math_object.cpp

    r33038 r34355  
    201201
    202202    if (isnan(arg2))
    203         return jsNumber(NaN);
     203        return jsNaN();
    204204    if (isinf(arg2) && fabs(arg) == 1)
    205         return jsNumber(NaN);
     205        return jsNaN();
    206206    return jsNumber(pow(arg, arg2));
    207207}
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r34351 r34355  
    4646namespace KJS {
    4747
    48 class FunctionBodyNodeWithDebuggerHooks : public FunctionBodyNode {
    49 public:
    50     FunctionBodyNodeWithDebuggerHooks(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
    51     virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    52 };
    53 
    54 #if COMPILER(GCC)
    55 #define UNLIKELY(x) \
    56   __builtin_expect ((x), 0)
    57 #else
    58 #define UNLIKELY(x) x
    59 #endif
    60    
    6148#define KJS_CHECKEXCEPTION \
    6249if (UNLIKELY(exec->hadException())) \
     
    8673    return; \
    8774}
    88 
    89 #if !ASSERT_DISABLED
    90 static inline bool canSkipLookup(OldInterpreterExecState* exec, const Identifier& ident)
    91 {
    92     // Static lookup in EvalCode is impossible because variables aren't DontDelete.
    93     // Static lookup in GlobalCode may be possible, but we haven't implemented support for it yet.
    94     if (exec->codeType() != FunctionCode)
    95         return false;
    96 
    97     // Static lookup is impossible when something dynamic has been added to the front of the scope chain.
    98     if (exec->variableObject() != exec->scopeChain().top())
    99         return false;
    100 
    101     // Static lookup is impossible if the symbol isn't statically declared.
    102     if (!exec->variableObject()->symbolTable().contains(ident.ustring().rep()))
    103         return false;
    104 
    105     return true;
    106 }
    107 #endif
    10875
    10976static inline bool isConstant(const LocalStorage& localStorage, size_t index)
     
    236203}
    237204
    238 double ExpressionNode::evaluateToNumber(OldInterpreterExecState* exec)
    239 {
    240     JSValue* value = evaluate(exec);
    241     KJS_CHECKEXCEPTIONNUMBER
    242     return value->toNumber(exec);
    243 }
    244 
    245 bool ExpressionNode::evaluateToBoolean(OldInterpreterExecState* exec)
    246 {
    247     JSValue* value = evaluate(exec);
    248     KJS_CHECKEXCEPTIONBOOLEAN
    249     return value->toBoolean(exec);
    250 }
    251 
    252 int32_t ExpressionNode::evaluateToInt32(OldInterpreterExecState* exec)
    253 {
    254     JSValue* value = evaluate(exec);
    255     KJS_CHECKEXCEPTIONNUMBER
    256     return value->toInt32(exec);
    257 }
    258 
    259 uint32_t ExpressionNode::evaluateToUInt32(OldInterpreterExecState* exec)
    260 {
    261     JSValue* value = evaluate(exec);
    262     KJS_CHECKEXCEPTIONNUMBER
    263     return value->toUInt32(exec);
    264 }
    265 
    266205static void substitute(UString& string, const UString& substring) KJS_FAST_CALL;
    267206static void substitute(UString& string, const UString& substring)
     
    289228}
    290229
    291 JSValue* Node::setErrorCompletion(OldInterpreterExecState* exec, ErrorType e, const char* msg)
    292 {
    293     return exec->setThrowCompletion(Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
    294 }
    295 
    296 JSValue* Node::setErrorCompletion(OldInterpreterExecState* exec, ErrorType e, const char* msg, const Identifier& ident)
    297 {
    298     UString message = msg;
    299     substitute(message, ident.ustring());
    300     return exec->setThrowCompletion(Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
    301 }
    302 
    303 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg)
    304 {
    305     return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    306 }
    307 
    308 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, const char* string)
    309 {
    310     UString message = msg;
    311     substitute(message, string);
    312     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    313 }
    314 
    315 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr)
    316 {
    317     UString message = msg;
    318     substitute(message, v->toString(exec));
    319     substitute(message, expr->toString());
    320     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    321 }
    322 
    323 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, const Identifier& label)
    324 {
    325     UString message = msg;
    326     substitute(message, label.ustring());
    327     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    328 }
    329 
    330 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* e1, Node* e2)
    331 {
    332     UString message = msg;
    333     substitute(message, v->toString(exec));
    334     substitute(message, e1->toString());
    335     substitute(message, e2->toString());
    336     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    337 }
    338 
    339 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr, const Identifier& label)
    340 {
    341     UString message = msg;
    342     substitute(message, v->toString(exec));
    343     substitute(message, expr->toString());
    344     substitute(message, label.ustring());
    345     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    346 }
    347 
    348 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, const Identifier& label)
    349 {
    350     UString message = msg;
    351     substitute(message, v->toString(exec));
    352     substitute(message, label.ustring());
    353     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
    354 }
    355 
    356 JSValue* Node::throwUndefinedVariableError(OldInterpreterExecState* exec, const Identifier& ident)
    357 {
    358     return throwError(exec, ReferenceError, "Can't find variable: %s", ident);
    359 }
    360 
    361 void Node::handleException(OldInterpreterExecState* exec)
    362 {
    363     handleException(exec, exec->exception());
    364 }
    365 
    366 void Node::handleException(OldInterpreterExecState* exec, JSValue* exceptionValue)
    367 {
    368     if (exceptionValue->isObject()) {
    369         JSObject* exception = static_cast<JSObject*>(exceptionValue);
    370         if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) {
    371             exception->put(exec, "line", jsNumber(m_line));
    372             exception->put(exec, "sourceURL", jsString(currentSourceURL(exec)));
    373         }
    374     }
    375 #if 0
    376     Debugger* dbg = exec->dynamicGlobalObject()->debugger();
    377     if (dbg && !dbg->hasHandledException(exec, exceptionValue))
    378         dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);
    379 #endif
    380 }
    381 
    382 NEVER_INLINE JSValue* Node::rethrowException(OldInterpreterExecState* exec)
    383 {
    384     JSValue* exception = exec->exception();
    385     exec->clearException();
    386     handleException(exec, exception);
    387     return exec->setThrowCompletion(exception);
    388 }
    389 
    390230RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
    391231{
     
    436276}
    437277
    438 JSValue* BreakpointCheckStatement::execute(OldInterpreterExecState* exec)
    439 {
    440     return m_statement->execute(exec);
    441 }
    442 
    443278void BreakpointCheckStatement::streamTo(SourceStream& stream) const
    444279{
     
    446281}
    447282
    448 void BreakpointCheckStatement::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    449 {
    450     nodeStack.append(m_statement.get());
    451 }
    452 
    453283// ------------------------------ NullNode -------------------------------------
    454284
     
    458288}
    459289
    460 JSValue* NullNode::evaluate(OldInterpreterExecState* )
    461 {
    462     return jsNull();
    463 }
    464 
    465290// ------------------------------ FalseNode ----------------------------------
    466291
     
    470295}
    471296
    472 JSValue* FalseNode::evaluate(OldInterpreterExecState*)
    473 {
    474     return jsBoolean(false);
    475 }
    476 
    477297// ------------------------------ TrueNode ----------------------------------
    478298
     
    482302}
    483303
    484 JSValue* TrueNode::evaluate(OldInterpreterExecState*)
    485 {
    486     return jsBoolean(true);
    487 }
    488 
    489304// ------------------------------ NumberNode -----------------------------------
    490305
     
    492307{
    493308    return generator.emitLoad(generator.finalDestination(dst), m_double);
    494 }
    495 
    496 JSValue* NumberNode::evaluate(OldInterpreterExecState*)
    497 {
    498     // Number nodes are only created when the number can't fit in a JSImmediate, so no need to check again.
    499     return jsNumberCell(m_double);
    500 }
    501 
    502 double NumberNode::evaluateToNumber(OldInterpreterExecState*)
    503 {
    504     return m_double;
    505 }
    506 
    507 bool NumberNode::evaluateToBoolean(OldInterpreterExecState*)
    508 {
    509     return m_double < 0.0 || m_double > 0.0; // false for NaN as well as 0
    510 }
    511 
    512 int32_t NumberNode::evaluateToInt32(OldInterpreterExecState*)
    513 {
    514     return JSValue::toInt32(m_double);
    515 }
    516 
    517 uint32_t NumberNode::evaluateToUInt32(OldInterpreterExecState*)
    518 {
    519     return JSValue::toUInt32(m_double);
    520 }
    521 
    522 // ------------------------------ ImmediateNumberNode -----------------------------------
    523 
    524 JSValue* ImmediateNumberNode::evaluate(OldInterpreterExecState*)
    525 {
    526     return m_value;
    527 }
    528 
    529 int32_t ImmediateNumberNode::evaluateToInt32(OldInterpreterExecState*)
    530 {
    531     return JSImmediate::getTruncatedInt32(m_value);
    532 }
    533 
    534 uint32_t ImmediateNumberNode::evaluateToUInt32(OldInterpreterExecState*)
    535 {
    536     uint32_t i;
    537     if (JSImmediate::getTruncatedUInt32(m_value, i))
    538         return i;
    539     bool ok;
    540     return JSValue::toUInt32SlowCase(m_double, ok);
    541309}
    542310
     
    547315    // FIXME: should we try to atomize constant strings?
    548316    return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(m_value));
    549 }
    550 
    551 JSValue* StringNode::evaluate(OldInterpreterExecState*)
    552 {
    553     return jsOwnedString(m_value);
    554 }
    555 
    556 double StringNode::evaluateToNumber(OldInterpreterExecState*)
    557 {
    558     return m_value.toDouble();
    559 }
    560 
    561 bool StringNode::evaluateToBoolean(OldInterpreterExecState*)
    562 {
    563     return !m_value.isEmpty();
    564317}
    565318
     
    573326}
    574327
    575 JSValue* RegExpNode::evaluate(OldInterpreterExecState*)
    576 {
    577     ASSERT_NOT_REACHED();
    578     return 0;
    579 }
    580 
    581328// ------------------------------ ThisNode -------------------------------------
    582329
     
    584331{
    585332    return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
    586 }
    587 
    588 // ECMA 11.1.1
    589 JSValue* ThisNode::evaluate(OldInterpreterExecState* exec)
    590 {
    591     return exec->thisValue();
    592333}
    593334
     
    600341
    601342    return generator.emitResolve(generator.finalDestination(dst), m_ident);
    602 }
    603 
    604 // ECMA 11.1.2 & 10.1.4
    605 JSValue* ResolveNode::inlineEvaluate(OldInterpreterExecState* exec)
    606 {
    607     // Check for missed optimization opportunity.
    608     ASSERT(!canSkipLookup(exec, m_ident));
    609 
    610     const ScopeChain& chain = exec->scopeChain();
    611     ScopeChainIterator iter = chain.begin();
    612     ScopeChainIterator end = chain.end();
    613 
    614     // we must always have something in the scope chain
    615     ASSERT(iter != end);
    616 
    617     PropertySlot slot;
    618     do {
    619         JSObject* o = *iter;
    620 
    621         if (o->getPropertySlot(exec, m_ident, slot))
    622             return slot.getValue(exec, o, m_ident);
    623 
    624         ++iter;
    625     } while (iter != end);
    626 
    627     return throwUndefinedVariableError(exec, m_ident);
    628 }
    629 
    630 JSValue* ResolveNode::evaluate(OldInterpreterExecState* exec)
    631 {
    632     return inlineEvaluate(exec);
    633 }
    634 
    635 double ResolveNode::evaluateToNumber(OldInterpreterExecState* exec)
    636 {
    637     JSValue* v = inlineEvaluate(exec);
    638     KJS_CHECKEXCEPTIONNUMBER
    639     return v->toNumber(exec);
    640 }
    641 
    642 bool ResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)
    643 {
    644     JSValue* v = inlineEvaluate(exec);
    645     KJS_CHECKEXCEPTIONBOOLEAN
    646     return v->toBoolean(exec);
    647 }
    648 
    649 int32_t ResolveNode::evaluateToInt32(OldInterpreterExecState* exec)
    650 {
    651     JSValue* v = inlineEvaluate(exec);
    652     KJS_CHECKEXCEPTIONNUMBER
    653     return v->toInt32(exec);
    654 }
    655 
    656 uint32_t ResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)
    657 {
    658     JSValue* v = inlineEvaluate(exec);
    659     KJS_CHECKEXCEPTIONNUMBER
    660     return v->toUInt32(exec);
    661 }
    662 
    663 static size_t getSymbolTableEntry(OldInterpreterExecState* exec, const Identifier& ident, const SymbolTable& symbolTable, size_t& stackDepth)
    664 {
    665     int index = symbolTable.get(ident.ustring().rep()).getIndex();
    666     if (index != missingSymbolMarker()) {
    667         stackDepth = 0;
    668         return index;
    669     }
    670    
    671     if (ident == exec->propertyNames().arguments) {
    672         stackDepth = 0;
    673         return missingSymbolMarker();
    674     }
    675    
    676     const ScopeChain& chain = exec->scopeChain();
    677     ScopeChainIterator iter = chain.begin();
    678     ScopeChainIterator end = chain.end();
    679     size_t depth = 0;
    680     for (; iter != end; ++iter, ++depth) {
    681         JSObject* currentScope = *iter;
    682         if (!currentScope->isVariableObject())
    683             break;
    684         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
    685         index = currentVariableObject->symbolTable().get(ident.ustring().rep()).getIndex();
    686         if (index != missingSymbolMarker()) {
    687             stackDepth = depth;
    688             return index;
    689         }
    690         if (currentVariableObject->isDynamicScope())
    691             break;
    692     }
    693     stackDepth = depth;
    694     return missingSymbolMarker();
    695 }
    696 
    697 void ResolveNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
    698 {
    699     size_t depth = 0;
    700     int index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
    701     if (index != missingSymbolMarker()) {
    702         if (!depth)
    703             new (this) LocalVarAccessNode(index);
    704         else
    705             new (this) ScopedVarAccessNode(index, depth);
    706         return;
    707     }
    708 
    709     if (!depth)
    710         return;
    711 
    712     new (this) NonLocalVarAccessNode(depth);
    713 }
    714 
    715 JSValue* LocalVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
    716 {
    717     ASSERT(exec->variableObject() == exec->scopeChain().top());
    718     return exec->localStorage()[m_index].value;
    719 }
    720 
    721 JSValue* LocalVarAccessNode::evaluate(OldInterpreterExecState* exec)
    722 {
    723     return inlineEvaluate(exec);
    724 }
    725 
    726 double LocalVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
    727 {
    728     return inlineEvaluate(exec)->toNumber(exec);
    729 }
    730 
    731 bool LocalVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
    732 {
    733     return inlineEvaluate(exec)->toBoolean(exec);
    734 }
    735 
    736 int32_t LocalVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
    737 {
    738     return inlineEvaluate(exec)->toInt32(exec);
    739 }
    740 
    741 uint32_t LocalVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
    742 {
    743     return inlineEvaluate(exec)->toUInt32(exec);
    744 }
    745 
    746 static inline JSValue* getNonLocalSymbol(OldInterpreterExecState* exec, size_t, size_t scopeDepth)
    747 {
    748     const ScopeChain& chain = exec->scopeChain();
    749     ScopeChainIterator iter = chain.begin();
    750     for (size_t i = 0; i < scopeDepth; ++iter, ++i)
    751         ASSERT(iter != chain.end());
    752 #ifndef NDEBUG
    753     JSObject* scope = *iter;
    754 #endif
    755     ASSERT(scope->isVariableObject());
    756     ASSERT_NOT_REACHED();
    757     return 0;
    758 }
    759 
    760 JSValue* ScopedVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
    761 {
    762     return getNonLocalSymbol(exec, m_index, m_scopeDepth);
    763 }
    764 
    765 JSValue* ScopedVarAccessNode::evaluate(OldInterpreterExecState* exec)
    766 {
    767     return inlineEvaluate(exec);
    768 }
    769 
    770 double ScopedVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
    771 {
    772     return inlineEvaluate(exec)->toNumber(exec);
    773 }
    774 
    775 bool ScopedVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
    776 {
    777     return inlineEvaluate(exec)->toBoolean(exec);
    778 }
    779 
    780 int32_t ScopedVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
    781 {
    782     return inlineEvaluate(exec)->toInt32(exec);
    783 }
    784 
    785 uint32_t ScopedVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
    786 {
    787     return inlineEvaluate(exec)->toUInt32(exec);
    788 }
    789 
    790 JSValue* NonLocalVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
    791 {
    792     // Check for missed optimization opportunity.
    793     ASSERT(!canSkipLookup(exec, m_ident));
    794    
    795     const ScopeChain& chain = exec->scopeChain();
    796     ScopeChainIterator iter = chain.begin();
    797     ScopeChainIterator end = chain.end();
    798     for (size_t i = 0; i < m_scopeDepth; ++i, ++iter)
    799         ASSERT(iter != end);
    800 
    801     // we must always have something in the scope chain
    802     ASSERT(iter != end);
    803    
    804     PropertySlot slot;
    805     do {
    806         JSObject* o = *iter;
    807        
    808         if (o->getPropertySlot(exec, m_ident, slot))
    809             return slot.getValue(exec, o, m_ident);
    810        
    811         ++iter;
    812     } while (iter != end);
    813    
    814     return throwUndefinedVariableError(exec, m_ident);
    815 }
    816 
    817 JSValue* NonLocalVarAccessNode::evaluate(OldInterpreterExecState* exec)
    818 {
    819     return inlineEvaluate(exec);
    820 }
    821 
    822 double NonLocalVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
    823 {
    824     return inlineEvaluate(exec)->toNumber(exec);
    825 }
    826 
    827 bool NonLocalVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
    828 {
    829     return inlineEvaluate(exec)->toBoolean(exec);
    830 }
    831 
    832 int32_t NonLocalVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
    833 {
    834     return inlineEvaluate(exec)->toInt32(exec);
    835 }
    836 
    837 uint32_t NonLocalVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
    838 {
    839     return inlineEvaluate(exec)->toUInt32(exec);
    840 }
    841 
    842 // ------------------------------ ElementNode ----------------------------------
    843 
    844 void ElementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    845 {
    846     if (m_next)
    847         nodeStack.append(m_next.get());
    848     ASSERT(m_node);
    849     nodeStack.append(m_node.get());
    850 }
    851 
    852 // ECMA 11.1.4
    853 JSValue* ElementNode::evaluate(OldInterpreterExecState* exec)
    854 {
    855     JSObject* array = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());
    856     int length = 0;
    857     for (ElementNode* n = this; n; n = n->m_next.get()) {
    858         JSValue* val = n->m_node->evaluate(exec);
    859         KJS_CHECKEXCEPTIONVALUE
    860         length += n->m_elision;
    861         array->put(exec, length++, val);
    862     }
    863     return array;
    864343}
    865344
     
    885364}
    886365
    887 void ArrayNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    888 {
    889     if (m_element)
    890         nodeStack.append(m_element.get());
    891 }
    892 
    893 // ECMA 11.1.4
    894 JSValue* ArrayNode::evaluate(OldInterpreterExecState* exec)
    895 {
    896     JSObject* array;
    897     int length;
    898 
    899     if (m_element) {
    900         array = static_cast<JSObject*>(m_element->evaluate(exec));
    901         KJS_CHECKEXCEPTIONVALUE
    902         length = m_optional ? array->get(exec, exec->propertyNames().length)->toInt32(exec) : 0;
    903     } else {
    904         JSValue* newArr = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());
    905         array = static_cast<JSObject*>(newArr);
    906         length = 0;
    907     }
    908 
    909     if (m_optional)
    910         array->put(exec, exec->propertyNames().length, jsNumber(m_elision + length));
    911 
    912     return array;
    913 }
    914 
    915366// ------------------------------ ObjectLiteralNode ----------------------------
    916367
     
    921372    else
    922373        return generator.emitNewObject(generator.finalDestination(dst));
    923 }
    924 
    925 void ObjectLiteralNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    926 {
    927     if (m_list)
    928         nodeStack.append(m_list.get());
    929 }
    930 
    931 // ECMA 11.1.5
    932 JSValue* ObjectLiteralNode::evaluate(OldInterpreterExecState* exec)
    933 {
    934     if (m_list)
    935         return m_list->evaluate(exec);
    936 
    937     return exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
    938374}
    939375
     
    970406}
    971407
    972 void PropertyListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    973 {
    974     if (m_next)
    975         nodeStack.append(m_next.get());
    976     nodeStack.append(m_node.get());
    977 }
    978 
    979 // ECMA 11.1.5
    980 JSValue* PropertyListNode::evaluate(OldInterpreterExecState* exec)
    981 {
    982     JSObject* obj = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
    983 
    984     for (PropertyListNode* p = this; p; p = p->m_next.get()) {
    985         JSValue* v = p->m_node->m_assign->evaluate(exec);
    986         KJS_CHECKEXCEPTIONVALUE
    987 
    988         switch (p->m_node->m_type) {
    989             case PropertyNode::Getter:
    990                 ASSERT(v->isObject());
    991                 obj->defineGetter(exec, p->m_node->name(), static_cast<JSObject* >(v));
    992                 break;
    993             case PropertyNode::Setter:
    994                 ASSERT(v->isObject());
    995                 obj->defineSetter(exec, p->m_node->name(), static_cast<JSObject* >(v));
    996                 break;
    997             case PropertyNode::Constant:
    998                 obj->put(exec, p->m_node->name(), v);
    999                 break;
    1000         }
    1001     }
    1002 
    1003     return obj;
    1004 }
    1005 
    1006 // ------------------------------ PropertyNode -----------------------------
    1007 
    1008 void PropertyNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1009 {
    1010     nodeStack.append(m_assign.get());
    1011 }
    1012 
    1013 // ECMA 11.1.5
    1014 JSValue* PropertyNode::evaluate(OldInterpreterExecState*)
    1015 {
    1016     ASSERT(false);
    1017     return jsNull();
    1018 }
    1019 
    1020408// ------------------------------ BracketAccessorNode --------------------------------
    1021409
     
    1028416}
    1029417
    1030 void BracketAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1031 {
    1032     nodeStack.append(m_subscript.get());
    1033     nodeStack.append(m_base.get());
    1034 }
    1035 
    1036 // ECMA 11.2.1a
    1037 JSValue* BracketAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)
    1038 {
    1039     JSValue* v1 = m_base->evaluate(exec);
    1040     KJS_CHECKEXCEPTIONVALUE
    1041     JSValue* v2 = m_subscript->evaluate(exec);
    1042     KJS_CHECKEXCEPTIONVALUE
    1043     JSObject* o = v1->toObject(exec);
    1044     uint32_t i;
    1045     if (v2->getUInt32(i))
    1046         return o->get(exec, i);
    1047     return o->get(exec, Identifier(v2->toString(exec)));
    1048 }
    1049 
    1050 JSValue* BracketAccessorNode::evaluate(OldInterpreterExecState* exec)
    1051 {
    1052     return inlineEvaluate(exec);
    1053 }
    1054 
    1055 double BracketAccessorNode::evaluateToNumber(OldInterpreterExecState* exec)
    1056 {
    1057     JSValue* v = inlineEvaluate(exec);
    1058     KJS_CHECKEXCEPTIONNUMBER
    1059     return v->toNumber(exec);
    1060 }
    1061 
    1062 bool BracketAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1063 {
    1064     JSValue* v = inlineEvaluate(exec);
    1065     KJS_CHECKEXCEPTIONBOOLEAN
    1066     return v->toBoolean(exec);
    1067 }
    1068 
    1069 int32_t BracketAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)
    1070 {
    1071     JSValue* v = inlineEvaluate(exec);
    1072     KJS_CHECKEXCEPTIONNUMBER
    1073     return v->toInt32(exec);
    1074 }
    1075 
    1076 uint32_t BracketAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1077 {
    1078     JSValue* v = inlineEvaluate(exec);
    1079     KJS_CHECKEXCEPTIONNUMBER
    1080     return v->toUInt32(exec);
    1081 }
    1082 
    1083418// ------------------------------ DotAccessorNode --------------------------------
    1084419
     
    1089424}
    1090425
    1091 void DotAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1092 {
    1093     nodeStack.append(m_base.get());
    1094 }
    1095 
    1096 // ECMA 11.2.1b
    1097 JSValue* DotAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)
    1098 {
    1099     JSValue* v = m_base->evaluate(exec);
    1100     KJS_CHECKEXCEPTIONVALUE
    1101     return v->toObject(exec)->get(exec, m_ident);
    1102 }
    1103 
    1104 JSValue* DotAccessorNode::evaluate(OldInterpreterExecState* exec)
    1105 {
    1106     return inlineEvaluate(exec);
    1107 }
    1108 
    1109 double DotAccessorNode::evaluateToNumber(OldInterpreterExecState* exec)
    1110 {
    1111     JSValue* v = inlineEvaluate(exec);
    1112     KJS_CHECKEXCEPTIONNUMBER
    1113     return v->toNumber(exec);
    1114 }
    1115 
    1116 bool DotAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1117 {
    1118     JSValue* v = inlineEvaluate(exec);
    1119     KJS_CHECKEXCEPTIONBOOLEAN
    1120     return v->toBoolean(exec);
    1121 }
    1122 
    1123 int32_t DotAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)
    1124 {
    1125     JSValue* v = inlineEvaluate(exec);
    1126     KJS_CHECKEXCEPTIONNUMBER
    1127     return v->toInt32(exec);
    1128 }
    1129 
    1130 uint32_t DotAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1131 {
    1132     JSValue* v = inlineEvaluate(exec);
    1133     KJS_CHECKEXCEPTIONNUMBER
    1134     return v->toUInt32(exec);
    1135 }
    1136 
    1137426// ------------------------------ ArgumentListNode -----------------------------
    1138427
     
    1143432}
    1144433
    1145 void ArgumentListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1146 {
    1147     if (m_next)
    1148         nodeStack.append(m_next.get());
    1149     ASSERT(m_expr);
    1150     nodeStack.append(m_expr.get());
    1151 }
    1152 
    1153 // ECMA 11.2.4
    1154 void ArgumentListNode::evaluateList(OldInterpreterExecState* exec, List& list)
    1155 {
    1156     for (ArgumentListNode* n = this; n; n = n->m_next.get()) {
    1157         JSValue* v = n->m_expr->evaluate(exec);
    1158         KJS_CHECKEXCEPTIONVOID
    1159         list.append(v);
    1160     }
    1161 }
    1162 
    1163 // ------------------------------ ArgumentsNode --------------------------------
    1164 
    1165 void ArgumentsNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1166 {
    1167     if (m_listNode)
    1168         nodeStack.append(m_listNode.get());
    1169 }
    1170 
    1171434// ------------------------------ NewExprNode ----------------------------------
    1172435
     
    1175438    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
    1176439    return generator.emitConstruct(generator.finalDestination(dst), r0.get(), m_args.get());
    1177 }
    1178 
    1179 void NewExprNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1180 {
    1181     if (m_args)
    1182         nodeStack.append(m_args.get());
    1183     nodeStack.append(m_expr.get());
    1184 }
    1185 
    1186 // ECMA 11.2.2
    1187 
    1188 JSValue* NewExprNode::inlineEvaluate(OldInterpreterExecState* exec)
    1189 {
    1190     JSValue* v = m_expr->evaluate(exec);
    1191     KJS_CHECKEXCEPTIONVALUE
    1192 
    1193     List argList;
    1194     if (m_args) {
    1195         m_args->evaluateList(exec, argList);
    1196         KJS_CHECKEXCEPTIONVALUE
    1197     }
    1198 
    1199     if (!v->isObject())
    1200         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, m_expr.get());
    1201 
    1202     ConstructData constructData;
    1203     if (v->getConstructData(constructData) == ConstructTypeNone)
    1204         return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, m_expr.get());
    1205 
    1206     return static_cast<JSObject*>(v)->construct(exec, argList);
    1207 }
    1208 
    1209 JSValue* NewExprNode::evaluate(OldInterpreterExecState* exec)
    1210 {
    1211     return inlineEvaluate(exec);
    1212 }
    1213 
    1214 double NewExprNode::evaluateToNumber(OldInterpreterExecState* exec)
    1215 {
    1216     JSValue* v = inlineEvaluate(exec);
    1217     KJS_CHECKEXCEPTIONNUMBER
    1218     return v->toNumber(exec);
    1219 }
    1220 
    1221 bool NewExprNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1222 {
    1223     JSValue* v = inlineEvaluate(exec);
    1224     KJS_CHECKEXCEPTIONBOOLEAN
    1225     return v->toBoolean(exec);
    1226 }
    1227 
    1228 int32_t NewExprNode::evaluateToInt32(OldInterpreterExecState* exec)
    1229 {
    1230     JSValue* v = inlineEvaluate(exec);
    1231     KJS_CHECKEXCEPTIONNUMBER
    1232     return v->toInt32(exec);
    1233 }
    1234 
    1235 uint32_t NewExprNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1236 {
    1237     JSValue* v = inlineEvaluate(exec);
    1238     KJS_CHECKEXCEPTIONNUMBER
    1239     return v->toUInt32(exec);
    1240 }
    1241 
    1242 template <ExpressionNode::CallerType callerType, bool scopeDepthIsZero>
    1243 inline JSValue* ExpressionNode::resolveAndCall(OldInterpreterExecState* exec, const Identifier& ident, ArgumentsNode* args, size_t scopeDepth)
    1244 {
    1245     const ScopeChain& chain = exec->scopeChain();
    1246     ScopeChainIterator iter = chain.begin();
    1247     ScopeChainIterator end = chain.end();
    1248 
    1249     if (!scopeDepthIsZero) {
    1250         for (size_t i = 0; i < scopeDepth; ++iter, ++i)
    1251             ASSERT(iter != chain.end());
    1252     }
    1253    
    1254     // we must always have something in the scope chain
    1255     ASSERT(iter != end);
    1256 
    1257     PropertySlot slot;
    1258     JSObject* base;
    1259     do {
    1260         base = *iter;
    1261         if (base->getPropertySlot(exec, ident, slot)) {
    1262             JSValue* v = slot.getValue(exec, base, ident);
    1263             KJS_CHECKEXCEPTIONVALUE
    1264 
    1265             if (!v->isObject())
    1266                 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident);
    1267 
    1268             JSObject* func = static_cast<JSObject*>(v);
    1269 
    1270             if (!func->implementsCall())
    1271                 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident);
    1272 
    1273             List argList;
    1274             args->evaluateList(exec, argList);
    1275             KJS_CHECKEXCEPTIONVALUE
    1276 
    1277             if (callerType == EvalOperator) {
    1278                 if (base == exec->lexicalGlobalObject() && func == exec->lexicalGlobalObject()->evalFunction()) {
    1279                     ASSERT_NOT_REACHED();
    1280                 }
    1281             }
    1282 
    1283             JSObject* thisObj = base->toThisObject(exec);
    1284             return func->callAsFunction(exec, thisObj, argList);
    1285         }
    1286         ++iter;
    1287     } while (iter != end);
    1288 
    1289     return throwUndefinedVariableError(exec, ident);
    1290440}
    1291441
     
    1298448}
    1299449
    1300 void EvalFunctionCallNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1301 {
    1302     nodeStack.append(m_args.get());
    1303 }
    1304 
    1305 JSValue* EvalFunctionCallNode::evaluate(OldInterpreterExecState* exec)
    1306 {
    1307     return resolveAndCall<EvalOperator, true>(exec, exec->propertyNames().eval, m_args.get());
    1308 }
    1309 
    1310450RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    1311451{
    1312452    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
    1313453    return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get());
    1314 }
    1315 
    1316 void FunctionCallValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1317 {
    1318     nodeStack.append(m_args.get());
    1319     nodeStack.append(m_expr.get());
    1320 }
    1321 
    1322 // ECMA 11.2.3
    1323 JSValue* FunctionCallValueNode::evaluate(OldInterpreterExecState* exec)
    1324 {
    1325     JSValue* v = m_expr->evaluate(exec);
    1326     KJS_CHECKEXCEPTIONVALUE
    1327 
    1328     if (!v->isObject()) {
    1329         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_expr.get());
    1330     }
    1331 
    1332     JSObject* func = static_cast<JSObject*>(v);
    1333 
    1334     if (!func->implementsCall()) {
    1335         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_expr.get());
    1336     }
    1337 
    1338     List argList;
    1339     m_args->evaluateList(exec, argList);
    1340     KJS_CHECKEXCEPTIONVALUE
    1341 
    1342     JSObject* thisObj = exec->globalThisValue();
    1343     return func->callAsFunction(exec, thisObj, argList);
    1344454}
    1345455
     
    1362472}
    1363473
    1364 void FunctionCallResolveNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack& nodeStack)
    1365 {
    1366     nodeStack.append(m_args.get());
    1367 
    1368     size_t depth = 0;
    1369     int index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
    1370     if (index != missingSymbolMarker()) {
    1371         if (!depth)
    1372             new (this) LocalVarFunctionCallNode(index);
    1373         else
    1374             new (this) ScopedVarFunctionCallNode(index, depth);
    1375         return;
    1376     }
    1377    
    1378     if (!depth)
    1379         return;
    1380    
    1381     new (this) NonLocalVarFunctionCallNode(depth);
    1382 }
    1383 
    1384 // ECMA 11.2.3
    1385 JSValue* FunctionCallResolveNode::inlineEvaluate(OldInterpreterExecState* exec)
    1386 {
    1387     // Check for missed optimization opportunity.
    1388     ASSERT(!canSkipLookup(exec, m_ident));
    1389 
    1390     return resolveAndCall<FunctionCall, true>(exec, m_ident, m_args.get());
    1391 }
    1392 
    1393 JSValue* FunctionCallResolveNode::evaluate(OldInterpreterExecState* exec)
    1394 {
    1395     return inlineEvaluate(exec);
    1396 }
    1397 
    1398 double FunctionCallResolveNode::evaluateToNumber(OldInterpreterExecState* exec)
    1399 {
    1400     JSValue* v = inlineEvaluate(exec);
    1401     KJS_CHECKEXCEPTIONNUMBER
    1402     return v->toNumber(exec);
    1403 }
    1404 
    1405 bool FunctionCallResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1406 {
    1407     JSValue* v = inlineEvaluate(exec);
    1408     KJS_CHECKEXCEPTIONBOOLEAN
    1409     return v->toBoolean(exec);
    1410 }
    1411 
    1412 int32_t FunctionCallResolveNode::evaluateToInt32(OldInterpreterExecState* exec)
    1413 {
    1414     JSValue* v = inlineEvaluate(exec);
    1415     KJS_CHECKEXCEPTIONNUMBER
    1416     return v->toInt32(exec);
    1417 }
    1418 
    1419 uint32_t FunctionCallResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1420 {
    1421     JSValue* v = inlineEvaluate(exec);
    1422     KJS_CHECKEXCEPTIONNUMBER
    1423     return v->toUInt32(exec);
    1424 }
    1425 
    1426 JSValue* LocalVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
    1427 {
    1428     ASSERT(exec->variableObject() == exec->scopeChain().top());
    1429 
    1430     JSValue* v = exec->localStorage()[m_index].value;
    1431 
    1432     if (!v->isObject())
    1433         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);
    1434 
    1435     JSObject* func = static_cast<JSObject*>(v);
    1436     if (!func->implementsCall())
    1437         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);
    1438 
    1439     List argList;
    1440     m_args->evaluateList(exec, argList);
    1441     KJS_CHECKEXCEPTIONVALUE
    1442 
    1443     JSObject* thisObj = exec->globalThisValue();
    1444     return func->callAsFunction(exec, thisObj, argList);
    1445 }
    1446 
    1447 JSValue* LocalVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
    1448 {
    1449     return inlineEvaluate(exec);
    1450 }
    1451 
    1452 double LocalVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
    1453 {
    1454     JSValue* v = inlineEvaluate(exec);
    1455     KJS_CHECKEXCEPTIONNUMBER
    1456     return v->toNumber(exec);
    1457 }
    1458 
    1459 bool LocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1460 {
    1461     JSValue* v = inlineEvaluate(exec);
    1462     KJS_CHECKEXCEPTIONBOOLEAN
    1463     return v->toBoolean(exec);
    1464 }
    1465 
    1466 int32_t LocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
    1467 {
    1468     JSValue* v = inlineEvaluate(exec);
    1469     KJS_CHECKEXCEPTIONNUMBER
    1470     return v->toInt32(exec);
    1471 }
    1472 
    1473 uint32_t LocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1474 {
    1475     JSValue* v = inlineEvaluate(exec);
    1476     KJS_CHECKEXCEPTIONNUMBER
    1477     return v->toUInt32(exec);
    1478 }
    1479 
    1480 JSValue* ScopedVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
    1481 {
    1482     ASSERT(exec->variableObject() == exec->scopeChain().top());
    1483    
    1484     JSValue* v = getNonLocalSymbol(exec, m_index, m_scopeDepth);
    1485    
    1486     if (!v->isObject())
    1487         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);
    1488    
    1489     JSObject* func = static_cast<JSObject*>(v);
    1490     if (!func->implementsCall())
    1491         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);
    1492    
    1493     List argList;
    1494     m_args->evaluateList(exec, argList);
    1495     KJS_CHECKEXCEPTIONVALUE
    1496 
    1497     JSObject* thisObj = exec->globalThisValue();
    1498     return func->callAsFunction(exec, thisObj, argList);
    1499 }
    1500 
    1501 JSValue* ScopedVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
    1502 {
    1503     return inlineEvaluate(exec);
    1504 }
    1505 
    1506 double ScopedVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
    1507 {
    1508     JSValue* v = inlineEvaluate(exec);
    1509     KJS_CHECKEXCEPTIONNUMBER
    1510     return v->toNumber(exec);
    1511 }
    1512 
    1513 bool ScopedVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1514 {
    1515     JSValue* v = inlineEvaluate(exec);
    1516     KJS_CHECKEXCEPTIONBOOLEAN
    1517     return v->toBoolean(exec);
    1518 }
    1519 
    1520 int32_t ScopedVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
    1521 {
    1522     JSValue* v = inlineEvaluate(exec);
    1523     KJS_CHECKEXCEPTIONNUMBER
    1524     return v->toInt32(exec);
    1525 }
    1526 
    1527 uint32_t ScopedVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1528 {
    1529     JSValue* v = inlineEvaluate(exec);
    1530     KJS_CHECKEXCEPTIONNUMBER
    1531     return v->toUInt32(exec);
    1532 }
    1533 
    1534 JSValue* NonLocalVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
    1535 {
    1536     // Check for missed optimization opportunity.
    1537     ASSERT(!canSkipLookup(exec, m_ident));
    1538    
    1539     return resolveAndCall<FunctionCall, false>(exec, m_ident, m_args.get(), m_scopeDepth);
    1540 }
    1541 
    1542 JSValue* NonLocalVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
    1543 {
    1544     return inlineEvaluate(exec);
    1545 }
    1546 
    1547 double NonLocalVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
    1548 {
    1549     JSValue* v = inlineEvaluate(exec);
    1550     KJS_CHECKEXCEPTIONNUMBER
    1551     return v->toNumber(exec);
    1552 }
    1553 
    1554 bool NonLocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1555 {
    1556     JSValue* v = inlineEvaluate(exec);
    1557     KJS_CHECKEXCEPTIONBOOLEAN
    1558     return v->toBoolean(exec);
    1559 }
    1560 
    1561 int32_t NonLocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
    1562 {
    1563     JSValue* v = inlineEvaluate(exec);
    1564     KJS_CHECKEXCEPTIONNUMBER
    1565     return v->toInt32(exec);
    1566 }
    1567 
    1568 uint32_t NonLocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1569 {
    1570     JSValue* v = inlineEvaluate(exec);
    1571     KJS_CHECKEXCEPTIONNUMBER
    1572     return v->toUInt32(exec);
    1573 }
    1574 
    1575474RegisterID* FunctionCallBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    1576475{
     
    1581480}
    1582481
    1583 void FunctionCallBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1584 {
    1585     nodeStack.append(m_args.get());
    1586     nodeStack.append(m_subscript.get());
    1587     nodeStack.append(m_base.get());
    1588 }
    1589 
    1590 // ECMA 11.2.3
    1591 JSValue* FunctionCallBracketNode::evaluate(OldInterpreterExecState* exec)
    1592 {
    1593     JSValue* baseVal = m_base->evaluate(exec);
    1594     KJS_CHECKEXCEPTIONVALUE
    1595 
    1596     JSValue* subscriptVal = m_subscript->evaluate(exec);
    1597 
    1598     JSObject* baseObj = baseVal->toObject(exec);
    1599     uint32_t i;
    1600     PropertySlot slot;
    1601 
    1602     JSValue* funcVal;
    1603     if (subscriptVal->getUInt32(i)) {
    1604         if (baseObj->getPropertySlot(exec, i, slot))
    1605             funcVal = slot.getValue(exec, baseObj, i);
    1606         else
    1607             funcVal = jsUndefined();
    1608     } else {
    1609         Identifier ident(subscriptVal->toString(exec));
    1610         if (baseObj->getPropertySlot(exec, ident, slot))
    1611             funcVal = baseObj->get(exec, ident);
    1612         else
    1613             funcVal = jsUndefined();
    1614     }
    1615 
    1616     KJS_CHECKEXCEPTIONVALUE
    1617 
    1618     if (!funcVal->isObject())
    1619         return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, m_base.get(), m_subscript.get());
    1620 
    1621     JSObject* func = static_cast<JSObject*>(funcVal);
    1622 
    1623     if (!func->implementsCall())
    1624         return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, m_base.get(), m_subscript.get());
    1625 
    1626     List argList;
    1627     m_args->evaluateList(exec, argList);
    1628     KJS_CHECKEXCEPTIONVALUE
    1629 
    1630     JSObject* thisObj = baseObj;
    1631     ASSERT(thisObj);
    1632     ASSERT(thisObj->isObject());
    1633     ASSERT(!thisObj->isActivationObject());
    1634 
    1635     // No need to call toThisObject() on the thisObj as it is known not to be the GlobalObject or ActivationObject
    1636     return func->callAsFunction(exec, thisObj, argList);
    1637 }
    1638 
    1639 static const char* dotExprNotAnObjectString() KJS_FAST_CALL;
    1640 static const char* dotExprNotAnObjectString()
    1641 {
    1642     return "Value %s (result of expression %s.%s) is not object.";
    1643 }
    1644 
    1645 static const char* dotExprDoesNotAllowCallsString() KJS_FAST_CALL;
    1646 static const char* dotExprDoesNotAllowCallsString()
    1647 {
    1648     return "Object %s (result of expression %s.%s) does not allow calls.";
    1649 }
    1650 
    1651482RegisterID* FunctionCallDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    1652483{
     
    1655486    return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
    1656487}
    1657 
    1658 void FunctionCallDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1659 {
    1660     nodeStack.append(m_args.get());
    1661     nodeStack.append(m_base.get());
    1662 }
    1663 
    1664 // ECMA 11.2.3
    1665 JSValue* FunctionCallDotNode::inlineEvaluate(OldInterpreterExecState* exec)
    1666 {
    1667     JSValue* baseVal = m_base->evaluate(exec);
    1668     KJS_CHECKEXCEPTIONVALUE
    1669 
    1670     JSObject* baseObj = baseVal->toObject(exec);
    1671     PropertySlot slot;
    1672     JSValue* funcVal = baseObj->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, baseObj, m_ident) : jsUndefined();
    1673     KJS_CHECKEXCEPTIONVALUE
    1674 
    1675     if (!funcVal->isObject())
    1676         return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, m_base.get(), m_ident);
    1677 
    1678     JSObject* func = static_cast<JSObject*>(funcVal);
    1679 
    1680     if (!func->implementsCall())
    1681         return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, m_base.get(), m_ident);
    1682 
    1683     List argList;
    1684     m_args->evaluateList(exec, argList);
    1685     KJS_CHECKEXCEPTIONVALUE
    1686 
    1687     JSObject* thisObj = baseObj;
    1688     ASSERT(thisObj);
    1689     ASSERT(thisObj->isObject());
    1690     ASSERT(!thisObj->isActivationObject());
    1691 
    1692     // No need to call toThisObject() on the thisObj as it is known not to be the GlobalObject or ActivationObject
    1693     return func->callAsFunction(exec, thisObj, argList);
    1694 }
    1695 
    1696 JSValue* FunctionCallDotNode::evaluate(OldInterpreterExecState* exec)
    1697 {
    1698     return inlineEvaluate(exec);
    1699 }
    1700 
    1701 double FunctionCallDotNode::evaluateToNumber(OldInterpreterExecState* exec)
    1702 {
    1703     JSValue* v = inlineEvaluate(exec);
    1704     KJS_CHECKEXCEPTIONNUMBER
    1705     return v->toNumber(exec);
    1706 }
    1707 
    1708 bool FunctionCallDotNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1709 {
    1710     JSValue* v = inlineEvaluate(exec);
    1711     KJS_CHECKEXCEPTIONBOOLEAN
    1712     return v->toBoolean(exec);
    1713 }
    1714 
    1715 int32_t FunctionCallDotNode::evaluateToInt32(OldInterpreterExecState* exec)
    1716 {
    1717     JSValue* v = inlineEvaluate(exec);
    1718     KJS_CHECKEXCEPTIONNUMBER
    1719     return v->toInt32(exec);
    1720 }
    1721 
    1722 uint32_t FunctionCallDotNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1723 {
    1724     JSValue* v = inlineEvaluate(exec);
    1725     KJS_CHECKEXCEPTIONNUMBER
    1726     return v->toUInt32(exec);
    1727 }
    1728 
    1729 // ECMA 11.3
    1730488
    1731489// ------------------------------ PostfixResolveNode ----------------------------------
     
    1759517}
    1760518
    1761 // Increment
    1762 void PostIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    1763 {
    1764     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    1765     if (index != missingSymbolMarker()) {
    1766         if (isConstant(localStorage, index))
    1767             new (this) PostIncConstNode(index);
    1768         else
    1769             new (this) PostIncLocalVarNode(index);
    1770     }
    1771 }
    1772 
    1773 JSValue* PostIncResolveNode::evaluate(OldInterpreterExecState* exec)
    1774 {
    1775     // Check for missed optimization opportunity.
    1776     ASSERT(!canSkipLookup(exec, m_ident));
    1777 
    1778     const ScopeChain& chain = exec->scopeChain();
    1779     ScopeChainIterator iter = chain.begin();
    1780     ScopeChainIterator end = chain.end();
    1781 
    1782     // we must always have something in the scope chain
    1783     ASSERT(iter != end);
    1784 
    1785     PropertySlot slot;
    1786     do {
    1787         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
    1788             // If m_ident is 'arguments', the base->getPropertySlot() may cause
    1789             // base (which must be an ActivationImp in such this case) to be torn
    1790             // off from the activation stack, in which case we need to get it again
    1791             // from the ScopeChainIterator.
    1792            
    1793             JSObject* base = *iter;
    1794             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
    1795             base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
    1796             return v;
    1797         }
    1798 
    1799         ++iter;
    1800     } while (iter != end);
    1801 
    1802     return throwUndefinedVariableError(exec, m_ident);
    1803 }
    1804 
    1805 void PostIncResolveNode::optimizeForUnnecessaryResult()
    1806 {
    1807     new (this) PreIncResolveNode(PlacementNewAdopt);
    1808 }
    1809 
    1810 JSValue* PostIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
    1811 {
    1812     ASSERT(exec->variableObject() == exec->scopeChain().top());
    1813 
    1814     JSValue** slot = &exec->localStorage()[m_index].value;
    1815     JSValue* v = (*slot)->toJSNumber(exec);
    1816     *slot = jsNumber(v->toNumber(exec) + 1);
    1817     return v;
    1818 }
    1819 
    1820 void PostIncLocalVarNode::optimizeForUnnecessaryResult()
    1821 {
    1822     new (this) PreIncLocalVarNode(m_index);
    1823 }
    1824 
    1825 // Decrement
    1826519RegisterID* PostDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    1827520{
     
    1852545}
    1853546
    1854 void PostDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    1855 {
    1856     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    1857     if (index != missingSymbolMarker()) {
    1858         if (isConstant(localStorage, index))
    1859             new (this) PostDecConstNode(index);
    1860         else
    1861             new (this) PostDecLocalVarNode(index);
    1862     }
    1863 }
    1864 
    1865 JSValue* PostDecResolveNode::evaluate(OldInterpreterExecState* exec)
    1866 {
    1867     // Check for missed optimization opportunity.
    1868     ASSERT(!canSkipLookup(exec, m_ident));
    1869 
    1870     const ScopeChain& chain = exec->scopeChain();
    1871     ScopeChainIterator iter = chain.begin();
    1872     ScopeChainIterator end = chain.end();
    1873 
    1874     // we must always have something in the scope chain
    1875     ASSERT(iter != end);
    1876 
    1877     PropertySlot slot;
    1878     do {
    1879         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
    1880             // See the comment in PostIncResolveNode::evaluate().
    1881 
    1882             JSObject* base = *iter;
    1883             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
    1884             base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
    1885             return v;
    1886         }
    1887 
    1888         ++iter;
    1889     } while (iter != end);
    1890 
    1891     return throwUndefinedVariableError(exec, m_ident);
    1892 }
    1893 
    1894 void PostDecResolveNode::optimizeForUnnecessaryResult()
    1895 {
    1896     new (this) PreDecResolveNode(PlacementNewAdopt);
    1897 }
    1898 
    1899 JSValue* PostDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
    1900 {
    1901     ASSERT(exec->variableObject() == exec->scopeChain().top());
    1902 
    1903     JSValue** slot = &exec->localStorage()[m_index].value;
    1904     JSValue* v = (*slot)->toJSNumber(exec);
    1905     *slot = jsNumber(v->toNumber(exec) - 1);
    1906     return v;
    1907 }
    1908 
    1909 double PostDecLocalVarNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    1910 {
    1911     ASSERT(exec->variableObject() == exec->scopeChain().top());
    1912 
    1913     JSValue** slot = &exec->localStorage()[m_index].value;
    1914     double n = (*slot)->toNumber(exec);
    1915     *slot = jsNumber(n - 1);
    1916     return n;
    1917 }
    1918 
    1919 double PostDecLocalVarNode::evaluateToNumber(OldInterpreterExecState* exec)
    1920 {
    1921     return inlineEvaluateToNumber(exec);
    1922 }
    1923 
    1924 bool PostDecLocalVarNode::evaluateToBoolean(OldInterpreterExecState* exec)
    1925 {
    1926     double result = inlineEvaluateToNumber(exec);
    1927     return  result > 0.0 || 0.0 > result; // NaN produces false as well
    1928 }
    1929 
    1930 int32_t PostDecLocalVarNode::evaluateToInt32(OldInterpreterExecState* exec)
    1931 {
    1932     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    1933 }
    1934 
    1935 uint32_t PostDecLocalVarNode::evaluateToUInt32(OldInterpreterExecState* exec)
    1936 {
    1937     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    1938 }
    1939 
    1940 void PostDecLocalVarNode::optimizeForUnnecessaryResult()
    1941 {
    1942     new (this) PreDecLocalVarNode(m_index);
    1943 }
    1944 
    1945547// ------------------------------ PostfixBracketNode ----------------------------------
    1946 
    1947 void PostfixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    1948 {
    1949     nodeStack.append(m_subscript.get());
    1950     nodeStack.append(m_base.get());
    1951 }
    1952548
    1953549RegisterID* PostIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    1961557}
    1962558
    1963 JSValue* PostIncBracketNode::evaluate(OldInterpreterExecState* exec)
    1964 {
    1965     JSValue* baseValue = m_base->evaluate(exec);
    1966     KJS_CHECKEXCEPTIONVALUE
    1967     JSValue* subscript = m_subscript->evaluate(exec);
    1968     KJS_CHECKEXCEPTIONVALUE
    1969 
    1970     JSObject* base = baseValue->toObject(exec);
    1971 
    1972     uint32_t propertyIndex;
    1973     if (subscript->getUInt32(propertyIndex)) {
    1974         PropertySlot slot;
    1975         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
    1976         KJS_CHECKEXCEPTIONVALUE
    1977 
    1978         JSValue* v2 = v->toJSNumber(exec);
    1979         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1));
    1980 
    1981         return v2;
    1982     }
    1983 
    1984     Identifier propertyName(subscript->toString(exec));
    1985     PropertySlot slot;
    1986     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
    1987     KJS_CHECKEXCEPTIONVALUE
    1988 
    1989     JSValue* v2 = v->toJSNumber(exec);
    1990     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));
    1991     return v2;
    1992 }
    1993 
    1994559RegisterID* PostDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    1995560{
     
    2002567}
    2003568
    2004 JSValue* PostDecBracketNode::evaluate(OldInterpreterExecState* exec)
    2005 {
    2006     JSValue* baseValue = m_base->evaluate(exec);
    2007     KJS_CHECKEXCEPTIONVALUE
    2008     JSValue* subscript = m_subscript->evaluate(exec);
    2009     KJS_CHECKEXCEPTIONVALUE
    2010 
    2011     JSObject* base = baseValue->toObject(exec);
    2012 
    2013     uint32_t propertyIndex;
    2014     if (subscript->getUInt32(propertyIndex)) {
    2015         PropertySlot slot;
    2016         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
    2017         KJS_CHECKEXCEPTIONVALUE
    2018 
    2019         JSValue* v2 = v->toJSNumber(exec);
    2020         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1));
    2021         return v2;
    2022     }
    2023 
    2024     Identifier propertyName(subscript->toString(exec));
    2025     PropertySlot slot;
    2026     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
    2027     KJS_CHECKEXCEPTIONVALUE
    2028 
    2029     JSValue* v2 = v->toJSNumber(exec);
    2030     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));
    2031     return v2;
    2032 }
    2033 
    2034569// ------------------------------ PostfixDotNode ----------------------------------
    2035 
    2036 void PostfixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2037 {
    2038     nodeStack.append(m_base.get());
    2039 }
    2040570
    2041571RegisterID* PostIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    2048578}
    2049579
    2050 JSValue* PostIncDotNode::evaluate(OldInterpreterExecState* exec)
    2051 {
    2052     JSValue* baseValue = m_base->evaluate(exec);
    2053     KJS_CHECKEXCEPTIONVALUE
    2054     JSObject* base = baseValue->toObject(exec);
    2055 
    2056     PropertySlot slot;
    2057     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
    2058     KJS_CHECKEXCEPTIONVALUE
    2059 
    2060     JSValue* v2 = v->toJSNumber(exec);
    2061     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));
    2062     return v2;
    2063 }
    2064 
    2065580RegisterID* PostDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    2066581{
     
    2072587}
    2073588
    2074 JSValue* PostDecDotNode::evaluate(OldInterpreterExecState* exec)
    2075 {
    2076     JSValue* baseValue = m_base->evaluate(exec);
    2077     KJS_CHECKEXCEPTIONVALUE
    2078     JSObject* base = baseValue->toObject(exec);
    2079 
    2080     PropertySlot slot;
    2081     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
    2082     KJS_CHECKEXCEPTIONVALUE
    2083 
    2084     JSValue* v2 = v->toJSNumber(exec);
    2085     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));
    2086     return v2;
    2087 }
    2088 
    2089589// ------------------------------ PostfixErrorNode -----------------------------------
    2090590
     
    2092592{
    2093593    return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
    2094 }
    2095 
    2096 JSValue* PostfixErrorNode::evaluate(OldInterpreterExecState* exec)
    2097 {
    2098     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
    2099                m_operator == OpPlusPlus ? "++" : "--");
    2100     handleException(exec);
    2101     return jsUndefined();
    2102594}
    2103595
     
    2111603    RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
    2112604    return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
    2113 }
    2114 
    2115 void DeleteResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
    2116 {
    2117     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    2118     if (index != missingSymbolMarker())
    2119         new (this) LocalVarDeleteNode();
    2120 }
    2121 
    2122 // ECMA 11.4.1
    2123 
    2124 JSValue* DeleteResolveNode::evaluate(OldInterpreterExecState* exec)
    2125 {
    2126     // Check for missed optimization opportunity.
    2127     ASSERT(!canSkipLookup(exec, m_ident));
    2128 
    2129     const ScopeChain& chain = exec->scopeChain();
    2130     ScopeChainIterator iter = chain.begin();
    2131     ScopeChainIterator end = chain.end();
    2132 
    2133     // We must always have something in the scope chain
    2134     ASSERT(iter != end);
    2135 
    2136     PropertySlot slot;
    2137     JSObject* base;
    2138     do {
    2139         base = *iter;
    2140         if (base->getPropertySlot(exec, m_ident, slot))
    2141             return jsBoolean(base->deleteProperty(exec, m_ident));
    2142 
    2143         ++iter;
    2144     } while (iter != end);
    2145 
    2146     return jsBoolean(true);
    2147 }
    2148 
    2149 JSValue* LocalVarDeleteNode::evaluate(OldInterpreterExecState*)
    2150 {
    2151     return jsBoolean(false);
    2152605}
    2153606
     
    2161614}
    2162615
    2163 void DeleteBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2164 {
    2165     nodeStack.append(m_subscript.get());
    2166     nodeStack.append(m_base.get());
    2167 }
    2168 
    2169 JSValue* DeleteBracketNode::evaluate(OldInterpreterExecState* exec)
    2170 {
    2171     JSValue* baseValue = m_base->evaluate(exec);
    2172     KJS_CHECKEXCEPTIONVALUE
    2173     JSValue* subscript = m_subscript->evaluate(exec);
    2174     KJS_CHECKEXCEPTIONVALUE
    2175 
    2176     JSObject* base = baseValue->toObject(exec);
    2177 
    2178     uint32_t propertyIndex;
    2179     if (subscript->getUInt32(propertyIndex))
    2180         return jsBoolean(base->deleteProperty(exec, propertyIndex));
    2181 
    2182     Identifier propertyName(subscript->toString(exec));
    2183     return jsBoolean(base->deleteProperty(exec, propertyName));
    2184 }
    2185 
    2186616// ------------------------------ DeleteDotNode -----------------------------------
    2187617
     
    2192622}
    2193623
    2194 void DeleteDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2195 {
    2196     nodeStack.append(m_base.get());
    2197 }
    2198 
    2199 JSValue* DeleteDotNode::evaluate(OldInterpreterExecState* exec)
    2200 {
    2201     JSValue* baseValue = m_base->evaluate(exec);
    2202     JSObject* base = baseValue->toObject(exec);
    2203     KJS_CHECKEXCEPTIONVALUE
    2204 
    2205     return jsBoolean(base->deleteProperty(exec, m_ident));
    2206 }
    2207 
    2208624// ------------------------------ DeleteValueNode -----------------------------------
    2209625
     
    2216632}
    2217633
    2218 void DeleteValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2219 {
    2220     nodeStack.append(m_expr.get());
    2221 }
    2222 
    2223 JSValue* DeleteValueNode::evaluate(OldInterpreterExecState* exec)
    2224 {
    2225     m_expr->evaluate(exec);
    2226     KJS_CHECKEXCEPTIONVALUE
    2227 
    2228     // delete on a non-location expression ignores the value and returns true
    2229     return jsBoolean(true);
    2230 }
    2231 
    2232634// ------------------------------ VoidNode -------------------------------------
    2233635
     
    2238640}
    2239641
    2240 void VoidNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2241 {
    2242     nodeStack.append(m_expr.get());
    2243 }
    2244 
    2245 // ECMA 11.4.2
    2246 JSValue* VoidNode::evaluate(OldInterpreterExecState* exec)
    2247 {
    2248     m_expr->evaluate(exec);
    2249     KJS_CHECKEXCEPTIONVALUE
    2250 
    2251     return jsUndefined();
    2252 }
    2253 
    2254 // ECMA 11.4.3
    2255 
    2256642// ------------------------------ TypeOfValueNode -----------------------------------
    2257 
    2258 void TypeOfValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2259 {
    2260     nodeStack.append(m_expr.get());
    2261 }
    2262 
    2263 static JSValue* typeStringForValue(JSValue* v) KJS_FAST_CALL;
    2264 static JSValue* typeStringForValue(JSValue* v)
    2265 {
    2266     switch (v->type()) {
    2267         case UndefinedType:
    2268             return jsString("undefined");
    2269         case NullType:
    2270             return jsString("object");
    2271         case BooleanType:
    2272             return jsString("boolean");
    2273         case NumberType:
    2274             return jsString("number");
    2275         case StringType:
    2276             return jsString("string");
    2277         default:
    2278             if (v->isObject()) {
    2279                 // Return "undefined" for objects that should be treated
    2280                 // as null when doing comparisons.
    2281                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
    2282                     return jsString("undefined");
    2283                 else if (static_cast<JSObject*>(v)->implementsCall())
    2284                     return jsString("function");
    2285             }
    2286 
    2287             return jsString("object");
    2288     }
    2289 }
    2290 
    2291 void TypeOfResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
    2292 {
    2293     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    2294     if (index != missingSymbolMarker())
    2295         new (this) LocalVarTypeOfNode(index);
    2296 }
    2297 
    2298 JSValue* LocalVarTypeOfNode::evaluate(OldInterpreterExecState* exec)
    2299 {
    2300     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2301 
    2302     return typeStringForValue(exec->localStorage()[m_index].value);
    2303 }
    2304643
    2305644RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    2313652}
    2314653
    2315 JSValue* TypeOfResolveNode::evaluate(OldInterpreterExecState* exec)
    2316 {
    2317     const ScopeChain& chain = exec->scopeChain();
    2318     ScopeChainIterator iter = chain.begin();
    2319     ScopeChainIterator end = chain.end();
    2320 
    2321     // We must always have something in the scope chain
    2322     ASSERT(iter != end);
    2323 
    2324     PropertySlot slot;
    2325     JSObject* base;
    2326     do {
    2327         base = *iter;
    2328         if (base->getPropertySlot(exec, m_ident, slot)) {
    2329             JSValue* v = slot.getValue(exec, base, m_ident);
    2330             return typeStringForValue(v);
    2331         }
    2332 
    2333         ++iter;
    2334     } while (iter != end);
    2335 
    2336     return jsString("undefined");
    2337 }
    2338 
    2339654// ------------------------------ TypeOfValueNode -----------------------------------
    2340655
     
    2344659    return generator.emitTypeOf(generator.finalDestination(dst), src.get());
    2345660}
    2346 
    2347 JSValue* TypeOfValueNode::evaluate(OldInterpreterExecState* exec)
    2348 {
    2349     JSValue* v = m_expr->evaluate(exec);
    2350     KJS_CHECKEXCEPTIONVALUE
    2351 
    2352     return typeStringForValue(v);
    2353 }
    2354 
    2355 // ECMA 11.4.4 and 11.4.5
    2356661
    2357662// ------------------------------ PrefixResolveNode ----------------------------------
     
    2385690}
    2386691
    2387 void PreIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    2388 {
    2389     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    2390     if (index != missingSymbolMarker()) {
    2391         if (isConstant(localStorage, index))
    2392             new (this) PreIncConstNode(index);
    2393         else
    2394             new (this) PreIncLocalVarNode(index);
    2395     }
    2396 }
    2397 
    2398 JSValue* PreIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
    2399 {
    2400     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2401     JSValue** slot = &exec->localStorage()[m_index].value;
    2402 
    2403     double n = (*slot)->toNumber(exec);
    2404     JSValue* n2 = jsNumber(n + 1);
    2405     *slot = n2;
    2406     return n2;
    2407 }
    2408 
    2409 JSValue* PreIncResolveNode::evaluate(OldInterpreterExecState* exec)
    2410 {
    2411     const ScopeChain& chain = exec->scopeChain();
    2412     ScopeChainIterator iter = chain.begin();
    2413     ScopeChainIterator end = chain.end();
    2414 
    2415     // we must always have something in the scope chain
    2416     ASSERT(iter != end);
    2417 
    2418     PropertySlot slot;
    2419     do {
    2420         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
    2421             // See the comment in PostIncResolveNode::evaluate().
    2422 
    2423             JSObject* base = *iter;
    2424             JSValue* v = slot.getValue(exec, base, m_ident);
    2425 
    2426             double n = v->toNumber(exec);
    2427             JSValue* n2 = jsNumber(n + 1);
    2428             base->put(exec, m_ident, n2);
    2429 
    2430             return n2;
    2431         }
    2432 
    2433         ++iter;
    2434     } while (iter != end);
    2435 
    2436     return throwUndefinedVariableError(exec, m_ident);
    2437 }
    2438 
    2439692RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    2440693{
     
    2465718}
    2466719
    2467 void PreDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
    2468 {
    2469     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    2470     if (index != missingSymbolMarker()) {
    2471         if (isConstant(localStorage, index))
    2472             new (this) PreDecConstNode(index);
    2473         else
    2474             new (this) PreDecLocalVarNode(index);
    2475     }
    2476 }
    2477 
    2478 JSValue* PreDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
    2479 {
    2480     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2481     JSValue** slot = &exec->localStorage()[m_index].value;
    2482 
    2483     double n = (*slot)->toNumber(exec);
    2484     JSValue* n2 = jsNumber(n - 1);
    2485     *slot = n2;
    2486     return n2;
    2487 }
    2488 
    2489 JSValue* PreDecResolveNode::evaluate(OldInterpreterExecState* exec)
    2490 {
    2491     const ScopeChain& chain = exec->scopeChain();
    2492     ScopeChainIterator iter = chain.begin();
    2493     ScopeChainIterator end = chain.end();
    2494 
    2495     // we must always have something in the scope chain
    2496     ASSERT(iter != end);
    2497 
    2498     PropertySlot slot;
    2499     do {
    2500         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
    2501             // See the comment in PostIncResolveNode::evaluate().
    2502 
    2503             JSObject* base = *iter;
    2504             JSValue* v = slot.getValue(exec, base, m_ident);
    2505 
    2506             double n = v->toNumber(exec);
    2507             JSValue* n2 = jsNumber(n - 1);
    2508             base->put(exec, m_ident, n2);
    2509 
    2510             return n2;
    2511         }
    2512 
    2513         ++iter;
    2514     } while (iter != end);
    2515 
    2516     return throwUndefinedVariableError(exec, m_ident);
    2517 }
    2518 
    2519 // ------------------------------ PreIncConstNode ----------------------------------
    2520 
    2521 JSValue* PreIncConstNode::evaluate(OldInterpreterExecState* exec)
    2522 {
    2523     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2524     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) + 1);
    2525 }
    2526 
    2527 // ------------------------------ PreDecConstNode ----------------------------------
    2528 
    2529 JSValue* PreDecConstNode::evaluate(OldInterpreterExecState* exec)
    2530 {
    2531     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2532     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) - 1);
    2533 }
    2534 
    2535 // ------------------------------ PostIncConstNode ----------------------------------
    2536 
    2537 JSValue* PostIncConstNode::evaluate(OldInterpreterExecState* exec)
    2538 {
    2539     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2540     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
    2541 }
    2542 
    2543 // ------------------------------ PostDecConstNode ----------------------------------
    2544 
    2545 JSValue* PostDecConstNode::evaluate(OldInterpreterExecState* exec)
    2546 {
    2547     ASSERT(exec->variableObject() == exec->scopeChain().top());
    2548     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
    2549 }
    2550 
    2551720// ------------------------------ PrefixBracketNode ----------------------------------
    2552 
    2553 void PrefixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2554 {
    2555     nodeStack.append(m_subscript.get());
    2556     nodeStack.append(m_base.get());
    2557 }
    2558721
    2559722RegisterID* PreIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    2568731}
    2569732
    2570 JSValue* PreIncBracketNode::evaluate(OldInterpreterExecState* exec)
    2571 {
    2572     JSValue* baseValue = m_base->evaluate(exec);
    2573     KJS_CHECKEXCEPTIONVALUE
    2574     JSValue* subscript = m_subscript->evaluate(exec);
    2575     KJS_CHECKEXCEPTIONVALUE
    2576 
    2577     JSObject* base = baseValue->toObject(exec);
    2578 
    2579     uint32_t propertyIndex;
    2580     if (subscript->getUInt32(propertyIndex)) {
    2581         PropertySlot slot;
    2582         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
    2583         KJS_CHECKEXCEPTIONVALUE
    2584 
    2585         JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
    2586         base->put(exec, propertyIndex, n2);
    2587 
    2588         return n2;
    2589     }
    2590 
    2591     Identifier propertyName(subscript->toString(exec));
    2592     PropertySlot slot;
    2593     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
    2594     KJS_CHECKEXCEPTIONVALUE
    2595 
    2596     JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
    2597     base->put(exec, propertyName, n2);
    2598 
    2599     return n2;
    2600 }
    2601 
    2602733RegisterID* PreDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    2603734{
     
    2612743}
    2613744
    2614 JSValue* PreDecBracketNode::evaluate(OldInterpreterExecState* exec)
    2615 {
    2616     JSValue* baseValue = m_base->evaluate(exec);
    2617     KJS_CHECKEXCEPTIONVALUE
    2618     JSValue* subscript = m_subscript->evaluate(exec);
    2619     KJS_CHECKEXCEPTIONVALUE
    2620 
    2621     JSObject* base = baseValue->toObject(exec);
    2622 
    2623     uint32_t propertyIndex;
    2624     if (subscript->getUInt32(propertyIndex)) {
    2625         PropertySlot slot;
    2626         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
    2627         KJS_CHECKEXCEPTIONVALUE
    2628 
    2629         JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
    2630         base->put(exec, propertyIndex, n2);
    2631 
    2632         return n2;
    2633     }
    2634 
    2635     Identifier propertyName(subscript->toString(exec));
    2636     PropertySlot slot;
    2637     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
    2638     KJS_CHECKEXCEPTIONVALUE
    2639 
    2640     JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
    2641     base->put(exec, propertyName, n2);
    2642 
    2643     return n2;
    2644 }
    2645 
    2646745// ------------------------------ PrefixDotNode ----------------------------------
    2647 
    2648 void PrefixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2649 {
    2650     nodeStack.append(m_base.get());
    2651 }
    2652746
    2653747RegisterID* PreIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    2661755}
    2662756
    2663 JSValue* PreIncDotNode::evaluate(OldInterpreterExecState* exec)
    2664 {
    2665     JSValue* baseValue = m_base->evaluate(exec);
    2666     KJS_CHECKEXCEPTIONVALUE
    2667     JSObject* base = baseValue->toObject(exec);
    2668 
    2669     PropertySlot slot;
    2670     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
    2671     KJS_CHECKEXCEPTIONVALUE
    2672 
    2673     double n = v->toNumber(exec);
    2674     JSValue* n2 = jsNumber(n + 1);
    2675     base->put(exec, m_ident, n2);
    2676 
    2677     return n2;
    2678 }
    2679 
    2680757RegisterID* PreDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    2681758{
     
    2688765}
    2689766
    2690 JSValue* PreDecDotNode::evaluate(OldInterpreterExecState* exec)
    2691 {
    2692     JSValue* baseValue = m_base->evaluate(exec);
    2693     KJS_CHECKEXCEPTIONVALUE
    2694     JSObject* base = baseValue->toObject(exec);
    2695 
    2696     PropertySlot slot;
    2697     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
    2698     KJS_CHECKEXCEPTIONVALUE
    2699 
    2700     double n = v->toNumber(exec);
    2701     JSValue* n2 = jsNumber(n - 1);
    2702     base->put(exec, m_ident, n2);
    2703 
    2704     return n2;
    2705 }
    2706 
    2707767// ------------------------------ PrefixErrorNode -----------------------------------
    2708768
     
    2710770{
    2711771    return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
    2712 }
    2713 
    2714 JSValue* PrefixErrorNode::evaluate(OldInterpreterExecState* exec)
    2715 {
    2716     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
    2717                m_operator == OpPlusPlus ? "++" : "--");
    2718     handleException(exec);
    2719     return jsUndefined();
    2720772}
    2721773
     
    2728780}
    2729781
    2730 void UnaryPlusNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2731 {
    2732     nodeStack.append(m_expr.get());
    2733 }
    2734 
    2735 // ECMA 11.4.6
    2736 JSValue* UnaryPlusNode::evaluate(OldInterpreterExecState* exec)
    2737 {
    2738     JSValue* v = m_expr->evaluate(exec);
    2739     KJS_CHECKEXCEPTIONVALUE
    2740     return v->toJSNumber(exec);
    2741 }
    2742 
    2743 bool UnaryPlusNode::evaluateToBoolean(OldInterpreterExecState* exec)
    2744 {
    2745     return m_expr->evaluateToBoolean(exec);
    2746 }
    2747 
    2748 double UnaryPlusNode::evaluateToNumber(OldInterpreterExecState* exec)
    2749 {
    2750     return m_expr->evaluateToNumber(exec);
    2751 }
    2752 
    2753 int32_t UnaryPlusNode::evaluateToInt32(OldInterpreterExecState* exec)
    2754 {
    2755     return m_expr->evaluateToInt32(exec);
    2756 }
    2757 
    2758 uint32_t UnaryPlusNode::evaluateToUInt32(OldInterpreterExecState* exec)
    2759 {
    2760     return m_expr->evaluateToInt32(exec);
    2761 }
    2762 
    2763782// ------------------------------ NegateNode -----------------------------------
    2764783
     
    2769788}
    2770789
    2771 void NegateNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2772 {
    2773     nodeStack.append(m_expr.get());
    2774 }
    2775 
    2776 // ECMA 11.4.7
    2777 JSValue* NegateNode::evaluate(OldInterpreterExecState* exec)
    2778 {
    2779     // No need to check exception, caller will do so right after evaluate()
    2780     return jsNumber(-m_expr->evaluateToNumber(exec));
    2781 }
    2782 
    2783 double NegateNode::evaluateToNumber(OldInterpreterExecState* exec)
    2784 {
    2785     // No need to check exception, caller will do so right after evaluateToNumber()
    2786     return -m_expr->evaluateToNumber(exec);
    2787 }
    2788 
    2789790// ------------------------------ BitwiseNotNode -------------------------------
    2790791
     
    2795796}
    2796797
    2797 void BitwiseNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2798 {
    2799     nodeStack.append(m_expr.get());
    2800 }
    2801 
    2802 // ECMA 11.4.8
    2803 int32_t BitwiseNotNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
    2804 {
    2805     return ~m_expr->evaluateToInt32(exec);
    2806 }
    2807 
    2808 JSValue* BitwiseNotNode::evaluate(OldInterpreterExecState* exec)
    2809 {
    2810     return jsNumber(inlineEvaluateToInt32(exec));
    2811 }
    2812 
    2813 double BitwiseNotNode::evaluateToNumber(OldInterpreterExecState* exec)
    2814 {
    2815     return inlineEvaluateToInt32(exec);
    2816 }
    2817 
    2818 bool BitwiseNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
    2819 {
    2820     return inlineEvaluateToInt32(exec);
    2821 }
    2822 
    2823 int32_t BitwiseNotNode::evaluateToInt32(OldInterpreterExecState* exec)
    2824 {
    2825     return inlineEvaluateToInt32(exec);
    2826 }
    2827 
    2828 uint32_t BitwiseNotNode::evaluateToUInt32(OldInterpreterExecState* exec)
    2829 {
    2830     return inlineEvaluateToInt32(exec);
    2831 }
    2832 
    2833798// ------------------------------ LogicalNotNode -------------------------------
    2834799
     
    2837802    RegisterID* src = generator.emitNode(m_expr.get());
    2838803    return generator.emitNot(generator.finalDestination(dst), src);
    2839 }
    2840 
    2841 void LogicalNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2842 {
    2843     nodeStack.append(m_expr.get());
    2844 }
    2845 
    2846 // ECMA 11.4.9
    2847 JSValue* LogicalNotNode::evaluate(OldInterpreterExecState* exec)
    2848 {
    2849     return jsBoolean(!m_expr->evaluateToBoolean(exec));
    2850 }
    2851 
    2852 bool LogicalNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
    2853 {
    2854     return !m_expr->evaluateToBoolean(exec);
    2855804}
    2856805
     
    2864813}
    2865814
    2866 void MultNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2867 {
    2868     nodeStack.append(m_term1.get());
    2869     nodeStack.append(m_term2.get());
    2870 }
    2871 
    2872 // ECMA 11.5.1
    2873 double MultNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    2874 {
    2875     double n1 = m_term1->evaluateToNumber(exec);
    2876     KJS_CHECKEXCEPTIONNUMBER
    2877     double n2 = m_term2->evaluateToNumber(exec);
    2878     return n1 * n2;
    2879 }
    2880 
    2881 JSValue* MultNode::evaluate(OldInterpreterExecState* exec)
    2882 {
    2883     return jsNumber(inlineEvaluateToNumber(exec));
    2884 }
    2885 
    2886 double MultNode::evaluateToNumber(OldInterpreterExecState* exec)
    2887 {
    2888     return inlineEvaluateToNumber(exec);
    2889 }
    2890 
    2891 bool MultNode::evaluateToBoolean(OldInterpreterExecState* exec)
    2892 {
    2893     double result = inlineEvaluateToNumber(exec);
    2894     return  result > 0.0 || 0.0 > result; // NaN produces false as well
    2895 }
    2896 
    2897 int32_t MultNode::evaluateToInt32(OldInterpreterExecState* exec)
    2898 {
    2899     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    2900 }
    2901 
    2902 uint32_t MultNode::evaluateToUInt32(OldInterpreterExecState* exec)
    2903 {
    2904     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    2905 }
    2906 
    2907815RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    2908816{
     
    2912820}
    2913821
    2914 void DivNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2915 {
    2916     nodeStack.append(m_term1.get());
    2917     nodeStack.append(m_term2.get());
    2918 }
    2919 
    2920 // ECMA 11.5.2
    2921 double DivNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    2922 {
    2923     double n1 = m_term1->evaluateToNumber(exec);
    2924     KJS_CHECKEXCEPTIONNUMBER
    2925     double n2 = m_term2->evaluateToNumber(exec);
    2926     return n1 / n2;
    2927 }
    2928 
    2929 JSValue* DivNode::evaluate(OldInterpreterExecState* exec)
    2930 {
    2931     return jsNumber(inlineEvaluateToNumber(exec));
    2932 }
    2933 
    2934 double DivNode::evaluateToNumber(OldInterpreterExecState* exec)
    2935 {
    2936     return inlineEvaluateToNumber(exec);
    2937 }
    2938 
    2939 int32_t DivNode::evaluateToInt32(OldInterpreterExecState* exec)
    2940 {
    2941     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    2942 }
    2943 
    2944 uint32_t DivNode::evaluateToUInt32(OldInterpreterExecState* exec)
    2945 {
    2946     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    2947 }
    2948 
    2949822RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    2950823{
     
    2954827}
    2955828
    2956 void ModNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    2957 {
    2958     nodeStack.append(m_term1.get());
    2959     nodeStack.append(m_term2.get());
    2960 }
    2961 
    2962 // ECMA 11.5.3
    2963 double ModNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    2964 {
    2965     double n1 = m_term1->evaluateToNumber(exec);
    2966     KJS_CHECKEXCEPTIONNUMBER
    2967     double n2 = m_term2->evaluateToNumber(exec);
    2968     return fmod(n1, n2);
    2969 }
    2970 
    2971 JSValue* ModNode::evaluate(OldInterpreterExecState* exec)
    2972 {
    2973     return jsNumber(inlineEvaluateToNumber(exec));
    2974 }
    2975 
    2976 double ModNode::evaluateToNumber(OldInterpreterExecState* exec)
    2977 {
    2978     return inlineEvaluateToNumber(exec);
    2979 }
    2980 
    2981 bool ModNode::evaluateToBoolean(OldInterpreterExecState* exec)
    2982 {
    2983     double result = inlineEvaluateToNumber(exec);
    2984     return  result > 0.0 || 0.0 > result; // NaN produces false as well
    2985 }
    2986 
    2987 int32_t ModNode::evaluateToInt32(OldInterpreterExecState* exec)
    2988 {
    2989     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    2990 }
    2991 
    2992 uint32_t ModNode::evaluateToUInt32(OldInterpreterExecState* exec)
    2993 {
    2994     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    2995 }
    2996 
    2997829// ------------------------------ Additive Nodes --------------------------------------
    2998 
    2999 static double throwOutOfMemoryErrorToNumber(OldInterpreterExecState* exec)
    3000 {
    3001     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
    3002     exec->setException(error);
    3003     return 0.0;
    3004 }
    3005 
    3006 // ECMA 11.6
    3007 static JSValue* addSlowCase(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
    3008 {
    3009     // exception for the Date exception in defaultValue()
    3010     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
    3011     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
    3012 
    3013     if (p1->isString() || p2->isString()) {
    3014         UString value = p1->toString(exec) + p2->toString(exec);
    3015         if (value.isNull())
    3016             return throwOutOfMemoryError(exec);
    3017         return jsString(value);
    3018     }
    3019 
    3020     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
    3021 }
    3022 
    3023 static double addSlowCaseToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
    3024 {
    3025     // exception for the Date exception in defaultValue()
    3026     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
    3027     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
    3028 
    3029     if (p1->isString() || p2->isString()) {
    3030         UString value = p1->toString(exec) + p2->toString(exec);
    3031         if (value.isNull())
    3032             return throwOutOfMemoryErrorToNumber(exec);
    3033         return value.toDouble();
    3034     }
    3035 
    3036     return p1->toNumber(exec) + p2->toNumber(exec);
    3037 }
    3038 
    3039 // Fast-path choices here are based on frequency data from SunSpider:
    3040 //    <times> Add case: <t1> <t2>
    3041 //    ---------------------------
    3042 //    5627160 Add case: 1 1
    3043 //    247427  Add case: 5 5
    3044 //    20901   Add case: 5 6
    3045 //    13978   Add case: 5 1
    3046 //    4000    Add case: 1 5
    3047 //    1       Add case: 3 5
    3048 
    3049 static inline JSValue* add(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
    3050 {
    3051     JSType t1 = v1->type();
    3052     JSType t2 = v2->type();
    3053     const unsigned bothTypes = (t1 << 3) | t2;
    3054 
    3055     if (bothTypes == ((NumberType << 3) | NumberType))
    3056         return jsNumber(v1->toNumber(exec) + v2->toNumber(exec));
    3057     if (bothTypes == ((StringType << 3) | StringType)) {
    3058         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
    3059         if (value.isNull())
    3060             return throwOutOfMemoryError(exec);
    3061         return jsString(value);
    3062     }
    3063 
    3064     // All other cases are pretty uncommon
    3065     return addSlowCase(exec, v1, v2);
    3066 }
    3067 
    3068 static inline double addToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
    3069 {
    3070     JSType t1 = v1->type();
    3071     JSType t2 = v2->type();
    3072     const unsigned bothTypes = (t1 << 3) | t2;
    3073 
    3074     if (bothTypes == ((NumberType << 3) | NumberType))
    3075         return v1->toNumber(exec) + v2->toNumber(exec);
    3076     if (bothTypes == ((StringType << 3) | StringType)) {
    3077         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
    3078         if (value.isNull())
    3079             return throwOutOfMemoryErrorToNumber(exec);
    3080         return value.toDouble();
    3081     }
    3082 
    3083     // All other cases are pretty uncommon
    3084     return addSlowCaseToNumber(exec, v1, v2);
    3085 }
    3086830
    3087831RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    3092836}
    3093837
    3094 void AddNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3095 {
    3096     nodeStack.append(m_term1.get());
    3097     nodeStack.append(m_term2.get());
    3098 }
    3099 
    3100 // ECMA 11.6.1
    3101 JSValue* AddNode::evaluate(OldInterpreterExecState* exec)
    3102 {
    3103     JSValue* v1 = m_term1->evaluate(exec);
    3104     KJS_CHECKEXCEPTIONVALUE
    3105 
    3106     JSValue* v2 = m_term2->evaluate(exec);
    3107     KJS_CHECKEXCEPTIONVALUE
    3108 
    3109     return add(exec, v1, v2);
    3110 }
    3111 
    3112 double AddNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    3113 {
    3114     JSValue* v1 = m_term1->evaluate(exec);
    3115     KJS_CHECKEXCEPTIONNUMBER
    3116 
    3117     JSValue* v2 = m_term2->evaluate(exec);
    3118     KJS_CHECKEXCEPTIONNUMBER
    3119 
    3120     return addToNumber(exec, v1, v2);
    3121 }
    3122 
    3123 double AddNode::evaluateToNumber(OldInterpreterExecState* exec)
    3124 {
    3125     return inlineEvaluateToNumber(exec);
    3126 }
    3127 
    3128 int32_t AddNode::evaluateToInt32(OldInterpreterExecState* exec)
    3129 {
    3130     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    3131 }
    3132 
    3133 uint32_t AddNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3134 {
    3135     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    3136 }
    3137 
    3138 double AddNumbersNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    3139 {
    3140     double n1 = m_term1->evaluateToNumber(exec);
    3141     KJS_CHECKEXCEPTIONNUMBER
    3142     double n2 = m_term2->evaluateToNumber(exec);
    3143     return n1 + n2;
    3144 }
    3145 
    3146 JSValue* AddNumbersNode::evaluate(OldInterpreterExecState* exec)
    3147 {
    3148     return jsNumber(inlineEvaluateToNumber(exec));
    3149 }
    3150 
    3151 double AddNumbersNode::evaluateToNumber(OldInterpreterExecState* exec)
    3152 {
    3153     return inlineEvaluateToNumber(exec);
    3154 }
    3155 
    3156 int32_t AddNumbersNode::evaluateToInt32(OldInterpreterExecState* exec)
    3157 {
    3158     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    3159 }
    3160 
    3161 uint32_t AddNumbersNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3162 {
    3163     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    3164 }
    3165 
    3166 JSValue* AddStringsNode::evaluate(OldInterpreterExecState* exec)
    3167 {
    3168     JSValue* v1 = m_term1->evaluate(exec);
    3169     KJS_CHECKEXCEPTIONVALUE
    3170 
    3171     JSValue* v2 = m_term2->evaluate(exec);
    3172     KJS_CHECKEXCEPTIONVALUE
    3173 
    3174     return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
    3175 }
    3176 
    3177 JSValue* AddStringLeftNode::evaluate(OldInterpreterExecState* exec)
    3178 {
    3179     JSValue* v1 = m_term1->evaluate(exec);
    3180     KJS_CHECKEXCEPTIONVALUE
    3181 
    3182     JSValue* v2 = m_term2->evaluate(exec);
    3183     KJS_CHECKEXCEPTIONVALUE
    3184 
    3185     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
    3186     return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
    3187 }
    3188 
    3189 JSValue* AddStringRightNode::evaluate(OldInterpreterExecState* exec)
    3190 {
    3191     JSValue* v1 = m_term1->evaluate(exec);
    3192     KJS_CHECKEXCEPTIONVALUE
    3193 
    3194     JSValue* v2 = m_term2->evaluate(exec);
    3195     KJS_CHECKEXCEPTIONVALUE
    3196 
    3197     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
    3198     return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
    3199 }
    3200 
    3201838RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3202839{
     
    3206843}
    3207844
    3208 void SubNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3209 {
    3210     nodeStack.append(m_term1.get());
    3211     nodeStack.append(m_term2.get());
    3212 }
    3213 
    3214 // ECMA 11.6.2
    3215 double SubNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
    3216 {
    3217     double n1 = m_term1->evaluateToNumber(exec);
    3218     KJS_CHECKEXCEPTIONNUMBER
    3219     double n2 = m_term2->evaluateToNumber(exec);
    3220     return n1 - n2;
    3221 }
    3222 
    3223 JSValue* SubNode::evaluate(OldInterpreterExecState* exec)
    3224 {
    3225     return jsNumber(inlineEvaluateToNumber(exec));
    3226 }
    3227 
    3228 double SubNode::evaluateToNumber(OldInterpreterExecState* exec)
    3229 {
    3230     return inlineEvaluateToNumber(exec);
    3231 }
    3232 
    3233 int32_t SubNode::evaluateToInt32(OldInterpreterExecState* exec)
    3234 {
    3235     return JSValue::toInt32(inlineEvaluateToNumber(exec));
    3236 }
    3237 
    3238 uint32_t SubNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3239 {
    3240     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
    3241 }
    3242 
    3243845// ------------------------------ Shift Nodes ------------------------------------
    3244846
     
    3250852}
    3251853
    3252 void LeftShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3253 {
    3254     nodeStack.append(m_term1.get());
    3255     nodeStack.append(m_term2.get());
    3256 }
    3257 
    3258 // ECMA 11.7.1
    3259 int32_t LeftShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
    3260 {
    3261     int i1 = m_term1->evaluateToInt32(exec);
    3262     KJS_CHECKEXCEPTIONNUMBER
    3263     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
    3264     return (i1 << i2);
    3265 }
    3266 
    3267 JSValue* LeftShiftNode::evaluate(OldInterpreterExecState* exec)
    3268 {
    3269     return jsNumber(inlineEvaluateToInt32(exec));
    3270 }
    3271 
    3272 double LeftShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
    3273 {
    3274     return inlineEvaluateToInt32(exec);
    3275 }
    3276 
    3277 int32_t LeftShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
    3278 {
    3279     return inlineEvaluateToInt32(exec);
    3280 }
    3281 
    3282 uint32_t LeftShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3283 {
    3284     return inlineEvaluateToInt32(exec);
    3285 }
    3286 
    3287854RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3288855{
     
    3292859}
    3293860
    3294 void RightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3295 {
    3296     nodeStack.append(m_term1.get());
    3297     nodeStack.append(m_term2.get());
    3298 }
    3299 
    3300 // ECMA 11.7.2
    3301 int32_t RightShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
    3302 {
    3303     int i1 = m_term1->evaluateToInt32(exec);
    3304     KJS_CHECKEXCEPTIONNUMBER
    3305     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
    3306     return (i1 >> i2);
    3307 }
    3308 
    3309 JSValue* RightShiftNode::evaluate(OldInterpreterExecState* exec)
    3310 {
    3311     return jsNumber(inlineEvaluateToInt32(exec));
    3312 }
    3313 
    3314 double RightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
    3315 {
    3316     return inlineEvaluateToInt32(exec);
    3317 }
    3318 
    3319 int32_t RightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
    3320 {
    3321     return inlineEvaluateToInt32(exec);
    3322 }
    3323 
    3324 uint32_t RightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3325 {
    3326     return inlineEvaluateToInt32(exec);
    3327 }
    3328 
    3329861RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3330862{
     
    3334866}
    3335867
    3336 void UnsignedRightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3337 {
    3338     nodeStack.append(m_term1.get());
    3339     nodeStack.append(m_term2.get());
    3340 }
    3341 
    3342 // ECMA 11.7.3
    3343 uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(OldInterpreterExecState* exec)
    3344 {
    3345     unsigned int i1 = m_term1->evaluateToUInt32(exec);
    3346     KJS_CHECKEXCEPTIONNUMBER
    3347     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
    3348     return (i1 >> i2);
    3349 }
    3350 
    3351 JSValue* UnsignedRightShiftNode::evaluate(OldInterpreterExecState* exec)
    3352 {
    3353     return jsNumber(inlineEvaluateToUInt32(exec));
    3354 }
    3355 
    3356 double UnsignedRightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
    3357 {
    3358     return inlineEvaluateToUInt32(exec);
    3359 }
    3360 
    3361 int32_t UnsignedRightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
    3362 {
    3363     return inlineEvaluateToUInt32(exec);
    3364 }
    3365 
    3366 uint32_t UnsignedRightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3367 {
    3368     return inlineEvaluateToUInt32(exec);
    3369 }
    3370 
    3371868// ------------------------------ Relational Nodes -------------------------------
    3372 
    3373 static inline bool lessThan(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
    3374 {
    3375     double n1;
    3376     double n2;
    3377     JSValue* p1;
    3378     JSValue* p2;
    3379     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
    3380     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
    3381 
    3382     if (wasNotString1 | wasNotString2)
    3383         return n1 < n2;
    3384 
    3385     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
    3386 }
    3387 
    3388 static inline bool lessThanEq(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
    3389 {
    3390     double n1;
    3391     double n2;
    3392     JSValue* p1;
    3393     JSValue* p2;
    3394     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
    3395     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
    3396 
    3397     if (wasNotString1 | wasNotString2)
    3398         return n1 <= n2;
    3399 
    3400     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
    3401 }
    3402869
    3403870RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    3408875}
    3409876
    3410 void LessNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3411 {
    3412     nodeStack.append(m_expr2.get());
    3413     nodeStack.append(m_expr1.get());
    3414 }
    3415 
    3416 // ECMA 11.8.1
    3417 bool LessNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3418 {
    3419     JSValue* v1 = m_expr1->evaluate(exec);
    3420     KJS_CHECKEXCEPTIONBOOLEAN
    3421     JSValue* v2 = m_expr2->evaluate(exec);
    3422     KJS_CHECKEXCEPTIONBOOLEAN
    3423     return lessThan(exec, v1, v2);
    3424 }
    3425 
    3426 JSValue* LessNode::evaluate(OldInterpreterExecState* exec)
    3427 {
    3428     return jsBoolean(inlineEvaluateToBoolean(exec));
    3429 }
    3430 
    3431 bool LessNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3432 {
    3433     return inlineEvaluateToBoolean(exec);
    3434 }
    3435 
    3436 bool LessNumbersNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3437 {
    3438     double n1 = m_expr1->evaluateToNumber(exec);
    3439     KJS_CHECKEXCEPTIONVALUE
    3440     double n2 = m_expr2->evaluateToNumber(exec);
    3441     return n1 < n2;
    3442 }
    3443 
    3444 JSValue* LessNumbersNode::evaluate(OldInterpreterExecState* exec)
    3445 {
    3446     return jsBoolean(inlineEvaluateToBoolean(exec));
    3447 }
    3448 
    3449 bool LessNumbersNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3450 {
    3451     return inlineEvaluateToBoolean(exec);
    3452 }
    3453 
    3454 bool LessStringsNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3455 {
    3456     JSValue* v1 = m_expr1->evaluate(exec);
    3457     KJS_CHECKEXCEPTIONVALUE
    3458     JSValue* v2 = m_expr2->evaluate(exec);
    3459     return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
    3460 }
    3461 
    3462 JSValue* LessStringsNode::evaluate(OldInterpreterExecState* exec)
    3463 {
    3464     return jsBoolean(inlineEvaluateToBoolean(exec));
    3465 }
    3466 
    3467 bool LessStringsNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3468 {
    3469     return inlineEvaluateToBoolean(exec);
    3470 }
    3471 
    3472877RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3473878{
     
    3477882}
    3478883
    3479 void GreaterNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3480 {
    3481     nodeStack.append(m_expr2.get());
    3482     nodeStack.append(m_expr1.get());
    3483 }
    3484 
    3485 // ECMA 11.8.2
    3486 bool GreaterNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3487 {
    3488     JSValue* v1 = m_expr1->evaluate(exec);
    3489     KJS_CHECKEXCEPTIONBOOLEAN
    3490     JSValue* v2 = m_expr2->evaluate(exec);
    3491     KJS_CHECKEXCEPTIONBOOLEAN
    3492     return lessThan(exec, v2, v1);
    3493 }
    3494 
    3495 JSValue* GreaterNode::evaluate(OldInterpreterExecState* exec)
    3496 {
    3497     return jsBoolean(inlineEvaluateToBoolean(exec));
    3498 }
    3499 
    3500 bool GreaterNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3501 {
    3502     return inlineEvaluateToBoolean(exec);
    3503 }
    3504 
    3505884RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3506885{
     
    3510889}
    3511890
    3512 void LessEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3513 {
    3514     nodeStack.append(m_expr2.get());
    3515     nodeStack.append(m_expr1.get());
    3516 }
    3517 
    3518 // ECMA 11.8.3
    3519 bool LessEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3520 {
    3521     JSValue* v1 = m_expr1->evaluate(exec);
    3522     KJS_CHECKEXCEPTIONBOOLEAN
    3523     JSValue* v2 = m_expr2->evaluate(exec);
    3524     KJS_CHECKEXCEPTIONBOOLEAN
    3525     return lessThanEq(exec, v1, v2);
    3526 }
    3527 
    3528 JSValue* LessEqNode::evaluate(OldInterpreterExecState* exec)
    3529 {
    3530     return jsBoolean(inlineEvaluateToBoolean(exec));
    3531 }
    3532 
    3533 bool LessEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3534 {
    3535     return inlineEvaluateToBoolean(exec);
    3536 }
    3537 
    3538891RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3539892{
     
    3543896}
    3544897
    3545 void GreaterEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3546 {
    3547     nodeStack.append(m_expr2.get());
    3548     nodeStack.append(m_expr1.get());
    3549 }
    3550 
    3551 // ECMA 11.8.4
    3552 bool GreaterEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3553 {
    3554     JSValue* v1 = m_expr1->evaluate(exec);
    3555     KJS_CHECKEXCEPTIONBOOLEAN
    3556     JSValue* v2 = m_expr2->evaluate(exec);
    3557     KJS_CHECKEXCEPTIONBOOLEAN
    3558     return lessThanEq(exec, v2, v1);
    3559 }
    3560 
    3561 JSValue* GreaterEqNode::evaluate(OldInterpreterExecState* exec)
    3562 {
    3563     return jsBoolean(inlineEvaluateToBoolean(exec));
    3564 }
    3565 
    3566 bool GreaterEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3567 {
    3568     return inlineEvaluateToBoolean(exec);
    3569 }
    3570 
    3571898RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3572899{
     
    3576903}
    3577904
    3578 void InstanceOfNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3579 {
    3580     nodeStack.append(m_expr2.get());
    3581     nodeStack.append(m_expr1.get());
    3582 }
    3583 
    3584 // ECMA 11.8.6
    3585 JSValue* InstanceOfNode::evaluate(OldInterpreterExecState* exec)
    3586 {
    3587     JSValue* v1 = m_expr1->evaluate(exec);
    3588     KJS_CHECKEXCEPTIONVALUE
    3589     JSValue* v2 = m_expr2->evaluate(exec);
    3590     KJS_CHECKEXCEPTIONVALUE
    3591 
    3592     if (!v2->isObject())
    3593         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, m_expr2.get());
    3594 
    3595     JSObject* o2 = static_cast<JSObject*>(v2);
    3596 
    3597     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
    3598     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
    3599     // property. It seems that all objects have the property, but not all implement it, so in this
    3600     // case we return false (consistent with Mozilla).
    3601     if (!o2->implementsHasInstance())
    3602         return jsBoolean(false);
    3603 
    3604     return jsBoolean(o2->hasInstance(exec, v1));
    3605 }
    3606 
    3607 bool InstanceOfNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3608 {
    3609     JSValue* v1 = m_expr1->evaluate(exec);
    3610     KJS_CHECKEXCEPTIONBOOLEAN
    3611     JSValue* v2 = m_expr2->evaluate(exec);
    3612     KJS_CHECKEXCEPTIONBOOLEAN
    3613 
    3614     if (!v2->isObject()) {
    3615         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'instanceof' operator.", v2, m_expr2.get());
    3616         return false;
    3617     }
    3618 
    3619     JSObject* o2 = static_cast<JSObject*>(v2);
    3620 
    3621     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
    3622     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
    3623     // property. It seems that all objects have the property, but not all implement it, so in this
    3624     // case we return false (consistent with Mozilla).
    3625     if (!o2->implementsHasInstance())
    3626         return false;
    3627 
    3628     return o2->hasInstance(exec, v1);
    3629 }
    3630 
    3631905RegisterID* InNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3632906{
     
    3636910}
    3637911
    3638 void InNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3639 {
    3640     nodeStack.append(m_expr2.get());
    3641     nodeStack.append(m_expr1.get());
    3642 }
    3643 
    3644 // ECMA 11.8.7
    3645 JSValue* InNode::evaluate(OldInterpreterExecState* exec)
    3646 {
    3647     JSValue* v1 = m_expr1->evaluate(exec);
    3648     KJS_CHECKEXCEPTIONVALUE
    3649     JSValue* v2 = m_expr2->evaluate(exec);
    3650     KJS_CHECKEXCEPTIONVALUE
    3651 
    3652     if (!v2->isObject())
    3653         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
    3654 
    3655     return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
    3656 }
    3657 
    3658 bool InNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3659 {
    3660     JSValue* v1 = m_expr1->evaluate(exec);
    3661     KJS_CHECKEXCEPTIONBOOLEAN
    3662     JSValue* v2 = m_expr2->evaluate(exec);
    3663     KJS_CHECKEXCEPTIONBOOLEAN
    3664 
    3665     if (!v2->isObject()) {
    3666         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
    3667         return false;
    3668     }
    3669 
    3670     return static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec)));
    3671 }
    3672 
    3673912// ------------------------------ Equality Nodes ------------------------------------
    3674913
     
    3680919}
    3681920
    3682 void EqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3683 {
    3684     nodeStack.append(m_expr2.get());
    3685     nodeStack.append(m_expr1.get());
    3686 }
    3687 
    3688 // ECMA 11.9.1
    3689 bool EqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3690 {
    3691     JSValue* v1 = m_expr1->evaluate(exec);
    3692     KJS_CHECKEXCEPTIONBOOLEAN
    3693     JSValue* v2 = m_expr2->evaluate(exec);
    3694     KJS_CHECKEXCEPTIONBOOLEAN
    3695 
    3696     return equal(exec, v1, v2);
    3697 }
    3698 
    3699 JSValue* EqualNode::evaluate(OldInterpreterExecState* exec)
    3700 {
    3701     return jsBoolean(inlineEvaluateToBoolean(exec));
    3702 }
    3703 
    3704 bool EqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3705 {
    3706     return inlineEvaluateToBoolean(exec);
    3707 }
    3708 
    3709921RegisterID* NotEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3710922{
     
    3714926}
    3715927
    3716 void NotEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3717 {
    3718     nodeStack.append(m_expr2.get());
    3719     nodeStack.append(m_expr1.get());
    3720 }
    3721 
    3722 // ECMA 11.9.2
    3723 bool NotEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3724 {
    3725     JSValue* v1 = m_expr1->evaluate(exec);
    3726     KJS_CHECKEXCEPTIONBOOLEAN
    3727     JSValue* v2 = m_expr2->evaluate(exec);
    3728     KJS_CHECKEXCEPTIONBOOLEAN
    3729 
    3730     return !equal(exec,v1, v2);
    3731 }
    3732 
    3733 JSValue* NotEqualNode::evaluate(OldInterpreterExecState* exec)
    3734 {
    3735     return jsBoolean(inlineEvaluateToBoolean(exec));
    3736 }
    3737 
    3738 bool NotEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3739 {
    3740     return inlineEvaluateToBoolean(exec);
    3741 }
    3742 
    3743928RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3744929{
     
    3748933}
    3749934
    3750 void StrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3751 {
    3752     nodeStack.append(m_expr2.get());
    3753     nodeStack.append(m_expr1.get());
    3754 }
    3755 
    3756 // ECMA 11.9.4
    3757 bool StrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3758 {
    3759     JSValue* v1 = m_expr1->evaluate(exec);
    3760     KJS_CHECKEXCEPTIONBOOLEAN
    3761     JSValue* v2 = m_expr2->evaluate(exec);
    3762     KJS_CHECKEXCEPTIONBOOLEAN
    3763 
    3764     return strictEqual(v1, v2);
    3765 }
    3766 
    3767 JSValue* StrictEqualNode::evaluate(OldInterpreterExecState* exec)
    3768 {
    3769     return jsBoolean(inlineEvaluateToBoolean(exec));
    3770 }
    3771 
    3772 bool StrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3773 {
    3774     return inlineEvaluateToBoolean(exec);
    3775 }
    3776 
    3777935RegisterID* NotStrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3778936{
     
    3782940}
    3783941
    3784 void NotStrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3785 {
    3786     nodeStack.append(m_expr2.get());
    3787     nodeStack.append(m_expr1.get());
    3788 }
    3789 
    3790 // ECMA 11.9.5
    3791 bool NotStrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
    3792 {
    3793     JSValue* v1 = m_expr1->evaluate(exec);
    3794     KJS_CHECKEXCEPTIONBOOLEAN
    3795     JSValue* v2 = m_expr2->evaluate(exec);
    3796     KJS_CHECKEXCEPTIONBOOLEAN
    3797 
    3798     return !strictEqual(v1, v2);
    3799 }
    3800 
    3801 JSValue* NotStrictEqualNode::evaluate(OldInterpreterExecState* exec)
    3802 {
    3803     return jsBoolean(inlineEvaluateToBoolean(exec));
    3804 }
    3805 
    3806 bool NotStrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3807 {
    3808     return inlineEvaluateToBoolean(exec);
    3809 }
    3810 
    3811942// ------------------------------ Bit Operation Nodes ----------------------------------
    3812943
     
    3818949}
    3819950
    3820 void BitAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3821 {
    3822     nodeStack.append(m_expr2.get());
    3823     nodeStack.append(m_expr1.get());
    3824 }
    3825 
    3826 // ECMA 11.10
    3827 JSValue* BitAndNode::evaluate(OldInterpreterExecState* exec)
    3828 {
    3829     JSValue* v1 = m_expr1->evaluate(exec);
    3830     KJS_CHECKEXCEPTIONVALUE
    3831     JSValue* v2 = m_expr2->evaluate(exec);
    3832     KJS_CHECKEXCEPTIONVALUE
    3833 
    3834     return jsNumberFromAnd(exec, v1, v2);
    3835 }
    3836 
    3837 int32_t BitAndNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
    3838 {
    3839     int32_t i1 = m_expr1->evaluateToInt32(exec);
    3840     KJS_CHECKEXCEPTIONNUMBER
    3841     int32_t i2 = m_expr2->evaluateToInt32(exec);
    3842     return (i1 & i2);
    3843 }
    3844 
    3845 double BitAndNode::evaluateToNumber(OldInterpreterExecState* exec)
    3846 {
    3847     return inlineEvaluateToInt32(exec);
    3848 }
    3849 
    3850 bool BitAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3851 {
    3852     return inlineEvaluateToInt32(exec);
    3853 }
    3854 
    3855 int32_t BitAndNode::evaluateToInt32(OldInterpreterExecState* exec)
    3856 {
    3857     return inlineEvaluateToInt32(exec);
    3858 }
    3859 
    3860 uint32_t BitAndNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3861 {
    3862     return inlineEvaluateToInt32(exec);
    3863 }
    3864 
    3865951RegisterID* BitXOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3866952{
     
    3870956}
    3871957
    3872 void BitXOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3873 {
    3874     nodeStack.append(m_expr2.get());
    3875     nodeStack.append(m_expr1.get());
    3876 }
    3877 
    3878 int32_t BitXOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
    3879 {
    3880     int i1 = m_expr1->evaluateToInt32(exec);
    3881     KJS_CHECKEXCEPTIONNUMBER
    3882     int i2 = m_expr2->evaluateToInt32(exec);
    3883     return (i1 ^ i2);
    3884 }
    3885 
    3886 JSValue* BitXOrNode::evaluate(OldInterpreterExecState* exec)
    3887 {
    3888     return jsNumber(inlineEvaluateToInt32(exec));
    3889 }
    3890 
    3891 double BitXOrNode::evaluateToNumber(OldInterpreterExecState* exec)
    3892 {
    3893     return inlineEvaluateToInt32(exec);
    3894 }
    3895 
    3896 bool BitXOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3897 {
    3898     return inlineEvaluateToInt32(exec);
    3899 }
    3900 
    3901 int32_t BitXOrNode::evaluateToInt32(OldInterpreterExecState* exec)
    3902 {
    3903     return inlineEvaluateToInt32(exec);
    3904 }
    3905 
    3906 uint32_t BitXOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3907 {
    3908     return inlineEvaluateToInt32(exec);
    3909 }
    3910 
    3911958RegisterID* BitOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    3912959{
     
    3914961    RegisterID* src2 = generator.emitNode(m_expr2.get());
    3915962    return generator.emitBitOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
    3916 }
    3917 
    3918 void BitOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3919 {
    3920     nodeStack.append(m_expr2.get());
    3921     nodeStack.append(m_expr1.get());
    3922 }
    3923 
    3924 int32_t BitOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
    3925 {
    3926     int i1 = m_expr1->evaluateToInt32(exec);
    3927     KJS_CHECKEXCEPTIONNUMBER
    3928     int i2 = m_expr2->evaluateToInt32(exec);
    3929     return (i1 | i2);
    3930 }
    3931 
    3932 JSValue* BitOrNode::evaluate(OldInterpreterExecState* exec)
    3933 {
    3934     return jsNumber(inlineEvaluateToInt32(exec));
    3935 }
    3936 
    3937 double BitOrNode::evaluateToNumber(OldInterpreterExecState* exec)
    3938 {
    3939     return inlineEvaluateToInt32(exec);
    3940 }
    3941 
    3942 bool BitOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3943 {
    3944     return inlineEvaluateToInt32(exec);
    3945 }
    3946 
    3947 int32_t BitOrNode::evaluateToInt32(OldInterpreterExecState* exec)
    3948 {
    3949     return inlineEvaluateToInt32(exec);
    3950 }
    3951 
    3952 uint32_t BitOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
    3953 {
    3954     return inlineEvaluateToInt32(exec);
    3955963}
    3956964
     
    3970978}
    3971979
    3972 void LogicalAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    3973 {
    3974     nodeStack.append(m_expr2.get());
    3975     nodeStack.append(m_expr1.get());
    3976 }
    3977 
    3978 // ECMA 11.11
    3979 JSValue* LogicalAndNode::evaluate(OldInterpreterExecState* exec)
    3980 {
    3981     JSValue* v1 = m_expr1->evaluate(exec);
    3982     KJS_CHECKEXCEPTIONVALUE
    3983     bool b1 = v1->toBoolean(exec);
    3984     KJS_CHECKEXCEPTIONVALUE
    3985     if (!b1)
    3986         return v1;
    3987     JSValue* v2 = m_expr2->evaluate(exec);
    3988     KJS_CHECKEXCEPTIONVALUE
    3989     return v2;
    3990 }
    3991 
    3992 bool LogicalAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
    3993 {
    3994     bool b = m_expr1->evaluateToBoolean(exec);
    3995     KJS_CHECKEXCEPTIONBOOLEAN
    3996     return b && m_expr2->evaluateToBoolean(exec);
    3997 }
    3998 
    3999980RegisterID* LogicalOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    4000981{
     
    4010991}
    4011992
    4012 void LogicalOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4013 {
    4014     nodeStack.append(m_expr2.get());
    4015     nodeStack.append(m_expr1.get());
    4016 }
    4017 
    4018 JSValue* LogicalOrNode::evaluate(OldInterpreterExecState* exec)
    4019 {
    4020     JSValue* v1 = m_expr1->evaluate(exec);
    4021     KJS_CHECKEXCEPTIONVALUE
    4022     if (v1->toBoolean(exec))
    4023         return v1;
    4024     return m_expr2->evaluate(exec);
    4025 }
    4026 
    4027 bool LogicalOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
    4028 {
    4029     bool b = m_expr1->evaluateToBoolean(exec);
    4030     KJS_CHECKEXCEPTIONBOOLEAN
    4031     return b || m_expr2->evaluateToBoolean(exec);
    4032 }
    4033 
    4034993// ------------------------------ ConditionalNode ------------------------------
    4035994
     
    40521011
    40531012    return newDst.get();
    4054 }
    4055 
    4056 void ConditionalNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4057 {
    4058     nodeStack.append(m_expr2.get());
    4059     nodeStack.append(m_expr1.get());
    4060     nodeStack.append(m_logical.get());
    4061 }
    4062 
    4063 // ECMA 11.12
    4064 JSValue* ConditionalNode::evaluate(OldInterpreterExecState* exec)
    4065 {
    4066     bool b = m_logical->evaluateToBoolean(exec);
    4067     KJS_CHECKEXCEPTIONVALUE
    4068     return b ? m_expr1->evaluate(exec) : m_expr2->evaluate(exec);
    4069 }
    4070 
    4071 bool ConditionalNode::evaluateToBoolean(OldInterpreterExecState* exec)
    4072 {
    4073     bool b = m_logical->evaluateToBoolean(exec);
    4074     KJS_CHECKEXCEPTIONBOOLEAN
    4075     return b ? m_expr1->evaluateToBoolean(exec) : m_expr2->evaluateToBoolean(exec);
    4076 }
    4077 
    4078 double ConditionalNode::evaluateToNumber(OldInterpreterExecState* exec)
    4079 {
    4080     bool b = m_logical->evaluateToBoolean(exec);
    4081     KJS_CHECKEXCEPTIONNUMBER
    4082     return b ? m_expr1->evaluateToNumber(exec) : m_expr2->evaluateToNumber(exec);
    4083 }
    4084 
    4085 int32_t ConditionalNode::evaluateToInt32(OldInterpreterExecState* exec)
    4086 {
    4087     bool b = m_logical->evaluateToBoolean(exec);
    4088     KJS_CHECKEXCEPTIONNUMBER
    4089     return b ? m_expr1->evaluateToInt32(exec) : m_expr2->evaluateToInt32(exec);
    4090 }
    4091 
    4092 uint32_t ConditionalNode::evaluateToUInt32(OldInterpreterExecState* exec)
    4093 {
    4094     bool b = m_logical->evaluateToBoolean(exec);
    4095     KJS_CHECKEXCEPTIONNUMBER
    4096     return b ? m_expr1->evaluateToUInt32(exec) : m_expr2->evaluateToUInt32(exec);
    4097 }
    4098 
    4099 // ECMA 11.13
    4100 
    4101 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
    4102 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
    4103 {
    4104     JSValue* v;
    4105     int i1;
    4106     int i2;
    4107     unsigned int ui;
    4108     switch (oper) {
    4109         case OpMultEq:
    4110             v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec));
    4111             break;
    4112         case OpDivEq:
    4113             v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec));
    4114             break;
    4115         case OpPlusEq:
    4116             v = add(exec, current, right->evaluate(exec));
    4117             break;
    4118         case OpMinusEq:
    4119             v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec));
    4120             break;
    4121         case OpLShift:
    4122             i1 = current->toInt32(exec);
    4123             i2 = right->evaluateToInt32(exec);
    4124             v = jsNumber(i1 << i2);
    4125             break;
    4126         case OpRShift:
    4127             i1 = current->toInt32(exec);
    4128             i2 = right->evaluateToInt32(exec);
    4129             v = jsNumber(i1 >> i2);
    4130             break;
    4131         case OpURShift:
    4132             ui = current->toUInt32(exec);
    4133             i2 = right->evaluateToInt32(exec);
    4134             v = jsNumber(ui >> i2);
    4135             break;
    4136         case OpAndEq:
    4137             i1 = current->toInt32(exec);
    4138             i2 = right->evaluateToInt32(exec);
    4139             v = jsNumber(i1 & i2);
    4140             break;
    4141         case OpXOrEq:
    4142             i1 = current->toInt32(exec);
    4143             i2 = right->evaluateToInt32(exec);
    4144             v = jsNumber(i1 ^ i2);
    4145             break;
    4146         case OpOrEq:
    4147             i1 = current->toInt32(exec);
    4148             i2 = right->evaluateToInt32(exec);
    4149             v = jsNumber(i1 | i2);
    4150             break;
    4151         case OpModEq: {
    4152             double d1 = current->toNumber(exec);
    4153             double d2 = right->evaluateToNumber(exec);
    4154             v = jsNumber(fmod(d1, d2));
    4155         }
    4156             break;
    4157         default:
    4158             ASSERT_NOT_REACHED();
    4159             v = jsUndefined();
    4160     }
    4161 
    4162     return v;
    41631013}
    41641014
     
    42371087}
    42381088
    4239 void ReadModifyResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
    4240 {
    4241     nodeStack.append(m_right.get());
    4242     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    4243     if (index != missingSymbolMarker()) {
    4244         if (isConstant(localStorage, index))
    4245             new (this) ReadModifyConstNode(index);
    4246         else
    4247             new (this) ReadModifyLocalVarNode(index);
    4248     }
    4249 }
    4250 
    42511089// ------------------------------ AssignResolveNode -----------------------------------
    42521090
     
    42741112}
    42751113
    4276 void AssignResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
    4277 {
    4278     nodeStack.append(m_right.get());
    4279     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
    4280     if (index != missingSymbolMarker()) {
    4281         if (isConstant(localStorage, index))
    4282             new (this) AssignConstNode;
    4283         else
    4284             new (this) AssignLocalVarNode(index);
    4285     }
    4286 }
    4287 
    4288 // ------------------------------ ReadModifyLocalVarNode -----------------------------------
    4289 
    4290 JSValue* ReadModifyLocalVarNode::evaluate(OldInterpreterExecState* exec)
    4291 {
    4292     ASSERT(exec->variableObject() == exec->scopeChain().top());
    4293 
    4294     ASSERT(m_operator != OpEqual);
    4295     JSValue* v = valueForReadModifyAssignment(exec, exec->localStorage()[m_index].value, m_right.get(), m_operator);
    4296 
    4297     KJS_CHECKEXCEPTIONVALUE
    4298    
    4299     // We can't store a pointer into localStorage() and use it throughout the function
    4300     // body, because valueForReadModifyAssignment() might cause an ActivationImp tear-off,
    4301     // changing the value of localStorage().
    4302    
    4303     exec->localStorage()[m_index].value = v;
    4304     return v;
    4305 }
    4306 
    4307 // ------------------------------ AssignLocalVarNode -----------------------------------
    4308 
    4309 JSValue* AssignLocalVarNode::evaluate(OldInterpreterExecState* exec)
    4310 {
    4311     ASSERT(exec->variableObject() == exec->scopeChain().top());
    4312     JSValue* v = m_right->evaluate(exec);
    4313 
    4314     KJS_CHECKEXCEPTIONVALUE
    4315 
    4316     exec->localStorage()[m_index].value = v;
    4317 
    4318     return v;
    4319 }
    4320 
    4321 // ------------------------------ ReadModifyConstNode -----------------------------------
    4322 
    4323 JSValue* ReadModifyConstNode::evaluate(OldInterpreterExecState* exec)
    4324 {
    4325     ASSERT(exec->variableObject() == exec->scopeChain().top());
    4326     JSValue* left = exec->localStorage()[m_index].value;
    4327     ASSERT(m_operator != OpEqual);
    4328     JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_operator);
    4329     KJS_CHECKEXCEPTIONVALUE
    4330     return result;
    4331 }
    4332 
    4333 // ------------------------------ AssignConstNode -----------------------------------
    4334 
    4335 JSValue* AssignConstNode::evaluate(OldInterpreterExecState* exec)
    4336 {
    4337     return m_right->evaluate(exec);
    4338 }
    4339 
    4340 JSValue* ReadModifyResolveNode::evaluate(OldInterpreterExecState* exec)
    4341 {
    4342     const ScopeChain& chain = exec->scopeChain();
    4343     ScopeChainIterator iter = chain.begin();
    4344     ScopeChainIterator end = chain.end();
    4345 
    4346     // We must always have something in the scope chain
    4347     ASSERT(iter != end);
    4348 
    4349     PropertySlot slot;
    4350     JSObject* base;
    4351     do {
    4352         base = *iter;
    4353         if (base->getPropertySlot(exec, m_ident, slot)) {
    4354             // See the comment in PostIncResolveNode::evaluate().
    4355 
    4356             base = *iter;
    4357             goto found;
    4358         }
    4359 
    4360         ++iter;
    4361     } while (iter != end);
    4362 
    4363     ASSERT(m_operator != OpEqual);
    4364     return throwUndefinedVariableError(exec, m_ident);
    4365 
    4366 found:
    4367     JSValue* v;
    4368 
    4369     ASSERT(m_operator != OpEqual);
    4370     JSValue* v1 = slot.getValue(exec, base, m_ident);
    4371     KJS_CHECKEXCEPTIONVALUE
    4372     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
    4373 
    4374     KJS_CHECKEXCEPTIONVALUE
    4375    
    4376     // Since valueForReadModifyAssignment() might cause an ActivationImp tear-off,
    4377     // we need to get the base from the ScopeChainIterator again.
    4378    
    4379     (*iter)->put(exec, m_ident, v);
    4380     return v;
    4381 }
    4382 
    4383 JSValue* AssignResolveNode::evaluate(OldInterpreterExecState* exec)
    4384 {
    4385     const ScopeChain& chain = exec->scopeChain();
    4386     ScopeChainIterator iter = chain.begin();
    4387     ScopeChainIterator end = chain.end();
    4388 
    4389     // we must always have something in the scope chain
    4390     ASSERT(iter != end);
    4391 
    4392     PropertySlot slot;
    4393     JSObject* base;
    4394     do {
    4395         base = *iter;
    4396         if (base->getPropertySlot(exec, m_ident, slot)) {
    4397             // See the comment in PostIncResolveNode::evaluate().
    4398 
    4399             base = *iter;
    4400             goto found;
    4401         }
    4402 
    4403         ++iter;
    4404     } while (iter != end);
    4405 
    4406 found:
    4407     JSValue* v = m_right->evaluate(exec);
    4408 
    4409     KJS_CHECKEXCEPTIONVALUE
    4410 
    4411     base->put(exec, m_ident, v);
    4412     return v;
    4413 }
    4414 
    4415 // ------------------------------ ReadModifyDotNode -----------------------------------
     1114// ------------------------------ AssignDotNode -----------------------------------
    44161115
    44171116RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    44241123}
    44251124
    4426 void AssignDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4427 {
    4428     nodeStack.append(m_right.get());
    4429     nodeStack.append(m_base.get());
    4430 }
    4431 
    4432 JSValue* AssignDotNode::evaluate(OldInterpreterExecState* exec)
    4433 {
    4434     JSValue* baseValue = m_base->evaluate(exec);
    4435     KJS_CHECKEXCEPTIONVALUE
    4436     JSObject* base = baseValue->toObject(exec);
    4437 
    4438     JSValue* v = m_right->evaluate(exec);
    4439 
    4440     KJS_CHECKEXCEPTIONVALUE
    4441 
    4442     base->put(exec, m_ident, v);
    4443     return v;
    4444 }
     1125// ------------------------------ ReadModifyDotNode -----------------------------------
    44451126
    44461127RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     
    44531134}
    44541135
    4455 void ReadModifyDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4456 {
    4457     nodeStack.append(m_right.get());
    4458     nodeStack.append(m_base.get());
    4459 }
    4460 
    4461 JSValue* ReadModifyDotNode::evaluate(OldInterpreterExecState* exec)
    4462 {
    4463     JSValue* baseValue = m_base->evaluate(exec);
    4464     KJS_CHECKEXCEPTIONVALUE
    4465     JSObject* base = baseValue->toObject(exec);
    4466 
    4467     JSValue* v;
    4468 
    4469     ASSERT(m_operator != OpEqual);
    4470     PropertySlot slot;
    4471     JSValue* v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
    4472     KJS_CHECKEXCEPTIONVALUE
    4473     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
    4474 
    4475     KJS_CHECKEXCEPTIONVALUE
    4476 
    4477     base->put(exec, m_ident, v);
    4478     return v;
    4479 }
    4480 
    44811136// ------------------------------ AssignErrorNode -----------------------------------
    44821137
     
    44841139{
    44851140    return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
    4486 }
    4487 
    4488 JSValue* AssignErrorNode::evaluate(OldInterpreterExecState* exec)
    4489 {
    4490     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
    4491     handleException(exec);
    4492     return jsUndefined();
    44931141}
    44941142
     
    45051153}
    45061154
    4507 void AssignBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4508 {
    4509     nodeStack.append(m_right.get());
    4510     nodeStack.append(m_subscript.get());
    4511     nodeStack.append(m_base.get());
    4512 }
    4513 
    4514 JSValue* AssignBracketNode::evaluate(OldInterpreterExecState* exec)
    4515 {
    4516     JSValue* baseValue = m_base->evaluate(exec);
    4517     KJS_CHECKEXCEPTIONVALUE
    4518     JSValue* subscript = m_subscript->evaluate(exec);
    4519     KJS_CHECKEXCEPTIONVALUE
    4520 
    4521     JSObject* base = baseValue->toObject(exec);
    4522 
    4523     uint32_t propertyIndex;
    4524     if (subscript->getUInt32(propertyIndex)) {
    4525         JSValue* v = m_right->evaluate(exec);
    4526         KJS_CHECKEXCEPTIONVALUE
    4527 
    4528         base->put(exec, propertyIndex, v);
    4529         return v;
    4530     }
    4531 
    4532     Identifier propertyName(subscript->toString(exec));
    4533     JSValue* v = m_right->evaluate(exec);
    4534     KJS_CHECKEXCEPTIONVALUE
    4535 
    4536     base->put(exec, propertyName, v);
    4537     return v;
    4538 }
    4539 
    45401155RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    45411156{
     
    45521167}
    45531168
    4554 void ReadModifyBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4555 {
    4556     nodeStack.append(m_right.get());
    4557     nodeStack.append(m_subscript.get());
    4558     nodeStack.append(m_base.get());
    4559 }
    4560 
    4561 JSValue* ReadModifyBracketNode::evaluate(OldInterpreterExecState* exec)
    4562 {
    4563     JSValue* baseValue = m_base->evaluate(exec);
    4564     KJS_CHECKEXCEPTIONVALUE
    4565     JSValue* subscript = m_subscript->evaluate(exec);
    4566     KJS_CHECKEXCEPTIONVALUE
    4567 
    4568     JSObject* base = baseValue->toObject(exec);
    4569 
    4570     uint32_t propertyIndex;
    4571     if (subscript->getUInt32(propertyIndex)) {
    4572         JSValue* v;
    4573         ASSERT(m_operator != OpEqual);
    4574         PropertySlot slot;
    4575         JSValue* v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
    4576         KJS_CHECKEXCEPTIONVALUE
    4577         v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
    4578 
    4579         KJS_CHECKEXCEPTIONVALUE
    4580 
    4581         base->put(exec, propertyIndex, v);
    4582         return v;
    4583     }
    4584 
    4585     Identifier propertyName(subscript->toString(exec));
    4586     JSValue* v;
    4587 
    4588     ASSERT(m_operator != OpEqual);
    4589     PropertySlot slot;
    4590     JSValue* v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
    4591     KJS_CHECKEXCEPTIONVALUE
    4592     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
    4593 
    4594     KJS_CHECKEXCEPTIONVALUE
    4595 
    4596     base->put(exec, propertyName, v);
    4597     return v;
    4598 }
    4599 
    46001169// ------------------------------ CommaNode ------------------------------------
    46011170
     
    46041173    generator.emitNode(m_expr1.get());
    46051174    return generator.emitNode(dst, m_expr2.get());
    4606 }
    4607 
    4608 void CommaNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4609 {
    4610     nodeStack.append(m_expr2.get());
    4611     nodeStack.append(m_expr1.get());
    4612 }
    4613 
    4614 // ECMA 11.14
    4615 JSValue* CommaNode::evaluate(OldInterpreterExecState* exec)
    4616 {
    4617     m_expr1->evaluate(exec);
    4618     KJS_CHECKEXCEPTIONVALUE
    4619     return m_expr2->evaluate(exec);
    46201175}
    46211176
     
    46261181    , m_init(init)
    46271182{
    4628 }
    4629 
    4630 void ConstDeclNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4631 {
    4632     if (m_next)
    4633         nodeStack.append(m_next.get());
    4634     if (m_init)
    4635         nodeStack.append(m_init.get());
    4636 }
    4637 
    4638 void ConstDeclNode::handleSlowCase(OldInterpreterExecState* exec, const ScopeChain& chain, JSValue* val)
    4639 {
    4640     ScopeChainIterator iter = chain.begin();
    4641     ScopeChainIterator end = chain.end();
    4642 
    4643     // We must always have something in the scope chain
    4644     ASSERT(iter != end);
    4645 
    4646     JSObject* base;
    4647 
    4648     do {
    4649         base = *iter;
    4650         if (base->isVariableObject())
    4651             break;
    4652         ++iter;
    4653     } while (iter != end);
    4654 
    4655     ASSERT(base && base->isVariableObject());
    4656 
    4657     static_cast<JSVariableObject*>(base)->putWithAttributes(exec, m_ident, val, ReadOnly);
    4658 }
    4659 
    4660 // ECMA 12.2
    4661 inline void ConstDeclNode::evaluateSingle(OldInterpreterExecState* exec)
    4662 {
    4663     ASSERT(exec->variableObject()->hasOwnProperty(exec, m_ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations.
    4664     const ScopeChain& chain = exec->scopeChain();
    4665     JSVariableObject* variableObject = exec->variableObject();
    4666 
    4667     bool inGlobalScope = ++chain.begin() == chain.end();
    4668 
    4669     if (m_init) {
    4670         if (inGlobalScope) {
    4671             JSValue* val = m_init->evaluate(exec);
    4672             unsigned attributes = ReadOnly;
    4673             if (exec->codeType() != EvalCode)
    4674                 attributes |= DontDelete;
    4675             variableObject->putWithAttributes(exec, m_ident, val, attributes);
    4676         } else {
    4677             JSValue* val = m_init->evaluate(exec);
    4678             KJS_CHECKEXCEPTIONVOID
    4679 
    4680             // if the variable object is the top of the scope chain, then that must
    4681             // be where this variable is declared, processVarDecls would have put
    4682             // it there. Don't search the scope chain, to optimize this very common case.
    4683             if (chain.top() != variableObject)
    4684                 return handleSlowCase(exec, chain, val);
    4685 
    4686             variableObject->putWithAttributes(exec, m_ident, val, ReadOnly);
    4687         }
    4688     }
    46891183}
    46901184
     
    47141208}
    47151209
    4716 JSValue* ConstDeclNode::evaluate(OldInterpreterExecState* exec)
    4717 {
    4718     evaluateSingle(exec);
    4719 
    4720     if (ConstDeclNode* n = m_next.get()) {
    4721         do {
    4722             n->evaluateSingle(exec);
    4723             KJS_CHECKEXCEPTIONVALUE
    4724             n = n->m_next.get();
    4725         } while (n);
    4726     }
    4727     return jsUndefined();
    4728 }
    4729 
    47301210// ------------------------------ ConstStatementNode -----------------------------
    47311211
    4732 void ConstStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4733 {
    4734     ASSERT(m_next);
    4735     nodeStack.append(m_next.get());
    4736 }
    4737 
    47381212RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
    47391213{
    47401214    return generator.emitNode(m_next.get());
    4741 }
    4742 
    4743 // ECMA 12.2
    4744 JSValue* ConstStatementNode::execute(OldInterpreterExecState* exec)
    4745 {
    4746     m_next->evaluate(exec);
    4747     KJS_CHECKEXCEPTION
    4748 
    4749     return exec->setNormalCompletion();
    47501215}
    47511216
     
    47941259}
    47951260
    4796 static inline JSValue* statementListExecute(StatementVector& statements, OldInterpreterExecState* exec)
    4797 {
    4798     JSValue* value = 0;
    4799     size_t size = statements.size();
    4800     for (size_t i = 0; i != size; ++i) {
    4801         JSValue* statementValue = statements[i]->execute(exec);
    4802         if (statementValue)
    4803             value = statementValue;
    4804         if (exec->completionType() != Normal)
    4805             return value;
    4806     }
    4807     return exec->setNormalCompletion(value);
    4808 }
    4809 
    48101261// ------------------------------ BlockNode ------------------------------------
    48111262
     
    48211272}
    48221273
    4823 void BlockNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4824 {
    4825     statementListPushFIFO(m_children, nodeStack);
    4826 }
    4827 
    4828 // ECMA 12.1
    4829 JSValue* BlockNode::execute(OldInterpreterExecState* exec)
    4830 {
    4831     return statementListExecute(m_children, exec);
    4832 }
    4833 
    48341274// ------------------------------ EmptyStatementNode ---------------------------
    48351275
     
    48371277{
    48381278    return dst;
    4839 }
    4840 
    4841 // ECMA 12.3
    4842 JSValue* EmptyStatementNode::execute(OldInterpreterExecState* exec)
    4843 {
    4844     return exec->setNormalCompletion();
    48451279}
    48461280
     
    48661300}
    48671301
    4868 void ExprStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4869 {
    4870     ASSERT(m_expr);
    4871     nodeStack.append(m_expr.get());
    4872 }
    4873 
    4874 // ECMA 12.4
    4875 JSValue* ExprStatementNode::execute(OldInterpreterExecState* exec)
    4876 {
    4877     JSValue* value = m_expr->evaluate(exec);
    4878     KJS_CHECKEXCEPTION
    4879 
    4880     return exec->setNormalCompletion(value);
    4881 }
    4882 
    48831302// ------------------------------ VarStatementNode ----------------------------
    48841303
     
    48891308}
    48901309
    4891 void VarStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4892 {
    4893     ASSERT(m_expr);
    4894     nodeStack.append(m_expr.get());
    4895 }
    4896 
    4897 JSValue* VarStatementNode::execute(OldInterpreterExecState* exec)
    4898 {
    4899     m_expr->evaluate(exec);
    4900     KJS_CHECKEXCEPTION
    4901 
    4902     return exec->setNormalCompletion();
    4903 }
    4904 
    49051310// ------------------------------ IfNode ---------------------------------------
    49061311
     
    49191324}
    49201325
    4921 void IfNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4922 {
    4923     nodeStack.append(m_ifBlock.get());
    4924     nodeStack.append(m_condition.get());
    4925 }
    4926 
    4927 // ECMA 12.5
    4928 JSValue* IfNode::execute(OldInterpreterExecState* exec)
    4929 {
    4930     bool b = m_condition->evaluateToBoolean(exec);
    4931     KJS_CHECKEXCEPTION
    4932 
    4933     if (b)
    4934         return m_ifBlock->execute(exec);
    4935     return exec->setNormalCompletion();
    4936 }
    4937 
    49381326RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    49391327{
     
    49541342    // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
    49551343    return 0;
    4956 }
    4957 
    4958 void IfElseNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
    4959 {
    4960     nodeStack.append(m_elseBlock.get());
    4961     IfNode::optimizeVariableAccess(exec, symbolTable, localStorage, nodeStack);
    4962 }
    4963 
    4964 // ECMA 12.5
    4965 JSValue* IfElseNode::execute(OldInterpreterExecState* exec)
    4966 {
    4967     bool b = m_condition->evaluateToBoolean(exec);
    4968     KJS_CHECKEXCEPTION
    4969 
    4970     if (b)
    4971         return m_ifBlock->execute(exec);
    4972     return m_elseBlock->execute(exec);
    49731344}
    49741345
     
    49941365}
    49951366
    4996 void DoWhileNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    4997 {
    4998     nodeStack.append(m_statement.get());
    4999     nodeStack.append(m_expr.get());
    5000 }
    5001 
    5002 // ECMA 12.6.1
    5003 JSValue* DoWhileNode::execute(OldInterpreterExecState* exec)
    5004 {
    5005     JSValue* value = 0;
    5006 
    5007     while (1) {
    5008         exec->pushIteration();
    5009         JSValue* statementValue = m_statement->execute(exec);
    5010         exec->popIteration();
    5011 
    5012         if (exec->dynamicGlobalObject()->timedOut())
    5013             return exec->setInterruptedCompletion();
    5014 
    5015         if (statementValue)
    5016             value = statementValue;
    5017 
    5018         if (exec->completionType() != Normal) {
    5019             if (exec->completionType() == Continue && m_labelStack.contains(exec->breakOrContinueTarget()))
    5020                 goto continueDoWhileLoop;
    5021             if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget()))
    5022                 break;
    5023             return statementValue;
    5024         }
    5025 
    5026     continueDoWhileLoop:
    5027         bool b = m_expr->evaluateToBoolean(exec);
    5028         KJS_CHECKEXCEPTION
    5029         if (!b)
    5030             break;
    5031     }
    5032 
    5033     return exec->setNormalCompletion(value);
    5034 }
    5035 
    50361367// ------------------------------ WhileNode ------------------------------------
    50371368
     
    50591390}
    50601391
    5061 void WhileNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5062 {
    5063     nodeStack.append(m_statement.get());
    5064     nodeStack.append(m_expr.get());
    5065 }
    5066 
    5067 // ECMA 12.6.2
    5068 JSValue* WhileNode::execute(OldInterpreterExecState* exec)
    5069 {
    5070     JSValue* value = 0;
    5071 
    5072     while (1) {
    5073         bool b = m_expr->evaluateToBoolean(exec);
    5074         KJS_CHECKEXCEPTION
    5075         if (!b)
    5076             break;
    5077 
    5078         exec->pushIteration();
    5079         JSValue* statementValue = m_statement->execute(exec);
    5080         exec->popIteration();
    5081 
    5082         if (exec->dynamicGlobalObject()->timedOut())
    5083             return exec->setInterruptedCompletion();
    5084 
    5085         if (statementValue)
    5086             value = statementValue;
    5087 
    5088         if (exec->completionType() != Normal) {
    5089             if (exec->completionType() == Continue && m_labelStack.contains(exec->breakOrContinueTarget()))
    5090                 continue;
    5091             if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget()))
    5092                 break;
    5093             return statementValue;
    5094         }
    5095     }
    5096 
    5097     return exec->setNormalCompletion(value);
    5098 }
    5099 
    51001392// ------------------------------ ForNode --------------------------------------
    51011393
    51021394RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    51031395{
    5104     generator.emitNode(m_expr1.get());
     1396    if (m_expr1)
     1397        generator.emitNode(m_expr1.get());
    51051398   
    51061399    RefPtr<LabelID> topOfLoop = generator.newLabel();
     
    51141407    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
    51151408    generator.popJumpContext();
    5116     generator.emitLabel(continueTarget.get()); 
    5117     generator.emitNode(m_expr3.get());
     1409    generator.emitLabel(continueTarget.get());
     1410    if (m_expr3)
     1411        generator.emitNode(m_expr3.get());
    51181412
    51191413    generator.emitLabel(beforeCondition.get());
    5120     RegisterID* cond = generator.emitNode(m_expr2.get());
    5121     generator.emitJumpIfTrue(cond, topOfLoop.get());
     1414    if (m_expr2) {
     1415        RegisterID* cond = generator.emitNode(m_expr2.get());
     1416        generator.emitJumpIfTrue(cond, topOfLoop.get());
     1417    } else {
     1418        generator.emitJump(topOfLoop.get());
     1419    }
    51221420    generator.emitLabel(breakTarget.get());
    51231421    return result.get();
    5124 }
    5125 
    5126 void ForNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5127 {
    5128     nodeStack.append(m_statement.get());
    5129     nodeStack.append(m_expr3.get());
    5130     nodeStack.append(m_expr2.get());
    5131     nodeStack.append(m_expr1.get());
    5132 }
    5133 
    5134 // ECMA 12.6.3
    5135 JSValue* ForNode::execute(OldInterpreterExecState* exec)
    5136 {
    5137     JSValue* value = 0;
    5138 
    5139     m_expr1->evaluate(exec);
    5140     KJS_CHECKEXCEPTION
    5141 
    5142     while (1) {
    5143         bool b = m_expr2->evaluateToBoolean(exec);
    5144         KJS_CHECKEXCEPTION
    5145         if (!b)
    5146             break;
    5147 
    5148         exec->pushIteration();
    5149         JSValue* statementValue = m_statement->execute(exec);
    5150         exec->popIteration();
    5151         if (statementValue)
    5152             value = statementValue;
    5153 
    5154         if (exec->dynamicGlobalObject()->timedOut())
    5155             return exec->setInterruptedCompletion();
    5156 
    5157         if (exec->completionType() != Normal) {
    5158             if (exec->completionType() == Continue && m_labelStack.contains(exec->breakOrContinueTarget()))
    5159                 goto continueForLoop;
    5160             if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget()))
    5161                 break;
    5162             return statementValue;
    5163         }
    5164 
    5165     continueForLoop:
    5166         m_expr3->evaluate(exec);
    5167         KJS_CHECKEXCEPTION
    5168     }
    5169 
    5170     return exec->setNormalCompletion(value);
    51711422}
    51721423
     
    51921443        m_init = new AssignResolveNode(ident, in, true);
    51931444    // for( var foo = bar in baz )
    5194 }
    5195 
    5196 void ForInNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5197 {
    5198     nodeStack.append(m_statement.get());
    5199     nodeStack.append(m_expr.get());
    5200     nodeStack.append(m_lexpr.get());
    5201     if (m_init)
    5202         nodeStack.append(m_init.get());
    52031445}
    52041446
     
    52521494}
    52531495
    5254 // ECMA 12.6.4
    5255 JSValue* ForInNode::execute(OldInterpreterExecState* exec)
    5256 {
    5257     JSValue* value = 0;
    5258 
    5259     if (m_init) {
    5260         m_init->evaluate(exec);
    5261         KJS_CHECKEXCEPTION
    5262     }
    5263 
    5264     JSValue* e = m_expr->evaluate(exec);
    5265     KJS_CHECKEXCEPTION
    5266 
    5267     // For Null and Undefined, we want to make sure not to go through
    5268     // the loop at all, because toObject will throw an exception.
    5269     if (e->isUndefinedOrNull())
    5270         return exec->setNormalCompletion();
    5271 
    5272     JSObject* v = e->toObject(exec);
    5273     PropertyNameArray propertyNames;
    5274     v->getPropertyNames(exec, propertyNames);
    5275 
    5276     PropertyNameArray::const_iterator end = propertyNames.end();
    5277     for (PropertyNameArray::const_iterator it = propertyNames.begin(); it != end; ++it) {
    5278         const Identifier& name = *it;
    5279         if (!v->hasProperty(exec, name))
    5280             continue;
    5281 
    5282         JSValue* str = jsOwnedString(name.ustring());
    5283 
    5284         if (m_lexpr->isResolveNode()) {
    5285             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
    5286 
    5287             const ScopeChain& chain = exec->scopeChain();
    5288             ScopeChainIterator iter = chain.begin();
    5289             ScopeChainIterator end = chain.end();
    5290 
    5291             // we must always have something in the scope chain
    5292             ASSERT(iter != end);
    5293 
    5294             PropertySlot slot;
    5295             JSObject* o;
    5296             do {
    5297                 o = *iter;
    5298                 if (o->getPropertySlot(exec, ident, slot)) {
    5299                     o->put(exec, ident, str);
    5300                     break;
    5301                 }
    5302                 ++iter;
    5303             } while (iter != end);
    5304 
    5305             if (iter == end)
    5306                 o->put(exec, ident, str);
    5307         } else if (m_lexpr->isDotAccessorNode()) {
    5308             const Identifier& ident = static_cast<DotAccessorNode*>(m_lexpr.get())->identifier();
    5309             JSValue* v = static_cast<DotAccessorNode*>(m_lexpr.get())->base()->evaluate(exec);
    5310             KJS_CHECKEXCEPTION
    5311             JSObject* o = v->toObject(exec);
    5312 
    5313             o->put(exec, ident, str);
    5314         } else {
    5315             ASSERT(m_lexpr->isBracketAccessorNode());
    5316             JSValue* v = static_cast<BracketAccessorNode*>(m_lexpr.get())->base()->evaluate(exec);
    5317             KJS_CHECKEXCEPTION
    5318             JSValue* v2 = static_cast<BracketAccessorNode*>(m_lexpr.get())->subscript()->evaluate(exec);
    5319             KJS_CHECKEXCEPTION
    5320             JSObject* o = v->toObject(exec);
    5321 
    5322             uint32_t i;
    5323             if (v2->getUInt32(i))
    5324                 o->put(exec, i, str);
    5325             o->put(exec, Identifier(v2->toString(exec)), str);
    5326         }
    5327 
    5328         KJS_CHECKEXCEPTION
    5329 
    5330         exec->pushIteration();
    5331         JSValue* statementValue = m_statement->execute(exec);
    5332         exec->popIteration();
    5333         if (statementValue)
    5334             value = statementValue;
    5335        
    5336         if (exec->dynamicGlobalObject()->timedOut())
    5337             return exec->setInterruptedCompletion();
    5338 
    5339         if (exec->completionType() != Normal) {
    5340             if (exec->completionType() == Continue && m_labelStack.contains(exec->breakOrContinueTarget()))
    5341                 continue;
    5342             if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget()))
    5343                 break;
    5344             return statementValue;
    5345         }
    5346     }
    5347 
    5348     return exec->setNormalCompletion(value);
    5349 }
    5350 
    53511496// ------------------------------ ContinueNode ---------------------------------
    53521497
     
    53741519}
    53751520
    5376 JSValue* ContinueNode::execute(OldInterpreterExecState* exec)
    5377 {
    5378     if (m_ident.isEmpty() && !exec->inIteration())
    5379         return setErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
    5380     if (!m_ident.isEmpty() && !exec->seenLabels().contains(m_ident))
    5381         return setErrorCompletion(exec, SyntaxError, "Label %s not found.", m_ident);
    5382     return exec->setContinueCompletion(&m_ident);
    5383 }
    5384 
    53851521// ------------------------------ BreakNode ------------------------------------
    53861522
     
    54051541
    54061542    return dst;
    5407 }
    5408 
    5409 JSValue* BreakNode::execute(OldInterpreterExecState* exec)
    5410 {
    5411     if (m_ident.isEmpty() && !exec->inIteration() && !exec->inSwitch())
    5412         return setErrorCompletion(exec, SyntaxError, "Invalid break statement.");
    5413     if (!m_ident.isEmpty() && !exec->seenLabels().contains(m_ident))
    5414         return setErrorCompletion(exec, SyntaxError, "Label %s not found.");
    5415     return exec->setBreakCompletion(&m_ident);
    54161543}
    54171544
     
    54331560}
    54341561
    5435 void ReturnNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5436 {
    5437     if (m_value)
    5438         nodeStack.append(m_value.get());
    5439 }
    5440 
    5441 // ECMA 12.9
    5442 JSValue* ReturnNode::execute(OldInterpreterExecState* exec)
    5443 {
    5444     CodeType codeType = exec->codeType();
    5445     if (codeType != FunctionCode)
    5446         return setErrorCompletion(exec, SyntaxError, "Invalid return statement.");
    5447 
    5448     if (!m_value)
    5449         return exec->setReturnValueCompletion(jsUndefined());
    5450 
    5451     JSValue* v = m_value->evaluate(exec);
    5452     KJS_CHECKEXCEPTION
    5453 
    5454     return exec->setReturnValueCompletion(v);
    5455 }
    5456 
    54571562// ------------------------------ WithNode -------------------------------------
    54581563
     
    54641569    generator.emitPopScope();
    54651570    return result;
    5466 }
    5467 
    5468 void WithNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5469 {
    5470     // Can't optimize within statement because "with" introduces a dynamic scope.
    5471     nodeStack.append(m_expr.get());
    5472 }
    5473 
    5474 // ECMA 12.10
    5475 JSValue* WithNode::execute(OldInterpreterExecState*)
    5476 {
    5477     ASSERT_NOT_REACHED();
    5478     return 0;
    5479 }
    5480 
    5481 // ------------------------------ CaseClauseNode -------------------------------
    5482 
    5483 void CaseClauseNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5484 {
    5485     if (m_expr)
    5486         nodeStack.append(m_expr.get());
    5487     statementListPushFIFO(m_children, nodeStack);
    5488 }
    5489 
    5490 // ECMA 12.11
    5491 JSValue* CaseClauseNode::evaluate(OldInterpreterExecState* exec)
    5492 {
    5493     JSValue* v = m_expr->evaluate(exec);
    5494     KJS_CHECKEXCEPTIONVALUE
    5495 
    5496     return v;
    5497 }
    5498 
    5499 // ECMA 12.11
    5500 JSValue* CaseClauseNode::executeStatements(OldInterpreterExecState* exec)
    5501 {
    5502     return statementListExecute(m_children, exec);
    5503 }
    5504 
    5505 // ------------------------------ ClauseListNode -------------------------------
    5506 
    5507 void ClauseListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5508 {
    5509     if (m_next)
    5510         nodeStack.append(m_next.get());
    5511     nodeStack.append(m_clause.get());
    55121571}
    55131572
     
    55621621}
    55631622
    5564 void CaseBlockNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5565 {
    5566     if (m_list2)
    5567         nodeStack.append(m_list2.get());
    5568     if (m_defaultClause)
    5569         nodeStack.append(m_defaultClause.get());
    5570     if (m_list1)
    5571         nodeStack.append(m_list1.get());
    5572 }
    5573 
    5574 // ECMA 12.11
    5575 JSValue* CaseBlockNode::executeBlock(OldInterpreterExecState* exec, JSValue* input)
    5576 {
    5577     ClauseListNode* a = m_list1.get();
    5578     while (a) {
    5579         CaseClauseNode* clause = a->getClause();
    5580         a = a->getNext();
    5581         JSValue* v = clause->evaluate(exec);
    5582         KJS_CHECKEXCEPTION
    5583         if (strictEqual(input, v)) {
    5584             JSValue* res = clause->executeStatements(exec);
    5585             if (exec->completionType() != Normal)
    5586                 return res;
    5587             for (; a; a = a->getNext()) {
    5588                 JSValue* res = a->getClause()->executeStatements(exec);
    5589                 if (exec->completionType() != Normal)
    5590                     return res;
    5591             }
    5592             break;
    5593         }
    5594     }
    5595 
    5596     ClauseListNode* b = m_list2.get();
    5597     while (b) {
    5598         CaseClauseNode* clause = b->getClause();
    5599         b = b->getNext();
    5600         JSValue* v = clause->evaluate(exec);
    5601         KJS_CHECKEXCEPTION
    5602         if (strictEqual(input, v)) {
    5603             JSValue* res = clause->executeStatements(exec);
    5604             if (exec->completionType() != Normal)
    5605                 return res;
    5606             goto step18;
    5607         }
    5608     }
    5609 
    5610     // default clause
    5611     if (m_defaultClause) {
    5612         JSValue* res = m_defaultClause->executeStatements(exec);
    5613         if (exec->completionType() != Normal)
    5614             return res;
    5615     }
    5616     b = m_list2.get();
    5617 step18:
    5618     while (b) {
    5619         CaseClauseNode* clause = b->getClause();
    5620         JSValue* res = clause->executeStatements(exec);
    5621         if (exec->completionType() != Normal)
    5622             return res;
    5623         b = b->getNext();
    5624     }
    5625 
    5626     // bail out on error
    5627     KJS_CHECKEXCEPTION
    5628 
    5629     return exec->setNormalCompletion();
    5630 }
    5631 
    56321623// ------------------------------ SwitchNode -----------------------------------
    56331624
     
    56461637}
    56471638
    5648 void SwitchNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5649 {
    5650     nodeStack.append(m_block.get());
    5651     nodeStack.append(m_expr.get());
    5652 }
    5653 
    5654 // ECMA 12.11
    5655 JSValue* SwitchNode::execute(OldInterpreterExecState* exec)
    5656 {
    5657     JSValue* v = m_expr->evaluate(exec);
    5658     KJS_CHECKEXCEPTION
    5659 
    5660     exec->pushSwitch();
    5661     JSValue* result = m_block->executeBlock(exec, v);
    5662     exec->popSwitch();
    5663 
    5664     if (exec->completionType() == Break && m_labelStack.contains(exec->breakOrContinueTarget()))
    5665         exec->setCompletionType(Normal);
    5666     return result;
    5667 }
    5668 
    56691639// ------------------------------ LabelNode ------------------------------------
     1640
    56701641RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    56711642{
     
    56861657}
    56871658
    5688 void LabelNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5689 {
    5690     nodeStack.append(m_statement.get());
    5691 }
    5692 
    5693 // ECMA 12.12
    5694 JSValue* LabelNode::execute(OldInterpreterExecState* exec)
    5695 {
    5696     if (!exec->seenLabels().push(m_label))
    5697         return setErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", m_label);
    5698     JSValue* result = m_statement->execute(exec);
    5699     exec->seenLabels().pop();
    5700 
    5701     if (exec->completionType() == Break && exec->breakOrContinueTarget() == m_label)
    5702         exec->setCompletionType(Normal);
    5703     return result;
    5704 }
    5705 
    57061659// ------------------------------ ThrowNode ------------------------------------
    57071660
     
    57101663    generator.emitThrow(generator.emitNode(dst, m_expr.get()));
    57111664    return dst;
    5712 }
    5713 
    5714 void ThrowNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5715 {
    5716     nodeStack.append(m_expr.get());
    5717 }
    5718 
    5719 // ECMA 12.13
    5720 JSValue* ThrowNode::execute(OldInterpreterExecState* exec)
    5721 {
    5722     JSValue* v = m_expr->evaluate(exec);
    5723     KJS_CHECKEXCEPTION
    5724 
    5725     handleException(exec, v);
    5726     return exec->setThrowCompletion(v);
    57271665}
    57281666
     
    57851723
    57861724
    5787 void TryNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
    5788 {
    5789     // Can't optimize within catchBlock because "catch" introduces a dynamic scope.
    5790     if (m_finallyBlock)
    5791         nodeStack.append(m_finallyBlock.get());
    5792     nodeStack.append(m_tryBlock.get());
    5793 }
    5794 
    5795 // ECMA 12.14
    5796 JSValue* TryNode::execute(OldInterpreterExecState*)
    5797 {
    5798     ASSERT_NOT_REACHED();
    5799     return 0;
    5800 }
    5801 
    58021725// ------------------------------ FunctionBodyNode -----------------------------
    58031726
     
    59421865}
    59431866
    5944 void ProgramNode::initializeSymbolTable(OldInterpreterExecState* exec)
    5945 {
    5946     // If a previous script defined a symbol with the same name as one of our
    5947     // symbols, to avoid breaking previously optimized nodes, we need to reuse
    5948     // the symbol's existing storage index. So, we can't be as efficient as
    5949     // FunctionBodyNode::initializeSymbolTable, which knows that no bindings
    5950     // have yet been made.
    5951 
    5952     JSVariableObject* variableObject = exec->variableObject();
    5953     SymbolTable& symbolTable = variableObject->symbolTable();
    5954 
    5955     size_t localStorageIndex = symbolTable.size();
    5956     size_t size;
    5957 
    5958     // Order must match the order in processDeclarations.
    5959 
    5960     size = m_functionStack.size();
    5961     m_functionIndexes.resize(size);
    5962     for (size_t i = 0; i < size; ++i) {
    5963         UString::Rep* rep = m_functionStack[i]->m_ident.ustring().rep();
    5964         pair<SymbolTable::iterator, bool> result = symbolTable.add(rep, localStorageIndex);
    5965         m_functionIndexes[i] = result.first->second.getIndex();
    5966         if (result.second)
    5967             ++localStorageIndex;
    5968     }
    5969 
    5970     size = m_varStack.size();
    5971     m_varIndexes.resize(size);
    5972     for (size_t i = 0; i < size; ++i) {
    5973         const Identifier& ident = m_varStack[i].first;
    5974         if (variableObject->hasProperty(exec, ident)) {
    5975             m_varIndexes[i] = missingSymbolMarker(); // Signal not to initialize this declaration.
    5976             continue;
    5977         }
    5978 
    5979         UString::Rep* rep = ident.ustring().rep();
    5980         pair<SymbolTable::iterator, bool> result = symbolTable.add(rep, localStorageIndex);
    5981         if (!result.second) {
    5982             m_varIndexes[i] = missingSymbolMarker(); // Signal not to initialize this declaration.
    5983             continue;
    5984         }
    5985 
    5986         m_varIndexes[i] = result.first->second.getIndex();
    5987         ++localStorageIndex;
    5988     }
    5989 }
    5990 
    5991 void ScopeNode::optimizeVariableAccess(OldInterpreterExecState* exec)
    5992 {
    5993     NodeStack nodeStack;
    5994     Node* node = statementListInitializeVariableAccessStack(m_children, nodeStack);
    5995     if (!node)
    5996         return;
    5997 
    5998     const SymbolTable& symbolTable = exec->variableObject()->symbolTable();
    5999     ASSERT_NOT_REACHED();
    6000     const LocalStorage localStorage;
    6001     while (true) {
    6002         node->optimizeVariableAccess(exec, symbolTable, localStorage, nodeStack);
    6003 
    6004         size_t size = nodeStack.size();
    6005         if (!size)
    6006             break;
    6007         --size;
    6008         node = nodeStack[size];
    6009         nodeStack.shrink(size);
    6010     }
    6011 }
    6012 
    6013 static void gccIsCrazy() KJS_FAST_CALL;
    6014 static void gccIsCrazy()
    6015 {
    6016 }
    6017 
    6018 void ProgramNode::processDeclarations(OldInterpreterExecState* exec)
    6019 {
    6020     // If you remove this call, some SunSpider tests, including
    6021     // bitops-nsieve-bits.js, will regress substantially on Mac, due to a ~40%
    6022     // increase in L2 cache misses. FIXME: <rdar://problem/5657439> WTF?
    6023     gccIsCrazy();
    6024 
    6025     initializeSymbolTable(exec);
    6026 
    6027     ASSERT_NOT_REACHED();
    6028     LocalStorage localStorage;
    6029 
    6030     // We can't just resize localStorage here because that would temporarily
    6031     // leave uninitialized entries, which would crash GC during the mark phase.
    6032     localStorage.reserveCapacity(localStorage.size() + m_varStack.size() + m_functionStack.size());
    6033 
    6034     int minAttributes = DontDelete;
    6035 
    6036     // In order for our localStorage indexes to be correct, we must match the
    6037     // order of addition in initializeSymbolTable().
    6038 
    6039     for (size_t i = 0, size = m_functionStack.size(); i < size; ++i) {
    6040         FuncDeclNode* node = m_functionStack[i].get();
    6041         LocalStorageEntry entry = LocalStorageEntry(node->makeFunction(exec, exec->scopeChain().node()), minAttributes);
    6042         size_t index = m_functionIndexes[i];
    6043 
    6044         if (index == localStorage.size())
    6045             localStorage.uncheckedAppend(entry);
    6046         else {
    6047             ASSERT(index < localStorage.size());
    6048             localStorage[index] = entry;
    6049         }
    6050     }
    6051 
    6052     for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
    6053         int index = m_varIndexes[i];
    6054         if (index == missingSymbolMarker())
    6055             continue;
    6056 
    6057         int attributes = minAttributes;
    6058         if (m_varStack[i].second & DeclarationStacks::IsConstant)
    6059             attributes |= ReadOnly;
    6060         LocalStorageEntry entry = LocalStorageEntry(jsUndefined(), attributes);
    6061 
    6062         ASSERT(static_cast<unsigned>(index) == localStorage.size());
    6063         localStorage.uncheckedAppend(entry);
    6064     }
    6065 
    6066     optimizeVariableAccess(exec);
    6067 }
    6068 
    6069 void EvalNode::processDeclarations(OldInterpreterExecState* exec)
    6070 {
    6071     // We could optimize access to pre-existing symbols here, but SunSpider
    6072     // reports that to be a net loss.
    6073 
    6074     size_t i;
    6075     size_t size;
    6076 
    6077     JSVariableObject* variableObject = exec->variableObject();
    6078 
    6079     for (i = 0, size = m_varStack.size(); i < size; ++i) {
    6080         Identifier& ident = m_varStack[i].first;
    6081         if (variableObject->hasProperty(exec, ident))
    6082             continue;
    6083         int attributes = 0;
    6084         if (m_varStack[i].second & DeclarationStacks::IsConstant)
    6085             attributes = ReadOnly;
    6086         variableObject->putWithAttributes(exec, ident, jsUndefined(), attributes);
    6087     }
    6088 
    6089     for (i = 0, size = m_functionStack.size(); i < size; ++i) {
    6090         FuncDeclNode* funcDecl = m_functionStack[i].get();
    6091         variableObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, exec->scopeChain().node()), 0);
    6092     }
    6093 }
    6094 
    60951867UString FunctionBodyNode::paramString() const
    60961868{
     
    61061878}
    61071879
    6108 JSValue* ProgramNode::execute(OldInterpreterExecState* exec)
    6109 {
    6110     processDeclarations(exec);
    6111     return ScopeNode::execute(exec);
    6112 }
    6113 
    6114 JSValue* EvalNode::execute(OldInterpreterExecState* exec)
    6115 {
    6116     processDeclarations(exec);
    6117     return ScopeNode::execute(exec);
    6118 }
    6119 
    6120 // ------------------------------ FunctionBodyNodeWithDebuggerHooks ---------------------------------
    6121 
    6122 FunctionBodyNodeWithDebuggerHooks::FunctionBodyNodeWithDebuggerHooks(SourceElements* children, DeclarationStacks::VarStack* varStack, DeclarationStacks::FunctionStack* funcStack, bool usesEval, bool needsClosure)
    6123     : FunctionBodyNode(children, varStack, funcStack, usesEval, needsClosure)
    6124 {
    6125 }
    6126 
    6127 JSValue* FunctionBodyNodeWithDebuggerHooks::execute(OldInterpreterExecState* exec)
    6128 {
    6129     JSValue* result = FunctionBodyNode::execute(exec);
    6130 
    6131     return result;
    6132 }
    6133 
    61341880// ------------------------------ FuncDeclNode ---------------------------------
    61351881
     
    61541900{
    61551901    return dst;
    6156 }
    6157 
    6158 JSValue* FuncDeclNode::execute(OldInterpreterExecState* exec)
    6159 {
    6160     return exec->setNormalCompletion();
    61611902}
    61621903
     
    61991940}
    62001941
    6201 JSValue* FuncExprNode::evaluate(OldInterpreterExecState* exec)
    6202 {
    6203     ASSERT_NOT_REACHED();
    6204 
    6205     bool named = !m_ident.isNull();
    6206     JSObject* functionScopeObject = 0;
    6207 
    6208     if (named) {
    6209         // named FunctionExpressions can recursively call themselves,
    6210         // but they won't register with the current scope chain and should
    6211         // be contained as single property in an anonymous object.
    6212         functionScopeObject = new JSObject;
    6213         exec->pushScope(functionScopeObject);
    6214     }
    6215 
    6216     FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain().node());
    6217     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
    6218     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
    6219     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
    6220 
    6221     if (named) {
    6222         functionScopeObject->putDirect(m_ident, func, ReadOnly | (exec->codeType() == EvalCode ? 0 : DontDelete));
    6223         exec->popScope();
    6224     }
    6225 
    6226     return func;
    6227 }
    6228 
    62291942} // namespace KJS
  • trunk/JavaScriptCore/kjs/nodes.h

    r34351 r34355  
    184184        virtual bool needsParensIfLeftmost() const { return false; }
    185185       
    186         // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
    187         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { }
    188 
    189186    protected:
    190187        Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
    191188
    192         // for use in execute()
    193         JSValue* setErrorCompletion(OldInterpreterExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
    194         JSValue* setErrorCompletion(OldInterpreterExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
    195 
    196         // for use in evaluate()
    197         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
    198         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
    199         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
    200         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
    201         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
    202         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
    203         JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
    204        
    205189        RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg);
    206190        RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&);
    207 
    208         JSValue* throwUndefinedVariableError(OldInterpreterExecState*, const Identifier&) KJS_FAST_CALL;
    209 
    210         void handleException(OldInterpreterExecState*) KJS_FAST_CALL;
    211         void handleException(OldInterpreterExecState*, JSValue*) KJS_FAST_CALL;
    212 
    213         // for use in execute()
    214         JSValue* rethrowException(OldInterpreterExecState*) KJS_FAST_CALL;
    215191
    216192        int m_line : 28;
     
    240216        JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
    241217
    242         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL = 0;
    243         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    244         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    245         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    246         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    247 
    248         // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
    249         virtual void optimizeForUnnecessaryResult() { }
    250 
    251218        // This needs to be in public in order to compile using GCC 3.x
    252219        typedef enum { EvalOperator, FunctionCall } CallerType;
    253     protected:
    254         template <CallerType, bool> inline JSValue* resolveAndCall(OldInterpreterExecState*, const Identifier&, ArgumentsNode*, size_t = 0);
    255220    };
    256221
     
    262227        int lastLine() const KJS_FAST_CALL { return m_lastLine; }
    263228
    264         virtual JSValue* execute(OldInterpreterExecState *exec) KJS_FAST_CALL = 0;
    265 
    266229        virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); }
    267230        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    284247        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    285248
    286         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    287249        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    288250        virtual Precedence precedence() const { return PrecPrimary; }
     
    298260        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    299261
    300         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    301         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL { return false; }
    302262        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    303263        virtual Precedence precedence() const { return PrecPrimary; }
     
    313273        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    314274
    315         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    316         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL { return true; }
    317275        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    318276        virtual Precedence precedence() const { return PrecPrimary; }
     
    340298        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    341299
    342         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    343         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    344         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    345         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    346         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    347300        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    348301        virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
     
    365318        }
    366319
    367         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    368         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    369         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    370 
    371320        virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
    372321
     
    385334        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    386335
    387         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    388         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    389         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    390336        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    391337        virtual Precedence precedence() const { return PrecPrimary; }
     
    404350        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    405351
    406         JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    407352        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    408353        virtual Precedence precedence() const { return PrecPrimary; }
     
    420365        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    421366
    422         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    423367        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    424368        virtual Precedence precedence() const { return PrecPrimary; }
     
    440384
    441385        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    442         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    443 
    444         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    445         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    446         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    447         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    448         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
     386
    449387        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    450388        virtual Precedence precedence() const { return PrecPrimary; }
     
    455393
    456394    protected:
    457         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    458395        Identifier m_ident;
    459396        int m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode.
     
    461398    };
    462399
    463     class LocalVarAccessNode : public ResolveNode {
    464     public:
    465         // Overwrites a ResolveNode in place.
    466         LocalVarAccessNode(int i) KJS_FAST_CALL
    467             : ResolveNode(PlacementNewAdopt)
    468         {
    469             ASSERT(i != missingSymbolMarker());
    470             m_index = i;
    471         }
    472 
    473         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    474         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    475         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    476         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    477         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    478 
    479     private:
    480         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    481     };
    482    
    483     class ScopedVarAccessNode : public ResolveNode {
    484     public:
    485         // Overwrites a ResolveNode in place.
    486         ScopedVarAccessNode(int i, size_t scopeDepth) KJS_FAST_CALL
    487         : ResolveNode(PlacementNewAdopt)
    488         {
    489             ASSERT(i != missingSymbolMarker());
    490             m_index = i;
    491             m_scopeDepth = scopeDepth;
    492         }
    493        
    494         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    495         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    496         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    497         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    498         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    499        
    500     private:
    501         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    502     };
    503    
    504     class NonLocalVarAccessNode : public ResolveNode {
    505     public:
    506         // Overwrites a ResolveNode in place.
    507         NonLocalVarAccessNode(size_t scopeDepth) KJS_FAST_CALL
    508         : ResolveNode(PlacementNewAdopt)
    509         {
    510             ASSERT(scopeDepth != 0);
    511             m_scopeDepth = scopeDepth;
    512         }
    513        
    514         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    515         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    516         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    517         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    518         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    519        
    520     private:
    521         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    522     };
    523 
    524400    class ElementNode : public Node {
    525401    public:
     
    539415        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    540416        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    541         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    542417
    543418        PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
    544 
    545         JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    546419
    547420    private:
     
    576449        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    577450
    578         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    579         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    580451        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    581452        virtual Precedence precedence() const { return PrecPrimary; }
     
    598469        }
    599470
    600         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    601471        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    602472        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    603473
    604         JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    605474        const Identifier& name() const { return m_name; }
    606475
     
    626495
    627496        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    628         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    629497        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    630498        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    631499
    632         JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    633500        PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
    634501
     
    651518
    652519        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    653         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    654         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    655520        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    656521        virtual Precedence precedence() const { return PrecPrimary; }
     
    671536        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    672537
    673         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    674         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    675         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    676         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    677         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    678         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    679538        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    680539        virtual Precedence precedence() const { return PrecMember; }
     
    686545
    687546    private:
    688         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    689 
    690547        RefPtr<ExpressionNode> m_base;
    691548        RefPtr<ExpressionNode> m_subscript;
     
    701558
    702559        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    703         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    704         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    705         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    706         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    707         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    708         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    709560        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    710561        virtual Precedence precedence() const { return PrecMember; }
     
    716567
    717568    private:
    718         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    719 
    720569        RefPtr<ExpressionNode> m_base;
    721570        Identifier m_ident;
     
    736585
    737586        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    738         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    739587        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    740588        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    741589
    742         void evaluateList(OldInterpreterExecState*, List&) KJS_FAST_CALL;
    743590        PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
    744591
     
    758605        }
    759606
    760         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    761607        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    762608        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    763 
    764         void evaluateList(OldInterpreterExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); }
    765609
    766610        RefPtr<ArgumentListNode> m_listNode;
     
    782626        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    783627
    784         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    785         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    786         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    787         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    788         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    789         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    790628        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    791629        virtual Precedence precedence() const { return PrecLeftHandSide; }
    792630
    793631    private:
    794         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    795 
    796632        RefPtr<ExpressionNode> m_expr;
    797633        RefPtr<ArgumentsNode> m_args;
     
    806642
    807643        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    808         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    809         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    810644        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    811645        virtual Precedence precedence() const { return PrecCall; }
     
    824658
    825659        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    826         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    827         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    828660        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    829661        virtual Precedence precedence() const { return PrecCall; }
     
    851683        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    852684
    853         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    854         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    855         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    856         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    857         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    858         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    859685        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    860686        virtual Precedence precedence() const { return PrecCall; }
    861687
    862688    protected:
    863         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    864 
    865689        Identifier m_ident;
    866690        RefPtr<ArgumentsNode> m_args;
     
    869693    };
    870694   
    871     class LocalVarFunctionCallNode : public FunctionCallResolveNode {
    872     public:
    873         LocalVarFunctionCallNode(int i) KJS_FAST_CALL
    874             : FunctionCallResolveNode(PlacementNewAdopt)
    875         {
    876             ASSERT(i != missingSymbolMarker());
    877             m_index = i;
    878         }
    879        
    880         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    881         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    882         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    883         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    884         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    885        
    886     private:
    887         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    888     };
    889    
    890     class ScopedVarFunctionCallNode : public FunctionCallResolveNode {
    891     public:
    892         ScopedVarFunctionCallNode(int i, size_t depth) KJS_FAST_CALL
    893             : FunctionCallResolveNode(PlacementNewAdopt)
    894         {
    895             ASSERT(i != missingSymbolMarker());
    896             m_index = i;
    897             m_scopeDepth = depth;
    898         }
    899        
    900         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    901         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    902         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    903         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    904         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    905        
    906     private:
    907         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    908     };
    909    
    910     class NonLocalVarFunctionCallNode : public FunctionCallResolveNode {
    911     public:
    912         NonLocalVarFunctionCallNode(size_t depth) KJS_FAST_CALL
    913             : FunctionCallResolveNode(PlacementNewAdopt)
    914         {
    915             m_scopeDepth = depth;
    916         }
    917        
    918         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    919         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    920         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    921         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    922         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    923        
    924     private:
    925         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    926     };
    927 
    928695    class FunctionCallBracketNode : public ExpressionNode {
    929696    public:
     
    936703
    937704        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    938         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    939         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    940705        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    941706        virtual Precedence precedence() const { return PrecCall; }
     
    957722
    958723        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    959         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    960         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    961         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    962         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    963         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    964         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    965724        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    966725        virtual Precedence precedence() const { return PrecCall; }
    967726
    968727    private:
    969         ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
    970 
    971728        RefPtr<ExpressionNode> m_base;
    972729        Identifier m_ident;
     
    1006763
    1007764        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1008         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1009         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1010765        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1011766        virtual Precedence precedence() const { return PrecPostfix; }
    1012         virtual void optimizeForUnnecessaryResult();
    1013     };
    1014 
    1015     class PostIncLocalVarNode : public PostIncResolveNode {
    1016     public:
    1017         PostIncLocalVarNode(int i) KJS_FAST_CALL
    1018             : PostIncResolveNode(PlacementNewAdopt)
    1019         {
    1020             ASSERT(i != missingSymbolMarker());
    1021             m_index = i;
    1022         }
    1023 
    1024         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1025         virtual void optimizeForUnnecessaryResult();
    1026     };
    1027 
    1028     class PostIncConstNode : public PostIncResolveNode {
    1029     public:
    1030         PostIncConstNode(int i) KJS_FAST_CALL
    1031             : PostIncResolveNode(PlacementNewAdopt)
    1032         {
    1033             ASSERT(i != missingSymbolMarker());
    1034             m_index = i;
    1035         }
    1036 
    1037         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1038767    };
    1039768
     
    1052781        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1053782
    1054         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1055         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1056783        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1057784        virtual Precedence precedence() const { return PrecPostfix; }
    1058         virtual void optimizeForUnnecessaryResult();
    1059     };
    1060 
    1061     class PostDecLocalVarNode : public PostDecResolveNode {
    1062     public:
    1063         PostDecLocalVarNode(int i) KJS_FAST_CALL
    1064             : PostDecResolveNode(PlacementNewAdopt)
    1065         {
    1066             ASSERT(i != missingSymbolMarker());
    1067             m_index = i;
    1068         }
    1069 
    1070         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1071         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1072         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1073         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1074         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1075         virtual void optimizeForUnnecessaryResult();
    1076 
    1077     private:
    1078         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
    1079     };
    1080 
    1081     class PostDecConstNode : public PostDecResolveNode {
    1082     public:
    1083         PostDecConstNode(int i) KJS_FAST_CALL
    1084             : PostDecResolveNode(PlacementNewAdopt)
    1085         {
    1086             ASSERT(i != missingSymbolMarker());
    1087             m_index = i;
    1088         }
    1089 
    1090         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1091785    };
    1092786
     
    1099793        }
    1100794
    1101         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1102795        virtual Precedence precedence() const { return PrecPostfix; }
    1103796
     
    1116809        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1117810
    1118         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1119811        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1120812    };
     
    1129821        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1130822
    1131         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1132823        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1133824    };
     
    1141832        }
    1142833
    1143         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1144834        virtual Precedence precedence() const { return PrecPostfix; }
    1145835
     
    1158848        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1159849
    1160         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1161850        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1162851    };
     
    1171860        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1172861
    1173         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1174862        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1175863    };
     
    1184872
    1185873        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1186         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1187874        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1188875        virtual Precedence precedence() const { return PrecPostfix; }
     
    1208895        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1209896
    1210         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1211         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1212897        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1213898        virtual Precedence precedence() const { return PrecUnary; }
     
    1215900    private:
    1216901        Identifier m_ident;
    1217     };
    1218 
    1219     class LocalVarDeleteNode : public DeleteResolveNode {
    1220     public:
    1221         LocalVarDeleteNode() KJS_FAST_CALL
    1222             : DeleteResolveNode(PlacementNewAdopt)
    1223         {
    1224         }
    1225 
    1226         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1227902    };
    1228903
     
    1237912        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1238913
    1239         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1240         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1241914        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1242915        virtual Precedence precedence() const { return PrecUnary; }
     
    1257930        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1258931
    1259         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1260         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1261932        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1262933        virtual Precedence precedence() const { return PrecUnary; }
     
    1276947        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1277948
    1278         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1279         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1280949        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1281950        virtual Precedence precedence() const { return PrecUnary; }
     
    1294963        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1295964
    1296         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1297         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1298965        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1299966        virtual Precedence precedence() const { return PrecUnary; }
     
    1320987        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1321988
    1322         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1323         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1324989        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1325990        virtual Precedence precedence() const { return PrecUnary; }
     
    1332997    };
    1333998
    1334     class LocalVarTypeOfNode : public TypeOfResolveNode {
    1335     public:
    1336         LocalVarTypeOfNode(int i) KJS_FAST_CALL
    1337             : TypeOfResolveNode(PlacementNewAdopt)
    1338         {
    1339             m_expectedReturnType = StringType;
    1340             ASSERT(i != missingSymbolMarker());
    1341             m_index = i;
    1342         }
    1343 
    1344         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1345     };
    1346 
    1347999    class TypeOfValueNode : public ExpressionNode {
    13481000    public:
     
    13551007        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    13561008
    1357         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1358         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    13591009        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    13601010        virtual Precedence precedence() const { return PrecUnary; }
     
    13781028        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    13791029
    1380         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1381         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    13821030        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    13831031        virtual Precedence precedence() const { return PrecUnary; }
    1384     };
    1385 
    1386     class PreIncLocalVarNode : public PreIncResolveNode {
    1387     public:
    1388         PreIncLocalVarNode(int i) KJS_FAST_CALL
    1389             : PreIncResolveNode(PlacementNewAdopt)
    1390         {
    1391             ASSERT(i != missingSymbolMarker());
    1392             m_index = i;
    1393         }
    1394 
    1395         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1396     };
    1397 
    1398     class PreIncConstNode : public PreIncResolveNode {
    1399     public:
    1400         PreIncConstNode(int i) KJS_FAST_CALL
    1401             : PreIncResolveNode(PlacementNewAdopt)
    1402         {
    1403             ASSERT(i != missingSymbolMarker());
    1404             m_index = i;
    1405         }
    1406 
    1407         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    14081032    };
    14091033
     
    14221046        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    14231047
    1424         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1425         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    14261048        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    14271049        virtual Precedence precedence() const { return PrecUnary; }
    1428     };
    1429 
    1430     class PreDecLocalVarNode : public PreDecResolveNode {
    1431     public:
    1432         PreDecLocalVarNode(int i) KJS_FAST_CALL
    1433             : PreDecResolveNode(PlacementNewAdopt)
    1434         {
    1435             ASSERT(i != missingSymbolMarker());
    1436             m_index = i;
    1437         }
    1438 
    1439         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1440     };
    1441 
    1442     class PreDecConstNode : public PreDecResolveNode {
    1443     public:
    1444         PreDecConstNode(int i) KJS_FAST_CALL
    1445             : PreDecResolveNode(PlacementNewAdopt)
    1446         {
    1447             ASSERT(i != missingSymbolMarker());
    1448             m_index = i;
    1449         }
    1450 
    1451         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    14521050    };
    14531051
     
    14601058        }
    14611059
    1462         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    14631060        virtual Precedence precedence() const { return PrecUnary; }
    14641061
     
    14771074        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    14781075
    1479         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    14801076        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    14811077    };
     
    14901086        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    14911087
    1492         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    14931088        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    14941089    };
     
    15021097        }
    15031098
    1504         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    15051099        virtual Precedence precedence() const { return PrecPostfix; }
    15061100
     
    15191113        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    15201114
    1521         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    15221115        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    15231116    };
     
    15321125        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    15331126
    1534         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    15351127        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    15361128    };
     
    15451137
    15461138        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1547         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    15481139        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    15491140        virtual Precedence precedence() const { return PrecUnary; }
     
    15631154
    15641155        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1565         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1566         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1567         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1568         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1569         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1570         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    15711156        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    15721157        virtual Precedence precedence() const { return PrecUnary; }
     
    15851170
    15861171        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1587         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1588         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1589         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    15901172        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    15911173        virtual Precedence precedence() const { return PrecUnary; }
     
    16041186
    16051187        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1606         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1607         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1608         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1609         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1610         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1611         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    16121188        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    16131189        virtual Precedence precedence() const { return PrecUnary; }
    16141190
    16151191    private:
    1616         ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
    1617 
    16181192        RefPtr<ExpressionNode> m_expr;
    16191193    };
     
    16281202
    16291203        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1630         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1631         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1632         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    16331204        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    16341205        virtual Precedence precedence() const { return PrecUnary; }
     
    16481219
    16491220        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1650         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1651         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1652         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1653         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1654         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1655         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    16561221        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    16571222        virtual Precedence precedence() const { return PrecMultiplicitave; }
    16581223
    16591224    private:
    1660         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
    1661 
    16621225        RefPtr<ExpressionNode> m_term1;
    16631226        RefPtr<ExpressionNode> m_term2;
     
    16741237
    16751238        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1676         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1677         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1678         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1679         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1680         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    16811239        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    16821240        virtual Precedence precedence() const { return PrecMultiplicitave; }
    16831241
    16841242    private:
    1685         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
    1686 
    16871243        RefPtr<ExpressionNode> m_term1;
    16881244        RefPtr<ExpressionNode> m_term2;
     
    16991255
    17001256        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1701         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1702         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1703         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1704         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1705         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1706         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    17071257        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    17081258        virtual Precedence precedence() const { return PrecMultiplicitave; }
    17091259
    17101260    private:
    1711         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
    1712 
    17131261        RefPtr<ExpressionNode> m_term1;
    17141262        RefPtr<ExpressionNode> m_term2;
     
    17241272
    17251273        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1726         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1727         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1728         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1729         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1730         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    17311274        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    17321275        virtual Precedence precedence() const { return PrecAdditive; }
     
    17421285        RefPtr<ExpressionNode> m_term1;
    17431286        RefPtr<ExpressionNode> m_term2;
    1744 
    1745     private:
    1746         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
    1747     };
    1748 
    1749     class AddNumbersNode : public AddNode {
    1750     public:
    1751         AddNumbersNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
    1752             : AddNode(term1, term2, NumberType)
    1753         {
    1754         }
    1755 
    1756         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1757         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1758         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1759         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1760 
    1761     private:
    1762         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1763     };
    1764 
    1765     class AddStringLeftNode : public AddNode {
    1766     public:
    1767         AddStringLeftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
    1768             : AddNode(term1, term2, StringType)
    1769         {
    1770         }
    1771 
    1772         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1773     };
    1774 
    1775     class AddStringRightNode : public AddNode {
    1776     public:
    1777         AddStringRightNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
    1778             : AddNode(term1, term2, StringType)
    1779         {
    1780         }
    1781 
    1782         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1783     };
    1784 
    1785     class AddStringsNode : public AddNode {
    1786     public:
    1787         AddStringsNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
    1788             : AddNode(term1, term2, StringType)
    1789         {
    1790         }
    1791 
    1792         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    17931287    };
    17941288
     
    18031297
    18041298        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1805         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1806         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1807         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1808         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1809         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    18101299        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    18111300        virtual Precedence precedence() const { return PrecAdditive; }
    18121301
    18131302    private:
    1814         ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
    1815 
    18161303        RefPtr<ExpressionNode> m_term1;
    18171304        RefPtr<ExpressionNode> m_term2;
     
    18281315
    18291316        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1830         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1831         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1832         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1833         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1834         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    18351317        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    18361318        virtual Precedence precedence() const { return PrecShift; }
    18371319
    18381320    private:
    1839         ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
    1840 
    18411321        RefPtr<ExpressionNode> m_term1;
    18421322        RefPtr<ExpressionNode> m_term2;
     
    18531333
    18541334        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1855         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1856         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1857         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1858         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1859         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    18601335        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    18611336        virtual Precedence precedence() const { return PrecShift; }
    18621337
    18631338    private:
    1864         ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
    1865 
    18661339        RefPtr<ExpressionNode> m_term1;
    18671340        RefPtr<ExpressionNode> m_term2;
     
    18781351
    18791352        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1880         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1881         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1882         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    1883         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    1884         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    18851353        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    18861354        virtual Precedence precedence() const { return PrecShift; }
    1887     private:
    1888         ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(OldInterpreterExecState*);
    1889 
     1355
     1356    private:
    18901357        RefPtr<ExpressionNode> m_term1;
    18911358        RefPtr<ExpressionNode> m_term2;
     
    19021369
    19031370        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1904         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1905         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1906         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    19071371        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    19081372        virtual Precedence precedence() const { return PrecRelational; }
    1909 
    1910     private:
    1911         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    19121373
    19131374    protected:
     
    19161377    };
    19171378
    1918     class LessNumbersNode : public LessNode {
    1919     public:
    1920         LessNumbersNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
    1921             : LessNode(expr1, expr2)
    1922         {
    1923         }
    1924 
    1925         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1926         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1927 
    1928     private:
    1929         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    1930     };
    1931 
    1932     class LessStringsNode : public LessNode {
    1933     public:
    1934         LessStringsNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
    1935             : LessNode(expr1, expr2)
    1936         {
    1937         }
    1938 
    1939         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1940         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    1941 
    1942     private:
    1943         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    1944     };
    1945 
    19461379    class GreaterNode : public ExpressionNode {
    19471380    public:
     
    19531386
    19541387        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1955         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1956         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1957         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    19581388        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    19591389        virtual Precedence precedence() const { return PrecRelational; }
    19601390
    19611391    private:
    1962         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    1963 
    19641392        RefPtr<ExpressionNode> m_expr1;
    19651393        RefPtr<ExpressionNode> m_expr2;
     
    19751403
    19761404        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1977         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    1978         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    1979         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    19801405        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    19811406        virtual Precedence precedence() const { return PrecRelational; }
    19821407
    19831408    private:
    1984         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    1985 
    19861409        RefPtr<ExpressionNode> m_expr1;
    19871410        RefPtr<ExpressionNode> m_expr2;
     
    19971420
    19981421        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    1999         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2000         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2001         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    20021422        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    20031423        virtual Precedence precedence() const { return PrecRelational; }
    20041424
    20051425    private:
    2006         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2007 
    20081426        RefPtr<ExpressionNode> m_expr1;
    20091427        RefPtr<ExpressionNode> m_expr2;
     
    20201438
    20211439        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2022         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2023         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2024         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    20251440        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    20261441        virtual Precedence precedence() const { return PrecRelational; }
     
    20411456        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    20421457
    2043         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2044         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2045         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    20461458        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    20471459        virtual Precedence precedence() const { return PrecRelational; }
     
    20621474
    20631475        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2064         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2065         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2066         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    20671476        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    20681477        virtual Precedence precedence() const { return PrecEquality; }
    20691478
    20701479    private:
    2071         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2072 
    20731480        RefPtr<ExpressionNode> m_expr1;
    20741481        RefPtr<ExpressionNode> m_expr2;
     
    20851492
    20861493        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2087         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2088         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2089         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    20901494        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    20911495        virtual Precedence precedence() const { return PrecEquality; }
    20921496
    20931497    private:
    2094         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2095 
    20961498        RefPtr<ExpressionNode> m_expr1;
    20971499        RefPtr<ExpressionNode> m_expr2;
     
    21081510
    21091511        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2110         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2111         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2112         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    21131512        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    21141513        virtual Precedence precedence() const { return PrecEquality; }
    21151514
    21161515    private:
    2117         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2118 
    21191516        RefPtr<ExpressionNode> m_expr1;
    21201517        RefPtr<ExpressionNode> m_expr2;
     
    21311528
    21321529        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2133         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2134         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2135         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    21361530        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    21371531        virtual Precedence precedence() const { return PrecEquality; }
    21381532
    21391533    private:
    2140         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2141 
    21421534        RefPtr<ExpressionNode> m_expr1;
    21431535        RefPtr<ExpressionNode> m_expr2;
     
    21541546
    21551547        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2156         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2157         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2158         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    2159         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    2160         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    2161         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    21621548        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    21631549        virtual Precedence precedence() const { return PrecBitwiseAnd; }
    21641550
    21651551    private:
    2166         ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
    2167 
    21681552        RefPtr<ExpressionNode> m_expr1;
    21691553        RefPtr<ExpressionNode> m_expr2;
     
    21801564
    21811565        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2182         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2183         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2184         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    2185         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    2186         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    2187         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    21881566        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    21891567        virtual Precedence precedence() const { return PrecBitwiseOr; }
    21901568
    21911569    private:
    2192         ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
    2193 
    21941570        RefPtr<ExpressionNode> m_expr1;
    21951571        RefPtr<ExpressionNode> m_expr2;
     
    22061582
    22071583        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2208         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2209         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2210         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    2211         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    2212         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    2213         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    22141584        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    22151585        virtual Precedence precedence() const { return PrecBitwiseXor; }
    22161586
    22171587    private:
    2218         ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
    2219 
    22201588        RefPtr<ExpressionNode> m_expr1;
    22211589        RefPtr<ExpressionNode> m_expr2;
     
    22351603
    22361604        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2237         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2238         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2239         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    22401605        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    22411606        virtual Precedence precedence() const { return PrecLogicalAnd; }
    22421607
    22431608    private:
    2244         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2245 
    22461609        RefPtr<ExpressionNode> m_expr1;
    22471610        RefPtr<ExpressionNode> m_expr2;
     
    22581621
    22591622        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2260         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2261         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2262         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    22631623        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    22641624        virtual Precedence precedence() const { return PrecLogicalOr; }
    22651625
    22661626    private:
    2267         ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
    2268 
    22691627        RefPtr<ExpressionNode> m_expr1;
    22701628        RefPtr<ExpressionNode> m_expr2;
     
    22841642
    22851643        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2286         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2287         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2288         virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
    2289         virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
    2290         virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    2291         virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
    22921644        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    22931645        virtual Precedence precedence() const { return PrecConditional; }
     
    23191671        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    23201672
    2321         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2322         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    23231673        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    23241674        virtual Precedence precedence() const { return PrecAssignment; }
     
    23321682    };
    23331683
    2334     class ReadModifyLocalVarNode : public ReadModifyResolveNode {
    2335     public:
    2336         ReadModifyLocalVarNode(int i) KJS_FAST_CALL
    2337             : ReadModifyResolveNode(PlacementNewAdopt)
    2338         {
    2339             ASSERT(i != missingSymbolMarker());
    2340             m_index = i;
    2341         }
    2342 
    2343         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2344     };
    2345 
    2346     class ReadModifyConstNode : public ReadModifyResolveNode {
    2347     public:
    2348         ReadModifyConstNode(int i) KJS_FAST_CALL
    2349             : ReadModifyResolveNode(PlacementNewAdopt)
    2350         {
    2351             ASSERT(i != missingSymbolMarker());
    2352             m_index = i;
    2353         }
    2354 
    2355         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2356     };
    2357 
    23581684    class AssignResolveNode : public ExpressionNode {
    23591685    public:
     
    23741700        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    23751701
    2376         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2377         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    23781702        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    23791703        virtual Precedence precedence() const { return PrecAssignment; }
     
    23841708        size_t m_index; // Used by ReadModifyLocalVarNode.
    23851709        bool m_rightHasAssignments;
    2386     };
    2387 
    2388     class AssignLocalVarNode : public AssignResolveNode {
    2389     public:
    2390         AssignLocalVarNode(int i) KJS_FAST_CALL
    2391             : AssignResolveNode(PlacementNewAdopt)
    2392         {
    2393             ASSERT(i != missingSymbolMarker());
    2394             m_index = i;
    2395         }
    2396 
    2397         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2398     };
    2399 
    2400     class AssignConstNode : public AssignResolveNode {
    2401     public:
    2402         AssignConstNode() KJS_FAST_CALL
    2403             : AssignResolveNode(PlacementNewAdopt)
    2404         {
    2405         }
    2406 
    2407         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    24081710    };
    24091711
     
    24221724        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    24231725
    2424         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2425         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    24261726        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    24271727        virtual Precedence precedence() const { return PrecAssignment; }
     
    24491749        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    24501750
    2451         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2452         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    24531751        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    24541752        virtual Precedence precedence() const { return PrecAssignment; }
     
    24731771
    24741772        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2475         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2476         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    24771773        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    24781774        virtual Precedence precedence() const { return PrecAssignment; }
     
    24981794        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    24991795
    2500         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2501         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    25021796        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    25031797        virtual Precedence precedence() const { return PrecAssignment; }
     
    25211815
    25221816        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2523         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    25241817        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    25251818        virtual Precedence precedence() const { return PrecAssignment; }
     
    25371830            , m_expr2(expr2)
    25381831        {
    2539             m_expr1->optimizeForUnnecessaryResult();
    2540         }
    2541 
    2542         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2543         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2544         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     1832        }
     1833
     1834        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    25451835        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    25461836        virtual Precedence precedence() const { return PrecExpression; }
     
    25641854        ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL;
    25651855
    2566         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2567         virtual KJS::JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    2568         void evaluateSingle(OldInterpreterExecState*) KJS_FAST_CALL;
    25691856        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    25701857        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    25771864        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    25781865        virtual RegisterID* emitCodeSingle(CodeGenerator&) KJS_FAST_CALL;
    2579     private:
    2580         void handleSlowCase(OldInterpreterExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;
    25811866    };
    25821867
     
    25881873        }
    25891874
    2590         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2591         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    25921875        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    25931876       
    25941877        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
     1878
    25951879    private:
    25961880        RefPtr<ConstDeclNode> m_next;
     
    26171901
    26181902        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2619         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2620         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    26211903        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    26221904
     
    26351917        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    26361918
    2637         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    26381919        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    26391920        virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
     
    26601941
    26611942        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2662         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2663         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    26641943        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    26651944
     
    26771956        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    26781957
    2679         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2680         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    26811958        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    26821959
     
    26941971
    26951972        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2696         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2697         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    26981973        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    26991974
     
    27121987
    27131988        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2714         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2715         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    27161989        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    27171990
     
    27292002
    27302003        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2731         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2732         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    27332004        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    27342005
     
    27472018
    27482019        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2749         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2750         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    27512020        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    27522021
     
    27592028    public:
    27602029        ForNode(ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) KJS_FAST_CALL
    2761             : m_expr1(expr1 ? expr1 : new PlaceholderTrueNode)
    2762             , m_expr2(expr2 ? expr2 : new PlaceholderTrueNode)
    2763             , m_expr3(expr3 ? expr3 : new PlaceholderTrueNode)
     2030            : m_expr1(expr1)
     2031            , m_expr2(expr2)
     2032            , m_expr3(expr3)
    27642033            , m_statement(statement)
    27652034            , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
    27662035        {
    2767             ASSERT(m_expr1);
    2768             ASSERT(m_expr2);
    2769             ASSERT(m_expr3);
    27702036            ASSERT(statement);
    2771 
    2772             m_expr1->optimizeForUnnecessaryResult();
    2773             m_expr3->optimizeForUnnecessaryResult();
    2774         }
    2775 
    2776         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2777         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2778         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
     2037        }
     2038
     2039        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    27792040        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    27802041
     
    27932054       
    27942055        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2795         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2796         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    27972056        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    27982057
     
    28182077       
    28192078        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2820         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    28212079        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    28222080
     
    28372095       
    28382096        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2839         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    28402097        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    28412098
     
    28522109
    28532110        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2854         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2855         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    28562111        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    28572112        virtual bool isReturnNode() const KJS_FAST_CALL { return true; }
     
    28702125
    28712126        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2872         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2873         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    28742127        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    28752128
     
    28882141
    28892142        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2890         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2891         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    28922143        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    28932144        virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_statement->pushLabel(ident); }
     
    29062157
    29072158        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    2908         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2909         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    29102159        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    29112160
     
    29242173        }
    29252174
    2926         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    2927         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    29282175        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    29292176
     
    29782225       
    29792226    protected:
    2980         void optimizeVariableAccess(OldInterpreterExecState*) KJS_FAST_CALL;
    2981 
    29822227        VarStack m_varStack;
    29832228        FunctionStack m_functionStack;
     
    29952240        virtual ~ProgramNode();
    29962241       
    2997         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    2998 
    29992242        ProgramCodeBlock& code(ScopeChainNode* scopeChain, bool canCreateGlobals) KJS_FAST_CALL
    30002243        {
     
    30102253        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    30112254
    3012         void initializeSymbolTable(OldInterpreterExecState*) KJS_FAST_CALL;
    3013         ALWAYS_INLINE void processDeclarations(OldInterpreterExecState*) KJS_FAST_CALL;
    3014 
    30152255        Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
    30162256        Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
     
    30242264        virtual ~EvalNode();
    30252265       
    3026         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    3027 
    30282266        EvalCodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL
    30292267        {
     
    30362274        EvalNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
    30372275
    3038         ALWAYS_INLINE void processDeclarations(OldInterpreterExecState*) KJS_FAST_CALL;
    30392276        void generateCode(ScopeChainNode*) KJS_FAST_CALL;
    30402277        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
     
    30992336        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    31002337        FunctionImp* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL;
    3101         virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    31022338        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    31032339        virtual Precedence precedence() const { return PrecMember; }
     
    31292365        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    31302366
    3131         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    31322367        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    31332368        FunctionImp* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL;
     
    31582393        }
    31592394
    3160         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    31612395        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    31622396        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    3163 
    3164         JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
    3165         JSValue* executeStatements(OldInterpreterExecState*) KJS_FAST_CALL;
    31662397
    31672398        ExpressionNode* expr() const { return m_expr.get(); }
     
    31862417        }
    31872418
    3188         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    31892419        CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
    31902420        ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
     
    32102440        RegisterID* emitCodeForBlock(CodeGenerator&, RegisterID* input, RegisterID* dst = 0) KJS_FAST_CALL;
    32112441
    3212         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    3213         JSValue* executeBlock(OldInterpreterExecState*, JSValue *input) KJS_FAST_CALL;
    32142442        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    32152443        virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     
    32312459        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
    32322460
    3233         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
    3234         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    32352461        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    32362462
     
    32442470        BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
    32452471
    3246         virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
    3247         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    3248         virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
     2472        virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    32492473
    32502474    private:
  • trunk/JavaScriptCore/kjs/object.cpp

    r34334 r34355  
    513513    JSObject *getterFunc = gs->getGetter();
    514514    if (getterFunc)
    515         slot.setGetterSlot(this->toThisObject(0), getterFunc);
     515        slot.setGetterSlot(getterFunc);
    516516    else
    517         slot.setUndefined(this);
     517        slot.setUndefined();
    518518}
    519519
  • trunk/JavaScriptCore/kjs/object.h

    r34334 r34355  
    103103     
    104104  private:
     105    // Object operations, with the toObject operation included.
     106    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     107    virtual bool getOwnPropertySlot(ExecState*, unsigned index, PropertySlot&);
     108    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     109    virtual void put(ExecState*, unsigned propertyName, JSValue*);
     110    virtual JSObject* toThisObject(ExecState*) const;
     111
    105112    JSObject *getter;
    106113    JSObject *setter; 
     
    526533inline JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const
    527534{
    528   PropertySlot slot;
     535  PropertySlot slot(const_cast<JSObject *>(this));
    529536
    530537  if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
    531     return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
     538    return slot.getValue(exec, propertyName);
    532539   
    533540  return jsUndefined();
     
    536543inline JSValue *JSObject::get(ExecState *exec, unsigned propertyName) const
    537544{
    538   PropertySlot slot;
     545  PropertySlot slot(const_cast<JSObject *>(this));
    539546  if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
    540     return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
     547    return slot.getValue(exec, propertyName);
    541548   
    542549  return jsUndefined();
     
    588595            fillGetterPropertySlot(slot, location);
    589596        } else
    590             slot.setValueSlot(this, location);
     597            slot.setValueSlot(location);
    591598        return true;
    592599    }
     
    594601    // non-standard Netscape extension
    595602    if (propertyName == exec->propertyNames().underscoreProto) {
    596         slot.setValueSlot(this, &_proto);
     603        slot.setValueSlot(&_proto);
    597604        slotIsWriteable = false;
    598605        return true;
     
    611618            fillGetterPropertySlot(slot, location);
    612619        else
    613             slot.setValueSlot(this, location);
     620            slot.setValueSlot(location);
    614621        return true;
    615622    }
     
    617624    // non-standard Netscape extension
    618625    if (propertyName == exec->propertyNames().underscoreProto) {
    619         slot.setValueSlot(this, &_proto);
     626        slot.setValueSlot(&_proto);
    620627        return true;
    621628    }
     
    639646}
    640647
     648inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const
     649{
     650    if (UNLIKELY(JSImmediate::isImmediate(this))) {
     651        JSObject* object = JSImmediate::toObject(this, exec);
     652        PropertySlot slot(object);
     653        if (!object->getPropertySlot(exec, propertyName, slot))
     654            return jsUndefined();
     655        return slot.getValue(exec, propertyName);
     656    }
     657    JSCell* cell = static_cast<JSCell*>(const_cast<JSValue*>(this));
     658    PropertySlot slot(cell);
     659    while (true) {
     660        if (cell->getOwnPropertySlot(exec, propertyName, slot))
     661            return slot.getValue(exec, propertyName);
     662        ASSERT(cell->isObject());
     663        JSValue* proto = static_cast<JSObject*>(cell)->prototype();
     664        if (!proto->isObject())
     665            return jsUndefined();
     666        cell = static_cast<JSCell*>(proto);
     667    }
     668}
     669
     670inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const
     671{
     672    if (UNLIKELY(JSImmediate::isImmediate(this))) {
     673        JSObject* object = JSImmediate::toObject(this, exec);
     674        PropertySlot slot(object);
     675        if (!object->getPropertySlot(exec, propertyName, slot))
     676            return jsUndefined();
     677        return slot.getValue(exec, propertyName);
     678    }
     679    JSCell* cell = const_cast<JSCell*>(asCell());
     680    PropertySlot slot(cell);
     681    while (true) {
     682        if (cell->getOwnPropertySlot(exec, propertyName, slot))
     683            return slot.getValue(exec, propertyName);
     684        ASSERT(cell->isObject());
     685        JSValue* proto = static_cast<JSObject*>(cell)->prototype();
     686        if (!proto->isObject())
     687            return jsUndefined();
     688        cell = static_cast<JSCell*>(proto);
     689    }
     690}
     691
     692inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     693{
     694    if (UNLIKELY(JSImmediate::isImmediate(this))) {
     695        JSImmediate::toObject(this, exec)->put(exec, propertyName, value);
     696        return;
     697    }
     698    asCell()->put(exec, propertyName, value);
     699}
     700
     701inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
     702{
     703    if (UNLIKELY(JSImmediate::isImmediate(this))) {
     704        JSImmediate::toObject(this, exec)->put(exec, propertyName, value);
     705        return;
     706    }
     707    asCell()->put(exec, propertyName, value);
     708}
     709
     710inline JSObject* PropertySlot::slotBase() const
     711{
     712    ASSERT(m_slotBase);
     713    // It's be nice to assert that m_slotBase is an object here, but that's a bit
     714    // too slow, even for debug builds.
     715    return static_cast<JSObject*>(m_slotBase);
     716}
     717
    641718} // namespace
    642719
  • trunk/JavaScriptCore/kjs/property_slot.cpp

    r34334 r34355  
    11// -*- c-basic-offset: 4 -*-
    22/*
    3  *  This file is part of the KDE libraries
    4  *  Copyright (C) 2005 Apple Computer, Inc.
     3 *  Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
    54 *
    65 *  This library is free software; you can redistribute it and/or
     
    3130namespace KJS {
    3231
    33 JSValue *PropertySlot::undefinedGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&)
     32JSValue* PropertySlot::undefinedGetter(ExecState*, const Identifier&, const PropertySlot&)
    3433{
    3534    return jsUndefined();
    3635}
    3736
    38 JSValue* PropertySlot::ungettableGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&)
     37JSValue* PropertySlot::ungettableGetter(ExecState*, const Identifier&, const PropertySlot&)
    3938{
    4039    ASSERT_NOT_REACHED();
     
    4241}
    4342
    44 JSValue *PropertySlot::functionGetter(ExecState* exec, JSObject* originalObject, const Identifier&, const PropertySlot& slot)
     43JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
    4544{
    4645    CallData data;
    4746    CallType callType = slot.m_data.getterFunc->getCallData(data);
    4847    if (callType == CallTypeNative)
    49         return slot.m_data.getterFunc->callAsFunction(exec, originalObject, exec->emptyList());
     48        return slot.m_data.getterFunc->callAsFunction(exec, slot.slotBase(), exec->emptyList());
    5049    ASSERT(callType == CallTypeJS);
    5150    RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack();
    5251    stack->pushFunctionRegisterFile();
    53     JSValue* result = slot.m_data.getterFunc->callAsFunction(exec, originalObject, exec->emptyList());
     52    JSValue* result = slot.m_data.getterFunc->callAsFunction(exec, slot.slotBase(), exec->emptyList());
    5453    stack->popFunctionRegisterFile();
    5554    return result;   
  • trunk/JavaScriptCore/kjs/property_slot.h

    r33979 r34355  
    11// -*- c-basic-offset: 4 -*-
    22/*
    3  *  Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    3939class PropertySlot {
    4040public:
    41     typedef JSValue* (*GetValueFunc)(ExecState*, JSObject* originalObject, const Identifier&, const PropertySlot&);
    42     typedef JSValue* (*GetValueNumericFunc)(ExecState*, JSObject* originalObject, unsigned index, const PropertySlot&);
     41    PropertySlot()
     42    {
     43        clearBase();
     44    }
    4345
    44     JSValue* getValue(ExecState* exec, JSObject* originalObject, const Identifier& propertyName) const
    45     {
     46    explicit PropertySlot(JSCell* base)
     47        : m_slotBase(base)
     48    {
     49    }
     50
     51    typedef JSValue* (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
     52    typedef JSValue* (*GetValueNumericFunc)(ExecState*, unsigned index, const PropertySlot&);
     53
     54    JSValue* getValue(ExecState* exec, const Identifier& propertyName) const
     55    {
    4656        if (m_getValue == KJS_VALUE_SLOT_MARKER)
    4757            return *m_data.valueSlot;
    4858        ASSERT(m_getValue != KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER);
    49         return m_getValue(exec, originalObject, propertyName, *this);
     59        return m_getValue(exec, propertyName, *this);
    5060    }
    5161
    52     JSValue* getValue(ExecState* exec, JSObject* originalObject, unsigned propertyName) const
    53     { 
     62    JSValue* getValue(ExecState* exec, unsigned propertyName) const
     63    {
    5464        if (m_getValue == KJS_VALUE_SLOT_MARKER)
    5565            return *m_data.valueSlot;
    5666        if (m_getValue == KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER)
    57             return m_data.numericFunc(exec, originalObject, propertyName, *this);
    58         return m_getValue(exec, originalObject, Identifier::from(propertyName), *this);
     67            return m_data.numericFunc(exec, propertyName, *this);
     68        return m_getValue(exec, Identifier::from(propertyName), *this);
    5969    }
    6070
     
    6575    }
    6676   
    67     void setValueSlot(JSObject* slotBase, JSValue** valueSlot)
     77    void setValueSlot(JSValue** valueSlot)
    6878    {
     79        ASSERT(valueSlot);
    6980        m_getValue = KJS_VALUE_SLOT_MARKER;
    70         m_slotBase = slotBase;
     81        clearBase();
    7182        m_data.valueSlot = valueSlot;
    7283    }
    7384
    74     void setStaticEntry(JSObject* slotBase, const HashEntry* staticEntry, GetValueFunc getValue)
     85    void setStaticEntry(JSCell* slotBase, const HashEntry* staticEntry, GetValueFunc getValue)
    7586    {
     87        ASSERT(slotBase);
     88        ASSERT(staticEntry);
    7689        ASSERT(getValue);
    7790        m_getValue = getValue;
     
    8093    }
    8194
    82     void setCustom(JSObject* slotBase, GetValueFunc getValue)
     95    void setCustom(JSCell* slotBase, GetValueFunc getValue)
    8396    {
     97        ASSERT(slotBase);
    8498        ASSERT(getValue);
    8599        m_getValue = getValue;
     
    87101    }
    88102
    89     void setCustomIndex(JSObject* slotBase, unsigned index, GetValueFunc getValue)
     103    void setCustomIndex(JSCell* slotBase, unsigned index, GetValueFunc getValue)
    90104    {
     105        ASSERT(slotBase);
    91106        ASSERT(getValue);
    92107        m_getValue = getValue;
     
    95110    }
    96111   
    97     void setCustomNumeric(JSObject* slotBase, GetValueNumericFunc getValue)
     112    void setCustomNumeric(JSCell* slotBase, GetValueNumericFunc getValue)
    98113    {
     114        ASSERT(slotBase);
    99115        ASSERT(getValue);
    100116        m_slotBase = slotBase;
     
    103119    }
    104120   
    105     void setGetterSlot(JSObject* slotBase, JSObject* getterFunc)
     121    void setGetterSlot(JSObject* getterFunc)
    106122    {
     123        ASSERT(getterFunc);
    107124        m_getValue = functionGetter;
    108         m_slotBase = slotBase;
    109125        m_data.getterFunc = getterFunc;
    110126    }
    111127   
    112     void setUndefined(JSObject *slotBase)
     128    void setUndefined()
    113129    {
    114         m_slotBase = slotBase;
     130        clearBase();
    115131        m_getValue = undefinedGetter;
    116132    }
    117133
    118     void setUngettable(JSObject* slotBase) // Used to signal that you have a property, but trying to get it at this time is an error.
     134    JSObject* slotBase() const;
     135
     136    void setBase(JSCell* base)
    119137    {
    120         m_slotBase = slotBase;
    121         m_getValue = ungettableGetter;
     138        ASSERT(m_slotBase);
     139        ASSERT(base);
     140        m_slotBase = base;
    122141    }
    123142
    124     JSObject* slotBase() const { return m_slotBase; }
     143    void clearBase()
     144    {
     145#ifndef NDEBUG
     146        m_slotBase = 0;
     147#endif
     148    }
    125149
    126150    const HashEntry* staticEntry() const { return m_data.staticEntry; }
     
    128152
    129153private:
    130     static JSValue* undefinedGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    131     static JSValue* ungettableGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    132     static JSValue* functionGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
     154    static JSValue* undefinedGetter(ExecState*, const Identifier&, const PropertySlot&);
     155    static JSValue* ungettableGetter(ExecState*, const Identifier&, const PropertySlot&);
     156    static JSValue* functionGetter(ExecState*, const Identifier&, const PropertySlot&);
    133157   
    134158    GetValueFunc m_getValue;
    135159
    136     JSObject* m_slotBase;
     160    JSCell* m_slotBase;
    137161    union {
    138162        JSObject* getterFunc;
  • trunk/JavaScriptCore/kjs/string_object.cpp

    r34334 r34355  
    5959}
    6060
    61 JSValue *StringInstance::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot &slot)
     61JSValue *StringInstance::lengthGetter(ExecState*, const Identifier&, const PropertySlot &slot)
    6262{
    6363    return jsNumber(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().size());
    6464}
    6565
    66 JSValue* StringInstance::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
     66JSValue* StringInstance::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
    6767{
    6868    return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(slot.index(), 1));
    6969}
    7070
    71 static JSValue* stringInstanceNumericPropertyGetter(ExecState*, JSObject*, unsigned index, const PropertySlot& slot)
     71static JSValue* stringInstanceNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
    7272{
    7373    return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(index, 1));
  • trunk/JavaScriptCore/kjs/string_object.h

    r33979 r34355  
    5151    bool inlineGetOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
    5252
    53     static JSValue* lengthGetter(ExecState*, JSObject *, const Identifier&, const PropertySlot&);
    54     static JSValue* indexGetter(ExecState*, JSObject *, const Identifier&, const PropertySlot&);
     53    static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
     54    static JSValue* indexGetter(ExecState*, const Identifier&, const PropertySlot&);
    5555  };
    5656
  • trunk/JavaScriptCore/kjs/value.cpp

    r33979 r34355  
    218218}
    219219
     220bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot)
     221{
     222    // This is not a general purpose implementation of getOwnPropertySlot.
     223    // It should only be called by JSValue::get.
     224    // It calls getPropertySlot, not getOwnPropertySlot.
     225    JSObject* object = toObject(exec);
     226    slot.setBase(object);
     227    if (!object->getPropertySlot(exec, identifier, slot))
     228        slot.setUndefined();
     229    return true;
     230}
     231
     232bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot)
     233{
     234    // This is not a general purpose implementation of getOwnPropertySlot.
     235    // It should only be called by JSValue::get.
     236    // It calls getPropertySlot, not getOwnPropertySlot.
     237    JSObject* object = toObject(exec);
     238    slot.setBase(object);
     239    if (!object->getPropertySlot(exec, identifier, slot))
     240        slot.setUndefined();
     241    return true;
     242}
     243
     244void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value)
     245{
     246    toObject(exec)->put(exec, identifier, value);
     247}
     248
     249void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)
     250{
     251    toObject(exec)->put(exec, identifier, value);
     252}
     253
     254JSObject* JSCell::toThisObject(ExecState* exec) const
     255{
     256    return toObject(exec);
     257}
     258
    220259JSCell* jsString(const char* s)
    221260{
  • trunk/JavaScriptCore/kjs/value.h

    r34088 r34355  
    3434
    3535class ExecState;
     36class Identifier;
    3637class JSObject;
    3738class JSCell;
     39class PropertySlot;
    3840
    3941struct ClassInfo;
     
    98100    JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
    99101    UString toString(ExecState *exec) const;
    100     JSObject *toObject(ExecState *exec) const;
     102    JSObject* toObject(ExecState *exec) const;
    101103
    102104    // Integer conversions.
     
    122124    static uint32_t toUInt32SlowCase(double, bool& ok);
    123125
     126    // Object operations, with the toObject operation included.
     127    JSValue* get(ExecState*, const Identifier& propertyName) const;
     128    JSValue* get(ExecState*, unsigned propertyName) const;
     129    void put(ExecState*, const Identifier& propertyName, JSValue*);
     130    void put(ExecState*, unsigned propertyName, JSValue*);
     131    JSObject* toThisObject(ExecState*) const;
     132
    124133private:
     134    bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
     135    bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    125136    int32_t toInt32SlowCase(ExecState*, bool& ok) const;
    126137    uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
     
    129140    JSCell *asCell();
    130141    const JSCell *asCell() const;
    131 
    132     // Give a compile time error if we try to copy one of these.
    133     JSValue(const JSValue&);
    134     JSValue& operator=(const JSValue&);
    135142};
    136143
     
    181188    virtual void mark();
    182189    bool marked() const;
     190
     191    // Object operations, with the toObject operation included.
     192    virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     193    virtual void put(ExecState*, unsigned propertyName, JSValue*);
     194    virtual JSObject* toThisObject(ExecState*) const;
     195
     196    // Base implementation, but for non-object classes implements getPropertySlot.
     197    virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
     198    virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    183199};
    184200
     
    197213  virtual UString toString(ExecState* exec) const;
    198214  virtual JSObject* toObject(ExecState* exec) const;
    199  
     215    virtual JSObject* toThisObject(ExecState*) const;
     216
    200217  void* operator new(size_t size)
    201218  {
     
    584601}
    585602
     603inline JSObject* JSValue::toThisObject(ExecState* exec) const
     604{
     605    if (UNLIKELY(JSImmediate::isImmediate(this)))
     606        return JSImmediate::toObject(this, exec);
     607    return asCell()->toThisObject(exec);
     608}
     609
    586610} // namespace
    587611
Note: See TracChangeset for help on using the changeset viewer.