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