JavaScriptCore:
[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     RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
1313     return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get());
1314 }
1315
1316 void FunctionCallValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1317 {
1318     nodeStack.append(m_args.get());
1319     nodeStack.append(m_expr.get());
1320 }
1321
1322 // ECMA 11.2.3
1323 JSValue* FunctionCallValueNode::evaluate(OldInterpreterExecState* exec)
1324 {
1325     JSValue* v = m_expr->evaluate(exec);
1326     KJS_CHECKEXCEPTIONVALUE
1327
1328     if (!v->isObject()) {
1329         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_expr.get());
1330     }
1331
1332     JSObject* func = static_cast<JSObject*>(v);
1333
1334     if (!func->implementsCall()) {
1335         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_expr.get());
1336     }
1337
1338     List argList;
1339     m_args->evaluateList(exec, argList);
1340     KJS_CHECKEXCEPTIONVALUE
1341
1342     JSObject* thisObj = exec->globalThisValue();
1343     return func->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     int index = 0;
1746     size_t depth = 0;
1747     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
1748         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
1749         RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
1750         generator.emitPutScopedVar(depth, index, value.get());
1751         return oldValue;
1752     }
1753
1754     RefPtr<RegisterID> value = generator.newTemporary();
1755     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
1756     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
1757     generator.emitPutById(base.get(), m_ident, value.get());
1758     return oldValue;
1759 }
1760
1761 // Increment
1762 void PostIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
1763 {
1764     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
1765     if (index != missingSymbolMarker()) {
1766         if (isConstant(localStorage, index))
1767             new (this) PostIncConstNode(index);
1768         else
1769             new (this) PostIncLocalVarNode(index);
1770     }
1771 }
1772
1773 JSValue* PostIncResolveNode::evaluate(OldInterpreterExecState* exec)
1774 {
1775     // Check for missed optimization opportunity.
1776     ASSERT(!canSkipLookup(exec, m_ident));
1777
1778     const ScopeChain& chain = exec->scopeChain();
1779     ScopeChainIterator iter = chain.begin();
1780     ScopeChainIterator end = chain.end();
1781
1782     // we must always have something in the scope chain
1783     ASSERT(iter != end);
1784
1785     PropertySlot slot;
1786     do {
1787         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
1788             // If m_ident is 'arguments', the base->getPropertySlot() may cause 
1789             // base (which must be an ActivationImp in such this case) to be torn
1790             // off from the activation stack, in which case we need to get it again
1791             // from the ScopeChainIterator.
1792             
1793             JSObject* base = *iter;
1794             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1795             base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
1796             return v;
1797         }
1798
1799         ++iter;
1800     } while (iter != end);
1801
1802     return throwUndefinedVariableError(exec, m_ident);
1803 }
1804
1805 void PostIncResolveNode::optimizeForUnnecessaryResult()
1806 {
1807     new (this) PreIncResolveNode(PlacementNewAdopt);
1808 }
1809
1810 JSValue* PostIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
1811 {
1812     ASSERT(exec->variableObject() == exec->scopeChain().top());
1813
1814     JSValue** slot = &exec->localStorage()[m_index].value;
1815     JSValue* v = (*slot)->toJSNumber(exec);
1816     *slot = jsNumber(v->toNumber(exec) + 1);
1817     return v;
1818 }
1819
1820 void PostIncLocalVarNode::optimizeForUnnecessaryResult()
1821 {
1822     new (this) PreIncLocalVarNode(m_index);
1823 }
1824
1825 // Decrement
1826 RegisterID* PostDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1827 {
1828     // FIXME: I think we can detect the absense of dependent expressions here, 
1829     // and emit a PreDec instead of a PostDec. A post-pass to eliminate dead
1830     // code would work, too.
1831     if (RegisterID* local = generator.registerForLocal(m_ident)) {
1832         if (generator.isLocalConstant(m_ident))
1833             return generator.emitToJSNumber(generator.finalDestination(dst), local);
1834         
1835         return generator.emitPostDec(generator.finalDestination(dst), local);
1836     }
1837
1838     int index = 0;
1839     size_t depth = 0;
1840     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
1841         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
1842         RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
1843         generator.emitPutScopedVar(depth, index, value.get());
1844         return oldValue;
1845     }
1846
1847     RefPtr<RegisterID> value = generator.newTemporary();
1848     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
1849     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
1850     generator.emitPutById(base.get(), m_ident, value.get());
1851     return oldValue;
1852 }
1853
1854 void PostDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
1855 {
1856     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
1857     if (index != missingSymbolMarker()) {
1858         if (isConstant(localStorage, index))
1859             new (this) PostDecConstNode(index);
1860         else
1861             new (this) PostDecLocalVarNode(index);
1862     }
1863 }
1864
1865 JSValue* PostDecResolveNode::evaluate(OldInterpreterExecState* exec)
1866 {
1867     // Check for missed optimization opportunity.
1868     ASSERT(!canSkipLookup(exec, m_ident));
1869
1870     const ScopeChain& chain = exec->scopeChain();
1871     ScopeChainIterator iter = chain.begin();
1872     ScopeChainIterator end = chain.end();
1873
1874     // we must always have something in the scope chain
1875     ASSERT(iter != end);
1876
1877     PropertySlot slot;
1878     do {
1879         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
1880             // See the comment in PostIncResolveNode::evaluate().
1881
1882             JSObject* base = *iter;
1883             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1884             base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
1885             return v;
1886         }
1887
1888         ++iter;
1889     } while (iter != end);
1890
1891     return throwUndefinedVariableError(exec, m_ident);
1892 }
1893
1894 void PostDecResolveNode::optimizeForUnnecessaryResult()
1895 {
1896     new (this) PreDecResolveNode(PlacementNewAdopt);
1897 }
1898
1899 JSValue* PostDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
1900 {
1901     ASSERT(exec->variableObject() == exec->scopeChain().top());
1902
1903     JSValue** slot = &exec->localStorage()[m_index].value;
1904     JSValue* v = (*slot)->toJSNumber(exec);
1905     *slot = jsNumber(v->toNumber(exec) - 1);
1906     return v;
1907 }
1908
1909 double PostDecLocalVarNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
1910 {
1911     ASSERT(exec->variableObject() == exec->scopeChain().top());
1912
1913     JSValue** slot = &exec->localStorage()[m_index].value;
1914     double n = (*slot)->toNumber(exec);
1915     *slot = jsNumber(n - 1);
1916     return n;
1917 }
1918
1919 double PostDecLocalVarNode::evaluateToNumber(OldInterpreterExecState* exec)
1920 {
1921     return inlineEvaluateToNumber(exec);
1922 }
1923
1924 bool PostDecLocalVarNode::evaluateToBoolean(OldInterpreterExecState* exec)
1925 {
1926     double result = inlineEvaluateToNumber(exec);
1927     return  result > 0.0 || 0.0 > result; // NaN produces false as well
1928 }
1929
1930 int32_t PostDecLocalVarNode::evaluateToInt32(OldInterpreterExecState* exec)
1931 {
1932     return JSValue::toInt32(inlineEvaluateToNumber(exec));
1933 }
1934
1935 uint32_t PostDecLocalVarNode::evaluateToUInt32(OldInterpreterExecState* exec)
1936 {
1937     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
1938 }
1939
1940 void PostDecLocalVarNode::optimizeForUnnecessaryResult()
1941 {
1942     new (this) PreDecLocalVarNode(m_index);
1943 }
1944
1945 // ------------------------------ PostfixBracketNode ----------------------------------
1946
1947 void PostfixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1948 {
1949     nodeStack.append(m_subscript.get());
1950     nodeStack.append(m_base.get());
1951 }
1952
1953 RegisterID* PostIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1954 {
1955     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1956     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1957     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1958     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
1959     generator.emitPutByVal(base.get(), property.get(), value.get());
1960     return oldValue;
1961 }
1962
1963 JSValue* PostIncBracketNode::evaluate(OldInterpreterExecState* exec)
1964 {
1965     JSValue* baseValue = m_base->evaluate(exec);
1966     KJS_CHECKEXCEPTIONVALUE
1967     JSValue* subscript = m_subscript->evaluate(exec);
1968     KJS_CHECKEXCEPTIONVALUE
1969
1970     JSObject* base = baseValue->toObject(exec);
1971
1972     uint32_t propertyIndex;
1973     if (subscript->getUInt32(propertyIndex)) {
1974         PropertySlot slot;
1975         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1976         KJS_CHECKEXCEPTIONVALUE
1977
1978         JSValue* v2 = v->toJSNumber(exec);
1979         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1));
1980
1981         return v2;
1982     }
1983
1984     Identifier propertyName(subscript->toString(exec));
1985     PropertySlot slot;
1986     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1987     KJS_CHECKEXCEPTIONVALUE
1988
1989     JSValue* v2 = v->toJSNumber(exec);
1990     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));
1991     return v2;
1992 }
1993
1994 RegisterID* PostDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1995 {
1996     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1997     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1998     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1999     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
2000     generator.emitPutByVal(base.get(), property.get(), value.get());
2001     return oldValue;
2002 }
2003
2004 JSValue* PostDecBracketNode::evaluate(OldInterpreterExecState* exec)
2005 {
2006     JSValue* baseValue = m_base->evaluate(exec);
2007     KJS_CHECKEXCEPTIONVALUE
2008     JSValue* subscript = m_subscript->evaluate(exec);
2009     KJS_CHECKEXCEPTIONVALUE
2010
2011     JSObject* base = baseValue->toObject(exec);
2012
2013     uint32_t propertyIndex;
2014     if (subscript->getUInt32(propertyIndex)) {
2015         PropertySlot slot;
2016         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2017         KJS_CHECKEXCEPTIONVALUE
2018
2019         JSValue* v2 = v->toJSNumber(exec);
2020         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1));
2021         return v2;
2022     }
2023
2024     Identifier propertyName(subscript->toString(exec));
2025     PropertySlot slot;
2026     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2027     KJS_CHECKEXCEPTIONVALUE
2028
2029     JSValue* v2 = v->toJSNumber(exec);
2030     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));
2031     return v2;
2032 }
2033
2034 // ------------------------------ PostfixDotNode ----------------------------------
2035
2036 void PostfixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2037 {
2038     nodeStack.append(m_base.get());
2039 }
2040
2041 RegisterID* PostIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2042 {
2043     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2044     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
2045     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
2046     generator.emitPutById(base.get(), m_ident, value.get());
2047     return oldValue;
2048 }
2049
2050 JSValue* PostIncDotNode::evaluate(OldInterpreterExecState* exec)
2051 {
2052     JSValue* baseValue = m_base->evaluate(exec);
2053     KJS_CHECKEXCEPTIONVALUE
2054     JSObject* base = baseValue->toObject(exec);
2055
2056     PropertySlot slot;
2057     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2058     KJS_CHECKEXCEPTIONVALUE
2059
2060     JSValue* v2 = v->toJSNumber(exec);
2061     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));
2062     return v2;
2063 }
2064
2065 RegisterID* PostDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2066 {
2067     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2068     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
2069     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
2070     generator.emitPutById(base.get(), m_ident, value.get());
2071     return oldValue;
2072 }
2073
2074 JSValue* PostDecDotNode::evaluate(OldInterpreterExecState* exec)
2075 {
2076     JSValue* baseValue = m_base->evaluate(exec);
2077     KJS_CHECKEXCEPTIONVALUE
2078     JSObject* base = baseValue->toObject(exec);
2079
2080     PropertySlot slot;
2081     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2082     KJS_CHECKEXCEPTIONVALUE
2083
2084     JSValue* v2 = v->toJSNumber(exec);
2085     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));
2086     return v2;
2087 }
2088
2089 // ------------------------------ PostfixErrorNode -----------------------------------
2090
2091 RegisterID* PostfixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
2092 {
2093     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
2094 }
2095
2096 JSValue* PostfixErrorNode::evaluate(OldInterpreterExecState* exec)
2097 {
2098     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
2099                m_operator == OpPlusPlus ? "++" : "--");
2100     handleException(exec);
2101     return jsUndefined();
2102 }
2103
2104 // ------------------------------ DeleteResolveNode -----------------------------------
2105
2106 RegisterID* DeleteResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2107 {
2108     if (generator.registerForLocal(m_ident))
2109         return generator.emitLoad(generator.finalDestination(dst), false);
2110
2111     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
2112     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
2113 }
2114
2115 void DeleteResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
2116 {
2117     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2118     if (index != missingSymbolMarker())
2119         new (this) LocalVarDeleteNode();
2120 }
2121
2122 // ECMA 11.4.1
2123
2124 JSValue* DeleteResolveNode::evaluate(OldInterpreterExecState* exec)
2125 {
2126     // Check for missed optimization opportunity.
2127     ASSERT(!canSkipLookup(exec, m_ident));
2128
2129     const ScopeChain& chain = exec->scopeChain();
2130     ScopeChainIterator iter = chain.begin();
2131     ScopeChainIterator end = chain.end();
2132
2133     // We must always have something in the scope chain
2134     ASSERT(iter != end);
2135
2136     PropertySlot slot;
2137     JSObject* base;
2138     do {
2139         base = *iter;
2140         if (base->getPropertySlot(exec, m_ident, slot))
2141             return jsBoolean(base->deleteProperty(exec, m_ident));
2142
2143         ++iter;
2144     } while (iter != end);
2145
2146     return jsBoolean(true);
2147 }
2148
2149 JSValue* LocalVarDeleteNode::evaluate(OldInterpreterExecState*)
2150 {
2151     return jsBoolean(false);
2152 }
2153
2154 // ------------------------------ DeleteBracketNode -----------------------------------
2155
2156 RegisterID* DeleteBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2157 {
2158     RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
2159     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript.get());
2160     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
2161 }
2162
2163 void DeleteBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2164 {
2165     nodeStack.append(m_subscript.get());
2166     nodeStack.append(m_base.get());
2167 }
2168
2169 JSValue* DeleteBracketNode::evaluate(OldInterpreterExecState* exec)
2170 {
2171     JSValue* baseValue = m_base->evaluate(exec);
2172     KJS_CHECKEXCEPTIONVALUE
2173     JSValue* subscript = m_subscript->evaluate(exec);
2174     KJS_CHECKEXCEPTIONVALUE
2175
2176     JSObject* base = baseValue->toObject(exec);
2177
2178     uint32_t propertyIndex;
2179     if (subscript->getUInt32(propertyIndex))
2180         return jsBoolean(base->deleteProperty(exec, propertyIndex));
2181
2182     Identifier propertyName(subscript->toString(exec));
2183     return jsBoolean(base->deleteProperty(exec, propertyName));
2184 }
2185
2186 // ------------------------------ DeleteDotNode -----------------------------------
2187
2188 RegisterID* DeleteDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2189 {
2190     RegisterID* r0 = generator.emitNode(m_base.get());
2191     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
2192 }
2193
2194 void DeleteDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2195 {
2196     nodeStack.append(m_base.get());
2197 }
2198
2199 JSValue* DeleteDotNode::evaluate(OldInterpreterExecState* exec)
2200 {
2201     JSValue* baseValue = m_base->evaluate(exec);
2202     JSObject* base = baseValue->toObject(exec);
2203     KJS_CHECKEXCEPTIONVALUE
2204
2205     return jsBoolean(base->deleteProperty(exec, m_ident));
2206 }
2207
2208 // ------------------------------ DeleteValueNode -----------------------------------
2209
2210 RegisterID* DeleteValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2211 {
2212     generator.emitNode(m_expr.get());
2213
2214     // delete on a non-location expression ignores the value and returns true
2215     return generator.emitLoad(generator.finalDestination(dst), true);
2216 }
2217
2218 void DeleteValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2219 {
2220     nodeStack.append(m_expr.get());
2221 }
2222
2223 JSValue* DeleteValueNode::evaluate(OldInterpreterExecState* exec)
2224 {
2225     m_expr->evaluate(exec);
2226     KJS_CHECKEXCEPTIONVALUE
2227
2228     // delete on a non-location expression ignores the value and returns true
2229     return jsBoolean(true);
2230 }
2231
2232 // ------------------------------ VoidNode -------------------------------------
2233
2234 RegisterID* VoidNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2235 {
2236     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2237     return generator.emitLoad(generator.finalDestination(dst, r0.get()), jsUndefined());
2238 }
2239
2240 void VoidNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2241 {
2242     nodeStack.append(m_expr.get());
2243 }
2244
2245 // ECMA 11.4.2
2246 JSValue* VoidNode::evaluate(OldInterpreterExecState* exec)
2247 {
2248     m_expr->evaluate(exec);
2249     KJS_CHECKEXCEPTIONVALUE
2250
2251     return jsUndefined();
2252 }
2253
2254 // ECMA 11.4.3
2255
2256 // ------------------------------ TypeOfValueNode -----------------------------------
2257
2258 void TypeOfValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2259 {
2260     nodeStack.append(m_expr.get());
2261 }
2262
2263 static JSValue* typeStringForValue(JSValue* v) KJS_FAST_CALL;
2264 static JSValue* typeStringForValue(JSValue* v)
2265 {
2266     switch (v->type()) {
2267         case UndefinedType:
2268             return jsString("undefined");
2269         case NullType:
2270             return jsString("object");
2271         case BooleanType:
2272             return jsString("boolean");
2273         case NumberType:
2274             return jsString("number");
2275         case StringType:
2276             return jsString("string");
2277         default:
2278             if (v->isObject()) {
2279                 // Return "undefined" for objects that should be treated
2280                 // as null when doing comparisons.
2281                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
2282                     return jsString("undefined");
2283                 else if (static_cast<JSObject*>(v)->implementsCall())
2284                     return jsString("function");
2285             }
2286
2287             return jsString("object");
2288     }
2289 }
2290
2291 void TypeOfResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
2292 {
2293     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2294     if (index != missingSymbolMarker())
2295         new (this) LocalVarTypeOfNode(index);
2296 }
2297
2298 JSValue* LocalVarTypeOfNode::evaluate(OldInterpreterExecState* exec)
2299 {
2300     ASSERT(exec->variableObject() == exec->scopeChain().top());
2301
2302     return typeStringForValue(exec->localStorage()[m_index].value);
2303 }
2304
2305 RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2306 {
2307     if (RegisterID* local = generator.registerForLocal(m_ident))
2308         return generator.emitTypeOf(generator.finalDestination(dst), local);
2309
2310     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
2311     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
2312     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
2313 }
2314
2315 JSValue* TypeOfResolveNode::evaluate(OldInterpreterExecState* exec)
2316 {
2317     const ScopeChain& chain = exec->scopeChain();
2318     ScopeChainIterator iter = chain.begin();
2319     ScopeChainIterator end = chain.end();
2320
2321     // We must always have something in the scope chain
2322     ASSERT(iter != end);
2323
2324     PropertySlot slot;
2325     JSObject* base;
2326     do {
2327         base = *iter;
2328         if (base->getPropertySlot(exec, m_ident, slot)) {
2329             JSValue* v = slot.getValue(exec, base, m_ident);
2330             return typeStringForValue(v);
2331         }
2332
2333         ++iter;
2334     } while (iter != end);
2335
2336     return jsString("undefined");
2337 }
2338
2339 // ------------------------------ TypeOfValueNode -----------------------------------
2340
2341 RegisterID* TypeOfValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2342 {
2343     RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
2344     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
2345 }
2346
2347 JSValue* TypeOfValueNode::evaluate(OldInterpreterExecState* exec)
2348 {
2349     JSValue* v = m_expr->evaluate(exec);
2350     KJS_CHECKEXCEPTIONVALUE
2351
2352     return typeStringForValue(v);
2353 }
2354
2355 // ECMA 11.4.4 and 11.4.5
2356
2357 // ------------------------------ PrefixResolveNode ----------------------------------
2358
2359 RegisterID* PreIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2360 {
2361     if (RegisterID* local = generator.registerForLocal(m_ident)) {
2362         if (generator.isLocalConstant(m_ident)) {
2363             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), 1.0);
2364             return generator.emitAdd(r0.get(), local, r0.get());
2365         }
2366         
2367         generator.emitPreInc(local);
2368         return generator.moveToDestinationIfNeeded(dst, local);
2369     }
2370
2371     int index = 0;
2372     size_t depth = 0;
2373     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
2374         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
2375         generator.emitPreInc(propDst.get());
2376         generator.emitPutScopedVar(depth, index, propDst.get());
2377         return generator.moveToDestinationIfNeeded(dst, propDst.get());;
2378     }
2379
2380     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2381     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
2382     generator.emitPreInc(propDst.get());
2383     generator.emitPutById(base.get(), m_ident, propDst.get());
2384     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2385 }
2386
2387 void PreIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
2388 {
2389     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2390     if (index != missingSymbolMarker()) {
2391         if (isConstant(localStorage, index))
2392             new (this) PreIncConstNode(index);
2393         else
2394             new (this) PreIncLocalVarNode(index);
2395     }
2396 }
2397
2398 JSValue* PreIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
2399 {
2400     ASSERT(exec->variableObject() == exec->scopeChain().top());
2401     JSValue** slot = &exec->localStorage()[m_index].value;
2402
2403     double n = (*slot)->toNumber(exec);
2404     JSValue* n2 = jsNumber(n + 1);
2405     *slot = n2;
2406     return n2;
2407 }
2408
2409 JSValue* PreIncResolveNode::evaluate(OldInterpreterExecState* exec)
2410 {
2411     const ScopeChain& chain = exec->scopeChain();
2412     ScopeChainIterator iter = chain.begin();
2413     ScopeChainIterator end = chain.end();
2414
2415     // we must always have something in the scope chain
2416     ASSERT(iter != end);
2417
2418     PropertySlot slot;
2419     do {
2420         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
2421             // See the comment in PostIncResolveNode::evaluate().
2422
2423             JSObject* base = *iter;
2424             JSValue* v = slot.getValue(exec, base, m_ident);
2425
2426             double n = v->toNumber(exec);
2427             JSValue* n2 = jsNumber(n + 1);
2428             base->put(exec, m_ident, n2);
2429
2430             return n2;
2431         }
2432
2433         ++iter;
2434     } while (iter != end);
2435
2436     return throwUndefinedVariableError(exec, m_ident);
2437 }
2438
2439 RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2440 {
2441     if (RegisterID* local = generator.registerForLocal(m_ident)) {
2442         if (generator.isLocalConstant(m_ident)) {
2443             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), -1.0);
2444             return generator.emitAdd(r0.get(), local, r0.get());
2445         }
2446         
2447         generator.emitPreDec(local);
2448         return generator.moveToDestinationIfNeeded(dst, local);
2449     }
2450
2451     int index = 0;
2452     size_t depth = 0;
2453     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
2454         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
2455         generator.emitPreDec(propDst.get());
2456         generator.emitPutScopedVar(depth, index, propDst.get());
2457         return generator.moveToDestinationIfNeeded(dst, propDst.get());;
2458     }
2459
2460     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2461     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
2462     generator.emitPreDec(propDst.get());
2463     generator.emitPutById(base.get(), m_ident, propDst.get());
2464     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2465 }
2466
2467 void PreDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
2468 {
2469     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
2470     if (index != missingSymbolMarker()) {
2471         if (isConstant(localStorage, index))
2472             new (this) PreDecConstNode(index);
2473         else
2474             new (this) PreDecLocalVarNode(index);
2475     }
2476 }
2477
2478 JSValue* PreDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
2479 {
2480     ASSERT(exec->variableObject() == exec->scopeChain().top());
2481     JSValue** slot = &exec->localStorage()[m_index].value;
2482
2483     double n = (*slot)->toNumber(exec);
2484     JSValue* n2 = jsNumber(n - 1);
2485     *slot = n2;
2486     return n2;
2487 }
2488
2489 JSValue* PreDecResolveNode::evaluate(OldInterpreterExecState* exec)
2490 {
2491     const ScopeChain& chain = exec->scopeChain();
2492     ScopeChainIterator iter = chain.begin();
2493     ScopeChainIterator end = chain.end();
2494
2495     // we must always have something in the scope chain
2496     ASSERT(iter != end);
2497
2498     PropertySlot slot;
2499     do {
2500         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
2501             // See the comment in PostIncResolveNode::evaluate().
2502
2503             JSObject* base = *iter;
2504             JSValue* v = slot.getValue(exec, base, m_ident);
2505
2506             double n = v->toNumber(exec);
2507             JSValue* n2 = jsNumber(n - 1);
2508             base->put(exec, m_ident, n2);
2509
2510             return n2;
2511         }
2512
2513         ++iter;
2514     } while (iter != end);
2515
2516     return throwUndefinedVariableError(exec, m_ident);
2517 }
2518
2519 // ------------------------------ PreIncConstNode ----------------------------------
2520
2521 JSValue* PreIncConstNode::evaluate(OldInterpreterExecState* exec)
2522 {
2523     ASSERT(exec->variableObject() == exec->scopeChain().top());
2524     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) + 1);
2525 }
2526
2527 // ------------------------------ PreDecConstNode ----------------------------------
2528
2529 JSValue* PreDecConstNode::evaluate(OldInterpreterExecState* exec)
2530 {
2531     ASSERT(exec->variableObject() == exec->scopeChain().top());
2532     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) - 1);
2533 }
2534
2535 // ------------------------------ PostIncConstNode ----------------------------------
2536
2537 JSValue* PostIncConstNode::evaluate(OldInterpreterExecState* exec)
2538 {
2539     ASSERT(exec->variableObject() == exec->scopeChain().top());
2540     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
2541 }
2542
2543 // ------------------------------ PostDecConstNode ----------------------------------
2544
2545 JSValue* PostDecConstNode::evaluate(OldInterpreterExecState* exec)
2546 {
2547     ASSERT(exec->variableObject() == exec->scopeChain().top());
2548     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
2549 }
2550
2551 // ------------------------------ PrefixBracketNode ----------------------------------
2552
2553 void PrefixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2554 {
2555     nodeStack.append(m_subscript.get());
2556     nodeStack.append(m_base.get());
2557 }
2558
2559 RegisterID* PreIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2560 {
2561     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2562     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
2563     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2564     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
2565     generator.emitPreInc(value);
2566     generator.emitPutByVal(base.get(), property.get(), value);
2567     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2568 }
2569
2570 JSValue* PreIncBracketNode::evaluate(OldInterpreterExecState* exec)
2571 {
2572     JSValue* baseValue = m_base->evaluate(exec);
2573     KJS_CHECKEXCEPTIONVALUE
2574     JSValue* subscript = m_subscript->evaluate(exec);
2575     KJS_CHECKEXCEPTIONVALUE
2576
2577     JSObject* base = baseValue->toObject(exec);
2578
2579     uint32_t propertyIndex;
2580     if (subscript->getUInt32(propertyIndex)) {
2581         PropertySlot slot;
2582         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2583         KJS_CHECKEXCEPTIONVALUE
2584
2585         JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
2586         base->put(exec, propertyIndex, n2);
2587
2588         return n2;
2589     }
2590
2591     Identifier propertyName(subscript->toString(exec));
2592     PropertySlot slot;
2593     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2594     KJS_CHECKEXCEPTIONVALUE
2595
2596     JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
2597     base->put(exec, propertyName, n2);
2598
2599     return n2;
2600 }
2601
2602 RegisterID* PreDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2603 {
2604     
2605     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2606     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
2607     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2608     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
2609     generator.emitPreDec(value);
2610     generator.emitPutByVal(base.get(), property.get(), value);
2611     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2612 }
2613
2614 JSValue* PreDecBracketNode::evaluate(OldInterpreterExecState* exec)
2615 {
2616     JSValue* baseValue = m_base->evaluate(exec);
2617     KJS_CHECKEXCEPTIONVALUE
2618     JSValue* subscript = m_subscript->evaluate(exec);
2619     KJS_CHECKEXCEPTIONVALUE
2620
2621     JSObject* base = baseValue->toObject(exec);
2622
2623     uint32_t propertyIndex;
2624     if (subscript->getUInt32(propertyIndex)) {
2625         PropertySlot slot;
2626         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2627         KJS_CHECKEXCEPTIONVALUE
2628
2629         JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
2630         base->put(exec, propertyIndex, n2);
2631
2632         return n2;
2633     }
2634
2635     Identifier propertyName(subscript->toString(exec));
2636     PropertySlot slot;
2637     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2638     KJS_CHECKEXCEPTIONVALUE
2639
2640     JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
2641     base->put(exec, propertyName, n2);
2642
2643     return n2;
2644 }
2645
2646 // ------------------------------ PrefixDotNode ----------------------------------
2647
2648 void PrefixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2649 {
2650     nodeStack.append(m_base.get());
2651 }
2652
2653 RegisterID* PreIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2654 {
2655     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2656     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2657     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
2658     generator.emitPreInc(value);
2659     generator.emitPutById(base.get(), m_ident, value);
2660     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2661 }
2662
2663 JSValue* PreIncDotNode::evaluate(OldInterpreterExecState* exec)
2664 {
2665     JSValue* baseValue = m_base->evaluate(exec);
2666     KJS_CHECKEXCEPTIONVALUE
2667     JSObject* base = baseValue->toObject(exec);
2668
2669     PropertySlot slot;
2670     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2671     KJS_CHECKEXCEPTIONVALUE
2672
2673     double n = v->toNumber(exec);
2674     JSValue* n2 = jsNumber(n + 1);
2675     base->put(exec, m_ident, n2);
2676
2677     return n2;
2678 }
2679
2680 RegisterID* PreDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2681 {
2682     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
2683     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
2684     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
2685     generator.emitPreDec(value);
2686     generator.emitPutById(base.get(), m_ident, value);
2687     return generator.moveToDestinationIfNeeded(dst, propDst.get());
2688 }
2689
2690 JSValue* PreDecDotNode::evaluate(OldInterpreterExecState* exec)
2691 {
2692     JSValue* baseValue = m_base->evaluate(exec);
2693     KJS_CHECKEXCEPTIONVALUE
2694     JSObject* base = baseValue->toObject(exec);
2695
2696     PropertySlot slot;
2697     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2698     KJS_CHECKEXCEPTIONVALUE
2699
2700     double n = v->toNumber(exec);
2701     JSValue* n2 = jsNumber(n - 1);
2702     base->put(exec, m_ident, n2);
2703
2704     return n2;
2705 }
2706
2707 // ------------------------------ PrefixErrorNode -----------------------------------
2708
2709 RegisterID* PrefixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
2710 {
2711     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
2712 }
2713
2714 JSValue* PrefixErrorNode::evaluate(OldInterpreterExecState* exec)
2715 {
2716     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
2717                m_operator == OpPlusPlus ? "++" : "--");
2718     handleException(exec);
2719     return jsUndefined();
2720 }
2721
2722 // ------------------------------ UnaryPlusNode --------------------------------
2723
2724 RegisterID* UnaryPlusNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2725 {
2726     RegisterID* src = generator.emitNode(m_expr.get());
2727     return generator.emitToJSNumber(generator.finalDestination(dst), src);
2728 }
2729
2730 void UnaryPlusNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2731 {
2732     nodeStack.append(m_expr.get());
2733 }
2734
2735 // ECMA 11.4.6
2736 JSValue* UnaryPlusNode::evaluate(OldInterpreterExecState* exec)
2737 {
2738     JSValue* v = m_expr->evaluate(exec);
2739     KJS_CHECKEXCEPTIONVALUE
2740     return v->toJSNumber(exec);
2741 }
2742
2743 bool UnaryPlusNode::evaluateToBoolean(OldInterpreterExecState* exec)
2744 {
2745     return m_expr->evaluateToBoolean(exec);
2746 }
2747
2748 double UnaryPlusNode::evaluateToNumber(OldInterpreterExecState* exec)
2749 {
2750     return m_expr->evaluateToNumber(exec);
2751 }
2752
2753 int32_t UnaryPlusNode::evaluateToInt32(OldInterpreterExecState* exec)
2754 {
2755     return m_expr->evaluateToInt32(exec);
2756 }
2757
2758 uint32_t UnaryPlusNode::evaluateToUInt32(OldInterpreterExecState* exec)
2759 {
2760     return m_expr->evaluateToInt32(exec);
2761 }
2762
2763 // ------------------------------ NegateNode -----------------------------------
2764
2765 RegisterID* NegateNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2766 {
2767     RegisterID* src = generator.emitNode(m_expr.get());
2768     return generator.emitNegate(generator.finalDestination(dst), src);
2769 }
2770
2771 void NegateNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2772 {
2773     nodeStack.append(m_expr.get());
2774 }
2775
2776 // ECMA 11.4.7
2777 JSValue* NegateNode::evaluate(OldInterpreterExecState* exec)
2778 {
2779     // No need to check exception, caller will do so right after evaluate()
2780     return jsNumber(-m_expr->evaluateToNumber(exec));
2781 }
2782
2783 double NegateNode::evaluateToNumber(OldInterpreterExecState* exec)
2784 {
2785     // No need to check exception, caller will do so right after evaluateToNumber()
2786     return -m_expr->evaluateToNumber(exec);
2787 }
2788
2789 // ------------------------------ BitwiseNotNode -------------------------------
2790
2791 RegisterID* BitwiseNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2792 {
2793     RegisterID* src = generator.emitNode(m_expr.get());
2794     return generator.emitBitNot(generator.finalDestination(dst), src);
2795 }
2796
2797 void BitwiseNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2798 {
2799     nodeStack.append(m_expr.get());
2800 }
2801
2802 // ECMA 11.4.8
2803 int32_t BitwiseNotNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
2804 {
2805     return ~m_expr->evaluateToInt32(exec);
2806 }
2807
2808 JSValue* BitwiseNotNode::evaluate(OldInterpreterExecState* exec)
2809 {
2810     return jsNumber(inlineEvaluateToInt32(exec));
2811 }
2812
2813 double BitwiseNotNode::evaluateToNumber(OldInterpreterExecState* exec)
2814 {
2815     return inlineEvaluateToInt32(exec);
2816 }
2817
2818 bool BitwiseNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
2819 {
2820     return inlineEvaluateToInt32(exec);
2821 }
2822
2823 int32_t BitwiseNotNode::evaluateToInt32(OldInterpreterExecState* exec)
2824 {
2825     return inlineEvaluateToInt32(exec);
2826 }
2827
2828 uint32_t BitwiseNotNode::evaluateToUInt32(OldInterpreterExecState* exec)
2829 {
2830     return inlineEvaluateToInt32(exec);
2831 }
2832
2833 // ------------------------------ LogicalNotNode -------------------------------
2834
2835 RegisterID* LogicalNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2836 {
2837     RegisterID* src = generator.emitNode(m_expr.get());
2838     return generator.emitNot(generator.finalDestination(dst), src);
2839 }
2840
2841 void LogicalNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2842 {
2843     nodeStack.append(m_expr.get());
2844 }
2845
2846 // ECMA 11.4.9
2847 JSValue* LogicalNotNode::evaluate(OldInterpreterExecState* exec)
2848 {
2849     return jsBoolean(!m_expr->evaluateToBoolean(exec));
2850 }
2851
2852 bool LogicalNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
2853 {
2854     return !m_expr->evaluateToBoolean(exec);
2855 }
2856
2857 // ------------------------------ Multiplicative Nodes -----------------------------------
2858
2859 RegisterID* MultNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2860 {
2861     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
2862     RegisterID* src2 = generator.emitNode(m_term2.get());
2863     return generator.emitMul(generator.finalDestination(dst, src1.get()), src1.get(), src2);
2864 }
2865
2866 void MultNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2867 {
2868     nodeStack.append(m_term1.get());
2869     nodeStack.append(m_term2.get());
2870 }
2871
2872 // ECMA 11.5.1
2873 double MultNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
2874 {
2875     double n1 = m_term1->evaluateToNumber(exec);
2876     KJS_CHECKEXCEPTIONNUMBER
2877     double n2 = m_term2->evaluateToNumber(exec);
2878     return n1 * n2;
2879 }
2880
2881 JSValue* MultNode::evaluate(OldInterpreterExecState* exec)
2882 {
2883     return jsNumber(inlineEvaluateToNumber(exec));
2884 }
2885
2886 double MultNode::evaluateToNumber(OldInterpreterExecState* exec)
2887 {
2888     return inlineEvaluateToNumber(exec);
2889 }
2890
2891 bool MultNode::evaluateToBoolean(OldInterpreterExecState* exec)
2892 {
2893     double result = inlineEvaluateToNumber(exec);
2894     return  result > 0.0 || 0.0 > result; // NaN produces false as well
2895 }
2896
2897 int32_t MultNode::evaluateToInt32(OldInterpreterExecState* exec)
2898 {
2899     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2900 }
2901
2902 uint32_t MultNode::evaluateToUInt32(OldInterpreterExecState* exec)
2903 {
2904     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2905 }
2906
2907 RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2908 {
2909     RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
2910     RegisterID* divisor = generator.emitNode(m_term2.get());
2911     return generator.emitDiv(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
2912 }
2913
2914 void DivNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2915 {
2916     nodeStack.append(m_term1.get());
2917     nodeStack.append(m_term2.get());
2918 }
2919
2920 // ECMA 11.5.2
2921 double DivNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
2922 {
2923     double n1 = m_term1->evaluateToNumber(exec);
2924     KJS_CHECKEXCEPTIONNUMBER
2925     double n2 = m_term2->evaluateToNumber(exec);
2926     return n1 / n2;
2927 }
2928
2929 JSValue* DivNode::evaluate(OldInterpreterExecState* exec)
2930 {
2931     return jsNumber(inlineEvaluateToNumber(exec));
2932 }
2933
2934 double DivNode::evaluateToNumber(OldInterpreterExecState* exec)
2935 {
2936     return inlineEvaluateToNumber(exec);
2937 }
2938
2939 int32_t DivNode::evaluateToInt32(OldInterpreterExecState* exec)
2940 {
2941     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2942 }
2943
2944 uint32_t DivNode::evaluateToUInt32(OldInterpreterExecState* exec)
2945 {
2946     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2947 }
2948
2949 RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
2950 {
2951     RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
2952     RegisterID* divisor = generator.emitNode(m_term2.get());
2953     return generator.emitMod(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
2954 }
2955
2956 void ModNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2957 {
2958     nodeStack.append(m_term1.get());
2959     nodeStack.append(m_term2.get());
2960 }
2961
2962 // ECMA 11.5.3
2963 double ModNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
2964 {
2965     double n1 = m_term1->evaluateToNumber(exec);
2966     KJS_CHECKEXCEPTIONNUMBER
2967     double n2 = m_term2->evaluateToNumber(exec);
2968     return fmod(n1, n2);
2969 }
2970
2971 JSValue* ModNode::evaluate(OldInterpreterExecState* exec)
2972 {
2973     return jsNumber(inlineEvaluateToNumber(exec));
2974 }
2975
2976 double ModNode::evaluateToNumber(OldInterpreterExecState* exec)
2977 {
2978     return inlineEvaluateToNumber(exec);
2979 }
2980
2981 bool ModNode::evaluateToBoolean(OldInterpreterExecState* exec)
2982 {
2983     double result = inlineEvaluateToNumber(exec);
2984     return  result > 0.0 || 0.0 > result; // NaN produces false as well
2985 }
2986
2987 int32_t ModNode::evaluateToInt32(OldInterpreterExecState* exec)
2988 {
2989     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2990 }
2991
2992 uint32_t ModNode::evaluateToUInt32(OldInterpreterExecState* exec)
2993 {
2994     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2995 }
2996
2997 // ------------------------------ Additive Nodes --------------------------------------
2998
2999 static double throwOutOfMemoryErrorToNumber(OldInterpreterExecState* exec)
3000 {
3001     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
3002     exec->setException(error);
3003     return 0.0;
3004 }
3005
3006 // ECMA 11.6
3007 static JSValue* addSlowCase(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3008 {
3009     // exception for the Date exception in defaultValue()
3010     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
3011     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
3012
3013     if (p1->isString() || p2->isString()) {
3014         UString value = p1->toString(exec) + p2->toString(exec);
3015         if (value.isNull())
3016             return throwOutOfMemoryError(exec);
3017         return jsString(value);
3018     }
3019
3020     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
3021 }
3022
3023 static double addSlowCaseToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3024 {
3025     // exception for the Date exception in defaultValue()
3026     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
3027     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
3028
3029     if (p1->isString() || p2->isString()) {
3030         UString value = p1->toString(exec) + p2->toString(exec);
3031         if (value.isNull())
3032             return throwOutOfMemoryErrorToNumber(exec);
3033         return value.toDouble();
3034     }
3035
3036     return p1->toNumber(exec) + p2->toNumber(exec);
3037 }
3038
3039 // Fast-path choices here are based on frequency data from SunSpider:
3040 //    <times> Add case: <t1> <t2>
3041 //    ---------------------------
3042 //    5627160 Add case: 1 1
3043 //    247427  Add case: 5 5
3044 //    20901   Add case: 5 6
3045 //    13978   Add case: 5 1
3046 //    4000    Add case: 1 5
3047 //    1       Add case: 3 5
3048
3049 static inline JSValue* add(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3050 {
3051     JSType t1 = v1->type();
3052     JSType t2 = v2->type();
3053     const unsigned bothTypes = (t1 << 3) | t2;
3054
3055     if (bothTypes == ((NumberType << 3) | NumberType))
3056         return jsNumber(v1->toNumber(exec) + v2->toNumber(exec));
3057     if (bothTypes == ((StringType << 3) | StringType)) {
3058         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
3059         if (value.isNull())
3060             return throwOutOfMemoryError(exec);
3061         return jsString(value);
3062     }
3063
3064     // All other cases are pretty uncommon
3065     return addSlowCase(exec, v1, v2);
3066 }
3067
3068 static inline double addToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3069 {
3070     JSType t1 = v1->type();
3071     JSType t2 = v2->type();
3072     const unsigned bothTypes = (t1 << 3) | t2;
3073
3074     if (bothTypes == ((NumberType << 3) | NumberType))
3075         return v1->toNumber(exec) + v2->toNumber(exec);
3076     if (bothTypes == ((StringType << 3) | StringType)) {
3077         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
3078         if (value.isNull())
3079             return throwOutOfMemoryErrorToNumber(exec);
3080         return value.toDouble();
3081     }
3082
3083     // All other cases are pretty uncommon
3084     return addSlowCaseToNumber(exec, v1, v2);
3085 }
3086
3087 RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3088 {
3089     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
3090     RegisterID* src2 = generator.emitNode(m_term2.get());
3091     return generator.emitAdd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3092 }
3093
3094 void AddNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3095 {
3096     nodeStack.append(m_term1.get());
3097     nodeStack.append(m_term2.get());
3098 }
3099
3100 // ECMA 11.6.1
3101 JSValue* AddNode::evaluate(OldInterpreterExecState* exec)
3102 {
3103     JSValue* v1 = m_term1->evaluate(exec);
3104     KJS_CHECKEXCEPTIONVALUE
3105
3106     JSValue* v2 = m_term2->evaluate(exec);
3107     KJS_CHECKEXCEPTIONVALUE
3108
3109     return add(exec, v1, v2);
3110 }
3111
3112 double AddNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
3113 {
3114     JSValue* v1 = m_term1->evaluate(exec);
3115     KJS_CHECKEXCEPTIONNUMBER
3116
3117     JSValue* v2 = m_term2->evaluate(exec);
3118     KJS_CHECKEXCEPTIONNUMBER
3119
3120     return addToNumber(exec, v1, v2);
3121 }
3122
3123 double AddNode::evaluateToNumber(OldInterpreterExecState* exec)
3124 {
3125     return inlineEvaluateToNumber(exec);
3126 }
3127
3128 int32_t AddNode::evaluateToInt32(OldInterpreterExecState* exec)
3129 {
3130     return JSValue::toInt32(inlineEvaluateToNumber(exec));
3131 }
3132
3133 uint32_t AddNode::evaluateToUInt32(OldInterpreterExecState* exec)
3134 {
3135     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
3136 }
3137
3138 double AddNumbersNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
3139 {
3140     double n1 = m_term1->evaluateToNumber(exec);
3141     KJS_CHECKEXCEPTIONNUMBER
3142     double n2 = m_term2->evaluateToNumber(exec);
3143     return n1 + n2;
3144 }
3145
3146 JSValue* AddNumbersNode::evaluate(OldInterpreterExecState* exec)
3147 {
3148     return jsNumber(inlineEvaluateToNumber(exec));
3149 }
3150
3151 double AddNumbersNode::evaluateToNumber(OldInterpreterExecState* exec)
3152 {
3153     return inlineEvaluateToNumber(exec);
3154 }
3155
3156 int32_t AddNumbersNode::evaluateToInt32(OldInterpreterExecState* exec)
3157 {
3158     return JSValue::toInt32(inlineEvaluateToNumber(exec));
3159 }
3160
3161 uint32_t AddNumbersNode::evaluateToUInt32(OldInterpreterExecState* exec)
3162 {
3163     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
3164 }
3165
3166 JSValue* AddStringsNode::evaluate(OldInterpreterExecState* exec)
3167 {
3168     JSValue* v1 = m_term1->evaluate(exec);
3169     KJS_CHECKEXCEPTIONVALUE
3170
3171     JSValue* v2 = m_term2->evaluate(exec);
3172     KJS_CHECKEXCEPTIONVALUE
3173
3174     return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
3175 }
3176
3177 JSValue* AddStringLeftNode::evaluate(OldInterpreterExecState* exec)
3178 {
3179     JSValue* v1 = m_term1->evaluate(exec);
3180     KJS_CHECKEXCEPTIONVALUE
3181
3182     JSValue* v2 = m_term2->evaluate(exec);
3183     KJS_CHECKEXCEPTIONVALUE
3184
3185     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
3186     return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
3187 }
3188
3189 JSValue* AddStringRightNode::evaluate(OldInterpreterExecState* exec)
3190 {
3191     JSValue* v1 = m_term1->evaluate(exec);
3192     KJS_CHECKEXCEPTIONVALUE
3193
3194     JSValue* v2 = m_term2->evaluate(exec);
3195     KJS_CHECKEXCEPTIONVALUE
3196
3197     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
3198     return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
3199 }
3200
3201 RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3202 {
3203     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
3204     RegisterID* src2 = generator.emitNode(m_term2.get());
3205     return generator.emitSub(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3206 }
3207
3208 void SubNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3209 {
3210     nodeStack.append(m_term1.get());
3211     nodeStack.append(m_term2.get());
3212 }
3213
3214 // ECMA 11.6.2
3215 double SubNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
3216 {
3217     double n1 = m_term1->evaluateToNumber(exec);
3218     KJS_CHECKEXCEPTIONNUMBER
3219     double n2 = m_term2->evaluateToNumber(exec);
3220     return n1 - n2;
3221 }
3222
3223 JSValue* SubNode::evaluate(OldInterpreterExecState* exec)
3224 {
3225     return jsNumber(inlineEvaluateToNumber(exec));
3226 }
3227
3228 double SubNode::evaluateToNumber(OldInterpreterExecState* exec)
3229 {
3230     return inlineEvaluateToNumber(exec);
3231 }
3232
3233 int32_t SubNode::evaluateToInt32(OldInterpreterExecState* exec)
3234 {
3235     return JSValue::toInt32(inlineEvaluateToNumber(exec));
3236 }
3237
3238 uint32_t SubNode::evaluateToUInt32(OldInterpreterExecState* exec)
3239 {
3240     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
3241 }
3242
3243 // ------------------------------ Shift Nodes ------------------------------------
3244
3245 RegisterID* LeftShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3246 {
3247     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
3248     RegisterID* shift = generator.emitNode(m_term2.get());
3249     return generator.emitLeftShift(generator.finalDestination(dst, val.get()), val.get(), shift);
3250 }
3251
3252 void LeftShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3253 {
3254     nodeStack.append(m_term1.get());
3255     nodeStack.append(m_term2.get());
3256 }
3257
3258 // ECMA 11.7.1
3259 int32_t LeftShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3260 {
3261     int i1 = m_term1->evaluateToInt32(exec);
3262     KJS_CHECKEXCEPTIONNUMBER
3263     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
3264     return (i1 << i2);
3265 }
3266
3267 JSValue* LeftShiftNode::evaluate(OldInterpreterExecState* exec)
3268 {
3269     return jsNumber(inlineEvaluateToInt32(exec));
3270 }
3271
3272 double LeftShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
3273 {
3274     return inlineEvaluateToInt32(exec);
3275 }
3276
3277 int32_t LeftShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
3278 {
3279     return inlineEvaluateToInt32(exec);
3280 }
3281
3282 uint32_t LeftShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
3283 {
3284     return inlineEvaluateToInt32(exec);
3285 }
3286
3287 RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3288 {
3289     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
3290     RegisterID* shift = generator.emitNode(m_term2.get());
3291     return generator.emitRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
3292 }
3293
3294 void RightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3295 {
3296     nodeStack.append(m_term1.get());
3297     nodeStack.append(m_term2.get());
3298 }
3299
3300 // ECMA 11.7.2
3301 int32_t RightShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3302 {
3303     int i1 = m_term1->evaluateToInt32(exec);
3304     KJS_CHECKEXCEPTIONNUMBER
3305     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
3306     return (i1 >> i2);
3307 }
3308
3309 JSValue* RightShiftNode::evaluate(OldInterpreterExecState* exec)
3310 {
3311     return jsNumber(inlineEvaluateToInt32(exec));
3312 }
3313
3314 double RightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
3315 {
3316     return inlineEvaluateToInt32(exec);
3317 }
3318
3319 int32_t RightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
3320 {
3321     return inlineEvaluateToInt32(exec);
3322 }
3323
3324 uint32_t RightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
3325 {
3326     return inlineEvaluateToInt32(exec);
3327 }
3328
3329 RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3330 {
3331     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
3332     RegisterID* shift = generator.emitNode(m_term2.get());
3333     return generator.emitUnsignedRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
3334 }
3335
3336 void UnsignedRightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3337 {
3338     nodeStack.append(m_term1.get());
3339     nodeStack.append(m_term2.get());
3340 }
3341
3342 // ECMA 11.7.3
3343 uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(OldInterpreterExecState* exec)
3344 {
3345     unsigned int i1 = m_term1->evaluateToUInt32(exec);
3346     KJS_CHECKEXCEPTIONNUMBER
3347     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
3348     return (i1 >> i2);
3349 }
3350
3351 JSValue* UnsignedRightShiftNode::evaluate(OldInterpreterExecState* exec)
3352 {
3353     return jsNumber(inlineEvaluateToUInt32(exec));
3354 }
3355
3356 double UnsignedRightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
3357 {
3358     return inlineEvaluateToUInt32(exec);
3359 }
3360
3361 int32_t UnsignedRightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
3362 {
3363     return inlineEvaluateToUInt32(exec);
3364 }
3365
3366 uint32_t UnsignedRightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
3367 {
3368     return inlineEvaluateToUInt32(exec);
3369 }
3370
3371 // ------------------------------ Relational Nodes -------------------------------
3372
3373 static inline bool lessThan(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3374 {
3375     double n1;
3376     double n2;
3377     JSValue* p1;
3378     JSValue* p2;
3379     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
3380     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
3381
3382     if (wasNotString1 | wasNotString2)
3383         return n1 < n2;
3384
3385     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
3386 }
3387
3388 static inline bool lessThanEq(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
3389 {
3390     double n1;
3391     double n2;
3392     JSValue* p1;
3393     JSValue* p2;
3394     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
3395     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
3396
3397     if (wasNotString1 | wasNotString2)
3398         return n1 <= n2;
3399
3400     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
3401 }
3402
3403 RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3404 {
3405     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3406     RegisterID* src2 = generator.emitNode(m_expr2.get());
3407     return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3408 }
3409
3410 void LessNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3411 {
3412     nodeStack.append(m_expr2.get());
3413     nodeStack.append(m_expr1.get());
3414 }
3415
3416 // ECMA 11.8.1
3417 bool LessNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3418 {
3419     JSValue* v1 = m_expr1->evaluate(exec);
3420     KJS_CHECKEXCEPTIONBOOLEAN
3421     JSValue* v2 = m_expr2->evaluate(exec);
3422     KJS_CHECKEXCEPTIONBOOLEAN
3423     return lessThan(exec, v1, v2);
3424 }
3425
3426 JSValue* LessNode::evaluate(OldInterpreterExecState* exec)
3427 {
3428     return jsBoolean(inlineEvaluateToBoolean(exec));
3429 }
3430
3431 bool LessNode::evaluateToBoolean(OldInterpreterExecState* exec)
3432 {
3433     return inlineEvaluateToBoolean(exec);
3434 }
3435
3436 bool LessNumbersNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3437 {
3438     double n1 = m_expr1->evaluateToNumber(exec);
3439     KJS_CHECKEXCEPTIONVALUE
3440     double n2 = m_expr2->evaluateToNumber(exec);
3441     return n1 < n2;
3442 }
3443
3444 JSValue* LessNumbersNode::evaluate(OldInterpreterExecState* exec)
3445 {
3446     return jsBoolean(inlineEvaluateToBoolean(exec));
3447 }
3448
3449 bool LessNumbersNode::evaluateToBoolean(OldInterpreterExecState* exec)
3450 {
3451     return inlineEvaluateToBoolean(exec);
3452 }
3453
3454 bool LessStringsNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3455 {
3456     JSValue* v1 = m_expr1->evaluate(exec);
3457     KJS_CHECKEXCEPTIONVALUE
3458     JSValue* v2 = m_expr2->evaluate(exec);
3459     return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
3460 }
3461
3462 JSValue* LessStringsNode::evaluate(OldInterpreterExecState* exec)
3463 {
3464     return jsBoolean(inlineEvaluateToBoolean(exec));
3465 }
3466
3467 bool LessStringsNode::evaluateToBoolean(OldInterpreterExecState* exec)
3468 {
3469     return inlineEvaluateToBoolean(exec);
3470 }
3471
3472 RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3473 {
3474     RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
3475     RegisterID* src2 = generator.emitNode(m_expr1.get());
3476     return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3477 }
3478
3479 void GreaterNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3480 {
3481     nodeStack.append(m_expr2.get());
3482     nodeStack.append(m_expr1.get());
3483 }
3484
3485 // ECMA 11.8.2
3486 bool GreaterNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3487 {
3488     JSValue* v1 = m_expr1->evaluate(exec);
3489     KJS_CHECKEXCEPTIONBOOLEAN
3490     JSValue* v2 = m_expr2->evaluate(exec);
3491     KJS_CHECKEXCEPTIONBOOLEAN
3492     return lessThan(exec, v2, v1);
3493 }
3494
3495 JSValue* GreaterNode::evaluate(OldInterpreterExecState* exec)
3496 {
3497     return jsBoolean(inlineEvaluateToBoolean(exec));
3498 }
3499
3500 bool GreaterNode::evaluateToBoolean(OldInterpreterExecState* exec)
3501 {
3502     return inlineEvaluateToBoolean(exec);
3503 }
3504
3505 RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3506 {
3507     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3508     RegisterID* src2 = generator.emitNode(m_expr2.get());
3509     return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3510 }
3511
3512 void LessEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3513 {
3514     nodeStack.append(m_expr2.get());
3515     nodeStack.append(m_expr1.get());
3516 }
3517
3518 // ECMA 11.8.3
3519 bool LessEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3520 {
3521     JSValue* v1 = m_expr1->evaluate(exec);
3522     KJS_CHECKEXCEPTIONBOOLEAN
3523     JSValue* v2 = m_expr2->evaluate(exec);
3524     KJS_CHECKEXCEPTIONBOOLEAN
3525     return lessThanEq(exec, v1, v2);
3526 }
3527
3528 JSValue* LessEqNode::evaluate(OldInterpreterExecState* exec)
3529 {
3530     return jsBoolean(inlineEvaluateToBoolean(exec));
3531 }
3532
3533 bool LessEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
3534 {
3535     return inlineEvaluateToBoolean(exec);
3536 }
3537
3538 RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3539 {
3540     RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
3541     RegisterID* src2 = generator.emitNode(m_expr1.get());
3542     return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3543 }
3544
3545 void GreaterEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3546 {
3547     nodeStack.append(m_expr2.get());
3548     nodeStack.append(m_expr1.get());
3549 }
3550
3551 // ECMA 11.8.4
3552 bool GreaterEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3553 {
3554     JSValue* v1 = m_expr1->evaluate(exec);
3555     KJS_CHECKEXCEPTIONBOOLEAN
3556     JSValue* v2 = m_expr2->evaluate(exec);
3557     KJS_CHECKEXCEPTIONBOOLEAN
3558     return lessThanEq(exec, v2, v1);
3559 }
3560
3561 JSValue* GreaterEqNode::evaluate(OldInterpreterExecState* exec)
3562 {
3563     return jsBoolean(inlineEvaluateToBoolean(exec));
3564 }
3565
3566 bool GreaterEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
3567 {
3568     return inlineEvaluateToBoolean(exec);
3569 }
3570
3571 RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3572 {
3573     RefPtr<RegisterID> value = generator.emitNode(m_expr1.get());
3574     RegisterID* base = generator.emitNode(m_expr2.get());
3575     return generator.emitInstanceOf(generator.finalDestination(dst, value.get()), value.get(), base);
3576 }
3577
3578 void InstanceOfNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3579 {
3580     nodeStack.append(m_expr2.get());
3581     nodeStack.append(m_expr1.get());
3582 }
3583
3584 // ECMA 11.8.6
3585 JSValue* InstanceOfNode::evaluate(OldInterpreterExecState* exec)
3586 {
3587     JSValue* v1 = m_expr1->evaluate(exec);
3588     KJS_CHECKEXCEPTIONVALUE
3589     JSValue* v2 = m_expr2->evaluate(exec);
3590     KJS_CHECKEXCEPTIONVALUE
3591
3592     if (!v2->isObject())
3593         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, m_expr2.get());
3594
3595     JSObject* o2 = static_cast<JSObject*>(v2);
3596
3597     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
3598     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
3599     // property. It seems that all objects have the property, but not all implement it, so in this
3600     // case we return false (consistent with Mozilla).
3601     if (!o2->implementsHasInstance())
3602         return jsBoolean(false);
3603
3604     return jsBoolean(o2->hasInstance(exec, v1));
3605 }
3606
3607 bool InstanceOfNode::evaluateToBoolean(OldInterpreterExecState* exec)
3608 {
3609     JSValue* v1 = m_expr1->evaluate(exec);
3610     KJS_CHECKEXCEPTIONBOOLEAN
3611     JSValue* v2 = m_expr2->evaluate(exec);
3612     KJS_CHECKEXCEPTIONBOOLEAN
3613
3614     if (!v2->isObject()) {
3615         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'instanceof' operator.", v2, m_expr2.get());
3616         return false;
3617     }
3618
3619     JSObject* o2 = static_cast<JSObject*>(v2);
3620
3621     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
3622     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
3623     // property. It seems that all objects have the property, but not all implement it, so in this
3624     // case we return false (consistent with Mozilla).
3625     if (!o2->implementsHasInstance())
3626         return false;
3627
3628     return o2->hasInstance(exec, v1);
3629 }
3630
3631 RegisterID* InNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3632 {
3633     RefPtr<RegisterID> property = generator.emitNode(m_expr1.get());
3634     RegisterID* base = generator.emitNode(m_expr2.get());
3635     return generator.emitIn(generator.finalDestination(dst, property.get()), property.get(), base);
3636 }
3637
3638 void InNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3639 {
3640     nodeStack.append(m_expr2.get());
3641     nodeStack.append(m_expr1.get());
3642 }
3643
3644 // ECMA 11.8.7
3645 JSValue* InNode::evaluate(OldInterpreterExecState* exec)
3646 {
3647     JSValue* v1 = m_expr1->evaluate(exec);
3648     KJS_CHECKEXCEPTIONVALUE
3649     JSValue* v2 = m_expr2->evaluate(exec);
3650     KJS_CHECKEXCEPTIONVALUE
3651
3652     if (!v2->isObject())
3653         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
3654
3655     return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
3656 }
3657
3658 bool InNode::evaluateToBoolean(OldInterpreterExecState* exec)
3659 {
3660     JSValue* v1 = m_expr1->evaluate(exec);
3661     KJS_CHECKEXCEPTIONBOOLEAN
3662     JSValue* v2 = m_expr2->evaluate(exec);
3663     KJS_CHECKEXCEPTIONBOOLEAN
3664
3665     if (!v2->isObject()) {
3666         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
3667         return false;
3668     }
3669
3670     return static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec)));
3671 }
3672
3673 // ------------------------------ Equality Nodes ------------------------------------
3674
3675 RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3676 {
3677     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3678     RegisterID* src2 = generator.emitNode(m_expr2.get());
3679     return generator.emitEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3680 }
3681
3682 void EqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3683 {
3684     nodeStack.append(m_expr2.get());
3685     nodeStack.append(m_expr1.get());
3686 }
3687
3688 // ECMA 11.9.1
3689 bool EqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3690 {
3691     JSValue* v1 = m_expr1->evaluate(exec);
3692     KJS_CHECKEXCEPTIONBOOLEAN
3693     JSValue* v2 = m_expr2->evaluate(exec);
3694     KJS_CHECKEXCEPTIONBOOLEAN
3695
3696     return equal(exec, v1, v2);
3697 }
3698
3699 JSValue* EqualNode::evaluate(OldInterpreterExecState* exec)
3700 {
3701     return jsBoolean(inlineEvaluateToBoolean(exec));
3702 }
3703
3704 bool EqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3705 {
3706     return inlineEvaluateToBoolean(exec);
3707 }
3708
3709 RegisterID* NotEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3710 {
3711     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3712     RegisterID* src2 = generator.emitNode(m_expr2.get());
3713     return generator.emitNotEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3714 }
3715
3716 void NotEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3717 {
3718     nodeStack.append(m_expr2.get());
3719     nodeStack.append(m_expr1.get());
3720 }
3721
3722 // ECMA 11.9.2
3723 bool NotEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3724 {
3725     JSValue* v1 = m_expr1->evaluate(exec);
3726     KJS_CHECKEXCEPTIONBOOLEAN
3727     JSValue* v2 = m_expr2->evaluate(exec);
3728     KJS_CHECKEXCEPTIONBOOLEAN
3729
3730     return !equal(exec,v1, v2);
3731 }
3732
3733 JSValue* NotEqualNode::evaluate(OldInterpreterExecState* exec)
3734 {
3735     return jsBoolean(inlineEvaluateToBoolean(exec));
3736 }
3737
3738 bool NotEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3739 {
3740     return inlineEvaluateToBoolean(exec);
3741 }
3742
3743 RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3744 {
3745     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3746     RegisterID* src2 = generator.emitNode(m_expr2.get());
3747     return generator.emitStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3748 }
3749
3750 void StrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3751 {
3752     nodeStack.append(m_expr2.get());
3753     nodeStack.append(m_expr1.get());
3754 }
3755
3756 // ECMA 11.9.4
3757 bool StrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3758 {
3759     JSValue* v1 = m_expr1->evaluate(exec);
3760     KJS_CHECKEXCEPTIONBOOLEAN
3761     JSValue* v2 = m_expr2->evaluate(exec);
3762     KJS_CHECKEXCEPTIONBOOLEAN
3763
3764     return strictEqual(v1, v2);
3765 }
3766
3767 JSValue* StrictEqualNode::evaluate(OldInterpreterExecState* exec)
3768 {
3769     return jsBoolean(inlineEvaluateToBoolean(exec));
3770 }
3771
3772 bool StrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3773 {
3774     return inlineEvaluateToBoolean(exec);
3775 }
3776
3777 RegisterID* NotStrictEqualNode::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.emitNotStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3782 }
3783
3784 void NotStrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3785 {
3786     nodeStack.append(m_expr2.get());
3787     nodeStack.append(m_expr1.get());
3788 }
3789
3790 // ECMA 11.9.5
3791 bool NotStrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
3792 {
3793     JSValue* v1 = m_expr1->evaluate(exec);
3794     KJS_CHECKEXCEPTIONBOOLEAN
3795     JSValue* v2 = m_expr2->evaluate(exec);
3796     KJS_CHECKEXCEPTIONBOOLEAN
3797
3798     return !strictEqual(v1, v2);
3799 }
3800
3801 JSValue* NotStrictEqualNode::evaluate(OldInterpreterExecState* exec)
3802 {
3803     return jsBoolean(inlineEvaluateToBoolean(exec));
3804 }
3805
3806 bool NotStrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
3807 {
3808     return inlineEvaluateToBoolean(exec);
3809 }
3810
3811 // ------------------------------ Bit Operation Nodes ----------------------------------
3812
3813 RegisterID* BitAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3814 {
3815     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3816     RegisterID* src2 = generator.emitNode(m_expr2.get());
3817     return generator.emitBitAnd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3818 }
3819
3820 void BitAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3821 {
3822     nodeStack.append(m_expr2.get());
3823     nodeStack.append(m_expr1.get());
3824 }
3825
3826 // ECMA 11.10
3827 JSValue* BitAndNode::evaluate(OldInterpreterExecState* exec)
3828 {
3829     JSValue* v1 = m_expr1->evaluate(exec);
3830     KJS_CHECKEXCEPTIONVALUE
3831     JSValue* v2 = m_expr2->evaluate(exec);
3832     KJS_CHECKEXCEPTIONVALUE
3833
3834     return jsNumberFromAnd(exec, v1, v2);
3835 }
3836
3837 int32_t BitAndNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3838 {
3839     int32_t i1 = m_expr1->evaluateToInt32(exec);
3840     KJS_CHECKEXCEPTIONNUMBER
3841     int32_t i2 = m_expr2->evaluateToInt32(exec);
3842     return (i1 & i2);
3843 }
3844
3845 double BitAndNode::evaluateToNumber(OldInterpreterExecState* exec)
3846 {
3847     return inlineEvaluateToInt32(exec);
3848 }
3849
3850 bool BitAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
3851 {
3852     return inlineEvaluateToInt32(exec);
3853 }
3854
3855 int32_t BitAndNode::evaluateToInt32(OldInterpreterExecState* exec)
3856 {
3857     return inlineEvaluateToInt32(exec);
3858 }
3859
3860 uint32_t BitAndNode::evaluateToUInt32(OldInterpreterExecState* exec)
3861 {
3862     return inlineEvaluateToInt32(exec);
3863 }
3864
3865 RegisterID* BitXOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3866 {
3867     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3868     RegisterID* src2 = generator.emitNode(m_expr2.get());
3869     return generator.emitBitXOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3870 }
3871
3872 void BitXOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3873 {
3874     nodeStack.append(m_expr2.get());
3875     nodeStack.append(m_expr1.get());
3876 }
3877
3878 int32_t BitXOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3879 {
3880     int i1 = m_expr1->evaluateToInt32(exec);
3881     KJS_CHECKEXCEPTIONNUMBER
3882     int i2 = m_expr2->evaluateToInt32(exec);
3883     return (i1 ^ i2);
3884 }
3885
3886 JSValue* BitXOrNode::evaluate(OldInterpreterExecState* exec)
3887 {
3888     return jsNumber(inlineEvaluateToInt32(exec));
3889 }
3890
3891 double BitXOrNode::evaluateToNumber(OldInterpreterExecState* exec)
3892 {
3893     return inlineEvaluateToInt32(exec);
3894 }
3895
3896 bool BitXOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
3897 {
3898     return inlineEvaluateToInt32(exec);
3899 }
3900
3901 int32_t BitXOrNode::evaluateToInt32(OldInterpreterExecState* exec)
3902 {
3903     return inlineEvaluateToInt32(exec);
3904 }
3905
3906 uint32_t BitXOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
3907 {
3908     return inlineEvaluateToInt32(exec);
3909 }
3910
3911 RegisterID* BitOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3912 {
3913     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
3914     RegisterID* src2 = generator.emitNode(m_expr2.get());
3915     return generator.emitBitOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
3916 }
3917
3918 void BitOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3919 {
3920     nodeStack.append(m_expr2.get());
3921     nodeStack.append(m_expr1.get());
3922 }
3923
3924 int32_t BitOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
3925 {
3926     int i1 = m_expr1->evaluateToInt32(exec);
3927     KJS_CHECKEXCEPTIONNUMBER
3928     int i2 = m_expr2->evaluateToInt32(exec);
3929     return (i1 | i2);
3930 }
3931
3932 JSValue* BitOrNode::evaluate(OldInterpreterExecState* exec)
3933 {
3934     return jsNumber(inlineEvaluateToInt32(exec));
3935 }
3936
3937 double BitOrNode::evaluateToNumber(OldInterpreterExecState* exec)
3938 {
3939     return inlineEvaluateToInt32(exec);
3940 }
3941
3942 bool BitOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
3943 {
3944     return inlineEvaluateToInt32(exec);
3945 }
3946
3947 int32_t BitOrNode::evaluateToInt32(OldInterpreterExecState* exec)
3948 {
3949     return inlineEvaluateToInt32(exec);
3950 }
3951
3952 uint32_t BitOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
3953 {
3954     return inlineEvaluateToInt32(exec);
3955 }
3956
3957 // ------------------------------ Binary Logical Nodes ----------------------------
3958
3959 RegisterID* LogicalAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
3960 {
3961     RefPtr<RegisterID> temp = generator.tempDestination(dst);
3962     RefPtr<LabelID> target = generator.newLabel();
3963     
3964     generator.emitNode(temp.get(), m_expr1.get());
3965     generator.emitJumpIfFalse(temp.get(), target.get());
3966     generator.emitNode(temp.get(), m_expr2.get());
3967     generator.emitLabel(target.get());
3968
3969     return generator.moveToDestinationIfNeeded(dst, temp.get());
3970 }
3971
3972 void LogicalAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3973 {
3974     nodeStack.append(m_expr2.get());
3975     nodeStack.append(m_expr1.get());
3976 }
3977
3978 // ECMA 11.11
3979 JSValue* LogicalAndNode::evaluate(OldInterpreterExecState* exec)
3980 {
3981     JSValue* v1 = m_expr1->evaluate(exec);
3982     KJS_CHECKEXCEPTIONVALUE
3983     bool b1 = v1->toBoolean(exec);
3984     KJS_CHECKEXCEPTIONVALUE
3985     if (!b1)
3986         return v1;
3987     JSValue* v2 = m_expr2->evaluate(exec);
3988     KJS_CHECKEXCEPTIONVALUE
3989     return v2;
3990 }
3991
3992 bool LogicalAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
3993 {
3994     bool b = m_expr1->evaluateToBoolean(exec);
3995     KJS_CHECKEXCEPTIONBOOLEAN
3996     return b && m_expr2->evaluateToBoolean(exec);
3997 }
3998
3999 RegisterID* LogicalOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4000 {
4001     RefPtr<RegisterID> temp = generator.tempDestination(dst);
4002     RefPtr<LabelID> target = generator.newLabel();
4003     
4004     generator.emitNode(temp.get(), m_expr1.get());
4005     generator.emitJumpIfTrue(temp.get(), target.get());
4006     generator.emitNode(temp.get(), m_expr2.get());
4007     generator.emitLabel(target.get());
4008
4009     return generator.moveToDestinationIfNeeded(dst, temp.get());
4010 }
4011
4012 void LogicalOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4013 {
4014     nodeStack.append(m_expr2.get());
4015     nodeStack.append(m_expr1.get());
4016 }
4017
4018 JSValue* LogicalOrNode::evaluate(OldInterpreterExecState* exec)
4019 {
4020     JSValue* v1 = m_expr1->evaluate(exec);
4021     KJS_CHECKEXCEPTIONVALUE
4022     if (v1->toBoolean(exec))
4023         return v1;
4024     return m_expr2->evaluate(exec);
4025 }
4026
4027 bool LogicalOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
4028 {
4029     bool b = m_expr1->evaluateToBoolean(exec);
4030     KJS_CHECKEXCEPTIONBOOLEAN
4031     return b || m_expr2->evaluateToBoolean(exec);
4032 }
4033
4034 // ------------------------------ ConditionalNode ------------------------------
4035
4036 RegisterID* ConditionalNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4037 {
4038     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
4039     RefPtr<LabelID> beforeElse = generator.newLabel();
4040     RefPtr<LabelID> afterElse = generator.newLabel();
4041
4042     RegisterID* cond = generator.emitNode(m_logical.get());
4043     generator.emitJumpIfFalse(cond, beforeElse.get());
4044
4045     generator.emitNode(newDst.get(), m_expr1.get());
4046     generator.emitJump(afterElse.get());
4047
4048     generator.emitLabel(beforeElse.get());
4049     generator.emitNode(newDst.get(), m_expr2.get());
4050
4051     generator.emitLabel(afterElse.get());
4052
4053     return newDst.get();
4054 }
4055
4056 void ConditionalNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4057 {
4058     nodeStack.append(m_expr2.get());
4059     nodeStack.append(m_expr1.get());
4060     nodeStack.append(m_logical.get());
4061 }
4062
4063 // ECMA 11.12
4064 JSValue* ConditionalNode::evaluate(OldInterpreterExecState* exec)
4065 {
4066     bool b = m_logical->evaluateToBoolean(exec);
4067     KJS_CHECKEXCEPTIONVALUE
4068     return b ? m_expr1->evaluate(exec) : m_expr2->evaluate(exec);
4069 }
4070
4071 bool ConditionalNode::evaluateToBoolean(OldInterpreterExecState* exec)
4072 {
4073     bool b = m_logical->evaluateToBoolean(exec);
4074     KJS_CHECKEXCEPTIONBOOLEAN
4075     return b ? m_expr1->evaluateToBoolean(exec) : m_expr2->evaluateToBoolean(exec);
4076 }
4077
4078 double ConditionalNode::evaluateToNumber(OldInterpreterExecState* exec)
4079 {
4080     bool b = m_logical->evaluateToBoolean(exec);
4081     KJS_CHECKEXCEPTIONNUMBER
4082     return b ? m_expr1->evaluateToNumber(exec) : m_expr2->evaluateToNumber(exec);
4083 }
4084
4085 int32_t ConditionalNode::evaluateToInt32(OldInterpreterExecState* exec)
4086 {
4087     bool b = m_logical->evaluateToBoolean(exec);
4088     KJS_CHECKEXCEPTIONNUMBER
4089     return b ? m_expr1->evaluateToInt32(exec) : m_expr2->evaluateToInt32(exec);
4090 }
4091
4092 uint32_t ConditionalNode::evaluateToUInt32(OldInterpreterExecState* exec)
4093 {
4094     bool b = m_logical->evaluateToBoolean(exec);
4095     KJS_CHECKEXCEPTIONNUMBER
4096     return b ? m_expr1->evaluateToUInt32(exec) : m_expr2->evaluateToUInt32(exec);
4097 }
4098
4099 // ECMA 11.13
4100
4101 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
4102 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
4103 {
4104     JSValue* v;
4105     int i1;
4106     int i2;
4107     unsigned int ui;
4108     switch (oper) {
4109         case OpMultEq:
4110             v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec));
4111             break;
4112         case OpDivEq:
4113             v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec));
4114             break;
4115         case OpPlusEq:
4116             v = add(exec, current, right->evaluate(exec));
4117             break;
4118         case OpMinusEq:
4119             v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec));
4120             break;
4121         case OpLShift:
4122             i1 = current->toInt32(exec);
4123             i2 = right->evaluateToInt32(exec);
4124             v = jsNumber(i1 << i2);
4125             break;
4126         case OpRShift:
4127             i1 = current->toInt32(exec);
4128             i2 = right->evaluateToInt32(exec);
4129             v = jsNumber(i1 >> i2);
4130             break;
4131         case OpURShift:
4132             ui = current->toUInt32(exec);
4133             i2 = right->evaluateToInt32(exec);
4134             v = jsNumber(ui >> i2);
4135             break;
4136         case OpAndEq:
4137             i1 = current->toInt32(exec);
4138             i2 = right->evaluateToInt32(exec);
4139             v = jsNumber(i1 & i2);
4140             break;
4141         case OpXOrEq:
4142             i1 = current->toInt32(exec);
4143             i2 = right->evaluateToInt32(exec);
4144             v = jsNumber(i1 ^ i2);
4145             break;
4146         case OpOrEq:
4147             i1 = current->toInt32(exec);
4148             i2 = right->evaluateToInt32(exec);
4149             v = jsNumber(i1 | i2);
4150             break;
4151         case OpModEq: {
4152             double d1 = current->toNumber(exec);
4153             double d2 = right->evaluateToNumber(exec);
4154             v = jsNumber(fmod(d1, d2));
4155         }
4156             break;
4157         default:
4158             ASSERT_NOT_REACHED();
4159             v = jsUndefined();
4160     }
4161
4162     return v;
4163 }
4164
4165 // ------------------------------ ReadModifyResolveNode -----------------------------------
4166
4167 // FIXME: should this be moved to be a method on CodeGenerator?
4168 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(CodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper)
4169 {
4170     switch (oper) {
4171         case OpMultEq:
4172             return generator.emitMul(dst, src1, src2);
4173         case OpDivEq:
4174             return generator.emitDiv(dst, src1, src2);
4175         case OpPlusEq:
4176             return generator.emitAdd(dst, src1, src2);
4177         case OpMinusEq:
4178             return generator.emitSub(dst, src1, src2);
4179         case OpLShift:
4180             return generator.emitLeftShift(dst, src1, src2);
4181         case OpRShift:
4182             return generator.emitRightShift(dst, src1, src2);
4183         case OpURShift:
4184             return generator.emitUnsignedRightShift(dst, src1, src2);
4185         case OpAndEq:
4186             return generator.emitBitAnd(dst, src1, src2);
4187         case OpXOrEq:
4188             return generator.emitBitXOr(dst, src1, src2);
4189         case OpOrEq:
4190             return generator.emitBitOr(dst, src1, src2);
4191         case OpModEq:
4192             return generator.emitMod(dst, src1, src2);
4193         default:
4194             ASSERT_NOT_REACHED();
4195     }
4196
4197     return dst;
4198 }
4199
4200 RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4201 {
4202     if (RegisterID* local = generator.registerForLocal(m_ident)) {
4203         if (generator.isLocalConstant(m_ident)) {
4204             RegisterID* src2 = generator.emitNode(m_right.get());
4205             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator);
4206         }
4207         
4208         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments) && !m_right.get()->isNumber()) {
4209             RefPtr<RegisterID> result = generator.newTemporary();
4210             generator.emitMove(result.get(), local);
4211             RegisterID* src2 = generator.emitNode(m_right.get());
4212             emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator);
4213             generator.emitMove(local, result.get());
4214             return generator.moveToDestinationIfNeeded(dst, result.get());
4215         }
4216         
4217         RegisterID* src2 = generator.emitNode(m_right.get());
4218         RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator);
4219         return generator.moveToDestinationIfNeeded(dst, result);
4220     }
4221
4222     int index = 0;
4223     size_t depth = 0;
4224     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
4225         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
4226         RegisterID* src2 = generator.emitNode(m_right.get());
4227         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
4228         generator.emitPutScopedVar(depth, index, result);
4229         return result;
4230     }
4231
4232     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
4233     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
4234     RegisterID* src2 = generator.emitNode(m_right.get());
4235     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
4236     return generator.emitPutById(base.get(), m_ident, result);
4237 }
4238
4239 void ReadModifyResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
4240 {
4241     nodeStack.append(m_right.get());
4242     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
4243     if (index != missingSymbolMarker()) {
4244         if (isConstant(localStorage, index))
4245             new (this) ReadModifyConstNode(index);
4246         else
4247             new (this) ReadModifyLocalVarNode(index);
4248     }
4249 }
4250
4251 // ------------------------------ AssignResolveNode -----------------------------------
4252
4253 RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4254 {
4255     if (RegisterID* local = generator.registerForLocal(m_ident)) {
4256         if (generator.isLocalConstant(m_ident))
4257             return generator.emitNode(dst, m_right.get());
4258         
4259         RegisterID* result = generator.emitNode(local, m_right.get());
4260         return generator.moveToDestinationIfNeeded(dst, result);
4261     }
4262
4263     int index = 0;
4264     size_t depth = 0;
4265     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
4266         RegisterID* value = generator.emitNode(dst, m_right.get());
4267         generator.emitPutScopedVar(depth, index, value);
4268         return value;
4269     }
4270
4271     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
4272     RegisterID* value = generator.emitNode(dst, m_right.get());
4273     return generator.emitPutById(base.get(), m_ident, value);
4274 }
4275
4276 void AssignResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
4277 {
4278     nodeStack.append(m_right.get());
4279     int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
4280     if (index != missingSymbolMarker()) {
4281         if (isConstant(localStorage, index))
4282             new (this) AssignConstNode;
4283         else
4284             new (this) AssignLocalVarNode(index);
4285     }
4286 }
4287
4288 // ------------------------------ ReadModifyLocalVarNode -----------------------------------
4289
4290 JSValue* ReadModifyLocalVarNode::evaluate(OldInterpreterExecState* exec)
4291 {
4292     ASSERT(exec->variableObject() == exec->scopeChain().top());
4293
4294     ASSERT(m_operator != OpEqual);
4295     JSValue* v = valueForReadModifyAssignment(exec, exec->localStorage()[m_index].value, m_right.get(), m_operator);
4296
4297     KJS_CHECKEXCEPTIONVALUE
4298     
4299     // We can't store a pointer into localStorage() and use it throughout the function
4300     // body, because valueForReadModifyAssignment() might cause an ActivationImp tear-off,
4301     // changing the value of localStorage().
4302     
4303     exec->localStorage()[m_index].value = v;
4304     return v;
4305 }
4306
4307 // ------------------------------ AssignLocalVarNode -----------------------------------
4308
4309 JSValue* AssignLocalVarNode::evaluate(OldInterpreterExecState* exec)
4310 {
4311     ASSERT(exec->variableObject() == exec->scopeChain().top());
4312     JSValue* v = m_right->evaluate(exec);
4313
4314     KJS_CHECKEXCEPTIONVALUE
4315
4316     exec->localStorage()[m_index].value = v;
4317
4318     return v;
4319 }
4320
4321 // ------------------------------ ReadModifyConstNode -----------------------------------
4322
4323 JSValue* ReadModifyConstNode::evaluate(OldInterpreterExecState* exec)
4324 {
4325     ASSERT(exec->variableObject() == exec->scopeChain().top());
4326     JSValue* left = exec->localStorage()[m_index].value;
4327     ASSERT(m_operator != OpEqual);
4328     JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_operator);
4329     KJS_CHECKEXCEPTIONVALUE
4330     return result;
4331 }
4332
4333 // ------------------------------ AssignConstNode -----------------------------------
4334
4335 JSValue* AssignConstNode::evaluate(OldInterpreterExecState* exec)
4336 {
4337     return m_right->evaluate(exec);
4338 }
4339
4340 JSValue* ReadModifyResolveNode::evaluate(OldInterpreterExecState* exec)
4341 {
4342     const ScopeChain& chain = exec->scopeChain();
4343     ScopeChainIterator iter = chain.begin();
4344     ScopeChainIterator end = chain.end();
4345
4346     // We must always have something in the scope chain
4347     ASSERT(iter != end);
4348
4349     PropertySlot slot;
4350     JSObject* base;
4351     do {
4352         base = *iter;
4353         if (base->getPropertySlot(exec, m_ident, slot)) {
4354             // See the comment in PostIncResolveNode::evaluate().
4355
4356             base = *iter;
4357             goto found;
4358         }
4359
4360         ++iter;
4361     } while (iter != end);
4362
4363     ASSERT(m_operator != OpEqual);
4364     return throwUndefinedVariableError(exec, m_ident);
4365
4366 found:
4367     JSValue* v;
4368
4369     ASSERT(m_operator != OpEqual);
4370     JSValue* v1 = slot.getValue(exec, base, m_ident);
4371     KJS_CHECKEXCEPTIONVALUE
4372     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
4373
4374     KJS_CHECKEXCEPTIONVALUE
4375     
4376     // Since valueForReadModifyAssignment() might cause an ActivationImp tear-off,
4377     // we need to get the base from the ScopeChainIterator again.
4378     
4379     (*iter)->put(exec, m_ident, v);
4380     return v;
4381 }
4382
4383 JSValue* AssignResolveNode::evaluate(OldInterpreterExecState* exec)
4384 {
4385     const ScopeChain& chain = exec->scopeChain();
4386     ScopeChainIterator iter = chain.begin();
4387     ScopeChainIterator end = chain.end();
4388
4389     // we must always have something in the scope chain
4390     ASSERT(iter != end);
4391
4392     PropertySlot slot;
4393     JSObject* base;
4394     do {
4395         base = *iter;
4396         if (base->getPropertySlot(exec, m_ident, slot)) {
4397             // See the comment in PostIncResolveNode::evaluate().
4398
4399             base = *iter;
4400             goto found;
4401         }
4402
4403         ++iter;
4404     } while (iter != end);
4405
4406 found:
4407     JSValue* v = m_right->evaluate(exec);
4408
4409     KJS_CHECKEXCEPTIONVALUE
4410
4411     base->put(exec, m_ident, v);
4412     return v;
4413 }
4414
4415 // ------------------------------ ReadModifyDotNode -----------------------------------
4416
4417 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4418 {
4419     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
4420     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
4421     RegisterID* result = generator.emitNode(value.get(), m_right.get());
4422     generator.emitPutById(base.get(), m_ident, result);
4423     return generator.moveToDestinationIfNeeded(dst, result);
4424 }
4425
4426 void AssignDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4427 {
4428     nodeStack.append(m_right.get());
4429     nodeStack.append(m_base.get());
4430 }
4431
4432 JSValue* AssignDotNode::evaluate(OldInterpreterExecState* exec)
4433 {
4434     JSValue* baseValue = m_base->evaluate(exec);
4435     KJS_CHECKEXCEPTIONVALUE
4436     JSObject* base = baseValue->toObject(exec);
4437
4438     JSValue* v = m_right->evaluate(exec);
4439
4440     KJS_CHECKEXCEPTIONVALUE
4441
4442     base->put(exec, m_ident, v);
4443     return v;
4444 }
4445
4446 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4447 {
4448     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
4449     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
4450     RegisterID* change = generator.emitNode(m_right.get());
4451     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
4452     return generator.emitPutById(base.get(), m_ident, updatedValue);
4453 }
4454
4455 void ReadModifyDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4456 {
4457     nodeStack.append(m_right.get());
4458     nodeStack.append(m_base.get());
4459 }
4460
4461 JSValue* ReadModifyDotNode::evaluate(OldInterpreterExecState* exec)
4462 {
4463     JSValue* baseValue = m_base->evaluate(exec);
4464     KJS_CHECKEXCEPTIONVALUE
4465     JSObject* base = baseValue->toObject(exec);
4466
4467     JSValue* v;
4468
4469     ASSERT(m_operator != OpEqual);
4470     PropertySlot slot;
4471     JSValue* v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
4472     KJS_CHECKEXCEPTIONVALUE
4473     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
4474
4475     KJS_CHECKEXCEPTIONVALUE
4476
4477     base->put(exec, m_ident, v);
4478     return v;
4479 }
4480
4481 // ------------------------------ AssignErrorNode -----------------------------------
4482
4483 RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
4484 {
4485     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
4486 }
4487
4488 JSValue* AssignErrorNode::evaluate(OldInterpreterExecState* exec)
4489 {
4490     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
4491     handleException(exec);
4492     return jsUndefined();
4493 }
4494
4495 // ------------------------------ AssignBracketNode -----------------------------------
4496
4497 RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
4498 {
4499     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
4500     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
4501     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
4502     RegisterID* result = generator.emitNode(value.get(), m_right.get());
4503     generator.emitPutByVal(base.get(), property.get(), result);
4504     return generator.moveToDestinationIfNeeded(dst, result);
4505 }
4506
4507 void AssignBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
4508 {
4509     nodeStack.append(m_right.get());
4510     nodeStack.append(m_subscript.get());
4511     nodeStack.append(m_base.get());
4512 }
4513
4514 JSValue* AssignBracketNode::evaluate(OldInterpreterExecState* exec)
4515 {
4516     JSValue* baseValue = m_base->evaluate(exec);
4517     KJS_CHECKEXCEPTIONVALUE
4518     JSValue* subscript = m_subscript->evaluate(exec);
4519     KJS_CHECKEXCEPTIONVALUE
4520
4521     JSObject* base = baseValue->toObject(exec);
4522
4523     uint32_t propertyIndex;
4524     if (subscript->getUInt32(propertyIndex)) {
4525         JSValue* v = m_right->evaluate(exec);
4526         KJS_CHECKEXCEPTIONVALUE
4527
4528         base->put(exec, propertyIndex, v);
4529         return v;
4530     }
4531
4532     Identifier propertyName(subscript->toString(exec));
4533     JSValue* v = m_right->evaluate(exec);
4534     KJS_CHECKEXCEPTIONVALUE
4535