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