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