Reviewed by Oliver.
[WebKit-https.git] / JavaScriptCore / kjs / nodes.cpp
1 /*
2  *  This file is part of the KDE libraries
3  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Library General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Library General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Library General Public License
19  *  along with this library; see the file COPYING.LIB.  If not, write to
20  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "config.h"
26 #include "nodes.h"
27
28 #include <math.h>
29 #ifdef KJS_DEBUG_MEM
30 #include <stdio.h>
31 #include <typeinfo>
32 #endif
33
34 #include "context.h"
35 #include "debugger.h"
36 #include "function_object.h"
37 #include "lexer.h"
38 #include "operations.h"
39 #include "PropertyNameArray.h"
40 #include <wtf/HashSet.h>
41 #include <wtf/HashCountedSet.h>
42 #include <wtf/MathExtras.h>
43
44 using namespace KJS;
45
46 #define KJS_BREAKPOINT \
47   if (Debugger::debuggersPresent > 0 && !hitStatement(exec)) \
48     return Completion(Normal);
49
50 #define KJS_ABORTPOINT \
51   if (Debugger::debuggersPresent > 0 && \
52       exec->dynamicInterpreter()->imp()->debugger() && \
53       exec->dynamicInterpreter()->imp()->debugger()->imp()->aborted()) \
54     return Completion(Normal);
55
56 #define KJS_CHECKEXCEPTION \
57   if (exec->hadException()) { \
58     JSValue *ex = exec->exception(); \
59     exec->clearException(); \
60     handleException(exec, ex); \
61     return Completion(Throw, ex); \
62   } \
63   if (Collector::isOutOfMemory()) \
64     return Completion(Throw, Error::create(exec, GeneralError, "Out of memory"));
65
66 #define KJS_CHECKEXCEPTIONVALUE \
67   if (exec->hadException()) { \
68     handleException(exec); \
69     return jsUndefined(); \
70   } \
71   if (Collector::isOutOfMemory()) \
72     return jsUndefined(); // will be picked up by KJS_CHECKEXCEPTION
73
74 #define KJS_CHECKEXCEPTIONLIST \
75   if (exec->hadException()) { \
76     handleException(exec); \
77     return List(); \
78   } \
79   if (Collector::isOutOfMemory()) \
80     return List(); // will be picked up by KJS_CHECKEXCEPTION
81
82 // ------------------------------ Node -----------------------------------------
83
84 #ifndef NDEBUG
85 #ifndef LOG_CHANNEL_PREFIX
86 #define LOG_CHANNEL_PREFIX Log
87 #endif
88 static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn };
89
90 struct NodeCounter { 
91     static unsigned count; 
92     ~NodeCounter() 
93     { 
94         if (count) 
95             LOG(KJSNodeLeaks, "LEAK: %u KJS::Node\n", count); 
96     }
97 };
98 unsigned NodeCounter::count = 0;
99 static NodeCounter nodeCounter;
100 #endif
101
102 static HashSet<Node*>* newNodes;
103 static HashCountedSet<Node*>* nodeExtraRefCounts;
104
105 Node::Node()
106 {
107 #ifndef NDEBUG
108     ++NodeCounter::count;
109 #endif
110   m_line = Lexer::curr()->lineNo();
111   if (!newNodes)
112       newNodes = new HashSet<Node*>;
113   newNodes->add(this);
114 }
115
116 Node::~Node()
117 {
118 #ifndef NDEBUG
119     --NodeCounter::count;
120 #endif
121 }
122
123 void Node::ref()
124 {
125     // bumping from 0 to 1 is just removing from the new nodes set
126     if (newNodes) {
127         HashSet<Node*>::iterator it = newNodes->find(this);
128         if (it != newNodes->end()) {
129             newNodes->remove(it);
130             ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
131             return;
132         }
133     }   
134
135     ASSERT(!newNodes || !newNodes->contains(this));
136     
137     if (!nodeExtraRefCounts)
138         nodeExtraRefCounts = new HashCountedSet<Node*>;
139     nodeExtraRefCounts->add(this);
140 }
141
142 void Node::deref()
143 {
144     ASSERT(!newNodes || !newNodes->contains(this));
145     
146     if (!nodeExtraRefCounts) {
147         delete this;
148         return;
149     }
150
151     HashCountedSet<Node*>::iterator it = nodeExtraRefCounts->find(this);
152     if (it == nodeExtraRefCounts->end())
153         delete this;
154     else
155         nodeExtraRefCounts->remove(it);
156 }
157
158 unsigned Node::refcount()
159 {
160     if (newNodes && newNodes->contains(this)) {
161         ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
162         return 0;
163     }
164  
165     ASSERT(!newNodes || !newNodes->contains(this));
166
167     if (!nodeExtraRefCounts)
168         return 1;
169
170     return 1 + nodeExtraRefCounts->count(this);
171 }
172
173 void Node::clearNewNodes()
174 {
175     if (!newNodes)
176         return;
177
178 #ifndef NDEBUG
179     HashSet<Node*>::iterator end = newNodes->end();
180     for (HashSet<Node*>::iterator it = newNodes->begin(); it != end; ++it)
181         ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));
182 #endif
183     deleteAllValues(*newNodes);
184     delete newNodes;
185     newNodes = 0;
186 }
187
188 static void substitute(UString &string, const UString &substring) KJS_FAST_CALL;
189 static void substitute(UString &string, const UString &substring)
190 {
191     int position = string.find("%s");
192     assert(position != -1);
193     string = string.substr(0, position) + substring + string.substr(position + 2);
194 }
195
196 static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
197 static inline int currentSourceId(ExecState* exec)
198 {
199     return exec->context()->currentBody()->sourceId();
200 }
201
202 static inline const UString& currentSourceURL(ExecState* exec) KJS_FAST_CALL;
203 static inline const UString& currentSourceURL(ExecState* exec)
204 {
205     return exec->context()->currentBody()->sourceURL();
206 }
207
208 Completion Node::createErrorCompletion(ExecState* exec, ErrorType e, const char *msg)
209 {
210     return Completion(Throw, Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
211 }
212
213 Completion Node::createErrorCompletion(ExecState *exec, ErrorType e, const char *msg, const Identifier &ident)
214 {
215     UString message = msg;
216     substitute(message, ident.ustring());
217     return Completion(Throw, Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
218 }
219
220 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char *msg)
221 {
222     return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
223 }
224
225 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char* msg, const char* string)
226 {
227     UString message = msg;
228     substitute(message, string);
229     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
230 }
231
232 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *expr)
233 {
234     UString message = msg;
235     substitute(message, v->toString(exec));
236     substitute(message, expr->toString());
237     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
238 }
239
240
241 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, const Identifier &label)
242 {
243     UString message = msg;
244     substitute(message, label.ustring());
245     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
246 }
247
248 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *e1, Node *e2)
249 {
250     UString message = msg;
251     substitute(message, v->toString(exec));
252     substitute(message, e1->toString());
253     substitute(message, e2->toString());
254     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
255 }
256
257 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *expr, const Identifier &label)
258 {
259     UString message = msg;
260     substitute(message, v->toString(exec));
261     substitute(message, expr->toString());
262     substitute(message, label.ustring());
263     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
264 }
265
266 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, const Identifier &label)
267 {
268     UString message = msg;
269     substitute(message, v->toString(exec));
270     substitute(message, label.ustring());
271     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
272 }
273
274 JSValue *Node::throwUndefinedVariableError(ExecState *exec, const Identifier &ident)
275 {
276     return throwError(exec, ReferenceError, "Can't find variable: %s", ident);
277 }
278
279 void Node::handleException(ExecState* exec)
280 {
281     handleException(exec, exec->exception());
282 }
283
284 void Node::handleException(ExecState* exec, JSValue* exceptionValue)
285 {
286     if (exceptionValue->isObject()) {
287         JSObject* exception = static_cast<JSObject*>(exceptionValue);
288         if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) {
289             exception->put(exec, "line", jsNumber(m_line));
290             exception->put(exec, "sourceURL", jsString(currentSourceURL(exec)));
291         }
292     }
293     Debugger* dbg = exec->dynamicInterpreter()->debugger();
294     if (dbg && !dbg->hasHandledException(exec, exceptionValue)) {
295         bool cont = dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);
296         if (!cont)
297             dbg->imp()->abort();
298     }
299 }
300
301 Node *Node::nodeInsideAllParens()
302 {
303     return this;
304 }
305
306 // ------------------------------ StatementNode --------------------------------
307
308 StatementNode::StatementNode() 
309     : m_lastLine(-1)
310 {
311     m_line = -1;
312 }
313
314 void StatementNode::setLoc(int firstLine, int lastLine)
315 {
316     m_line = firstLine;
317     m_lastLine = lastLine;
318 }
319
320 // return true if the debugger wants us to stop at this point
321 bool StatementNode::hitStatement(ExecState* exec)
322 {
323   Debugger *dbg = exec->dynamicInterpreter()->debugger();
324   if (dbg)
325     return dbg->atStatement(exec, currentSourceId(exec), firstLine(), lastLine());
326   else
327     return true; // continue
328 }
329
330 void StatementNode::processFuncDecl(ExecState*)
331 {
332 }
333
334 // ------------------------------ NullNode -------------------------------------
335
336 JSValue *NullNode::evaluate(ExecState *)
337 {
338   return jsNull();
339 }
340
341 // ------------------------------ BooleanNode ----------------------------------
342
343 JSValue *BooleanNode::evaluate(ExecState *)
344 {
345   return jsBoolean(value);
346 }
347
348 // ------------------------------ NumberNode -----------------------------------
349
350 JSValue *NumberNode::evaluate(ExecState *)
351 {
352   return jsNumber(value);
353 }
354
355 // ------------------------------ StringNode -----------------------------------
356
357 JSValue *StringNode::evaluate(ExecState *)
358 {
359   return jsString(value);
360 }
361
362 // ------------------------------ RegExpNode -----------------------------------
363
364 JSValue *RegExpNode::evaluate(ExecState *exec)
365 {
366   List list;
367   list.append(jsString(pattern));
368   list.append(jsString(flags));
369
370   JSObject *reg = exec->lexicalInterpreter()->builtinRegExp();
371   return reg->construct(exec,list);
372 }
373
374 // ------------------------------ ThisNode -------------------------------------
375
376 // ECMA 11.1.1
377 JSValue *ThisNode::evaluate(ExecState *exec)
378 {
379   return exec->context()->thisValue();
380 }
381
382 // ------------------------------ ResolveNode ----------------------------------
383
384 // ECMA 11.1.2 & 10.1.4
385 JSValue *ResolveNode::evaluate(ExecState *exec)
386 {
387   const ScopeChain& chain = exec->context()->scopeChain();
388   ScopeChainIterator iter = chain.begin();
389   ScopeChainIterator end = chain.end();
390   
391   // we must always have something in the scope chain
392   assert(iter != end);
393
394   PropertySlot slot;
395   do { 
396     JSObject *o = *iter;
397
398     if (o->getPropertySlot(exec, ident, slot))
399       return slot.getValue(exec, o, ident);
400     
401     ++iter;
402   } while (iter != end);
403
404   return throwUndefinedVariableError(exec, ident);
405 }
406
407 // ------------------------------ GroupNode ------------------------------------
408
409 // ECMA 11.1.6
410 JSValue *GroupNode::evaluate(ExecState *exec)
411 {
412   return group->evaluate(exec);
413 }
414
415 Node *GroupNode::nodeInsideAllParens()
416 {
417     Node *n = this;
418     do
419         n = static_cast<GroupNode *>(n)->group.get();
420     while (n->isGroupNode());
421     return n;
422 }
423
424 // ------------------------------ ElementNode ----------------------------------
425
426 // ECMA 11.1.4
427 JSValue *ElementNode::evaluate(ExecState *exec)
428 {
429   JSObject *array = exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty());
430   int length = 0;
431   for (ElementNode *n = this; n; n = n->next.get()) {
432     JSValue *val = n->node->evaluate(exec);
433     KJS_CHECKEXCEPTIONVALUE
434     length += n->elision;
435     array->put(exec, length++, val);
436   }
437   return array;
438 }
439
440 void ElementNode::breakCycle() 
441
442     next = 0;
443 }
444
445 // ------------------------------ ArrayNode ------------------------------------
446
447 // ECMA 11.1.4
448 JSValue *ArrayNode::evaluate(ExecState *exec)
449 {
450   JSObject *array;
451   int length;
452
453   if (element) {
454     array = static_cast<JSObject*>(element->evaluate(exec));
455     KJS_CHECKEXCEPTIONVALUE
456     length = opt ? array->get(exec, exec->propertyNames().length)->toInt32(exec) : 0;
457   } else {
458     JSValue *newArr = exec->lexicalInterpreter()->builtinArray()->construct(exec,List::empty());
459     array = static_cast<JSObject*>(newArr);
460     length = 0;
461   }
462
463   if (opt)
464     array->put(exec, exec->propertyNames().length, jsNumber(elision + length), DontEnum | DontDelete);
465
466   return array;
467 }
468
469 // ------------------------------ ObjectLiteralNode ----------------------------
470
471 // ECMA 11.1.5
472 JSValue *ObjectLiteralNode::evaluate(ExecState *exec)
473 {
474   if (list)
475     return list->evaluate(exec);
476
477   return exec->lexicalInterpreter()->builtinObject()->construct(exec,List::empty());
478 }
479
480 // ------------------------------ PropertyListNode -----------------------------
481
482 // ECMA 11.1.5
483 JSValue *PropertyListNode::evaluate(ExecState *exec)
484 {
485   JSObject *obj = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
486   
487   for (PropertyListNode *p = this; p; p = p->next.get()) {
488     JSValue *n = p->node->name->evaluate(exec);
489     KJS_CHECKEXCEPTIONVALUE
490     JSValue *v = p->node->assign->evaluate(exec);
491     KJS_CHECKEXCEPTIONVALUE
492     
493     Identifier propertyName = Identifier(n->toString(exec));
494     switch (p->node->type) {
495       case PropertyNode::Getter:
496         assert(v->isObject());
497         obj->defineGetter(exec, propertyName, static_cast<JSObject *>(v));
498         break;
499       case PropertyNode::Setter:
500         assert(v->isObject());
501         obj->defineSetter(exec, propertyName, static_cast<JSObject *>(v));
502         break;
503       case PropertyNode::Constant:
504         obj->put(exec, propertyName, v);
505         break;
506     }
507   }
508
509   return obj;
510 }
511
512 void PropertyListNode::breakCycle() 
513
514     next = 0;
515 }
516
517 // ------------------------------ PropertyNode -----------------------------
518 // ECMA 11.1.5
519 JSValue *PropertyNode::evaluate(ExecState*)
520 {
521   assert(false);
522   return jsNull();
523 }
524
525 // ---------------------------- PropertyNameNode -------------------------------
526
527 // ECMA 11.1.5
528 JSValue *PropertyNameNode::evaluate(ExecState*)
529 {
530   JSValue *s;
531
532   if (str.isNull()) {
533     s = jsString(UString::from(numeric));
534   } else {
535     s = jsString(str.ustring());
536   }
537
538   return s;
539 }
540
541 // ------------------------------ BracketAccessorNode --------------------------------
542
543 // ECMA 11.2.1a
544 JSValue *BracketAccessorNode::evaluate(ExecState *exec)
545 {
546   JSValue *v1 = expr1->evaluate(exec);
547   KJS_CHECKEXCEPTIONVALUE
548   JSValue *v2 = expr2->evaluate(exec);
549   KJS_CHECKEXCEPTIONVALUE
550   JSObject *o = v1->toObject(exec);
551   uint32_t i;
552   if (v2->getUInt32(i))
553     return o->get(exec, i);
554   return o->get(exec, Identifier(v2->toString(exec)));
555 }
556
557 // ------------------------------ DotAccessorNode --------------------------------
558
559 // ECMA 11.2.1b
560 JSValue *DotAccessorNode::evaluate(ExecState *exec)
561 {
562   JSValue *v = expr->evaluate(exec);
563   KJS_CHECKEXCEPTIONVALUE
564   return v->toObject(exec)->get(exec, ident);
565
566 }
567
568 // ------------------------------ ArgumentListNode -----------------------------
569
570 JSValue *ArgumentListNode::evaluate(ExecState *)
571 {
572   assert(0);
573   return 0; // dummy, see evaluateList()
574 }
575
576 // ECMA 11.2.4
577 List ArgumentListNode::evaluateList(ExecState *exec)
578 {
579   List l;
580
581   for (ArgumentListNode *n = this; n; n = n->next.get()) {
582     JSValue *v = n->expr->evaluate(exec);
583     KJS_CHECKEXCEPTIONLIST
584     l.append(v);
585   }
586
587   return l;
588 }
589
590 void ArgumentListNode::breakCycle() 
591
592     next = 0;
593 }
594
595 // ------------------------------ ArgumentsNode --------------------------------
596
597 JSValue *ArgumentsNode::evaluate(ExecState *)
598 {
599   assert(0);
600   return 0; // dummy, see evaluateList()
601 }
602
603 // ------------------------------ NewExprNode ----------------------------------
604
605 // ECMA 11.2.2
606
607 JSValue *NewExprNode::evaluate(ExecState *exec)
608 {
609   JSValue *v = expr->evaluate(exec);
610   KJS_CHECKEXCEPTIONVALUE
611
612   List argList;
613   if (args) {
614     argList = args->evaluateList(exec);
615     KJS_CHECKEXCEPTIONVALUE
616   }
617
618   if (!v->isObject()) {
619     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr.get());
620   }
621
622   JSObject *constr = static_cast<JSObject*>(v);
623   if (!constr->implementsConstruct()) {
624     return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr.get());
625   }
626
627   return constr->construct(exec, argList);
628 }
629
630 // ECMA 11.2.3
631 JSValue *FunctionCallValueNode::evaluate(ExecState *exec)
632 {
633   JSValue *v = expr->evaluate(exec);
634   KJS_CHECKEXCEPTIONVALUE
635
636   if (!v->isObject()) {
637     return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr.get());
638   }
639   
640   JSObject *func = static_cast<JSObject*>(v);
641
642   if (!func->implementsCall()) {
643     return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr.get());
644   }
645
646   List argList = args->evaluateList(exec);
647   KJS_CHECKEXCEPTIONVALUE
648
649   JSObject *thisObj =  exec->dynamicInterpreter()->globalObject();
650
651   return func->call(exec, thisObj, argList);
652 }
653
654 // ECMA 11.2.3
655 JSValue *FunctionCallResolveNode::evaluate(ExecState *exec)
656 {
657   const ScopeChain& chain = exec->context()->scopeChain();
658   ScopeChainIterator iter = chain.begin();
659   ScopeChainIterator end = chain.end();
660   
661   // we must always have something in the scope chain
662   assert(iter != end);
663
664   PropertySlot slot;
665   JSObject *base;
666   do { 
667     base = *iter;
668     if (base->getPropertySlot(exec, ident, slot)) {
669       JSValue *v = slot.getValue(exec, base, ident);
670       KJS_CHECKEXCEPTIONVALUE
671         
672       if (!v->isObject()) {
673         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident);
674       }
675       
676       JSObject *func = static_cast<JSObject*>(v);
677       
678       if (!func->implementsCall()) {
679         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident);
680       }
681       
682       List argList = args->evaluateList(exec);
683       KJS_CHECKEXCEPTIONVALUE
684         
685       JSObject *thisObj = base;
686       // ECMA 11.2.3 says that in this situation the this value should be null.
687       // However, section 10.2.3 says that in the case where the value provided
688       // by the caller is null, the global object should be used. It also says
689       // that the section does not apply to interal functions, but for simplicity
690       // of implementation we use the global object anyway here. This guarantees
691       // that in host objects you always get a valid object for this.
692       if (thisObj->isActivation())
693         thisObj = exec->dynamicInterpreter()->globalObject();
694
695       return func->call(exec, thisObj, argList);
696     }
697     ++iter;
698   } while (iter != end);
699   
700   return throwUndefinedVariableError(exec, ident);
701 }
702
703 // ECMA 11.2.3
704 JSValue *FunctionCallBracketNode::evaluate(ExecState *exec)
705 {
706   JSValue *baseVal = base->evaluate(exec);
707   KJS_CHECKEXCEPTIONVALUE
708
709   JSValue *subscriptVal = subscript->evaluate(exec);
710
711   JSObject *baseObj = baseVal->toObject(exec);
712   uint32_t i;
713   PropertySlot slot;
714
715   JSValue *funcVal;
716   if (subscriptVal->getUInt32(i)) {
717     if (baseObj->getPropertySlot(exec, i, slot))
718       funcVal = slot.getValue(exec, baseObj, i);
719     else
720       funcVal = jsUndefined();
721   } else {
722     Identifier ident(subscriptVal->toString(exec));
723     if (baseObj->getPropertySlot(exec, ident, slot))
724       funcVal = baseObj->get(exec, ident);
725     else
726       funcVal = jsUndefined();
727   }
728
729   KJS_CHECKEXCEPTIONVALUE
730   
731   if (!funcVal->isObject()) {
732     return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, base.get(), subscript.get());
733   }
734   
735   JSObject *func = static_cast<JSObject*>(funcVal);
736
737   if (!func->implementsCall()) {
738     return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, base.get(), subscript.get());
739   }
740
741   List argList = args->evaluateList(exec);
742   KJS_CHECKEXCEPTIONVALUE
743
744   JSObject *thisObj = baseObj;
745   assert(thisObj);
746   assert(thisObj->isObject());
747   assert(!thisObj->isActivation());
748
749   return func->call(exec, thisObj, argList);
750 }
751
752 static const char *dotExprNotAnObjectString() KJS_FAST_CALL;
753 static const char *dotExprNotAnObjectString()
754 {
755   return "Value %s (result of expression %s.%s) is not object.";
756 }
757
758 static const char *dotExprDoesNotAllowCallsString() KJS_FAST_CALL;
759 static const char *dotExprDoesNotAllowCallsString()
760 {
761   return "Object %s (result of expression %s.%s) does not allow calls.";
762 }
763
764 // ECMA 11.2.3
765 JSValue *FunctionCallDotNode::evaluate(ExecState *exec)
766 {
767   JSValue *baseVal = base->evaluate(exec);
768   KJS_CHECKEXCEPTIONVALUE
769
770   JSObject *baseObj = baseVal->toObject(exec);
771   PropertySlot slot;
772   JSValue *funcVal = baseObj->getPropertySlot(exec, ident, slot) ? slot.getValue(exec, baseObj, ident) : jsUndefined();
773   KJS_CHECKEXCEPTIONVALUE
774
775   if (!funcVal->isObject())
776     return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, base.get(), ident);
777   
778   JSObject *func = static_cast<JSObject*>(funcVal);
779
780   if (!func->implementsCall())
781     return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, base.get(), ident);
782
783   List argList = args->evaluateList(exec);
784   KJS_CHECKEXCEPTIONVALUE
785
786   JSObject *thisObj = baseObj;
787   assert(thisObj);
788   assert(thisObj->isObject());
789   assert(!thisObj->isActivation());
790
791   return func->call(exec, thisObj, argList);
792 }
793
794 // ECMA 11.3
795
796 // ------------------------------ PostfixResolveNode ----------------------------------
797
798 JSValue *PostfixResolveNode::evaluate(ExecState *exec)
799 {
800   const ScopeChain& chain = exec->context()->scopeChain();
801   ScopeChainIterator iter = chain.begin();
802   ScopeChainIterator end = chain.end();
803   
804   // we must always have something in the scope chain
805   assert(iter != end);
806
807   PropertySlot slot;
808   JSObject *base;
809   do { 
810     base = *iter;
811     if (base->getPropertySlot(exec, m_ident, slot)) {
812         JSValue *v = slot.getValue(exec, base, m_ident);
813
814         double n = v->toNumber(exec);
815         
816         double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
817         base->put(exec, m_ident, jsNumber(newValue));
818         
819         return jsNumber(n);
820     }
821
822     ++iter;
823   } while (iter != end);
824
825   return throwUndefinedVariableError(exec, m_ident);
826 }
827
828 // ------------------------------ PostfixBracketNode ----------------------------------
829
830 JSValue *PostfixBracketNode::evaluate(ExecState *exec)
831 {
832   JSValue *baseValue = m_base->evaluate(exec);
833   KJS_CHECKEXCEPTIONVALUE
834   JSValue *subscript = m_subscript->evaluate(exec);
835   KJS_CHECKEXCEPTIONVALUE
836
837   JSObject *base = baseValue->toObject(exec);
838
839   uint32_t propertyIndex;
840   if (subscript->getUInt32(propertyIndex)) {
841     PropertySlot slot;
842     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
843     KJS_CHECKEXCEPTIONVALUE
844
845     double n = v->toNumber(exec);
846
847     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
848     base->put(exec, propertyIndex, jsNumber(newValue));
849         
850     return jsNumber(n);
851   }
852
853   Identifier propertyName(subscript->toString(exec));
854   PropertySlot slot;
855   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
856   KJS_CHECKEXCEPTIONVALUE
857
858   double n = v->toNumber(exec);
859   
860   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
861   base->put(exec, propertyName, jsNumber(newValue));
862         
863   return jsNumber(n);
864 }
865
866 // ------------------------------ PostfixDotNode ----------------------------------
867
868 JSValue *PostfixDotNode::evaluate(ExecState *exec)
869 {
870   JSValue *baseValue = m_base->evaluate(exec);
871   KJS_CHECKEXCEPTIONVALUE
872   JSObject *base = baseValue->toObject(exec);
873
874   PropertySlot slot;
875   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
876   KJS_CHECKEXCEPTIONVALUE
877
878   double n = v->toNumber(exec);
879   
880   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
881   base->put(exec, m_ident, jsNumber(newValue));
882         
883   return jsNumber(n);
884 }
885
886 // ------------------------------ PostfixErrorNode -----------------------------------
887
888 JSValue* PostfixErrorNode::evaluate(ExecState* exec)
889 {
890     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
891         m_oper == OpPlusPlus ? "++" : "--");
892     handleException(exec);
893     return jsUndefined();
894 }
895
896 // ------------------------------ DeleteResolveNode -----------------------------------
897
898 // ECMA 11.4.1
899
900 JSValue *DeleteResolveNode::evaluate(ExecState *exec)
901 {
902   const ScopeChain& chain = exec->context()->scopeChain();
903   ScopeChainIterator iter = chain.begin();
904   ScopeChainIterator end = chain.end();
905   
906   // we must always have something in the scope chain
907   assert(iter != end);
908
909   PropertySlot slot;
910   JSObject *base;
911   do { 
912     base = *iter;
913     if (base->getPropertySlot(exec, m_ident, slot)) {
914         return jsBoolean(base->deleteProperty(exec, m_ident));
915     }
916
917     ++iter;
918   } while (iter != end);
919
920   return jsBoolean(true);
921 }
922
923 // ------------------------------ DeleteBracketNode -----------------------------------
924
925 JSValue *DeleteBracketNode::evaluate(ExecState *exec)
926 {
927   JSValue *baseValue = m_base->evaluate(exec);
928   KJS_CHECKEXCEPTIONVALUE
929   JSValue *subscript = m_subscript->evaluate(exec);
930   KJS_CHECKEXCEPTIONVALUE
931
932   JSObject *base = baseValue->toObject(exec);
933
934   uint32_t propertyIndex;
935   if (subscript->getUInt32(propertyIndex))
936       return jsBoolean(base->deleteProperty(exec, propertyIndex));
937
938   Identifier propertyName(subscript->toString(exec));
939   return jsBoolean(base->deleteProperty(exec, propertyName));
940 }
941
942 // ------------------------------ DeleteDotNode -----------------------------------
943 JSValue *DeleteDotNode::evaluate(ExecState *exec)
944 {
945   JSValue *baseValue = m_base->evaluate(exec);
946   JSObject *base = baseValue->toObject(exec);
947   KJS_CHECKEXCEPTIONVALUE
948
949   return jsBoolean(base->deleteProperty(exec, m_ident));
950 }
951
952 // ------------------------------ DeleteValueNode -----------------------------------
953 JSValue *DeleteValueNode::evaluate(ExecState *exec)
954 {
955   m_expr->evaluate(exec);
956   KJS_CHECKEXCEPTIONVALUE
957
958   // delete on a non-location expression ignores the value and returns true
959   return jsBoolean(true);
960 }
961
962 // ------------------------------ VoidNode -------------------------------------
963
964 // ECMA 11.4.2
965 JSValue *VoidNode::evaluate(ExecState *exec)
966 {
967   expr->evaluate(exec);
968   KJS_CHECKEXCEPTIONVALUE
969
970   return jsUndefined();
971 }
972
973 // ECMA 11.4.3
974
975 // ------------------------------ TypeOfValueNode -----------------------------------
976
977 static JSValue *typeStringForValue(JSValue *v) KJS_FAST_CALL;
978 static JSValue *typeStringForValue(JSValue *v)
979 {
980     switch (v->type()) {
981     case UndefinedType:
982         return jsString("undefined");
983     case NullType:
984         return jsString("object");
985     case BooleanType:
986         return jsString("boolean");
987     case NumberType:
988         return jsString("number");
989     case StringType:
990         return jsString("string");
991     default:
992         if (v->isObject()) {
993             // Return "undefined" for objects that should be treated
994             // as null when doing comparisons.
995             if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
996                 return jsString("undefined");            
997             else if (static_cast<JSObject*>(v)->implementsCall())
998                 return jsString("function");
999         }
1000         
1001         return jsString("object");
1002     }
1003 }
1004
1005 JSValue *TypeOfResolveNode::evaluate(ExecState *exec)
1006 {
1007   const ScopeChain& chain = exec->context()->scopeChain();
1008   ScopeChainIterator iter = chain.begin();
1009   ScopeChainIterator end = chain.end();
1010   
1011   // we must always have something in the scope chain
1012   assert(iter != end);
1013
1014   PropertySlot slot;
1015   JSObject *base;
1016   do { 
1017     base = *iter;
1018     if (base->getPropertySlot(exec, m_ident, slot)) {
1019         JSValue *v = slot.getValue(exec, base, m_ident);
1020         return typeStringForValue(v);
1021     }
1022
1023     ++iter;
1024   } while (iter != end);
1025
1026   return jsString("undefined");
1027 }
1028
1029 // ------------------------------ TypeOfValueNode -----------------------------------
1030
1031 JSValue *TypeOfValueNode::evaluate(ExecState *exec)
1032 {
1033   JSValue *v = m_expr->evaluate(exec);
1034   KJS_CHECKEXCEPTIONVALUE
1035
1036   return typeStringForValue(v);
1037 }
1038
1039 // ECMA 11.4.4 and 11.4.5
1040
1041 // ------------------------------ PrefixResolveNode ----------------------------------
1042
1043 JSValue *PrefixResolveNode::evaluate(ExecState *exec)
1044 {
1045   const ScopeChain& chain = exec->context()->scopeChain();
1046   ScopeChainIterator iter = chain.begin();
1047   ScopeChainIterator end = chain.end();
1048   
1049   // we must always have something in the scope chain
1050   assert(iter != end);
1051
1052   PropertySlot slot;
1053   JSObject *base;
1054   do { 
1055     base = *iter;
1056     if (base->getPropertySlot(exec, m_ident, slot)) {
1057         JSValue *v = slot.getValue(exec, base, m_ident);
1058
1059         double n = v->toNumber(exec);
1060         
1061         double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
1062         JSValue *n2 = jsNumber(newValue);
1063         base->put(exec, m_ident, n2);
1064
1065         return n2;
1066     }
1067
1068     ++iter;
1069   } while (iter != end);
1070
1071   return throwUndefinedVariableError(exec, m_ident);
1072 }
1073
1074 // ------------------------------ PrefixBracketNode ----------------------------------
1075
1076 JSValue *PrefixBracketNode::evaluate(ExecState *exec)
1077 {
1078   JSValue *baseValue = m_base->evaluate(exec);
1079   KJS_CHECKEXCEPTIONVALUE
1080   JSValue *subscript = m_subscript->evaluate(exec);
1081   KJS_CHECKEXCEPTIONVALUE
1082
1083   JSObject *base = baseValue->toObject(exec);
1084
1085   uint32_t propertyIndex;
1086   if (subscript->getUInt32(propertyIndex)) {
1087     PropertySlot slot;
1088     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1089     KJS_CHECKEXCEPTIONVALUE
1090
1091     double n = v->toNumber(exec);
1092
1093     double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
1094     JSValue *n2 = jsNumber(newValue);
1095     base->put(exec, propertyIndex, n2);
1096
1097     return n2;
1098   }
1099
1100   Identifier propertyName(subscript->toString(exec));
1101   PropertySlot slot;
1102   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1103   KJS_CHECKEXCEPTIONVALUE
1104
1105   double n = v->toNumber(exec);
1106   
1107   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
1108   JSValue *n2 = jsNumber(newValue);
1109   base->put(exec, propertyName, n2);
1110
1111   return n2;
1112 }
1113
1114 // ------------------------------ PrefixDotNode ----------------------------------
1115
1116 JSValue *PrefixDotNode::evaluate(ExecState *exec)
1117 {
1118   JSValue *baseValue = m_base->evaluate(exec);
1119   KJS_CHECKEXCEPTIONVALUE
1120   JSObject *base = baseValue->toObject(exec);
1121
1122   PropertySlot slot;
1123   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1124   KJS_CHECKEXCEPTIONVALUE
1125
1126   double n = v->toNumber(exec);
1127   
1128   double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1;
1129   JSValue *n2 = jsNumber(newValue);
1130   base->put(exec, m_ident, n2);
1131
1132   return n2;
1133 }
1134
1135 // ------------------------------ PrefixErrorNode -----------------------------------
1136
1137 JSValue* PrefixErrorNode::evaluate(ExecState* exec)
1138 {
1139     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
1140         m_oper == OpPlusPlus ? "++" : "--");
1141     handleException(exec);
1142     return jsUndefined();
1143 }
1144
1145 // ------------------------------ UnaryPlusNode --------------------------------
1146
1147 // ECMA 11.4.6
1148 JSValue *UnaryPlusNode::evaluate(ExecState *exec)
1149 {
1150   JSValue *v = expr->evaluate(exec);
1151   KJS_CHECKEXCEPTIONVALUE
1152
1153   return jsNumber(v->toNumber(exec));
1154 }
1155
1156 // ------------------------------ NegateNode -----------------------------------
1157
1158 // ECMA 11.4.7
1159 JSValue *NegateNode::evaluate(ExecState *exec)
1160 {
1161   JSValue *v = expr->evaluate(exec);
1162   KJS_CHECKEXCEPTIONVALUE
1163
1164   double n = v->toNumber(exec);
1165   return jsNumber(-n);
1166 }
1167
1168 // ------------------------------ BitwiseNotNode -------------------------------
1169
1170 // ECMA 11.4.8
1171 JSValue *BitwiseNotNode::evaluate(ExecState *exec)
1172 {
1173   JSValue *v = expr->evaluate(exec);
1174   KJS_CHECKEXCEPTIONVALUE
1175   return jsNumber(~v->toInt32(exec));
1176 }
1177
1178 // ------------------------------ LogicalNotNode -------------------------------
1179
1180 // ECMA 11.4.9
1181 JSValue *LogicalNotNode::evaluate(ExecState *exec)
1182 {
1183   JSValue *v = expr->evaluate(exec);
1184   KJS_CHECKEXCEPTIONVALUE
1185   return jsBoolean(!v->toBoolean(exec));
1186 }
1187
1188 // ------------------------------ MultNode -------------------------------------
1189
1190 // ECMA 11.5
1191 JSValue *MultNode::evaluate(ExecState *exec)
1192 {
1193   JSValue *v1 = term1->evaluate(exec);
1194   KJS_CHECKEXCEPTIONVALUE
1195
1196   JSValue *v2 = term2->evaluate(exec);
1197   KJS_CHECKEXCEPTIONVALUE
1198
1199   return mult(exec, v1, v2, oper);
1200 }
1201
1202 // ------------------------------ AddNode --------------------------------------
1203
1204 // ECMA 11.6
1205 JSValue *AddNode::evaluate(ExecState *exec)
1206 {
1207   JSValue *v1 = term1->evaluate(exec);
1208   KJS_CHECKEXCEPTIONVALUE
1209
1210   JSValue *v2 = term2->evaluate(exec);
1211   KJS_CHECKEXCEPTIONVALUE
1212
1213   return add(exec, v1, v2, oper);
1214 }
1215
1216 // ------------------------------ ShiftNode ------------------------------------
1217
1218 // ECMA 11.7
1219 JSValue *ShiftNode::evaluate(ExecState *exec)
1220 {
1221   JSValue *v1 = term1->evaluate(exec);
1222   KJS_CHECKEXCEPTIONVALUE
1223   JSValue *v2 = term2->evaluate(exec);
1224   KJS_CHECKEXCEPTIONVALUE
1225   unsigned int i2 = v2->toUInt32(exec);
1226   i2 &= 0x1f;
1227
1228   switch (oper) {
1229   case OpLShift:
1230     return jsNumber(v1->toInt32(exec) << i2);
1231   case OpRShift:
1232     return jsNumber(v1->toInt32(exec) >> i2);
1233   case OpURShift:
1234     return jsNumber(v1->toUInt32(exec) >> i2);
1235   default:
1236     assert(!"ShiftNode: unhandled switch case");
1237     return jsUndefined();
1238   }
1239 }
1240
1241 // ------------------------------ RelationalNode -------------------------------
1242
1243 // ECMA 11.8
1244 JSValue *RelationalNode::evaluate(ExecState *exec)
1245 {
1246   JSValue *v1 = expr1->evaluate(exec);
1247   KJS_CHECKEXCEPTIONVALUE
1248   JSValue *v2 = expr2->evaluate(exec);
1249   KJS_CHECKEXCEPTIONVALUE
1250
1251   bool b;
1252   if (oper == OpLess || oper == OpGreaterEq) {
1253     int r = relation(exec, v1, v2);
1254     if (r < 0)
1255       b = false;
1256     else
1257       b = (oper == OpLess) ? (r == 1) : (r == 0);
1258   } else if (oper == OpGreater || oper == OpLessEq) {
1259     int r = relation(exec, v2, v1);
1260     if (r < 0)
1261       b = false;
1262     else
1263       b = (oper == OpGreater) ? (r == 1) : (r == 0);
1264   } else if (oper == OpIn) {
1265       // Is all of this OK for host objects?
1266       if (!v2->isObject())
1267           return throwError(exec,  TypeError,
1268                              "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2.get());
1269       JSObject *o2(static_cast<JSObject*>(v2));
1270       b = o2->hasProperty(exec, Identifier(v1->toString(exec)));
1271   } else {
1272     if (!v2->isObject())
1273         return throwError(exec,  TypeError,
1274                            "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
1275
1276     JSObject *o2(static_cast<JSObject*>(v2));
1277     if (!o2->implementsHasInstance())
1278       // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
1279       // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
1280       // property. It seems that all object have the property, but not all implement it, so in this
1281       // case we return false (consistent with mozilla)
1282       return jsBoolean(false);
1283     return jsBoolean(o2->hasInstance(exec, v1));
1284   }
1285
1286   return jsBoolean(b);
1287 }
1288
1289 // ------------------------------ EqualNode ------------------------------------
1290
1291 // ECMA 11.9
1292 JSValue *EqualNode::evaluate(ExecState *exec)
1293 {
1294   JSValue *v1 = expr1->evaluate(exec);
1295   KJS_CHECKEXCEPTIONVALUE
1296   JSValue *v2 = expr2->evaluate(exec);
1297   KJS_CHECKEXCEPTIONVALUE
1298
1299   bool result;
1300   if (oper == OpEqEq || oper == OpNotEq) {
1301     // == and !=
1302     bool eq = equal(exec,v1, v2);
1303     result = oper == OpEqEq ? eq : !eq;
1304   } else {
1305     // === and !==
1306     bool eq = strictEqual(exec,v1, v2);
1307     result = oper == OpStrEq ? eq : !eq;
1308   }
1309   return jsBoolean(result);
1310 }
1311
1312 // ------------------------------ BitOperNode ----------------------------------
1313
1314 // ECMA 11.10
1315 JSValue *BitOperNode::evaluate(ExecState *exec)
1316 {
1317   JSValue *v1 = expr1->evaluate(exec);
1318   KJS_CHECKEXCEPTIONVALUE
1319   JSValue *v2 = expr2->evaluate(exec);
1320   KJS_CHECKEXCEPTIONVALUE
1321   int i1 = v1->toInt32(exec);
1322   int i2 = v2->toInt32(exec);
1323   int result;
1324   if (oper == OpBitAnd)
1325     result = i1 & i2;
1326   else if (oper == OpBitXOr)
1327     result = i1 ^ i2;
1328   else
1329     result = i1 | i2;
1330
1331   return jsNumber(result);
1332 }
1333
1334 // ------------------------------ BinaryLogicalNode ----------------------------
1335
1336 // ECMA 11.11
1337 JSValue *BinaryLogicalNode::evaluate(ExecState *exec)
1338 {
1339   JSValue *v1 = expr1->evaluate(exec);
1340   KJS_CHECKEXCEPTIONVALUE
1341   bool b1 = v1->toBoolean(exec);
1342   if ((!b1 && oper == OpAnd) || (b1 && oper == OpOr))
1343     return v1;
1344
1345   JSValue *v2 = expr2->evaluate(exec);
1346   KJS_CHECKEXCEPTIONVALUE
1347
1348   return v2;
1349 }
1350
1351 // ------------------------------ ConditionalNode ------------------------------
1352
1353 // ECMA 11.12
1354 JSValue *ConditionalNode::evaluate(ExecState *exec)
1355 {
1356   JSValue *v = logical->evaluate(exec);
1357   KJS_CHECKEXCEPTIONVALUE
1358   bool b = v->toBoolean(exec);
1359
1360   if (b)
1361     v = expr1->evaluate(exec);
1362   else
1363     v = expr2->evaluate(exec);
1364   KJS_CHECKEXCEPTIONVALUE
1365
1366   return v;
1367 }
1368
1369 // ECMA 11.13
1370
1371 static ALWAYS_INLINE JSValue *valueForReadModifyAssignment(ExecState * exec, JSValue *v1, JSValue *v2, Operator oper) KJS_FAST_CALL;
1372 static ALWAYS_INLINE JSValue *valueForReadModifyAssignment(ExecState * exec, JSValue *v1, JSValue *v2, Operator oper)
1373 {
1374   JSValue *v;
1375   int i1;
1376   int i2;
1377   unsigned int ui;
1378   switch (oper) {
1379   case OpMultEq:
1380     v = mult(exec, v1, v2, '*');
1381     break;
1382   case OpDivEq:
1383     v = mult(exec, v1, v2, '/');
1384     break;
1385   case OpPlusEq:
1386     v = add(exec, v1, v2, '+');
1387     break;
1388   case OpMinusEq:
1389     v = add(exec, v1, v2, '-');
1390     break;
1391   case OpLShift:
1392     i1 = v1->toInt32(exec);
1393     i2 = v2->toInt32(exec);
1394     v = jsNumber(i1 << i2);
1395     break;
1396   case OpRShift:
1397     i1 = v1->toInt32(exec);
1398     i2 = v2->toInt32(exec);
1399     v = jsNumber(i1 >> i2);
1400     break;
1401   case OpURShift:
1402     ui = v1->toUInt32(exec);
1403     i2 = v2->toInt32(exec);
1404     v = jsNumber(ui >> i2);
1405     break;
1406   case OpAndEq:
1407     i1 = v1->toInt32(exec);
1408     i2 = v2->toInt32(exec);
1409     v = jsNumber(i1 & i2);
1410     break;
1411   case OpXOrEq:
1412     i1 = v1->toInt32(exec);
1413     i2 = v2->toInt32(exec);
1414     v = jsNumber(i1 ^ i2);
1415     break;
1416   case OpOrEq:
1417     i1 = v1->toInt32(exec);
1418     i2 = v2->toInt32(exec);
1419     v = jsNumber(i1 | i2);
1420     break;
1421   case OpModEq: {
1422     double d1 = v1->toNumber(exec);
1423     double d2 = v2->toNumber(exec);
1424     v = jsNumber(fmod(d1, d2));
1425   }
1426     break;
1427   default:
1428     assert(0);
1429     v = jsUndefined();
1430   }
1431   
1432   return v;
1433 }
1434
1435 // ------------------------------ AssignResolveNode -----------------------------------
1436
1437 JSValue *AssignResolveNode::evaluate(ExecState *exec)
1438 {
1439   const ScopeChain& chain = exec->context()->scopeChain();
1440   ScopeChainIterator iter = chain.begin();
1441   ScopeChainIterator end = chain.end();
1442   
1443   // we must always have something in the scope chain
1444   assert(iter != end);
1445
1446   PropertySlot slot;
1447   JSObject *base;
1448   do { 
1449     base = *iter;
1450     if (base->getPropertySlot(exec, m_ident, slot))
1451       goto found;
1452
1453     ++iter;
1454   } while (iter != end);
1455
1456   if (m_oper != OpEqual)
1457     return throwUndefinedVariableError(exec, m_ident);
1458
1459  found:
1460   JSValue *v;
1461
1462   if (m_oper == OpEqual) {
1463     v = m_right->evaluate(exec);
1464   } else {
1465     JSValue *v1 = slot.getValue(exec, base, m_ident);
1466     KJS_CHECKEXCEPTIONVALUE
1467     JSValue *v2 = m_right->evaluate(exec);
1468     v = valueForReadModifyAssignment(exec, v1, v2, m_oper);
1469   }
1470
1471   KJS_CHECKEXCEPTIONVALUE
1472
1473   base->put(exec, m_ident, v);
1474   return v;
1475 }
1476
1477 // ------------------------------ AssignDotNode -----------------------------------
1478
1479 JSValue *AssignDotNode::evaluate(ExecState *exec)
1480 {
1481   JSValue *baseValue = m_base->evaluate(exec);
1482   KJS_CHECKEXCEPTIONVALUE
1483   JSObject *base = baseValue->toObject(exec);
1484
1485   JSValue *v;
1486
1487   if (m_oper == OpEqual) {
1488     v = m_right->evaluate(exec);
1489   } else {
1490     PropertySlot slot;
1491     JSValue *v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1492     KJS_CHECKEXCEPTIONVALUE
1493     JSValue *v2 = m_right->evaluate(exec);
1494     v = valueForReadModifyAssignment(exec, v1, v2, m_oper);
1495   }
1496
1497   KJS_CHECKEXCEPTIONVALUE
1498
1499   base->put(exec, m_ident, v);
1500   return v;
1501 }
1502
1503 // ------------------------------ AssignErrorNode -----------------------------------
1504
1505 JSValue* AssignErrorNode::evaluate(ExecState* exec)
1506 {
1507     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
1508     handleException(exec);
1509     return jsUndefined();
1510 }
1511
1512 // ------------------------------ AssignBracketNode -----------------------------------
1513
1514 JSValue *AssignBracketNode::evaluate(ExecState *exec)
1515 {
1516   JSValue *baseValue = m_base->evaluate(exec);
1517   KJS_CHECKEXCEPTIONVALUE
1518   JSValue *subscript = m_subscript->evaluate(exec);
1519   KJS_CHECKEXCEPTIONVALUE
1520
1521   JSObject *base = baseValue->toObject(exec);
1522
1523   uint32_t propertyIndex;
1524   if (subscript->getUInt32(propertyIndex)) {
1525     JSValue *v;
1526     if (m_oper == OpEqual) {
1527       v = m_right->evaluate(exec);
1528     } else {
1529       PropertySlot slot;
1530       JSValue *v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1531       KJS_CHECKEXCEPTIONVALUE
1532       JSValue *v2 = m_right->evaluate(exec);
1533       v = valueForReadModifyAssignment(exec, v1, v2, m_oper);
1534     }
1535
1536     KJS_CHECKEXCEPTIONVALUE
1537
1538     base->put(exec, propertyIndex, v);
1539     return v;
1540   }
1541
1542   Identifier propertyName(subscript->toString(exec));
1543   JSValue *v;
1544
1545   if (m_oper == OpEqual) {
1546     v = m_right->evaluate(exec);
1547   } else {
1548     PropertySlot slot;
1549     JSValue *v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1550     KJS_CHECKEXCEPTIONVALUE
1551     JSValue *v2 = m_right->evaluate(exec);
1552     v = valueForReadModifyAssignment(exec, v1, v2, m_oper);
1553   }
1554
1555   KJS_CHECKEXCEPTIONVALUE
1556
1557   base->put(exec, propertyName, v);
1558   return v;
1559 }
1560
1561 // ------------------------------ CommaNode ------------------------------------
1562
1563 // ECMA 11.14
1564 JSValue *CommaNode::evaluate(ExecState *exec)
1565 {
1566   expr1->evaluate(exec);
1567   KJS_CHECKEXCEPTIONVALUE
1568   JSValue *v = expr2->evaluate(exec);
1569   KJS_CHECKEXCEPTIONVALUE
1570
1571   return v;
1572 }
1573
1574 // ------------------------------ AssignExprNode -------------------------------
1575
1576 // ECMA 12.2
1577 JSValue *AssignExprNode::evaluate(ExecState *exec)
1578 {
1579   return expr->evaluate(exec);
1580 }
1581
1582 // ------------------------------ VarDeclNode ----------------------------------
1583
1584     
1585 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t)
1586     : varType(t), ident(id), init(in)
1587 {
1588 }
1589
1590 JSValue* VarDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
1591 {
1592     ScopeChainIterator iter = chain.begin();
1593     ScopeChainIterator end = chain.end();        
1594     
1595     // we must always have something in the scope chain
1596     ASSERT(iter != end);
1597     
1598     PropertySlot slot;
1599     JSObject* base;
1600     
1601     do {
1602         base = *iter;
1603         if (base->getPropertySlot(exec, ident, slot))
1604             break;
1605         
1606         ++iter;
1607     } while (iter != end);
1608     
1609     unsigned flags = 0;
1610     base->getPropertyAttributes(ident, flags);
1611     if (varType == VarDeclNode::Constant)
1612         flags |= ReadOnly;
1613     
1614     base->put(exec, ident, val, flags);
1615     return 0;
1616 }
1617
1618 // ECMA 12.2
1619 JSValue* VarDeclNode::evaluate(ExecState* exec)
1620 {
1621     const ScopeChain& chain = exec->context()->scopeChain();
1622     JSObject* variableObject = exec->context()->variableObject();
1623
1624     ASSERT(!chain.isEmpty());
1625
1626     bool inGlobalScope = ++chain.begin() == chain.end();
1627
1628     if (inGlobalScope && (init || !variableObject->getDirect(ident))) {
1629         JSValue* val = init ? init->evaluate(exec) : jsUndefined();
1630         int flags = Internal;
1631         if (exec->context()->codeType() != EvalCode)
1632             flags |= DontDelete;
1633         if (varType == VarDeclNode::Constant)
1634             flags |= ReadOnly;
1635         variableObject->putDirect(ident, val, flags);
1636     } else if (init) {
1637         JSValue* val = init->evaluate(exec);
1638         KJS_CHECKEXCEPTIONVALUE
1639             
1640         // if the variable object is the top of the scope chain, then that must
1641         // be where this variable is declared, processVarDecls would have put 
1642         // it there. Don't search the scope chain, to optimize this very common case.
1643         if (chain.top() != variableObject)
1644             return handleSlowCase(exec, chain, val);
1645
1646         unsigned flags = 0;
1647         variableObject->getPropertyAttributes(ident, flags);
1648         if (varType == VarDeclNode::Constant)
1649             flags |= ReadOnly;
1650         
1651         ASSERT(variableObject->getDirect(ident) || ident == exec->propertyNames().arguments);
1652         variableObject->put(exec, ident, val, flags);
1653     }
1654
1655     // no caller of this function actually uses the return value. 
1656     // FIXME: It would be better to change the inheritence hierarchy so this
1657     // node doesn't even have an evaluate method, but instead a differently named
1658     // one with a void return.
1659     return 0;
1660 }
1661
1662 void VarDeclNode::processVarDecls(ExecState *exec)
1663 {
1664   JSObject* variable = exec->context()->variableObject();
1665
1666   // If a variable by this name already exists, don't clobber it -
1667   // it might be a function parameter
1668   if (!variable->hasProperty(exec, ident)) {
1669     int flags = Internal;
1670     if (exec->context()->codeType() != EvalCode)
1671       flags |= DontDelete;
1672     if (varType == VarDeclNode::Constant)
1673       flags |= ReadOnly;
1674     variable->put(exec, ident, jsUndefined(), flags);
1675   }
1676 }
1677
1678 // ------------------------------ VarDeclListNode ------------------------------
1679
1680 // ECMA 12.2
1681 JSValue *VarDeclListNode::evaluate(ExecState *exec)
1682 {
1683   for (VarDeclListNode *n = this; n; n = n->next.get()) {
1684     n->var->evaluate(exec);
1685     KJS_CHECKEXCEPTIONVALUE
1686   }
1687   return jsUndefined();
1688 }
1689
1690 void VarDeclListNode::processVarDecls(ExecState *exec)
1691 {
1692   for (VarDeclListNode *n = this; n; n = n->next.get())
1693     n->var->processVarDecls(exec);
1694 }
1695
1696 void VarDeclListNode::breakCycle() 
1697
1698     next = 0;
1699 }
1700
1701 // ------------------------------ VarStatementNode -----------------------------
1702
1703 // ECMA 12.2
1704 Completion VarStatementNode::execute(ExecState *exec)
1705 {
1706   KJS_BREAKPOINT;
1707
1708   (void) next->evaluate(exec);
1709   KJS_CHECKEXCEPTION
1710
1711   return Completion(Normal);
1712 }
1713
1714 void VarStatementNode::processVarDecls(ExecState *exec)
1715 {
1716   next->processVarDecls(exec);
1717 }
1718
1719 // ------------------------------ BlockNode ------------------------------------
1720
1721 BlockNode::BlockNode(SourceElementsNode *s)
1722 {
1723   if (s) {
1724     source = s->next.release();
1725     Parser::removeNodeCycle(source.get());
1726     setLoc(s->firstLine(), s->lastLine());
1727   } else {
1728     source = 0;
1729   }
1730 }
1731
1732 // ECMA 12.1
1733 Completion BlockNode::execute(ExecState *exec)
1734 {
1735   if (!source)
1736     return Completion(Normal);
1737
1738   source->processFuncDecl(exec);
1739
1740   return source->execute(exec);
1741 }
1742
1743 void BlockNode::processVarDecls(ExecState *exec)
1744 {
1745   if (source)
1746     source->processVarDecls(exec);
1747 }
1748
1749 // ------------------------------ EmptyStatementNode ---------------------------
1750
1751 // ECMA 12.3
1752 Completion EmptyStatementNode::execute(ExecState *)
1753 {
1754   return Completion(Normal);
1755 }
1756
1757 // ------------------------------ ExprStatementNode ----------------------------
1758
1759 // ECMA 12.4
1760 Completion ExprStatementNode::execute(ExecState *exec)
1761 {
1762   KJS_BREAKPOINT;
1763
1764   JSValue *v = expr->evaluate(exec);
1765   KJS_CHECKEXCEPTION
1766
1767   return Completion(Normal, v);
1768 }
1769
1770 // ------------------------------ IfNode ---------------------------------------
1771
1772 // ECMA 12.5
1773 Completion IfNode::execute(ExecState *exec)
1774 {
1775   KJS_BREAKPOINT;
1776
1777   JSValue *v = expr->evaluate(exec);
1778   KJS_CHECKEXCEPTION
1779   bool b = v->toBoolean(exec);
1780
1781   // if ... then
1782   if (b)
1783     return statement1->execute(exec);
1784
1785   // no else
1786   if (!statement2)
1787     return Completion(Normal);
1788
1789   // else
1790   return statement2->execute(exec);
1791 }
1792
1793 void IfNode::processVarDecls(ExecState *exec)
1794 {
1795   statement1->processVarDecls(exec);
1796
1797   if (statement2)
1798     statement2->processVarDecls(exec);
1799 }
1800
1801 // ------------------------------ DoWhileNode ----------------------------------
1802
1803 // ECMA 12.6.1
1804 Completion DoWhileNode::execute(ExecState *exec)
1805 {
1806   KJS_BREAKPOINT;
1807
1808   JSValue *bv;
1809   Completion c;
1810
1811   do {
1812     // bail out on error
1813     KJS_CHECKEXCEPTION
1814
1815     exec->context()->pushIteration();
1816     c = statement->execute(exec);
1817     exec->context()->popIteration();
1818     
1819     if (exec->dynamicInterpreter()->timedOut())
1820         return Completion(Interrupted);
1821
1822     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
1823       if ((c.complType() == Break) && ls.contains(c.target()))
1824         return Completion(Normal, 0);
1825       if (c.complType() != Normal)
1826         return c;
1827     }
1828     bv = expr->evaluate(exec);
1829     KJS_CHECKEXCEPTION
1830   } while (bv->toBoolean(exec));
1831
1832   return Completion(Normal, 0);
1833 }
1834
1835 void DoWhileNode::processVarDecls(ExecState *exec)
1836 {
1837   statement->processVarDecls(exec);
1838 }
1839
1840 // ------------------------------ WhileNode ------------------------------------
1841
1842 // ECMA 12.6.2
1843 Completion WhileNode::execute(ExecState *exec)
1844 {
1845   KJS_BREAKPOINT;
1846
1847   JSValue *bv;
1848   Completion c;
1849   bool b(false);
1850   JSValue *value = 0;
1851
1852   while (1) {
1853     bv = expr->evaluate(exec);
1854     KJS_CHECKEXCEPTION
1855     b = bv->toBoolean(exec);
1856
1857     // bail out on error
1858     KJS_CHECKEXCEPTION
1859
1860     if (!b)
1861       return Completion(Normal, value);
1862
1863     exec->context()->pushIteration();
1864     c = statement->execute(exec);
1865     exec->context()->popIteration();
1866
1867     if (exec->dynamicInterpreter()->timedOut())
1868         return Completion(Interrupted);
1869     
1870     if (c.isValueCompletion())
1871       value = c.value();
1872
1873     if ((c.complType() == Continue) && ls.contains(c.target()))
1874       continue;
1875     if ((c.complType() == Break) && ls.contains(c.target()))
1876       return Completion(Normal, value);
1877     if (c.complType() != Normal)
1878       return c;
1879   }
1880
1881   return Completion(); // work around gcc 4.0 bug
1882 }
1883
1884 void WhileNode::processVarDecls(ExecState *exec)
1885 {
1886   statement->processVarDecls(exec);
1887 }
1888
1889 // ------------------------------ ForNode --------------------------------------
1890
1891 // ECMA 12.6.3
1892 Completion ForNode::execute(ExecState *exec)
1893 {
1894   JSValue *v, *cval = 0;
1895
1896   if (expr1) {
1897     v = expr1->evaluate(exec);
1898     KJS_CHECKEXCEPTION
1899   }
1900   while (1) {
1901     if (expr2) {
1902       v = expr2->evaluate(exec);
1903       KJS_CHECKEXCEPTION
1904       if (!v->toBoolean(exec))
1905         return Completion(Normal, cval);
1906     }
1907     // bail out on error
1908     KJS_CHECKEXCEPTION
1909
1910     exec->context()->pushIteration();
1911     Completion c = statement->execute(exec);
1912     exec->context()->popIteration();
1913     if (c.isValueCompletion())
1914       cval = c.value();
1915     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
1916       if ((c.complType() == Break) && ls.contains(c.target()))
1917         return Completion(Normal, cval);
1918       if (c.complType() != Normal)
1919       return c;
1920     }
1921     
1922     if (exec->dynamicInterpreter()->timedOut())
1923         return Completion(Interrupted);
1924     
1925     if (expr3) {
1926       v = expr3->evaluate(exec);
1927       KJS_CHECKEXCEPTION
1928     }
1929   }
1930   
1931   return Completion(); // work around gcc 4.0 bug
1932 }
1933
1934 void ForNode::processVarDecls(ExecState *exec)
1935 {
1936   if (expr1)
1937     expr1->processVarDecls(exec);
1938
1939   statement->processVarDecls(exec);
1940 }
1941
1942 // ------------------------------ ForInNode ------------------------------------
1943
1944 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
1945   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
1946 {
1947 }
1948
1949 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
1950   : ident(i), init(in), expr(e), statement(s)
1951 {
1952   // for( var foo = bar in baz )
1953   varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
1954   lexpr = new ResolveNode(ident);
1955 }
1956
1957 // ECMA 12.6.4
1958 Completion ForInNode::execute(ExecState *exec)
1959 {
1960   JSValue *e;
1961   JSValue *retval = 0;
1962   JSObject *v;
1963   Completion c;
1964   PropertyNameArray propertyNames;
1965
1966   if (varDecl) {
1967     varDecl->evaluate(exec);
1968     KJS_CHECKEXCEPTION
1969   }
1970
1971   e = expr->evaluate(exec);
1972
1973   // for Null and Undefined, we want to make sure not to go through
1974   // the loop at all, because their object wrappers will have a
1975   // property list but will throw an exception if you attempt to
1976   // access any property.
1977   if (e->isUndefinedOrNull()) {
1978     return Completion(Normal, 0);
1979   }
1980
1981   KJS_CHECKEXCEPTION
1982   v = e->toObject(exec);
1983   v->getPropertyNames(exec, propertyNames);
1984   
1985   PropertyNameArrayIterator end = propertyNames.end();
1986   for (PropertyNameArrayIterator it = propertyNames.begin(); it != end; ++it) {
1987       const Identifier &name = *it;
1988       if (!v->hasProperty(exec, name))
1989           continue;
1990
1991       JSValue *str = jsString(name.ustring());
1992
1993       if (lexpr->isResolveNode()) {
1994         const Identifier &ident = static_cast<ResolveNode *>(lexpr.get())->identifier();
1995
1996         const ScopeChain& chain = exec->context()->scopeChain();
1997         ScopeChainIterator iter = chain.begin();
1998         ScopeChainIterator end = chain.end();
1999   
2000         // we must always have something in the scope chain
2001         assert(iter != end);
2002
2003         PropertySlot slot;
2004         JSObject *o;
2005         do { 
2006             o = *iter;
2007             if (o->getPropertySlot(exec, ident, slot)) {
2008                 o->put(exec, ident, str);
2009                 break;
2010             }
2011             ++iter;
2012         } while (iter != end);
2013         
2014         if (iter == end)
2015             o->put(exec, ident, str);
2016     } else if (lexpr->isDotAccessorNode()) {
2017         const Identifier& ident = static_cast<DotAccessorNode *>(lexpr.get())->identifier();
2018         JSValue *v = static_cast<DotAccessorNode *>(lexpr.get())->base()->evaluate(exec);
2019         KJS_CHECKEXCEPTION
2020         JSObject *o = v->toObject(exec);
2021
2022         o->put(exec, ident, str);
2023     } else {
2024         assert(lexpr->isBracketAccessorNode());
2025         JSValue *v = static_cast<BracketAccessorNode *>(lexpr.get())->base()->evaluate(exec);
2026         KJS_CHECKEXCEPTION
2027         JSValue *v2 = static_cast<BracketAccessorNode *>(lexpr.get())->subscript()->evaluate(exec);
2028         KJS_CHECKEXCEPTION
2029         JSObject *o = v->toObject(exec);
2030
2031         uint32_t i;
2032         if (v2->getUInt32(i))
2033             o->put(exec, i, str);
2034         o->put(exec, Identifier(v2->toString(exec)), str);
2035     }
2036
2037     KJS_CHECKEXCEPTION
2038
2039     exec->context()->pushIteration();
2040     c = statement->execute(exec);
2041     exec->context()->popIteration();
2042     if (c.isValueCompletion())
2043       retval = c.value();
2044
2045     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2046       if ((c.complType() == Break) && ls.contains(c.target()))
2047         break;
2048       if (c.complType() != Normal) {
2049         return c;
2050       }
2051     }
2052   }
2053
2054   // bail out on error
2055   KJS_CHECKEXCEPTION
2056
2057   return Completion(Normal, retval);
2058 }
2059
2060 void ForInNode::processVarDecls(ExecState *exec)
2061 {
2062   if (varDecl)
2063     varDecl->processVarDecls(exec);
2064   statement->processVarDecls(exec);
2065 }
2066
2067 // ------------------------------ ContinueNode ---------------------------------
2068
2069 // ECMA 12.7
2070 Completion ContinueNode::execute(ExecState *exec)
2071 {
2072   KJS_BREAKPOINT;
2073
2074   if (ident.isEmpty() && !exec->context()->inIteration())
2075     return createErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
2076   else if (!ident.isEmpty() && !exec->context()->seenLabels()->contains(ident))
2077     return createErrorCompletion(exec, SyntaxError, "Label %s not found.", ident);
2078   else
2079     return Completion(Continue, 0, ident);
2080 }
2081
2082 // ------------------------------ BreakNode ------------------------------------
2083
2084 // ECMA 12.8
2085 Completion BreakNode::execute(ExecState *exec)
2086 {
2087   KJS_BREAKPOINT;
2088
2089   if (ident.isEmpty() && !exec->context()->inIteration() &&
2090       !exec->context()->inSwitch())
2091     return createErrorCompletion(exec, SyntaxError, "Invalid break statement.");
2092   else if (!ident.isEmpty() && !exec->context()->seenLabels()->contains(ident))
2093     return createErrorCompletion(exec, SyntaxError, "Label %s not found.");
2094   else
2095     return Completion(Break, 0, ident);
2096 }
2097
2098 // ------------------------------ ReturnNode -----------------------------------
2099
2100 // ECMA 12.9
2101 Completion ReturnNode::execute(ExecState *exec)
2102 {
2103   KJS_BREAKPOINT;
2104
2105   CodeType codeType = exec->context()->codeType();
2106   if (codeType != FunctionCode && codeType != AnonymousCode ) {
2107     return createErrorCompletion(exec, SyntaxError, "Invalid return statement.");
2108   }
2109
2110   if (!value)
2111     return Completion(ReturnValue, jsUndefined());
2112
2113   JSValue *v = value->evaluate(exec);
2114   KJS_CHECKEXCEPTION
2115
2116   return Completion(ReturnValue, v);
2117 }
2118
2119 // ------------------------------ WithNode -------------------------------------
2120
2121 // ECMA 12.10
2122 Completion WithNode::execute(ExecState *exec)
2123 {
2124   KJS_BREAKPOINT;
2125
2126   JSValue *v = expr->evaluate(exec);
2127   KJS_CHECKEXCEPTION
2128   JSObject *o = v->toObject(exec);
2129   KJS_CHECKEXCEPTION
2130   exec->context()->pushScope(o);
2131   Completion res = statement->execute(exec);
2132   exec->context()->popScope();
2133
2134   return res;
2135 }
2136
2137 void WithNode::processVarDecls(ExecState *exec)
2138 {
2139   statement->processVarDecls(exec);
2140 }
2141
2142 // ------------------------------ CaseClauseNode -------------------------------
2143
2144 // ECMA 12.11
2145 JSValue *CaseClauseNode::evaluate(ExecState *exec)
2146 {
2147   JSValue *v = expr->evaluate(exec);
2148   KJS_CHECKEXCEPTIONVALUE
2149
2150   return v;
2151 }
2152
2153 // ECMA 12.11
2154 Completion CaseClauseNode::evalStatements(ExecState *exec)
2155 {
2156   if (source)
2157     return source->execute(exec);
2158   else
2159     return Completion(Normal, jsUndefined());
2160 }
2161
2162 void CaseClauseNode::processVarDecls(ExecState *exec)
2163 {
2164   if (source)
2165     source->processVarDecls(exec);
2166 }
2167
2168 void CaseClauseNode::processFuncDecl(ExecState* exec)
2169 {
2170   if (source)
2171       source->processFuncDecl(exec);
2172 }
2173
2174 // ------------------------------ ClauseListNode -------------------------------
2175
2176 JSValue *ClauseListNode::evaluate(ExecState *)
2177 {
2178   // should never be called
2179   assert(false);
2180   return 0;
2181 }
2182
2183 // ECMA 12.11
2184 void ClauseListNode::processVarDecls(ExecState *exec)
2185 {
2186   for (ClauseListNode *n = this; n; n = n->next.get())
2187     if (n->clause)
2188       n->clause->processVarDecls(exec);
2189 }
2190
2191 void ClauseListNode::processFuncDecl(ExecState* exec)
2192 {
2193   for (ClauseListNode* n = this; n; n = n->next.get())
2194     if (n->clause)
2195       n->clause->processFuncDecl(exec);
2196 }
2197
2198 void ClauseListNode::breakCycle() 
2199
2200     next = 0;
2201 }
2202
2203 // ------------------------------ CaseBlockNode --------------------------------
2204
2205 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
2206                              ClauseListNode *l2)
2207 {
2208   if (l1) {
2209     list1 = l1->next.release();
2210     Parser::removeNodeCycle(list1.get());
2211   } else {
2212     list1 = 0;
2213   }
2214
2215   def = d;
2216
2217   if (l2) {
2218     list2 = l2->next.release();
2219     Parser::removeNodeCycle(list2.get());
2220   } else {
2221     list2 = 0;
2222   }
2223 }
2224  
2225 JSValue *CaseBlockNode::evaluate(ExecState *)
2226 {
2227   // should never be called
2228   assert(false);
2229   return 0;
2230 }
2231
2232 // ECMA 12.11
2233 Completion CaseBlockNode::evalBlock(ExecState *exec, JSValue *input)
2234 {
2235   JSValue *v;
2236   Completion res;
2237   ClauseListNode *a = list1.get();
2238   ClauseListNode *b = list2.get();
2239   CaseClauseNode *clause;
2240
2241     while (a) {
2242       clause = a->getClause();
2243       a = a->getNext();
2244       v = clause->evaluate(exec);
2245       KJS_CHECKEXCEPTION
2246       if (strictEqual(exec, input, v)) {
2247         res = clause->evalStatements(exec);
2248         if (res.complType() != Normal)
2249           return res;
2250         while (a) {
2251           res = a->getClause()->evalStatements(exec);
2252           if (res.complType() != Normal)
2253             return res;
2254           a = a->getNext();
2255         }
2256         break;
2257       }
2258     }
2259
2260   while (b) {
2261     clause = b->getClause();
2262     b = b->getNext();
2263     v = clause->evaluate(exec);
2264     KJS_CHECKEXCEPTION
2265     if (strictEqual(exec, input, v)) {
2266       res = clause->evalStatements(exec);
2267       if (res.complType() != Normal)
2268         return res;
2269       goto step18;
2270     }
2271   }
2272
2273   // default clause
2274   if (def) {
2275     res = def->evalStatements(exec);
2276     if (res.complType() != Normal)
2277       return res;
2278   }
2279   b = list2.get();
2280  step18:
2281   while (b) {
2282     clause = b->getClause();
2283     res = clause->evalStatements(exec);
2284     if (res.complType() != Normal)
2285       return res;
2286     b = b->getNext();
2287   }
2288
2289   // bail out on error
2290   KJS_CHECKEXCEPTION
2291
2292   return Completion(Normal);
2293 }
2294
2295 void CaseBlockNode::processVarDecls(ExecState *exec)
2296 {
2297   if (list1)
2298     list1->processVarDecls(exec);
2299   if (def)
2300     def->processVarDecls(exec);
2301   if (list2)
2302     list2->processVarDecls(exec);
2303 }
2304
2305 void CaseBlockNode::processFuncDecl(ExecState* exec)
2306 {
2307   if (list1)
2308    list1->processFuncDecl(exec);
2309   if (def)
2310     def->processFuncDecl(exec);
2311   if (list2)
2312     list2->processFuncDecl(exec);
2313 }
2314
2315 // ------------------------------ SwitchNode -----------------------------------
2316
2317 // ECMA 12.11
2318 Completion SwitchNode::execute(ExecState *exec)
2319 {
2320   KJS_BREAKPOINT;
2321
2322   JSValue *v = expr->evaluate(exec);
2323   KJS_CHECKEXCEPTION
2324
2325   exec->context()->pushSwitch();
2326   Completion res = block->evalBlock(exec,v);
2327   exec->context()->popSwitch();
2328
2329   if ((res.complType() == Break) && ls.contains(res.target()))
2330     return Completion(Normal, res.value());
2331   return res;
2332 }
2333
2334 void SwitchNode::processVarDecls(ExecState *exec)
2335 {
2336   block->processVarDecls(exec);
2337 }
2338
2339 void SwitchNode::processFuncDecl(ExecState* exec)
2340 {
2341   block->processFuncDecl(exec);
2342 }
2343
2344 // ------------------------------ LabelNode ------------------------------------
2345
2346 // ECMA 12.12
2347 Completion LabelNode::execute(ExecState *exec)
2348 {
2349   if (!exec->context()->seenLabels()->push(label))
2350     return createErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", label);
2351   Completion e = statement->execute(exec);
2352   exec->context()->seenLabels()->pop();
2353
2354   if ((e.complType() == Break) && (e.target() == label))
2355     return Completion(Normal, e.value());
2356   return e;
2357 }
2358
2359 void LabelNode::processVarDecls(ExecState *exec)
2360 {
2361   statement->processVarDecls(exec);
2362 }
2363
2364 // ------------------------------ ThrowNode ------------------------------------
2365
2366 // ECMA 12.13
2367 Completion ThrowNode::execute(ExecState *exec)
2368 {
2369   KJS_BREAKPOINT;
2370
2371   JSValue *v = expr->evaluate(exec);
2372   KJS_CHECKEXCEPTION
2373
2374   handleException(exec, v);
2375   return Completion(Throw, v);
2376 }
2377
2378 // ------------------------------ TryNode --------------------------------------
2379
2380 // ECMA 12.14
2381 Completion TryNode::execute(ExecState *exec)
2382 {
2383   KJS_BREAKPOINT;
2384
2385   Completion c = tryBlock->execute(exec);
2386
2387   if (catchBlock && c.complType() == Throw) {
2388     JSObject *obj = new JSObject;
2389     obj->put(exec, exceptionIdent, c.value(), DontDelete);
2390     exec->context()->pushScope(obj);
2391     c = catchBlock->execute(exec);
2392     exec->context()->popScope();
2393   }
2394
2395   if (finallyBlock) {
2396     Completion c2 = finallyBlock->execute(exec);
2397     if (c2.complType() != Normal)
2398       c = c2;
2399   }
2400
2401   return c;
2402 }
2403
2404 void TryNode::processVarDecls(ExecState *exec)
2405 {
2406   tryBlock->processVarDecls(exec);
2407   if (catchBlock)
2408     catchBlock->processVarDecls(exec);
2409   if (finallyBlock)
2410     finallyBlock->processVarDecls(exec);
2411 }
2412
2413 // ------------------------------ ParameterNode --------------------------------
2414
2415 // ECMA 13
2416 JSValue *ParameterNode::evaluate(ExecState *)
2417 {
2418   return jsUndefined();
2419 }
2420
2421 void ParameterNode::breakCycle() 
2422
2423     next = 0;
2424 }
2425
2426 // ------------------------------ FunctionBodyNode -----------------------------
2427
2428 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
2429     : BlockNode(s)
2430     , m_sourceURL(Lexer::curr()->sourceURL())
2431     , m_sourceId(Parser::sid)
2432 {
2433
2434   setLoc(-1, -1);
2435 }
2436
2437 void FunctionBodyNode::processFuncDecl(ExecState *exec)
2438 {
2439     if (source)
2440         source->processFuncDecl(exec);
2441 }
2442
2443 void FunctionBodyNode::addParam(const Identifier& ident)
2444 {
2445   m_parameters.append(Parameter(ident));
2446 }
2447
2448 UString FunctionBodyNode::paramString() const
2449 {
2450   UString s("");
2451   size_t count = numParams();
2452   for (size_t pos = 0; pos < count; ++pos) {
2453     if (!s.isEmpty())
2454         s += ", ";
2455     s += paramName(pos).ustring();
2456   }
2457
2458   return s;
2459 }
2460
2461
2462 // ------------------------------ FuncDeclNode ---------------------------------
2463
2464 void FuncDeclNode::addParams() 
2465 {
2466   for (ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
2467     body->addParam(p->ident());
2468 }
2469
2470 // ECMA 13
2471 void FuncDeclNode::processFuncDecl(ExecState *exec)
2472 {
2473   Context *context = exec->context();
2474
2475   // TODO: let this be an object with [[Class]] property "Function"
2476   FunctionImp *func = new DeclaredFunctionImp(exec, ident, body.get(), context->scopeChain());
2477
2478   JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
2479   proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum);
2480   func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete);
2481
2482   func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum);
2483
2484   // ECMA 10.2.2
2485   context->variableObject()->put(exec, ident, func, Internal | (context->codeType() == EvalCode ? 0 : DontDelete));
2486
2487   if (body) {
2488     // hack the scope so that the function gets put as a property of func, and it's scope
2489     // contains the func as well as our current scope
2490     JSObject *oldVar = context->variableObject();
2491     context->setVariableObject(func);
2492     context->pushScope(func);
2493     body->processFuncDecl(exec);
2494     context->popScope();
2495     context->setVariableObject(oldVar);
2496   }
2497 }
2498
2499 Completion FuncDeclNode::execute(ExecState *)
2500 {
2501     return Completion(Normal);
2502 }
2503
2504 // ------------------------------ FuncExprNode ---------------------------------
2505
2506 // ECMA 13
2507 void FuncExprNode::addParams()
2508 {
2509   for (ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
2510     body->addParam(p->ident());
2511 }
2512
2513 JSValue *FuncExprNode::evaluate(ExecState *exec)
2514 {
2515   Context *context = exec->context();
2516   bool named = !ident.isNull();
2517   JSObject *functionScopeObject = 0;
2518
2519   if (named) {
2520     // named FunctionExpressions can recursively call themselves,
2521     // but they won't register with the current scope chain and should
2522     // be contained as single property in an anonymous object.
2523     functionScopeObject = new JSObject;
2524     context->pushScope(functionScopeObject);
2525   }
2526
2527   FunctionImp* func = new DeclaredFunctionImp(exec, ident, body.get(), context->scopeChain());
2528   JSObject* proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
2529   proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum);
2530   func->put(exec, exec->propertyNames().prototype, proto, Internal | DontDelete);
2531
2532   if (named) {
2533     functionScopeObject->put(exec, ident, func, Internal | ReadOnly | (context->codeType() == EvalCode ? 0 : DontDelete));
2534     context->popScope();
2535   }
2536
2537   return func;
2538 }
2539
2540 // ------------------------------ SourceElementsNode ---------------------------
2541
2542 int SourceElementsNode::count = 0;
2543
2544 SourceElementsNode::SourceElementsNode(StatementNode *s1)
2545   : node(s1), next(this)
2546 {
2547     Parser::noteNodeCycle(this);
2548     setLoc(s1->firstLine(), s1->lastLine());
2549 }
2550
2551 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
2552   : node(s2), next(s1->next)
2553 {
2554   s1->next = this;
2555   setLoc(s1->firstLine(), s2->lastLine());
2556 }
2557
2558 // ECMA 14
2559 Completion SourceElementsNode::execute(ExecState *exec)
2560 {
2561   KJS_CHECKEXCEPTION
2562
2563   Completion c1 = node->execute(exec);
2564   KJS_CHECKEXCEPTION;
2565   if (c1.complType() != Normal)
2566     return c1;
2567   
2568   for (SourceElementsNode *n = next.get(); n; n = n->next.get()) {
2569     Completion c2 = n->node->execute(exec);
2570     if (c2.complType() != Normal)
2571       return c2;
2572     // The spec says to return c2 here, but it seems that mozilla returns c1 if
2573     // c2 doesn't have a value
2574     if (c2.value())
2575       c1 = c2;
2576   }
2577   
2578   return c1;
2579 }
2580
2581 // ECMA 14
2582 void SourceElementsNode::processFuncDecl(ExecState *exec)
2583 {
2584   for (SourceElementsNode *n = this; n; n = n->next.get())
2585     n->node->processFuncDecl(exec);
2586 }
2587
2588 void SourceElementsNode::processVarDecls(ExecState *exec)
2589 {
2590   for (SourceElementsNode *n = this; n; n = n->next.get())
2591     n->node->processVarDecls(exec);
2592 }
2593
2594 void SourceElementsNode::breakCycle() 
2595
2596     next = 0;
2597 }
2598
2599 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s)
2600 {
2601 }