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