6b488dc73586b2916ce794d07cb14ba5dfd1d8bf
[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 // ECMA 12.2
1591 JSValue *VarDeclNode::evaluate(ExecState *exec)
1592 {
1593   JSObject* variable = exec->context()->variableObject();
1594
1595   JSValue* val;
1596   if (init) {
1597       val = init->evaluate(exec);
1598       KJS_CHECKEXCEPTIONVALUE
1599       
1600       if (variable->getDirect(ident) || ident == exec->propertyNames().arguments) {
1601           const ScopeChain& chain = exec->context()->scopeChain();
1602           ScopeChainIterator iter = chain.begin();
1603           ScopeChainIterator end = chain.end();        
1604
1605           // we must always have something in the scope chain
1606           ASSERT(iter != end);
1607
1608           PropertySlot slot;
1609           JSObject* base;
1610
1611           do {
1612               base = *iter;
1613               if (base->getPropertySlot(exec, ident, slot))
1614                   break;
1615
1616              ++iter;
1617           } while (iter != end);
1618
1619           unsigned flags = 0;
1620           base->getPropertyAttributes(ident, flags);
1621           if (varType == VarDeclNode::Constant)
1622               flags |= ReadOnly;
1623
1624           base->put(exec, ident, val, flags);
1625           return jsString(ident.ustring());
1626       }
1627     } else {
1628       // already declared? - check with getDirect so you can override
1629       // built-in properties of the global object with var declarations.
1630       // Also check for 'arguments' property. The 'arguments' cannot be found with
1631       // getDirect, because it's created lazily by
1632       // ActivationImp::getOwnPropertySlot.
1633       // Since variable declarations are always in function scope, 'variable'
1634       // will always contain instance of ActivationImp and ActivationImp will
1635       // always have 'arguments' property
1636       if (variable->getDirect(ident) || ident == exec->propertyNames().arguments)
1637           return 0;
1638       val = jsUndefined();
1639   }
1640
1641 #ifdef KJS_VERBOSE
1642   printInfo(exec,(UString("new variable ")+ident.ustring()).cstring().c_str(),val);
1643 #endif
1644   // We use Internal to bypass all checks in derived objects, e.g. so that
1645   // "var location" creates a dynamic property instead of activating window.location.
1646   int flags = Internal;
1647   if (exec->context()->codeType() != EvalCode)
1648     flags |= DontDelete;
1649   if (varType == VarDeclNode::Constant)
1650     flags |= ReadOnly;
1651   variable->put(exec, ident, val, flags);
1652
1653   return jsString(ident.ustring());
1654 }
1655
1656 void VarDeclNode::processVarDecls(ExecState *exec)
1657 {
1658   JSObject* variable = exec->context()->variableObject();
1659
1660   // If a variable by this name already exists, don't clobber it -
1661   // it might be a function parameter
1662   if (!variable->hasProperty(exec, ident)) {
1663     int flags = Internal;
1664     if (exec->context()->codeType() != EvalCode)
1665       flags |= DontDelete;
1666     if (varType == VarDeclNode::Constant)
1667       flags |= ReadOnly;
1668     variable->put(exec, ident, jsUndefined(), flags);
1669   }
1670 }
1671
1672 // ------------------------------ VarDeclListNode ------------------------------
1673
1674 // ECMA 12.2
1675 JSValue *VarDeclListNode::evaluate(ExecState *exec)
1676 {
1677   for (VarDeclListNode *n = this; n; n = n->next.get()) {
1678     n->var->evaluate(exec);
1679     KJS_CHECKEXCEPTIONVALUE
1680   }
1681   return jsUndefined();
1682 }
1683
1684 void VarDeclListNode::processVarDecls(ExecState *exec)
1685 {
1686   for (VarDeclListNode *n = this; n; n = n->next.get())
1687     n->var->processVarDecls(exec);
1688 }
1689
1690 void VarDeclListNode::breakCycle() 
1691
1692     next = 0;
1693 }
1694
1695 // ------------------------------ VarStatementNode -----------------------------
1696
1697 // ECMA 12.2
1698 Completion VarStatementNode::execute(ExecState *exec)
1699 {
1700   KJS_BREAKPOINT;
1701
1702   (void) next->evaluate(exec);
1703   KJS_CHECKEXCEPTION
1704
1705   return Completion(Normal);
1706 }
1707
1708 void VarStatementNode::processVarDecls(ExecState *exec)
1709 {
1710   next->processVarDecls(exec);
1711 }
1712
1713 // ------------------------------ BlockNode ------------------------------------
1714
1715 BlockNode::BlockNode(SourceElementsNode *s)
1716 {
1717   if (s) {
1718     source = s->next.release();
1719     Parser::removeNodeCycle(source.get());
1720     setLoc(s->firstLine(), s->lastLine());
1721   } else {
1722     source = 0;
1723   }
1724 }
1725
1726 // ECMA 12.1
1727 Completion BlockNode::execute(ExecState *exec)
1728 {
1729   if (!source)
1730     return Completion(Normal);
1731
1732   source->processFuncDecl(exec);
1733
1734   return source->execute(exec);
1735 }
1736
1737 void BlockNode::processVarDecls(ExecState *exec)
1738 {
1739   if (source)
1740     source->processVarDecls(exec);
1741 }
1742
1743 // ------------------------------ EmptyStatementNode ---------------------------
1744
1745 // ECMA 12.3
1746 Completion EmptyStatementNode::execute(ExecState *)
1747 {
1748   return Completion(Normal);
1749 }
1750
1751 // ------------------------------ ExprStatementNode ----------------------------
1752
1753 // ECMA 12.4
1754 Completion ExprStatementNode::execute(ExecState *exec)
1755 {
1756   KJS_BREAKPOINT;
1757
1758   JSValue *v = expr->evaluate(exec);
1759   KJS_CHECKEXCEPTION
1760
1761   return Completion(Normal, v);
1762 }
1763
1764 // ------------------------------ IfNode ---------------------------------------
1765
1766 // ECMA 12.5
1767 Completion IfNode::execute(ExecState *exec)
1768 {
1769   KJS_BREAKPOINT;
1770
1771   JSValue *v = expr->evaluate(exec);
1772   KJS_CHECKEXCEPTION
1773   bool b = v->toBoolean(exec);
1774
1775   // if ... then
1776   if (b)
1777     return statement1->execute(exec);
1778
1779   // no else
1780   if (!statement2)
1781     return Completion(Normal);
1782
1783   // else
1784   return statement2->execute(exec);
1785 }
1786
1787 void IfNode::processVarDecls(ExecState *exec)
1788 {
1789   statement1->processVarDecls(exec);
1790
1791   if (statement2)
1792     statement2->processVarDecls(exec);
1793 }
1794
1795 // ------------------------------ DoWhileNode ----------------------------------
1796
1797 // ECMA 12.6.1
1798 Completion DoWhileNode::execute(ExecState *exec)
1799 {
1800   KJS_BREAKPOINT;
1801
1802   JSValue *bv;
1803   Completion c;
1804
1805   do {
1806     // bail out on error
1807     KJS_CHECKEXCEPTION
1808
1809     exec->context()->pushIteration();
1810     c = statement->execute(exec);
1811     exec->context()->popIteration();
1812     
1813     if (exec->dynamicInterpreter()->timedOut())
1814         return Completion(Interrupted);
1815
1816     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
1817       if ((c.complType() == Break) && ls.contains(c.target()))
1818         return Completion(Normal, 0);
1819       if (c.complType() != Normal)
1820         return c;
1821     }
1822     bv = expr->evaluate(exec);
1823     KJS_CHECKEXCEPTION
1824   } while (bv->toBoolean(exec));
1825
1826   return Completion(Normal, 0);
1827 }
1828
1829 void DoWhileNode::processVarDecls(ExecState *exec)
1830 {
1831   statement->processVarDecls(exec);
1832 }
1833
1834 // ------------------------------ WhileNode ------------------------------------
1835
1836 // ECMA 12.6.2
1837 Completion WhileNode::execute(ExecState *exec)
1838 {
1839   KJS_BREAKPOINT;
1840
1841   JSValue *bv;
1842   Completion c;
1843   bool b(false);
1844   JSValue *value = 0;
1845
1846   while (1) {
1847     bv = expr->evaluate(exec);
1848     KJS_CHECKEXCEPTION
1849     b = bv->toBoolean(exec);
1850
1851     // bail out on error
1852     KJS_CHECKEXCEPTION
1853
1854     if (!b)
1855       return Completion(Normal, value);
1856
1857     exec->context()->pushIteration();
1858     c = statement->execute(exec);
1859     exec->context()->popIteration();
1860
1861     if (exec->dynamicInterpreter()->timedOut())
1862         return Completion(Interrupted);
1863     
1864     if (c.isValueCompletion())
1865       value = c.value();
1866
1867     if ((c.complType() == Continue) && ls.contains(c.target()))
1868       continue;
1869     if ((c.complType() == Break) && ls.contains(c.target()))
1870       return Completion(Normal, value);
1871     if (c.complType() != Normal)
1872       return c;
1873   }
1874
1875   return Completion(); // work around gcc 4.0 bug
1876 }
1877
1878 void WhileNode::processVarDecls(ExecState *exec)
1879 {
1880   statement->processVarDecls(exec);
1881 }
1882
1883 // ------------------------------ ForNode --------------------------------------
1884
1885 // ECMA 12.6.3
1886 Completion ForNode::execute(ExecState *exec)
1887 {
1888   JSValue *v, *cval = 0;
1889
1890   if (expr1) {
1891     v = expr1->evaluate(exec);
1892     KJS_CHECKEXCEPTION
1893   }
1894   while (1) {
1895     if (expr2) {
1896       v = expr2->evaluate(exec);
1897       KJS_CHECKEXCEPTION
1898       if (!v->toBoolean(exec))
1899         return Completion(Normal, cval);
1900     }
1901     // bail out on error
1902     KJS_CHECKEXCEPTION
1903
1904     exec->context()->pushIteration();
1905     Completion c = statement->execute(exec);
1906     exec->context()->popIteration();
1907     if (c.isValueCompletion())
1908       cval = c.value();
1909     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
1910       if ((c.complType() == Break) && ls.contains(c.target()))
1911         return Completion(Normal, cval);
1912       if (c.complType() != Normal)
1913       return c;
1914     }
1915     
1916     if (exec->dynamicInterpreter()->timedOut())
1917         return Completion(Interrupted);
1918     
1919     if (expr3) {
1920       v = expr3->evaluate(exec);
1921       KJS_CHECKEXCEPTION
1922     }
1923   }
1924   
1925   return Completion(); // work around gcc 4.0 bug
1926 }
1927
1928 void ForNode::processVarDecls(ExecState *exec)
1929 {
1930   if (expr1)
1931     expr1->processVarDecls(exec);
1932
1933   statement->processVarDecls(exec);
1934 }
1935
1936 // ------------------------------ ForInNode ------------------------------------
1937
1938 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
1939   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
1940 {
1941 }
1942
1943 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
1944   : ident(i), init(in), expr(e), statement(s)
1945 {
1946   // for( var foo = bar in baz )
1947   varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
1948   lexpr = new ResolveNode(ident);
1949 }
1950
1951 // ECMA 12.6.4
1952 Completion ForInNode::execute(ExecState *exec)
1953 {
1954   JSValue *e;
1955   JSValue *retval = 0;
1956   JSObject *v;
1957   Completion c;
1958   PropertyNameArray propertyNames;
1959
1960   if (varDecl) {
1961     varDecl->evaluate(exec);
1962     KJS_CHECKEXCEPTION
1963   }
1964
1965   e = expr->evaluate(exec);
1966
1967   // for Null and Undefined, we want to make sure not to go through
1968   // the loop at all, because their object wrappers will have a
1969   // property list but will throw an exception if you attempt to
1970   // access any property.
1971   if (e->isUndefinedOrNull()) {
1972     return Completion(Normal, 0);
1973   }
1974
1975   KJS_CHECKEXCEPTION
1976   v = e->toObject(exec);
1977   v->getPropertyNames(exec, propertyNames);
1978   
1979   PropertyNameArrayIterator end = propertyNames.end();
1980   for (PropertyNameArrayIterator it = propertyNames.begin(); it != end; ++it) {
1981       const Identifier &name = *it;
1982       if (!v->hasProperty(exec, name))
1983           continue;
1984
1985       JSValue *str = jsString(name.ustring());
1986
1987       if (lexpr->isResolveNode()) {
1988         const Identifier &ident = static_cast<ResolveNode *>(lexpr.get())->identifier();
1989
1990         const ScopeChain& chain = exec->context()->scopeChain();
1991         ScopeChainIterator iter = chain.begin();
1992         ScopeChainIterator end = chain.end();
1993   
1994         // we must always have something in the scope chain
1995         assert(iter != end);
1996
1997         PropertySlot slot;
1998         JSObject *o;
1999         do { 
2000             o = *iter;
2001             if (o->getPropertySlot(exec, ident, slot)) {
2002                 o->put(exec, ident, str);
2003                 break;
2004             }
2005             ++iter;
2006         } while (iter != end);
2007         
2008         if (iter == end)
2009             o->put(exec, ident, str);
2010     } else if (lexpr->isDotAccessorNode()) {
2011         const Identifier& ident = static_cast<DotAccessorNode *>(lexpr.get())->identifier();
2012         JSValue *v = static_cast<DotAccessorNode *>(lexpr.get())->base()->evaluate(exec);
2013         KJS_CHECKEXCEPTION
2014         JSObject *o = v->toObject(exec);
2015
2016         o->put(exec, ident, str);
2017     } else {
2018         assert(lexpr->isBracketAccessorNode());
2019         JSValue *v = static_cast<BracketAccessorNode *>(lexpr.get())->base()->evaluate(exec);
2020         KJS_CHECKEXCEPTION
2021         JSValue *v2 = static_cast<BracketAccessorNode *>(lexpr.get())->subscript()->evaluate(exec);
2022         KJS_CHECKEXCEPTION
2023         JSObject *o = v->toObject(exec);
2024
2025         uint32_t i;
2026         if (v2->getUInt32(i))
2027             o->put(exec, i, str);
2028         o->put(exec, Identifier(v2->toString(exec)), str);
2029     }
2030
2031     KJS_CHECKEXCEPTION
2032
2033     exec->context()->pushIteration();
2034     c = statement->execute(exec);
2035     exec->context()->popIteration();
2036     if (c.isValueCompletion())
2037       retval = c.value();
2038
2039     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2040       if ((c.complType() == Break) && ls.contains(c.target()))
2041         break;
2042       if (c.complType() != Normal) {
2043         return c;
2044       }
2045     }
2046   }
2047
2048   // bail out on error
2049   KJS_CHECKEXCEPTION
2050
2051   return Completion(Normal, retval);
2052 }
2053
2054 void ForInNode::processVarDecls(ExecState *exec)
2055 {
2056   if (varDecl)
2057     varDecl->processVarDecls(exec);
2058   statement->processVarDecls(exec);
2059 }
2060
2061 // ------------------------------ ContinueNode ---------------------------------
2062
2063 // ECMA 12.7
2064 Completion ContinueNode::execute(ExecState *exec)
2065 {
2066   KJS_BREAKPOINT;
2067
2068   if (ident.isEmpty() && !exec->context()->inIteration())
2069     return createErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
2070   else if (!ident.isEmpty() && !exec->context()->seenLabels()->contains(ident))
2071     return createErrorCompletion(exec, SyntaxError, "Label %s not found.", ident);
2072   else
2073     return Completion(Continue, 0, ident);
2074 }
2075
2076 // ------------------------------ BreakNode ------------------------------------
2077
2078 // ECMA 12.8
2079 Completion BreakNode::execute(ExecState *exec)
2080 {
2081   KJS_BREAKPOINT;
2082
2083   if (ident.isEmpty() && !exec->context()->inIteration() &&
2084       !exec->context()->inSwitch())
2085     return createErrorCompletion(exec, SyntaxError, "Invalid break statement.");
2086   else if (!ident.isEmpty() && !exec->context()->seenLabels()->contains(ident))
2087     return createErrorCompletion(exec, SyntaxError, "Label %s not found.");
2088   else
2089     return Completion(Break, 0, ident);
2090 }
2091
2092 // ------------------------------ ReturnNode -----------------------------------
2093
2094 // ECMA 12.9
2095 Completion ReturnNode::execute(ExecState *exec)
2096 {
2097   KJS_BREAKPOINT;
2098
2099   CodeType codeType = exec->context()->codeType();
2100   if (codeType != FunctionCode && codeType != AnonymousCode ) {
2101     return createErrorCompletion(exec, SyntaxError, "Invalid return statement.");
2102   }
2103
2104   if (!value)
2105     return Completion(ReturnValue, jsUndefined());
2106
2107   JSValue *v = value->evaluate(exec);
2108   KJS_CHECKEXCEPTION
2109
2110   return Completion(ReturnValue, v);
2111 }
2112
2113 // ------------------------------ WithNode -------------------------------------
2114
2115 // ECMA 12.10
2116 Completion WithNode::execute(ExecState *exec)
2117 {
2118   KJS_BREAKPOINT;
2119
2120   JSValue *v = expr->evaluate(exec);
2121   KJS_CHECKEXCEPTION
2122   JSObject *o = v->toObject(exec);
2123   KJS_CHECKEXCEPTION
2124   exec->context()->pushScope(o);
2125   Completion res = statement->execute(exec);
2126   exec->context()->popScope();
2127
2128   return res;
2129 }
2130
2131 void WithNode::processVarDecls(ExecState *exec)
2132 {
2133   statement->processVarDecls(exec);
2134 }
2135
2136 // ------------------------------ CaseClauseNode -------------------------------
2137
2138 // ECMA 12.11
2139 JSValue *CaseClauseNode::evaluate(ExecState *exec)
2140 {
2141   JSValue *v = expr->evaluate(exec);
2142   KJS_CHECKEXCEPTIONVALUE
2143
2144   return v;
2145 }
2146
2147 // ECMA 12.11
2148 Completion CaseClauseNode::evalStatements(ExecState *exec)
2149 {
2150   if (source)
2151     return source->execute(exec);
2152   else
2153     return Completion(Normal, jsUndefined());
2154 }
2155
2156 void CaseClauseNode::processVarDecls(ExecState *exec)
2157 {
2158   if (source)
2159     source->processVarDecls(exec);
2160 }
2161
2162 void CaseClauseNode::processFuncDecl(ExecState* exec)
2163 {
2164   if (source)
2165       source->processFuncDecl(exec);
2166 }
2167
2168 // ------------------------------ ClauseListNode -------------------------------
2169
2170 JSValue *ClauseListNode::evaluate(ExecState *)
2171 {
2172   // should never be called
2173   assert(false);
2174   return 0;
2175 }
2176
2177 // ECMA 12.11
2178 void ClauseListNode::processVarDecls(ExecState *exec)
2179 {
2180   for (ClauseListNode *n = this; n; n = n->next.get())
2181     if (n->clause)
2182       n->clause->processVarDecls(exec);
2183 }
2184
2185 void ClauseListNode::processFuncDecl(ExecState* exec)
2186 {
2187   for (ClauseListNode* n = this; n; n = n->next.get())
2188     if (n->clause)
2189       n->clause->processFuncDecl(exec);
2190 }
2191
2192 void ClauseListNode::breakCycle() 
2193
2194     next = 0;
2195 }
2196
2197 // ------------------------------ CaseBlockNode --------------------------------
2198
2199 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
2200                              ClauseListNode *l2)
2201 {
2202   if (l1) {
2203     list1 = l1->next.release();
2204     Parser::removeNodeCycle(list1.get());
2205   } else {
2206     list1 = 0;
2207   }
2208
2209   def = d;
2210
2211   if (l2) {
2212     list2 = l2->next.release();
2213     Parser::removeNodeCycle(list2.get());
2214   } else {
2215     list2 = 0;
2216   }
2217 }
2218  
2219 JSValue *CaseBlockNode::evaluate(ExecState *)
2220 {
2221   // should never be called
2222   assert(false);
2223   return 0;
2224 }
2225
2226 // ECMA 12.11
2227 Completion CaseBlockNode::evalBlock(ExecState *exec, JSValue *input)
2228 {
2229   JSValue *v;
2230   Completion res;
2231   ClauseListNode *a = list1.get();
2232   ClauseListNode *b = list2.get();
2233   CaseClauseNode *clause;
2234
2235     while (a) {
2236       clause = a->getClause();
2237       a = a->getNext();
2238       v = clause->evaluate(exec);
2239       KJS_CHECKEXCEPTION
2240       if (strictEqual(exec, input, v)) {
2241         res = clause->evalStatements(exec);
2242         if (res.complType() != Normal)
2243           return res;
2244         while (a) {
2245           res = a->getClause()->evalStatements(exec);
2246           if (res.complType() != Normal)
2247             return res;
2248           a = a->getNext();
2249         }
2250         break;
2251       }
2252     }
2253
2254   while (b) {
2255     clause = b->getClause();
2256     b = b->getNext();
2257     v = clause->evaluate(exec);
2258     KJS_CHECKEXCEPTION
2259     if (strictEqual(exec, input, v)) {
2260       res = clause->evalStatements(exec);
2261       if (res.complType() != Normal)
2262         return res;
2263       goto step18;
2264     }
2265   }
2266
2267   // default clause
2268   if (def) {
2269     res = def->evalStatements(exec);
2270     if (res.complType() != Normal)
2271       return res;
2272   }
2273   b = list2.get();
2274  step18:
2275   while (b) {
2276     clause = b->getClause();
2277     res = clause->evalStatements(exec);
2278     if (res.complType() != Normal)
2279       return res;
2280     b = b->getNext();
2281   }
2282
2283   // bail out on error
2284   KJS_CHECKEXCEPTION
2285
2286   return Completion(Normal);
2287 }
2288
2289 void CaseBlockNode::processVarDecls(ExecState *exec)
2290 {
2291   if (list1)
2292     list1->processVarDecls(exec);
2293   if (def)
2294     def->processVarDecls(exec);
2295   if (list2)
2296     list2->processVarDecls(exec);
2297 }
2298
2299 void CaseBlockNode::processFuncDecl(ExecState* exec)
2300 {
2301   if (list1)
2302    list1->processFuncDecl(exec);
2303   if (def)
2304     def->processFuncDecl(exec);
2305   if (list2)
2306     list2->processFuncDecl(exec);
2307 }
2308
2309 // ------------------------------ SwitchNode -----------------------------------
2310
2311 // ECMA 12.11
2312 Completion SwitchNode::execute(ExecState *exec)
2313 {
2314   KJS_BREAKPOINT;
2315
2316   JSValue *v = expr->evaluate(exec);
2317   KJS_CHECKEXCEPTION
2318
2319   exec->context()->pushSwitch();
2320   Completion res = block->evalBlock(exec,v);
2321   exec->context()->popSwitch();
2322
2323   if ((res.complType() == Break) && ls.contains(res.target()))
2324     return Completion(Normal, res.value());
2325   return res;
2326 }
2327
2328 void SwitchNode::processVarDecls(ExecState *exec)
2329 {
2330   block->processVarDecls(exec);
2331 }
2332
2333 void SwitchNode::processFuncDecl(ExecState* exec)
2334 {
2335   block->processFuncDecl(exec);
2336 }
2337
2338 // ------------------------------ LabelNode ------------------------------------
2339
2340 // ECMA 12.12
2341 Completion LabelNode::execute(ExecState *exec)
2342 {
2343   if (!exec->context()->seenLabels()->push(label))
2344     return createErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", label);
2345   Completion e = statement->execute(exec);
2346   exec->context()->seenLabels()->pop();
2347
2348   if ((e.complType() == Break) && (e.target() == label))
2349     return Completion(Normal, e.value());
2350   return e;
2351 }
2352
2353 void LabelNode::processVarDecls(ExecState *exec)
2354 {
2355   statement->processVarDecls(exec);
2356 }
2357
2358 // ------------------------------ ThrowNode ------------------------------------
2359
2360 // ECMA 12.13
2361 Completion ThrowNode::execute(ExecState *exec)
2362 {
2363   KJS_BREAKPOINT;
2364
2365   JSValue *v = expr->evaluate(exec);
2366   KJS_CHECKEXCEPTION
2367
2368   handleException(exec, v);
2369   return Completion(Throw, v);
2370 }
2371
2372 // ------------------------------ TryNode --------------------------------------
2373
2374 // ECMA 12.14
2375 Completion TryNode::execute(ExecState *exec)
2376 {
2377   KJS_BREAKPOINT;
2378
2379   Completion c = tryBlock->execute(exec);
2380
2381   if (catchBlock && c.complType() == Throw) {
2382     JSObject *obj = new JSObject;
2383     obj->put(exec, exceptionIdent, c.value(), DontDelete);
2384     exec->context()->pushScope(obj);
2385     c = catchBlock->execute(exec);
2386     exec->context()->popScope();
2387   }
2388
2389   if (finallyBlock) {
2390     Completion c2 = finallyBlock->execute(exec);
2391     if (c2.complType() != Normal)
2392       c = c2;
2393   }
2394
2395   return c;
2396 }
2397
2398 void TryNode::processVarDecls(ExecState *exec)
2399 {
2400   tryBlock->processVarDecls(exec);
2401   if (catchBlock)
2402     catchBlock->processVarDecls(exec);
2403   if (finallyBlock)
2404     finallyBlock->processVarDecls(exec);
2405 }
2406
2407 // ------------------------------ ParameterNode --------------------------------
2408
2409 // ECMA 13
2410 JSValue *ParameterNode::evaluate(ExecState *)
2411 {
2412   return jsUndefined();
2413 }
2414
2415 void ParameterNode::breakCycle() 
2416
2417     next = 0;
2418 }
2419
2420 // ------------------------------ FunctionBodyNode -----------------------------
2421
2422 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
2423     : BlockNode(s)
2424     , m_sourceURL(Lexer::curr()->sourceURL())
2425     , m_sourceId(Parser::sid)
2426 {
2427
2428   setLoc(-1, -1);
2429 }
2430
2431 void FunctionBodyNode::processFuncDecl(ExecState *exec)
2432 {
2433     if (source)
2434         source->processFuncDecl(exec);
2435 }
2436
2437 void FunctionBodyNode::addParam(const Identifier& ident)
2438 {
2439   m_parameters.append(Parameter(ident));
2440 }
2441
2442 UString FunctionBodyNode::paramString() const
2443 {
2444   UString s("");
2445   size_t count = numParams();
2446   for (size_t pos = 0; pos < count; ++pos) {
2447     if (!s.isEmpty())
2448         s += ", ";
2449     s += paramName(pos).ustring();
2450   }
2451
2452   return s;
2453 }
2454
2455
2456 // ------------------------------ FuncDeclNode ---------------------------------
2457
2458 void FuncDeclNode::addParams() 
2459 {
2460   for (ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
2461     body->addParam(p->ident());
2462 }
2463
2464 // ECMA 13
2465 void FuncDeclNode::processFuncDecl(ExecState *exec)
2466 {
2467   Context *context = exec->context();
2468
2469   // TODO: let this be an object with [[Class]] property "Function"
2470   FunctionImp *func = new DeclaredFunctionImp(exec, ident, body.get(), context->scopeChain());
2471
2472   JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
2473   proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum);
2474   func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete);
2475
2476   func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum);
2477
2478   // ECMA 10.2.2
2479   context->variableObject()->put(exec, ident, func, Internal | (context->codeType() == EvalCode ? 0 : DontDelete));
2480
2481   if (body) {
2482     // hack the scope so that the function gets put as a property of func, and it's scope
2483     // contains the func as well as our current scope
2484     JSObject *oldVar = context->variableObject();
2485     context->setVariableObject(func);
2486     context->pushScope(func);
2487     body->processFuncDecl(exec);
2488     context->popScope();
2489     context->setVariableObject(oldVar);
2490   }
2491 }
2492
2493 Completion FuncDeclNode::execute(ExecState *)
2494 {
2495     return Completion(Normal);
2496 }
2497
2498 // ------------------------------ FuncExprNode ---------------------------------
2499
2500 // ECMA 13
2501 void FuncExprNode::addParams()
2502 {
2503   for (ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
2504     body->addParam(p->ident());
2505 }
2506
2507 JSValue *FuncExprNode::evaluate(ExecState *exec)
2508 {
2509   Context *context = exec->context();
2510   bool named = !ident.isNull();
2511   JSObject *functionScopeObject = 0;
2512
2513   if (named) {
2514     // named FunctionExpressions can recursively call themselves,
2515     // but they won't register with the current scope chain and should
2516     // be contained as single property in an anonymous object.
2517     functionScopeObject = new JSObject;
2518     context->pushScope(functionScopeObject);
2519   }
2520
2521   FunctionImp* func = new DeclaredFunctionImp(exec, ident, body.get(), context->scopeChain());
2522   JSObject* proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
2523   proto->put(exec, exec->propertyNames().constructor, func, ReadOnly | DontDelete | DontEnum);
2524   func->put(exec, exec->propertyNames().prototype, proto, Internal | DontDelete);
2525
2526   if (named) {
2527     functionScopeObject->put(exec, ident, func, Internal | ReadOnly | (context->codeType() == EvalCode ? 0 : DontDelete));
2528     context->popScope();
2529   }
2530
2531   return func;
2532 }
2533
2534 // ------------------------------ SourceElementsNode ---------------------------
2535
2536 int SourceElementsNode::count = 0;
2537
2538 SourceElementsNode::SourceElementsNode(StatementNode *s1)
2539   : node(s1), next(this)
2540 {
2541     Parser::noteNodeCycle(this);
2542     setLoc(s1->firstLine(), s1->lastLine());
2543 }
2544
2545 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
2546   : node(s2), next(s1->next)
2547 {
2548   s1->next = this;
2549   setLoc(s1->firstLine(), s2->lastLine());
2550 }
2551
2552 // ECMA 14
2553 Completion SourceElementsNode::execute(ExecState *exec)
2554 {
2555   KJS_CHECKEXCEPTION
2556
2557   Completion c1 = node->execute(exec);
2558   KJS_CHECKEXCEPTION;
2559   if (c1.complType() != Normal)
2560     return c1;
2561   
2562   for (SourceElementsNode *n = next.get(); n; n = n->next.get()) {
2563     Completion c2 = n->node->execute(exec);
2564     if (c2.complType() != Normal)
2565       return c2;
2566     // The spec says to return c2 here, but it seems that mozilla returns c1 if
2567     // c2 doesn't have a value
2568     if (c2.value())
2569       c1 = c2;
2570   }
2571   
2572   return c1;
2573 }
2574
2575 // ECMA 14
2576 void SourceElementsNode::processFuncDecl(ExecState *exec)
2577 {
2578   for (SourceElementsNode *n = this; n; n = n->next.get())
2579     n->node->processFuncDecl(exec);
2580 }
2581
2582 void SourceElementsNode::processVarDecls(ExecState *exec)
2583 {
2584   for (SourceElementsNode *n = this; n; n = n->next.get())
2585     n->node->processVarDecls(exec);
2586 }
2587
2588 void SourceElementsNode::breakCycle() 
2589
2590     next = 0;
2591 }
2592
2593 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s)
2594 {
2595 }