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