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