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