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