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