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