e3b952b183bba3a8f1ed4cae15d60ec28f36c6a1
[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 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in)
1591     : ident(id), init(in)
1592 {
1593 }
1594
1595 void VarDeclNode::ref()
1596 {
1597   Node::ref();
1598   if ( init )
1599     init->ref();
1600 }
1601
1602 bool VarDeclNode::deref()
1603 {
1604   if ( init && init->deref() )
1605     delete init;
1606   return Node::deref();
1607 }
1608
1609 // ECMA 12.2
1610 Value VarDeclNode::evaluate(ExecState *exec)
1611 {
1612   Object variable = exec->context().imp()->variableObject();
1613
1614   Value val;
1615   if (init) {
1616       val = init->evaluate(exec);
1617       KJS_CHECKEXCEPTIONVALUE
1618   } else {
1619       // already declared? - check with getDirect so you can override
1620       // built-in properties of the global object with var declarations.
1621       if ( variable.imp()->getDirect(ident) ) 
1622           return Value();
1623       val = Undefined();
1624   }
1625
1626 #ifdef KJS_VERBOSE
1627   printInfo(exec,(UString("new variable ")+ident).cstring().c_str(),val);
1628 #endif
1629   // We use Internal to bypass all checks in derived objects, e.g. so that
1630   // "var location" creates a dynamic property instead of activating window.location.
1631   if (exec->context().imp()->codeType() == EvalCode) {
1632       // ECMA 10.2.2
1633       variable.put(exec, ident, val, Internal); 
1634   } else {
1635       variable.put(exec, ident, val, DontDelete | Internal);
1636   }
1637   return ident.ustring();
1638 }
1639
1640 void VarDeclNode::processVarDecls(ExecState *exec)
1641 {
1642   Object variable = exec->context().imp()->variableObject();
1643
1644   // If a variable by this name already exists, don't clobber it -
1645   // it might be a function parameter
1646   if (!variable.hasProperty(exec, ident)) {
1647     variable.put(exec,ident, Undefined(), DontDelete);
1648   }
1649 }
1650
1651 // ------------------------------ VarDeclListNode ------------------------------
1652
1653 void VarDeclListNode::ref()
1654 {
1655   for (VarDeclListNode *n = this; n; n = n->list) {
1656     n->Node::ref();
1657     if (n->var)
1658       n->var->ref();
1659   }
1660 }
1661
1662 bool VarDeclListNode::deref()
1663 {
1664   VarDeclListNode *next;
1665   for (VarDeclListNode *n = this; n; n = next) {
1666     next = n->list;
1667     if (n->var && n->var->deref())
1668       delete n->var;
1669     if (n != this && n->Node::deref())
1670       delete n;
1671   }
1672   return Node::deref();
1673 }
1674
1675
1676 // ECMA 12.2
1677 Value VarDeclListNode::evaluate(ExecState *exec)
1678 {
1679   for (VarDeclListNode *n = this; n; n = n->list) {
1680     n->var->evaluate(exec);
1681     KJS_CHECKEXCEPTIONVALUE
1682   }
1683   return Undefined();
1684 }
1685
1686 void VarDeclListNode::processVarDecls(ExecState *exec)
1687 {
1688   for (VarDeclListNode *n = this; n; n = n->list)
1689     n->var->processVarDecls(exec);
1690 }
1691
1692 // ------------------------------ VarStatementNode -----------------------------
1693
1694 void VarStatementNode::ref()
1695 {
1696   Node::ref();
1697   if ( list )
1698     list->ref();
1699 }
1700
1701 bool VarStatementNode::deref()
1702 {
1703   if ( list && list->deref() )
1704     delete list;
1705   return Node::deref();
1706 }
1707
1708 // ECMA 12.2
1709 Completion VarStatementNode::execute(ExecState *exec)
1710 {
1711   KJS_BREAKPOINT;
1712
1713   (void) list->evaluate(exec); // returns 0L
1714   KJS_CHECKEXCEPTION
1715
1716   return Completion(Normal);
1717 }
1718
1719 void VarStatementNode::processVarDecls(ExecState *exec)
1720 {
1721   list->processVarDecls(exec);
1722 }
1723
1724 // ------------------------------ BlockNode ------------------------------------
1725
1726 BlockNode::BlockNode(SourceElementsNode *s)
1727 {
1728   if (s) {
1729     source = s->elements;
1730     s->elements = 0;
1731     setLoc(s->firstLine(), s->lastLine(), s->sourceId());
1732   } else {
1733     source = 0;
1734   }
1735 }
1736
1737 void BlockNode::ref()
1738 {
1739   Node::ref();
1740   if ( source )
1741     source->ref();
1742 }
1743
1744 bool BlockNode::deref()
1745 {
1746   if ( source && source->deref() )
1747     delete source;
1748   return Node::deref();
1749 }
1750
1751 // ECMA 12.1
1752 Completion BlockNode::execute(ExecState *exec)
1753 {
1754   if (!source)
1755     return Completion(Normal);
1756
1757   source->processFuncDecl(exec);
1758
1759   return source->execute(exec);
1760 }
1761
1762 void BlockNode::processVarDecls(ExecState *exec)
1763 {
1764   if (source)
1765     source->processVarDecls(exec);
1766 }
1767
1768 // ------------------------------ EmptyStatementNode ---------------------------
1769
1770 // ECMA 12.3
1771 Completion EmptyStatementNode::execute(ExecState */*exec*/)
1772 {
1773   return Completion(Normal);
1774 }
1775
1776 // ------------------------------ ExprStatementNode ----------------------------
1777
1778 void ExprStatementNode::ref()
1779 {
1780   Node::ref();
1781   if ( expr )
1782     expr->ref();
1783 }
1784
1785 bool ExprStatementNode::deref()
1786 {
1787   if ( expr && expr->deref() )
1788     delete expr;
1789   return Node::deref();
1790 }
1791
1792 // ECMA 12.4
1793 Completion ExprStatementNode::execute(ExecState *exec)
1794 {
1795   KJS_BREAKPOINT;
1796
1797   Value v = expr->evaluate(exec);
1798   KJS_CHECKEXCEPTION
1799
1800   return Completion(Normal, v);
1801 }
1802
1803 // ------------------------------ IfNode ---------------------------------------
1804
1805 void IfNode::ref()
1806 {
1807   Node::ref();
1808   if ( statement1 )
1809     statement1->ref();
1810   if ( statement2 )
1811     statement2->ref();
1812   if ( expr )
1813     expr->ref();
1814 }
1815
1816 bool IfNode::deref()
1817 {
1818   if ( statement1 && statement1->deref() )
1819     delete statement1;
1820   if ( statement2 && statement2->deref() )
1821     delete statement2;
1822   if ( expr && expr->deref() )
1823     delete expr;
1824   return Node::deref();
1825 }
1826
1827 // ECMA 12.5
1828 Completion IfNode::execute(ExecState *exec)
1829 {
1830   KJS_BREAKPOINT;
1831
1832   Value v = expr->evaluate(exec);
1833   KJS_CHECKEXCEPTION
1834   bool b = v.toBoolean(exec);
1835
1836   // if ... then
1837   if (b)
1838     return statement1->execute(exec);
1839
1840   // no else
1841   if (!statement2)
1842     return Completion(Normal);
1843
1844   // else
1845   return statement2->execute(exec);
1846 }
1847
1848 void IfNode::processVarDecls(ExecState *exec)
1849 {
1850   statement1->processVarDecls(exec);
1851
1852   if (statement2)
1853     statement2->processVarDecls(exec);
1854 }
1855
1856 // ------------------------------ DoWhileNode ----------------------------------
1857
1858 void DoWhileNode::ref()
1859 {
1860   Node::ref();
1861   if ( statement )
1862     statement->ref();
1863   if ( expr )
1864     expr->ref();
1865 }
1866
1867 bool DoWhileNode::deref()
1868 {
1869   if ( statement && statement->deref() )
1870     delete statement;
1871   if ( expr && expr->deref() )
1872     delete expr;
1873   return Node::deref();
1874 }
1875
1876 // ECMA 12.6.1
1877 Completion DoWhileNode::execute(ExecState *exec)
1878 {
1879   KJS_BREAKPOINT;
1880
1881   Value be, bv;
1882   Completion c;
1883   Value value;
1884
1885   do {
1886     // bail out on error
1887     KJS_CHECKEXCEPTION
1888
1889     c = statement->execute(exec);
1890     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
1891       if ((c.complType() == Break) && ls.contains(c.target()))
1892         return Completion(Normal, value);
1893       if (c.complType() != Normal)
1894         return c;
1895     }
1896     bv = expr->evaluate(exec);
1897     KJS_CHECKEXCEPTION
1898   } while (bv.toBoolean(exec));
1899
1900   return Completion(Normal, value);
1901 }
1902
1903 void DoWhileNode::processVarDecls(ExecState *exec)
1904 {
1905   statement->processVarDecls(exec);
1906 }
1907
1908 // ------------------------------ WhileNode ------------------------------------
1909
1910 void WhileNode::ref()
1911 {
1912   Node::ref();
1913   if ( statement )
1914     statement->ref();
1915   if ( expr )
1916     expr->ref();
1917 }
1918
1919 bool WhileNode::deref()
1920 {
1921   if ( statement && statement->deref() )
1922     delete statement;
1923   if ( expr && expr->deref() )
1924     delete expr;
1925   return Node::deref();
1926 }
1927
1928 // ECMA 12.6.2
1929 Completion WhileNode::execute(ExecState *exec)
1930 {
1931   KJS_BREAKPOINT;
1932
1933   Value be, bv;
1934   Completion c;
1935   bool b(false);
1936   Value value;
1937
1938   while (1) {
1939     bv = expr->evaluate(exec);
1940     KJS_CHECKEXCEPTION
1941     b = bv.toBoolean(exec);
1942
1943     // bail out on error
1944     KJS_CHECKEXCEPTION
1945
1946     if (!b)
1947       return Completion(Normal, value);
1948
1949     c = statement->execute(exec);
1950     if (c.isValueCompletion())
1951       value = c.value();
1952
1953     if ((c.complType() == Continue) && ls.contains(c.target()))
1954       continue;
1955     if ((c.complType() == Break) && ls.contains(c.target()))
1956       return Completion(Normal, value);
1957     if (c.complType() != Normal)
1958       return c;
1959   }
1960
1961   return Completion(); // work around gcc 4.0 bug
1962 }
1963
1964 void WhileNode::processVarDecls(ExecState *exec)
1965 {
1966   statement->processVarDecls(exec);
1967 }
1968
1969 // ------------------------------ ForNode --------------------------------------
1970
1971 void ForNode::ref()
1972 {
1973   Node::ref();
1974   if ( statement )
1975     statement->ref();
1976   if ( expr1 )
1977     expr1->ref();
1978   if ( expr2 )
1979     expr2->ref();
1980   if ( expr3 )
1981     expr3->ref();
1982 }
1983
1984 bool ForNode::deref()
1985 {
1986   if ( statement && statement->deref() )
1987     delete statement;
1988   if ( expr1 && expr1->deref() )
1989     delete expr1;
1990   if ( expr2 && expr2->deref() )
1991     delete expr2;
1992   if ( expr3 && expr3->deref() )
1993     delete expr3;
1994   return Node::deref();
1995 }
1996
1997 // ECMA 12.6.3
1998 Completion ForNode::execute(ExecState *exec)
1999 {
2000   Value v, cval;
2001
2002   if (expr1) {
2003     v = expr1->evaluate(exec);
2004     KJS_CHECKEXCEPTION
2005   }
2006   while (1) {
2007     if (expr2) {
2008       v = expr2->evaluate(exec);
2009       KJS_CHECKEXCEPTION
2010       if (!v.toBoolean(exec))
2011         return Completion(Normal, cval);
2012     }
2013     // bail out on error
2014     KJS_CHECKEXCEPTION
2015
2016     Completion c = statement->execute(exec);
2017     if (c.isValueCompletion())
2018       cval = c.value();
2019     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2020       if ((c.complType() == Break) && ls.contains(c.target()))
2021         return Completion(Normal, cval);
2022       if (c.complType() != Normal)
2023       return c;
2024     }
2025     if (expr3) {
2026       v = expr3->evaluate(exec);
2027       KJS_CHECKEXCEPTION
2028     }
2029   }
2030   
2031   return Completion(); // work around gcc 4.0 bug
2032 }
2033
2034 void ForNode::processVarDecls(ExecState *exec)
2035 {
2036   if (expr1)
2037     expr1->processVarDecls(exec);
2038
2039   statement->processVarDecls(exec);
2040 }
2041
2042 // ------------------------------ ForInNode ------------------------------------
2043
2044 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
2045   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
2046 {
2047 }
2048
2049 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
2050   : ident(i), init(in), expr(e), statement(s)
2051 {
2052   // for( var foo = bar in baz )
2053   varDecl = new VarDeclNode(ident, init);
2054   lexpr = new ResolveNode(ident);
2055 }
2056
2057 void ForInNode::ref()
2058 {
2059   Node::ref();
2060   if ( statement )
2061     statement->ref();
2062   if ( expr )
2063     expr->ref();
2064   if ( lexpr )
2065     lexpr->ref();
2066   if ( init )
2067     init->ref();
2068   if ( varDecl )
2069     varDecl->ref();
2070 }
2071
2072 bool ForInNode::deref()
2073 {
2074   if ( statement && statement->deref() )
2075     delete statement;
2076   if ( expr && expr->deref() )
2077     delete expr;
2078   if ( lexpr && lexpr->deref() )
2079     delete lexpr;
2080   if ( init && init->deref() )
2081     delete init;
2082   if ( varDecl && varDecl->deref() )
2083     delete varDecl;
2084   return Node::deref();
2085 }
2086
2087 // ECMA 12.6.4
2088 Completion ForInNode::execute(ExecState *exec)
2089 {
2090   Value e, retval;
2091   Object v;
2092   Completion c;
2093   ReferenceList propList;
2094
2095   if ( varDecl ) {
2096     varDecl->evaluate(exec);
2097     KJS_CHECKEXCEPTION
2098   }
2099
2100   e = expr->evaluate(exec);
2101
2102   // for Null and Undefined, we want to make sure not to go through
2103   // the loop at all, because their object wrappers will have a
2104   // property list but will throw an exception if you attempt to
2105   // access any property.
2106   if (e.type() == UndefinedType || e.type() == NullType) {
2107     return Completion(Normal, retval);
2108   }
2109
2110   KJS_CHECKEXCEPTION
2111   v = e.toObject(exec);
2112   propList = v.propList(exec);
2113
2114   ReferenceListIterator propIt = propList.begin();
2115
2116   while (propIt != propList.end()) {
2117     Identifier name = propIt->getPropertyName(exec);
2118     if (!v.hasProperty(exec,name)) {
2119       propIt++;
2120       continue;
2121     }
2122
2123     Reference ref = lexpr->evaluateReference(exec);
2124     KJS_CHECKEXCEPTION
2125     ref.putValue(exec, String(name.ustring()));
2126
2127     c = statement->execute(exec);
2128     if (c.isValueCompletion())
2129       retval = c.value();
2130
2131     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2132       if ((c.complType() == Break) && ls.contains(c.target()))
2133         break;
2134       if (c.complType() != Normal) {
2135         return c;
2136       }
2137     }
2138
2139     propIt++;
2140   }
2141
2142   // bail out on error
2143   KJS_CHECKEXCEPTION
2144
2145   return Completion(Normal, retval);
2146 }
2147
2148 void ForInNode::processVarDecls(ExecState *exec)
2149 {
2150   statement->processVarDecls(exec);
2151 }
2152
2153 // ------------------------------ ContinueNode ---------------------------------
2154
2155 // ECMA 12.7
2156 Completion ContinueNode::execute(ExecState *exec)
2157 {
2158   KJS_BREAKPOINT;
2159
2160   Value dummy;
2161   return exec->context().imp()->seenLabels()->contains(ident) ?
2162     Completion(Continue, dummy, ident) :
2163     Completion(Throw,
2164                throwError(exec, SyntaxError, "Label %s not found in containing block. Can't continue.", ident));
2165 }
2166
2167 // ------------------------------ BreakNode ------------------------------------
2168
2169 // ECMA 12.8
2170 Completion BreakNode::execute(ExecState *exec)
2171 {
2172   KJS_BREAKPOINT;
2173
2174   Value dummy;
2175   return exec->context().imp()->seenLabels()->contains(ident) ?
2176     Completion(Break, dummy, ident) :
2177     Completion(Throw,
2178                throwError(exec, SyntaxError, "Label %s not found in containing block. Can't break.", ident));
2179 }
2180
2181 // ------------------------------ ReturnNode -----------------------------------
2182
2183 void ReturnNode::ref()
2184 {
2185   Node::ref();
2186   if ( value )
2187     value->ref();
2188 }
2189
2190 bool ReturnNode::deref()
2191 {
2192   if ( value && value->deref() )
2193     delete value;
2194   return Node::deref();
2195 }
2196
2197 // ECMA 12.9
2198 Completion ReturnNode::execute(ExecState *exec)
2199 {
2200   KJS_BREAKPOINT;
2201
2202   if (!value)
2203     return Completion(ReturnValue, Undefined());
2204
2205   Value v = value->evaluate(exec);
2206   KJS_CHECKEXCEPTION
2207
2208   return Completion(ReturnValue, v);
2209 }
2210
2211 // ------------------------------ WithNode -------------------------------------
2212
2213 void WithNode::ref()
2214 {
2215   Node::ref();
2216   if ( statement )
2217     statement->ref();
2218   if ( expr )
2219     expr->ref();
2220 }
2221
2222 bool WithNode::deref()
2223 {
2224   if ( statement && statement->deref() )
2225     delete statement;
2226   if ( expr && expr->deref() )
2227     delete expr;
2228   return Node::deref();
2229 }
2230
2231 // ECMA 12.10
2232 Completion WithNode::execute(ExecState *exec)
2233 {
2234   KJS_BREAKPOINT;
2235
2236   Value v = expr->evaluate(exec);
2237   KJS_CHECKEXCEPTION
2238   Object o = v.toObject(exec);
2239   KJS_CHECKEXCEPTION
2240   exec->context().imp()->pushScope(o);
2241   Completion res = statement->execute(exec);
2242   exec->context().imp()->popScope();
2243
2244   return res;
2245 }
2246
2247 void WithNode::processVarDecls(ExecState *exec)
2248 {
2249   statement->processVarDecls(exec);
2250 }
2251
2252 // ------------------------------ CaseClauseNode -------------------------------
2253
2254 void CaseClauseNode::ref()
2255 {
2256   Node::ref();
2257   if ( expr )
2258     expr->ref();
2259   if ( list )
2260     list->ref();
2261 }
2262
2263 bool CaseClauseNode::deref()
2264 {
2265   if ( expr && expr->deref() )
2266     delete expr;
2267   if ( list && list->deref() )
2268     delete list;
2269   return Node::deref();
2270 }
2271
2272 // ECMA 12.11
2273 Value CaseClauseNode::evaluate(ExecState *exec)
2274 {
2275   Value v = expr->evaluate(exec);
2276   KJS_CHECKEXCEPTIONVALUE
2277
2278   return v;
2279 }
2280
2281 // ECMA 12.11
2282 Completion CaseClauseNode::evalStatements(ExecState *exec)
2283 {
2284   if (list)
2285     return list->execute(exec);
2286   else
2287     return Completion(Normal, Undefined());
2288 }
2289
2290 void CaseClauseNode::processVarDecls(ExecState *exec)
2291 {
2292   if (list)
2293     list->processVarDecls(exec);
2294 }
2295
2296 // ------------------------------ ClauseListNode -------------------------------
2297
2298 void ClauseListNode::ref()
2299 {
2300   for (ClauseListNode *n = this; n; n = n->nx) {
2301     n->Node::ref();
2302     if (n->cl)
2303       n->cl->ref();
2304   }
2305 }
2306
2307 bool ClauseListNode::deref()
2308 {
2309   ClauseListNode *next;
2310   for (ClauseListNode *n = this; n; n = next) {
2311     next = n->nx;
2312     if (n->cl && n->cl->deref())
2313       delete n->cl;
2314     if (n != this && n->Node::deref())
2315       delete n;
2316   }
2317   return Node::deref();
2318 }
2319
2320 Value ClauseListNode::evaluate(ExecState */*exec*/)
2321 {
2322   /* should never be called */
2323   assert(false);
2324   return Value();
2325 }
2326
2327 // ECMA 12.11
2328 void ClauseListNode::processVarDecls(ExecState *exec)
2329 {
2330   for (ClauseListNode *n = this; n; n = n->nx)
2331     if (n->cl)
2332       n->cl->processVarDecls(exec);
2333 }
2334
2335 // ------------------------------ CaseBlockNode --------------------------------
2336
2337 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
2338                              ClauseListNode *l2)
2339 {
2340   if (l1) {
2341     list1 = l1->nx;
2342     l1->nx = 0;
2343   } else {
2344     list1 = 0;
2345   }
2346
2347   def = d;
2348
2349   if (l2) {
2350     list2 = l2->nx;
2351     l2->nx = 0;
2352   } else {
2353     list2 = 0;
2354   }
2355 }
2356  
2357 void CaseBlockNode::ref()
2358 {
2359   Node::ref();
2360   if ( def )
2361     def->ref();
2362   if ( list1 )
2363     list1->ref();
2364   if ( list2 )
2365     list2->ref();
2366 }
2367
2368 bool CaseBlockNode::deref()
2369 {
2370   if ( def && def->deref() )
2371     delete def;
2372   if ( list1 && list1->deref() )
2373     delete list1;
2374   if ( list2 && list2->deref() )
2375     delete list2;
2376   return Node::deref();
2377 }
2378
2379 Value CaseBlockNode::evaluate(ExecState */*exec*/)
2380 {
2381   /* should never be called */
2382   assert(false);
2383   return Value();
2384 }
2385
2386 // ECMA 12.11
2387 Completion CaseBlockNode::evalBlock(ExecState *exec, const Value& input)
2388 {
2389   Value v;
2390   Completion res;
2391   ClauseListNode *a = list1, *b = list2;
2392   CaseClauseNode *clause;
2393
2394     while (a) {
2395       clause = a->clause();
2396       a = a->next();
2397       v = clause->evaluate(exec);
2398       KJS_CHECKEXCEPTION
2399       if (strictEqual(exec, input, v)) {
2400         res = clause->evalStatements(exec);
2401         if (res.complType() != Normal)
2402           return res;
2403         while (a) {
2404           res = a->clause()->evalStatements(exec);
2405           if (res.complType() != Normal)
2406             return res;
2407           a = a->next();
2408         }
2409         break;
2410       }
2411     }
2412
2413   while (b) {
2414     clause = b->clause();
2415     b = b->next();
2416     v = clause->evaluate(exec);
2417     KJS_CHECKEXCEPTION
2418     if (strictEqual(exec, input, v)) {
2419       res = clause->evalStatements(exec);
2420       if (res.complType() != Normal)
2421         return res;
2422       goto step18;
2423     }
2424   }
2425
2426   // default clause
2427   if (def) {
2428     res = def->evalStatements(exec);
2429     if (res.complType() != Normal)
2430       return res;
2431   }
2432   b = list2;
2433  step18:
2434   while (b) {
2435     clause = b->clause();
2436     res = clause->evalStatements(exec);
2437     if (res.complType() != Normal)
2438       return res;
2439     b = b->next();
2440   }
2441
2442   // bail out on error
2443   KJS_CHECKEXCEPTION
2444
2445   return Completion(Normal);
2446 }
2447
2448 void CaseBlockNode::processVarDecls(ExecState *exec)
2449 {
2450   if (list1)
2451     list1->processVarDecls(exec);
2452   if (def)
2453     def->processVarDecls(exec);
2454   if (list2)
2455     list2->processVarDecls(exec);
2456 }
2457
2458 // ------------------------------ SwitchNode -----------------------------------
2459
2460 void SwitchNode::ref()
2461 {
2462   Node::ref();
2463   if ( expr )
2464     expr->ref();
2465   if ( block )
2466     block->ref();
2467 }
2468
2469 bool SwitchNode::deref()
2470 {
2471   if ( expr && expr->deref() )
2472     delete expr;
2473   if ( block && block->deref() )
2474     delete block;
2475   return Node::deref();
2476 }
2477
2478 // ECMA 12.11
2479 Completion SwitchNode::execute(ExecState *exec)
2480 {
2481   KJS_BREAKPOINT;
2482
2483   Value v = expr->evaluate(exec);
2484   KJS_CHECKEXCEPTION
2485   Completion res = block->evalBlock(exec,v);
2486
2487   if ((res.complType() == Break) && ls.contains(res.target()))
2488     return Completion(Normal, res.value());
2489   return res;
2490 }
2491
2492 void SwitchNode::processVarDecls(ExecState *exec)
2493 {
2494   block->processVarDecls(exec);
2495 }
2496
2497 // ------------------------------ LabelNode ------------------------------------
2498
2499 void LabelNode::ref()
2500 {
2501   Node::ref();
2502   if ( statement )
2503     statement->ref();
2504 }
2505
2506 bool LabelNode::deref()
2507 {
2508   if ( statement && statement->deref() )
2509     delete statement;
2510   return Node::deref();
2511 }
2512
2513 // ECMA 12.12
2514 Completion LabelNode::execute(ExecState *exec)
2515 {
2516   Completion e;
2517
2518   if (!exec->context().imp()->seenLabels()->push(label)) {
2519     return Completion( Throw,
2520                        throwError(exec, SyntaxError, "Duplicated label %s found.", label));
2521   };
2522   e = statement->execute(exec);
2523   exec->context().imp()->seenLabels()->pop();
2524
2525   if ((e.complType() == Break) && (e.target() == label))
2526     return Completion(Normal, e.value());
2527   return e;
2528 }
2529
2530 void LabelNode::processVarDecls(ExecState *exec)
2531 {
2532   statement->processVarDecls(exec);
2533 }
2534
2535 // ------------------------------ ThrowNode ------------------------------------
2536
2537 void ThrowNode::ref()
2538 {
2539   Node::ref();
2540   if ( expr )
2541     expr->ref();
2542 }
2543
2544 bool ThrowNode::deref()
2545 {
2546   if ( expr && expr->deref() )
2547     delete expr;
2548   return Node::deref();
2549 }
2550
2551 // ECMA 12.13
2552 Completion ThrowNode::execute(ExecState *exec)
2553 {
2554   KJS_BREAKPOINT;
2555
2556   Value v = expr->evaluate(exec);
2557   KJS_CHECKEXCEPTION
2558
2559   // bail out on error
2560   KJS_CHECKEXCEPTION
2561
2562   return Completion(Throw, v);
2563 }
2564
2565 // ------------------------------ CatchNode ------------------------------------
2566
2567 void CatchNode::ref()
2568 {
2569   Node::ref();
2570   if ( block )
2571     block->ref();
2572 }
2573
2574 bool CatchNode::deref()
2575 {
2576   if ( block && block->deref() )
2577     delete block;
2578   return Node::deref();
2579 }
2580
2581 Completion CatchNode::execute(ExecState */*exec*/)
2582 {
2583   // should never be reached. execute(exec, arg) is used instead
2584   assert(0L);
2585   return Completion();
2586 }
2587
2588 // ECMA 12.14
2589 Completion CatchNode::execute(ExecState *exec, const Value &arg)
2590 {
2591   /* TODO: correct ? Not part of the spec */
2592
2593   exec->clearException();
2594
2595   Object obj(new ObjectImp());
2596   obj.put(exec, ident, arg, DontDelete);
2597   exec->context().imp()->pushScope(obj);
2598   Completion c = block->execute(exec);
2599   exec->context().imp()->popScope();
2600
2601   return c;
2602 }
2603
2604 void CatchNode::processVarDecls(ExecState *exec)
2605 {
2606   block->processVarDecls(exec);
2607 }
2608
2609 // ------------------------------ FinallyNode ----------------------------------
2610
2611 void FinallyNode::ref()
2612 {
2613   Node::ref();
2614   if ( block )
2615     block->ref();
2616 }
2617
2618 bool FinallyNode::deref()
2619 {
2620   if ( block && block->deref() )
2621     delete block;
2622   return Node::deref();
2623 }
2624
2625 // ECMA 12.14
2626 Completion FinallyNode::execute(ExecState *exec)
2627 {
2628   return block->execute(exec);
2629 }
2630
2631 void FinallyNode::processVarDecls(ExecState *exec)
2632 {
2633   block->processVarDecls(exec);
2634 }
2635
2636 // ------------------------------ TryNode --------------------------------------
2637
2638 void TryNode::ref()
2639 {
2640   Node::ref();
2641   if ( block )
2642     block->ref();
2643   if ( _final )
2644     _final->ref();
2645   if ( _catch )
2646     _catch->ref();
2647 }
2648
2649 bool TryNode::deref()
2650 {
2651   if ( block && block->deref() )
2652     delete block;
2653   if ( _final && _final->deref() )
2654     delete _final;
2655   if ( _catch && _catch->deref() )
2656     delete _catch;
2657   return Node::deref();
2658 }
2659
2660 // ECMA 12.14
2661 Completion TryNode::execute(ExecState *exec)
2662 {
2663   KJS_BREAKPOINT;
2664
2665   Completion c, c2;
2666
2667   c = block->execute(exec);
2668
2669   if (!_final) {
2670     if (c.complType() != Throw)
2671       return c;
2672     return _catch->execute(exec,c.value());
2673   }
2674
2675   if (!_catch) {
2676     c2 = _final->execute(exec);
2677     return (c2.complType() == Normal) ? c : c2;
2678   }
2679
2680   if (c.complType() == Throw)
2681     c = _catch->execute(exec,c.value());
2682
2683   c2 = _final->execute(exec);
2684   return (c2.complType() == Normal) ? c : c2;
2685 }
2686
2687 void TryNode::processVarDecls(ExecState *exec)
2688 {
2689   block->processVarDecls(exec);
2690   if (_final)
2691     _final->processVarDecls(exec);
2692   if (_catch)
2693     _catch->processVarDecls(exec);
2694 }
2695
2696 // ------------------------------ ParameterNode --------------------------------
2697
2698 void ParameterNode::ref()
2699 {
2700   for (ParameterNode *n = this; n; n = n->next)
2701     n->Node::ref();
2702 }
2703
2704 bool ParameterNode::deref()
2705 {
2706   ParameterNode *next;
2707   for (ParameterNode *n = this; n; n = next) {
2708     next = n->next;
2709     if (n != this && n->Node::deref())
2710       delete n;
2711   }
2712   return Node::deref();
2713 }
2714
2715 // ECMA 13
2716 Value ParameterNode::evaluate(ExecState */*exec*/)
2717 {
2718   return Undefined();
2719 }
2720
2721 // ------------------------------ FunctionBodyNode -----------------------------
2722
2723 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
2724   : BlockNode(s)
2725 {
2726   setLoc(-1, -1, -1);
2727   //fprintf(stderr,"FunctionBodyNode::FunctionBodyNode %p\n",this);
2728 }
2729
2730 void FunctionBodyNode::processFuncDecl(ExecState *exec)
2731 {
2732   if (source)
2733     source->processFuncDecl(exec);
2734 }
2735
2736 // ------------------------------ FuncDeclNode ---------------------------------
2737
2738 void FuncDeclNode::ref()
2739 {
2740   Node::ref();
2741   if ( param )
2742     param->ref();
2743   if ( body )
2744     body->ref();
2745 }
2746
2747 bool FuncDeclNode::deref()
2748 {
2749   if ( param && param->deref() )
2750     delete param;
2751   if ( body && body->deref() )
2752     delete body;
2753   return Node::deref();
2754 }
2755
2756 // ECMA 13
2757 void FuncDeclNode::processFuncDecl(ExecState *exec)
2758 {
2759   // TODO: let this be an object with [[Class]] property "Function"
2760   FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, exec->context().imp()->scopeChain());
2761   Object func(fimp); // protect from GC
2762
2763   //  Value proto = exec->lexicalInterpreter()->builtinObject().construct(exec,List::empty());
2764   List empty;
2765   Object proto = exec->lexicalInterpreter()->builtinObject().construct(exec,empty);
2766   proto.put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum);
2767   func.put(exec, prototypePropertyName, proto, Internal|DontDelete);
2768
2769   int plen = 0;
2770   for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
2771     fimp->addParameter(p->ident());
2772
2773   func.put(exec, lengthPropertyName, Number(plen), ReadOnly|DontDelete|DontEnum);
2774
2775   exec->context().imp()->variableObject().put(exec,ident,func);
2776
2777   if (body) {
2778     // hack the scope so that the function gets put as a property of func, and it's scope
2779     // contains the func as well as our current scope
2780     Object oldVar = exec->context().imp()->variableObject();
2781     exec->context().imp()->setVariableObject(func);
2782     exec->context().imp()->pushScope(func);
2783     body->processFuncDecl(exec);
2784     exec->context().imp()->popScope();
2785     exec->context().imp()->setVariableObject(oldVar);
2786   }
2787 }
2788
2789 // ------------------------------ FuncExprNode ---------------------------------
2790
2791 void FuncExprNode::ref()
2792 {
2793   Node::ref();
2794   if ( param )
2795     param->ref();
2796   if ( body )
2797     body->ref();
2798 }
2799
2800 bool FuncExprNode::deref()
2801 {
2802   if ( param && param->deref() )
2803     delete param;
2804   if ( body && body->deref() )
2805     delete body;
2806   return Node::deref();
2807 }
2808
2809
2810 // ECMA 13
2811 Value FuncExprNode::evaluate(ExecState *exec)
2812 {
2813   FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body, exec->context().imp()->scopeChain());
2814   Value ret(fimp);
2815   List empty;
2816   Value proto = exec->lexicalInterpreter()->builtinObject().construct(exec,empty);
2817   fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
2818
2819   int plen = 0;
2820   for(ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
2821     fimp->addParameter(p->ident());
2822
2823   return ret;
2824 }
2825
2826 // ------------------------------ SourceElementsNode ---------------------------
2827
2828 SourceElementsNode::SourceElementsNode(StatementNode *s1)
2829   : element(s1), elements(this)
2830 {
2831   setLoc(s1->firstLine(), s1->lastLine(), s1->sourceId());
2832 }
2833  
2834 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
2835   : element(s2), elements(s1->elements)
2836 {
2837   s1->elements = this;
2838   setLoc(s1->firstLine(), s2->lastLine(), s1->sourceId());
2839 }
2840
2841 void SourceElementsNode::ref()
2842 {
2843   for (SourceElementsNode *n = this; n; n = n->elements) {
2844     n->Node::ref();
2845     if (n->element)
2846       n->element->ref();
2847   }
2848 }
2849
2850 bool SourceElementsNode::deref()
2851 {
2852   SourceElementsNode *next;
2853   for (SourceElementsNode *n = this; n; n = next) {
2854     next = n->elements;
2855     if (n->element && n->element->deref())
2856       delete n->element;
2857     if (n != this && n->Node::deref())
2858       delete n;
2859   }
2860   return Node::deref();
2861 }
2862
2863 // ECMA 14
2864 Completion SourceElementsNode::execute(ExecState *exec)
2865 {
2866   KJS_CHECKEXCEPTION
2867
2868   Completion c1 = element->execute(exec);
2869   KJS_CHECKEXCEPTION;
2870   if (c1.complType() != Normal)
2871     return c1;
2872   
2873   for (SourceElementsNode *n = elements; n; n = n->elements) {
2874     Completion c2 = n->element->execute(exec);
2875     if (c2.complType() != Normal)
2876       return c2;
2877     // The spec says to return c2 here, but it seems that mozilla returns c1 if
2878     // c2 doesn't have a value
2879     if (!c2.value().isNull())
2880       c1 = c2;
2881   }
2882   
2883   return c1;
2884 }
2885
2886 // ECMA 14
2887 void SourceElementsNode::processFuncDecl(ExecState *exec)
2888 {
2889   for (SourceElementsNode *n = this; n; n = n->elements)
2890     n->element->processFuncDecl(exec);
2891 }
2892
2893 void SourceElementsNode::processVarDecls(ExecState *exec)
2894 {
2895   for (SourceElementsNode *n = this; n; n = n->elements)
2896     n->element->processVarDecls(exec);
2897 }
2898
2899 ProgramNode::ProgramNode(SourceElementsNode *s): FunctionBodyNode(s) {
2900     //fprintf(stderr,"ProgramNode::ProgramNode %p\n",this);
2901 }