Changeset 34355 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Jun 3, 2008, 5:40:47 PM (17 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/ExecState.h
r34071 r34355 105 105 106 106 private: 107 // Default constructor required for OldInterpreterExecState withgcc 3.108 ExecState() { };107 // Default constructor required for gcc 3. 108 ExecState() { } 109 109 110 110 ExecState(ExecState*, Machine*, RegisterFile*, ScopeChainNode*, int callFrameOffset); … … 127 127 }; 128 128 129 // This code is now defunct:130 131 129 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() const141 {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 };232 130 233 131 } // namespace KJS -
trunk/JavaScriptCore/kjs/JSActivation.cpp
r34095 r34355 75 75 76 76 if (JSValue** location = getDirectLocation(propertyName)) { 77 slot.setValueSlot( this,location);77 slot.setValueSlot(location); 78 78 return true; 79 79 } … … 161 161 } 162 162 163 JSValue* JSActivation::argumentsGetter(ExecState* exec, JSObject*,const Identifier&, const PropertySlot& slot)163 JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 164 164 { 165 165 JSActivation* thisObj = static_cast<JSActivation*>(slot.slotBase()); -
trunk/JavaScriptCore/kjs/JSActivation.h
r33979 r34355 77 77 }; 78 78 79 static JSValue* argumentsGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot&);79 static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&); 80 80 NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter(); 81 81 NEVER_INLINE JSObject* createArgumentsObject(ExecState*); -
trunk/JavaScriptCore/kjs/JSVariableObject.h
r33979 r34355 101 101 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 102 102 if (!entry.isEmpty()) { 103 slot.setValueSlot( this,&valueAt(entry.getIndex()));103 slot.setValueSlot(&valueAt(entry.getIndex())); 104 104 return true; 105 105 } … … 111 111 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 112 112 if (!entry.isEmpty()) { 113 slot.setValueSlot( this,&valueAt(entry.getIndex()));113 slot.setValueSlot(&valueAt(entry.getIndex())); 114 114 slotIsWriteable = !entry.isReadOnly(); 115 115 return true; -
trunk/JavaScriptCore/kjs/array_instance.cpp
r34334 r34355 131 131 } 132 132 133 JSValue* ArrayInstance::lengthGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot& slot)133 JSValue* ArrayInstance::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot) 134 134 { 135 135 return jsNumber(static_cast<ArrayInstance*>(slot.slotBase())->m_length); … … 140 140 ArrayStorage* storage = m_storage; 141 141 142 if ( i >= m_length) {142 if (UNLIKELY(i >= m_length)) { 143 143 if (i > maxArrayIndex) 144 144 return getOwnPropertySlot(exec, Identifier::from(i), slot); … … 149 149 JSValue*& valueSlot = storage->m_vector[i]; 150 150 if (valueSlot) { 151 slot.setValueSlot( this,&valueSlot);151 slot.setValueSlot(&valueSlot); 152 152 return true; 153 153 } … … 156 156 SparseArrayValueMap::iterator it = map->find(i); 157 157 if (it != map->end()) { 158 slot.setValueSlot( this,&it->second);158 slot.setValueSlot(&it->second); 159 159 return true; 160 160 } -
trunk/JavaScriptCore/kjs/array_instance.h
r34118 r34355 59 59 60 60 private: 61 static JSValue* lengthGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot&);61 static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&); 62 62 bool inlineGetOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 63 63 -
trunk/JavaScriptCore/kjs/array_object.cpp
r34334 r34355 83 83 static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index) 84 84 { 85 PropertySlot slot ;85 PropertySlot slot(obj); 86 86 if (!obj->getPropertySlot(exec, index, slot)) 87 87 return 0; 88 return slot.getValue(exec, obj,index);88 return slot.getValue(exec, index); 89 89 } 90 90 … … 514 514 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 515 515 for (unsigned k = 0; k < length && !exec->hadException(); ++k) { 516 PropertySlot slot ;516 PropertySlot slot(thisObj); 517 517 518 518 if (!thisObj->getPropertySlot(exec, k, slot)) 519 519 continue; 520 520 521 JSValue* v = slot.getValue(exec, thisObj,k);521 JSValue* v = slot.getValue(exec, k); 522 522 523 523 List eachArguments; … … 550 550 551 551 for (unsigned k = 0; k < length && !exec->hadException(); ++k) { 552 PropertySlot slot ;552 PropertySlot slot(thisObj); 553 553 if (!thisObj->getPropertySlot(exec, k, slot)) 554 554 continue; 555 555 556 JSValue* v = slot.getValue(exec, thisObj,k);556 JSValue* v = slot.getValue(exec, k); 557 557 558 558 List eachArguments; … … 587 587 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 588 588 for (unsigned k = 0; k < length && !exec->hadException(); ++k) { 589 PropertySlot slot ;589 PropertySlot slot(thisObj); 590 590 591 591 if (!thisObj->getPropertySlot(exec, k, slot)) … … 594 594 List eachArguments; 595 595 596 eachArguments.append(slot.getValue(exec, thisObj,k));596 eachArguments.append(slot.getValue(exec, k)); 597 597 eachArguments.append(jsNumber(k)); 598 598 eachArguments.append(thisObj); … … 620 620 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 621 621 for (unsigned k = 0; k < length && !exec->hadException(); ++k) { 622 PropertySlot slot ;622 PropertySlot slot(thisObj); 623 623 if (!thisObj->getPropertySlot(exec, k, slot)) 624 624 continue; 625 625 626 626 List eachArguments; 627 eachArguments.append(slot.getValue(exec, thisObj,k));627 eachArguments.append(slot.getValue(exec, k)); 628 628 eachArguments.append(jsNumber(k)); 629 629 eachArguments.append(thisObj); … … 647 647 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 648 648 for (unsigned k = 0; k < length && !exec->hadException(); ++k) { 649 PropertySlot slot ;649 PropertySlot slot(thisObj); 650 650 if (!thisObj->getPropertySlot(exec, k, slot)) 651 651 continue; 652 652 653 653 List eachArguments; 654 eachArguments.append(slot.getValue(exec, thisObj,k));654 eachArguments.append(slot.getValue(exec, k)); 655 655 eachArguments.append(jsNumber(k)); 656 656 eachArguments.append(thisObj); -
trunk/JavaScriptCore/kjs/function.cpp
r34273 r34355 100 100 } 101 101 102 JSValue* FunctionImp::argumentsGetter(ExecState* exec, JSObject*,const Identifier&, const PropertySlot& slot)102 JSValue* FunctionImp::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 103 103 { 104 104 FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase()); … … 107 107 } 108 108 109 JSValue* FunctionImp::callerGetter(ExecState* exec, JSObject*,const Identifier&, const PropertySlot& slot)109 JSValue* FunctionImp::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 110 110 { 111 111 FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase()); … … 114 114 } 115 115 116 JSValue* FunctionImp::lengthGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot& slot)116 JSValue* FunctionImp::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot) 117 117 { 118 118 FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase()); … … 303 303 } 304 304 305 JSValue* Arguments::mappedIndexGetter(ExecState* exec, JSObject*,const Identifier& propertyName, const PropertySlot& slot)305 JSValue* Arguments::mappedIndexGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) 306 306 { 307 307 Arguments* thisObj = static_cast<Arguments*>(slot.slotBase()); -
trunk/JavaScriptCore/kjs/function.h
r33979 r34355 87 87 ScopeChain _scope; 88 88 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&); 92 92 }; 93 93 … … 116 116 static const ClassInfo info; 117 117 private: 118 static JSValue* mappedIndexGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot& slot);118 static JSValue* mappedIndexGetter(ExecState*, const Identifier&, const PropertySlot& slot); 119 119 120 120 JSActivation* _activationObject; -
trunk/JavaScriptCore/kjs/grammar.y
r34351 r34355 1095 1095 static AddNode* makeAddNode(ExpressionNode* left, ExpressionNode* right) 1096 1096 { 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);1108 1097 return new AddNode(left, right); 1109 1098 } … … 1111 1100 static LessNode* makeLessNode(ExpressionNode* left, ExpressionNode* right) 1112 1101 { 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 necessary1120 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.1125 1102 return new LessNode(left, right); 1126 1103 } -
trunk/JavaScriptCore/kjs/internal.cpp
r33979 r34355 84 84 } 85 85 86 JSObject* StringImp::toThisObject(ExecState* exec) const 87 { 88 return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this)); 89 } 90 86 91 // ------------------------------ NumberImp ------------------------------------ 87 92 … … 125 130 args.append(const_cast<NumberImp*>(this)); 126 131 return static_cast<JSObject *>(exec->lexicalGlobalObject()->numberConstructor()->construct(exec,args)); 132 } 133 134 JSObject* 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)); 127 139 } 128 140 … … 198 210 } 199 211 212 bool GetterSetterImp::getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) 213 { 214 ASSERT_NOT_REACHED(); 215 return false; 216 } 217 218 bool GetterSetterImp::getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) 219 { 220 ASSERT_NOT_REACHED(); 221 return false; 222 } 223 224 void GetterSetterImp::put(ExecState*, const Identifier&, JSValue*) 225 { 226 ASSERT_NOT_REACHED(); 227 } 228 229 void GetterSetterImp::put(ExecState*, unsigned, JSValue*) 230 { 231 ASSERT_NOT_REACHED(); 232 } 233 234 JSObject* GetterSetterImp::toThisObject(ExecState*) const 235 { 236 ASSERT_NOT_REACHED(); 237 return 0; 238 } 239 200 240 // ------------------------------ LabelStack ----------------------------------- 201 241 -
trunk/JavaScriptCore/kjs/internal.h
r33979 r34355 60 60 virtual JSObject *toObject(ExecState *exec) const; 61 61 virtual UString toString(ExecState*) const; 62 62 virtual JSObject* toThisObject(ExecState*) const; 63 63 64 UString val; 64 65 }; -
trunk/JavaScriptCore/kjs/lookup.h
r33038 r34355 84 84 * Helper for getStaticFunctionSlot and getStaticPropertySlot 85 85 */ 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) 87 87 { 88 88 // Look for cached value in dynamic map of properties (in JSObject) … … 103 103 */ 104 104 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) 106 106 { 107 107 ThisImp* thisObj = static_cast<ThisImp*>(slot.slotBase()); -
trunk/JavaScriptCore/kjs/math_object.cpp
r33038 r34355 201 201 202 202 if (isnan(arg2)) 203 return jsN umber(NaN);203 return jsNaN(); 204 204 if (isinf(arg2) && fabs(arg) == 1) 205 return jsN umber(NaN);205 return jsNaN(); 206 206 return jsNumber(pow(arg, arg2)); 207 207 } -
trunk/JavaScriptCore/kjs/nodes.cpp
r34351 r34355 46 46 namespace KJS { 47 47 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 #else58 #define UNLIKELY(x) x59 #endif60 61 48 #define KJS_CHECKEXCEPTION \ 62 49 if (UNLIKELY(exec->hadException())) \ … … 86 73 return; \ 87 74 } 88 89 #if !ASSERT_DISABLED90 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 #endif108 75 109 76 static inline bool isConstant(const LocalStorage& localStorage, size_t index) … … 236 203 } 237 204 238 double ExpressionNode::evaluateToNumber(OldInterpreterExecState* exec)239 {240 JSValue* value = evaluate(exec);241 KJS_CHECKEXCEPTIONNUMBER242 return value->toNumber(exec);243 }244 245 bool ExpressionNode::evaluateToBoolean(OldInterpreterExecState* exec)246 {247 JSValue* value = evaluate(exec);248 KJS_CHECKEXCEPTIONBOOLEAN249 return value->toBoolean(exec);250 }251 252 int32_t ExpressionNode::evaluateToInt32(OldInterpreterExecState* exec)253 {254 JSValue* value = evaluate(exec);255 KJS_CHECKEXCEPTIONNUMBER256 return value->toInt32(exec);257 }258 259 uint32_t ExpressionNode::evaluateToUInt32(OldInterpreterExecState* exec)260 {261 JSValue* value = evaluate(exec);262 KJS_CHECKEXCEPTIONNUMBER263 return value->toUInt32(exec);264 }265 266 205 static void substitute(UString& string, const UString& substring) KJS_FAST_CALL; 267 206 static void substitute(UString& string, const UString& substring) … … 289 228 } 290 229 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 0376 Debugger* dbg = exec->dynamicGlobalObject()->debugger();377 if (dbg && !dbg->hasHandledException(exec, exceptionValue))378 dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);379 #endif380 }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 390 230 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg) 391 231 { … … 436 276 } 437 277 438 JSValue* BreakpointCheckStatement::execute(OldInterpreterExecState* exec)439 {440 return m_statement->execute(exec);441 }442 443 278 void BreakpointCheckStatement::streamTo(SourceStream& stream) const 444 279 { … … 446 281 } 447 282 448 void BreakpointCheckStatement::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)449 {450 nodeStack.append(m_statement.get());451 }452 453 283 // ------------------------------ NullNode ------------------------------------- 454 284 … … 458 288 } 459 289 460 JSValue* NullNode::evaluate(OldInterpreterExecState* )461 {462 return jsNull();463 }464 465 290 // ------------------------------ FalseNode ---------------------------------- 466 291 … … 470 295 } 471 296 472 JSValue* FalseNode::evaluate(OldInterpreterExecState*)473 {474 return jsBoolean(false);475 }476 477 297 // ------------------------------ TrueNode ---------------------------------- 478 298 … … 482 302 } 483 303 484 JSValue* TrueNode::evaluate(OldInterpreterExecState*)485 {486 return jsBoolean(true);487 }488 489 304 // ------------------------------ NumberNode ----------------------------------- 490 305 … … 492 307 { 493 308 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 0510 }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);541 309 } 542 310 … … 547 315 // FIXME: should we try to atomize constant strings? 548 316 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();564 317 } 565 318 … … 573 326 } 574 327 575 JSValue* RegExpNode::evaluate(OldInterpreterExecState*)576 {577 ASSERT_NOT_REACHED();578 return 0;579 }580 581 328 // ------------------------------ ThisNode ------------------------------------- 582 329 … … 584 331 { 585 332 return generator.moveToDestinationIfNeeded(dst, generator.thisRegister()); 586 }587 588 // ECMA 11.1.1589 JSValue* ThisNode::evaluate(OldInterpreterExecState* exec)590 {591 return exec->thisValue();592 333 } 593 334 … … 600 341 601 342 return generator.emitResolve(generator.finalDestination(dst), m_ident); 602 }603 604 // ECMA 11.1.2 & 10.1.4605 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 chain615 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_CHECKEXCEPTIONNUMBER639 return v->toNumber(exec);640 }641 642 bool ResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)643 {644 JSValue* v = inlineEvaluate(exec);645 KJS_CHECKEXCEPTIONBOOLEAN646 return v->toBoolean(exec);647 }648 649 int32_t ResolveNode::evaluateToInt32(OldInterpreterExecState* exec)650 {651 JSValue* v = inlineEvaluate(exec);652 KJS_CHECKEXCEPTIONNUMBER653 return v->toInt32(exec);654 }655 656 uint32_t ResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)657 {658 JSValue* v = inlineEvaluate(exec);659 KJS_CHECKEXCEPTIONNUMBER660 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 else705 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 NDEBUG753 JSObject* scope = *iter;754 #endif755 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 chain802 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.4853 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_CHECKEXCEPTIONVALUE860 length += n->m_elision;861 array->put(exec, length++, val);862 }863 return array;864 343 } 865 344 … … 885 364 } 886 365 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.4894 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_CHECKEXCEPTIONVALUE902 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 915 366 // ------------------------------ ObjectLiteralNode ---------------------------- 916 367 … … 921 372 else 922 373 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.5932 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());938 374 } 939 375 … … 970 406 } 971 407 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.5980 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_CHECKEXCEPTIONVALUE987 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.51014 JSValue* PropertyNode::evaluate(OldInterpreterExecState*)1015 {1016 ASSERT(false);1017 return jsNull();1018 }1019 1020 408 // ------------------------------ BracketAccessorNode -------------------------------- 1021 409 … … 1028 416 } 1029 417 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.1a1037 JSValue* BracketAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)1038 {1039 JSValue* v1 = m_base->evaluate(exec);1040 KJS_CHECKEXCEPTIONVALUE1041 JSValue* v2 = m_subscript->evaluate(exec);1042 KJS_CHECKEXCEPTIONVALUE1043 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_CHECKEXCEPTIONNUMBER1059 return v->toNumber(exec);1060 }1061 1062 bool BracketAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)1063 {1064 JSValue* v = inlineEvaluate(exec);1065 KJS_CHECKEXCEPTIONBOOLEAN1066 return v->toBoolean(exec);1067 }1068 1069 int32_t BracketAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)1070 {1071 JSValue* v = inlineEvaluate(exec);1072 KJS_CHECKEXCEPTIONNUMBER1073 return v->toInt32(exec);1074 }1075 1076 uint32_t BracketAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)1077 {1078 JSValue* v = inlineEvaluate(exec);1079 KJS_CHECKEXCEPTIONNUMBER1080 return v->toUInt32(exec);1081 }1082 1083 418 // ------------------------------ DotAccessorNode -------------------------------- 1084 419 … … 1089 424 } 1090 425 1091 void DotAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)1092 {1093 nodeStack.append(m_base.get());1094 }1095 1096 // ECMA 11.2.1b1097 JSValue* DotAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)1098 {1099 JSValue* v = m_base->evaluate(exec);1100 KJS_CHECKEXCEPTIONVALUE1101 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_CHECKEXCEPTIONNUMBER1113 return v->toNumber(exec);1114 }1115 1116 bool DotAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)1117 {1118 JSValue* v = inlineEvaluate(exec);1119 KJS_CHECKEXCEPTIONBOOLEAN1120 return v->toBoolean(exec);1121 }1122 1123 int32_t DotAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)1124 {1125 JSValue* v = inlineEvaluate(exec);1126 KJS_CHECKEXCEPTIONNUMBER1127 return v->toInt32(exec);1128 }1129 1130 uint32_t DotAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)1131 {1132 JSValue* v = inlineEvaluate(exec);1133 KJS_CHECKEXCEPTIONNUMBER1134 return v->toUInt32(exec);1135 }1136 1137 426 // ------------------------------ ArgumentListNode ----------------------------- 1138 427 … … 1143 432 } 1144 433 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.41154 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_CHECKEXCEPTIONVOID1159 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 1171 434 // ------------------------------ NewExprNode ---------------------------------- 1172 435 … … 1175 438 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get()); 1176 439 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.21187 1188 JSValue* NewExprNode::inlineEvaluate(OldInterpreterExecState* exec)1189 {1190 JSValue* v = m_expr->evaluate(exec);1191 KJS_CHECKEXCEPTIONVALUE1192 1193 List argList;1194 if (m_args) {1195 m_args->evaluateList(exec, argList);1196 KJS_CHECKEXCEPTIONVALUE1197 }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_CHECKEXCEPTIONNUMBER1218 return v->toNumber(exec);1219 }1220 1221 bool NewExprNode::evaluateToBoolean(OldInterpreterExecState* exec)1222 {1223 JSValue* v = inlineEvaluate(exec);1224 KJS_CHECKEXCEPTIONBOOLEAN1225 return v->toBoolean(exec);1226 }1227 1228 int32_t NewExprNode::evaluateToInt32(OldInterpreterExecState* exec)1229 {1230 JSValue* v = inlineEvaluate(exec);1231 KJS_CHECKEXCEPTIONNUMBER1232 return v->toInt32(exec);1233 }1234 1235 uint32_t NewExprNode::evaluateToUInt32(OldInterpreterExecState* exec)1236 {1237 JSValue* v = inlineEvaluate(exec);1238 KJS_CHECKEXCEPTIONNUMBER1239 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 chain1255 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_CHECKEXCEPTIONVALUE1264 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_CHECKEXCEPTIONVALUE1276 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);1290 440 } 1291 441 … … 1298 448 } 1299 449 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 1310 450 RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst) 1311 451 { 1312 452 RefPtr<RegisterID> func = generator.emitNode(m_expr.get()); 1313 453 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.31323 JSValue* FunctionCallValueNode::evaluate(OldInterpreterExecState* exec)1324 {1325 JSValue* v = m_expr->evaluate(exec);1326 KJS_CHECKEXCEPTIONVALUE1327 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_CHECKEXCEPTIONVALUE1341 1342 JSObject* thisObj = exec->globalThisValue();1343 return func->callAsFunction(exec, thisObj, argList);1344 454 } 1345 455 … … 1362 472 } 1363 473 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 else1374 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.31385 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_CHECKEXCEPTIONNUMBER1402 return v->toNumber(exec);1403 }1404 1405 bool FunctionCallResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)1406 {1407 JSValue* v = inlineEvaluate(exec);1408 KJS_CHECKEXCEPTIONBOOLEAN1409 return v->toBoolean(exec);1410 }1411 1412 int32_t FunctionCallResolveNode::evaluateToInt32(OldInterpreterExecState* exec)1413 {1414 JSValue* v = inlineEvaluate(exec);1415 KJS_CHECKEXCEPTIONNUMBER1416 return v->toInt32(exec);1417 }1418 1419 uint32_t FunctionCallResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)1420 {1421 JSValue* v = inlineEvaluate(exec);1422 KJS_CHECKEXCEPTIONNUMBER1423 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_CHECKEXCEPTIONVALUE1442 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_CHECKEXCEPTIONNUMBER1456 return v->toNumber(exec);1457 }1458 1459 bool LocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)1460 {1461 JSValue* v = inlineEvaluate(exec);1462 KJS_CHECKEXCEPTIONBOOLEAN1463 return v->toBoolean(exec);1464 }1465 1466 int32_t LocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)1467 {1468 JSValue* v = inlineEvaluate(exec);1469 KJS_CHECKEXCEPTIONNUMBER1470 return v->toInt32(exec);1471 }1472 1473 uint32_t LocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)1474 {1475 JSValue* v = inlineEvaluate(exec);1476 KJS_CHECKEXCEPTIONNUMBER1477 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_CHECKEXCEPTIONVALUE1496 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_CHECKEXCEPTIONNUMBER1510 return v->toNumber(exec);1511 }1512 1513 bool ScopedVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)1514 {1515 JSValue* v = inlineEvaluate(exec);1516 KJS_CHECKEXCEPTIONBOOLEAN1517 return v->toBoolean(exec);1518 }1519 1520 int32_t ScopedVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)1521 {1522 JSValue* v = inlineEvaluate(exec);1523 KJS_CHECKEXCEPTIONNUMBER1524 return v->toInt32(exec);1525 }1526 1527 uint32_t ScopedVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)1528 {1529 JSValue* v = inlineEvaluate(exec);1530 KJS_CHECKEXCEPTIONNUMBER1531 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_CHECKEXCEPTIONNUMBER1551 return v->toNumber(exec);1552 }1553 1554 bool NonLocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)1555 {1556 JSValue* v = inlineEvaluate(exec);1557 KJS_CHECKEXCEPTIONBOOLEAN1558 return v->toBoolean(exec);1559 }1560 1561 int32_t NonLocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)1562 {1563 JSValue* v = inlineEvaluate(exec);1564 KJS_CHECKEXCEPTIONNUMBER1565 return v->toInt32(exec);1566 }1567 1568 uint32_t NonLocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)1569 {1570 JSValue* v = inlineEvaluate(exec);1571 KJS_CHECKEXCEPTIONNUMBER1572 return v->toUInt32(exec);1573 }1574 1575 474 RegisterID* FunctionCallBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) 1576 475 { … … 1581 480 } 1582 481 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.31591 JSValue* FunctionCallBracketNode::evaluate(OldInterpreterExecState* exec)1592 {1593 JSValue* baseVal = m_base->evaluate(exec);1594 KJS_CHECKEXCEPTIONVALUE1595 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 else1607 funcVal = jsUndefined();1608 } else {1609 Identifier ident(subscriptVal->toString(exec));1610 if (baseObj->getPropertySlot(exec, ident, slot))1611 funcVal = baseObj->get(exec, ident);1612 else1613 funcVal = jsUndefined();1614 }1615 1616 KJS_CHECKEXCEPTIONVALUE1617 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_CHECKEXCEPTIONVALUE1629 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 ActivationObject1636 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 1651 482 RegisterID* FunctionCallDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) 1652 483 { … … 1655 486 return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get()); 1656 487 } 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.31665 JSValue* FunctionCallDotNode::inlineEvaluate(OldInterpreterExecState* exec)1666 {1667 JSValue* baseVal = m_base->evaluate(exec);1668 KJS_CHECKEXCEPTIONVALUE1669 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_CHECKEXCEPTIONVALUE1674 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_CHECKEXCEPTIONVALUE1686 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 ActivationObject1693 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_CHECKEXCEPTIONNUMBER1705 return v->toNumber(exec);1706 }1707 1708 bool FunctionCallDotNode::evaluateToBoolean(OldInterpreterExecState* exec)1709 {1710 JSValue* v = inlineEvaluate(exec);1711 KJS_CHECKEXCEPTIONBOOLEAN1712 return v->toBoolean(exec);1713 }1714 1715 int32_t FunctionCallDotNode::evaluateToInt32(OldInterpreterExecState* exec)1716 {1717 JSValue* v = inlineEvaluate(exec);1718 KJS_CHECKEXCEPTIONNUMBER1719 return v->toInt32(exec);1720 }1721 1722 uint32_t FunctionCallDotNode::evaluateToUInt32(OldInterpreterExecState* exec)1723 {1724 JSValue* v = inlineEvaluate(exec);1725 KJS_CHECKEXCEPTIONNUMBER1726 return v->toUInt32(exec);1727 }1728 1729 // ECMA 11.31730 488 1731 489 // ------------------------------ PostfixResolveNode ---------------------------------- … … 1759 517 } 1760 518 1761 // Increment1762 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 else1769 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 chain1783 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 cause1789 // base (which must be an ActivationImp in such this case) to be torn1790 // off from the activation stack, in which case we need to get it again1791 // 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 // Decrement1826 519 RegisterID* PostDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst) 1827 520 { … … 1852 545 } 1853 546 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 else1861 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 chain1875 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 well1928 }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 1945 547 // ------------------------------ 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 }1952 548 1953 549 RegisterID* PostIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 1961 557 } 1962 558 1963 JSValue* PostIncBracketNode::evaluate(OldInterpreterExecState* exec)1964 {1965 JSValue* baseValue = m_base->evaluate(exec);1966 KJS_CHECKEXCEPTIONVALUE1967 JSValue* subscript = m_subscript->evaluate(exec);1968 KJS_CHECKEXCEPTIONVALUE1969 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_CHECKEXCEPTIONVALUE1977 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_CHECKEXCEPTIONVALUE1988 1989 JSValue* v2 = v->toJSNumber(exec);1990 base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));1991 return v2;1992 }1993 1994 559 RegisterID* PostDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) 1995 560 { … … 2002 567 } 2003 568 2004 JSValue* PostDecBracketNode::evaluate(OldInterpreterExecState* exec)2005 {2006 JSValue* baseValue = m_base->evaluate(exec);2007 KJS_CHECKEXCEPTIONVALUE2008 JSValue* subscript = m_subscript->evaluate(exec);2009 KJS_CHECKEXCEPTIONVALUE2010 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_CHECKEXCEPTIONVALUE2018 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_CHECKEXCEPTIONVALUE2028 2029 JSValue* v2 = v->toJSNumber(exec);2030 base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));2031 return v2;2032 }2033 2034 569 // ------------------------------ PostfixDotNode ---------------------------------- 2035 2036 void PostfixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)2037 {2038 nodeStack.append(m_base.get());2039 }2040 570 2041 571 RegisterID* PostIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 2048 578 } 2049 579 2050 JSValue* PostIncDotNode::evaluate(OldInterpreterExecState* exec)2051 {2052 JSValue* baseValue = m_base->evaluate(exec);2053 KJS_CHECKEXCEPTIONVALUE2054 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_CHECKEXCEPTIONVALUE2059 2060 JSValue* v2 = v->toJSNumber(exec);2061 base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));2062 return v2;2063 }2064 2065 580 RegisterID* PostDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) 2066 581 { … … 2072 587 } 2073 588 2074 JSValue* PostDecDotNode::evaluate(OldInterpreterExecState* exec)2075 {2076 JSValue* baseValue = m_base->evaluate(exec);2077 KJS_CHECKEXCEPTIONVALUE2078 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_CHECKEXCEPTIONVALUE2083 2084 JSValue* v2 = v->toJSNumber(exec);2085 base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));2086 return v2;2087 }2088 2089 589 // ------------------------------ PostfixErrorNode ----------------------------------- 2090 590 … … 2092 592 { 2093 593 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();2102 594 } 2103 595 … … 2111 603 RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident); 2112 604 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.12123 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 chain2134 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);2152 605 } 2153 606 … … 2161 614 } 2162 615 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_CHECKEXCEPTIONVALUE2173 JSValue* subscript = m_subscript->evaluate(exec);2174 KJS_CHECKEXCEPTIONVALUE2175 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 2186 616 // ------------------------------ DeleteDotNode ----------------------------------- 2187 617 … … 2192 622 } 2193 623 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_CHECKEXCEPTIONVALUE2204 2205 return jsBoolean(base->deleteProperty(exec, m_ident));2206 }2207 2208 624 // ------------------------------ DeleteValueNode ----------------------------------- 2209 625 … … 2216 632 } 2217 633 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_CHECKEXCEPTIONVALUE2227 2228 // delete on a non-location expression ignores the value and returns true2229 return jsBoolean(true);2230 }2231 2232 634 // ------------------------------ VoidNode ------------------------------------- 2233 635 … … 2238 640 } 2239 641 2240 void VoidNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)2241 {2242 nodeStack.append(m_expr.get());2243 }2244 2245 // ECMA 11.4.22246 JSValue* VoidNode::evaluate(OldInterpreterExecState* exec)2247 {2248 m_expr->evaluate(exec);2249 KJS_CHECKEXCEPTIONVALUE2250 2251 return jsUndefined();2252 }2253 2254 // ECMA 11.4.32255 2256 642 // ------------------------------ 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 treated2280 // 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 }2304 643 2305 644 RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 2313 652 } 2314 653 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 chain2322 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 2339 654 // ------------------------------ TypeOfValueNode ----------------------------------- 2340 655 … … 2344 659 return generator.emitTypeOf(generator.finalDestination(dst), src.get()); 2345 660 } 2346 2347 JSValue* TypeOfValueNode::evaluate(OldInterpreterExecState* exec)2348 {2349 JSValue* v = m_expr->evaluate(exec);2350 KJS_CHECKEXCEPTIONVALUE2351 2352 return typeStringForValue(v);2353 }2354 2355 // ECMA 11.4.4 and 11.4.52356 661 2357 662 // ------------------------------ PrefixResolveNode ---------------------------------- … … 2385 690 } 2386 691 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 else2394 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 chain2416 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 2439 692 RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst) 2440 693 { … … 2465 718 } 2466 719 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 else2474 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 chain2496 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 2551 720 // ------------------------------ 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 }2558 721 2559 722 RegisterID* PreIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 2568 731 } 2569 732 2570 JSValue* PreIncBracketNode::evaluate(OldInterpreterExecState* exec)2571 {2572 JSValue* baseValue = m_base->evaluate(exec);2573 KJS_CHECKEXCEPTIONVALUE2574 JSValue* subscript = m_subscript->evaluate(exec);2575 KJS_CHECKEXCEPTIONVALUE2576 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_CHECKEXCEPTIONVALUE2584 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_CHECKEXCEPTIONVALUE2595 2596 JSValue* n2 = jsNumber(v->toNumber(exec) + 1);2597 base->put(exec, propertyName, n2);2598 2599 return n2;2600 }2601 2602 733 RegisterID* PreDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) 2603 734 { … … 2612 743 } 2613 744 2614 JSValue* PreDecBracketNode::evaluate(OldInterpreterExecState* exec)2615 {2616 JSValue* baseValue = m_base->evaluate(exec);2617 KJS_CHECKEXCEPTIONVALUE2618 JSValue* subscript = m_subscript->evaluate(exec);2619 KJS_CHECKEXCEPTIONVALUE2620 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_CHECKEXCEPTIONVALUE2628 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_CHECKEXCEPTIONVALUE2639 2640 JSValue* n2 = jsNumber(v->toNumber(exec) - 1);2641 base->put(exec, propertyName, n2);2642 2643 return n2;2644 }2645 2646 745 // ------------------------------ PrefixDotNode ---------------------------------- 2647 2648 void PrefixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)2649 {2650 nodeStack.append(m_base.get());2651 }2652 746 2653 747 RegisterID* PreIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 2661 755 } 2662 756 2663 JSValue* PreIncDotNode::evaluate(OldInterpreterExecState* exec)2664 {2665 JSValue* baseValue = m_base->evaluate(exec);2666 KJS_CHECKEXCEPTIONVALUE2667 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_CHECKEXCEPTIONVALUE2672 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 2680 757 RegisterID* PreDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) 2681 758 { … … 2688 765 } 2689 766 2690 JSValue* PreDecDotNode::evaluate(OldInterpreterExecState* exec)2691 {2692 JSValue* baseValue = m_base->evaluate(exec);2693 KJS_CHECKEXCEPTIONVALUE2694 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_CHECKEXCEPTIONVALUE2699 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 2707 767 // ------------------------------ PrefixErrorNode ----------------------------------- 2708 768 … … 2710 770 { 2711 771 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();2720 772 } 2721 773 … … 2728 780 } 2729 781 2730 void UnaryPlusNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)2731 {2732 nodeStack.append(m_expr.get());2733 }2734 2735 // ECMA 11.4.62736 JSValue* UnaryPlusNode::evaluate(OldInterpreterExecState* exec)2737 {2738 JSValue* v = m_expr->evaluate(exec);2739 KJS_CHECKEXCEPTIONVALUE2740 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 2763 782 // ------------------------------ NegateNode ----------------------------------- 2764 783 … … 2769 788 } 2770 789 2771 void NegateNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)2772 {2773 nodeStack.append(m_expr.get());2774 }2775 2776 // ECMA 11.4.72777 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 2789 790 // ------------------------------ BitwiseNotNode ------------------------------- 2790 791 … … 2795 796 } 2796 797 2797 void BitwiseNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)2798 {2799 nodeStack.append(m_expr.get());2800 }2801 2802 // ECMA 11.4.82803 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 2833 798 // ------------------------------ LogicalNotNode ------------------------------- 2834 799 … … 2837 802 RegisterID* src = generator.emitNode(m_expr.get()); 2838 803 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.92847 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);2855 804 } 2856 805 … … 2864 813 } 2865 814 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.12873 double MultNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)2874 {2875 double n1 = m_term1->evaluateToNumber(exec);2876 KJS_CHECKEXCEPTIONNUMBER2877 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 well2895 }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 2907 815 RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst) 2908 816 { … … 2912 820 } 2913 821 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.22921 double DivNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)2922 {2923 double n1 = m_term1->evaluateToNumber(exec);2924 KJS_CHECKEXCEPTIONNUMBER2925 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 2949 822 RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst) 2950 823 { … … 2954 827 } 2955 828 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.32963 double ModNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)2964 {2965 double n1 = m_term1->evaluateToNumber(exec);2966 KJS_CHECKEXCEPTIONNUMBER2967 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 well2985 }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 2997 829 // ------------------------------ 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.63007 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 13043 // 247427 Add case: 5 53044 // 20901 Add case: 5 63045 // 13978 Add case: 5 13046 // 4000 Add case: 1 53047 // 1 Add case: 3 53048 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 uncommon3065 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 uncommon3084 return addSlowCaseToNumber(exec, v1, v2);3085 }3086 830 3087 831 RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 3092 836 } 3093 837 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.13101 JSValue* AddNode::evaluate(OldInterpreterExecState* exec)3102 {3103 JSValue* v1 = m_term1->evaluate(exec);3104 KJS_CHECKEXCEPTIONVALUE3105 3106 JSValue* v2 = m_term2->evaluate(exec);3107 KJS_CHECKEXCEPTIONVALUE3108 3109 return add(exec, v1, v2);3110 }3111 3112 double AddNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)3113 {3114 JSValue* v1 = m_term1->evaluate(exec);3115 KJS_CHECKEXCEPTIONNUMBER3116 3117 JSValue* v2 = m_term2->evaluate(exec);3118 KJS_CHECKEXCEPTIONNUMBER3119 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_CHECKEXCEPTIONNUMBER3142 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_CHECKEXCEPTIONVALUE3170 3171 JSValue* v2 = m_term2->evaluate(exec);3172 KJS_CHECKEXCEPTIONVALUE3173 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_CHECKEXCEPTIONVALUE3181 3182 JSValue* v2 = m_term2->evaluate(exec);3183 KJS_CHECKEXCEPTIONVALUE3184 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_CHECKEXCEPTIONVALUE3193 3194 JSValue* v2 = m_term2->evaluate(exec);3195 KJS_CHECKEXCEPTIONVALUE3196 3197 JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);3198 return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());3199 }3200 3201 838 RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3202 839 { … … 3206 843 } 3207 844 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.23215 double SubNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)3216 {3217 double n1 = m_term1->evaluateToNumber(exec);3218 KJS_CHECKEXCEPTIONNUMBER3219 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 3243 845 // ------------------------------ Shift Nodes ------------------------------------ 3244 846 … … 3250 852 } 3251 853 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.13259 int32_t LeftShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)3260 {3261 int i1 = m_term1->evaluateToInt32(exec);3262 KJS_CHECKEXCEPTIONNUMBER3263 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 3287 854 RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3288 855 { … … 3292 859 } 3293 860 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.23301 int32_t RightShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)3302 {3303 int i1 = m_term1->evaluateToInt32(exec);3304 KJS_CHECKEXCEPTIONNUMBER3305 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 3329 861 RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3330 862 { … … 3334 866 } 3335 867 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.33343 uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(OldInterpreterExecState* exec)3344 {3345 unsigned int i1 = m_term1->evaluateToUInt32(exec);3346 KJS_CHECKEXCEPTIONNUMBER3347 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 3371 868 // ------------------------------ 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 }3402 869 3403 870 RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 3408 875 } 3409 876 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.13417 bool LessNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3418 {3419 JSValue* v1 = m_expr1->evaluate(exec);3420 KJS_CHECKEXCEPTIONBOOLEAN3421 JSValue* v2 = m_expr2->evaluate(exec);3422 KJS_CHECKEXCEPTIONBOOLEAN3423 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_CHECKEXCEPTIONVALUE3440 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_CHECKEXCEPTIONVALUE3458 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 3472 877 RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3473 878 { … … 3477 882 } 3478 883 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.23486 bool GreaterNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3487 {3488 JSValue* v1 = m_expr1->evaluate(exec);3489 KJS_CHECKEXCEPTIONBOOLEAN3490 JSValue* v2 = m_expr2->evaluate(exec);3491 KJS_CHECKEXCEPTIONBOOLEAN3492 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 3505 884 RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3506 885 { … … 3510 889 } 3511 890 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.33519 bool LessEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3520 {3521 JSValue* v1 = m_expr1->evaluate(exec);3522 KJS_CHECKEXCEPTIONBOOLEAN3523 JSValue* v2 = m_expr2->evaluate(exec);3524 KJS_CHECKEXCEPTIONBOOLEAN3525 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 3538 891 RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3539 892 { … … 3543 896 } 3544 897 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.43552 bool GreaterEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3553 {3554 JSValue* v1 = m_expr1->evaluate(exec);3555 KJS_CHECKEXCEPTIONBOOLEAN3556 JSValue* v2 = m_expr2->evaluate(exec);3557 KJS_CHECKEXCEPTIONBOOLEAN3558 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 3571 898 RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3572 899 { … … 3576 903 } 3577 904 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.63585 JSValue* InstanceOfNode::evaluate(OldInterpreterExecState* exec)3586 {3587 JSValue* v1 = m_expr1->evaluate(exec);3588 KJS_CHECKEXCEPTIONVALUE3589 JSValue* v2 = m_expr2->evaluate(exec);3590 KJS_CHECKEXCEPTIONVALUE3591 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 this3600 // 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_CHECKEXCEPTIONBOOLEAN3611 JSValue* v2 = m_expr2->evaluate(exec);3612 KJS_CHECKEXCEPTIONBOOLEAN3613 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 this3624 // case we return false (consistent with Mozilla).3625 if (!o2->implementsHasInstance())3626 return false;3627 3628 return o2->hasInstance(exec, v1);3629 }3630 3631 905 RegisterID* InNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3632 906 { … … 3636 910 } 3637 911 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.73645 JSValue* InNode::evaluate(OldInterpreterExecState* exec)3646 {3647 JSValue* v1 = m_expr1->evaluate(exec);3648 KJS_CHECKEXCEPTIONVALUE3649 JSValue* v2 = m_expr2->evaluate(exec);3650 KJS_CHECKEXCEPTIONVALUE3651 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_CHECKEXCEPTIONBOOLEAN3662 JSValue* v2 = m_expr2->evaluate(exec);3663 KJS_CHECKEXCEPTIONBOOLEAN3664 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 3673 912 // ------------------------------ Equality Nodes ------------------------------------ 3674 913 … … 3680 919 } 3681 920 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.13689 bool EqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3690 {3691 JSValue* v1 = m_expr1->evaluate(exec);3692 KJS_CHECKEXCEPTIONBOOLEAN3693 JSValue* v2 = m_expr2->evaluate(exec);3694 KJS_CHECKEXCEPTIONBOOLEAN3695 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 3709 921 RegisterID* NotEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3710 922 { … … 3714 926 } 3715 927 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.23723 bool NotEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3724 {3725 JSValue* v1 = m_expr1->evaluate(exec);3726 KJS_CHECKEXCEPTIONBOOLEAN3727 JSValue* v2 = m_expr2->evaluate(exec);3728 KJS_CHECKEXCEPTIONBOOLEAN3729 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 3743 928 RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3744 929 { … … 3748 933 } 3749 934 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.43757 bool StrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3758 {3759 JSValue* v1 = m_expr1->evaluate(exec);3760 KJS_CHECKEXCEPTIONBOOLEAN3761 JSValue* v2 = m_expr2->evaluate(exec);3762 KJS_CHECKEXCEPTIONBOOLEAN3763 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 3777 935 RegisterID* NotStrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3778 936 { … … 3782 940 } 3783 941 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.53791 bool NotStrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)3792 {3793 JSValue* v1 = m_expr1->evaluate(exec);3794 KJS_CHECKEXCEPTIONBOOLEAN3795 JSValue* v2 = m_expr2->evaluate(exec);3796 KJS_CHECKEXCEPTIONBOOLEAN3797 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 3811 942 // ------------------------------ Bit Operation Nodes ---------------------------------- 3812 943 … … 3818 949 } 3819 950 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.103827 JSValue* BitAndNode::evaluate(OldInterpreterExecState* exec)3828 {3829 JSValue* v1 = m_expr1->evaluate(exec);3830 KJS_CHECKEXCEPTIONVALUE3831 JSValue* v2 = m_expr2->evaluate(exec);3832 KJS_CHECKEXCEPTIONVALUE3833 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_CHECKEXCEPTIONNUMBER3841 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 3865 951 RegisterID* BitXOrNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3866 952 { … … 3870 956 } 3871 957 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_CHECKEXCEPTIONNUMBER3882 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 3911 958 RegisterID* BitOrNode::emitCode(CodeGenerator& generator, RegisterID* dst) 3912 959 { … … 3914 961 RegisterID* src2 = generator.emitNode(m_expr2.get()); 3915 962 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_CHECKEXCEPTIONNUMBER3928 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);3955 963 } 3956 964 … … 3970 978 } 3971 979 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.113979 JSValue* LogicalAndNode::evaluate(OldInterpreterExecState* exec)3980 {3981 JSValue* v1 = m_expr1->evaluate(exec);3982 KJS_CHECKEXCEPTIONVALUE3983 bool b1 = v1->toBoolean(exec);3984 KJS_CHECKEXCEPTIONVALUE3985 if (!b1)3986 return v1;3987 JSValue* v2 = m_expr2->evaluate(exec);3988 KJS_CHECKEXCEPTIONVALUE3989 return v2;3990 }3991 3992 bool LogicalAndNode::evaluateToBoolean(OldInterpreterExecState* exec)3993 {3994 bool b = m_expr1->evaluateToBoolean(exec);3995 KJS_CHECKEXCEPTIONBOOLEAN3996 return b && m_expr2->evaluateToBoolean(exec);3997 }3998 3999 980 RegisterID* LogicalOrNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4000 981 { … … 4010 991 } 4011 992 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_CHECKEXCEPTIONVALUE4022 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_CHECKEXCEPTIONBOOLEAN4031 return b || m_expr2->evaluateToBoolean(exec);4032 }4033 4034 993 // ------------------------------ ConditionalNode ------------------------------ 4035 994 … … 4052 1011 4053 1012 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.124064 JSValue* ConditionalNode::evaluate(OldInterpreterExecState* exec)4065 {4066 bool b = m_logical->evaluateToBoolean(exec);4067 KJS_CHECKEXCEPTIONVALUE4068 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_CHECKEXCEPTIONBOOLEAN4075 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_CHECKEXCEPTIONNUMBER4082 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_CHECKEXCEPTIONNUMBER4089 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_CHECKEXCEPTIONNUMBER4096 return b ? m_expr1->evaluateToUInt32(exec) : m_expr2->evaluateToUInt32(exec);4097 }4098 4099 // ECMA 11.134100 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;4163 1013 } 4164 1014 … … 4237 1087 } 4238 1088 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 else4247 new (this) ReadModifyLocalVarNode(index);4248 }4249 }4250 4251 1089 // ------------------------------ AssignResolveNode ----------------------------------- 4252 1090 … … 4274 1112 } 4275 1113 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 ----------------------------------- 4416 1115 4417 1116 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 4424 1123 } 4425 1124 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 ----------------------------------- 4445 1126 4446 1127 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) … … 4453 1134 } 4454 1135 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_CHECKEXCEPTIONVALUE4465 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_CHECKEXCEPTIONVALUE4473 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);4474 4475 KJS_CHECKEXCEPTIONVALUE4476 4477 base->put(exec, m_ident, v);4478 return v;4479 }4480 4481 1136 // ------------------------------ AssignErrorNode ----------------------------------- 4482 1137 … … 4484 1139 { 4485 1140 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();4493 1141 } 4494 1142 … … 4505 1153 } 4506 1154 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_CHECKEXCEPTIONVALUE4518 JSValue* subscript = m_subscript->evaluate(exec);4519 KJS_CHECKEXCEPTIONVALUE4520 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_CHECKEXCEPTIONVALUE4527 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_CHECKEXCEPTIONVALUE4535 4536 base->put(exec, propertyName, v);4537 return v;4538 }4539 4540 1155 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4541 1156 { … … 4552 1167 } 4553 1168 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_CHECKEXCEPTIONVALUE4565 JSValue* subscript = m_subscript->evaluate(exec);4566 KJS_CHECKEXCEPTIONVALUE4567 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_CHECKEXCEPTIONVALUE4577 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);4578 4579 KJS_CHECKEXCEPTIONVALUE4580 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_CHECKEXCEPTIONVALUE4592 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);4593 4594 KJS_CHECKEXCEPTIONVALUE4595 4596 base->put(exec, propertyName, v);4597 return v;4598 }4599 4600 1169 // ------------------------------ CommaNode ------------------------------------ 4601 1170 … … 4604 1173 generator.emitNode(m_expr1.get()); 4605 1174 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.144615 JSValue* CommaNode::evaluate(OldInterpreterExecState* exec)4616 {4617 m_expr1->evaluate(exec);4618 KJS_CHECKEXCEPTIONVALUE4619 return m_expr2->evaluate(exec);4620 1175 } 4621 1176 … … 4626 1181 , m_init(init) 4627 1182 { 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 chain4644 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.24661 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_CHECKEXCEPTIONVOID4679 4680 // if the variable object is the top of the scope chain, then that must4681 // be where this variable is declared, processVarDecls would have put4682 // 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 }4689 1183 } 4690 1184 … … 4714 1208 } 4715 1209 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_CHECKEXCEPTIONVALUE4724 n = n->m_next.get();4725 } while (n);4726 }4727 return jsUndefined();4728 }4729 4730 1210 // ------------------------------ ConstStatementNode ----------------------------- 4731 1211 4732 void ConstStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)4733 {4734 ASSERT(m_next);4735 nodeStack.append(m_next.get());4736 }4737 4738 1212 RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*) 4739 1213 { 4740 1214 return generator.emitNode(m_next.get()); 4741 }4742 4743 // ECMA 12.24744 JSValue* ConstStatementNode::execute(OldInterpreterExecState* exec)4745 {4746 m_next->evaluate(exec);4747 KJS_CHECKEXCEPTION4748 4749 return exec->setNormalCompletion();4750 1215 } 4751 1216 … … 4794 1259 } 4795 1260 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 4810 1261 // ------------------------------ BlockNode ------------------------------------ 4811 1262 … … 4821 1272 } 4822 1273 4823 void BlockNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)4824 {4825 statementListPushFIFO(m_children, nodeStack);4826 }4827 4828 // ECMA 12.14829 JSValue* BlockNode::execute(OldInterpreterExecState* exec)4830 {4831 return statementListExecute(m_children, exec);4832 }4833 4834 1274 // ------------------------------ EmptyStatementNode --------------------------- 4835 1275 … … 4837 1277 { 4838 1278 return dst; 4839 }4840 4841 // ECMA 12.34842 JSValue* EmptyStatementNode::execute(OldInterpreterExecState* exec)4843 {4844 return exec->setNormalCompletion();4845 1279 } 4846 1280 … … 4866 1300 } 4867 1301 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.44875 JSValue* ExprStatementNode::execute(OldInterpreterExecState* exec)4876 {4877 JSValue* value = m_expr->evaluate(exec);4878 KJS_CHECKEXCEPTION4879 4880 return exec->setNormalCompletion(value);4881 }4882 4883 1302 // ------------------------------ VarStatementNode ---------------------------- 4884 1303 … … 4889 1308 } 4890 1309 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_CHECKEXCEPTION4901 4902 return exec->setNormalCompletion();4903 }4904 4905 1310 // ------------------------------ IfNode --------------------------------------- 4906 1311 … … 4919 1324 } 4920 1325 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.54928 JSValue* IfNode::execute(OldInterpreterExecState* exec)4929 {4930 bool b = m_condition->evaluateToBoolean(exec);4931 KJS_CHECKEXCEPTION4932 4933 if (b)4934 return m_ifBlock->execute(exec);4935 return exec->setNormalCompletion();4936 }4937 4938 1326 RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4939 1327 { … … 4954 1342 // FIXME: This should return the last statement exectuted so that it can be returned as a Completion 4955 1343 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.54965 JSValue* IfElseNode::execute(OldInterpreterExecState* exec)4966 {4967 bool b = m_condition->evaluateToBoolean(exec);4968 KJS_CHECKEXCEPTION4969 4970 if (b)4971 return m_ifBlock->execute(exec);4972 return m_elseBlock->execute(exec);4973 1344 } 4974 1345 … … 4994 1365 } 4995 1366 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.15003 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_CHECKEXCEPTION5029 if (!b)5030 break;5031 }5032 5033 return exec->setNormalCompletion(value);5034 }5035 5036 1367 // ------------------------------ WhileNode ------------------------------------ 5037 1368 … … 5059 1390 } 5060 1391 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.25068 JSValue* WhileNode::execute(OldInterpreterExecState* exec)5069 {5070 JSValue* value = 0;5071 5072 while (1) {5073 bool b = m_expr->evaluateToBoolean(exec);5074 KJS_CHECKEXCEPTION5075 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 5100 1392 // ------------------------------ ForNode -------------------------------------- 5101 1393 5102 1394 RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst) 5103 1395 { 5104 generator.emitNode(m_expr1.get()); 1396 if (m_expr1) 1397 generator.emitNode(m_expr1.get()); 5105 1398 5106 1399 RefPtr<LabelID> topOfLoop = generator.newLabel(); … … 5114 1407 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get()); 5115 1408 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()); 5118 1412 5119 1413 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 } 5122 1420 generator.emitLabel(breakTarget.get()); 5123 1421 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.35135 JSValue* ForNode::execute(OldInterpreterExecState* exec)5136 {5137 JSValue* value = 0;5138 5139 m_expr1->evaluate(exec);5140 KJS_CHECKEXCEPTION5141 5142 while (1) {5143 bool b = m_expr2->evaluateToBoolean(exec);5144 KJS_CHECKEXCEPTION5145 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_CHECKEXCEPTION5168 }5169 5170 return exec->setNormalCompletion(value);5171 1422 } 5172 1423 … … 5192 1443 m_init = new AssignResolveNode(ident, in, true); 5193 1444 // 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());5203 1445 } 5204 1446 … … 5252 1494 } 5253 1495 5254 // ECMA 12.6.45255 JSValue* ForInNode::execute(OldInterpreterExecState* exec)5256 {5257 JSValue* value = 0;5258 5259 if (m_init) {5260 m_init->evaluate(exec);5261 KJS_CHECKEXCEPTION5262 }5263 5264 JSValue* e = m_expr->evaluate(exec);5265 KJS_CHECKEXCEPTION5266 5267 // For Null and Undefined, we want to make sure not to go through5268 // 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 chain5292 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_CHECKEXCEPTION5311 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_CHECKEXCEPTION5318 JSValue* v2 = static_cast<BracketAccessorNode*>(m_lexpr.get())->subscript()->evaluate(exec);5319 KJS_CHECKEXCEPTION5320 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_CHECKEXCEPTION5329 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 5351 1496 // ------------------------------ ContinueNode --------------------------------- 5352 1497 … … 5374 1519 } 5375 1520 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 5385 1521 // ------------------------------ BreakNode ------------------------------------ 5386 1522 … … 5405 1541 5406 1542 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);5416 1543 } 5417 1544 … … 5433 1560 } 5434 1561 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.95442 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_CHECKEXCEPTION5453 5454 return exec->setReturnValueCompletion(v);5455 }5456 5457 1562 // ------------------------------ WithNode ------------------------------------- 5458 1563 … … 5464 1569 generator.emitPopScope(); 5465 1570 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.105475 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.115491 JSValue* CaseClauseNode::evaluate(OldInterpreterExecState* exec)5492 {5493 JSValue* v = m_expr->evaluate(exec);5494 KJS_CHECKEXCEPTIONVALUE5495 5496 return v;5497 }5498 5499 // ECMA 12.115500 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());5512 1571 } 5513 1572 … … 5562 1621 } 5563 1622 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.115575 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_CHECKEXCEPTION5583 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_CHECKEXCEPTION5602 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 clause5611 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 error5627 KJS_CHECKEXCEPTION5628 5629 return exec->setNormalCompletion();5630 }5631 5632 1623 // ------------------------------ SwitchNode ----------------------------------- 5633 1624 … … 5646 1637 } 5647 1638 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.115655 JSValue* SwitchNode::execute(OldInterpreterExecState* exec)5656 {5657 JSValue* v = m_expr->evaluate(exec);5658 KJS_CHECKEXCEPTION5659 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 5669 1639 // ------------------------------ LabelNode ------------------------------------ 1640 5670 1641 RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst) 5671 1642 { … … 5686 1657 } 5687 1658 5688 void LabelNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)5689 {5690 nodeStack.append(m_statement.get());5691 }5692 5693 // ECMA 12.125694 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 5706 1659 // ------------------------------ ThrowNode ------------------------------------ 5707 1660 … … 5710 1663 generator.emitThrow(generator.emitNode(dst, m_expr.get())); 5711 1664 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.135720 JSValue* ThrowNode::execute(OldInterpreterExecState* exec)5721 {5722 JSValue* v = m_expr->evaluate(exec);5723 KJS_CHECKEXCEPTION5724 5725 handleException(exec, v);5726 return exec->setThrowCompletion(v);5727 1665 } 5728 1666 … … 5785 1723 5786 1724 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.145796 JSValue* TryNode::execute(OldInterpreterExecState*)5797 {5798 ASSERT_NOT_REACHED();5799 return 0;5800 }5801 5802 1725 // ------------------------------ FunctionBodyNode ----------------------------- 5803 1726 … … 5942 1865 } 5943 1866 5944 void ProgramNode::initializeSymbolTable(OldInterpreterExecState* exec)5945 {5946 // If a previous script defined a symbol with the same name as one of our5947 // symbols, to avoid breaking previously optimized nodes, we need to reuse5948 // the symbol's existing storage index. So, we can't be as efficient as5949 // FunctionBodyNode::initializeSymbolTable, which knows that no bindings5950 // 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, including6021 // 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 temporarily6031 // 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 the6037 // 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 SunSpider6072 // 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 6095 1867 UString FunctionBodyNode::paramString() const 6096 1868 { … … 6106 1878 } 6107 1879 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 6134 1880 // ------------------------------ FuncDeclNode --------------------------------- 6135 1881 … … 6154 1900 { 6155 1901 return dst; 6156 }6157 6158 JSValue* FuncDeclNode::execute(OldInterpreterExecState* exec)6159 {6160 return exec->setNormalCompletion();6161 1902 } 6162 1903 … … 6199 1940 } 6200 1941 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 should6211 // 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 6229 1942 } // namespace KJS -
trunk/JavaScriptCore/kjs/nodes.h
r34351 r34355 184 184 virtual bool needsParensIfLeftmost() const { return false; } 185 185 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 189 186 protected: 190 187 Node(JSType) KJS_FAST_CALL; // used by ExpressionNode 191 188 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 205 189 RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg); 206 190 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;215 191 216 192 int m_line : 28; … … 240 216 JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); } 241 217 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 relevance249 virtual void optimizeForUnnecessaryResult() { }250 251 218 // This needs to be in public in order to compile using GCC 3.x 252 219 typedef enum { EvalOperator, FunctionCall } CallerType; 253 protected:254 template <CallerType, bool> inline JSValue* resolveAndCall(OldInterpreterExecState*, const Identifier&, ArgumentsNode*, size_t = 0);255 220 }; 256 221 … … 262 227 int lastLine() const KJS_FAST_CALL { return m_lastLine; } 263 228 264 virtual JSValue* execute(OldInterpreterExecState *exec) KJS_FAST_CALL = 0;265 266 229 virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); } 267 230 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } … … 284 247 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 285 248 286 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;287 249 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 288 250 virtual Precedence precedence() const { return PrecPrimary; } … … 298 260 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 299 261 300 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;301 virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL { return false; }302 262 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 303 263 virtual Precedence precedence() const { return PrecPrimary; } … … 313 273 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 314 274 315 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;316 virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL { return true; }317 275 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 318 276 virtual Precedence precedence() const { return PrecPrimary; } … … 340 298 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 341 299 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;347 300 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 348 301 virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; } … … 365 318 } 366 319 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 371 320 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); } 372 321 … … 385 334 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 386 335 387 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;388 virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;389 virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;390 336 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 391 337 virtual Precedence precedence() const { return PrecPrimary; } … … 404 350 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 405 351 406 JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;407 352 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 408 353 virtual Precedence precedence() const { return PrecPrimary; } … … 420 365 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 421 366 422 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;423 367 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 424 368 virtual Precedence precedence() const { return PrecPrimary; } … … 440 384 441 385 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 449 387 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 450 388 virtual Precedence precedence() const { return PrecPrimary; } … … 455 393 456 394 protected: 457 ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);458 395 Identifier m_ident; 459 396 int m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode. … … 461 398 }; 462 399 463 class LocalVarAccessNode : public ResolveNode {464 public:465 // Overwrites a ResolveNode in place.466 LocalVarAccessNode(int i) KJS_FAST_CALL467 : 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_CALL487 : 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_CALL508 : 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 524 400 class ElementNode : public Node { 525 401 public: … … 539 415 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 540 416 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 541 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;542 417 543 418 PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 544 545 JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;546 419 547 420 private: … … 576 449 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 577 450 578 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;579 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;580 451 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 581 452 virtual Precedence precedence() const { return PrecPrimary; } … … 598 469 } 599 470 600 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;601 471 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 602 472 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 603 473 604 JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;605 474 const Identifier& name() const { return m_name; } 606 475 … … 626 495 627 496 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 628 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;629 497 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 630 498 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 631 499 632 JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;633 500 PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 634 501 … … 651 518 652 519 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;655 520 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 656 521 virtual Precedence precedence() const { return PrecPrimary; } … … 671 536 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 672 537 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;679 538 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 680 539 virtual Precedence precedence() const { return PrecMember; } … … 686 545 687 546 private: 688 ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);689 690 547 RefPtr<ExpressionNode> m_base; 691 548 RefPtr<ExpressionNode> m_subscript; … … 701 558 702 559 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;709 560 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 710 561 virtual Precedence precedence() const { return PrecMember; } … … 716 567 717 568 private: 718 ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);719 720 569 RefPtr<ExpressionNode> m_base; 721 570 Identifier m_ident; … … 736 585 737 586 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 738 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;739 587 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 740 588 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 741 589 742 void evaluateList(OldInterpreterExecState*, List&) KJS_FAST_CALL;743 590 PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); } 744 591 … … 758 605 } 759 606 760 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;761 607 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 762 608 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); }765 609 766 610 RefPtr<ArgumentListNode> m_listNode; … … 782 626 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 783 627 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;790 628 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 791 629 virtual Precedence precedence() const { return PrecLeftHandSide; } 792 630 793 631 private: 794 ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);795 796 632 RefPtr<ExpressionNode> m_expr; 797 633 RefPtr<ArgumentsNode> m_args; … … 806 642 807 643 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;810 644 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 811 645 virtual Precedence precedence() const { return PrecCall; } … … 824 658 825 659 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;828 660 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 829 661 virtual Precedence precedence() const { return PrecCall; } … … 851 683 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 852 684 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;859 685 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 860 686 virtual Precedence precedence() const { return PrecCall; } 861 687 862 688 protected: 863 ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);864 865 689 Identifier m_ident; 866 690 RefPtr<ArgumentsNode> m_args; … … 869 693 }; 870 694 871 class LocalVarFunctionCallNode : public FunctionCallResolveNode {872 public:873 LocalVarFunctionCallNode(int i) KJS_FAST_CALL874 : 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_CALL893 : 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_CALL913 : 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 928 695 class FunctionCallBracketNode : public ExpressionNode { 929 696 public: … … 936 703 937 704 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;940 705 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 941 706 virtual Precedence precedence() const { return PrecCall; } … … 957 722 958 723 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;965 724 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 966 725 virtual Precedence precedence() const { return PrecCall; } 967 726 968 727 private: 969 ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);970 971 728 RefPtr<ExpressionNode> m_base; 972 729 Identifier m_ident; … … 1006 763 1007 764 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;1010 765 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1011 766 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_CALL1018 : 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_CALL1031 : PostIncResolveNode(PlacementNewAdopt)1032 {1033 ASSERT(i != missingSymbolMarker());1034 m_index = i;1035 }1036 1037 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1038 767 }; 1039 768 … … 1052 781 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1053 782 1054 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1055 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1056 783 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1057 784 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_CALL1064 : 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_CALL1084 : PostDecResolveNode(PlacementNewAdopt)1085 {1086 ASSERT(i != missingSymbolMarker());1087 m_index = i;1088 }1089 1090 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1091 785 }; 1092 786 … … 1099 793 } 1100 794 1101 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1102 795 virtual Precedence precedence() const { return PrecPostfix; } 1103 796 … … 1116 809 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1117 810 1118 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1119 811 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1120 812 }; … … 1129 821 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1130 822 1131 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1132 823 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1133 824 }; … … 1141 832 } 1142 833 1143 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1144 834 virtual Precedence precedence() const { return PrecPostfix; } 1145 835 … … 1158 848 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1159 849 1160 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1161 850 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1162 851 }; … … 1171 860 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1172 861 1173 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1174 862 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1175 863 }; … … 1184 872 1185 873 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1186 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1187 874 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1188 875 virtual Precedence precedence() const { return PrecPostfix; } … … 1208 895 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1209 896 1210 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1211 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1212 897 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1213 898 virtual Precedence precedence() const { return PrecUnary; } … … 1215 900 private: 1216 901 Identifier m_ident; 1217 };1218 1219 class LocalVarDeleteNode : public DeleteResolveNode {1220 public:1221 LocalVarDeleteNode() KJS_FAST_CALL1222 : DeleteResolveNode(PlacementNewAdopt)1223 {1224 }1225 1226 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1227 902 }; 1228 903 … … 1237 912 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1238 913 1239 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1240 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1241 914 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1242 915 virtual Precedence precedence() const { return PrecUnary; } … … 1257 930 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1258 931 1259 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1260 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1261 932 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1262 933 virtual Precedence precedence() const { return PrecUnary; } … … 1276 947 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1277 948 1278 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1279 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1280 949 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1281 950 virtual Precedence precedence() const { return PrecUnary; } … … 1294 963 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1295 964 1296 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1297 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1298 965 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1299 966 virtual Precedence precedence() const { return PrecUnary; } … … 1320 987 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1321 988 1322 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1323 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1324 989 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1325 990 virtual Precedence precedence() const { return PrecUnary; } … … 1332 997 }; 1333 998 1334 class LocalVarTypeOfNode : public TypeOfResolveNode {1335 public:1336 LocalVarTypeOfNode(int i) KJS_FAST_CALL1337 : 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 1347 999 class TypeOfValueNode : public ExpressionNode { 1348 1000 public: … … 1355 1007 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1356 1008 1357 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1358 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1359 1009 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1360 1010 virtual Precedence precedence() const { return PrecUnary; } … … 1378 1028 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1379 1029 1380 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1381 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1382 1030 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1383 1031 virtual Precedence precedence() const { return PrecUnary; } 1384 };1385 1386 class PreIncLocalVarNode : public PreIncResolveNode {1387 public:1388 PreIncLocalVarNode(int i) KJS_FAST_CALL1389 : 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_CALL1401 : PreIncResolveNode(PlacementNewAdopt)1402 {1403 ASSERT(i != missingSymbolMarker());1404 m_index = i;1405 }1406 1407 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1408 1032 }; 1409 1033 … … 1422 1046 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1423 1047 1424 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1425 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1426 1048 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1427 1049 virtual Precedence precedence() const { return PrecUnary; } 1428 };1429 1430 class PreDecLocalVarNode : public PreDecResolveNode {1431 public:1432 PreDecLocalVarNode(int i) KJS_FAST_CALL1433 : 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_CALL1445 : PreDecResolveNode(PlacementNewAdopt)1446 {1447 ASSERT(i != missingSymbolMarker());1448 m_index = i;1449 }1450 1451 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1452 1050 }; 1453 1051 … … 1460 1058 } 1461 1059 1462 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1463 1060 virtual Precedence precedence() const { return PrecUnary; } 1464 1061 … … 1477 1074 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1478 1075 1479 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1480 1076 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1481 1077 }; … … 1490 1086 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1491 1087 1492 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1493 1088 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1494 1089 }; … … 1502 1097 } 1503 1098 1504 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;1505 1099 virtual Precedence precedence() const { return PrecPostfix; } 1506 1100 … … 1519 1113 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1520 1114 1521 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1522 1115 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1523 1116 }; … … 1532 1125 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1533 1126 1534 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1535 1127 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1536 1128 }; … … 1545 1137 1546 1138 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1547 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1548 1139 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1549 1140 virtual Precedence precedence() const { return PrecUnary; } … … 1563 1154 1564 1155 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;1571 1156 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1572 1157 virtual Precedence precedence() const { return PrecUnary; } … … 1585 1170 1586 1171 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;1590 1172 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1591 1173 virtual Precedence precedence() const { return PrecUnary; } … … 1604 1186 1605 1187 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;1612 1188 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1613 1189 virtual Precedence precedence() const { return PrecUnary; } 1614 1190 1615 1191 private: 1616 ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);1617 1618 1192 RefPtr<ExpressionNode> m_expr; 1619 1193 }; … … 1628 1202 1629 1203 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;1633 1204 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1634 1205 virtual Precedence precedence() const { return PrecUnary; } … … 1648 1219 1649 1220 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;1656 1221 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1657 1222 virtual Precedence precedence() const { return PrecMultiplicitave; } 1658 1223 1659 1224 private: 1660 ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);1661 1662 1225 RefPtr<ExpressionNode> m_term1; 1663 1226 RefPtr<ExpressionNode> m_term2; … … 1674 1237 1675 1238 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;1681 1239 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1682 1240 virtual Precedence precedence() const { return PrecMultiplicitave; } 1683 1241 1684 1242 private: 1685 ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);1686 1687 1243 RefPtr<ExpressionNode> m_term1; 1688 1244 RefPtr<ExpressionNode> m_term2; … … 1699 1255 1700 1256 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;1707 1257 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1708 1258 virtual Precedence precedence() const { return PrecMultiplicitave; } 1709 1259 1710 1260 private: 1711 ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);1712 1713 1261 RefPtr<ExpressionNode> m_term1; 1714 1262 RefPtr<ExpressionNode> m_term2; … … 1724 1272 1725 1273 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;1731 1274 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1732 1275 virtual Precedence precedence() const { return PrecAdditive; } … … 1742 1285 RefPtr<ExpressionNode> m_term1; 1743 1286 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_CALL1752 : 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_CALL1768 : 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_CALL1778 : 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_CALL1788 : AddNode(term1, term2, StringType)1789 {1790 }1791 1792 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;1793 1287 }; 1794 1288 … … 1803 1297 1804 1298 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;1810 1299 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1811 1300 virtual Precedence precedence() const { return PrecAdditive; } 1812 1301 1813 1302 private: 1814 ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);1815 1816 1303 RefPtr<ExpressionNode> m_term1; 1817 1304 RefPtr<ExpressionNode> m_term2; … … 1828 1315 1829 1316 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;1835 1317 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1836 1318 virtual Precedence precedence() const { return PrecShift; } 1837 1319 1838 1320 private: 1839 ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);1840 1841 1321 RefPtr<ExpressionNode> m_term1; 1842 1322 RefPtr<ExpressionNode> m_term2; … … 1853 1333 1854 1334 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;1860 1335 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1861 1336 virtual Precedence precedence() const { return PrecShift; } 1862 1337 1863 1338 private: 1864 ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);1865 1866 1339 RefPtr<ExpressionNode> m_term1; 1867 1340 RefPtr<ExpressionNode> m_term2; … … 1878 1351 1879 1352 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;1885 1353 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1886 1354 virtual Precedence precedence() const { return PrecShift; } 1887 private: 1888 ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(OldInterpreterExecState*); 1889 1355 1356 private: 1890 1357 RefPtr<ExpressionNode> m_term1; 1891 1358 RefPtr<ExpressionNode> m_term2; … … 1902 1369 1903 1370 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;1907 1371 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1908 1372 virtual Precedence precedence() const { return PrecRelational; } 1909 1910 private:1911 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);1912 1373 1913 1374 protected: … … 1916 1377 }; 1917 1378 1918 class LessNumbersNode : public LessNode {1919 public:1920 LessNumbersNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL1921 : 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_CALL1935 : 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 1946 1379 class GreaterNode : public ExpressionNode { 1947 1380 public: … … 1953 1386 1954 1387 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;1958 1388 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1959 1389 virtual Precedence precedence() const { return PrecRelational; } 1960 1390 1961 1391 private: 1962 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);1963 1964 1392 RefPtr<ExpressionNode> m_expr1; 1965 1393 RefPtr<ExpressionNode> m_expr2; … … 1975 1403 1976 1404 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;1980 1405 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1981 1406 virtual Precedence precedence() const { return PrecRelational; } 1982 1407 1983 1408 private: 1984 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);1985 1986 1409 RefPtr<ExpressionNode> m_expr1; 1987 1410 RefPtr<ExpressionNode> m_expr2; … … 1997 1420 1998 1421 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;2002 1422 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2003 1423 virtual Precedence precedence() const { return PrecRelational; } 2004 1424 2005 1425 private: 2006 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2007 2008 1426 RefPtr<ExpressionNode> m_expr1; 2009 1427 RefPtr<ExpressionNode> m_expr2; … … 2020 1438 2021 1439 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;2025 1440 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2026 1441 virtual Precedence precedence() const { return PrecRelational; } … … 2041 1456 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2042 1457 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;2046 1458 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2047 1459 virtual Precedence precedence() const { return PrecRelational; } … … 2062 1474 2063 1475 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;2067 1476 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2068 1477 virtual Precedence precedence() const { return PrecEquality; } 2069 1478 2070 1479 private: 2071 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2072 2073 1480 RefPtr<ExpressionNode> m_expr1; 2074 1481 RefPtr<ExpressionNode> m_expr2; … … 2085 1492 2086 1493 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;2090 1494 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2091 1495 virtual Precedence precedence() const { return PrecEquality; } 2092 1496 2093 1497 private: 2094 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2095 2096 1498 RefPtr<ExpressionNode> m_expr1; 2097 1499 RefPtr<ExpressionNode> m_expr2; … … 2108 1510 2109 1511 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;2113 1512 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2114 1513 virtual Precedence precedence() const { return PrecEquality; } 2115 1514 2116 1515 private: 2117 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2118 2119 1516 RefPtr<ExpressionNode> m_expr1; 2120 1517 RefPtr<ExpressionNode> m_expr2; … … 2131 1528 2132 1529 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;2136 1530 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2137 1531 virtual Precedence precedence() const { return PrecEquality; } 2138 1532 2139 1533 private: 2140 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2141 2142 1534 RefPtr<ExpressionNode> m_expr1; 2143 1535 RefPtr<ExpressionNode> m_expr2; … … 2154 1546 2155 1547 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;2162 1548 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2163 1549 virtual Precedence precedence() const { return PrecBitwiseAnd; } 2164 1550 2165 1551 private: 2166 ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);2167 2168 1552 RefPtr<ExpressionNode> m_expr1; 2169 1553 RefPtr<ExpressionNode> m_expr2; … … 2180 1564 2181 1565 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;2188 1566 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2189 1567 virtual Precedence precedence() const { return PrecBitwiseOr; } 2190 1568 2191 1569 private: 2192 ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);2193 2194 1570 RefPtr<ExpressionNode> m_expr1; 2195 1571 RefPtr<ExpressionNode> m_expr2; … … 2206 1582 2207 1583 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;2214 1584 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2215 1585 virtual Precedence precedence() const { return PrecBitwiseXor; } 2216 1586 2217 1587 private: 2218 ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);2219 2220 1588 RefPtr<ExpressionNode> m_expr1; 2221 1589 RefPtr<ExpressionNode> m_expr2; … … 2235 1603 2236 1604 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;2240 1605 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2241 1606 virtual Precedence precedence() const { return PrecLogicalAnd; } 2242 1607 2243 1608 private: 2244 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2245 2246 1609 RefPtr<ExpressionNode> m_expr1; 2247 1610 RefPtr<ExpressionNode> m_expr2; … … 2258 1621 2259 1622 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;2263 1623 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2264 1624 virtual Precedence precedence() const { return PrecLogicalOr; } 2265 1625 2266 1626 private: 2267 ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);2268 2269 1627 RefPtr<ExpressionNode> m_expr1; 2270 1628 RefPtr<ExpressionNode> m_expr2; … … 2284 1642 2285 1643 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;2292 1644 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2293 1645 virtual Precedence precedence() const { return PrecConditional; } … … 2319 1671 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2320 1672 2321 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2322 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2323 1673 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2324 1674 virtual Precedence precedence() const { return PrecAssignment; } … … 2332 1682 }; 2333 1683 2334 class ReadModifyLocalVarNode : public ReadModifyResolveNode {2335 public:2336 ReadModifyLocalVarNode(int i) KJS_FAST_CALL2337 : 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_CALL2349 : ReadModifyResolveNode(PlacementNewAdopt)2350 {2351 ASSERT(i != missingSymbolMarker());2352 m_index = i;2353 }2354 2355 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2356 };2357 2358 1684 class AssignResolveNode : public ExpressionNode { 2359 1685 public: … … 2374 1700 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2375 1701 2376 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2377 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2378 1702 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2379 1703 virtual Precedence precedence() const { return PrecAssignment; } … … 2384 1708 size_t m_index; // Used by ReadModifyLocalVarNode. 2385 1709 bool m_rightHasAssignments; 2386 };2387 2388 class AssignLocalVarNode : public AssignResolveNode {2389 public:2390 AssignLocalVarNode(int i) KJS_FAST_CALL2391 : 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_CALL2403 : AssignResolveNode(PlacementNewAdopt)2404 {2405 }2406 2407 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2408 1710 }; 2409 1711 … … 2422 1724 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2423 1725 2424 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2425 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2426 1726 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2427 1727 virtual Precedence precedence() const { return PrecAssignment; } … … 2449 1749 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2450 1750 2451 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2452 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2453 1751 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2454 1752 virtual Precedence precedence() const { return PrecAssignment; } … … 2473 1771 2474 1772 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;2477 1773 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2478 1774 virtual Precedence precedence() const { return PrecAssignment; } … … 2498 1794 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2499 1795 2500 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2501 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2502 1796 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2503 1797 virtual Precedence precedence() const { return PrecAssignment; } … … 2521 1815 2522 1816 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2523 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;2524 1817 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2525 1818 virtual Precedence precedence() const { return PrecAssignment; } … … 2537 1830 , m_expr2(expr2) 2538 1831 { 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; 2545 1835 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2546 1836 virtual Precedence precedence() const { return PrecExpression; } … … 2564 1854 ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL; 2565 1855 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;2569 1856 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2570 1857 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } … … 2577 1864 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2578 1865 virtual RegisterID* emitCodeSingle(CodeGenerator&) KJS_FAST_CALL; 2579 private:2580 void handleSlowCase(OldInterpreterExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;2581 1866 }; 2582 1867 … … 2588 1873 } 2589 1874 2590 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2591 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2592 1875 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2593 1876 2594 1877 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 1878 2595 1879 private: 2596 1880 RefPtr<ConstDeclNode> m_next; … … 2617 1901 2618 1902 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;2621 1903 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2622 1904 … … 2635 1917 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2636 1918 2637 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2638 1919 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2639 1920 virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; } … … 2660 1941 2661 1942 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;2664 1943 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2665 1944 … … 2677 1956 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2678 1957 2679 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2680 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2681 1958 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2682 1959 … … 2694 1971 2695 1972 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;2698 1973 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2699 1974 … … 2712 1987 2713 1988 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;2716 1989 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2717 1990 … … 2729 2002 2730 2003 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;2733 2004 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2734 2005 … … 2747 2018 2748 2019 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;2751 2020 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2752 2021 … … 2759 2028 public: 2760 2029 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) 2764 2033 , m_statement(statement) 2765 2034 , m_expr1WasVarDecl(expr1 && expr1WasVarDecl) 2766 2035 { 2767 ASSERT(m_expr1);2768 ASSERT(m_expr2);2769 ASSERT(m_expr3);2770 2036 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; 2779 2040 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2780 2041 … … 2793 2054 2794 2055 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;2797 2056 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2798 2057 … … 2818 2077 2819 2078 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2820 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2821 2079 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2822 2080 … … 2837 2095 2838 2096 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2839 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2840 2097 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2841 2098 … … 2852 2109 2853 2110 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;2856 2111 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2857 2112 virtual bool isReturnNode() const KJS_FAST_CALL { return true; } … … 2870 2125 2871 2126 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;2874 2127 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2875 2128 … … 2888 2141 2889 2142 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;2892 2143 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2893 2144 virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_statement->pushLabel(ident); } … … 2906 2157 2907 2158 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;2910 2159 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2911 2160 … … 2924 2173 } 2925 2174 2926 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;2927 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2928 2175 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2929 2176 … … 2978 2225 2979 2226 protected: 2980 void optimizeVariableAccess(OldInterpreterExecState*) KJS_FAST_CALL;2981 2982 2227 VarStack m_varStack; 2983 2228 FunctionStack m_functionStack; … … 2995 2240 virtual ~ProgramNode(); 2996 2241 2997 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;2998 2999 2242 ProgramCodeBlock& code(ScopeChainNode* scopeChain, bool canCreateGlobals) KJS_FAST_CALL 3000 2243 { … … 3010 2253 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 3011 2254 3012 void initializeSymbolTable(OldInterpreterExecState*) KJS_FAST_CALL;3013 ALWAYS_INLINE void processDeclarations(OldInterpreterExecState*) KJS_FAST_CALL;3014 3015 2255 Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.) 3016 2256 Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.) … … 3024 2264 virtual ~EvalNode(); 3025 2265 3026 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;3027 3028 2266 EvalCodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL 3029 2267 { … … 3036 2274 EvalNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; 3037 2275 3038 ALWAYS_INLINE void processDeclarations(OldInterpreterExecState*) KJS_FAST_CALL;3039 2276 void generateCode(ScopeChainNode*) KJS_FAST_CALL; 3040 2277 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; … … 3099 2336 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 3100 2337 FunctionImp* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL; 3101 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;3102 2338 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 3103 2339 virtual Precedence precedence() const { return PrecMember; } … … 3129 2365 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 3130 2366 3131 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;3132 2367 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 3133 2368 FunctionImp* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL; … … 3158 2393 } 3159 2394 3160 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;3161 2395 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 3162 2396 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } 3163 3164 JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;3165 JSValue* executeStatements(OldInterpreterExecState*) KJS_FAST_CALL;3166 2397 3167 2398 ExpressionNode* expr() const { return m_expr.get(); } … … 3186 2417 } 3187 2418 3188 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;3189 2419 CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); } 3190 2420 ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); } … … 3210 2440 RegisterID* emitCodeForBlock(CodeGenerator&, RegisterID* input, RegisterID* dst = 0) KJS_FAST_CALL; 3211 2441 3212 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;3213 JSValue* executeBlock(OldInterpreterExecState*, JSValue *input) KJS_FAST_CALL;3214 2442 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 3215 2443 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; } … … 3231 2459 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 3232 2460 3233 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;3234 virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;3235 2461 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 3236 2462 … … 3244 2470 BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL; 3245 2471 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; 3249 2473 3250 2474 private: -
trunk/JavaScriptCore/kjs/object.cpp
r34334 r34355 513 513 JSObject *getterFunc = gs->getGetter(); 514 514 if (getterFunc) 515 slot.setGetterSlot( this->toThisObject(0),getterFunc);515 slot.setGetterSlot(getterFunc); 516 516 else 517 slot.setUndefined( this);517 slot.setUndefined(); 518 518 } 519 519 -
trunk/JavaScriptCore/kjs/object.h
r34334 r34355 103 103 104 104 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 105 112 JSObject *getter; 106 113 JSObject *setter; … … 526 533 inline JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const 527 534 { 528 PropertySlot slot ;535 PropertySlot slot(const_cast<JSObject *>(this)); 529 536 530 537 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); 532 539 533 540 return jsUndefined(); … … 536 543 inline JSValue *JSObject::get(ExecState *exec, unsigned propertyName) const 537 544 { 538 PropertySlot slot ;545 PropertySlot slot(const_cast<JSObject *>(this)); 539 546 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); 541 548 542 549 return jsUndefined(); … … 588 595 fillGetterPropertySlot(slot, location); 589 596 } else 590 slot.setValueSlot( this,location);597 slot.setValueSlot(location); 591 598 return true; 592 599 } … … 594 601 // non-standard Netscape extension 595 602 if (propertyName == exec->propertyNames().underscoreProto) { 596 slot.setValueSlot( this,&_proto);603 slot.setValueSlot(&_proto); 597 604 slotIsWriteable = false; 598 605 return true; … … 611 618 fillGetterPropertySlot(slot, location); 612 619 else 613 slot.setValueSlot( this,location);620 slot.setValueSlot(location); 614 621 return true; 615 622 } … … 617 624 // non-standard Netscape extension 618 625 if (propertyName == exec->propertyNames().underscoreProto) { 619 slot.setValueSlot( this,&_proto);626 slot.setValueSlot(&_proto); 620 627 return true; 621 628 } … … 639 646 } 640 647 648 inline 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 670 inline 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 692 inline 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 701 inline 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 710 inline 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 641 718 } // namespace 642 719 -
trunk/JavaScriptCore/kjs/property_slot.cpp
r34334 r34355 1 1 // -*- c-basic-offset: 4 -*- 2 2 /* 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. 5 4 * 6 5 * This library is free software; you can redistribute it and/or … … 31 30 namespace KJS { 32 31 33 JSValue *PropertySlot::undefinedGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&)32 JSValue* PropertySlot::undefinedGetter(ExecState*, const Identifier&, const PropertySlot&) 34 33 { 35 34 return jsUndefined(); 36 35 } 37 36 38 JSValue* PropertySlot::ungettableGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot&)37 JSValue* PropertySlot::ungettableGetter(ExecState*, const Identifier&, const PropertySlot&) 39 38 { 40 39 ASSERT_NOT_REACHED(); … … 42 41 } 43 42 44 JSValue *PropertySlot::functionGetter(ExecState* exec, JSObject* originalObject, const Identifier&, const PropertySlot& slot)43 JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 45 44 { 46 45 CallData data; 47 46 CallType callType = slot.m_data.getterFunc->getCallData(data); 48 47 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()); 50 49 ASSERT(callType == CallTypeJS); 51 50 RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack(); 52 51 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()); 54 53 stack->popFunctionRegisterFile(); 55 54 return result; -
trunk/JavaScriptCore/kjs/property_slot.h
r33979 r34355 1 1 // -*- c-basic-offset: 4 -*- 2 2 /* 3 * Copyright (C) 2005, 2007 Apple Inc. All rights reserved.3 * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 39 39 class PropertySlot { 40 40 public: 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 } 43 45 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 { 46 56 if (m_getValue == KJS_VALUE_SLOT_MARKER) 47 57 return *m_data.valueSlot; 48 58 ASSERT(m_getValue != KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER); 49 return m_getValue(exec, originalObject, propertyName, *this);59 return m_getValue(exec, propertyName, *this); 50 60 } 51 61 52 JSValue* getValue(ExecState* exec, JSObject* originalObject,unsigned propertyName) const53 { 62 JSValue* getValue(ExecState* exec, unsigned propertyName) const 63 { 54 64 if (m_getValue == KJS_VALUE_SLOT_MARKER) 55 65 return *m_data.valueSlot; 56 66 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); 59 69 } 60 70 … … 65 75 } 66 76 67 void setValueSlot(JS Object* slotBase, JSValue** valueSlot)77 void setValueSlot(JSValue** valueSlot) 68 78 { 79 ASSERT(valueSlot); 69 80 m_getValue = KJS_VALUE_SLOT_MARKER; 70 m_slotBase = slotBase;81 clearBase(); 71 82 m_data.valueSlot = valueSlot; 72 83 } 73 84 74 void setStaticEntry(JS Object* slotBase, const HashEntry* staticEntry, GetValueFunc getValue)85 void setStaticEntry(JSCell* slotBase, const HashEntry* staticEntry, GetValueFunc getValue) 75 86 { 87 ASSERT(slotBase); 88 ASSERT(staticEntry); 76 89 ASSERT(getValue); 77 90 m_getValue = getValue; … … 80 93 } 81 94 82 void setCustom(JS Object* slotBase, GetValueFunc getValue)95 void setCustom(JSCell* slotBase, GetValueFunc getValue) 83 96 { 97 ASSERT(slotBase); 84 98 ASSERT(getValue); 85 99 m_getValue = getValue; … … 87 101 } 88 102 89 void setCustomIndex(JS Object* slotBase, unsigned index, GetValueFunc getValue)103 void setCustomIndex(JSCell* slotBase, unsigned index, GetValueFunc getValue) 90 104 { 105 ASSERT(slotBase); 91 106 ASSERT(getValue); 92 107 m_getValue = getValue; … … 95 110 } 96 111 97 void setCustomNumeric(JS Object* slotBase, GetValueNumericFunc getValue)112 void setCustomNumeric(JSCell* slotBase, GetValueNumericFunc getValue) 98 113 { 114 ASSERT(slotBase); 99 115 ASSERT(getValue); 100 116 m_slotBase = slotBase; … … 103 119 } 104 120 105 void setGetterSlot(JSObject* slotBase, JSObject*getterFunc)121 void setGetterSlot(JSObject* getterFunc) 106 122 { 123 ASSERT(getterFunc); 107 124 m_getValue = functionGetter; 108 m_slotBase = slotBase;109 125 m_data.getterFunc = getterFunc; 110 126 } 111 127 112 void setUndefined( JSObject *slotBase)128 void setUndefined() 113 129 { 114 m_slotBase = slotBase;130 clearBase(); 115 131 m_getValue = undefinedGetter; 116 132 } 117 133 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) 119 137 { 120 m_slotBase = slotBase; 121 m_getValue = ungettableGetter; 138 ASSERT(m_slotBase); 139 ASSERT(base); 140 m_slotBase = base; 122 141 } 123 142 124 JSObject* slotBase() const { return m_slotBase; } 143 void clearBase() 144 { 145 #ifndef NDEBUG 146 m_slotBase = 0; 147 #endif 148 } 125 149 126 150 const HashEntry* staticEntry() const { return m_data.staticEntry; } … … 128 152 129 153 private: 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&); 133 157 134 158 GetValueFunc m_getValue; 135 159 136 JS Object* m_slotBase;160 JSCell* m_slotBase; 137 161 union { 138 162 JSObject* getterFunc; -
trunk/JavaScriptCore/kjs/string_object.cpp
r34334 r34355 59 59 } 60 60 61 JSValue *StringInstance::lengthGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot &slot)61 JSValue *StringInstance::lengthGetter(ExecState*, const Identifier&, const PropertySlot &slot) 62 62 { 63 63 return jsNumber(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().size()); 64 64 } 65 65 66 JSValue* StringInstance::indexGetter(ExecState*, JSObject*,const Identifier&, const PropertySlot& slot)66 JSValue* StringInstance::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot) 67 67 { 68 68 return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(slot.index(), 1)); 69 69 } 70 70 71 static JSValue* stringInstanceNumericPropertyGetter(ExecState*, JSObject*,unsigned index, const PropertySlot& slot)71 static JSValue* stringInstanceNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot) 72 72 { 73 73 return jsString(static_cast<StringInstance*>(slot.slotBase())->internalValue()->value().substr(index, 1)); -
trunk/JavaScriptCore/kjs/string_object.h
r33979 r34355 51 51 bool inlineGetOwnPropertySlot(ExecState*, unsigned, PropertySlot&); 52 52 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&); 55 55 }; 56 56 -
trunk/JavaScriptCore/kjs/value.cpp
r33979 r34355 218 218 } 219 219 220 bool 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 232 bool 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 244 void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value) 245 { 246 toObject(exec)->put(exec, identifier, value); 247 } 248 249 void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value) 250 { 251 toObject(exec)->put(exec, identifier, value); 252 } 253 254 JSObject* JSCell::toThisObject(ExecState* exec) const 255 { 256 return toObject(exec); 257 } 258 220 259 JSCell* jsString(const char* s) 221 260 { -
trunk/JavaScriptCore/kjs/value.h
r34088 r34355 34 34 35 35 class ExecState; 36 class Identifier; 36 37 class JSObject; 37 38 class JSCell; 39 class PropertySlot; 38 40 39 41 struct ClassInfo; … … 98 100 JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number. 99 101 UString toString(ExecState *exec) const; 100 JSObject *toObject(ExecState *exec) const;102 JSObject* toObject(ExecState *exec) const; 101 103 102 104 // Integer conversions. … … 122 124 static uint32_t toUInt32SlowCase(double, bool& ok); 123 125 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 124 133 private: 134 bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 135 bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 125 136 int32_t toInt32SlowCase(ExecState*, bool& ok) const; 126 137 uint32_t toUInt32SlowCase(ExecState*, bool& ok) const; … … 129 140 JSCell *asCell(); 130 141 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&);135 142 }; 136 143 … … 181 188 virtual void mark(); 182 189 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&); 183 199 }; 184 200 … … 197 213 virtual UString toString(ExecState* exec) const; 198 214 virtual JSObject* toObject(ExecState* exec) const; 199 215 virtual JSObject* toThisObject(ExecState*) const; 216 200 217 void* operator new(size_t size) 201 218 { … … 584 601 } 585 602 603 inline 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 586 610 } // namespace 587 611
Note:
See TracChangeset
for help on using the changeset viewer.