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