d4eb401f16a48c938e1a4050c8c3237dd75d62cd
[WebKit-https.git] / JavaScriptCore / kjs / nodes.cpp
1 /*
2 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 *  Copyright (C) 2007 Maks Orlovich
7 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public
11 *  License as published by the Free Software Foundation; either
12 *  version 2 of the License, or (at your option) any later version.
13 *
14 *  This library is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public License
20 *  along with this library; see the file COPYING.LIB.  If not, write to
21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26 #include "config.h"
27 #include "nodes.h"
28
29 #include "CodeGenerator.h"
30 #include "ExecState.h"
31 #include "JSGlobalObject.h"
32 #include "Parser.h"
33 #include "PropertyNameArray.h"
34 #include "array_object.h"
35 #include "debugger.h"
36 #include "function_object.h"
37 #include "lexer.h"
38 #include "operations.h"
39 #include "regexp_object.h"
40 #include <math.h>
41 #include <wtf/Assertions.h>
42 #include <wtf/HashCountedSet.h>
43 #include <wtf/HashSet.h>
44 #include <wtf/MathExtras.h>
45
46 namespace KJS {
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 #else
58 #define UNLIKELY(x) x
59 #endif
60     
61 #define KJS_CHECKEXCEPTION \
62 if (UNLIKELY(exec->hadException())) \
63     return rethrowException(exec);
64
65 #define KJS_CHECKEXCEPTIONVALUE \
66 if (UNLIKELY(exec->hadException())) { \
67     handleException(exec); \
68     return jsUndefined(); \
69 }
70
71 #define KJS_CHECKEXCEPTIONNUMBER \
72 if (UNLIKELY(exec->hadException())) { \
73     handleException(exec); \
74     return 0; \
75 }
76
77 #define KJS_CHECKEXCEPTIONBOOLEAN \
78 if (UNLIKELY(exec->hadException())) { \
79     handleException(exec); \
80     return false; \
81 }
82
83 #define KJS_CHECKEXCEPTIONVOID \
84 if (UNLIKELY(exec->hadException())) { \
85     handleException(exec); \
86     return; \
87 }
88
89 #if !ASSERT_DISABLED
90 static inline bool canSkipLookup(OldInterpreterExecState* exec, const Identifier& ident)
91 {
92     // Static lookup in EvalCode is impossible because variables aren't DontDelete.
93     // Static lookup in GlobalCode may be possible, but we haven't implemented support for it yet.
94     if (exec->codeType() != FunctionCode)
95         return false;
96
97     // Static lookup is impossible when something dynamic has been added to the front of the scope chain.
98     if (exec->variableObject() != exec->scopeChain().top())
99         return false;
100
101     // Static lookup is impossible if the symbol isn't statically declared.
102     if (!exec->variableObject()->symbolTable().contains(ident.ustring().rep()))
103         return false;
104
105     return true;
106 }
107 #endif
108
109 static inline bool isConstant(const LocalStorage& localStorage, size_t index)
110 {
111     ASSERT(index < localStorage.size());
112     return localStorage[index].attributes & ReadOnly;
113 }
114
115 static inline UString::Rep* rep(const Identifier& ident)
116 {
117     return ident.ustring().rep();
118 }
119
120 // ------------------------------ Node -----------------------------------------
121
122 #ifndef NDEBUG
123 #ifndef LOG_CHANNEL_PREFIX
124 #define LOG_CHANNEL_PREFIX Log
125 #endif
126 static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn };
127
128 struct ParserRefCountedCounter {
129     static unsigned count;
130     ParserRefCountedCounter()
131     {
132         if (count)
133             LOG(KJSNodeLeaks, "LEAK: %u KJS::Node\n", count);
134     }
135 };
136 unsigned ParserRefCountedCounter::count = 0;
137 static ParserRefCountedCounter parserRefCountedCounter;
138 #endif
139
140 static HashSet<ParserRefCounted*>* newTrackedObjects;
141 static HashCountedSet<ParserRefCounted*>* trackedObjectExtraRefCounts;
142
143 ParserRefCounted::ParserRefCounted()
144 {
145 #ifndef NDEBUG
146     ++ParserRefCountedCounter::count;
147 #endif
148     if (!newTrackedObjects)
149         newTrackedObjects = new HashSet<ParserRefCounted*>;
150     newTrackedObjects->add(this);
151     ASSERT(newTrackedObjects->contains(this));
152 }
153
154 ParserRefCounted::~ParserRefCounted()
155 {
156 #ifndef NDEBUG
157     --ParserRefCountedCounter::count;
158 #endif
159 }
160
161 void ParserRefCounted::ref()
162 {
163     // bumping from 0 to 1 is just removing from the new nodes set
164     if (newTrackedObjects) {
165         HashSet<ParserRefCounted*>::iterator it = newTrackedObjects->find(this);
166         if (it != newTrackedObjects->end()) {
167             newTrackedObjects->remove(it);
168             ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(this));
169             return;
170         }
171     }
172
173     ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this));
174
175     if (!trackedObjectExtraRefCounts)
176         trackedObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>;
177     trackedObjectExtraRefCounts->add(this);
178 }
179
180 void ParserRefCounted::deref()
181 {
182     ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this));
183
184     if (!trackedObjectExtraRefCounts) {
185         delete this;
186         return;
187     }
188
189     HashCountedSet<ParserRefCounted*>::iterator it = trackedObjectExtraRefCounts->find(this);
190     if (it == trackedObjectExtraRefCounts->end())
191         delete this;
192     else
193         trackedObjectExtraRefCounts->remove(it);
194 }
195
196 unsigned ParserRefCounted::refcount()
197 {
198     if (newTrackedObjects && newTrackedObjects->contains(this)) {
199         ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(this));
200         return 0;
201     }
202
203     ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this));
204
205     if (!trackedObjectExtraRefCounts)
206         return 1;
207
208     return 1 + trackedObjectExtraRefCounts->count(this);
209 }
210
211 void ParserRefCounted::deleteNewObjects()
212 {
213     if (!newTrackedObjects)
214         return;
215
216 #ifndef NDEBUG
217     HashSet<ParserRefCounted*>::iterator end = newTrackedObjects->end();
218     for (HashSet<ParserRefCounted*>::iterator it = newTrackedObjects->begin(); it != end; ++it)
219         ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(*it));
220 #endif
221     deleteAllValues(*newTrackedObjects);
222     delete newTrackedObjects;
223     newTrackedObjects = 0;
224 }
225
226 Node::Node()
227     : m_expectedReturnType(ObjectType)
228 {
229     m_line = lexer().lineNo();
230 }
231
232 Node::Node(JSType expectedReturn)
233     : m_expectedReturnType(expectedReturn)
234 {
235     m_line = lexer().lineNo();
236 }
237
238 double ExpressionNode::evaluateToNumber(OldInterpreterExecState* exec)
239 {
240     JSValue* value = evaluate(exec);
241     KJS_CHECKEXCEPTIONNUMBER
242     return value->toNumber(exec);
243 }
244
245 bool ExpressionNode::evaluateToBoolean(OldInterpreterExecState* exec)
246 {
247     JSValue* value = evaluate(exec);
248     KJS_CHECKEXCEPTIONBOOLEAN
249     return value->toBoolean(exec);
250 }
251
252 int32_t ExpressionNode::evaluateToInt32(OldInterpreterExecState* exec)
253 {
254     JSValue* value = evaluate(exec);
255     KJS_CHECKEXCEPTIONNUMBER
256     return value->toInt32(exec);
257 }
258
259 uint32_t ExpressionNode::evaluateToUInt32(OldInterpreterExecState* exec)
260 {
261     JSValue* value = evaluate(exec);
262     KJS_CHECKEXCEPTIONNUMBER
263     return value->toUInt32(exec);
264 }
265
266 static void substitute(UString& string, const UString& substring) KJS_FAST_CALL;
267 static void substitute(UString& string, const UString& substring)
268 {
269     int position = string.find("%s");
270     ASSERT(position != -1);
271     UString newString = string.substr(0, position);
272     newString.append(substring);
273     newString.append(string.substr(position + 2));
274     string = newString;
275 }
276
277 static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
278 static inline int currentSourceId(ExecState*)
279 {
280     ASSERT_NOT_REACHED();
281     return 0;
282 }
283
284 static inline const UString currentSourceURL(ExecState* exec) KJS_FAST_CALL;
285 static inline const UString currentSourceURL(ExecState*)
286 {
287     ASSERT_NOT_REACHED();
288     return UString();
289 }
290
291 JSValue* Node::setErrorCompletion(OldInterpreterExecState* exec, ErrorType e, const char* msg)
292 {
293     return exec->setThrowCompletion(Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
294 }
295
296 JSValue* Node::setErrorCompletion(OldInterpreterExecState* exec, ErrorType e, const char* msg, const Identifier& ident)
297 {
298     UString message = msg;
299     substitute(message, ident.ustring());
300     return exec->setThrowCompletion(Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
301 }
302
303 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg)
304 {
305     return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
306 }
307
308 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, const char* string)
309 {
310     UString message = msg;
311     substitute(message, string);
312     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
313 }
314
315 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr)
316 {
317     UString message = msg;
318     substitute(message, v->toString(exec));
319     substitute(message, expr->toString());
320     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
321 }
322
323 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, const Identifier& label)
324 {
325     UString message = msg;
326     substitute(message, label.ustring());
327     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
328 }
329
330 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* e1, Node* e2)
331 {
332     UString message = msg;
333     substitute(message, v->toString(exec));
334     substitute(message, e1->toString());
335     substitute(message, e2->toString());
336     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
337 }
338
339 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr, const Identifier& label)
340 {
341     UString message = msg;
342     substitute(message, v->toString(exec));
343     substitute(message, expr->toString());
344     substitute(message, label.ustring());
345     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
346 }
347
348 JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, const Identifier& label)
349 {
350     UString message = msg;
351     substitute(message, v->toString(exec));
352     substitute(message, label.ustring());
353     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
354 }
355
356 JSValue* Node::throwUndefinedVariableError(OldInterpreterExecState* exec, const Identifier& ident)
357 {
358     return throwError(exec, ReferenceError, "Can't find variable: %s", ident);
359 }
360
361 void Node::handleException(OldInterpreterExecState* exec)
362 {
363     handleException(exec, exec->exception());
364 }
365
366 void Node::handleException(OldInterpreterExecState* exec, JSValue* exceptionValue)
367 {
368     if (exceptionValue->isObject()) {
369         JSObject* exception = static_cast<JSObject*>(exceptionValue);
370         if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) {
371             exception->put(exec, "line", jsNumber(m_line));
372             exception->put(exec, "sourceURL", jsString(currentSourceURL(exec)));
373         }
374     }
375 #if 0
376     Debugger* dbg = exec->dynamicGlobalObject()->debugger();
377     if (dbg && !dbg->hasHandledException(exec, exceptionValue))
378         dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);
379 #endif
380 }
381
382 NEVER_INLINE JSValue* Node::rethrowException(OldInterpreterExecState* exec)
383 {
384     JSValue* exception = exec->exception();
385     exec->clearException();
386     handleException(exec, exception);
387     return exec->setThrowCompletion(exception);
388 }
389
390 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
391 {
392     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(msg));
393     generator.emitThrow(exception);
394     return exception;
395 }
396
397 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
398 {
399     UString message = msg;
400     substitute(message, label.ustring());
401     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(message));
402     generator.emitThrow(exception);
403     return exception;
404 }
405     
406 // ------------------------------ StatementNode --------------------------------
407
408 StatementNode::StatementNode()
409     : m_lastLine(-1)
410 {
411     m_line = -1;
412 }
413
414 void StatementNode::setLoc(int firstLine, int lastLine)
415 {
416     m_line = firstLine;
417     m_lastLine = lastLine;
418 }
419
420 // ------------------------------ SourceElements --------------------------------
421
422 void SourceElements::append(PassRefPtr<StatementNode> statement)
423 {
424     if (statement->isEmptyStatement())
425         return;
426
427     m_statements.append(statement);
428 }
429
430 // ------------------------------ BreakpointCheckStatement --------------------------------
431
432 BreakpointCheckStatement::BreakpointCheckStatement(PassRefPtr<StatementNode> statement)
433     : m_statement(statement)
434 {
435     ASSERT(m_statement);
436 }
437
438 JSValue* BreakpointCheckStatement::execute(OldInterpreterExecState* exec)
439 {
440     return m_statement->execute(exec);
441 }
442
443 void BreakpointCheckStatement::streamTo(SourceStream& stream) const
444 {
445     m_statement->streamTo(stream);
446 }
447
448 void BreakpointCheckStatement::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
449 {
450     nodeStack.append(m_statement.get());
451 }
452
453 // ------------------------------ NullNode -------------------------------------
454
455 RegisterID* NullNode::emitCode(CodeGenerator& generator, RegisterID* dst)
456 {
457     return generator.emitLoad(generator.finalDestination(dst), jsNull());
458 }
459
460 JSValue* NullNode::evaluate(OldInterpreterExecState* )
461 {
462     return jsNull();
463 }
464
465 // ------------------------------ FalseNode ----------------------------------
466
467 RegisterID* FalseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
468 {
469     return generator.emitLoad(generator.finalDestination(dst), false);
470 }
471
472 JSValue* FalseNode::evaluate(OldInterpreterExecState*)
473 {
474     return jsBoolean(false);
475 }
476
477 // ------------------------------ TrueNode ----------------------------------
478
479 RegisterID* TrueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
480 {
481     return generator.emitLoad(generator.finalDestination(dst), true);
482 }
483
484 JSValue* TrueNode::evaluate(OldInterpreterExecState*)
485 {
486     return jsBoolean(true);
487 }
488
489 // ------------------------------ NumberNode -----------------------------------
490
491 RegisterID* NumberNode::emitCode(CodeGenerator& generator, RegisterID* dst)
492 {
493     return generator.emitLoad(generator.finalDestination(dst), m_double);
494 }
495
496 JSValue* NumberNode::evaluate(OldInterpreterExecState*)
497 {
498     // Number nodes are only created when the number can't fit in a JSImmediate, so no need to check again.
499     return jsNumberCell(m_double);
500 }
501
502 double NumberNode::evaluateToNumber(OldInterpreterExecState*)
503 {
504     return m_double;
505 }
506
507 bool NumberNode::evaluateToBoolean(OldInterpreterExecState*)
508 {
509     return m_double < 0.0 || m_double > 0.0; // false for NaN as well as 0
510 }
511
512 int32_t NumberNode::evaluateToInt32(OldInterpreterExecState*)
513 {
514     return JSValue::toInt32(m_double);
515 }
516
517 uint32_t NumberNode::evaluateToUInt32(OldInterpreterExecState*)
518 {
519     return JSValue::toUInt32(m_double);
520 }
521
522 // ------------------------------ ImmediateNumberNode -----------------------------------
523
524 JSValue* ImmediateNumberNode::evaluate(OldInterpreterExecState*)
525 {
526     return m_value;
527 }
528
529 int32_t ImmediateNumberNode::evaluateToInt32(OldInterpreterExecState*)
530 {
531     return JSImmediate::getTruncatedInt32(m_value);
532 }
533
534 uint32_t ImmediateNumberNode::evaluateToUInt32(OldInterpreterExecState*)
535 {
536     uint32_t i;
537     if (JSImmediate::getTruncatedUInt32(m_value, i))
538         return i;
539     bool ok;
540     return JSValue::toUInt32SlowCase(m_double, ok);
541 }
542
543 // ------------------------------ StringNode -----------------------------------
544
545 RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
546 {
547     // FIXME: should we try to atomize constant strings?
548     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 }
565
566 // ------------------------------ RegExpNode -----------------------------------
567
568 RegisterID* RegExpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
569 {
570     if (!m_regExp->isValid())
571         return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", m_regExp->errorMessage());
572     return generator.emitNewRegExp(generator.finalDestination(dst), m_regExp.get());
573 }
574
575 JSValue* RegExpNode::evaluate(OldInterpreterExecState*)
576 {
577     ASSERT_NOT_REACHED();
578     return 0;
579 }
580
581 // ------------------------------ ThisNode -------------------------------------
582
583 RegisterID* ThisNode::emitCode(CodeGenerator& generator, RegisterID* dst)
584 {
585     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
586 }
587
588 // ECMA 11.1.1
589 JSValue* ThisNode::evaluate(OldInterpreterExecState* exec)
590 {
591     return exec->thisValue();
592 }
593
594 // ------------------------------ ResolveNode ----------------------------------
595
596 RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
597 {
598     if (RegisterID* local = generator.registerForLocal(m_ident))
599         return generator.moveToDestinationIfNeeded(dst, local);
600
601     return generator.emitResolve(generator.finalDestination(dst), m_ident);
602 }
603
604 // ECMA 11.1.2 & 10.1.4
605 JSValue* ResolveNode::inlineEvaluate(OldInterpreterExecState* exec)
606 {
607     // Check for missed optimization opportunity.
608     ASSERT(!canSkipLookup(exec, m_ident));
609
610     const ScopeChain& chain = exec->scopeChain();
611     ScopeChainIterator iter = chain.begin();
612     ScopeChainIterator end = chain.end();
613
614     // we must always have something in the scope chain
615     ASSERT(iter != end);
616
617     PropertySlot slot;
618     do {
619         JSObject* o = *iter;
620
621         if (o->getPropertySlot(exec, m_ident, slot))
622             return slot.getValue(exec, o, m_ident);
623
624         ++iter;
625     } while (iter != end);
626
627     return throwUndefinedVariableError(exec, m_ident);
628 }
629
630 JSValue* ResolveNode::evaluate(OldInterpreterExecState* exec)
631 {
632     return inlineEvaluate(exec);
633 }
634
635 double ResolveNode::evaluateToNumber(OldInterpreterExecState* exec)
636 {
637     JSValue* v = inlineEvaluate(exec);
638     KJS_CHECKEXCEPTIONNUMBER
639     return v->toNumber(exec);
640 }
641
642 bool ResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)
643 {
644     JSValue* v = inlineEvaluate(exec);
645     KJS_CHECKEXCEPTIONBOOLEAN
646     return v->toBoolean(exec);
647 }
648
649 int32_t ResolveNode::evaluateToInt32(OldInterpreterExecState* exec)
650 {
651     JSValue* v = inlineEvaluate(exec);
652     KJS_CHECKEXCEPTIONNUMBER
653     return v->toInt32(exec);
654 }
655
656 uint32_t ResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)
657 {
658     JSValue* v = inlineEvaluate(exec);
659     KJS_CHECKEXCEPTIONNUMBER
660     return v->toUInt32(exec);
661 }
662
663 static size_t getSymbolTableEntry(OldInterpreterExecState* exec, const Identifier& ident, const SymbolTable& symbolTable, size_t& stackDepth) 
664 {
665     int index = symbolTable.get(ident.ustring().rep()).getIndex();
666     if (index != missingSymbolMarker()) {
667         stackDepth = 0;
668         return index;
669     }
670     
671     if (ident == exec->propertyNames().arguments) {
672         stackDepth = 0;
673         return missingSymbolMarker();
674     }
675     
676     const ScopeChain& chain = exec->scopeChain();
677     ScopeChainIterator iter = chain.begin();
678     ScopeChainIterator end = chain.end();
679     size_t depth = 0;
680     for (; iter != end; ++iter, ++depth) {
681         JSObject* currentScope = *iter;
682         if (!currentScope->isVariableObject()) 
683             break;
684         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
685         index = currentVariableObject->symbolTable().get(ident.ustring().rep()).getIndex();
686         if (index != missingSymbolMarker()) {
687             stackDepth = depth;
688             return index;
689         }
690         if (currentVariableObject->isDynamicScope())
691             break;
692     }
693     stackDepth = depth;
694     return missingSymbolMarker();
695 }
696
697 void ResolveNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
698 {
699     size_t depth = 0;
700     int index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
701     if (index != missingSymbolMarker()) {
702         if (!depth)
703             new (this) LocalVarAccessNode(index);
704         else
705             new (this) ScopedVarAccessNode(index, depth);
706         return;
707     }
708
709     if (!depth)
710         return;
711
712     new (this) NonLocalVarAccessNode(depth);
713 }
714
715 JSValue* LocalVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
716 {
717     ASSERT(exec->variableObject() == exec->scopeChain().top());
718     return exec->localStorage()[m_index].value;
719 }
720
721 JSValue* LocalVarAccessNode::evaluate(OldInterpreterExecState* exec)
722 {
723     return inlineEvaluate(exec);
724 }
725
726 double LocalVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
727 {
728     return inlineEvaluate(exec)->toNumber(exec);
729 }
730
731 bool LocalVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
732 {
733     return inlineEvaluate(exec)->toBoolean(exec);
734 }
735
736 int32_t LocalVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
737 {
738     return inlineEvaluate(exec)->toInt32(exec);
739 }
740
741 uint32_t LocalVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
742 {
743     return inlineEvaluate(exec)->toUInt32(exec);
744 }
745
746 static inline JSValue* getNonLocalSymbol(OldInterpreterExecState* exec, size_t, size_t scopeDepth)
747 {
748     const ScopeChain& chain = exec->scopeChain();
749     ScopeChainIterator iter = chain.begin();
750     for (size_t i = 0; i < scopeDepth; ++iter, ++i)
751         ASSERT(iter != chain.end());
752 #ifndef NDEBUG
753     JSObject* scope = *iter;
754 #endif
755     ASSERT(scope->isVariableObject());
756     ASSERT_NOT_REACHED();
757     return 0;
758 }
759
760 JSValue* ScopedVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
761 {
762     return getNonLocalSymbol(exec, m_index, m_scopeDepth);
763 }
764
765 JSValue* ScopedVarAccessNode::evaluate(OldInterpreterExecState* exec)
766 {
767     return inlineEvaluate(exec);
768 }
769
770 double ScopedVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
771 {
772     return inlineEvaluate(exec)->toNumber(exec);
773 }
774
775 bool ScopedVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
776 {
777     return inlineEvaluate(exec)->toBoolean(exec);
778 }
779
780 int32_t ScopedVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
781 {
782     return inlineEvaluate(exec)->toInt32(exec);
783 }
784
785 uint32_t ScopedVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
786 {
787     return inlineEvaluate(exec)->toUInt32(exec);
788 }
789
790 JSValue* NonLocalVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
791 {
792     // Check for missed optimization opportunity.
793     ASSERT(!canSkipLookup(exec, m_ident));
794     
795     const ScopeChain& chain = exec->scopeChain();
796     ScopeChainIterator iter = chain.begin();
797     ScopeChainIterator end = chain.end();
798     for (size_t i = 0; i < m_scopeDepth; ++i, ++iter)
799         ASSERT(iter != end);
800
801     // we must always have something in the scope chain
802     ASSERT(iter != end);
803     
804     PropertySlot slot;
805     do {
806         JSObject* o = *iter;
807         
808         if (o->getPropertySlot(exec, m_ident, slot))
809             return slot.getValue(exec, o, m_ident);
810         
811         ++iter;
812     } while (iter != end);
813     
814     return throwUndefinedVariableError(exec, m_ident);
815 }
816
817 JSValue* NonLocalVarAccessNode::evaluate(OldInterpreterExecState* exec)
818 {
819     return inlineEvaluate(exec);
820 }
821
822 double NonLocalVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
823 {
824     return inlineEvaluate(exec)->toNumber(exec);
825 }
826
827 bool NonLocalVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
828 {
829     return inlineEvaluate(exec)->toBoolean(exec);
830 }
831
832 int32_t NonLocalVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
833 {
834     return inlineEvaluate(exec)->toInt32(exec);
835 }
836
837 uint32_t NonLocalVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
838 {
839     return inlineEvaluate(exec)->toUInt32(exec);
840 }
841
842 // ------------------------------ ElementNode ----------------------------------
843
844 void ElementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
845 {
846     if (m_next)
847         nodeStack.append(m_next.get());
848     ASSERT(m_node);
849     nodeStack.append(m_node.get());
850 }
851
852 // ECMA 11.1.4
853 JSValue* ElementNode::evaluate(OldInterpreterExecState* exec)
854 {
855     JSObject* array = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());
856     int length = 0;
857     for (ElementNode* n = this; n; n = n->m_next.get()) {
858         JSValue* val = n->m_node->evaluate(exec);
859         KJS_CHECKEXCEPTIONVALUE
860         length += n->m_elision;
861         array->put(exec, length++, val);
862     }
863     return array;
864 }
865
866 // ------------------------------ ArrayNode ------------------------------------
867
868
869 RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
870 {
871     RefPtr<RegisterID> newArray = generator.emitNewArray(generator.tempDestination(dst));
872     unsigned length = 0;
873
874     RegisterID* value;
875     for (ElementNode* n = m_element.get(); n; n = n->m_next.get()) {
876         value = generator.emitNode(n->m_node.get());
877         length += n->m_elision;
878         generator.emitPutByIndex(newArray.get(), length++, value);
879     }
880
881     value = generator.emitLoad(generator.newTemporary(), jsNumber(m_elision + length));
882     generator.emitPutById(newArray.get(), generator.propertyNames().length, value);
883
884     return generator.moveToDestinationIfNeeded(dst, newArray.get());
885 }
886
887 void ArrayNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
888 {
889     if (m_element)
890         nodeStack.append(m_element.get());
891 }
892
893 // ECMA 11.1.4
894 JSValue* ArrayNode::evaluate(OldInterpreterExecState* exec)
895 {
896     JSObject* array;
897     int length;
898
899     if (m_element) {
900         array = static_cast<JSObject*>(m_element->evaluate(exec));
901         KJS_CHECKEXCEPTIONVALUE
902         length = m_optional ? array->get(exec, exec->propertyNames().length)->toInt32(exec) : 0;
903     } else {
904         JSValue* newArr = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());
905         array = static_cast<JSObject*>(newArr);
906         length = 0;
907     }
908
909     if (m_optional)
910         array->put(exec, exec->propertyNames().length, jsNumber(m_elision + length));
911
912     return array;
913 }
914
915 // ------------------------------ ObjectLiteralNode ----------------------------
916
917 RegisterID* ObjectLiteralNode::emitCode(CodeGenerator& generator, RegisterID* dst)
918 {
919     if (m_list)
920         return generator.emitNode(dst, m_list.get());
921     else
922         return generator.emitNewObject(generator.finalDestination(dst));
923 }
924
925 void ObjectLiteralNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
926 {
927     if (m_list)
928         nodeStack.append(m_list.get());
929 }
930
931 // ECMA 11.1.5
932 JSValue* ObjectLiteralNode::evaluate(OldInterpreterExecState* exec)
933 {
934     if (m_list)
935         return m_list->evaluate(exec);
936
937     return exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
938 }
939
940 // ------------------------------ PropertyListNode -----------------------------
941
942 RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
943 {
944     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
945     
946     generator.emitNewObject(newObj.get());
947     
948     for (PropertyListNode* p = this; p; p = p->m_next.get()) {
949         RegisterID* value = generator.emitNode(p->m_node->m_assign.get());
950         
951         switch (p->m_node->m_type) {
952             case PropertyNode::Constant: {
953                 generator.emitPutById(newObj.get(), p->m_node->name(), value);
954                 break;
955             }
956             case PropertyNode::Getter: {
957                 generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
958                 break;
959             }
960             case PropertyNode::Setter: {
961                 generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
962                 break;
963             }
964             default:
965                 ASSERT_NOT_REACHED();
966         }
967     }
968     
969     return generator.moveToDestinationIfNeeded(dst, newObj.get());
970 }
971
972 void PropertyListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
973 {
974     if (m_next)
975         nodeStack.append(m_next.get());
976     nodeStack.append(m_node.get());
977 }
978
979 // ECMA 11.1.5
980 JSValue* PropertyListNode::evaluate(OldInterpreterExecState* exec)
981 {
982     JSObject* obj = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
983
984     for (PropertyListNode* p = this; p; p = p->m_next.get()) {
985         JSValue* v = p->m_node->m_assign->evaluate(exec);
986         KJS_CHECKEXCEPTIONVALUE
987
988         switch (p->m_node->m_type) {
989             case PropertyNode::Getter:
990                 ASSERT(v->isObject());
991                 obj->defineGetter(exec, p->m_node->name(), static_cast<JSObject* >(v));
992                 break;
993             case PropertyNode::Setter:
994                 ASSERT(v->isObject());
995                 obj->defineSetter(exec, p->m_node->name(), static_cast<JSObject* >(v));
996                 break;
997             case PropertyNode::Constant:
998                 obj->put(exec, p->m_node->name(), v);
999                 break;
1000         }
1001     }
1002
1003     return obj;
1004 }
1005
1006 // ------------------------------ PropertyNode -----------------------------
1007
1008 void PropertyNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1009 {
1010     nodeStack.append(m_assign.get());
1011 }
1012
1013 // ECMA 11.1.5
1014 JSValue* PropertyNode::evaluate(OldInterpreterExecState*)
1015 {
1016     ASSERT(false);
1017     return jsNull();
1018 }
1019
1020 // ------------------------------ BracketAccessorNode --------------------------------
1021
1022 RegisterID* BracketAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1023 {
1024     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1025     RegisterID* property = generator.emitNode(m_subscript.get());
1026
1027     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
1028 }
1029
1030 void BracketAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1031 {
1032     nodeStack.append(m_subscript.get());
1033     nodeStack.append(m_base.get());
1034 }
1035
1036 // ECMA 11.2.1a
1037 JSValue* BracketAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)
1038 {
1039     JSValue* v1 = m_base->evaluate(exec);
1040     KJS_CHECKEXCEPTIONVALUE
1041     JSValue* v2 = m_subscript->evaluate(exec);
1042     KJS_CHECKEXCEPTIONVALUE
1043     JSObject* o = v1->toObject(exec);
1044     uint32_t i;
1045     if (v2->getUInt32(i))
1046         return o->get(exec, i);
1047     return o->get(exec, Identifier(v2->toString(exec)));
1048 }
1049
1050 JSValue* BracketAccessorNode::evaluate(OldInterpreterExecState* exec)
1051 {
1052     return inlineEvaluate(exec);
1053 }
1054
1055 double BracketAccessorNode::evaluateToNumber(OldInterpreterExecState* exec)
1056 {
1057     JSValue* v = inlineEvaluate(exec);
1058     KJS_CHECKEXCEPTIONNUMBER
1059     return v->toNumber(exec);
1060 }
1061
1062 bool BracketAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)
1063 {
1064     JSValue* v = inlineEvaluate(exec);
1065     KJS_CHECKEXCEPTIONBOOLEAN
1066     return v->toBoolean(exec);
1067 }
1068
1069 int32_t BracketAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)
1070 {
1071     JSValue* v = inlineEvaluate(exec);
1072     KJS_CHECKEXCEPTIONNUMBER
1073     return v->toInt32(exec);
1074 }
1075
1076 uint32_t BracketAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)
1077 {
1078     JSValue* v = inlineEvaluate(exec);
1079     KJS_CHECKEXCEPTIONNUMBER
1080     return v->toUInt32(exec);
1081 }
1082
1083 // ------------------------------ DotAccessorNode --------------------------------
1084
1085 RegisterID* DotAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1086 {
1087     RegisterID* base = generator.emitNode(m_base.get());
1088     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
1089 }
1090
1091 void DotAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1092 {
1093     nodeStack.append(m_base.get());
1094 }
1095
1096 // ECMA 11.2.1b
1097 JSValue* DotAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)
1098 {
1099     JSValue* v = m_base->evaluate(exec);
1100     KJS_CHECKEXCEPTIONVALUE
1101     return v->toObject(exec)->get(exec, m_ident);
1102 }
1103
1104 JSValue* DotAccessorNode::evaluate(OldInterpreterExecState* exec)
1105 {
1106     return inlineEvaluate(exec);
1107 }
1108
1109 double DotAccessorNode::evaluateToNumber(OldInterpreterExecState* exec)
1110 {
1111     JSValue* v = inlineEvaluate(exec);
1112     KJS_CHECKEXCEPTIONNUMBER
1113     return v->toNumber(exec);
1114 }
1115
1116 bool DotAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)
1117 {
1118     JSValue* v = inlineEvaluate(exec);
1119     KJS_CHECKEXCEPTIONBOOLEAN
1120     return v->toBoolean(exec);
1121 }
1122
1123 int32_t DotAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)
1124 {
1125     JSValue* v = inlineEvaluate(exec);
1126     KJS_CHECKEXCEPTIONNUMBER
1127     return v->toInt32(exec);
1128 }
1129
1130 uint32_t DotAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)
1131 {
1132     JSValue* v = inlineEvaluate(exec);
1133     KJS_CHECKEXCEPTIONNUMBER
1134     return v->toUInt32(exec);
1135 }
1136
1137 // ------------------------------ ArgumentListNode -----------------------------
1138
1139 RegisterID* ArgumentListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1140 {
1141     ASSERT(m_expr);
1142     return generator.emitNode(dst, m_expr.get());
1143 }
1144
1145 void ArgumentListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1146 {
1147     if (m_next)
1148         nodeStack.append(m_next.get());
1149     ASSERT(m_expr);
1150     nodeStack.append(m_expr.get());
1151 }
1152
1153 // ECMA 11.2.4
1154 void ArgumentListNode::evaluateList(OldInterpreterExecState* exec, List& list)
1155 {
1156     for (ArgumentListNode* n = this; n; n = n->m_next.get()) {
1157         JSValue* v = n->m_expr->evaluate(exec);
1158         KJS_CHECKEXCEPTIONVOID
1159         list.append(v);
1160     }
1161 }
1162
1163 // ------------------------------ ArgumentsNode --------------------------------
1164
1165 void ArgumentsNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1166 {
1167     if (m_listNode)
1168         nodeStack.append(m_listNode.get());
1169 }
1170
1171 // ------------------------------ NewExprNode ----------------------------------
1172
1173 RegisterID* NewExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1174 {
1175     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
1176     return generator.emitConstruct(generator.finalDestination(dst), r0.get(), m_args.get());
1177 }
1178
1179 void NewExprNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1180 {
1181     if (m_args)
1182         nodeStack.append(m_args.get());
1183     nodeStack.append(m_expr.get());
1184 }
1185
1186 // ECMA 11.2.2
1187
1188 JSValue* NewExprNode::inlineEvaluate(OldInterpreterExecState* exec)
1189 {
1190     JSValue* v = m_expr->evaluate(exec);
1191     KJS_CHECKEXCEPTIONVALUE
1192
1193     List argList;
1194     if (m_args) {
1195         m_args->evaluateList(exec, argList);
1196         KJS_CHECKEXCEPTIONVALUE
1197     }
1198
1199     if (!v->isObject())
1200         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, m_expr.get());
1201
1202     ConstructData constructData;
1203     if (v->getConstructData(constructData) == ConstructTypeNone)
1204         return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, m_expr.get());
1205
1206     return static_cast<JSObject*>(v)->construct(exec, argList);
1207 }
1208
1209 JSValue* NewExprNode::evaluate(OldInterpreterExecState* exec)
1210 {
1211     return inlineEvaluate(exec);
1212 }
1213
1214 double NewExprNode::evaluateToNumber(OldInterpreterExecState* exec)
1215 {
1216     JSValue* v = inlineEvaluate(exec);
1217     KJS_CHECKEXCEPTIONNUMBER
1218     return v->toNumber(exec);
1219 }
1220
1221 bool NewExprNode::evaluateToBoolean(OldInterpreterExecState* exec)
1222 {
1223     JSValue* v = inlineEvaluate(exec);
1224     KJS_CHECKEXCEPTIONBOOLEAN
1225     return v->toBoolean(exec);
1226 }
1227
1228 int32_t NewExprNode::evaluateToInt32(OldInterpreterExecState* exec)
1229 {
1230     JSValue* v = inlineEvaluate(exec);
1231     KJS_CHECKEXCEPTIONNUMBER
1232     return v->toInt32(exec);
1233 }
1234
1235 uint32_t NewExprNode::evaluateToUInt32(OldInterpreterExecState* exec)
1236 {
1237     JSValue* v = inlineEvaluate(exec);
1238     KJS_CHECKEXCEPTIONNUMBER
1239     return v->toUInt32(exec);
1240 }
1241
1242 template <ExpressionNode::CallerType callerType, bool scopeDepthIsZero> 
1243 inline JSValue* ExpressionNode::resolveAndCall(OldInterpreterExecState* exec, const Identifier& ident, ArgumentsNode* args, size_t scopeDepth)
1244 {
1245     const ScopeChain& chain = exec->scopeChain();
1246     ScopeChainIterator iter = chain.begin();
1247     ScopeChainIterator end = chain.end();
1248
1249     if (!scopeDepthIsZero) {
1250         for (size_t i = 0; i < scopeDepth; ++iter, ++i)
1251             ASSERT(iter != chain.end());
1252     }
1253     
1254     // we must always have something in the scope chain
1255     ASSERT(iter != end);
1256
1257     PropertySlot slot;
1258     JSObject* base;
1259     do {
1260         base = *iter;
1261         if (base->getPropertySlot(exec, ident, slot)) {
1262             JSValue* v = slot.getValue(exec, base, ident);
1263             KJS_CHECKEXCEPTIONVALUE
1264
1265             if (!v->isObject())
1266                 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident);
1267
1268             JSObject* func = static_cast<JSObject*>(v);
1269
1270             if (!func->implementsCall())
1271                 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident);
1272
1273             List argList;
1274             args->evaluateList(exec, argList);
1275             KJS_CHECKEXCEPTIONVALUE
1276
1277             if (callerType == EvalOperator) {
1278                 if (base == exec->lexicalGlobalObject() && func == exec->lexicalGlobalObject()->evalFunction()) {
1279                     ASSERT_NOT_REACHED();
1280                 }
1281             }
1282
1283             JSObject* thisObj = base->toThisObject(exec);
1284             return func->call(exec, thisObj, argList);
1285         }
1286         ++iter;
1287     } while (iter != end);
1288
1289     return throwUndefinedVariableError(exec, ident);
1290 }
1291
1292 RegisterID* EvalFunctionCallNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1293 {
1294     RefPtr<RegisterID> base = generator.tempDestination(dst);
1295     RegisterID* func = generator.newTemporary();
1296     generator.emitResolveWithBase(base.get(), func, CommonIdentifiers::shared()->eval);
1297     return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
1298 }
1299
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 RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1311 {
1312     RegisterID* r0 = generator.emitNode(m_expr.get());
1313     return generator.emitCall(generator.finalDestination(dst), r0, 0, m_args.get());
1314 }
1315
1316 void FunctionCallValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1317 {
1318     nodeStack.append(m_args.get());
1319     nodeStack.append(m_expr.get());
1320 }
1321
1322 // ECMA 11.2.3
1323 JSValue* FunctionCallValueNode::evaluate(OldInterpreterExecState* exec)
1324 {
1325     JSValue* v = m_expr->evaluate(exec);
1326     KJS_CHECKEXCEPTIONVALUE
1327
1328     if (!v->isObject()) {
1329         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_expr.get());
1330     }
1331
1332     JSObject* func = static_cast<JSObject*>(v);
1333
1334     if (!func->implementsCall()) {
1335         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_expr.get());
1336     }
1337
1338     List argList;
1339     m_args->evaluateList(exec, argList);
1340     KJS_CHECKEXCEPTIONVALUE
1341
1342     JSObject* thisObj = exec->globalThisValue();
1343     return func->call(exec, thisObj, argList);
1344 }
1345
1346 RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1347 {
1348     if (RegisterID* local = generator.registerForLocal(m_ident))
1349         return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get());
1350
1351     int index = 0;
1352     size_t depth = 0;
1353     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
1354         RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
1355         return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get());
1356     }
1357
1358     RefPtr<RegisterID> base = generator.tempDestination(dst);
1359     RegisterID* func = generator.newTemporary();
1360     generator.emitResolveFunction(base.get(), func, m_ident);
1361     return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
1362 }
1363
1364 void FunctionCallResolveNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack& nodeStack)
1365 {
1366     nodeStack.append(m_args.get());
1367
1368     size_t depth = 0;
1369     int index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
1370     if (index != missingSymbolMarker()) {
1371         if (!depth)
1372             new (this) LocalVarFunctionCallNode(index);
1373         else
1374             new (this) ScopedVarFunctionCallNode(index, depth);
1375         return;
1376     }
1377     
1378     if (!depth)
1379         return;
1380     
1381     new (this) NonLocalVarFunctionCallNode(depth);
1382 }
1383
1384 // ECMA 11.2.3
1385 JSValue* FunctionCallResolveNode::inlineEvaluate(OldInterpreterExecState* exec)
1386 {
1387     // Check for missed optimization opportunity.
1388     ASSERT(!canSkipLookup(exec, m_ident));
1389
1390     return resolveAndCall<FunctionCall, true>(exec, m_ident, m_args.get());
1391 }
1392
1393 JSValue* FunctionCallResolveNode::evaluate(OldInterpreterExecState* exec)
1394 {
1395     return inlineEvaluate(exec);
1396 }
1397
1398 double FunctionCallResolveNode::evaluateToNumber(OldInterpreterExecState* exec)
1399 {
1400     JSValue* v = inlineEvaluate(exec);
1401     KJS_CHECKEXCEPTIONNUMBER
1402     return v->toNumber(exec);
1403 }
1404
1405 bool FunctionCallResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)
1406 {
1407     JSValue* v = inlineEvaluate(exec);
1408     KJS_CHECKEXCEPTIONBOOLEAN
1409     return v->toBoolean(exec);
1410 }
1411
1412 int32_t FunctionCallResolveNode::evaluateToInt32(OldInterpreterExecState* exec)
1413 {
1414     JSValue* v = inlineEvaluate(exec);
1415     KJS_CHECKEXCEPTIONNUMBER
1416     return v->toInt32(exec);
1417 }
1418
1419 uint32_t FunctionCallResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)
1420 {
1421     JSValue* v = inlineEvaluate(exec);
1422     KJS_CHECKEXCEPTIONNUMBER
1423     return v->toUInt32(exec);
1424 }
1425
1426 JSValue* LocalVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
1427 {
1428     ASSERT(exec->variableObject() == exec->scopeChain().top());
1429
1430     JSValue* v = exec->localStorage()[m_index].value;
1431
1432     if (!v->isObject())
1433         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);
1434
1435     JSObject* func = static_cast<JSObject*>(v);
1436     if (!func->implementsCall())
1437         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);
1438
1439     List argList;
1440     m_args->evaluateList(exec, argList);
1441     KJS_CHECKEXCEPTIONVALUE
1442
1443     JSObject* thisObj = exec->globalThisValue();
1444     return func->call(exec, thisObj, argList);
1445 }
1446
1447 JSValue* LocalVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
1448 {
1449     return inlineEvaluate(exec);
1450 }
1451
1452 double LocalVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
1453 {
1454     JSValue* v = inlineEvaluate(exec);
1455     KJS_CHECKEXCEPTIONNUMBER
1456     return v->toNumber(exec);
1457 }
1458
1459 bool LocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
1460 {
1461     JSValue* v = inlineEvaluate(exec);
1462     KJS_CHECKEXCEPTIONBOOLEAN
1463     return v->toBoolean(exec);
1464 }
1465
1466 int32_t LocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
1467 {
1468     JSValue* v = inlineEvaluate(exec);
1469     KJS_CHECKEXCEPTIONNUMBER
1470     return v->toInt32(exec);
1471 }
1472
1473 uint32_t LocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
1474 {
1475     JSValue* v = inlineEvaluate(exec);
1476     KJS_CHECKEXCEPTIONNUMBER
1477     return v->toUInt32(exec);
1478 }
1479
1480 JSValue* ScopedVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
1481 {
1482     ASSERT(exec->variableObject() == exec->scopeChain().top());
1483     
1484     JSValue* v = getNonLocalSymbol(exec, m_index, m_scopeDepth);
1485     
1486     if (!v->isObject())
1487         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);
1488     
1489     JSObject* func = static_cast<JSObject*>(v);
1490     if (!func->implementsCall())
1491         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);
1492     
1493     List argList;
1494     m_args->evaluateList(exec, argList);
1495     KJS_CHECKEXCEPTIONVALUE
1496
1497     JSObject* thisObj = exec->globalThisValue();
1498     return func->call(exec, thisObj, argList);
1499 }
1500
1501 JSValue* ScopedVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
1502 {
1503     return inlineEvaluate(exec);
1504 }
1505
1506 double ScopedVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
1507 {
1508     JSValue* v = inlineEvaluate(exec);
1509     KJS_CHECKEXCEPTIONNUMBER
1510     return v->toNumber(exec);
1511 }
1512
1513 bool ScopedVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
1514 {
1515     JSValue* v = inlineEvaluate(exec);
1516     KJS_CHECKEXCEPTIONBOOLEAN
1517     return v->toBoolean(exec);
1518 }
1519
1520 int32_t ScopedVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
1521 {
1522     JSValue* v = inlineEvaluate(exec);
1523     KJS_CHECKEXCEPTIONNUMBER
1524     return v->toInt32(exec);
1525 }
1526
1527 uint32_t ScopedVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
1528 {
1529     JSValue* v = inlineEvaluate(exec);
1530     KJS_CHECKEXCEPTIONNUMBER
1531     return v->toUInt32(exec);
1532 }
1533
1534 JSValue* NonLocalVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
1535 {
1536     // Check for missed optimization opportunity.
1537     ASSERT(!canSkipLookup(exec, m_ident));
1538     
1539     return resolveAndCall<FunctionCall, false>(exec, m_ident, m_args.get(), m_scopeDepth);
1540 }
1541
1542 JSValue* NonLocalVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
1543 {
1544     return inlineEvaluate(exec);
1545 }
1546
1547 double NonLocalVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
1548 {
1549     JSValue* v = inlineEvaluate(exec);
1550     KJS_CHECKEXCEPTIONNUMBER
1551     return v->toNumber(exec);
1552 }
1553
1554 bool NonLocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
1555 {
1556     JSValue* v = inlineEvaluate(exec);
1557     KJS_CHECKEXCEPTIONBOOLEAN
1558     return v->toBoolean(exec);
1559 }
1560
1561 int32_t NonLocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
1562 {
1563     JSValue* v = inlineEvaluate(exec);
1564     KJS_CHECKEXCEPTIONNUMBER
1565     return v->toInt32(exec);
1566 }
1567
1568 uint32_t NonLocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
1569 {
1570     JSValue* v = inlineEvaluate(exec);
1571     KJS_CHECKEXCEPTIONNUMBER
1572     return v->toUInt32(exec);
1573 }
1574
1575 RegisterID* FunctionCallBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1576 {
1577     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1578     RegisterID* property = generator.emitNode(m_subscript.get());
1579     RegisterID* function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
1580     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
1581 }
1582
1583 void FunctionCallBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1584 {
1585     nodeStack.append(m_args.get());
1586     nodeStack.append(m_subscript.get());
1587     nodeStack.append(m_base.get());
1588 }
1589
1590 // ECMA 11.2.3
1591 JSValue* FunctionCallBracketNode::evaluate(OldInterpreterExecState* exec)
1592 {
1593     JSValue* baseVal = m_base->evaluate(exec);
1594     KJS_CHECKEXCEPTIONVALUE
1595
1596     JSValue* subscriptVal = m_subscript->evaluate(exec);
1597
1598     JSObject* baseObj = baseVal->toObject(exec);
1599     uint32_t i;
1600     PropertySlot slot;
1601
1602     JSValue* funcVal;
1603     if (subscriptVal->getUInt32(i)) {
1604         if (baseObj->getPropertySlot(exec, i, slot))
1605             funcVal = slot.getValue(exec, baseObj, i);
1606         else
1607             funcVal = jsUndefined();
1608     } else {
1609         Identifier ident(subscriptVal->toString(exec));
1610         if (baseObj->getPropertySlot(exec, ident, slot))
1611             funcVal = baseObj->get(exec, ident);
1612         else
1613             funcVal = jsUndefined();
1614     }
1615
1616     KJS_CHECKEXCEPTIONVALUE
1617
1618     if (!funcVal->isObject())
1619         return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, m_base.get(), m_subscript.get());
1620
1621     JSObject* func = static_cast<JSObject*>(funcVal);
1622
1623     if (!func->implementsCall())
1624         return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, m_base.get(), m_subscript.get());
1625
1626     List argList;
1627     m_args->evaluateList(exec, argList);
1628     KJS_CHECKEXCEPTIONVALUE
1629
1630     JSObject* thisObj = baseObj;
1631     ASSERT(thisObj);
1632     ASSERT(thisObj->isObject());
1633     ASSERT(!thisObj->isActivationObject());
1634
1635     // No need to call toThisObject() on the thisObj as it is known not to be the GlobalObject or ActivationObject
1636     return func->call(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 RegisterID* FunctionCallDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1652 {
1653     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1654     RegisterID* function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
1655     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
1656 }
1657
1658 void FunctionCallDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1659 {
1660     nodeStack.append(m_args.get());
1661     nodeStack.append(m_base.get());
1662 }
1663
1664 // ECMA 11.2.3
1665 JSValue* FunctionCallDotNode::inlineEvaluate(OldInterpreterExecState* exec)
1666 {
1667     JSValue* baseVal = m_base->evaluate(exec);
1668     KJS_CHECKEXCEPTIONVALUE
1669
1670     JSObject* baseObj = baseVal->toObject(exec);
1671     PropertySlot slot;
1672     JSValue* funcVal = baseObj->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, baseObj, m_ident) : jsUndefined();
1673     KJS_CHECKEXCEPTIONVALUE
1674
1675     if (!funcVal->isObject())
1676         return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, m_base.get(), m_ident);
1677
1678     JSObject* func = static_cast<JSObject*>(funcVal);
1679
1680     if (!func->implementsCall())
1681         return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, m_base.get(), m_ident);
1682
1683     List argList;
1684     m_args->evaluateList(exec, argList);
1685     KJS_CHECKEXCEPTIONVALUE
1686
1687     JSObject* thisObj = baseObj;
1688     ASSERT(thisObj);
1689     ASSERT(thisObj->isObject());
1690     ASSERT(!thisObj->isActivationObject());
1691
1692     // No need to call toThisObject() on the thisObj as it is known not to be the GlobalObject or ActivationObject
1693     return func->call(exec, thisObj, argList);
1694 }
1695
1696 JSValue* FunctionCallDotNode::evaluate(OldInterpreterExecState* exec)
1697 {
1698     return inlineEvaluate(exec);
1699 }
1700
1701 double FunctionCallDotNode::evaluateToNumber(OldInterpreterExecState* exec)
1702 {
1703     JSValue* v = inlineEvaluate(exec);
1704     KJS_CHECKEXCEPTIONNUMBER
1705     return v->toNumber(exec);
1706 }
1707
1708 bool FunctionCallDotNode::evaluateToBoolean(OldInterpreterExecState* exec)
1709 {
1710     JSValue* v = inlineEvaluate(exec);
1711     KJS_CHECKEXCEPTIONBOOLEAN
1712     return v->toBoolean(exec);
1713 }
1714
1715 int32_t FunctionCallDotNode::evaluateToInt32(OldInterpreterExecState* exec)
1716 {
1717     JSValue* v = inlineEvaluate(exec);
1718     KJS_CHECKEXCEPTIONNUMBER
1719     return v->toInt32(exec);
1720 }
1721
1722 uint32_t FunctionCallDotNode::evaluateToUInt32(OldInterpreterExecState* exec)
1723 {
1724     JSValue* v = inlineEvaluate(exec);
1725     KJS_CHECKEXCEPTIONNUMBER
1726     return v->toUInt32(exec);
1727 }
1728
1729 // ECMA 11.3
1730
1731 // ------------------------------ PostfixResolveNode ----------------------------------
1732
1733 RegisterID* PostIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1734 {
1735     // FIXME: I think we can detect the absense of dependent expressions here, 
1736     // and emit a PreInc instead of a PostInc. A post-pass to eliminate dead
1737     // code would work, too.
1738     if (RegisterID* local = generator.registerForLocal(m_ident)) {
1739         if (generator.isLocalConstant(m_ident))
1740             return generator.emitToJSNumber(generator.finalDestination(dst), local);
1741         
1742         return generator.emitPostInc(generator.finalDestination(dst), local);
1743     }
1744
1745     RefPtr<RegisterID> value = generator.newTemporary();
1746     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
1747     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
1748     generator.emitPutById(base.get(), m_ident, value.get());
1749     return oldValue;
1750 }
1751
1752 // Increment
1753 void PostIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
1754 {
1755     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
1756     if (index != missingSymbolMarker()) {
1757         if (isConstant(localStorage, index))
1758             new (this) PostIncConstNode(index);
1759         else
1760             new (this) PostIncLocalVarNode(index);
1761     }
1762 }
1763
1764 JSValue* PostIncResolveNode::evaluate(OldInterpreterExecState* exec)
1765 {
1766     // Check for missed optimization opportunity.
1767     ASSERT(!canSkipLookup(exec, m_ident));
1768
1769     const ScopeChain& chain = exec->scopeChain();
1770     ScopeChainIterator iter = chain.begin();
1771     ScopeChainIterator end = chain.end();
1772
1773     // we must always have something in the scope chain
1774     ASSERT(iter != end);
1775
1776     PropertySlot slot;
1777     do {
1778         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
1779             // If m_ident is 'arguments', the base->getPropertySlot() may cause 
1780             // base (which must be an ActivationImp in such this case) to be torn
1781             // off from the activation stack, in which case we need to get it again
1782             // from the ScopeChainIterator.
1783             
1784             JSObject* base = *iter;
1785             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1786             base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
1787             return v;
1788         }
1789
1790         ++iter;
1791     } while (iter != end);
1792
1793     return throwUndefinedVariableError(exec, m_ident);
1794 }
1795
1796 void PostIncResolveNode::optimizeForUnnecessaryResult()
1797 {
1798     new (this) PreIncResolveNode(PlacementNewAdopt);
1799 }
1800
1801 JSValue* PostIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
1802 {
1803     ASSERT(exec->variableObject() == exec->scopeChain().top());
1804
1805     JSValue** slot = &exec->localStorage()[m_index].value;
1806     JSValue* v = (*slot)->toJSNumber(exec);
1807     *slot = jsNumber(v->toNumber(exec) + 1);
1808     return v;
1809 }
1810
1811 void PostIncLocalVarNode::optimizeForUnnecessaryResult()
1812 {
1813     new (this) PreIncLocalVarNode(m_index);
1814 }
1815
1816 // Decrement
1817 RegisterID* PostDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1818 {
1819     // FIXME: I think we can detect the absense of dependent expressions here, 
1820     // and emit a PreDec instead of a PostDec. A post-pass to eliminate dead
1821     // code would work, too.
1822     if (RegisterID* local = generator.registerForLocal(m_ident)) {
1823         if (generator.isLocalConstant(m_ident))
1824             return generator.emitToJSNumber(generator.finalDestination(dst), local);
1825         
1826         return generator.emitPostDec(generator.finalDestination(dst), local);
1827     }
1828
1829     RefPtr<RegisterID> value = generator.newTemporary();
1830     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
1831     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
1832     generator.emitPutById(base.get(), m_ident, value.get());
1833     return oldValue;
1834 }
1835
1836 void PostDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
1837 {
1838     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
1839     if (index != missingSymbolMarker()) {
1840         if (isConstant(localStorage, index))
1841             new (this) PostDecConstNode(index);
1842         else
1843             new (this) PostDecLocalVarNode(index);
1844     }
1845 }
1846
1847 JSValue* PostDecResolveNode::evaluate(OldInterpreterExecState* exec)
1848 {
1849     // Check for missed optimization opportunity.
1850     ASSERT(!canSkipLookup(exec, m_ident));
1851
1852     const ScopeChain& chain = exec->scopeChain();
1853     ScopeChainIterator iter = chain.begin();
1854     ScopeChainIterator end = chain.end();
1855
1856     // we must always have something in the scope chain
1857     ASSERT(iter != end);
1858
1859     PropertySlot slot;
1860     do {
1861         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
1862             // See the comment in PostIncResolveNode::evaluate().
1863
1864             JSObject* base = *iter;
1865             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1866             base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
1867             return v;
1868         }
1869
1870         ++iter;
1871     } while (iter != end);
1872
1873     return throwUndefinedVariableError(exec, m_ident);
1874 }
1875
1876 void PostDecResolveNode::optimizeForUnnecessaryResult()
1877 {
1878     new (this) PreDecResolveNode(PlacementNewAdopt);
1879 }
1880
1881 JSValue* PostDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
1882 {
1883     ASSERT(exec->variableObject() == exec->scopeChain().top());
1884
1885     JSValue** slot = &exec->localStorage()[m_index].value;
1886     JSValue* v = (*slot)->toJSNumber(exec);
1887     *slot = jsNumber(v->toNumber(exec) - 1);
1888     return v;
1889 }
1890
1891 double PostDecLocalVarNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
1892 {
1893     ASSERT(exec->variableObject() == exec->scopeChain().top());
1894
1895     JSValue** slot = &exec->localStorage()[m_index].value;
1896     double n = (*slot)->toNumber(exec);
1897     *slot = jsNumber(n - 1);
1898     return n;
1899 }
1900
1901 double PostDecLocalVarNode::evaluateToNumber(OldInterpreterExecState* exec)
1902 {
1903     return inlineEvaluateToNumber(exec);
1904 }
1905
1906 bool PostDecLocalVarNode::evaluateToBoolean(OldInterpreterExecState* exec)
1907 {
1908     double result = inlineEvaluateToNumber(exec);
1909     return  result > 0.0 || 0.0 > result; // NaN produces false as well
1910 }
1911
1912 int32_t PostDecLocalVarNode::evaluateToInt32(OldInterpreterExecState* exec)
1913 {
1914     return JSValue::toInt32(inlineEvaluateToNumber(exec));
1915 }
1916
1917 uint32_t PostDecLocalVarNode::evaluateToUInt32(OldInterpreterExecState* exec)
1918 {
1919     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
1920 }
1921
1922 void PostDecLocalVarNode::optimizeForUnnecessaryResult()
1923 {
1924     new (this) PreDecLocalVarNode(m_index);
1925 }
1926
1927 // ------------------------------ PostfixBracketNode ----------------------------------
1928
1929 void PostfixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1930 {
1931     nodeStack.append(m_subscript.get());
1932     nodeStack.append(m_base.get());
1933 }
1934
1935 RegisterID* PostIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1936 {
1937     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1938     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1939     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1940     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
1941     generator.emitPutByVal(base.get(), property.get(), value.get());
1942     return oldValue;
1943 }
1944
1945 JSValue* PostIncBracketNode::evaluate(OldInterpreterExecState* exec)
1946 {
1947     JSValue* baseValue = m_base->evaluate(exec);
1948     KJS_CHECKEXCEPTIONVALUE
1949     JSValue* subscript = m_subscript->evaluate(exec);
1950     KJS_CHECKEXCEPTIONVALUE
1951
1952     JSObject* base = baseValue->toObject(exec);
1953
1954     uint32_t propertyIndex;
1955     if (subscript->getUInt32(propertyIndex)) {
1956         PropertySlot slot;
1957         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1958         KJS_CHECKEXCEPTIONVALUE
1959
1960         JSValue* v2 = v->toJSNumber(exec);
1961         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1));
1962
1963         return v2;
1964     }
1965
1966     Identifier propertyName(subscript->toString(exec));
1967     PropertySlot slot;
1968     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1969     KJS_CHECKEXCEPTIONVALUE
1970
1971     JSValue* v2 = v->toJSNumber(exec);
1972     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));
1973     return v2;
1974 }
1975
1976 RegisterID* PostDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1977 {
1978     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1979     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1980     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1981     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
1982     generator.emitPutByVal(base.get(), property.get(), value.get());
1983     return oldValue;
1984 }
1985
1986 JSValue* PostDecBracketNode::evaluate(OldInterpreterExecState* exec)
1987 {
1988     JSValue* baseValue = m_base->evaluate(exec);
1989     KJS_CHECKEXCEPTIONVALUE
1990     JSValue* subscript = m_subscript->evaluate(exec);
1991     KJS_CHECKEXCEPTIONVALUE
1992
1993     JSObject* base = baseValue->toObject(exec);
1994
1995     uint32_t propertyIndex;
1996     if (subscript->getUInt32(propertyIndex)) {
1997         PropertySlot slot;
1998         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1999         KJS_CHECKEXCEPTIONVALUE
2000
2001         JSValue* v2 = v->toJSNumber(exec);
2002         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1));
2003         return v2;
2004     }
2005
2006     Identifier propertyName(subscript->toString(exec));
2007     PropertySlot slot;
2008     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2009     KJS_CHECKEXCEPTIONVALUE
2010
2011     JSValue* v2 = v->toJSNumber(exec);
2012     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));
2013     return v2;
2014 }
2015
2016 // ------------------------------ PostfixDotNode ----------------------------------
2017
2018 void PostfixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2019 {
2020     nodeStack.append(m_base.get());
2021 }
2022
2023 RegisterID* PostIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2024 {
2025     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2026     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
2027     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
2028     generator.emitPutById(base.get(), m_ident, value.get());
2029     return oldValue;
2030 }
2031
2032 JSValue* PostIncDotNode::evaluate(OldInterpreterExecState* exec)
2033 {
2034     JSValue* baseValue = m_base->evaluate(exec);
2035     KJS_CHECKEXCEPTIONVALUE
2036     JSObject* base = baseValue->toObject(exec);
2037
2038     PropertySlot slot;
2039     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2040     KJS_CHECKEXCEPTIONVALUE
2041
2042     JSValue* v2 = v->toJSNumber(exec);
2043     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));
2044     return v2;
2045 }
2046
2047 RegisterID* PostDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2048 {
2049     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2050     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
2051     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
2052     generator.emitPutById(base.get(), m_ident, value.get());
2053     return oldValue;
2054 }
2055
2056 JSValue* PostDecDotNode::evaluate(OldInterpreterExecState* exec)
2057 {
2058     JSValue* baseValue = m_base->evaluate(exec);
2059     KJS_CHECKEXCEPTIONVALUE
2060     JSObject* base = baseValue->toObject(exec);
2061
2062     PropertySlot slot;
2063     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2064     KJS_CHECKEXCEPTIONVALUE
2065
2066     JSValue* v2 = v->toJSNumber(exec);
2067     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));
2068     return v2;
2069 }
2070
2071 // ------------------------------ PostfixErrorNode -----------------------------------
2072
2073 RegisterID* PostfixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
2074 {
2075     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.");
2076 }
2077
2078 JSValue* PostfixErrorNode::evaluate(OldInterpreterExecState* exec)
2079 {
2080     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
2081                m_operator == OpPlusPlus ? "++" : "--");
2082     handleException(exec);
2083     return jsUndefined();
2084 }
2085
2086 // ------------------------------ DeleteResolveNode -----------------------------------
2087
2088 RegisterID* DeleteResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2089 {
2090     if (generator.registerForLocal(m_ident))
2091         return generator.emitLoad(generator.finalDestination(dst), false);
2092
2093     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
2094     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
2095 }
2096
2097 void DeleteResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
2098 {
2099     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2100     if (index != missingSymbolMarker())
2101         new (this) LocalVarDeleteNode();
2102 }
2103
2104 // ECMA 11.4.1
2105
2106 JSValue* DeleteResolveNode::evaluate(OldInterpreterExecState* exec)
2107 {
2108     // Check for missed optimization opportunity.
2109     ASSERT(!canSkipLookup(exec, m_ident));
2110
2111     const ScopeChain& chain = exec->scopeChain();
2112     ScopeChainIterator iter = chain.begin();
2113     ScopeChainIterator end = chain.end();
2114
2115     // We must always have something in the scope chain
2116     ASSERT(iter != end);
2117
2118     PropertySlot slot;
2119     JSObject* base;
2120     do {
2121         base = *iter;
2122         if (base->getPropertySlot(exec, m_ident, slot))
2123             return jsBoolean(base->deleteProperty(exec, m_ident));
2124
2125         ++iter;
2126     } while (iter != end);
2127
2128     return jsBoolean(true);
2129 }
2130
2131 JSValue* LocalVarDeleteNode::evaluate(OldInterpreterExecState*)
2132 {
2133     return jsBoolean(false);
2134 }
2135
2136 // ------------------------------ DeleteBracketNode -----------------------------------
2137
2138 RegisterID* DeleteBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2139 {
2140     RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
2141     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript.get());
2142     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
2143 }
2144
2145 void DeleteBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2146 {
2147     nodeStack.append(m_subscript.get());
2148     nodeStack.append(m_base.get());
2149 }
2150
2151 JSValue* DeleteBracketNode::evaluate(OldInterpreterExecState* exec)
2152 {
2153     JSValue* baseValue = m_base->evaluate(exec);
2154     KJS_CHECKEXCEPTIONVALUE
2155     JSValue* subscript = m_subscript->evaluate(exec);
2156     KJS_CHECKEXCEPTIONVALUE
2157
2158     JSObject* base = baseValue->toObject(exec);
2159
2160     uint32_t propertyIndex;
2161     if (subscript->getUInt32(propertyIndex))
2162         return jsBoolean(base->deleteProperty(exec, propertyIndex));
2163
2164     Identifier propertyName(subscript->toString(exec));
2165     return jsBoolean(base->deleteProperty(exec, propertyName));
2166 }
2167
2168 // ------------------------------ DeleteDotNode -----------------------------------
2169
2170 RegisterID* DeleteDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2171 {
2172     RegisterID* r0 = generator.emitNode(m_base.get());
2173     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
2174 }
2175
2176 void DeleteDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2177 {
2178     nodeStack.append(m_base.get());
2179 }
2180
2181 JSValue* DeleteDotNode::evaluate(OldInterpreterExecState* exec)
2182 {
2183     JSValue* baseValue = m_base->evaluate(exec);
2184     JSObject* base = baseValue->toObject(exec);
2185     KJS_CHECKEXCEPTIONVALUE
2186
2187     return jsBoolean(base->deleteProperty(exec, m_ident));
2188 }
2189
2190 // ------------------------------ DeleteValueNode -----------------------------------
2191
2192 RegisterID* DeleteValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2193 {
2194     generator.emitNode(m_expr.get());
2195
2196     // delete on a non-location expression ignores the value and returns true
2197     return generator.emitLoad(generator.finalDestination(dst), true);
2198 }
2199
2200 void DeleteValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2201 {
2202     nodeStack.append(m_expr.get());
2203 }
2204
2205 JSValue* DeleteValueNode::evaluate(OldInterpreterExecState* exec)
2206 {
2207     m_expr->evaluate(exec);
2208     KJS_CHECKEXCEPTIONVALUE
2209
2210     // delete on a non-location expression ignores the value and returns true
2211     return jsBoolean(true);
2212 }
2213
2214 // ------------------------------ VoidNode -------------------------------------
2215
2216 RegisterID* VoidNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2217 {
2218     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2219     return generator.emitLoad(generator.finalDestination(dst, r0.get()), jsUndefined());
2220 }
2221
2222 void VoidNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2223 {
2224     nodeStack.append(m_expr.get());
2225 }
2226
2227 // ECMA 11.4.2
2228 JSValue* VoidNode::evaluate(OldInterpreterExecState* exec)
2229 {
2230     m_expr->evaluate(exec);
2231     KJS_CHECKEXCEPTIONVALUE
2232
2233     return jsUndefined();
2234 }
2235
2236 // ECMA 11.4.3
2237
2238 // ------------------------------ TypeOfValueNode -----------------------------------
2239
2240 void TypeOfValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2241 {
2242     nodeStack.append(m_expr.get());
2243 }
2244
2245 static JSValue* typeStringForValue(JSValue* v) KJS_FAST_CALL;
2246 static JSValue* typeStringForValue(JSValue* v)
2247 {
2248     switch (v->type()) {
2249         case UndefinedType:
2250             return jsString("undefined");
2251         case NullType:
2252             return jsString("object");
2253         case BooleanType:
2254             return jsString("boolean");
2255         case NumberType:
2256             return jsString("number");
2257         case StringType:
2258             return jsString("string");
2259         default:
2260             if (v->isObject()) {
2261                 // Return "undefined" for objects that should be treated
2262                 // as null when doing comparisons.
2263                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
2264                     return jsString("undefined");
2265                 else if (static_cast<JSObject*>(v)->implementsCall())
2266                     return jsString("function");
2267             }
2268
2269             return jsString("object");
2270     }
2271 }
2272
2273 void TypeOfResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
2274 {
2275     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2276     if (index != missingSymbolMarker())
2277         new (this) LocalVarTypeOfNode(index);
2278 }
2279
2280 JSValue* LocalVarTypeOfNode::evaluate(OldInterpreterExecState* exec)
2281 {
2282     ASSERT(exec->variableObject() == exec->scopeChain().top());
2283
2284     return typeStringForValue(exec->localStorage()[m_index].value);
2285 }
2286
2287 RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2288 {
2289     if (RegisterID* local = generator.registerForLocal(m_ident))
2290         return generator.emitTypeOf(generator.finalDestination(dst), local);
2291
2292     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
2293     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
2294     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
2295 }
2296
2297 JSValue* TypeOfResolveNode::evaluate(OldInterpreterExecState* exec)
2298 {
2299     const ScopeChain& chain = exec->scopeChain();
2300     ScopeChainIterator iter = chain.begin();
2301     ScopeChainIterator end = chain.end();
2302
2303     // We must always have something in the scope chain
2304     ASSERT(iter != end);
2305
2306     PropertySlot slot;
2307     JSObject* base;
2308     do {
2309         base = *iter;
2310         if (base->getPropertySlot(exec, m_ident, slot)) {
2311             JSValue* v = slot.getValue(exec, base, m_ident);
2312             return typeStringForValue(v);
2313         }
2314
2315         ++iter;
2316     } while (iter != end);
2317
2318     return jsString("undefined");
2319 }
2320
2321 // ------------------------------ TypeOfValueNode -----------------------------------
2322
2323 RegisterID* TypeOfValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2324 {
2325     RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
2326     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
2327 }
2328
2329 JSValue* TypeOfValueNode::evaluate(OldInterpreterExecState* exec)
2330 {
2331     JSValue* v = m_expr->evaluate(exec);
2332     KJS_CHECKEXCEPTIONVALUE
2333
2334     return typeStringForValue(v);
2335 }
2336
2337 // ECMA 11.4.4 and 11.4.5
2338
2339 // ------------------------------ PrefixResolveNode ----------------------------------
2340
2341 RegisterID* PreIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2342 {
2343     if (RegisterID* local = generator.registerForLocal(m_ident)) {
2344         if (generator.isLocalConstant(m_ident)) {
2345             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), 1.0);
2346             return generator.emitAdd(r0.get(), local, r0.get());
2347         }
2348         
2349         generator.emitPreInc(local);
2350         return generator.moveToDestinationIfNeeded(dst, local);
2351     }
2352     
2353     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2354     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
2355     generator.emitPreInc(propDst.get());
2356     generator.emitPutById(base.get(), m_ident, propDst.get());
2357     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2358 }
2359
2360 void PreIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
2361 {
2362     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2363     if (index != missingSymbolMarker()) {
2364         if (isConstant(localStorage, index))
2365             new (this) PreIncConstNode(index);
2366         else
2367             new (this) PreIncLocalVarNode(index);
2368     }
2369 }
2370
2371 JSValue* PreIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
2372 {
2373     ASSERT(exec->variableObject() == exec->scopeChain().top());
2374     JSValue** slot = &exec->localStorage()[m_index].value;
2375
2376     double n = (*slot)->toNumber(exec);
2377     JSValue* n2 = jsNumber(n + 1);
2378     *slot = n2;
2379     return n2;
2380 }
2381
2382 JSValue* PreIncResolveNode::evaluate(OldInterpreterExecState* exec)
2383 {
2384     const ScopeChain& chain = exec->scopeChain();
2385     ScopeChainIterator iter = chain.begin();
2386     ScopeChainIterator end = chain.end();
2387
2388     // we must always have something in the scope chain
2389     ASSERT(iter != end);
2390
2391     PropertySlot slot;
2392     do {
2393         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
2394             // See the comment in PostIncResolveNode::evaluate().
2395
2396             JSObject* base = *iter;
2397             JSValue* v = slot.getValue(exec, base, m_ident);
2398
2399             double n = v->toNumber(exec);
2400             JSValue* n2 = jsNumber(n + 1);
2401             base->put(exec, m_ident, n2);
2402
2403             return n2;
2404         }
2405
2406         ++iter;
2407     } while (iter != end);
2408
2409     return throwUndefinedVariableError(exec, m_ident);
2410 }
2411
2412 RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2413 {
2414     if (RegisterID* local = generator.registerForLocal(m_ident)) {
2415         if (generator.isLocalConstant(m_ident)) {
2416             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), -1.0);
2417             return generator.emitAdd(r0.get(), local, r0.get());
2418         }
2419         
2420         generator.emitPreDec(local);
2421         return generator.moveToDestinationIfNeeded(dst, local);
2422     }
2423
2424     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2425     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
2426     generator.emitPreDec(propDst.get());
2427     generator.emitPutById(base.get(), m_ident, propDst.get());
2428     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2429 }
2430
2431 void PreDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
2432 {
2433     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2434     if (index != missingSymbolMarker()) {
2435         if (isConstant(localStorage, index))
2436             new (this) PreDecConstNode(index);
2437         else
2438             new (this) PreDecLocalVarNode(index);
2439     }
2440 }
2441
2442 JSValue* PreDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
2443 {
2444     ASSERT(exec->variableObject() == exec->scopeChain().top());
2445     JSValue** slot = &exec->localStorage()[m_index].value;
2446
2447     double n = (*slot)->toNumber(exec);
2448     JSValue* n2 = jsNumber(n - 1);
2449     *slot = n2;
2450     return n2;
2451 }
2452
2453 JSValue* PreDecResolveNode::evaluate(OldInterpreterExecState* exec)
2454 {
2455     const ScopeChain& chain = exec->scopeChain();
2456     ScopeChainIterator iter = chain.begin();
2457     ScopeChainIterator end = chain.end();
2458
2459     // we must always have something in the scope chain
2460     ASSERT(iter != end);
2461
2462     PropertySlot slot;
2463     do {
2464         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
2465             // See the comment in PostIncResolveNode::evaluate().
2466
2467             JSObject* base = *iter;
2468             JSValue* v = slot.getValue(exec, base, m_ident);
2469
2470             double n = v->toNumber(exec);
2471             JSValue* n2 = jsNumber(n - 1);
2472             base->put(exec, m_ident, n2);
2473
2474             return n2;
2475         }
2476
2477         ++iter;
2478     } while (iter != end);
2479
2480     return throwUndefinedVariableError(exec, m_ident);
2481 }
2482
2483 // ------------------------------ PreIncConstNode ----------------------------------
2484
2485 JSValue* PreIncConstNode::evaluate(OldInterpreterExecState* exec)
2486 {
2487     ASSERT(exec->variableObject() == exec->scopeChain().top());
2488     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) + 1);
2489 }
2490
2491 // ------------------------------ PreDecConstNode ----------------------------------
2492
2493 JSValue* PreDecConstNode::evaluate(OldInterpreterExecState* exec)
2494 {
2495     ASSERT(exec->variableObject() == exec->scopeChain().top());
2496     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) - 1);
2497 }
2498
2499 // ------------------------------ PostIncConstNode ----------------------------------
2500
2501 JSValue* PostIncConstNode::evaluate(OldInterpreterExecState* exec)
2502 {
2503     ASSERT(exec->variableObject() == exec->scopeChain().top());
2504     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
2505 }
2506
2507 // ------------------------------ PostDecConstNode ----------------------------------
2508
2509 JSValue* PostDecConstNode::evaluate(OldInterpreterExecState* exec)
2510 {
2511     ASSERT(exec->variableObject() == exec->scopeChain().top());
2512     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
2513 }
2514
2515 // ------------------------------ PrefixBracketNode ----------------------------------
2516
2517 void PrefixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2518 {
2519     nodeStack.append(m_subscript.get());
2520     nodeStack.append(m_base.get());
2521 }
2522
2523 RegisterID* PreIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2524 {
2525     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2526     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
2527     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2528     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
2529     generator.emitPreInc(value);
2530     generator.emitPutByVal(base.get(), property.get(), value);
2531     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2532 }
2533
2534 JSValue* PreIncBracketNode::evaluate(OldInterpreterExecState* exec)
2535 {
2536     JSValue* baseValue = m_base->evaluate(exec);
2537     KJS_CHECKEXCEPTIONVALUE
2538     JSValue* subscript = m_subscript->evaluate(exec);
2539     KJS_CHECKEXCEPTIONVALUE
2540
2541     JSObject* base = baseValue->toObject(exec);
2542
2543     uint32_t propertyIndex;
2544     if (subscript->getUInt32(propertyIndex)) {
2545         PropertySlot slot;
2546         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2547         KJS_CHECKEXCEPTIONVALUE
2548
2549         JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
2550         base->put(exec, propertyIndex, n2);
2551
2552         return n2;
2553     }
2554
2555     Identifier propertyName(subscript->toString(exec));
2556     PropertySlot slot;
2557     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2558     KJS_CHECKEXCEPTIONVALUE
2559
2560     JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
2561     base->put(exec, propertyName, n2);
2562
2563     return n2;
2564 }
2565
2566 RegisterID* PreDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2567 {
2568     
2569     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2570     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
2571     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2572     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
2573     generator.emitPreDec(value);
2574     generator.emitPutByVal(base.get(), property.get(), value);
2575     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2576 }
2577
2578 JSValue* PreDecBracketNode::evaluate(OldInterpreterExecState* exec)
2579 {
2580     JSValue* baseValue = m_base->evaluate(exec);
2581     KJS_CHECKEXCEPTIONVALUE
2582     JSValue* subscript = m_subscript->evaluate(exec);
2583     KJS_CHECKEXCEPTIONVALUE
2584
2585     JSObject* base = baseValue->toObject(exec);
2586
2587     uint32_t propertyIndex;
2588     if (subscript->getUInt32(propertyIndex)) {
2589         PropertySlot slot;
2590         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2591         KJS_CHECKEXCEPTIONVALUE
2592
2593         JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
2594         base->put(exec, propertyIndex, n2);
2595
2596         return n2;
2597     }
2598
2599     Identifier propertyName(subscript->toString(exec));
2600     PropertySlot slot;
2601     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2602     KJS_CHECKEXCEPTIONVALUE
2603
2604     JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
2605     base->put(exec, propertyName, n2);
2606
2607     return n2;
2608 }
2609
2610 // ------------------------------ PrefixDotNode ----------------------------------
2611
2612 void PrefixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2613 {
2614     nodeStack.append(m_base.get());
2615 }
2616
2617 RegisterID* PreIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2618 {
2619     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2620     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2621     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
2622     generator.emitPreInc(value);
2623     generator.emitPutById(base.get(), m_ident, value);
2624     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2625 }
2626
2627 JSValue* PreIncDotNode::evaluate(OldInterpreterExecState* exec)
2628 {
2629     JSValue* baseValue = m_base->evaluate(exec);
2630     KJS_CHECKEXCEPTIONVALUE
2631     JSObject* base = baseValue->toObject(exec);
2632
2633     PropertySlot slot;
2634     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2635     KJS_CHECKEXCEPTIONVALUE
2636
2637     double n = v->toNumber(exec);
2638     JSValue* n2 = jsNumber(n + 1);
2639     base->put(exec, m_ident, n2);
2640
2641     return n2;
2642 }
2643
2644 RegisterID* PreDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2645 {
2646     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2647     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2648     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
2649     generator.emitPreDec(value);
2650     generator.emitPutById(base.get(), m_ident, value);
2651     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2652 }
2653
2654 JSValue* PreDecDotNode::evaluate(OldInterpreterExecState* exec)
2655 {
2656     JSValue* baseValue = m_base->evaluate(exec);
2657     KJS_CHECKEXCEPTIONVALUE
2658     JSObject* base = baseValue->toObject(exec);
2659
2660     PropertySlot slot;
2661     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2662     KJS_CHECKEXCEPTIONVALUE
2663
2664     double n = v->toNumber(exec);
2665     JSValue* n2 = jsNumber(n - 1);
2666     base->put(exec, m_ident, n2);
2667
2668     return n2;
2669 }
2670
2671 // ------------------------------ PrefixErrorNode -----------------------------------
2672
2673 RegisterID* PrefixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
2674 {
2675     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.");
2676 }
2677
2678 JSValue* PrefixErrorNode::evaluate(OldInterpreterExecState* exec)
2679 {
2680     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
2681                m_operator == OpPlusPlus ? "++" : "--");
2682     handleException(exec);
2683     return jsUndefined();
2684 }
2685
2686 // ------------------------------ UnaryPlusNode --------------------------------
2687
2688 RegisterID* UnaryPlusNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2689 {
2690     RegisterID* src = generator.emitNode(m_expr.get());
2691     return generator.emitToJSNumber(generator.finalDestination(dst), src);
2692 }
2693
2694 void UnaryPlusNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2695 {
2696     nodeStack.append(m_expr.get());
2697 }
2698
2699 // ECMA 11.4.6
2700 JSValue* UnaryPlusNode::evaluate(OldInterpreterExecState* exec)
2701 {
2702     JSValue* v = m_expr->evaluate(exec);
2703     KJS_CHECKEXCEPTIONVALUE
2704     return v->toJSNumber(exec);
2705 }
2706
2707 bool UnaryPlusNode::evaluateToBoolean(OldInterpreterExecState* exec)
2708 {
2709     return m_expr->evaluateToBoolean(exec);
2710 }
2711
2712 double UnaryPlusNode::evaluateToNumber(OldInterpreterExecState* exec)
2713 {
2714     return m_expr->evaluateToNumber(exec);
2715 }
2716
2717 int32_t UnaryPlusNode::evaluateToInt32(OldInterpreterExecState* exec)
2718 {
2719     return m_expr->evaluateToInt32(exec);
2720 }
2721
2722 uint32_t UnaryPlusNode::evaluateToUInt32(OldInterpreterExecState* exec)
2723 {
2724     return m_expr->evaluateToInt32(exec);
2725 }
2726
2727 // ------------------------------ NegateNode -----------------------------------
2728
2729 RegisterID* NegateNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2730 {
2731     RegisterID* src = generator.emitNode(m_expr.get());
2732     return generator.emitNegate(generator.finalDestination(dst), src);
2733 }
2734
2735 void NegateNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2736 {
2737     nodeStack.append(m_expr.get());
2738 }
2739
2740 // ECMA 11.4.7
2741 JSValue* NegateNode::evaluate(OldInterpreterExecState* exec)
2742 {
2743     // No need to check exception, caller will do so right after evaluate()
2744     return jsNumber(-m_expr->evaluateToNumber(exec));
2745 }
2746
2747 double NegateNode::evaluateToNumber(OldInterpreterExecState* exec)
2748 {
2749     // No need to check exception, caller will do so right after evaluateToNumber()
2750     return -m_expr->evaluateToNumber(exec);
2751 }
2752
2753 // ------------------------------ BitwiseNotNode -------------------------------
2754
2755 RegisterID* BitwiseNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2756 {
2757     RegisterID* src = generator.emitNode(m_expr.get());
2758     return generator.emitBitNot(generator.finalDestination(dst), src);
2759 }
2760
2761 void BitwiseNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2762 {
2763     nodeStack.append(m_expr.get());
2764 }
2765
2766 // ECMA 11.4.8
2767 int32_t BitwiseNotNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
2768 {
2769     return ~m_expr->evaluateToInt32(exec);
2770 }
2771
2772 JSValue* BitwiseNotNode::evaluate(OldInterpreterExecState* exec)
2773 {
2774     return jsNumber(inlineEvaluateToInt32(exec));
2775 }
2776
2777 double BitwiseNotNode::evaluateToNumber(OldInterpreterExecState* exec)
2778 {
2779     return inlineEvaluateToInt32(exec);
2780 }
2781
2782 bool BitwiseNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
2783 {
2784     return inlineEvaluateToInt32(exec);
2785 }
2786
2787 int32_t BitwiseNotNode::evaluateToInt32(OldInterpreterExecState* exec)
2788 {
2789     return inlineEvaluateToInt32(exec);
2790 }
2791
2792 uint32_t BitwiseNotNode::evaluateToUInt32(OldInterpreterExecState* exec)
2793 {
2794     return inlineEvaluateToInt32(exec);
2795 }
2796
2797 // ------------------------------ LogicalNotNode -------------------------------
2798
2799 RegisterID* LogicalNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2800 {
2801     RegisterID* src = generator.emitNode(m_expr.get());
2802     return generator.emitNot(generator.finalDestination(dst), src);
2803 }
2804
2805 void LogicalNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2806 {
2807     nodeStack.append(m_expr.get());
2808 }
2809
2810 // ECMA 11.4.9
2811 JSValue* LogicalNotNode::evaluate(OldInterpreterExecState* exec)
2812 {
2813     return jsBoolean(!m_expr->evaluateToBoolean(exec));
2814 }
2815
2816 bool LogicalNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
2817 {
2818     return !m_expr->evaluateToBoolean(exec);
2819 }
2820
2821 // ------------------------------ Multiplicative Nodes -----------------------------------
2822
2823 RegisterID* MultNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2824 {
2825     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
2826     RegisterID* src2 = generator.emitNode(m_term2.get());
2827     return generator.emitMul(generator.finalDestination(dst, src1.get()), src1.get(), src2);
2828 }
2829
2830 void MultNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2831 {
2832     nodeStack.append(m_term1.get());
2833     nodeStack.append(m_term2.get());
2834 }
2835
2836 // ECMA 11.5.1
2837 double MultNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
2838 {
2839     double n1 = m_term1->evaluateToNumber(exec);
2840     KJS_CHECKEXCEPTIONNUMBER
2841     double n2 = m_term2->evaluateToNumber(exec);
2842     return n1 * n2;
2843 }
2844
2845 JSValue* MultNode::evaluate(OldInterpreterExecState* exec)
2846 {
2847     return jsNumber(inlineEvaluateToNumber(exec));
2848 }
2849
2850 double MultNode::evaluateToNumber(OldInterpreterExecState* exec)
2851 {
2852     return inlineEvaluateToNumber(exec);
2853 }
2854
2855 bool MultNode::evaluateToBoolean(OldInterpreterExecState* exec)
2856 {
2857     double result = inlineEvaluateToNumber(exec);
2858     return  result > 0.0 || 0.0 > result; // NaN produces false as well
2859 }
2860
2861 int32_t MultNode::evaluateToInt32(OldInterpreterExecState* exec)
2862 {
2863     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2864 }
2865
2866 uint32_t MultNode::evaluateToUInt32(OldInterpreterExecState* exec)
2867 {
2868     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2869 }
2870
2871 RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2872 {
2873     RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
2874     RegisterID* divisor = generator.emitNode(m_term2.get());
2875     return generator.emitDiv(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
2876 }
2877
2878 void DivNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2879 {
2880     nodeStack.append(m_term1.get());
2881     nodeStack.append(m_term2.get());
2882 }
2883
2884 // ECMA 11.5.2
2885 double DivNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
2886 {
2887     double n1 = m_term1->evaluateToNumber(exec);
2888     KJS_CHECKEXCEPTIONNUMBER
2889     double n2 = m_term2->evaluateToNumber(exec);
2890     return n1 / n2;
2891 }
2892
2893 JSValue* DivNode::evaluate(OldInterpreterExecState* exec)
2894 {
2895     return jsNumber(inlineEvaluateToNumber(exec));
2896 }
2897
2898 double DivNode::evaluateToNumber(OldInterpreterExecState* exec)
2899 {
2900     return inlineEvaluateToNumber(exec);
2901 }
2902
2903 int32_t DivNode::evaluateToInt32(OldInterpreterExecState* exec)
2904 {
2905     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2906 }
2907
2908 uint32_t DivNode::evaluateToUInt32(OldInterpreterExecState* exec)
2909 {
2910     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2911 }
2912
2913 RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2914 {
2915     RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
2916     RegisterID* divisor = generator.emitNode(m_term2.get());
2917     return generator.emitMod(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
2918 }
2919
2920 void ModNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2921 {
2922     nodeStack.append(m_term1.get());
2923     nodeStack.append(m_term2.get());
2924 }
2925
2926 // ECMA 11.5.3
2927 double ModNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
2928 {
2929     double n1 = m_term1->evaluateToNumber(exec);
2930     KJS_CHECKEXCEPTIONNUMBER
2931     double n2 = m_term2->evaluateToNumber(exec);
2932     return fmod(n1, n2);
2933 }
2934
2935 JSValue* ModNode::evaluate(OldInterpreterExecState* exec)
2936 {
2937     return jsNumber(inlineEvaluateToNumber(exec));
2938 }
2939
2940 double ModNode::evaluateToNumber(OldInterpreterExecState* exec)
2941 {
2942     return inlineEvaluateToNumber(exec);
2943 }
2944
2945 bool ModNode::evaluateToBoolean(OldInterpreterExecState* exec)
2946 {
2947     double result = inlineEvaluateToNumber(exec);
2948     return  result > 0.0 || 0.0 > result; // NaN produces false as well
2949 }
2950
2951 int32_t ModNode::evaluateToInt32(OldInterpreterExecState* exec)
2952 {
2953     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2954 }
2955
2956 uint32_t ModNode::evaluateToUInt32(OldInterpreterExecState* exec)
2957 {
2958     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2959 }
2960
2961 // ------------------------------ Additive Nodes --------------------------------------
2962
2963 static double throwOutOfMemoryErrorToNumber(OldInterpreterExecState* exec)
2964 {
2965     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
2966     exec->setException(error);
2967     return 0.0;
2968 }
2969
2970 // ECMA 11.6
2971 static JSValue* addSlowCase(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
2972 {
2973     // exception for the Date exception in defaultValue()
2974     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
2975     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
2976
2977     if (p1->isString() || p2->isString()) {
2978         UString value = p1->toString(exec) + p2->toString(exec);
2979         if (value.isNull())
2980             return throwOutOfMemoryError(exec);
2981         return jsString(value);
2982     }
2983
2984     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
2985 }
2986
2987 static double addSlowCaseToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
2988 {
2989     // exception for the Date exception in defaultValue()
2990     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
2991     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
2992
2993     if (p1->isString() || p2->isString()) {
2994         UString value = p1->toString(exec) + p2->toString(exec);
2995         if (value.isNull())
2996             return throwOutOfMemoryErrorToNumber(exec);
2997         return value.toDouble();
2998     }
2999
3000     return p1->toNumber(exec) + p2->toNumber(exec);
3001 }
3002
3003 // Fast-path choices here are based on frequency data from SunSpider:
3004 //    <times> Add case: <t1> <t2>
3005 //    ---------------------------
3006 //    5627160 Add case: 1 1
3007 //    247427  Add case: 5 5
3008 //    20901   Add case: 5 6
3009 //    13978   Add case: 5 1
3010 //    4000    Add case: 1 5
3011 //    1       Add case: 3 5
3012
3013 static inline JSValue* add(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3014 {
3015     JSType t1 = v1->type();
3016     JSType t2 = v2->type();
3017     const unsigned bothTypes = (t1 << 3) | t2;
3018
3019     if (bothTypes == ((NumberType << 3) | NumberType))
3020         return jsNumber(v1->toNumber(exec) + v2->toNumber(exec));
3021     if (bothTypes == ((StringType << 3) | StringType)) {
3022         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
3023         if (value.isNull())
3024             return throwOutOfMemoryError(exec);
3025         return jsString(value);
3026     }
3027
3028     // All other cases are pretty uncommon
3029     return addSlowCase(exec, v1, v2);
3030 }
3031
3032 static inline double addToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3033 {
3034     JSType t1 = v1->type();
3035     JSType t2 = v2->type();
3036     const unsigned bothTypes = (t1 << 3) | t2;
3037
3038     if (bothTypes == ((NumberType << 3) | NumberType))
3039         return v1->toNumber(exec) + v2->toNumber(exec);
3040     if (bothTypes == ((StringType << 3) | StringType)) {
3041         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
3042         if (value.isNull())
3043             return throwOutOfMemoryErrorToNumber(exec);
3044         return value.toDouble();
3045     }
3046
3047     // All other cases are pretty uncommon
3048     return addSlowCaseToNumber(exec, v1, v2);
3049 }
3050
3051 RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3052 {
3053     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
3054     RegisterID* src2 = generator.emitNode(m_term2.get());
3055     return generator.emitAdd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3056 }
3057
3058 void AddNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3059 {
3060     nodeStack.append(m_term1.get());
3061     nodeStack.append(m_term2.get());
3062 }
3063
3064 // ECMA 11.6.1
3065 JSValue* AddNode::evaluate(OldInterpreterExecState* exec)
3066 {
3067     JSValue* v1 = m_term1->evaluate(exec);
3068     KJS_CHECKEXCEPTIONVALUE
3069
3070     JSValue* v2 = m_term2->evaluate(exec);
3071     KJS_CHECKEXCEPTIONVALUE
3072
3073     return add(exec, v1, v2);
3074 }
3075
3076 double AddNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
3077 {
3078     JSValue* v1 = m_term1->evaluate(exec);
3079     KJS_CHECKEXCEPTIONNUMBER
3080
3081     JSValue* v2 = m_term2->evaluate(exec);
3082     KJS_CHECKEXCEPTIONNUMBER
3083
3084     return addToNumber(exec, v1, v2);
3085 }
3086
3087 double AddNode::evaluateToNumber(OldInterpreterExecState* exec)
3088 {
3089     return inlineEvaluateToNumber(exec);
3090 }
3091
3092 int32_t AddNode::evaluateToInt32(OldInterpreterExecState* exec)
3093 {
3094     return JSValue::toInt32(inlineEvaluateToNumber(exec));
3095 }
3096
3097 uint32_t AddNode::evaluateToUInt32(OldInterpreterExecState* exec)
3098 {
3099     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
3100 }
3101
3102 double AddNumbersNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
3103 {
3104     double n1 = m_term1->evaluateToNumber(exec);
3105     KJS_CHECKEXCEPTIONNUMBER
3106     double n2 = m_term2->evaluateToNumber(exec);
3107     return n1 + n2;
3108 }
3109
3110 JSValue* AddNumbersNode::evaluate(OldInterpreterExecState* exec)
3111 {
3112     return jsNumber(inlineEvaluateToNumber(exec));
3113 }
3114
3115 double AddNumbersNode::evaluateToNumber(OldInterpreterExecState* exec)
3116 {
3117     return inlineEvaluateToNumber(exec);
3118 }
3119
3120 int32_t AddNumbersNode::evaluateToInt32(OldInterpreterExecState* exec)
3121 {
3122     return JSValue::toInt32(inlineEvaluateToNumber(exec));
3123 }
3124
3125 uint32_t AddNumbersNode::evaluateToUInt32(OldInterpreterExecState* exec)
3126 {
3127     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
3128 }
3129
3130 JSValue* AddStringsNode::evaluate(OldInterpreterExecState* exec)
3131 {
3132     JSValue* v1 = m_term1->evaluate(exec);
3133     KJS_CHECKEXCEPTIONVALUE
3134
3135     JSValue* v2 = m_term2->evaluate(exec);
3136     KJS_CHECKEXCEPTIONVALUE
3137
3138     return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
3139 }
3140
3141 JSValue* AddStringLeftNode::evaluate(OldInterpreterExecState* exec)
3142 {
3143     JSValue* v1 = m_term1->evaluate(exec);
3144     KJS_CHECKEXCEPTIONVALUE
3145
3146     JSValue* v2 = m_term2->evaluate(exec);
3147     KJS_CHECKEXCEPTIONVALUE
3148
3149     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
3150     return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
3151 }
3152
3153 JSValue* AddStringRightNode::evaluate(OldInterpreterExecState* exec)
3154 {
3155     JSValue* v1 = m_term1->evaluate(exec);
3156     KJS_CHECKEXCEPTIONVALUE
3157
3158     JSValue* v2 = m_term2->evaluate(exec);
3159     KJS_CHECKEXCEPTIONVALUE
3160
3161     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
3162     return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
3163 }
3164
3165 RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3166 {
3167     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
3168     RegisterID* src2 = generator.emitNode(m_term2.get());
3169     return generator.emitSub(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3170 }
3171
3172 void SubNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3173 {
3174     nodeStack.append(m_term1.get());
3175     nodeStack.append(m_term2.get());
3176 }
3177
3178 // ECMA 11.6.2
3179 double SubNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
3180 {
3181     double n1 = m_term1->evaluateToNumber(exec);
3182     KJS_CHECKEXCEPTIONNUMBER
3183     double n2 = m_term2->evaluateToNumber(exec);
3184     return n1 - n2;
3185 }
3186
3187 JSValue* SubNode::evaluate(OldInterpreterExecState* exec)
3188 {
3189     return jsNumber(inlineEvaluateToNumber(exec));
3190 }
3191
3192 double SubNode::evaluateToNumber(OldInterpreterExecState* exec)
3193 {
3194     return inlineEvaluateToNumber(exec);
3195 }
3196
3197 int32_t SubNode::evaluateToInt32(OldInterpreterExecState* exec)
3198 {
3199     return JSValue::toInt32(inlineEvaluateToNumber(exec));
3200 }
3201
3202 uint32_t SubNode::evaluateToUInt32(OldInterpreterExecState* exec)
3203 {
3204     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
3205 }
3206
3207 // ------------------------------ Shift Nodes ------------------------------------
3208
3209 RegisterID* LeftShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3210 {
3211     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
3212     RegisterID* shift = generator.emitNode(m_term2.get());
3213     return generator.emitLeftShift(generator.finalDestination(dst, val.get()), val.get(), shift);
3214 }
3215
3216 void LeftShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3217 {
3218     nodeStack.append(m_term1.get());
3219     nodeStack.append(m_term2.get());
3220 }
3221
3222 // ECMA 11.7.1
3223 int32_t LeftShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3224 {
3225     int i1 = m_term1->evaluateToInt32(exec);
3226     KJS_CHECKEXCEPTIONNUMBER
3227     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
3228     return (i1 << i2);
3229 }
3230
3231 JSValue* LeftShiftNode::evaluate(OldInterpreterExecState* exec)
3232 {
3233     return jsNumber(inlineEvaluateToInt32(exec));
3234 }
3235
3236 double LeftShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
3237 {
3238     return inlineEvaluateToInt32(exec);
3239 }
3240
3241 int32_t LeftShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
3242 {
3243     return inlineEvaluateToInt32(exec);
3244 }
3245
3246 uint32_t LeftShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
3247 {
3248     return inlineEvaluateToInt32(exec);
3249 }
3250
3251 RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3252 {
3253     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
3254     RegisterID* shift = generator.emitNode(m_term2.get());
3255     return generator.emitRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
3256 }
3257
3258 void RightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3259 {
3260     nodeStack.append(m_term1.get());
3261     nodeStack.append(m_term2.get());
3262 }
3263
3264 // ECMA 11.7.2
3265 int32_t RightShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3266 {
3267     int i1 = m_term1->evaluateToInt32(exec);
3268     KJS_CHECKEXCEPTIONNUMBER
3269     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
3270     return (i1 >> i2);
3271 }
3272
3273 JSValue* RightShiftNode::evaluate(OldInterpreterExecState* exec)
3274 {
3275     return jsNumber(inlineEvaluateToInt32(exec));
3276 }
3277
3278 double RightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
3279 {
3280     return inlineEvaluateToInt32(exec);
3281 }
3282
3283 int32_t RightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
3284 {
3285     return inlineEvaluateToInt32(exec);
3286 }
3287
3288 uint32_t RightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
3289 {
3290     return inlineEvaluateToInt32(exec);
3291 }
3292
3293 RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3294 {
3295     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
3296     RegisterID* shift = generator.emitNode(m_term2.get());
3297     return generator.emitUnsignedRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
3298 }
3299
3300 void UnsignedRightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3301 {
3302     nodeStack.append(m_term1.get());
3303     nodeStack.append(m_term2.get());
3304 }
3305
3306 // ECMA 11.7.3
3307 uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(OldInterpreterExecState* exec)
3308 {
3309     unsigned int i1 = m_term1->evaluateToUInt32(exec);
3310     KJS_CHECKEXCEPTIONNUMBER
3311     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
3312     return (i1 >> i2);
3313 }
3314
3315 JSValue* UnsignedRightShiftNode::evaluate(OldInterpreterExecState* exec)
3316 {
3317     return jsNumber(inlineEvaluateToUInt32(exec));
3318 }
3319
3320 double UnsignedRightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
3321 {
3322     return inlineEvaluateToUInt32(exec);
3323 }
3324
3325 int32_t UnsignedRightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
3326 {
3327     return inlineEvaluateToUInt32(exec);
3328 }
3329
3330 uint32_t UnsignedRightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
3331 {
3332     return inlineEvaluateToUInt32(exec);
3333 }
3334
3335 // ------------------------------ Relational Nodes -------------------------------
3336
3337 static inline bool lessThan(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3338 {
3339     double n1;
3340     double n2;
3341     JSValue* p1;
3342     JSValue* p2;
3343     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
3344     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
3345
3346     if (wasNotString1 | wasNotString2)
3347         return n1 < n2;
3348
3349     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
3350 }
3351
3352 static inline bool lessThanEq(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3353 {
3354     double n1;
3355     double n2;
3356     JSValue* p1;
3357     JSValue* p2;
3358     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
3359     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
3360
3361     if (wasNotString1 | wasNotString2)
3362         return n1 <= n2;
3363
3364     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
3365 }
3366
3367 RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3368 {
3369     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3370     RegisterID* src2 = generator.emitNode(m_expr2.get());
3371     return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3372 }
3373
3374 void LessNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3375 {
3376     nodeStack.append(m_expr2.get());
3377     nodeStack.append(m_expr1.get());
3378 }
3379
3380 // ECMA 11.8.1
3381 bool LessNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3382 {
3383     JSValue* v1 = m_expr1->evaluate(exec);
3384     KJS_CHECKEXCEPTIONBOOLEAN
3385     JSValue* v2 = m_expr2->evaluate(exec);
3386     KJS_CHECKEXCEPTIONBOOLEAN
3387     return lessThan(exec, v1, v2);
3388 }
3389
3390 JSValue* LessNode::evaluate(OldInterpreterExecState* exec)
3391 {
3392     return jsBoolean(inlineEvaluateToBoolean(exec));
3393 }
3394
3395 bool LessNode::evaluateToBoolean(OldInterpreterExecState* exec)
3396 {
3397     return inlineEvaluateToBoolean(exec);
3398 }
3399
3400 bool LessNumbersNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3401 {
3402     double n1 = m_expr1->evaluateToNumber(exec);
3403     KJS_CHECKEXCEPTIONVALUE
3404     double n2 = m_expr2->evaluateToNumber(exec);
3405     return n1 < n2;
3406 }
3407
3408 JSValue* LessNumbersNode::evaluate(OldInterpreterExecState* exec)
3409 {
3410     return jsBoolean(inlineEvaluateToBoolean(exec));
3411 }
3412
3413 bool LessNumbersNode::evaluateToBoolean(OldInterpreterExecState* exec)
3414 {
3415     return inlineEvaluateToBoolean(exec);
3416 }
3417
3418 bool LessStringsNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3419 {
3420     JSValue* v1 = m_expr1->evaluate(exec);
3421     KJS_CHECKEXCEPTIONVALUE
3422     JSValue* v2 = m_expr2->evaluate(exec);
3423     return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
3424 }
3425
3426 JSValue* LessStringsNode::evaluate(OldInterpreterExecState* exec)
3427 {
3428     return jsBoolean(inlineEvaluateToBoolean(exec));
3429 }
3430
3431 bool LessStringsNode::evaluateToBoolean(OldInterpreterExecState* exec)
3432 {
3433     return inlineEvaluateToBoolean(exec);
3434 }
3435
3436 RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3437 {
3438     RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
3439     RegisterID* src2 = generator.emitNode(m_expr1.get());
3440     return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3441 }
3442
3443 void GreaterNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3444 {
3445     nodeStack.append(m_expr2.get());
3446     nodeStack.append(m_expr1.get());
3447 }
3448
3449 // ECMA 11.8.2
3450 bool GreaterNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3451 {
3452     JSValue* v1 = m_expr1->evaluate(exec);
3453     KJS_CHECKEXCEPTIONBOOLEAN
3454     JSValue* v2 = m_expr2->evaluate(exec);
3455     KJS_CHECKEXCEPTIONBOOLEAN
3456     return lessThan(exec, v2, v1);
3457 }
3458
3459 JSValue* GreaterNode::evaluate(OldInterpreterExecState* exec)
3460 {
3461     return jsBoolean(inlineEvaluateToBoolean(exec));
3462 }
3463
3464 bool GreaterNode::evaluateToBoolean(OldInterpreterExecState* exec)
3465 {
3466     return inlineEvaluateToBoolean(exec);
3467 }
3468
3469 RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3470 {
3471     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3472     RegisterID* src2 = generator.emitNode(m_expr2.get());
3473     return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3474 }
3475
3476 void LessEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3477 {
3478     nodeStack.append(m_expr2.get());
3479     nodeStack.append(m_expr1.get());
3480 }
3481
3482 // ECMA 11.8.3
3483 bool LessEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3484 {
3485     JSValue* v1 = m_expr1->evaluate(exec);
3486     KJS_CHECKEXCEPTIONBOOLEAN
3487     JSValue* v2 = m_expr2->evaluate(exec);
3488     KJS_CHECKEXCEPTIONBOOLEAN
3489     return lessThanEq(exec, v1, v2);
3490 }
3491
3492 JSValue* LessEqNode::evaluate(OldInterpreterExecState* exec)
3493 {
3494     return jsBoolean(inlineEvaluateToBoolean(exec));
3495 }
3496
3497 bool LessEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
3498 {
3499     return inlineEvaluateToBoolean(exec);
3500 }
3501
3502 RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3503 {
3504     RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
3505     RegisterID* src2 = generator.emitNode(m_expr1.get());
3506     return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3507 }
3508
3509 void GreaterEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3510 {
3511     nodeStack.append(m_expr2.get());
3512     nodeStack.append(m_expr1.get());
3513 }
3514
3515 // ECMA 11.8.4
3516 bool GreaterEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3517 {
3518     JSValue* v1 = m_expr1->evaluate(exec);
3519     KJS_CHECKEXCEPTIONBOOLEAN
3520     JSValue* v2 = m_expr2->evaluate(exec);
3521     KJS_CHECKEXCEPTIONBOOLEAN
3522     return lessThanEq(exec, v2, v1);
3523 }
3524
3525 JSValue* GreaterEqNode::evaluate(OldInterpreterExecState* exec)
3526 {
3527     return jsBoolean(inlineEvaluateToBoolean(exec));
3528 }
3529
3530 bool GreaterEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
3531 {
3532     return inlineEvaluateToBoolean(exec);
3533 }
3534
3535 RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3536 {
3537     RefPtr<RegisterID> value = generator.emitNode(m_expr1.get());
3538     RegisterID* base = generator.emitNode(m_expr2.get());
3539     return generator.emitInstanceOf(generator.finalDestination(dst, value.get()), value.get(), base);
3540 }
3541
3542 void InstanceOfNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3543 {
3544     nodeStack.append(m_expr2.get());
3545     nodeStack.append(m_expr1.get());
3546 }
3547
3548 // ECMA 11.8.6
3549 JSValue* InstanceOfNode::evaluate(OldInterpreterExecState* exec)
3550 {
3551     JSValue* v1 = m_expr1->evaluate(exec);
3552     KJS_CHECKEXCEPTIONVALUE
3553     JSValue* v2 = m_expr2->evaluate(exec);
3554     KJS_CHECKEXCEPTIONVALUE
3555
3556     if (!v2->isObject())
3557         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, m_expr2.get());
3558
3559     JSObject* o2 = static_cast<JSObject*>(v2);
3560
3561     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
3562     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
3563     // property. It seems that all objects have the property, but not all implement it, so in this
3564     // case we return false (consistent with Mozilla).
3565     if (!o2->implementsHasInstance())
3566         return jsBoolean(false);
3567
3568     return jsBoolean(o2->hasInstance(exec, v1));
3569 }
3570
3571 bool InstanceOfNode::evaluateToBoolean(OldInterpreterExecState* exec)
3572 {
3573     JSValue* v1 = m_expr1->evaluate(exec);
3574     KJS_CHECKEXCEPTIONBOOLEAN
3575     JSValue* v2 = m_expr2->evaluate(exec);
3576     KJS_CHECKEXCEPTIONBOOLEAN
3577
3578     if (!v2->isObject()) {
3579         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'instanceof' operator.", v2, m_expr2.get());
3580         return false;
3581     }
3582
3583     JSObject* o2 = static_cast<JSObject*>(v2);
3584
3585     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
3586     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
3587     // property. It seems that all objects have the property, but not all implement it, so in this
3588     // case we return false (consistent with Mozilla).
3589     if (!o2->implementsHasInstance())
3590         return false;
3591
3592     return o2->hasInstance(exec, v1);
3593 }
3594
3595 RegisterID* InNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3596 {
3597     RefPtr<RegisterID> property = generator.emitNode(m_expr1.get());
3598     RegisterID* base = generator.emitNode(m_expr2.get());
3599     return generator.emitIn(generator.finalDestination(dst, property.get()), property.get(), base);
3600 }
3601
3602 void InNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3603 {
3604     nodeStack.append(m_expr2.get());
3605     nodeStack.append(m_expr1.get());
3606 }
3607
3608 // ECMA 11.8.7
3609 JSValue* InNode::evaluate(OldInterpreterExecState* exec)
3610 {
3611     JSValue* v1 = m_expr1->evaluate(exec);
3612     KJS_CHECKEXCEPTIONVALUE
3613     JSValue* v2 = m_expr2->evaluate(exec);
3614     KJS_CHECKEXCEPTIONVALUE
3615
3616     if (!v2->isObject())
3617         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
3618
3619     return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
3620 }
3621
3622 bool InNode::evaluateToBoolean(OldInterpreterExecState* exec)
3623 {
3624     JSValue* v1 = m_expr1->evaluate(exec);
3625     KJS_CHECKEXCEPTIONBOOLEAN
3626     JSValue* v2 = m_expr2->evaluate(exec);
3627     KJS_CHECKEXCEPTIONBOOLEAN
3628
3629     if (!v2->isObject()) {
3630         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
3631         return false;
3632     }
3633
3634     return static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec)));
3635 }
3636
3637 // ------------------------------ Equality Nodes ------------------------------------
3638
3639 RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3640 {
3641     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3642     RegisterID* src2 = generator.emitNode(m_expr2.get());
3643     return generator.emitEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3644 }
3645
3646 void EqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3647 {
3648     nodeStack.append(m_expr2.get());
3649     nodeStack.append(m_expr1.get());
3650 }
3651
3652 // ECMA 11.9.1
3653 bool EqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3654 {
3655     JSValue* v1 = m_expr1->evaluate(exec);
3656     KJS_CHECKEXCEPTIONBOOLEAN
3657     JSValue* v2 = m_expr2->evaluate(exec);
3658     KJS_CHECKEXCEPTIONBOOLEAN
3659
3660     return equal(exec, v1, v2);
3661 }
3662
3663 JSValue* EqualNode::evaluate(OldInterpreterExecState* exec)
3664 {
3665     return jsBoolean(inlineEvaluateToBoolean(exec));
3666 }
3667
3668 bool EqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3669 {
3670     return inlineEvaluateToBoolean(exec);
3671 }
3672
3673 RegisterID* NotEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3674 {
3675     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3676     RegisterID* src2 = generator.emitNode(m_expr2.get());
3677     return generator.emitNotEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3678 }
3679
3680 void NotEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3681 {
3682     nodeStack.append(m_expr2.get());
3683     nodeStack.append(m_expr1.get());
3684 }
3685
3686 // ECMA 11.9.2
3687 bool NotEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3688 {
3689     JSValue* v1 = m_expr1->evaluate(exec);
3690     KJS_CHECKEXCEPTIONBOOLEAN
3691     JSValue* v2 = m_expr2->evaluate(exec);
3692     KJS_CHECKEXCEPTIONBOOLEAN
3693
3694     return !equal(exec,v1, v2);
3695 }
3696
3697 JSValue* NotEqualNode::evaluate(OldInterpreterExecState* exec)
3698 {
3699     return jsBoolean(inlineEvaluateToBoolean(exec));
3700 }
3701
3702 bool NotEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3703 {
3704     return inlineEvaluateToBoolean(exec);
3705 }
3706
3707 RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3708 {
3709     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3710     RegisterID* src2 = generator.emitNode(m_expr2.get());
3711     return generator.emitStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3712 }
3713
3714 void StrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3715 {
3716     nodeStack.append(m_expr2.get());
3717     nodeStack.append(m_expr1.get());
3718 }
3719
3720 // ECMA 11.9.4
3721 bool StrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3722 {
3723     JSValue* v1 = m_expr1->evaluate(exec);
3724     KJS_CHECKEXCEPTIONBOOLEAN
3725     JSValue* v2 = m_expr2->evaluate(exec);
3726     KJS_CHECKEXCEPTIONBOOLEAN
3727
3728     return strictEqual(v1, v2);
3729 }
3730
3731 JSValue* StrictEqualNode::evaluate(OldInterpreterExecState* exec)
3732 {
3733     return jsBoolean(inlineEvaluateToBoolean(exec));
3734 }
3735
3736 bool StrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3737 {
3738     return inlineEvaluateToBoolean(exec);
3739 }
3740
3741 RegisterID* NotStrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3742 {
3743     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3744     RegisterID* src2 = generator.emitNode(m_expr2.get());
3745     return generator.emitNotStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3746 }
3747
3748 void NotStrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3749 {
3750     nodeStack.append(m_expr2.get());
3751     nodeStack.append(m_expr1.get());
3752 }
3753
3754 // ECMA 11.9.5
3755 bool NotStrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3756 {
3757     JSValue* v1 = m_expr1->evaluate(exec);
3758     KJS_CHECKEXCEPTIONBOOLEAN
3759     JSValue* v2 = m_expr2->evaluate(exec);
3760     KJS_CHECKEXCEPTIONBOOLEAN
3761
3762     return !strictEqual(v1, v2);
3763 }
3764
3765 JSValue* NotStrictEqualNode::evaluate(OldInterpreterExecState* exec)
3766 {
3767     return jsBoolean(inlineEvaluateToBoolean(exec));
3768 }
3769
3770 bool NotStrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3771 {
3772     return inlineEvaluateToBoolean(exec);
3773 }
3774
3775 // ------------------------------ Bit Operation Nodes ----------------------------------
3776
3777 RegisterID* BitAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3778 {
3779     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3780     RegisterID* src2 = generator.emitNode(m_expr2.get());
3781     return generator.emitBitAnd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3782 }
3783
3784 void BitAndNode::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.10
3791 JSValue* BitAndNode::evaluate(OldInterpreterExecState* exec)
3792 {
3793     JSValue* v1 = m_expr1->evaluate(exec);
3794     KJS_CHECKEXCEPTIONVALUE
3795     JSValue* v2 = m_expr2->evaluate(exec);
3796     KJS_CHECKEXCEPTIONVALUE
3797
3798     return jsNumberFromAnd(exec, v1, v2);
3799 }
3800
3801 int32_t BitAndNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3802 {
3803     int32_t i1 = m_expr1->evaluateToInt32(exec);
3804     KJS_CHECKEXCEPTIONNUMBER
3805     int32_t i2 = m_expr2->evaluateToInt32(exec);
3806     return (i1 & i2);
3807 }
3808
3809 double BitAndNode::evaluateToNumber(OldInterpreterExecState* exec)
3810 {
3811     return inlineEvaluateToInt32(exec);
3812 }
3813
3814 bool BitAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
3815 {
3816     return inlineEvaluateToInt32(exec);
3817 }
3818
3819 int32_t BitAndNode::evaluateToInt32(OldInterpreterExecState* exec)
3820 {
3821     return inlineEvaluateToInt32(exec);
3822 }
3823
3824 uint32_t BitAndNode::evaluateToUInt32(OldInterpreterExecState* exec)
3825 {
3826     return inlineEvaluateToInt32(exec);
3827 }
3828
3829 RegisterID* BitXOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3830 {
3831     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3832     RegisterID* src2 = generator.emitNode(m_expr2.get());
3833     return generator.emitBitXOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3834 }
3835
3836 void BitXOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3837 {
3838     nodeStack.append(m_expr2.get());
3839     nodeStack.append(m_expr1.get());
3840 }
3841
3842 int32_t BitXOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3843 {
3844     int i1 = m_expr1->evaluateToInt32(exec);
3845     KJS_CHECKEXCEPTIONNUMBER
3846     int i2 = m_expr2->evaluateToInt32(exec);
3847     return (i1 ^ i2);
3848 }
3849
3850 JSValue* BitXOrNode::evaluate(OldInterpreterExecState* exec)
3851 {
3852     return jsNumber(inlineEvaluateToInt32(exec));
3853 }
3854
3855 double BitXOrNode::evaluateToNumber(OldInterpreterExecState* exec)
3856 {
3857     return inlineEvaluateToInt32(exec);
3858 }
3859
3860 bool BitXOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
3861 {
3862     return inlineEvaluateToInt32(exec);
3863 }
3864
3865 int32_t BitXOrNode::evaluateToInt32(OldInterpreterExecState* exec)
3866 {
3867     return inlineEvaluateToInt32(exec);
3868 }
3869
3870 uint32_t BitXOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
3871 {
3872     return inlineEvaluateToInt32(exec);
3873 }
3874
3875 RegisterID* BitOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3876 {
3877     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3878     RegisterID* src2 = generator.emitNode(m_expr2.get());
3879     return generator.emitBitOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3880 }
3881
3882 void BitOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3883 {
3884     nodeStack.append(m_expr2.get());
3885     nodeStack.append(m_expr1.get());
3886 }
3887
3888 int32_t BitOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3889 {
3890     int i1 = m_expr1->evaluateToInt32(exec);
3891     KJS_CHECKEXCEPTIONNUMBER
3892     int i2 = m_expr2->evaluateToInt32(exec);
3893     return (i1 | i2);
3894 }
3895
3896 JSValue* BitOrNode::evaluate(OldInterpreterExecState* exec)
3897 {
3898     return jsNumber(inlineEvaluateToInt32(exec));
3899 }
3900
3901 double BitOrNode::evaluateToNumber(OldInterpreterExecState* exec)
3902 {
3903     return inlineEvaluateToInt32(exec);
3904 }
3905
3906 bool BitOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
3907 {
3908     return inlineEvaluateToInt32(exec);
3909 }
3910
3911 int32_t BitOrNode::evaluateToInt32(OldInterpreterExecState* exec)
3912 {
3913     return inlineEvaluateToInt32(exec);
3914 }
3915
3916 uint32_t BitOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
3917 {
3918     return inlineEvaluateToInt32(exec);
3919 }
3920
3921 // ------------------------------ Binary Logical Nodes ----------------------------
3922
3923 RegisterID* LogicalAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3924 {
3925     RefPtr<RegisterID> temp = generator.tempDestination(dst);
3926     RefPtr<LabelID> target = generator.newLabel();
3927     
3928     generator.emitNode(temp.get(), m_expr1.get());
3929     generator.emitJumpIfFalse(temp.get(), target.get());
3930     generator.emitNode(temp.get(), m_expr2.get());
3931     generator.emitLabel(target.get());
3932
3933     return generator.moveToDestinationIfNeeded(dst, temp.get());
3934 }
3935
3936 void LogicalAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3937 {
3938     nodeStack.append(m_expr2.get());
3939     nodeStack.append(m_expr1.get());
3940 }
3941
3942 // ECMA 11.11
3943 JSValue* LogicalAndNode::evaluate(OldInterpreterExecState* exec)
3944 {
3945     JSValue* v1 = m_expr1->evaluate(exec);
3946     KJS_CHECKEXCEPTIONVALUE
3947     bool b1 = v1->toBoolean(exec);
3948     KJS_CHECKEXCEPTIONVALUE
3949     if (!b1)
3950         return v1;
3951     JSValue* v2 = m_expr2->evaluate(exec);
3952     KJS_CHECKEXCEPTIONVALUE
3953     return v2;
3954 }
3955
3956 bool LogicalAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
3957 {
3958     bool b = m_expr1->evaluateToBoolean(exec);
3959     KJS_CHECKEXCEPTIONBOOLEAN
3960     return b && m_expr2->evaluateToBoolean(exec);
3961 }
3962
3963 RegisterID* LogicalOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3964 {
3965     RefPtr<RegisterID> temp = generator.tempDestination(dst);
3966     RefPtr<LabelID> target = generator.newLabel();
3967     
3968     generator.emitNode(temp.get(), m_expr1.get());
3969     generator.emitJumpIfTrue(temp.get(), target.get());
3970     generator.emitNode(temp.get(), m_expr2.get());
3971     generator.emitLabel(target.get());
3972
3973     return generator.moveToDestinationIfNeeded(dst, temp.get());
3974 }
3975
3976 void LogicalOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3977 {
3978     nodeStack.append(m_expr2.get());
3979     nodeStack.append(m_expr1.get());
3980 }
3981
3982 JSValue* LogicalOrNode::evaluate(OldInterpreterExecState* exec)
3983 {
3984     JSValue* v1 = m_expr1->evaluate(exec);
3985     KJS_CHECKEXCEPTIONVALUE
3986     if (v1->toBoolean(exec))
3987         return v1;
3988     return m_expr2->evaluate(exec);
3989 }
3990
3991 bool LogicalOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
3992 {
3993     bool b = m_expr1->evaluateToBoolean(exec);
3994     KJS_CHECKEXCEPTIONBOOLEAN
3995     return b || m_expr2->evaluateToBoolean(exec);
3996 }
3997
3998 // ------------------------------ ConditionalNode ------------------------------
3999
4000 RegisterID* ConditionalNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4001 {
4002     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
4003     RefPtr<LabelID> beforeElse = generator.newLabel();
4004     RefPtr<LabelID> afterElse = generator.newLabel();
4005
4006     RegisterID* cond = generator.emitNode(m_logical.get());
4007     generator.emitJumpIfFalse(cond, beforeElse.get());
4008
4009     generator.emitNode(newDst.get(), m_expr1.get());
4010     generator.emitJump(afterElse.get());
4011
4012     generator.emitLabel(beforeElse.get());
4013     generator.emitNode(newDst.get(), m_expr2.get());
4014
4015     generator.emitLabel(afterElse.get());
4016
4017     return newDst.get();
4018 }
4019
4020 void ConditionalNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4021 {
4022     nodeStack.append(m_expr2.get());
4023     nodeStack.append(m_expr1.get());
4024     nodeStack.append(m_logical.get());
4025 }
4026
4027 // ECMA 11.12
4028 JSValue* ConditionalNode::evaluate(OldInterpreterExecState* exec)
4029 {
4030     bool b = m_logical->evaluateToBoolean(exec);
4031     KJS_CHECKEXCEPTIONVALUE
4032     return b ? m_expr1->evaluate(exec) : m_expr2->evaluate(exec);
4033 }
4034
4035 bool ConditionalNode::evaluateToBoolean(OldInterpreterExecState* exec)
4036 {
4037     bool b = m_logical->evaluateToBoolean(exec);
4038     KJS_CHECKEXCEPTIONBOOLEAN
4039     return b ? m_expr1->evaluateToBoolean(exec) : m_expr2->evaluateToBoolean(exec);
4040 }
4041
4042 double ConditionalNode::evaluateToNumber(OldInterpreterExecState* exec)
4043 {
4044     bool b = m_logical->evaluateToBoolean(exec);
4045     KJS_CHECKEXCEPTIONNUMBER
4046     return b ? m_expr1->evaluateToNumber(exec) : m_expr2->evaluateToNumber(exec);
4047 }
4048
4049 int32_t ConditionalNode::evaluateToInt32(OldInterpreterExecState* exec)
4050 {
4051     bool b = m_logical->evaluateToBoolean(exec);
4052     KJS_CHECKEXCEPTIONNUMBER
4053     return b ? m_expr1->evaluateToInt32(exec) : m_expr2->evaluateToInt32(exec);
4054 }
4055
4056 uint32_t ConditionalNode::evaluateToUInt32(OldInterpreterExecState* exec)
4057 {
4058     bool b = m_logical->evaluateToBoolean(exec);
4059     KJS_CHECKEXCEPTIONNUMBER
4060     return b ? m_expr1->evaluateToUInt32(exec) : m_expr2->evaluateToUInt32(exec);
4061 }
4062
4063 // ECMA 11.13
4064
4065 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
4066 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
4067 {
4068     JSValue* v;
4069     int i1;
4070     int i2;
4071     unsigned int ui;
4072     switch (oper) {
4073         case OpMultEq:
4074             v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec));
4075             break;
4076         case OpDivEq:
4077             v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec));
4078             break;
4079         case OpPlusEq:
4080             v = add(exec, current, right->evaluate(exec));
4081             break;
4082         case OpMinusEq:
4083             v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec));
4084             break;
4085         case OpLShift:
4086             i1 = current->toInt32(exec);
4087             i2 = right->evaluateToInt32(exec);
4088             v = jsNumber(i1 << i2);
4089             break;
4090         case OpRShift:
4091             i1 = current->toInt32(exec);
4092             i2 = right->evaluateToInt32(exec);
4093             v = jsNumber(i1 >> i2);
4094             break;
4095         case OpURShift:
4096             ui = current->toUInt32(exec);
4097             i2 = right->evaluateToInt32(exec);
4098             v = jsNumber(ui >> i2);
4099             break;
4100         case OpAndEq:
4101             i1 = current->toInt32(exec);
4102             i2 = right->evaluateToInt32(exec);
4103             v = jsNumber(i1 & i2);
4104             break;
4105         case OpXOrEq:
4106             i1 = current->toInt32(exec);
4107             i2 = right->evaluateToInt32(exec);
4108             v = jsNumber(i1 ^ i2);
4109             break;
4110         case OpOrEq:
4111             i1 = current->toInt32(exec);
4112             i2 = right->evaluateToInt32(exec);
4113             v = jsNumber(i1 | i2);
4114             break;
4115         case OpModEq: {
4116             double d1 = current->toNumber(exec);
4117             double d2 = right->evaluateToNumber(exec);
4118             v = jsNumber(fmod(d1, d2));
4119         }
4120             break;
4121         default:
4122             ASSERT_NOT_REACHED();
4123             v = jsUndefined();
4124     }
4125
4126     return v;
4127 }
4128
4129 // ------------------------------ ReadModifyResolveNode -----------------------------------
4130
4131 // FIXME: should this be moved to be a method on CodeGenerator?
4132 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(CodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper)
4133 {
4134     switch (oper) {
4135         case OpMultEq:
4136             return generator.emitMul(dst, src1, src2);
4137         case OpDivEq:
4138             return generator.emitDiv(dst, src1, src2);
4139         case OpPlusEq:
4140             return generator.emitAdd(dst, src1, src2);
4141         case OpMinusEq:
4142             return generator.emitSub(dst, src1, src2);
4143         case OpLShift:
4144             return generator.emitLeftShift(dst, src1, src2);
4145         case OpRShift:
4146             return generator.emitRightShift(dst, src1, src2);
4147         case OpURShift:
4148             return generator.emitUnsignedRightShift(dst, src1, src2);
4149         case OpAndEq:
4150             return generator.emitBitAnd(dst, src1, src2);
4151         case OpXOrEq:
4152             return generator.emitBitXOr(dst, src1, src2);
4153         case OpOrEq:
4154             return generator.emitBitOr(dst, src1, src2);
4155         case OpModEq:
4156             return generator.emitMod(dst, src1, src2);
4157         default:
4158             ASSERT_NOT_REACHED();
4159     }
4160
4161     return dst;
4162 }
4163
4164 RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4165 {
4166     if (RegisterID* local = generator.registerForLocal(m_ident)) {
4167         if (generator.isLocalConstant(m_ident)) {
4168             RegisterID* src2 = generator.emitNode(m_right.get());
4169             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator);
4170         }
4171         
4172         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments) && !m_right.get()->isNumber()) {
4173             RefPtr<RegisterID> result = generator.newTemporary();
4174             generator.emitMove(result.get(), local);
4175             RegisterID* src2 = generator.emitNode(m_right.get());
4176             emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator);
4177             generator.emitMove(local, result.get());
4178             return generator.moveToDestinationIfNeeded(dst, result.get());
4179         }
4180         
4181         RegisterID* src2 = generator.emitNode(m_right.get());
4182         RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator);
4183         return generator.moveToDestinationIfNeeded(dst, result);
4184     }
4185
4186     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
4187     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
4188     RegisterID* src2 = generator.emitNode(m_right.get());
4189     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
4190     return generator.emitPutById(base.get(), m_ident, result);
4191 }
4192
4193 void ReadModifyResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
4194 {
4195     nodeStack.append(m_right.get());
4196     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
4197     if (index != missingSymbolMarker()) {
4198         if (isConstant(localStorage, index))
4199             new (this) ReadModifyConstNode(index);
4200         else
4201             new (this) ReadModifyLocalVarNode(index);
4202     }
4203 }
4204
4205 // ------------------------------ AssignResolveNode -----------------------------------
4206
4207 RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4208 {
4209     if (RegisterID* local = generator.registerForLocal(m_ident)) {
4210         if (generator.isLocalConstant(m_ident))
4211             return generator.emitNode(dst, m_right.get());
4212         
4213         RegisterID* result = generator.emitNode(local, m_right.get());
4214         return generator.moveToDestinationIfNeeded(dst, result);
4215     }
4216
4217     int index = 0;
4218     size_t depth = 0;
4219     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
4220         RegisterID* value = generator.emitNode(dst, m_right.get());
4221         generator.emitPutScopedVar(depth, index, value);
4222         return value;
4223     }
4224
4225     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
4226     RegisterID* value = generator.emitNode(dst, m_right.get());
4227     return generator.emitPutById(base.get(), m_ident, value);
4228 }
4229
4230 void AssignResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
4231 {
4232     nodeStack.append(m_right.get());
4233     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
4234     if (index != missingSymbolMarker()) {
4235         if (isConstant(localStorage, index))
4236             new (this) AssignConstNode;
4237         else
4238             new (this) AssignLocalVarNode(index);
4239     }
4240 }
4241
4242 // ------------------------------ ReadModifyLocalVarNode -----------------------------------
4243
4244 JSValue* ReadModifyLocalVarNode::evaluate(OldInterpreterExecState* exec)
4245 {
4246     ASSERT(exec->variableObject() == exec->scopeChain().top());
4247
4248     ASSERT(m_operator != OpEqual);
4249     JSValue* v = valueForReadModifyAssignment(exec, exec->localStorage()[m_index].value, m_right.get(), m_operator);
4250
4251     KJS_CHECKEXCEPTIONVALUE
4252     
4253     // We can't store a pointer into localStorage() and use it throughout the function
4254     // body, because valueForReadModifyAssignment() might cause an ActivationImp tear-off,
4255     // changing the value of localStorage().
4256     
4257     exec->localStorage()[m_index].value = v;
4258     return v;
4259 }
4260
4261 // ------------------------------ AssignLocalVarNode -----------------------------------
4262
4263 JSValue* AssignLocalVarNode::evaluate(OldInterpreterExecState* exec)
4264 {
4265     ASSERT(exec->variableObject() == exec->scopeChain().top());
4266     JSValue* v = m_right->evaluate(exec);
4267
4268     KJS_CHECKEXCEPTIONVALUE
4269
4270     exec->localStorage()[m_index].value = v;
4271
4272     return v;
4273 }
4274
4275 // ------------------------------ ReadModifyConstNode -----------------------------------
4276
4277 JSValue* ReadModifyConstNode::evaluate(OldInterpreterExecState* exec)
4278 {
4279     ASSERT(exec->variableObject() == exec->scopeChain().top());
4280     JSValue* left = exec->localStorage()[m_index].value;
4281     ASSERT(m_operator != OpEqual);
4282     JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_operator);
4283     KJS_CHECKEXCEPTIONVALUE
4284     return result;
4285 }
4286
4287 // ------------------------------ AssignConstNode -----------------------------------
4288
4289 JSValue* AssignConstNode::evaluate(OldInterpreterExecState* exec)
4290 {
4291     return m_right->evaluate(exec);
4292 }
4293
4294 JSValue* ReadModifyResolveNode::evaluate(OldInterpreterExecState* exec)
4295 {
4296     const ScopeChain& chain = exec->scopeChain();
4297     ScopeChainIterator iter = chain.begin();
4298     ScopeChainIterator end = chain.end();
4299
4300     // We must always have something in the scope chain
4301     ASSERT(iter != end);
4302
4303     PropertySlot slot;
4304     JSObject* base;
4305     do {
4306         base = *iter;
4307         if (base->getPropertySlot(exec, m_ident, slot)) {
4308             // See the comment in PostIncResolveNode::evaluate().
4309
4310             base = *iter;
4311             goto found;
4312         }
4313
4314         ++iter;
4315     } while (iter != end);
4316
4317     ASSERT(m_operator != OpEqual);
4318     return throwUndefinedVariableError(exec, m_ident);
4319
4320 found:
4321     JSValue* v;
4322
4323     ASSERT(m_operator != OpEqual);
4324     JSValue* v1 = slot.getValue(exec, base, m_ident);
4325     KJS_CHECKEXCEPTIONVALUE
4326     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
4327
4328     KJS_CHECKEXCEPTIONVALUE
4329     
4330     // Since valueForReadModifyAssignment() might cause an ActivationImp tear-off,
4331     // we need to get the base from the ScopeChainIterator again.
4332     
4333     (*iter)->put(exec, m_ident, v);
4334     return v;
4335 }
4336
4337 JSValue* AssignResolveNode::evaluate(OldInterpreterExecState* exec)
4338 {
4339     const ScopeChain& chain = exec->scopeChain();
4340     ScopeChainIterator iter = chain.begin();
4341     ScopeChainIterator end = chain.end();
4342
4343     // we must always have something in the scope chain
4344     ASSERT(iter != end);
4345
4346     PropertySlot slot;
4347     JSObject* base;
4348     do {
4349         base = *iter;
4350         if (base->getPropertySlot(exec, m_ident, slot)) {
4351             // See the comment in PostIncResolveNode::evaluate().
4352
4353             base = *iter;
4354             goto found;
4355         }
4356
4357         ++iter;
4358     } while (iter != end);
4359
4360 found:
4361     JSValue* v = m_right->evaluate(exec);
4362
4363     KJS_CHECKEXCEPTIONVALUE
4364
4365     base->put(exec, m_ident, v);
4366     return v;
4367 }
4368
4369 // ------------------------------ ReadModifyDotNode -----------------------------------
4370
4371 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4372 {
4373     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
4374     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
4375     RegisterID* result = generator.emitNode(value.get(), m_right.get());
4376     generator.emitPutById(base.get(), m_ident, result);
4377     return generator.moveToDestinationIfNeeded(dst, result);
4378 }
4379
4380 void AssignDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4381 {
4382     nodeStack.append(m_right.get());
4383     nodeStack.append(m_base.get());
4384 }
4385
4386 JSValue* AssignDotNode::evaluate(OldInterpreterExecState* exec)
4387 {
4388     JSValue* baseValue = m_base->evaluate(exec);
4389     KJS_CHECKEXCEPTIONVALUE
4390     JSObject* base = baseValue->toObject(exec);
4391
4392     JSValue* v = m_right->evaluate(exec);
4393
4394     KJS_CHECKEXCEPTIONVALUE
4395
4396     base->put(exec, m_ident, v);
4397     return v;
4398 }
4399
4400 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4401 {
4402     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
4403     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
4404     RegisterID* change = generator.emitNode(m_right.get());
4405     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
4406     return generator.emitPutById(base.get(), m_ident, updatedValue);
4407 }
4408
4409 void ReadModifyDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4410 {
4411     nodeStack.append(m_right.get());
4412     nodeStack.append(m_base.get());
4413 }
4414
4415 JSValue* ReadModifyDotNode::evaluate(OldInterpreterExecState* exec)
4416 {
4417     JSValue* baseValue = m_base->evaluate(exec);
4418     KJS_CHECKEXCEPTIONVALUE
4419     JSObject* base = baseValue->toObject(exec);
4420
4421     JSValue* v;
4422
4423     ASSERT(m_operator != OpEqual);
4424     PropertySlot slot;
4425     JSValue* v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
4426     KJS_CHECKEXCEPTIONVALUE
4427     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
4428
4429     KJS_CHECKEXCEPTIONVALUE
4430
4431     base->put(exec, m_ident, v);
4432     return v;
4433 }
4434
4435 // ------------------------------ AssignErrorNode -----------------------------------
4436
4437 RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
4438 {
4439     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
4440 }
4441
4442 JSValue* AssignErrorNode::evaluate(OldInterpreterExecState* exec)
4443 {
4444     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
4445     handleException(exec);
4446     return jsUndefined();
4447 }
4448
4449 // ------------------------------ AssignBracketNode -----------------------------------
4450
4451 RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4452 {
4453     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
4454     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
4455     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
4456     RegisterID* result = generator.emitNode(value.get(), m_right.get());
4457     generator.emitPutByVal(base.get(), property.get(), result);
4458     return generator.moveToDestinationIfNeeded(dst, result);
4459 }
4460
4461 void AssignBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4462 {
4463     nodeStack.append(m_right.get());
4464     nodeStack.append(m_subscript.get());
4465     nodeStack.append(m_base.get());
4466 }
4467
4468 JSValue* AssignBracketNode::evaluate(OldInterpreterExecState* exec)
4469 {
4470     JSValue* baseValue = m_base->evaluate(exec);
4471     KJS_CHECKEXCEPTIONVALUE
4472     JSValue* subscript = m_subscript->evaluate(exec);
4473     KJS_CHECKEXCEPTIONVALUE
4474
4475     JSObject* base = baseValue->toObject(exec);
4476
4477     uint32_t propertyIndex;
4478     if (subscript->getUInt32(propertyIndex)) {
4479         JSValue* v = m_right->evaluate(exec);
4480         KJS_CHECKEXCEPTIONVALUE
4481
4482         base->put(exec, propertyIndex, v);
4483         return v;
4484     }
4485
4486     Identifier propertyName(subscript->toString(exec));
4487     JSValue* v = m_right->evaluate(exec);
4488     KJS_CHECKEXCEPTIONVALUE
4489
4490     base->put(exec, propertyName, v);
4491     return v;
4492 }
4493
4494 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4495 {
4496     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
4497     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
4498
4499     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
4500     RegisterID* change = generator.emitNode(m_right.get());
4501     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
4502
4503     generator.emitPutByVal(base.get(), property.get(), updatedValue);
4504
4505     return updatedValue;
4506 }
4507
4508 void ReadModifyBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4509 {
4510     nodeStack.append(m_right.get());
4511     nodeStack.append(m_subscript.get());
4512     nodeStack.append(m_base.get());
4513 }
4514
4515 JSValue* ReadModifyBracketNode::evaluate(OldInterpreterExecState* exec)
4516 {
4517     JSValue* baseValue = m_base->evaluate(exec);
4518     KJS_CHECKEXCEPTIONVALUE
4519     JSValue* subscript = m_subscript->evaluate(exec);
4520     KJS_CHECKEXCEPTIONVALUE
4521
4522     JSObject* base = baseValue->toObject(exec);
4523
4524     uint32_t propertyIndex;
4525     if (subscript->getUInt32(propertyIndex)) {
4526         JSValue* v;
4527         ASSERT(m_operator != OpEqual);
4528         PropertySlot slot;
4529         JSValue* v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
4530         KJS_CHECKEXCEPTIONVALUE
4531         v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
4532
4533         KJS_CHECKEXCEPTIONVALUE
4534
4535         base->put(exec, propertyIndex, v);
4536         return v;
4537     }
4538
4539     Identifier propertyName(subscript->toString(exec));
4540     JSValue* v;
4541
4542     ASSERT(m_operator != OpEqual);
4543     PropertySlot slot;
4544     JSValue* v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
4545     KJS_CHECKEXCEPTIONVALUE
4546     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
4547
4548     KJS_CHECKEXCEPTIONVALUE
4549
4550     base->put(exec, propertyName, v);
4551     return v;
4552 }
4553
4554 // ------------------------------ CommaNode ------------------------------------
4555
4556 RegisterID* CommaNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4557 {
4558     generator.emitNode(m_expr1.get());
4559     return generator.emitNode(dst, m_expr2.get());
4560 }
4561
4562 void CommaNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4563 {
4564     nodeStack.append(m_expr2.get());
4565     nodeStack.append(m_expr1.get());
4566 }