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