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