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