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