Reviewed by Maciej.
[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  *  Copyright (C) 2007 Maks Orlovich
7  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Library General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Library General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Library General Public License
20  *  along with this library; see the file COPYING.LIB.  If not, write to
21  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301, USA.
23  *
24  */
25
26 #include "config.h"
27 #include "nodes.h"
28
29 #include "ExecState.h"
30 #include "JSGlobalObject.h"
31 #include "Parser.h"
32 #include "PropertyNameArray.h"
33 #include "array_object.h"
34 #include "debugger.h"
35 #include "function_object.h"
36 #include "lexer.h"
37 #include "operations.h"
38 #include "regexp_object.h"
39 #include <math.h>
40 #include <wtf/Assertions.h>
41 #include <wtf/HashCountedSet.h>
42 #include <wtf/HashSet.h>
43 #include <wtf/MathExtras.h>
44
45 namespace KJS {
46
47 #define KJS_BREAKPOINT \
48   if (Debugger::debuggersPresent > 0 && !hitStatement(exec)) \
49     return Completion(Normal);
50
51 #define KJS_CHECKEXCEPTION \
52   if (exec->hadException()) \
53     return rethrowException(exec);
54
55 #define KJS_CHECKEXCEPTIONVALUE \
56   if (exec->hadException()) { \
57     handleException(exec); \
58     return jsUndefined(); \
59   }
60
61 #define KJS_CHECKEXCEPTIONNUMBER \
62   if (exec->hadException()) { \
63     handleException(exec); \
64     return 0; \
65   }
66
67 #define KJS_CHECKEXCEPTIONBOOLEAN \
68   if (exec->hadException()) { \
69     handleException(exec); \
70     return false; \
71   }
72
73 #define KJS_CHECKEXCEPTIONLIST \
74   if (exec->hadException()) { \
75     handleException(exec); \
76     return; \
77   }
78
79 #define KJS_CHECKEXCEPTIONVOID \
80   if (exec->hadException()) { \
81     handleException(exec); \
82     return; \
83   }
84
85 #if !ASSERT_DISABLED
86 static inline bool canSkipLookup(ExecState* exec, const Identifier& ident)
87 {
88     // Static lookup in EvalCode is impossible because variables aren't DontDelete. 
89     // Static lookup in GlobalCode may be possible, but we haven't implemented support for it yet.
90     if (exec->codeType() != FunctionCode)
91         return false;
92
93     // Static lookup is impossible when something dynamic has been added to the front of the scope chain.
94     if (exec->variableObject() != exec->scopeChain().top())
95         return false;
96
97     // Static lookup is impossible if the symbol isn't statically declared.
98     if (!exec->variableObject()->symbolTable().contains(ident.ustring().rep()))
99         return false;
100         
101     return true;
102 }
103 #endif
104
105 // ------------------------------ Node -----------------------------------------
106
107 #ifndef NDEBUG
108 #ifndef LOG_CHANNEL_PREFIX
109 #define LOG_CHANNEL_PREFIX Log
110 #endif
111 static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn };
112
113 struct NodeCounter { 
114     static unsigned count; 
115     ~NodeCounter() 
116     { 
117         if (count) 
118             LOG(KJSNodeLeaks, "LEAK: %u KJS::Node\n", count); 
119     }
120 };
121 unsigned NodeCounter::count = 0;
122 static NodeCounter nodeCounter;
123 #endif
124
125 static HashSet<Node*>* newNodes;
126 static HashCountedSet<Node*>* nodeExtraRefCounts;
127
128 Node::Node()
129     : m_mayHaveDeclarations(false)
130     , m_expectedReturnType(ObjectType)
131 {
132 #ifndef NDEBUG
133     ++NodeCounter::count;
134 #endif
135   m_line = lexer().lineNo();
136   if (!newNodes)
137       newNodes = new HashSet<Node*>;
138   newNodes->add(this);
139 }
140
141 Node::Node(JSType expectedReturn)
142     : m_mayHaveDeclarations(false)
143     , m_expectedReturnType(expectedReturn)
144 {
145 #ifndef NDEBUG
146     ++NodeCounter::count;
147 #endif
148     m_line = lexer().lineNo();
149     if (!newNodes)
150         newNodes = new HashSet<Node*>;
151     newNodes->add(this);
152 }
153
154 Node::~Node()
155 {
156 #ifndef NDEBUG
157     --NodeCounter::count;
158 #endif
159 }
160
161 void Node::ref()
162 {
163     // bumping from 0 to 1 is just removing from the new nodes set
164     if (newNodes) {
165         HashSet<Node*>::iterator it = newNodes->find(this);
166         if (it != newNodes->end()) {
167             newNodes->remove(it);
168             ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
169             return;
170         }
171     }   
172
173     ASSERT(!newNodes || !newNodes->contains(this));
174     
175     if (!nodeExtraRefCounts)
176         nodeExtraRefCounts = new HashCountedSet<Node*>;
177     nodeExtraRefCounts->add(this);
178 }
179
180 void Node::deref()
181 {
182     ASSERT(!newNodes || !newNodes->contains(this));
183     
184     if (!nodeExtraRefCounts) {
185         delete this;
186         return;
187     }
188
189     HashCountedSet<Node*>::iterator it = nodeExtraRefCounts->find(this);
190     if (it == nodeExtraRefCounts->end())
191         delete this;
192     else
193         nodeExtraRefCounts->remove(it);
194 }
195
196 unsigned Node::refcount()
197 {
198     if (newNodes && newNodes->contains(this)) {
199         ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
200         return 0;
201     }
202  
203     ASSERT(!newNodes || !newNodes->contains(this));
204
205     if (!nodeExtraRefCounts)
206         return 1;
207
208     return 1 + nodeExtraRefCounts->count(this);
209 }
210
211 void Node::clearNewNodes()
212 {
213     if (!newNodes)
214         return;
215
216 #ifndef NDEBUG
217     HashSet<Node*>::iterator end = newNodes->end();
218     for (HashSet<Node*>::iterator it = newNodes->begin(); it != end; ++it)
219         ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));
220 #endif
221     deleteAllValues(*newNodes);
222     delete newNodes;
223     newNodes = 0;
224 }
225
226 double ExpressionNode::evaluateToNumber(ExecState* exec)
227 {
228     JSValue* value = evaluate(exec);
229     KJS_CHECKEXCEPTIONNUMBER
230     return value->toNumber(exec);
231 }
232
233 bool ExpressionNode::evaluateToBoolean(ExecState* exec)
234 {
235     JSValue* value = evaluate(exec);
236     KJS_CHECKEXCEPTIONBOOLEAN
237     return value->toBoolean(exec);
238 }
239
240 int32_t ExpressionNode::evaluateToInt32(ExecState* exec)
241 {
242     JSValue* value = evaluate(exec);
243     KJS_CHECKEXCEPTIONNUMBER
244     return value->toInt32(exec);
245 }
246
247 uint32_t ExpressionNode::evaluateToUInt32(ExecState* exec)
248 {
249     JSValue* value = evaluate(exec);
250     KJS_CHECKEXCEPTIONNUMBER
251     return value->toUInt32(exec);
252 }
253
254 static void substitute(UString &string, const UString &substring) KJS_FAST_CALL;
255 static void substitute(UString &string, const UString &substring)
256 {
257     int position = string.find("%s");
258     ASSERT(position != -1);
259     UString newString = string.substr(0, position);
260     newString.append(substring);
261     newString.append(string.substr(position + 2));
262     string = newString;
263 }
264
265 static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
266 static inline int currentSourceId(ExecState* exec)
267 {
268     return exec->currentBody()->sourceId();
269 }
270
271 static inline const UString& currentSourceURL(ExecState* exec) KJS_FAST_CALL;
272 static inline const UString& currentSourceURL(ExecState* exec)
273 {
274     return exec->currentBody()->sourceURL();
275 }
276
277 Completion Node::createErrorCompletion(ExecState* exec, ErrorType e, const char *msg)
278 {
279     return Completion(Throw, Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
280 }
281
282 Completion Node::createErrorCompletion(ExecState *exec, ErrorType e, const char *msg, const Identifier &ident)
283 {
284     UString message = msg;
285     substitute(message, ident.ustring());
286     return Completion(Throw, Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
287 }
288
289 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char *msg)
290 {
291     return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
292 }
293
294 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char* msg, const char* string)
295 {
296     UString message = msg;
297     substitute(message, string);
298     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
299 }
300
301 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *expr)
302 {
303     UString message = msg;
304     substitute(message, v->toString(exec));
305     substitute(message, expr->toString());
306     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
307 }
308
309
310 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, const Identifier &label)
311 {
312     UString message = msg;
313     substitute(message, label.ustring());
314     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
315 }
316
317 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *e1, Node *e2)
318 {
319     UString message = msg;
320     substitute(message, v->toString(exec));
321     substitute(message, e1->toString());
322     substitute(message, e2->toString());
323     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
324 }
325
326 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, Node *expr, const Identifier &label)
327 {
328     UString message = msg;
329     substitute(message, v->toString(exec));
330     substitute(message, expr->toString());
331     substitute(message, label.ustring());
332     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
333 }
334
335 JSValue *Node::throwError(ExecState *exec, ErrorType e, const char *msg, JSValue *v, const Identifier &label)
336 {
337     UString message = msg;
338     substitute(message, v->toString(exec));
339     substitute(message, label.ustring());
340     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
341 }
342
343 JSValue *Node::throwUndefinedVariableError(ExecState *exec, const Identifier &ident)
344 {
345     return throwError(exec, ReferenceError, "Can't find variable: %s", ident);
346 }
347
348 void Node::handleException(ExecState* exec)
349 {
350     handleException(exec, exec->exception());
351 }
352
353 void Node::handleException(ExecState* exec, JSValue* exceptionValue)
354 {
355     if (exceptionValue->isObject()) {
356         JSObject* exception = static_cast<JSObject*>(exceptionValue);
357         if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) {
358             exception->put(exec, "line", jsNumber(m_line));
359             exception->put(exec, "sourceURL", jsString(currentSourceURL(exec)));
360         }
361     }
362     Debugger* dbg = exec->dynamicGlobalObject()->debugger();
363     if (dbg && !dbg->hasHandledException(exec, exceptionValue)) {
364         bool cont = dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);
365         if (!cont)
366             dbg->imp()->abort();
367     }
368 }
369
370 Completion Node::rethrowException(ExecState* exec)
371 {
372     JSValue* exception = exec->exception();
373     exec->clearException();
374     handleException(exec, exception);
375     return Completion(Throw, exception);
376 }
377
378 // ------------------------------ StatementNode --------------------------------
379
380 StatementNode::StatementNode() 
381     : m_lastLine(-1)
382 {
383     m_line = -1;
384 }
385
386 void StatementNode::setLoc(int firstLine, int lastLine)
387 {
388     m_line = firstLine;
389     m_lastLine = lastLine;
390 }
391
392 // return true if the debugger wants us to stop at this point
393 bool StatementNode::hitStatement(ExecState* exec)
394 {
395   Debugger *dbg = exec->dynamicGlobalObject()->debugger();
396   if (dbg)
397     return dbg->atStatement(exec, currentSourceId(exec), firstLine(), lastLine());
398   else
399     return true; // continue
400 }
401
402 // ------------------------------ NullNode -------------------------------------
403
404 JSValue *NullNode::evaluate(ExecState *)
405 {
406   return jsNull();
407 }
408
409 // ------------------------------ FalseNode ----------------------------------
410
411 JSValue* FalseNode::evaluate(ExecState*)
412 {
413     return jsBoolean(false);
414 }
415
416 // ------------------------------ TrueNode ----------------------------------
417
418 JSValue* TrueNode::evaluate(ExecState*)
419 {
420     return jsBoolean(true);
421 }
422
423 // ------------------------------ NumberNode -----------------------------------
424
425 JSValue* NumberNode::evaluate(ExecState*)
426 {
427     // Number nodes are only created when the number can't fit in a JSImmediate, so no need to check again.
428     return jsNumberCell(m_double);
429 }
430     
431 double NumberNode::evaluateToNumber(ExecState*)
432 {
433     return m_double;
434 }
435
436 bool NumberNode::evaluateToBoolean(ExecState*)
437 {
438     return m_double < 0.0 || m_double > 0.0; // false for NaN as well as 0
439 }
440
441 int32_t NumberNode::evaluateToInt32(ExecState*)
442 {
443     return JSValue::toInt32(m_double);
444 }
445
446 uint32_t NumberNode::evaluateToUInt32(ExecState*)
447 {
448     return JSValue::toUInt32(m_double);
449 }
450
451 // ------------------------------ ImmediateNumberNode -----------------------------------
452
453 JSValue* ImmediateNumberNode::evaluate(ExecState*)
454 {
455     return m_value;
456 }
457
458 int32_t ImmediateNumberNode::evaluateToInt32(ExecState*)
459 {
460     return JSImmediate::getTruncatedInt32(m_value);
461 }
462
463 uint32_t ImmediateNumberNode::evaluateToUInt32(ExecState*)
464 {
465     uint32_t i;
466     if (JSImmediate::getTruncatedUInt32(m_value, i))
467         return i;
468     bool ok;
469     return JSValue::toUInt32SlowCase(m_double, ok);
470 }
471
472 // ------------------------------ StringNode -----------------------------------
473
474 JSValue* StringNode::evaluate(ExecState*)
475 {
476   return jsOwnedString(m_value);
477 }
478
479 double StringNode::evaluateToNumber(ExecState*)
480 {
481     return m_value.toDouble();
482 }
483
484 bool StringNode::evaluateToBoolean(ExecState*)
485 {
486     return !m_value.isEmpty();
487 }
488     
489 // ------------------------------ RegExpNode -----------------------------------
490
491 JSValue* RegExpNode::evaluate(ExecState* exec)
492 {
493     return exec->lexicalGlobalObject()->regExpConstructor()->createRegExpImp(exec, m_regExp);
494 }
495
496 // ------------------------------ ThisNode -------------------------------------
497
498 // ECMA 11.1.1
499 JSValue *ThisNode::evaluate(ExecState *exec)
500 {
501   return exec->thisValue();
502 }
503
504 // ------------------------------ ResolveNode ----------------------------------
505
506 // ECMA 11.1.2 & 10.1.4
507 JSValue* ResolveNode::inlineEvaluate(ExecState* exec)
508 {
509   // Check for missed optimization opportunity.
510   ASSERT(!canSkipLookup(exec, ident));
511
512   const ScopeChain& chain = exec->scopeChain();
513   ScopeChainIterator iter = chain.begin();
514   ScopeChainIterator end = chain.end();
515   
516   // we must always have something in the scope chain
517   ASSERT(iter != end);
518
519   PropertySlot slot;
520   do { 
521     JSObject *o = *iter;
522
523     if (o->getPropertySlot(exec, ident, slot))
524       return slot.getValue(exec, o, ident);
525     
526     ++iter;
527   } while (iter != end);
528
529   return throwUndefinedVariableError(exec, ident);
530 }
531
532 JSValue* ResolveNode::evaluate(ExecState* exec)
533 {
534     return inlineEvaluate(exec);
535 }
536
537 double ResolveNode::evaluateToNumber(ExecState* exec)
538 {
539     JSValue* v = inlineEvaluate(exec);
540     KJS_CHECKEXCEPTIONNUMBER
541     return v->toNumber(exec);
542 }
543
544 bool ResolveNode::evaluateToBoolean(ExecState* exec)
545 {
546     JSValue* v = inlineEvaluate(exec);
547     KJS_CHECKEXCEPTIONBOOLEAN
548     return v->toBoolean(exec);
549 }
550
551 int32_t ResolveNode::evaluateToInt32(ExecState* exec)
552 {
553     JSValue* v = inlineEvaluate(exec);
554     KJS_CHECKEXCEPTIONNUMBER
555     return v->toInt32(exec);
556 }
557
558 uint32_t ResolveNode::evaluateToUInt32(ExecState* exec)
559 {
560     JSValue* v = inlineEvaluate(exec);
561     KJS_CHECKEXCEPTIONNUMBER
562     return v->toUInt32(exec);
563 }
564
565 void ResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
566 {
567     size_t index = symbolTable.get(ident.ustring().rep());
568     if (index != missingSymbolMarker())
569         new (this) LocalVarAccessNode(index);
570 }
571
572 JSValue* LocalVarAccessNode::inlineEvaluate(ExecState* exec)
573 {
574     ASSERT(exec->variableObject() == exec->scopeChain().top());
575     return exec->localStorage()[index].value;
576 }
577
578 JSValue* LocalVarAccessNode::evaluate(ExecState* exec)
579 {
580     return inlineEvaluate(exec);
581 }
582
583 double LocalVarAccessNode::evaluateToNumber(ExecState* exec)
584 {
585     return inlineEvaluate(exec)->toNumber(exec);
586 }
587
588 bool LocalVarAccessNode::evaluateToBoolean(ExecState* exec)
589 {
590     return inlineEvaluate(exec)->toBoolean(exec);
591 }
592
593 int32_t LocalVarAccessNode::evaluateToInt32(ExecState* exec)
594 {
595     return inlineEvaluate(exec)->toInt32(exec);
596 }
597
598 uint32_t LocalVarAccessNode::evaluateToUInt32(ExecState* exec)
599 {
600     return inlineEvaluate(exec)->toUInt32(exec);
601 }
602
603 // ------------------------------ ElementNode ----------------------------------
604
605 void ElementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
606 {
607     if (next)
608         nodeStack.append(next.get());
609     ASSERT(node);
610     nodeStack.append(node.get());
611 }
612
613 // ECMA 11.1.4
614 JSValue *ElementNode::evaluate(ExecState *exec)
615 {
616   JSObject *array = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, List::empty());
617   int length = 0;
618   for (ElementNode *n = this; n; n = n->next.get()) {
619     JSValue *val = n->node->evaluate(exec);
620     KJS_CHECKEXCEPTIONVALUE
621     length += n->elision;
622     array->put(exec, length++, val);
623   }
624   return array;
625 }
626
627 // ------------------------------ ArrayNode ------------------------------------
628
629 void ArrayNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
630 {
631     if (element)
632         nodeStack.append(element.get());
633 }
634
635
636 // ECMA 11.1.4
637 JSValue *ArrayNode::evaluate(ExecState *exec)
638 {
639   JSObject *array;
640   int length;
641
642   if (element) {
643     array = static_cast<JSObject*>(element->evaluate(exec));
644     KJS_CHECKEXCEPTIONVALUE
645     length = opt ? array->get(exec, exec->propertyNames().length)->toInt32(exec) : 0;
646   } else {
647     JSValue *newArr = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec,List::empty());
648     array = static_cast<JSObject*>(newArr);
649     length = 0;
650   }
651
652   if (opt)
653     array->put(exec, exec->propertyNames().length, jsNumber(elision + length), DontEnum | DontDelete);
654
655   return array;
656 }
657
658 // ------------------------------ ObjectLiteralNode ----------------------------
659
660 void ObjectLiteralNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
661 {
662     if (list)
663         nodeStack.append(list.get());
664 }
665
666 // ECMA 11.1.5
667 JSValue *ObjectLiteralNode::evaluate(ExecState *exec)
668 {
669   if (list)
670     return list->evaluate(exec);
671
672   return exec->lexicalGlobalObject()->objectConstructor()->construct(exec,List::empty());
673 }
674
675 // ------------------------------ PropertyListNode -----------------------------
676
677 void PropertyListNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
678 {
679     if (next)
680         nodeStack.append(next.get());
681     nodeStack.append(node.get());
682 }
683
684 // ECMA 11.1.5
685 JSValue *PropertyListNode::evaluate(ExecState *exec)
686 {
687   JSObject *obj = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, List::empty());
688   
689   for (PropertyListNode *p = this; p; p = p->next.get()) {
690     JSValue *v = p->node->assign->evaluate(exec);
691     KJS_CHECKEXCEPTIONVALUE
692     
693     switch (p->node->type) {
694       case PropertyNode::Getter:
695         ASSERT(v->isObject());
696         obj->defineGetter(exec, p->node->name(), static_cast<JSObject *>(v));
697         break;
698       case PropertyNode::Setter:
699         ASSERT(v->isObject());
700         obj->defineSetter(exec, p->node->name(), static_cast<JSObject *>(v));
701         break;
702       case PropertyNode::Constant:
703         obj->put(exec, p->node->name(), v);
704         break;
705     }
706   }
707
708   return obj;
709 }
710
711 // ------------------------------ PropertyNode -----------------------------
712
713 void PropertyNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
714 {
715     nodeStack.append(assign.get());
716 }
717
718 // ECMA 11.1.5
719 JSValue *PropertyNode::evaluate(ExecState*)
720 {
721   ASSERT(false);
722   return jsNull();
723 }
724
725 // ------------------------------ BracketAccessorNode --------------------------------
726
727 void BracketAccessorNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
728 {
729     nodeStack.append(expr2.get());
730     nodeStack.append(expr1.get());
731 }
732
733 // ECMA 11.2.1a
734 JSValue* BracketAccessorNode::inlineEvaluate(ExecState* exec)
735 {
736   JSValue* v1 = expr1->evaluate(exec);
737   KJS_CHECKEXCEPTIONVALUE
738   JSValue* v2 = expr2->evaluate(exec);
739   KJS_CHECKEXCEPTIONVALUE
740   JSObject* o = v1->toObject(exec);
741   uint32_t i;
742   if (v2->getUInt32(i))
743     return o->get(exec, i);
744   return o->get(exec, Identifier(v2->toString(exec)));
745 }
746
747 JSValue* BracketAccessorNode::evaluate(ExecState* exec)
748 {
749     return inlineEvaluate(exec);
750 }
751
752 double BracketAccessorNode::evaluateToNumber(ExecState* exec)
753 {
754     JSValue* v = inlineEvaluate(exec);
755     KJS_CHECKEXCEPTIONNUMBER
756     return v->toNumber(exec);
757 }
758
759 bool BracketAccessorNode::evaluateToBoolean(ExecState* exec)
760 {
761     JSValue* v = inlineEvaluate(exec);
762     KJS_CHECKEXCEPTIONBOOLEAN
763     return v->toBoolean(exec);
764 }
765
766 int32_t BracketAccessorNode::evaluateToInt32(ExecState* exec)
767 {
768     JSValue* v = inlineEvaluate(exec);
769     KJS_CHECKEXCEPTIONNUMBER
770     return v->toInt32(exec);
771 }
772
773 uint32_t BracketAccessorNode::evaluateToUInt32(ExecState* exec)
774 {
775     JSValue* v = inlineEvaluate(exec);
776     KJS_CHECKEXCEPTIONNUMBER
777     return v->toUInt32(exec);
778 }    
779
780 // ------------------------------ DotAccessorNode --------------------------------
781
782 void DotAccessorNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
783 {
784     nodeStack.append(expr.get());
785 }
786
787 // ECMA 11.2.1b
788 JSValue* DotAccessorNode::inlineEvaluate(ExecState* exec)
789 {
790     JSValue* v = expr->evaluate(exec);
791     KJS_CHECKEXCEPTIONVALUE
792     return v->toObject(exec)->get(exec, ident);
793 }
794
795 JSValue* DotAccessorNode::evaluate(ExecState* exec)
796 {
797     return inlineEvaluate(exec);
798 }
799
800 double DotAccessorNode::evaluateToNumber(ExecState* exec)
801 {
802     JSValue* v = inlineEvaluate(exec);
803     KJS_CHECKEXCEPTIONNUMBER
804     return v->toNumber(exec);
805 }
806
807 bool DotAccessorNode::evaluateToBoolean(ExecState* exec)
808 {
809     JSValue* v = inlineEvaluate(exec);
810     KJS_CHECKEXCEPTIONBOOLEAN
811     return v->toBoolean(exec);
812 }
813
814 int32_t DotAccessorNode::evaluateToInt32(ExecState* exec)
815 {
816     JSValue* v = inlineEvaluate(exec);
817     KJS_CHECKEXCEPTIONNUMBER
818     return v->toInt32(exec);
819 }
820
821 uint32_t DotAccessorNode::evaluateToUInt32(ExecState* exec)
822 {
823     JSValue* v = inlineEvaluate(exec);
824     KJS_CHECKEXCEPTIONNUMBER
825     return v->toUInt32(exec);
826 }    
827
828 // ------------------------------ ArgumentListNode -----------------------------
829
830 void ArgumentListNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
831 {
832     if (next)
833         nodeStack.append(next.get());
834     ASSERT(expr);
835     nodeStack.append(expr.get());
836 }
837
838 // ECMA 11.2.4
839 void ArgumentListNode::evaluateList(ExecState* exec, List& list)
840 {
841   for (ArgumentListNode *n = this; n; n = n->next.get()) {
842     JSValue *v = n->expr->evaluate(exec);
843     KJS_CHECKEXCEPTIONLIST
844     list.append(v);
845   }
846 }
847
848 // ------------------------------ ArgumentsNode --------------------------------
849
850 void ArgumentsNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
851 {
852     if (listNode)
853         nodeStack.append(listNode.get());
854 }
855
856 // ------------------------------ NewExprNode ----------------------------------
857
858 void NewExprNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
859 {
860     if (args)
861         nodeStack.append(args.get());
862     nodeStack.append(expr.get());
863 }
864
865 // ECMA 11.2.2
866
867 JSValue* NewExprNode::inlineEvaluate(ExecState* exec)
868 {
869   JSValue* v = expr->evaluate(exec);
870   KJS_CHECKEXCEPTIONVALUE
871
872   List argList;
873   if (args) {
874     args->evaluateList(exec, argList);
875     KJS_CHECKEXCEPTIONVALUE
876   }
877
878   if (!v->isObject())
879     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr.get());
880
881   JSObject *constr = static_cast<JSObject*>(v);
882   if (!constr->implementsConstruct())
883     return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr.get());
884
885   return constr->construct(exec, argList);
886 }
887
888 JSValue* NewExprNode::evaluate(ExecState* exec)
889 {
890     return inlineEvaluate(exec);
891 }
892
893 double NewExprNode::evaluateToNumber(ExecState* exec)
894 {
895     JSValue* v = inlineEvaluate(exec);
896     KJS_CHECKEXCEPTIONNUMBER
897     return v->toNumber(exec);
898 }
899
900 bool NewExprNode::evaluateToBoolean(ExecState* exec)
901 {
902     JSValue* v = inlineEvaluate(exec);
903     KJS_CHECKEXCEPTIONBOOLEAN
904     return v->toBoolean(exec);
905 }
906
907 int32_t NewExprNode::evaluateToInt32(ExecState* exec)
908 {
909     JSValue* v = inlineEvaluate(exec);
910     KJS_CHECKEXCEPTIONNUMBER
911     return v->toInt32(exec);
912 }
913
914 uint32_t NewExprNode::evaluateToUInt32(ExecState* exec)
915 {
916     JSValue* v = inlineEvaluate(exec);
917     KJS_CHECKEXCEPTIONNUMBER
918     return v->toUInt32(exec);
919 }    
920
921 void FunctionCallValueNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
922 {
923     nodeStack.append(args.get());
924     nodeStack.append(expr.get());
925 }
926
927 // ECMA 11.2.3
928 JSValue *FunctionCallValueNode::evaluate(ExecState *exec)
929 {
930   JSValue *v = expr->evaluate(exec);
931   KJS_CHECKEXCEPTIONVALUE
932
933   if (!v->isObject()) {
934     return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, expr.get());
935   }
936   
937   JSObject *func = static_cast<JSObject*>(v);
938
939   if (!func->implementsCall()) {
940     return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr.get());
941   }
942
943   List argList;
944   args->evaluateList(exec, argList);
945   KJS_CHECKEXCEPTIONVALUE
946
947   JSObject *thisObj =  exec->dynamicGlobalObject();
948
949   return func->call(exec, thisObj, argList);
950 }
951
952 void FunctionCallResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack& nodeStack)
953 {
954     nodeStack.append(args.get());
955
956     size_t index = symbolTable.get(ident.ustring().rep());
957     if (index != missingSymbolMarker())
958         new (this) LocalVarFunctionCallNode(index);
959 }
960
961 // ECMA 11.2.3
962 JSValue* FunctionCallResolveNode::inlineEvaluate(ExecState* exec)
963 {
964   // Check for missed optimization opportunity.
965   ASSERT(!canSkipLookup(exec, ident));
966
967   const ScopeChain& chain = exec->scopeChain();
968   ScopeChainIterator iter = chain.begin();
969   ScopeChainIterator end = chain.end();
970   
971   // we must always have something in the scope chain
972   ASSERT(iter != end);
973
974   PropertySlot slot;
975   JSObject *base;
976   do { 
977     base = *iter;
978     if (base->getPropertySlot(exec, ident, slot)) {
979       JSValue *v = slot.getValue(exec, base, ident);
980       KJS_CHECKEXCEPTIONVALUE
981         
982       if (!v->isObject())
983         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident);
984       
985       JSObject *func = static_cast<JSObject*>(v);
986       
987       if (!func->implementsCall())
988         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident);
989       
990       List argList;
991       args->evaluateList(exec, argList);
992       KJS_CHECKEXCEPTIONVALUE
993         
994       JSObject *thisObj = base;
995       // ECMA 11.2.3 says that in this situation the this value should be null.
996       // However, section 10.2.3 says that in the case where the value provided
997       // by the caller is null, the global object should be used. It also says
998       // that the section does not apply to interal functions, but for simplicity
999       // of implementation we use the global object anyway here. This guarantees
1000       // that in host objects you always get a valid object for this.
1001       if (thisObj->isActivationObject())
1002         thisObj = exec->dynamicGlobalObject();
1003
1004       return func->call(exec, thisObj, argList);
1005     }
1006     ++iter;
1007   } while (iter != end);
1008   
1009   return throwUndefinedVariableError(exec, ident);
1010 }
1011
1012 JSValue* FunctionCallResolveNode::evaluate(ExecState* exec)
1013 {
1014     return inlineEvaluate(exec);
1015 }
1016
1017 double FunctionCallResolveNode::evaluateToNumber(ExecState* exec)
1018 {
1019     JSValue* v = inlineEvaluate(exec);
1020     KJS_CHECKEXCEPTIONNUMBER
1021     return v->toNumber(exec);
1022 }
1023
1024 bool FunctionCallResolveNode::evaluateToBoolean(ExecState* exec)
1025 {
1026     JSValue* v = inlineEvaluate(exec);
1027     KJS_CHECKEXCEPTIONBOOLEAN
1028     return v->toBoolean(exec);
1029 }
1030
1031 int32_t FunctionCallResolveNode::evaluateToInt32(ExecState* exec)
1032 {
1033     JSValue* v = inlineEvaluate(exec);
1034     KJS_CHECKEXCEPTIONNUMBER
1035     return v->toInt32(exec);
1036 }
1037
1038 uint32_t FunctionCallResolveNode::evaluateToUInt32(ExecState* exec)
1039 {
1040     JSValue* v = inlineEvaluate(exec);
1041     KJS_CHECKEXCEPTIONNUMBER
1042     return v->toUInt32(exec);
1043 }
1044
1045 JSValue* LocalVarFunctionCallNode::inlineEvaluate(ExecState* exec)
1046 {
1047     ASSERT(exec->variableObject() == exec->scopeChain().top());
1048
1049     JSValue* v = exec->localStorage()[index].value;
1050
1051     if (!v->isObject())
1052         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident);
1053       
1054     JSObject* func = static_cast<JSObject*>(v);
1055     if (!func->implementsCall())
1056         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident);
1057       
1058     List argList;
1059     args->evaluateList(exec, argList);
1060     KJS_CHECKEXCEPTIONVALUE
1061
1062     return func->call(exec, exec->dynamicGlobalObject(), argList);
1063 }
1064
1065 JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec)
1066 {
1067     return inlineEvaluate(exec);
1068 }
1069
1070 double LocalVarFunctionCallNode::evaluateToNumber(ExecState* exec)
1071 {
1072     JSValue* v = inlineEvaluate(exec);
1073     KJS_CHECKEXCEPTIONNUMBER
1074     return v->toNumber(exec);
1075 }
1076
1077 bool LocalVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
1078 {
1079     JSValue* v = inlineEvaluate(exec);
1080     KJS_CHECKEXCEPTIONBOOLEAN
1081     return v->toBoolean(exec);
1082 }
1083
1084 int32_t LocalVarFunctionCallNode::evaluateToInt32(ExecState* exec)
1085 {
1086     JSValue* v = inlineEvaluate(exec);
1087     KJS_CHECKEXCEPTIONNUMBER
1088     return v->toInt32(exec);
1089 }
1090
1091 uint32_t LocalVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
1092 {
1093     JSValue* v = inlineEvaluate(exec);
1094     KJS_CHECKEXCEPTIONNUMBER
1095     return v->toUInt32(exec);
1096 }
1097
1098 void FunctionCallBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1099 {
1100     nodeStack.append(args.get());
1101     nodeStack.append(subscript.get());
1102     nodeStack.append(base.get());
1103 }
1104
1105 // ECMA 11.2.3
1106 JSValue *FunctionCallBracketNode::evaluate(ExecState *exec)
1107 {
1108   JSValue *baseVal = base->evaluate(exec);
1109   KJS_CHECKEXCEPTIONVALUE
1110
1111   JSValue *subscriptVal = subscript->evaluate(exec);
1112
1113   JSObject *baseObj = baseVal->toObject(exec);
1114   uint32_t i;
1115   PropertySlot slot;
1116
1117   JSValue *funcVal;
1118   if (subscriptVal->getUInt32(i)) {
1119     if (baseObj->getPropertySlot(exec, i, slot))
1120       funcVal = slot.getValue(exec, baseObj, i);
1121     else
1122       funcVal = jsUndefined();
1123   } else {
1124     Identifier ident(subscriptVal->toString(exec));
1125     if (baseObj->getPropertySlot(exec, ident, slot))
1126       funcVal = baseObj->get(exec, ident);
1127     else
1128       funcVal = jsUndefined();
1129   }
1130
1131   KJS_CHECKEXCEPTIONVALUE
1132   
1133   if (!funcVal->isObject()) {
1134     return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, base.get(), subscript.get());
1135   }
1136   
1137   JSObject *func = static_cast<JSObject*>(funcVal);
1138
1139   if (!func->implementsCall()) {
1140     return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, base.get(), subscript.get());
1141   }
1142
1143   List argList;
1144   args->evaluateList(exec, argList);
1145   KJS_CHECKEXCEPTIONVALUE
1146
1147   JSObject *thisObj = baseObj;
1148   ASSERT(thisObj);
1149   ASSERT(thisObj->isObject());
1150   ASSERT(!thisObj->isActivationObject());
1151
1152   return func->call(exec, thisObj, argList);
1153 }
1154
1155 static const char *dotExprNotAnObjectString() KJS_FAST_CALL;
1156 static const char *dotExprNotAnObjectString()
1157 {
1158   return "Value %s (result of expression %s.%s) is not object.";
1159 }
1160
1161 static const char *dotExprDoesNotAllowCallsString() KJS_FAST_CALL;
1162 static const char *dotExprDoesNotAllowCallsString()
1163 {
1164   return "Object %s (result of expression %s.%s) does not allow calls.";
1165 }
1166
1167 void FunctionCallDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1168 {
1169     nodeStack.append(args.get());
1170     nodeStack.append(base.get());
1171 }
1172
1173 // ECMA 11.2.3
1174 JSValue* FunctionCallDotNode::inlineEvaluate(ExecState* exec)
1175 {
1176   JSValue *baseVal = base->evaluate(exec);
1177   KJS_CHECKEXCEPTIONVALUE
1178
1179   JSObject *baseObj = baseVal->toObject(exec);
1180   PropertySlot slot;
1181   JSValue *funcVal = baseObj->getPropertySlot(exec, ident, slot) ? slot.getValue(exec, baseObj, ident) : jsUndefined();
1182   KJS_CHECKEXCEPTIONVALUE
1183
1184   if (!funcVal->isObject())
1185     return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, base.get(), ident);
1186   
1187   JSObject *func = static_cast<JSObject*>(funcVal);
1188
1189   if (!func->implementsCall())
1190     return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, base.get(), ident);
1191
1192   List argList;
1193   args->evaluateList(exec, argList);
1194   KJS_CHECKEXCEPTIONVALUE
1195
1196   JSObject *thisObj = baseObj;
1197   ASSERT(thisObj);
1198   ASSERT(thisObj->isObject());
1199   ASSERT(!thisObj->isActivationObject());
1200
1201   return func->call(exec, thisObj, argList);
1202 }
1203
1204 JSValue* FunctionCallDotNode::evaluate(ExecState* exec)
1205 {
1206     return inlineEvaluate(exec);
1207 }
1208
1209 double FunctionCallDotNode::evaluateToNumber(ExecState* exec)
1210 {
1211     JSValue* v = inlineEvaluate(exec);
1212     KJS_CHECKEXCEPTIONNUMBER
1213     return v->toNumber(exec);
1214 }
1215
1216 bool FunctionCallDotNode::evaluateToBoolean(ExecState* exec)
1217 {
1218     JSValue* v = inlineEvaluate(exec);
1219     KJS_CHECKEXCEPTIONBOOLEAN
1220     return v->toBoolean(exec);
1221 }
1222
1223 int32_t FunctionCallDotNode::evaluateToInt32(ExecState* exec)
1224 {
1225     JSValue* v = inlineEvaluate(exec);
1226     KJS_CHECKEXCEPTIONNUMBER
1227     return v->toInt32(exec);
1228 }
1229
1230 uint32_t FunctionCallDotNode::evaluateToUInt32(ExecState* exec)
1231 {
1232     JSValue* v = inlineEvaluate(exec);
1233     KJS_CHECKEXCEPTIONNUMBER
1234     return v->toUInt32(exec);
1235 }
1236
1237 // ECMA 11.3
1238
1239 // ------------------------------ PostfixResolveNode ----------------------------------
1240
1241 // Increment
1242 void PostIncResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
1243 {
1244     size_t index = symbolTable.get(m_ident.ustring().rep());
1245     if (index != missingSymbolMarker())
1246         new (this) PostIncLocalVarNode(index);
1247 }
1248
1249 JSValue *PostIncResolveNode::evaluate(ExecState *exec)
1250 {
1251   // Check for missed optimization opportunity.
1252   ASSERT(!canSkipLookup(exec, m_ident));
1253
1254   const ScopeChain& chain = exec->scopeChain();
1255   ScopeChainIterator iter = chain.begin();
1256   ScopeChainIterator end = chain.end();
1257   
1258   // we must always have something in the scope chain
1259   ASSERT(iter != end);
1260
1261   PropertySlot slot;
1262   JSObject *base;
1263   do { 
1264     base = *iter;
1265     if (base->getPropertySlot(exec, m_ident, slot)) {
1266         JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1267         base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
1268         return v;
1269     }
1270
1271     ++iter;
1272   } while (iter != end);
1273
1274   return throwUndefinedVariableError(exec, m_ident);
1275 }
1276
1277 void PostIncResolveNode::optimizeForUnnecessaryResult()
1278 {
1279     new (this) PreIncResolveNode(PlacementNewAdopt);
1280 }
1281     
1282 JSValue* PostIncLocalVarNode::evaluate(ExecState* exec)
1283 {
1284     ASSERT(exec->variableObject() == exec->scopeChain().top());
1285
1286     JSValue** slot = &exec->localStorage()[m_index].value;
1287     JSValue* v = (*slot)->toJSNumber(exec);
1288     *slot = jsNumber(v->toNumber(exec) + 1);
1289     return v;
1290 }
1291
1292 void PostIncLocalVarNode::optimizeForUnnecessaryResult()
1293 {
1294     new (this) PreIncLocalVarNode(m_index);
1295 }
1296
1297
1298 // Decrement
1299 void PostDecResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
1300 {
1301     size_t index = symbolTable.get(m_ident.ustring().rep());
1302     if (index != missingSymbolMarker())
1303         new (this) PostDecLocalVarNode(index);
1304 }
1305
1306 JSValue *PostDecResolveNode::evaluate(ExecState *exec)
1307 {
1308   // Check for missed optimization opportunity.
1309   ASSERT(!canSkipLookup(exec, m_ident));
1310
1311   const ScopeChain& chain = exec->scopeChain();
1312   ScopeChainIterator iter = chain.begin();
1313   ScopeChainIterator end = chain.end();
1314   
1315   // we must always have something in the scope chain
1316   ASSERT(iter != end);
1317
1318   PropertySlot slot;
1319   JSObject *base;
1320   do { 
1321     base = *iter;
1322     if (base->getPropertySlot(exec, m_ident, slot)) {
1323         JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1324         base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
1325         return v;
1326     }
1327
1328     ++iter;
1329   } while (iter != end);
1330
1331   return throwUndefinedVariableError(exec, m_ident);
1332 }
1333     
1334 void PostDecResolveNode::optimizeForUnnecessaryResult()
1335 {
1336     new (this) PreDecResolveNode(PlacementNewAdopt);
1337 }
1338     
1339 JSValue* PostDecLocalVarNode::evaluate(ExecState* exec)
1340 {
1341     ASSERT(exec->variableObject() == exec->scopeChain().top());
1342
1343     JSValue** slot = &exec->localStorage()[m_index].value;
1344     JSValue* v = (*slot)->toJSNumber(exec);
1345     *slot = jsNumber(v->toNumber(exec) - 1);
1346     return v;
1347 }
1348
1349 double PostDecLocalVarNode::inlineEvaluateToNumber(ExecState* exec)
1350 {
1351     ASSERT(exec->variableObject() == exec->scopeChain().top());
1352     
1353     JSValue** slot = &exec->localStorage()[m_index].value;
1354     double n = (*slot)->toNumber(exec);
1355     *slot = jsNumber(n - 1);
1356     return n;
1357 }
1358
1359 double PostDecLocalVarNode::evaluateToNumber(ExecState* exec)
1360 {
1361     return inlineEvaluateToNumber(exec);
1362 }
1363
1364 bool PostDecLocalVarNode::evaluateToBoolean(ExecState* exec)
1365 {
1366     return inlineEvaluateToNumber(exec);
1367 }
1368
1369 int32_t PostDecLocalVarNode::evaluateToInt32(ExecState* exec)
1370 {
1371     return JSValue::toInt32(inlineEvaluateToNumber(exec));
1372 }
1373
1374 uint32_t PostDecLocalVarNode::evaluateToUInt32(ExecState* exec)
1375 {
1376     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
1377 }
1378
1379 void PostDecLocalVarNode::optimizeForUnnecessaryResult()
1380 {
1381     new (this) PreDecLocalVarNode(m_index);
1382 }
1383     
1384 // ------------------------------ PostfixBracketNode ----------------------------------
1385
1386 void PostfixBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1387 {
1388     nodeStack.append(m_subscript.get());
1389     nodeStack.append(m_base.get());
1390 }
1391
1392 JSValue *PostIncBracketNode::evaluate(ExecState *exec)
1393 {
1394   JSValue *baseValue = m_base->evaluate(exec);
1395   KJS_CHECKEXCEPTIONVALUE
1396   JSValue *subscript = m_subscript->evaluate(exec);
1397   KJS_CHECKEXCEPTIONVALUE
1398
1399   JSObject *base = baseValue->toObject(exec);
1400
1401   uint32_t propertyIndex;
1402   if (subscript->getUInt32(propertyIndex)) {
1403     PropertySlot slot;
1404     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1405     KJS_CHECKEXCEPTIONVALUE
1406
1407     JSValue* v2 = v->toJSNumber(exec);
1408     base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1));
1409         
1410     return v2;
1411   }
1412
1413   Identifier propertyName(subscript->toString(exec));
1414   PropertySlot slot;
1415   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1416   KJS_CHECKEXCEPTIONVALUE
1417
1418   JSValue* v2 = v->toJSNumber(exec);
1419   base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));
1420   return v2;
1421 }
1422
1423 JSValue *PostDecBracketNode::evaluate(ExecState *exec)
1424 {
1425   JSValue *baseValue = m_base->evaluate(exec);
1426   KJS_CHECKEXCEPTIONVALUE
1427   JSValue *subscript = m_subscript->evaluate(exec);
1428   KJS_CHECKEXCEPTIONVALUE
1429
1430   JSObject *base = baseValue->toObject(exec);
1431
1432   uint32_t propertyIndex;
1433   if (subscript->getUInt32(propertyIndex)) {
1434     PropertySlot slot;
1435     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1436     KJS_CHECKEXCEPTIONVALUE
1437
1438     JSValue* v2 = v->toJSNumber(exec);
1439     base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1));
1440     return v2;
1441   }
1442
1443   Identifier propertyName(subscript->toString(exec));
1444   PropertySlot slot;
1445   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1446   KJS_CHECKEXCEPTIONVALUE
1447
1448   JSValue* v2 = v->toJSNumber(exec);
1449   base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));
1450   return v2;
1451 }
1452
1453 // ------------------------------ PostfixDotNode ----------------------------------
1454
1455 void PostfixDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1456 {
1457     nodeStack.append(m_base.get());
1458 }
1459
1460 JSValue *PostIncDotNode::evaluate(ExecState *exec)
1461 {
1462   JSValue *baseValue = m_base->evaluate(exec);
1463   KJS_CHECKEXCEPTIONVALUE
1464   JSObject *base = baseValue->toObject(exec);
1465
1466   PropertySlot slot;
1467   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1468   KJS_CHECKEXCEPTIONVALUE
1469
1470   JSValue* v2 = v->toJSNumber(exec);
1471   base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));
1472   return v2;
1473 }
1474
1475 JSValue *PostDecDotNode::evaluate(ExecState *exec)
1476 {
1477   JSValue *baseValue = m_base->evaluate(exec);
1478   KJS_CHECKEXCEPTIONVALUE
1479   JSObject *base = baseValue->toObject(exec);
1480
1481   PropertySlot slot;
1482   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1483   KJS_CHECKEXCEPTIONVALUE
1484
1485   JSValue* v2 = v->toJSNumber(exec);
1486   base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));
1487   return v2;
1488 }
1489
1490 // ------------------------------ PostfixErrorNode -----------------------------------
1491
1492 JSValue* PostfixErrorNode::evaluate(ExecState* exec)
1493 {
1494     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
1495         m_oper == OpPlusPlus ? "++" : "--");
1496     handleException(exec);
1497     return jsUndefined();
1498 }
1499
1500 // ------------------------------ DeleteResolveNode -----------------------------------
1501
1502 void DeleteResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
1503 {
1504     size_t index = symbolTable.get(m_ident.ustring().rep());
1505     if (index != missingSymbolMarker())
1506         new (this) LocalVarDeleteNode();
1507 }
1508
1509 // ECMA 11.4.1
1510
1511 JSValue *DeleteResolveNode::evaluate(ExecState *exec)
1512 {
1513   // Check for missed optimization opportunity.
1514   ASSERT(!canSkipLookup(exec, m_ident));
1515
1516   const ScopeChain& chain = exec->scopeChain();
1517   ScopeChainIterator iter = chain.begin();
1518   ScopeChainIterator end = chain.end();
1519   
1520   // we must always have something in the scope chain
1521   ASSERT(iter != end);
1522
1523   PropertySlot slot;
1524   JSObject *base;
1525   do { 
1526     base = *iter;
1527     if (base->getPropertySlot(exec, m_ident, slot)) {
1528         return jsBoolean(base->deleteProperty(exec, m_ident));
1529     }
1530
1531     ++iter;
1532   } while (iter != end);
1533
1534   return jsBoolean(true);
1535 }
1536
1537 JSValue* LocalVarDeleteNode::evaluate(ExecState*)
1538 {
1539     return jsBoolean(false);
1540 }
1541
1542 // ------------------------------ DeleteBracketNode -----------------------------------
1543
1544 void DeleteBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1545 {
1546     nodeStack.append(m_subscript.get());
1547     nodeStack.append(m_base.get());
1548 }
1549
1550 JSValue *DeleteBracketNode::evaluate(ExecState *exec)
1551 {
1552   JSValue *baseValue = m_base->evaluate(exec);
1553   KJS_CHECKEXCEPTIONVALUE
1554   JSValue *subscript = m_subscript->evaluate(exec);
1555   KJS_CHECKEXCEPTIONVALUE
1556
1557   JSObject *base = baseValue->toObject(exec);
1558
1559   uint32_t propertyIndex;
1560   if (subscript->getUInt32(propertyIndex))
1561       return jsBoolean(base->deleteProperty(exec, propertyIndex));
1562
1563   Identifier propertyName(subscript->toString(exec));
1564   return jsBoolean(base->deleteProperty(exec, propertyName));
1565 }
1566
1567 // ------------------------------ DeleteDotNode -----------------------------------
1568
1569 void DeleteDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1570 {
1571     nodeStack.append(m_base.get());
1572 }
1573
1574 JSValue *DeleteDotNode::evaluate(ExecState *exec)
1575 {
1576   JSValue *baseValue = m_base->evaluate(exec);
1577   JSObject *base = baseValue->toObject(exec);
1578   KJS_CHECKEXCEPTIONVALUE
1579
1580   return jsBoolean(base->deleteProperty(exec, m_ident));
1581 }
1582
1583 // ------------------------------ DeleteValueNode -----------------------------------
1584
1585 void DeleteValueNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1586 {
1587     nodeStack.append(m_expr.get());
1588 }
1589
1590 JSValue *DeleteValueNode::evaluate(ExecState *exec)
1591 {
1592   m_expr->evaluate(exec);
1593   KJS_CHECKEXCEPTIONVALUE
1594
1595   // delete on a non-location expression ignores the value and returns true
1596   return jsBoolean(true);
1597 }
1598
1599 // ------------------------------ VoidNode -------------------------------------
1600
1601 void VoidNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1602 {
1603     nodeStack.append(expr.get());
1604 }
1605
1606 // ECMA 11.4.2
1607 JSValue *VoidNode::evaluate(ExecState *exec)
1608 {
1609   expr->evaluate(exec);
1610   KJS_CHECKEXCEPTIONVALUE
1611
1612   return jsUndefined();
1613 }
1614
1615 // ECMA 11.4.3
1616
1617 // ------------------------------ TypeOfValueNode -----------------------------------
1618
1619 void TypeOfValueNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1620 {
1621     nodeStack.append(m_expr.get());
1622 }
1623
1624 static JSValue *typeStringForValue(JSValue *v) KJS_FAST_CALL;
1625 static JSValue *typeStringForValue(JSValue *v)
1626 {
1627     switch (v->type()) {
1628     case UndefinedType:
1629         return jsString("undefined");
1630     case NullType:
1631         return jsString("object");
1632     case BooleanType:
1633         return jsString("boolean");
1634     case NumberType:
1635         return jsString("number");
1636     case StringType:
1637         return jsString("string");
1638     default:
1639         if (v->isObject()) {
1640             // Return "undefined" for objects that should be treated
1641             // as null when doing comparisons.
1642             if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
1643                 return jsString("undefined");
1644             else if (static_cast<JSObject*>(v)->implementsCall())
1645                 return jsString("function");
1646         }
1647         
1648         return jsString("object");
1649     }
1650 }
1651
1652 void TypeOfResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
1653 {
1654     size_t index = symbolTable.get(m_ident.ustring().rep());
1655     if (index != missingSymbolMarker())
1656         new (this) LocalVarTypeOfNode(index);
1657 }
1658
1659 JSValue* LocalVarTypeOfNode::evaluate(ExecState* exec)
1660 {
1661     ASSERT(exec->variableObject() == exec->scopeChain().top());
1662
1663     return typeStringForValue(exec->localStorage()[m_index].value);
1664 }
1665
1666 JSValue *TypeOfResolveNode::evaluate(ExecState *exec)
1667 {
1668   const ScopeChain& chain = exec->scopeChain();
1669   ScopeChainIterator iter = chain.begin();
1670   ScopeChainIterator end = chain.end();
1671   
1672   // we must always have something in the scope chain
1673   ASSERT(iter != end);
1674
1675   PropertySlot slot;
1676   JSObject *base;
1677   do { 
1678     base = *iter;
1679     if (base->getPropertySlot(exec, m_ident, slot)) {
1680         JSValue *v = slot.getValue(exec, base, m_ident);
1681         return typeStringForValue(v);
1682     }
1683
1684     ++iter;
1685   } while (iter != end);
1686
1687   return jsString("undefined");
1688 }
1689
1690 // ------------------------------ TypeOfValueNode -----------------------------------
1691
1692 JSValue *TypeOfValueNode::evaluate(ExecState *exec)
1693 {
1694   JSValue *v = m_expr->evaluate(exec);
1695   KJS_CHECKEXCEPTIONVALUE
1696
1697   return typeStringForValue(v);
1698 }
1699
1700 // ECMA 11.4.4 and 11.4.5
1701
1702 // ------------------------------ PrefixResolveNode ----------------------------------
1703
1704 void PreIncResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
1705 {
1706     size_t index = symbolTable.get(m_ident.ustring().rep());
1707     if (index != missingSymbolMarker())
1708         new (this) PreIncLocalVarNode(index);
1709 }
1710
1711 JSValue* PreIncLocalVarNode::evaluate(ExecState* exec)
1712 {
1713     ASSERT(exec->variableObject() == exec->scopeChain().top());
1714     JSValue** slot = &exec->localStorage()[m_index].value;
1715
1716     double n = (*slot)->toNumber(exec);
1717     JSValue* n2 = jsNumber(n + 1);
1718     *slot = n2;
1719     return n2;
1720 }
1721
1722 JSValue *PreIncResolveNode::evaluate(ExecState *exec)
1723 {
1724   const ScopeChain& chain = exec->scopeChain();
1725   ScopeChainIterator iter = chain.begin();
1726   ScopeChainIterator end = chain.end();
1727   
1728   // we must always have something in the scope chain
1729   ASSERT(iter != end);
1730
1731   PropertySlot slot;
1732   JSObject *base;
1733   do { 
1734     base = *iter;
1735     if (base->getPropertySlot(exec, m_ident, slot)) {
1736         JSValue *v = slot.getValue(exec, base, m_ident);
1737
1738         double n = v->toNumber(exec);
1739         JSValue *n2 = jsNumber(n + 1);
1740         base->put(exec, m_ident, n2);
1741
1742         return n2;
1743     }
1744
1745     ++iter;
1746   } while (iter != end);
1747
1748   return throwUndefinedVariableError(exec, m_ident);
1749 }
1750
1751 void PreDecResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack&)
1752 {
1753     size_t index = symbolTable.get(m_ident.ustring().rep());
1754     if (index != missingSymbolMarker())
1755         new (this) PreDecLocalVarNode(index);
1756 }
1757
1758 JSValue* PreDecLocalVarNode::evaluate(ExecState* exec)
1759 {
1760     ASSERT(exec->variableObject() == exec->scopeChain().top());
1761     JSValue** slot = &exec->localStorage()[m_index].value;
1762
1763     double n = (*slot)->toNumber(exec);
1764     JSValue* n2 = jsNumber(n - 1);
1765     *slot = n2;
1766     return n2;
1767 }
1768
1769 JSValue *PreDecResolveNode::evaluate(ExecState *exec)
1770 {
1771   const ScopeChain& chain = exec->scopeChain();
1772   ScopeChainIterator iter = chain.begin();
1773   ScopeChainIterator end = chain.end();
1774   
1775   // we must always have something in the scope chain
1776   ASSERT(iter != end);
1777
1778   PropertySlot slot;
1779   JSObject *base;
1780   do { 
1781     base = *iter;
1782     if (base->getPropertySlot(exec, m_ident, slot)) {
1783         JSValue *v = slot.getValue(exec, base, m_ident);
1784
1785         double n = v->toNumber(exec);
1786         JSValue *n2 = jsNumber(n - 1);
1787         base->put(exec, m_ident, n2);
1788
1789         return n2;
1790     }
1791
1792     ++iter;
1793   } while (iter != end);
1794
1795   return throwUndefinedVariableError(exec, m_ident);
1796 }
1797
1798 // ------------------------------ PrefixBracketNode ----------------------------------
1799
1800 void PrefixBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1801 {
1802     nodeStack.append(m_subscript.get());
1803     nodeStack.append(m_base.get());
1804 }
1805
1806 JSValue *PreIncBracketNode::evaluate(ExecState *exec)
1807 {
1808   JSValue *baseValue = m_base->evaluate(exec);
1809   KJS_CHECKEXCEPTIONVALUE
1810   JSValue *subscript = m_subscript->evaluate(exec);
1811   KJS_CHECKEXCEPTIONVALUE
1812
1813   JSObject *base = baseValue->toObject(exec);
1814
1815   uint32_t propertyIndex;
1816   if (subscript->getUInt32(propertyIndex)) {
1817     PropertySlot slot;
1818     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1819     KJS_CHECKEXCEPTIONVALUE
1820
1821     JSValue *n2 = jsNumber(v->toNumber(exec) + 1);
1822     base->put(exec, propertyIndex, n2);
1823
1824     return n2;
1825   }
1826
1827   Identifier propertyName(subscript->toString(exec));
1828   PropertySlot slot;
1829   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1830   KJS_CHECKEXCEPTIONVALUE
1831
1832   JSValue *n2 = jsNumber(v->toNumber(exec) + 1);
1833   base->put(exec, propertyName, n2);
1834
1835   return n2;
1836 }
1837
1838 JSValue *PreDecBracketNode::evaluate(ExecState *exec)
1839 {
1840   JSValue *baseValue = m_base->evaluate(exec);
1841   KJS_CHECKEXCEPTIONVALUE
1842   JSValue *subscript = m_subscript->evaluate(exec);
1843   KJS_CHECKEXCEPTIONVALUE
1844
1845   JSObject *base = baseValue->toObject(exec);
1846
1847   uint32_t propertyIndex;
1848   if (subscript->getUInt32(propertyIndex)) {
1849     PropertySlot slot;
1850     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1851     KJS_CHECKEXCEPTIONVALUE
1852
1853     JSValue *n2 = jsNumber(v->toNumber(exec) - 1);
1854     base->put(exec, propertyIndex, n2);
1855
1856     return n2;
1857   }
1858
1859   Identifier propertyName(subscript->toString(exec));
1860   PropertySlot slot;
1861   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1862   KJS_CHECKEXCEPTIONVALUE
1863
1864   JSValue *n2 = jsNumber(v->toNumber(exec) - 1);
1865   base->put(exec, propertyName, n2);
1866
1867   return n2;
1868 }
1869
1870 // ------------------------------ PrefixDotNode ----------------------------------
1871
1872 void PrefixDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1873 {
1874     nodeStack.append(m_base.get());
1875 }
1876
1877 JSValue *PreIncDotNode::evaluate(ExecState *exec)
1878 {
1879   JSValue *baseValue = m_base->evaluate(exec);
1880   KJS_CHECKEXCEPTIONVALUE
1881   JSObject *base = baseValue->toObject(exec);
1882
1883   PropertySlot slot;
1884   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1885   KJS_CHECKEXCEPTIONVALUE
1886
1887   double n = v->toNumber(exec);
1888   JSValue *n2 = jsNumber(n + 1);
1889   base->put(exec, m_ident, n2);
1890
1891   return n2;
1892 }
1893
1894 JSValue *PreDecDotNode::evaluate(ExecState *exec)
1895 {
1896   JSValue *baseValue = m_base->evaluate(exec);
1897   KJS_CHECKEXCEPTIONVALUE
1898   JSObject *base = baseValue->toObject(exec);
1899
1900   PropertySlot slot;
1901   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1902   KJS_CHECKEXCEPTIONVALUE
1903
1904   double n = v->toNumber(exec);
1905   JSValue *n2 = jsNumber(n - 1);
1906   base->put(exec, m_ident, n2);
1907
1908   return n2;
1909 }
1910
1911 // ------------------------------ PrefixErrorNode -----------------------------------
1912
1913 JSValue* PrefixErrorNode::evaluate(ExecState* exec)
1914 {
1915     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
1916         m_oper == OpPlusPlus ? "++" : "--");
1917     handleException(exec);
1918     return jsUndefined();
1919 }
1920
1921 // ------------------------------ UnaryPlusNode --------------------------------
1922
1923 void UnaryPlusNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1924 {
1925     nodeStack.append(m_expr.get());
1926 }
1927
1928 // ECMA 11.4.6
1929 JSValue* UnaryPlusNode::evaluate(ExecState* exec)
1930 {
1931     JSValue *v = m_expr->evaluate(exec);
1932     KJS_CHECKEXCEPTIONVALUE
1933     return v->toJSNumber(exec);
1934 }
1935
1936 bool UnaryPlusNode::evaluateToBoolean(ExecState* exec)
1937 {
1938     return m_expr->evaluateToBoolean(exec);
1939 }
1940
1941 double UnaryPlusNode::evaluateToNumber(ExecState* exec)
1942 {
1943     return m_expr->evaluateToNumber(exec);
1944 }
1945
1946 int32_t UnaryPlusNode::evaluateToInt32(ExecState* exec)
1947 {
1948     return m_expr->evaluateToInt32(exec);
1949 }
1950
1951 uint32_t UnaryPlusNode::evaluateToUInt32(ExecState* exec)
1952 {
1953     return m_expr->evaluateToInt32(exec);
1954 }
1955
1956 // ------------------------------ NegateNode -----------------------------------
1957
1958 void NegateNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1959 {
1960     nodeStack.append(expr.get());
1961 }
1962
1963 // ECMA 11.4.7
1964 JSValue *NegateNode::evaluate(ExecState *exec)
1965 {
1966     // No need to check exception, caller will do so right after evaluate()
1967     return jsNumber(-expr->evaluateToNumber(exec));
1968 }
1969
1970 double NegateNode::evaluateToNumber(ExecState* exec)
1971 {
1972     // No need to check exception, caller will do so right after evaluateToNumber()
1973     return -expr->evaluateToNumber(exec);
1974 }
1975
1976 // ------------------------------ BitwiseNotNode -------------------------------
1977
1978 void BitwiseNotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
1979 {
1980     nodeStack.append(expr.get());
1981 }
1982
1983 // ECMA 11.4.8
1984 int32_t BitwiseNotNode::inlineEvaluateToInt32(ExecState* exec)
1985 {
1986     return ~expr->evaluateToInt32(exec);
1987 }
1988
1989 JSValue* BitwiseNotNode::evaluate(ExecState* exec)
1990 {
1991     return jsNumber(inlineEvaluateToInt32(exec));
1992 }
1993
1994 double BitwiseNotNode::evaluateToNumber(ExecState* exec)
1995 {
1996     return inlineEvaluateToInt32(exec);
1997 }
1998
1999 bool BitwiseNotNode::evaluateToBoolean(ExecState* exec)
2000 {
2001     return inlineEvaluateToInt32(exec);
2002 }
2003
2004 int32_t BitwiseNotNode::evaluateToInt32(ExecState* exec)
2005 {
2006     return inlineEvaluateToInt32(exec);
2007 }
2008
2009 uint32_t BitwiseNotNode::evaluateToUInt32(ExecState* exec)
2010 {
2011     return inlineEvaluateToInt32(exec);
2012 }
2013
2014 // ------------------------------ LogicalNotNode -------------------------------
2015
2016 void LogicalNotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2017 {
2018     nodeStack.append(expr.get());
2019 }
2020
2021 // ECMA 11.4.9
2022 JSValue* LogicalNotNode::evaluate(ExecState* exec)
2023 {
2024     return jsBoolean(!expr->evaluateToBoolean(exec));
2025 }
2026
2027 bool LogicalNotNode::evaluateToBoolean(ExecState* exec)
2028 {
2029     return !expr->evaluateToBoolean(exec);
2030 }
2031
2032 // ------------------------------ Multiplicative Nodes -----------------------------------
2033
2034 void MultNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2035 {
2036     nodeStack.append(term1.get());
2037     nodeStack.append(term2.get());
2038 }
2039
2040 // ECMA 11.5.1
2041 double MultNode::inlineEvaluateToNumber(ExecState* exec)
2042 {
2043     double n1 = term1->evaluateToNumber(exec);
2044     KJS_CHECKEXCEPTIONNUMBER
2045     double n2 = term2->evaluateToNumber(exec);
2046     return n1 * n2;
2047 }
2048
2049 JSValue *MultNode::evaluate(ExecState* exec)
2050 {
2051     return jsNumber(inlineEvaluateToNumber(exec));
2052 }
2053     
2054 double MultNode::evaluateToNumber(ExecState* exec)
2055 {
2056     return inlineEvaluateToNumber(exec);
2057 }
2058
2059 bool MultNode::evaluateToBoolean(ExecState* exec)
2060 {
2061     return inlineEvaluateToNumber(exec);
2062 }
2063
2064 int32_t MultNode::evaluateToInt32(ExecState* exec)
2065 {
2066     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2067 }
2068
2069 uint32_t MultNode::evaluateToUInt32(ExecState* exec)
2070 {
2071     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2072 }
2073
2074 void DivNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2075 {
2076     nodeStack.append(term1.get());
2077     nodeStack.append(term2.get());
2078 }
2079
2080 // ECMA 11.5.2
2081 double DivNode::inlineEvaluateToNumber(ExecState* exec)
2082 {
2083     double n1 = term1->evaluateToNumber(exec);
2084     KJS_CHECKEXCEPTIONNUMBER
2085     double n2 = term2->evaluateToNumber(exec);
2086     return n1 / n2;
2087 }
2088
2089 JSValue* DivNode::evaluate(ExecState* exec)
2090 {
2091     return jsNumber(inlineEvaluateToNumber(exec));
2092 }
2093
2094 double DivNode::evaluateToNumber(ExecState* exec)
2095 {
2096     return inlineEvaluateToNumber(exec);
2097 }
2098
2099 int32_t DivNode::evaluateToInt32(ExecState* exec)
2100 {
2101     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2102 }
2103
2104 uint32_t DivNode::evaluateToUInt32(ExecState* exec)
2105 {
2106     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2107 }
2108
2109 void ModNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2110 {
2111     nodeStack.append(term1.get());
2112     nodeStack.append(term2.get());
2113 }
2114
2115 // ECMA 11.5.3
2116 double ModNode::inlineEvaluateToNumber(ExecState* exec)
2117 {
2118     double n1 = term1->evaluateToNumber(exec);
2119     KJS_CHECKEXCEPTIONNUMBER
2120     double n2 = term2->evaluateToNumber(exec);
2121     return fmod(n1, n2);
2122 }
2123
2124 JSValue* ModNode::evaluate(ExecState* exec)
2125 {
2126     return jsNumber(inlineEvaluateToNumber(exec));
2127 }
2128
2129 double ModNode::evaluateToNumber(ExecState* exec)
2130 {
2131     return inlineEvaluateToNumber(exec);
2132 }
2133
2134 bool ModNode::evaluateToBoolean(ExecState* exec)
2135 {
2136     return inlineEvaluateToNumber(exec);
2137 }
2138
2139 int32_t ModNode::evaluateToInt32(ExecState* exec)
2140 {
2141     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2142 }
2143
2144 uint32_t ModNode::evaluateToUInt32(ExecState* exec)
2145 {
2146     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2147 }
2148
2149 // ------------------------------ Additive Nodes --------------------------------------
2150
2151 static JSValue* throwOutOfMemoryError(ExecState* exec)
2152 {
2153     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
2154     exec->setException(error);
2155     return error;
2156 }
2157
2158 static double throwOutOfMemoryErrorToNumber(ExecState* exec)
2159 {
2160     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
2161     exec->setException(error);
2162     return 0.0;
2163 }    
2164
2165 // ECMA 11.6
2166 static JSValue* addSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
2167 {
2168     // exception for the Date exception in defaultValue()
2169     JSValue *p1 = v1->toPrimitive(exec, UnspecifiedType);
2170     JSValue *p2 = v2->toPrimitive(exec, UnspecifiedType);
2171     
2172     if (p1->isString() || p2->isString()) {
2173         UString value = p1->toString(exec) + p2->toString(exec);
2174         if (value.isNull())
2175             return throwOutOfMemoryError(exec);
2176         return jsString(value);
2177     }
2178     
2179     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
2180 }
2181
2182 static double addSlowCaseToNumber(ExecState* exec, JSValue* v1, JSValue* v2)
2183 {
2184     // exception for the Date exception in defaultValue()
2185     JSValue *p1 = v1->toPrimitive(exec, UnspecifiedType);
2186     JSValue *p2 = v2->toPrimitive(exec, UnspecifiedType);
2187     
2188     if (p1->isString() || p2->isString()) {
2189         UString value = p1->toString(exec) + p2->toString(exec);
2190         if (value.isNull())
2191             return throwOutOfMemoryErrorToNumber(exec);
2192         return value.toDouble();
2193     }
2194     
2195     return p1->toNumber(exec) + p2->toNumber(exec);
2196 }
2197
2198 // Fast-path choices here are based on frequency data from SunSpider:
2199 //    <times> Add case: <t1> <t2>
2200 //    ---------------------------
2201 //    5627160 Add case: 1 1
2202 //    247427  Add case: 5 5
2203 //    20901   Add case: 5 6
2204 //    13978   Add case: 5 1
2205 //    4000    Add case: 1 5
2206 //    1       Add case: 3 5
2207
2208 static inline JSValue* add(ExecState* exec, JSValue* v1, JSValue *v2)
2209 {
2210     JSType t1 = v1->type();
2211     JSType t2 = v2->type();
2212     const unsigned bothTypes = (t1 << 3) | t2;
2213     
2214     if (bothTypes == ((NumberType << 3) | NumberType))
2215         return jsNumber(v1->toNumber(exec) + v2->toNumber(exec));
2216     if (bothTypes == ((StringType << 3) | StringType)) {
2217         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
2218         if (value.isNull())
2219             return throwOutOfMemoryError(exec);
2220         return jsString(value);
2221     }
2222     
2223     // All other cases are pretty uncommon
2224     return addSlowCase(exec, v1, v2);
2225 }
2226
2227 static inline double addToNumber(ExecState* exec, JSValue* v1, JSValue *v2)
2228 {
2229     JSType t1 = v1->type();
2230     JSType t2 = v2->type();
2231     const unsigned bothTypes = (t1 << 3) | t2;
2232     
2233     if (bothTypes == ((NumberType << 3) | NumberType))
2234         return v1->toNumber(exec) + v2->toNumber(exec);
2235     if (bothTypes == ((StringType << 3) | StringType)) {
2236         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
2237         if (value.isNull())
2238             return throwOutOfMemoryErrorToNumber(exec);
2239         return value.toDouble();
2240     }
2241     
2242     // All other cases are pretty uncommon
2243     return addSlowCaseToNumber(exec, v1, v2);
2244 }
2245
2246 void AddNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2247 {
2248     nodeStack.append(term1.get());
2249     nodeStack.append(term2.get());
2250 }
2251
2252 // ECMA 11.6.1
2253 JSValue* AddNode::evaluate(ExecState* exec)
2254 {
2255   JSValue* v1 = term1->evaluate(exec);
2256   KJS_CHECKEXCEPTIONVALUE
2257
2258   JSValue* v2 = term2->evaluate(exec);
2259   KJS_CHECKEXCEPTIONVALUE
2260
2261   return add(exec, v1, v2);
2262 }
2263
2264 double AddNode::inlineEvaluateToNumber(ExecState* exec)
2265 {
2266     JSValue* v1 = term1->evaluate(exec);
2267     KJS_CHECKEXCEPTIONNUMBER
2268     
2269     JSValue* v2 = term2->evaluate(exec);
2270     KJS_CHECKEXCEPTIONNUMBER
2271     
2272     return addToNumber(exec, v1, v2);
2273 }
2274
2275 double AddNode::evaluateToNumber(ExecState* exec)
2276 {
2277     return inlineEvaluateToNumber(exec);
2278 }
2279
2280 int32_t AddNode::evaluateToInt32(ExecState* exec)
2281 {
2282     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2283 }
2284
2285 uint32_t AddNode::evaluateToUInt32(ExecState* exec)
2286 {
2287     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2288 }    
2289
2290 double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec)
2291 {
2292     double n1 = term1->evaluateToNumber(exec);
2293     KJS_CHECKEXCEPTIONNUMBER
2294     double n2 = term2->evaluateToNumber(exec);
2295     return n1 + n2;
2296 }
2297
2298 JSValue* AddNumbersNode::evaluate(ExecState* exec)
2299 {
2300     return jsNumber(inlineEvaluateToNumber(exec));
2301 }
2302
2303 double AddNumbersNode::evaluateToNumber(ExecState* exec)
2304 {
2305     return inlineEvaluateToNumber(exec);
2306 }
2307
2308 int32_t AddNumbersNode::evaluateToInt32(ExecState* exec)
2309 {
2310     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2311 }
2312
2313 uint32_t AddNumbersNode::evaluateToUInt32(ExecState* exec)
2314 {
2315     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2316 }
2317
2318 JSValue* AddStringsNode::evaluate(ExecState* exec)
2319 {
2320     JSValue* v1 = term1->evaluate(exec);
2321     KJS_CHECKEXCEPTIONVALUE
2322     
2323     JSValue* v2 = term2->evaluate(exec);
2324     KJS_CHECKEXCEPTIONVALUE
2325     
2326     return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
2327 }
2328
2329 JSValue* AddStringLeftNode::evaluate(ExecState* exec)
2330 {
2331     JSValue* v1 = term1->evaluate(exec);
2332     KJS_CHECKEXCEPTIONVALUE
2333     
2334     JSValue* v2 = term2->evaluate(exec);
2335     KJS_CHECKEXCEPTIONVALUE
2336     
2337     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
2338     return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
2339 }
2340
2341 JSValue* AddStringRightNode::evaluate(ExecState* exec)
2342 {
2343     JSValue* v1 = term1->evaluate(exec);
2344     KJS_CHECKEXCEPTIONVALUE
2345     
2346     JSValue* v2 = term2->evaluate(exec);
2347     KJS_CHECKEXCEPTIONVALUE
2348     
2349     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
2350     return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
2351 }
2352
2353 void SubNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2354 {
2355     nodeStack.append(term1.get());
2356     nodeStack.append(term2.get());
2357 }
2358
2359 // ECMA 11.6.2
2360 double SubNode::inlineEvaluateToNumber(ExecState* exec)
2361 {
2362     double n1 = term1->evaluateToNumber(exec);
2363     KJS_CHECKEXCEPTIONNUMBER
2364     double n2 = term2->evaluateToNumber(exec);
2365     return n1 - n2;
2366 }
2367
2368 JSValue* SubNode::evaluate(ExecState* exec)
2369 {
2370     return jsNumber(inlineEvaluateToNumber(exec));
2371 }
2372
2373 double SubNode::evaluateToNumber(ExecState* exec)
2374 {
2375     return inlineEvaluateToNumber(exec);
2376 }
2377
2378 int32_t SubNode::evaluateToInt32(ExecState* exec)
2379 {
2380     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2381 }
2382
2383 uint32_t SubNode::evaluateToUInt32(ExecState* exec)
2384 {
2385     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2386 }    
2387
2388 // ------------------------------ Shift Nodes ------------------------------------
2389
2390 void LeftShiftNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2391 {
2392     nodeStack.append(term1.get());
2393     nodeStack.append(term2.get());
2394 }
2395
2396 // ECMA 11.7.1
2397 int32_t LeftShiftNode::inlineEvaluateToInt32(ExecState* exec)
2398 {
2399     int i1 = term1->evaluateToInt32(exec);
2400     KJS_CHECKEXCEPTIONNUMBER
2401     unsigned int i2 = term2->evaluateToUInt32(exec) & 0x1f;
2402     return (i1 << i2);
2403 }
2404
2405 JSValue* LeftShiftNode::evaluate(ExecState* exec)
2406 {
2407     return jsNumber(inlineEvaluateToInt32(exec));
2408 }
2409
2410 double LeftShiftNode::evaluateToNumber(ExecState* exec)
2411 {
2412     return inlineEvaluateToInt32(exec);
2413 }
2414
2415 int32_t LeftShiftNode::evaluateToInt32(ExecState* exec)
2416 {
2417     return inlineEvaluateToInt32(exec);
2418 }
2419
2420 uint32_t LeftShiftNode::evaluateToUInt32(ExecState* exec)
2421 {
2422     return inlineEvaluateToInt32(exec);
2423 }
2424
2425 void RightShiftNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2426 {
2427     nodeStack.append(term1.get());
2428     nodeStack.append(term2.get());
2429 }
2430
2431 // ECMA 11.7.2
2432 int32_t RightShiftNode::inlineEvaluateToInt32(ExecState* exec)
2433 {
2434     int i1 = term1->evaluateToInt32(exec);
2435     KJS_CHECKEXCEPTIONNUMBER
2436     unsigned int i2 = term2->evaluateToUInt32(exec) & 0x1f;
2437     return (i1 >> i2);
2438 }
2439
2440 JSValue* RightShiftNode::evaluate(ExecState* exec)
2441 {
2442     return jsNumber(inlineEvaluateToInt32(exec));
2443 }
2444
2445 double RightShiftNode::evaluateToNumber(ExecState* exec)
2446 {
2447     return inlineEvaluateToInt32(exec);
2448 }
2449
2450 int32_t RightShiftNode::evaluateToInt32(ExecState* exec)
2451 {
2452     return inlineEvaluateToInt32(exec);
2453 }
2454
2455 uint32_t RightShiftNode::evaluateToUInt32(ExecState* exec)
2456 {
2457     return inlineEvaluateToInt32(exec);
2458 }
2459
2460 void UnsignedRightShiftNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2461 {
2462     nodeStack.append(term1.get());
2463     nodeStack.append(term2.get());
2464 }
2465
2466 // ECMA 11.7.3
2467 uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(ExecState* exec)
2468 {
2469     unsigned int i1 = term1->evaluateToUInt32(exec);
2470     KJS_CHECKEXCEPTIONNUMBER
2471     unsigned int i2 = term2->evaluateToUInt32(exec) & 0x1f;
2472     return (i1 >> i2);
2473 }
2474
2475 JSValue* UnsignedRightShiftNode::evaluate(ExecState* exec)
2476 {
2477     return jsNumber(inlineEvaluateToUInt32(exec));
2478 }
2479
2480 double UnsignedRightShiftNode::evaluateToNumber(ExecState* exec)
2481 {
2482     return inlineEvaluateToUInt32(exec);
2483 }
2484
2485 int32_t UnsignedRightShiftNode::evaluateToInt32(ExecState* exec)
2486 {
2487     return inlineEvaluateToUInt32(exec);
2488 }
2489
2490 uint32_t UnsignedRightShiftNode::evaluateToUInt32(ExecState* exec)
2491 {
2492     return inlineEvaluateToUInt32(exec);
2493 }
2494
2495 // ------------------------------ Relational Nodes -------------------------------
2496
2497 static inline bool lessThan(ExecState *exec, JSValue* v1, JSValue* v2) 
2498 {
2499     double n1;
2500     double n2;
2501     JSValue* p1;
2502     JSValue* p2;
2503     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
2504     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
2505     
2506     if (wasNotString1 | wasNotString2)
2507         return n1 < n2;
2508
2509     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
2510 }
2511
2512 static inline bool lessThanEq(ExecState *exec, JSValue* v1, JSValue* v2) 
2513 {
2514     double n1;
2515     double n2;
2516     JSValue* p1;
2517     JSValue* p2;
2518     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
2519     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
2520     
2521     if (wasNotString1 | wasNotString2)
2522         return n1 <= n2;
2523
2524     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
2525 }
2526
2527 void LessNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2528 {
2529     nodeStack.append(expr2.get());
2530     nodeStack.append(expr1.get());
2531 }
2532
2533 // ECMA 11.8.1
2534 bool LessNode::inlineEvaluateToBoolean(ExecState* exec)
2535 {
2536     JSValue* v1 = expr1->evaluate(exec);
2537     KJS_CHECKEXCEPTIONBOOLEAN
2538     JSValue* v2 = expr2->evaluate(exec);
2539     KJS_CHECKEXCEPTIONBOOLEAN
2540     return lessThan(exec, v1, v2);
2541 }
2542
2543 JSValue* LessNode::evaluate(ExecState* exec)
2544 {
2545     return jsBoolean(inlineEvaluateToBoolean(exec));
2546 }
2547
2548 bool LessNode::evaluateToBoolean(ExecState* exec)
2549 {
2550     return inlineEvaluateToBoolean(exec);
2551 }
2552
2553 bool LessNumbersNode::inlineEvaluateToBoolean(ExecState* exec)
2554 {
2555     double n1 = expr1->evaluateToNumber(exec);
2556     KJS_CHECKEXCEPTIONVALUE
2557     double n2 = expr2->evaluateToNumber(exec);
2558     return n1 < n2;
2559 }
2560
2561 JSValue* LessNumbersNode::evaluate(ExecState* exec)
2562 {
2563     return jsBoolean(inlineEvaluateToBoolean(exec));
2564 }
2565
2566 bool LessNumbersNode::evaluateToBoolean(ExecState* exec)
2567 {
2568     return inlineEvaluateToBoolean(exec);
2569 }
2570
2571 bool LessStringsNode::inlineEvaluateToBoolean(ExecState* exec)
2572 {
2573     JSValue* v1 = expr1->evaluate(exec);
2574     KJS_CHECKEXCEPTIONVALUE
2575     JSValue* v2 = expr2->evaluate(exec);
2576     return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
2577 }
2578
2579 JSValue* LessStringsNode::evaluate(ExecState* exec)
2580 {
2581     return jsBoolean(inlineEvaluateToBoolean(exec));
2582 }
2583
2584 bool LessStringsNode::evaluateToBoolean(ExecState* exec)
2585 {
2586     return inlineEvaluateToBoolean(exec);
2587 }
2588
2589 void GreaterNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2590 {
2591     nodeStack.append(expr2.get());
2592     nodeStack.append(expr1.get());
2593 }
2594
2595 // ECMA 11.8.2
2596 bool GreaterNode::inlineEvaluateToBoolean(ExecState *exec)
2597 {
2598     JSValue* v1 = expr1->evaluate(exec);
2599     KJS_CHECKEXCEPTIONBOOLEAN
2600     JSValue* v2 = expr2->evaluate(exec);
2601     KJS_CHECKEXCEPTIONBOOLEAN
2602     return lessThan(exec, v2, v1);
2603 }
2604
2605 JSValue* GreaterNode::evaluate(ExecState* exec)
2606 {
2607     return jsBoolean(inlineEvaluateToBoolean(exec));
2608 }
2609
2610 bool GreaterNode::evaluateToBoolean(ExecState *exec)
2611 {
2612     return inlineEvaluateToBoolean(exec);
2613 }
2614
2615 void LessEqNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2616 {
2617     nodeStack.append(expr2.get());
2618     nodeStack.append(expr1.get());
2619 }
2620
2621 // ECMA 11.8.3
2622 bool LessEqNode::inlineEvaluateToBoolean(ExecState* exec)
2623 {
2624     JSValue* v1 = expr1->evaluate(exec);
2625     KJS_CHECKEXCEPTIONBOOLEAN
2626     JSValue* v2 = expr2->evaluate(exec);
2627     KJS_CHECKEXCEPTIONBOOLEAN
2628     return lessThanEq(exec, v1, v2);
2629 }
2630
2631 JSValue* LessEqNode::evaluate(ExecState* exec)
2632 {
2633     return jsBoolean(inlineEvaluateToBoolean(exec));
2634 }
2635
2636 bool LessEqNode::evaluateToBoolean(ExecState* exec)
2637 {
2638     return inlineEvaluateToBoolean(exec);
2639 }
2640
2641 void GreaterEqNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2642 {
2643     nodeStack.append(expr2.get());
2644     nodeStack.append(expr1.get());
2645 }
2646
2647 // ECMA 11.8.4
2648 bool GreaterEqNode::inlineEvaluateToBoolean(ExecState* exec)
2649 {
2650     JSValue* v1 = expr1->evaluate(exec);
2651     KJS_CHECKEXCEPTIONBOOLEAN
2652     JSValue* v2 = expr2->evaluate(exec);
2653     KJS_CHECKEXCEPTIONBOOLEAN
2654     return lessThanEq(exec, v2, v1);
2655 }
2656
2657 JSValue* GreaterEqNode::evaluate(ExecState* exec)
2658 {
2659     return jsBoolean(inlineEvaluateToBoolean(exec));
2660 }
2661
2662 bool GreaterEqNode::evaluateToBoolean(ExecState* exec)
2663 {
2664     return inlineEvaluateToBoolean(exec);
2665 }
2666
2667 void InstanceOfNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2668 {
2669     nodeStack.append(expr2.get());
2670     nodeStack.append(expr1.get());
2671 }
2672
2673 // ECMA 11.8.6
2674 JSValue* InstanceOfNode::evaluate(ExecState* exec)
2675 {
2676     JSValue* v1 = expr1->evaluate(exec);
2677     KJS_CHECKEXCEPTIONVALUE
2678     JSValue* v2 = expr2->evaluate(exec);
2679     KJS_CHECKEXCEPTIONVALUE
2680
2681     if (!v2->isObject())
2682         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
2683
2684     JSObject* o2 = static_cast<JSObject*>(v2);
2685
2686     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
2687     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
2688     // property. It seems that all objects have the property, but not all implement it, so in this
2689     // case we return false (consistent with Mozilla).
2690     if (!o2->implementsHasInstance())
2691         return jsBoolean(false);
2692
2693     return jsBoolean(o2->hasInstance(exec, v1));
2694 }
2695
2696 bool InstanceOfNode::evaluateToBoolean(ExecState* exec)
2697 {
2698     JSValue* v1 = expr1->evaluate(exec);
2699     KJS_CHECKEXCEPTIONBOOLEAN
2700     JSValue* v2 = expr2->evaluate(exec);
2701     KJS_CHECKEXCEPTIONBOOLEAN
2702
2703     if (!v2->isObject()) {
2704         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'instanceof' operator.", v2, expr2.get());
2705         return false;
2706     }
2707
2708     JSObject* o2 = static_cast<JSObject*>(v2);
2709
2710     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
2711     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
2712     // property. It seems that all objects have the property, but not all implement it, so in this
2713     // case we return false (consistent with Mozilla).
2714     if (!o2->implementsHasInstance())
2715         return false;
2716
2717     return o2->hasInstance(exec, v1);
2718 }
2719
2720 void InNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2721 {
2722     nodeStack.append(expr2.get());
2723     nodeStack.append(expr1.get());
2724 }
2725
2726 // ECMA 11.8.7
2727 JSValue* InNode::evaluate(ExecState *exec)
2728 {
2729     JSValue* v1 = expr1->evaluate(exec);
2730     KJS_CHECKEXCEPTIONVALUE
2731     JSValue* v2 = expr2->evaluate(exec);
2732     KJS_CHECKEXCEPTIONVALUE
2733
2734     if (!v2->isObject())
2735         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, expr2.get());
2736
2737     return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
2738 }
2739
2740 bool InNode::evaluateToBoolean(ExecState *exec)
2741 {
2742     JSValue* v1 = expr1->evaluate(exec);
2743     KJS_CHECKEXCEPTIONBOOLEAN
2744     JSValue* v2 = expr2->evaluate(exec);
2745     KJS_CHECKEXCEPTIONBOOLEAN
2746
2747     if (!v2->isObject()) {
2748         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, expr2.get());
2749         return false;
2750     }
2751
2752     return static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec)));
2753 }
2754
2755 // ------------------------------ Equality Nodes ------------------------------------
2756
2757 void EqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2758 {
2759     nodeStack.append(expr2.get());
2760     nodeStack.append(expr1.get());
2761 }
2762
2763 // ECMA 11.9.1
2764 bool EqualNode::inlineEvaluateToBoolean(ExecState* exec)
2765 {
2766     JSValue* v1 = expr1->evaluate(exec);
2767     KJS_CHECKEXCEPTIONBOOLEAN
2768     JSValue* v2 = expr2->evaluate(exec);
2769     KJS_CHECKEXCEPTIONBOOLEAN
2770     
2771     return equal(exec, v1, v2);
2772 }
2773
2774 JSValue* EqualNode::evaluate(ExecState* exec)
2775 {
2776     return jsBoolean(inlineEvaluateToBoolean(exec));
2777 }
2778
2779 bool EqualNode::evaluateToBoolean(ExecState* exec)
2780 {
2781     return inlineEvaluateToBoolean(exec);
2782 }
2783
2784 void NotEqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2785 {
2786     nodeStack.append(expr2.get());
2787     nodeStack.append(expr1.get());
2788 }
2789
2790 // ECMA 11.9.2
2791 bool NotEqualNode::inlineEvaluateToBoolean(ExecState* exec)
2792 {
2793     JSValue* v1 = expr1->evaluate(exec);
2794     KJS_CHECKEXCEPTIONBOOLEAN
2795     JSValue* v2 = expr2->evaluate(exec);
2796     KJS_CHECKEXCEPTIONBOOLEAN
2797
2798     return !equal(exec,v1, v2);
2799 }
2800
2801 JSValue* NotEqualNode::evaluate(ExecState* exec)
2802 {
2803     return jsBoolean(inlineEvaluateToBoolean(exec));
2804 }
2805
2806 bool NotEqualNode::evaluateToBoolean(ExecState* exec)
2807 {
2808     return inlineEvaluateToBoolean(exec);
2809 }
2810
2811 void StrictEqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2812 {
2813     nodeStack.append(expr2.get());
2814     nodeStack.append(expr1.get());
2815 }
2816
2817 // ECMA 11.9.4
2818 bool StrictEqualNode::inlineEvaluateToBoolean(ExecState* exec)
2819 {
2820     JSValue* v1 = expr1->evaluate(exec);
2821     KJS_CHECKEXCEPTIONBOOLEAN
2822     JSValue* v2 = expr2->evaluate(exec);
2823     KJS_CHECKEXCEPTIONBOOLEAN
2824
2825     return strictEqual(exec,v1, v2);
2826 }
2827
2828 JSValue* StrictEqualNode::evaluate(ExecState* exec)
2829 {
2830     return jsBoolean(inlineEvaluateToBoolean(exec));
2831 }
2832
2833 bool StrictEqualNode::evaluateToBoolean(ExecState* exec)
2834 {
2835     return inlineEvaluateToBoolean(exec);
2836 }
2837
2838 void NotStrictEqualNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2839 {
2840     nodeStack.append(expr2.get());
2841     nodeStack.append(expr1.get());
2842 }
2843
2844 // ECMA 11.9.5
2845 bool NotStrictEqualNode::inlineEvaluateToBoolean(ExecState* exec)
2846 {
2847     JSValue* v1 = expr1->evaluate(exec);
2848     KJS_CHECKEXCEPTIONBOOLEAN
2849     JSValue* v2 = expr2->evaluate(exec);
2850     KJS_CHECKEXCEPTIONBOOLEAN
2851
2852     return !strictEqual(exec,v1, v2);
2853 }
2854
2855 JSValue* NotStrictEqualNode::evaluate(ExecState* exec)
2856 {
2857     return jsBoolean(inlineEvaluateToBoolean(exec));
2858 }
2859
2860 bool NotStrictEqualNode::evaluateToBoolean(ExecState* exec)
2861 {
2862     return inlineEvaluateToBoolean(exec);
2863 }
2864
2865 // ------------------------------ Bit Operation Nodes ----------------------------------
2866
2867 void BitAndNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2868 {
2869     nodeStack.append(expr2.get());
2870     nodeStack.append(expr1.get());
2871 }
2872
2873 // ECMA 11.10
2874 JSValue* BitAndNode::evaluate(ExecState* exec)
2875 {    
2876     JSValue *v1 = expr1->evaluate(exec);
2877     KJS_CHECKEXCEPTIONVALUE
2878     JSValue *v2 = expr2->evaluate(exec);
2879     KJS_CHECKEXCEPTIONVALUE
2880
2881     return jsNumberFromAnd(exec, v1, v2);
2882 }
2883
2884 int32_t BitAndNode::inlineEvaluateToInt32(ExecState* exec)
2885 {
2886     int32_t i1 = expr1->evaluateToInt32(exec);
2887     KJS_CHECKEXCEPTIONNUMBER
2888     int32_t i2 = expr2->evaluateToInt32(exec);
2889     return (i1 & i2);
2890 }
2891
2892 double BitAndNode::evaluateToNumber(ExecState* exec)
2893 {
2894     return inlineEvaluateToInt32(exec);
2895 }
2896
2897 bool BitAndNode::evaluateToBoolean(ExecState* exec)
2898 {
2899     return inlineEvaluateToInt32(exec);
2900 }
2901
2902 int32_t BitAndNode::evaluateToInt32(ExecState* exec)
2903 {
2904     return inlineEvaluateToInt32(exec);
2905 }
2906
2907 uint32_t BitAndNode::evaluateToUInt32(ExecState* exec)
2908 {
2909     return inlineEvaluateToInt32(exec);
2910 }
2911
2912 void BitXOrNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2913 {
2914     nodeStack.append(expr2.get());
2915     nodeStack.append(expr1.get());
2916 }
2917
2918 int32_t BitXOrNode::inlineEvaluateToInt32(ExecState* exec)
2919 {
2920     int i1 = expr1->evaluateToInt32(exec);
2921     KJS_CHECKEXCEPTIONNUMBER
2922     int i2 = expr2->evaluateToInt32(exec);
2923     return (i1 ^ i2);
2924 }
2925
2926 JSValue* BitXOrNode::evaluate(ExecState* exec)
2927 {
2928     return jsNumber(inlineEvaluateToInt32(exec));
2929 }
2930
2931 double BitXOrNode::evaluateToNumber(ExecState* exec)
2932 {
2933     return inlineEvaluateToInt32(exec);
2934 }
2935
2936 bool BitXOrNode::evaluateToBoolean(ExecState* exec)
2937 {
2938     return inlineEvaluateToInt32(exec);
2939 }
2940
2941 int32_t BitXOrNode::evaluateToInt32(ExecState* exec)
2942 {
2943     return inlineEvaluateToInt32(exec);
2944 }
2945
2946 uint32_t BitXOrNode::evaluateToUInt32(ExecState* exec)
2947 {
2948     return inlineEvaluateToInt32(exec);
2949 }
2950
2951 void BitOrNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2952 {
2953     nodeStack.append(expr2.get());
2954     nodeStack.append(expr1.get());
2955 }
2956
2957 int32_t BitOrNode::inlineEvaluateToInt32(ExecState* exec)
2958 {
2959     int i1 = expr1->evaluateToInt32(exec);
2960     KJS_CHECKEXCEPTIONNUMBER
2961     int i2 = expr2->evaluateToInt32(exec);
2962     return (i1 | i2);
2963 }
2964
2965 JSValue* BitOrNode::evaluate(ExecState* exec)
2966 {
2967     return jsNumber(inlineEvaluateToInt32(exec));
2968 }
2969
2970 double BitOrNode::evaluateToNumber(ExecState* exec)
2971 {
2972     return inlineEvaluateToInt32(exec);
2973 }
2974
2975 bool BitOrNode::evaluateToBoolean(ExecState* exec)
2976 {
2977     return inlineEvaluateToInt32(exec);
2978 }
2979
2980 int32_t BitOrNode::evaluateToInt32(ExecState* exec)
2981 {
2982     return inlineEvaluateToInt32(exec);
2983 }
2984
2985 uint32_t BitOrNode::evaluateToUInt32(ExecState* exec)
2986 {
2987     return inlineEvaluateToInt32(exec);
2988 }
2989
2990 // ------------------------------ Binary Logical Nodes ----------------------------
2991
2992 void LogicalAndNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
2993 {
2994     nodeStack.append(expr2.get());
2995     nodeStack.append(expr1.get());
2996 }
2997
2998 // ECMA 11.11
2999 JSValue* LogicalAndNode::evaluate(ExecState* exec)
3000 {
3001     JSValue* v1 = expr1->evaluate(exec);
3002     KJS_CHECKEXCEPTIONVALUE
3003     bool b1 = v1->toBoolean(exec);
3004     KJS_CHECKEXCEPTIONVALUE
3005     if (!b1)
3006         return v1;
3007     JSValue* v2 = expr2->evaluate(exec);
3008     KJS_CHECKEXCEPTIONVALUE
3009     return v2;
3010 }
3011
3012 bool LogicalAndNode::evaluateToBoolean(ExecState* exec)
3013 {
3014     bool b = expr1->evaluateToBoolean(exec);
3015     KJS_CHECKEXCEPTIONBOOLEAN
3016     return b && expr2->evaluateToBoolean(exec);
3017 }
3018
3019 void LogicalOrNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3020 {
3021     nodeStack.append(expr2.get());
3022     nodeStack.append(expr1.get());
3023 }
3024
3025 JSValue* LogicalOrNode::evaluate(ExecState* exec)
3026 {
3027     JSValue* v1 = expr1->evaluate(exec);
3028     KJS_CHECKEXCEPTIONVALUE
3029     if (v1->toBoolean(exec))
3030         return v1;
3031     return expr2->evaluate(exec);
3032 }
3033
3034 bool LogicalOrNode::evaluateToBoolean(ExecState* exec)
3035 {
3036     bool b = expr1->evaluateToBoolean(exec);
3037     KJS_CHECKEXCEPTIONBOOLEAN
3038     return b || expr2->evaluateToBoolean(exec);
3039 }
3040
3041 // ------------------------------ ConditionalNode ------------------------------
3042
3043 void ConditionalNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3044 {
3045     nodeStack.append(expr2.get());
3046     nodeStack.append(expr1.get());
3047     nodeStack.append(logical.get());
3048 }
3049
3050 // ECMA 11.12
3051 JSValue* ConditionalNode::evaluate(ExecState* exec)
3052 {
3053     bool b = logical->evaluateToBoolean(exec);
3054     KJS_CHECKEXCEPTIONVALUE
3055     return b ? expr1->evaluate(exec) : expr2->evaluate(exec);
3056 }
3057
3058 bool ConditionalNode::evaluateToBoolean(ExecState* exec)
3059 {
3060     bool b = logical->evaluateToBoolean(exec);
3061     KJS_CHECKEXCEPTIONBOOLEAN
3062     return b ? expr1->evaluateToBoolean(exec) : expr2->evaluateToBoolean(exec);
3063 }
3064
3065 double ConditionalNode::evaluateToNumber(ExecState* exec)
3066 {
3067     bool b = logical->evaluateToBoolean(exec);
3068     KJS_CHECKEXCEPTIONNUMBER
3069     return b ? expr1->evaluateToNumber(exec) : expr2->evaluateToNumber(exec);
3070 }
3071
3072 int32_t ConditionalNode::evaluateToInt32(ExecState* exec)
3073 {
3074     bool b = logical->evaluateToBoolean(exec);
3075     KJS_CHECKEXCEPTIONNUMBER
3076     return b ? expr1->evaluateToInt32(exec) : expr2->evaluateToInt32(exec);
3077 }
3078
3079 uint32_t ConditionalNode::evaluateToUInt32(ExecState* exec)
3080 {
3081     bool b = logical->evaluateToBoolean(exec);
3082     KJS_CHECKEXCEPTIONNUMBER
3083     return b ? expr1->evaluateToUInt32(exec) : expr2->evaluateToUInt32(exec);
3084 }
3085
3086 // ECMA 11.13
3087
3088 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
3089 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
3090 {
3091   JSValue *v;
3092   int i1;
3093   int i2;
3094   unsigned int ui;
3095   switch (oper) {
3096   case OpMultEq:
3097     v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec));
3098     break;
3099   case OpDivEq:
3100     v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec));
3101     break;
3102   case OpPlusEq:
3103     v = add(exec, current, right->evaluate(exec));
3104     break;
3105   case OpMinusEq:
3106     v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec));
3107     break;
3108   case OpLShift:
3109     i1 = current->toInt32(exec);
3110     i2 = right->evaluateToInt32(exec);
3111     v = jsNumber(i1 << i2);
3112     break;
3113   case OpRShift:
3114     i1 = current->toInt32(exec);
3115     i2 = right->evaluateToInt32(exec);
3116     v = jsNumber(i1 >> i2);
3117     break;
3118   case OpURShift:
3119     ui = current->toUInt32(exec);
3120     i2 = right->evaluateToInt32(exec);
3121     v = jsNumber(ui >> i2);
3122     break;
3123   case OpAndEq:
3124     i1 = current->toInt32(exec);
3125     i2 = right->evaluateToInt32(exec);
3126     v = jsNumber(i1 & i2);
3127     break;
3128   case OpXOrEq:
3129     i1 = current->toInt32(exec);
3130     i2 = right->evaluateToInt32(exec);
3131     v = jsNumber(i1 ^ i2);
3132     break;
3133   case OpOrEq:
3134     i1 = current->toInt32(exec);
3135     i2 = right->evaluateToInt32(exec);
3136     v = jsNumber(i1 | i2);
3137     break;
3138   case OpModEq: {
3139     double d1 = current->toNumber(exec);
3140     double d2 = right->evaluateToNumber(exec);
3141     v = jsNumber(fmod(d1, d2));
3142   }
3143     break;
3144   default:
3145     ASSERT_NOT_REACHED();
3146     v = jsUndefined();
3147   }
3148   
3149   return v;
3150 }
3151
3152 // ------------------------------ ReadModifyResolveNode -----------------------------------
3153
3154 void ReadModifyResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack& nodeStack)
3155 {
3156     nodeStack.append(m_right.get());
3157     size_t index = symbolTable.get(m_ident.ustring().rep());
3158     if (index != missingSymbolMarker())
3159         new (this) ReadModifyLocalVarNode(index);
3160 }
3161
3162 void AssignResolveNode::optimizeVariableAccess(SymbolTable& symbolTable, DeclarationStacks::NodeStack& nodeStack)
3163 {
3164     nodeStack.append(m_right.get());
3165     size_t index = symbolTable.get(m_ident.ustring().rep());
3166     if (index != missingSymbolMarker())
3167         new (this) AssignLocalVarNode(index);
3168 }
3169
3170 JSValue* ReadModifyLocalVarNode::evaluate(ExecState* exec)
3171 {
3172     ASSERT(exec->variableObject() == exec->scopeChain().top());
3173     JSValue** slot = &exec->localStorage()[m_index].value;
3174
3175     ASSERT(m_oper != OpEqual);
3176     JSValue* v = valueForReadModifyAssignment(exec, *slot, m_right.get(), m_oper);
3177
3178     KJS_CHECKEXCEPTIONVALUE
3179
3180     *slot = v;
3181     return v;
3182 }
3183
3184 JSValue* AssignLocalVarNode::evaluate(ExecState* exec)
3185 {
3186     ASSERT(exec->variableObject() == exec->scopeChain().top());
3187     JSValue* v = m_right->evaluate(exec);
3188
3189     KJS_CHECKEXCEPTIONVALUE
3190
3191     exec->localStorage()[m_index].value = v;
3192     
3193     return v;
3194 }
3195
3196 JSValue *ReadModifyResolveNode::evaluate(ExecState *exec)
3197 {
3198   const ScopeChain& chain = exec->scopeChain();
3199   ScopeChainIterator iter = chain.begin();
3200   ScopeChainIterator end = chain.end();
3201   
3202   // we must always have something in the scope chain
3203   ASSERT(iter != end);
3204
3205   PropertySlot slot;
3206   JSObject *base;
3207   do { 
3208     base = *iter;
3209     if (base->getPropertySlot(exec, m_ident, slot))
3210       goto found;
3211
3212     ++iter;
3213   } while (iter != end);
3214
3215   ASSERT(m_oper != OpEqual);
3216   return throwUndefinedVariableError(exec, m_ident);
3217
3218  found:
3219   JSValue *v;
3220
3221   
3222   ASSERT(m_oper != OpEqual);
3223   JSValue *v1 = slot.getValue(exec, base, m_ident);
3224   KJS_CHECKEXCEPTIONVALUE
3225   v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper);
3226
3227   KJS_CHECKEXCEPTIONVALUE
3228
3229   base->put(exec, m_ident, v);
3230   return v;
3231 }
3232
3233 JSValue *AssignResolveNode::evaluate(ExecState *exec)
3234 {
3235   const ScopeChain& chain = exec->scopeChain();
3236   ScopeChainIterator iter = chain.begin();
3237   ScopeChainIterator end = chain.end();
3238   
3239   // we must always have something in the scope chain
3240   ASSERT(iter != end);
3241
3242   PropertySlot slot;
3243   JSObject *base;
3244   do { 
3245     base = *iter;
3246     if (base->getPropertySlot(exec, m_ident, slot))
3247       goto found;
3248
3249     ++iter;
3250   } while (iter != end);
3251
3252  found:
3253   JSValue *v = m_right->evaluate(exec);
3254
3255   KJS_CHECKEXCEPTIONVALUE
3256
3257   base->put(exec, m_ident, v);
3258   return v;
3259 }
3260
3261 // ------------------------------ ReadModifyDotNode -----------------------------------
3262
3263 void AssignDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3264 {
3265     nodeStack.append(m_right.get());
3266     nodeStack.append(m_base.get());
3267 }
3268
3269 JSValue *AssignDotNode::evaluate(ExecState *exec)
3270 {
3271   JSValue *baseValue = m_base->evaluate(exec);
3272   KJS_CHECKEXCEPTIONVALUE
3273   JSObject *base = baseValue->toObject(exec);
3274
3275   JSValue *v = m_right->evaluate(exec);
3276
3277   KJS_CHECKEXCEPTIONVALUE
3278
3279   base->put(exec, m_ident, v);
3280   return v;
3281 }
3282
3283 void ReadModifyDotNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3284 {
3285     nodeStack.append(m_right.get());
3286     nodeStack.append(m_base.get());
3287 }
3288
3289 JSValue *ReadModifyDotNode::evaluate(ExecState *exec)
3290 {
3291   JSValue *baseValue = m_base->evaluate(exec);
3292   KJS_CHECKEXCEPTIONVALUE
3293   JSObject *base = baseValue->toObject(exec);
3294
3295   JSValue *v;
3296
3297   ASSERT(m_oper != OpEqual);
3298   PropertySlot slot;
3299   JSValue *v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
3300   KJS_CHECKEXCEPTIONVALUE
3301   v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper);
3302
3303   KJS_CHECKEXCEPTIONVALUE
3304
3305   base->put(exec, m_ident, v);
3306   return v;
3307 }
3308
3309 // ------------------------------ AssignErrorNode -----------------------------------
3310
3311 JSValue* AssignErrorNode::evaluate(ExecState* exec)
3312 {
3313     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
3314     handleException(exec);
3315     return jsUndefined();
3316 }
3317
3318 // ------------------------------ AssignBracketNode -----------------------------------
3319
3320 void AssignBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3321 {
3322     nodeStack.append(m_right.get());
3323     nodeStack.append(m_subscript.get());
3324     nodeStack.append(m_base.get());
3325 }
3326
3327 JSValue *AssignBracketNode::evaluate(ExecState *exec)
3328 {
3329   JSValue *baseValue = m_base->evaluate(exec);
3330   KJS_CHECKEXCEPTIONVALUE
3331   JSValue *subscript = m_subscript->evaluate(exec);
3332   KJS_CHECKEXCEPTIONVALUE
3333
3334   JSObject *base = baseValue->toObject(exec);
3335
3336   uint32_t propertyIndex;
3337   if (subscript->getUInt32(propertyIndex)) {
3338     JSValue *v = m_right->evaluate(exec);
3339     KJS_CHECKEXCEPTIONVALUE
3340
3341     base->put(exec, propertyIndex, v);
3342     return v;
3343   }
3344
3345   Identifier propertyName(subscript->toString(exec));
3346   JSValue *v = m_right->evaluate(exec);
3347   KJS_CHECKEXCEPTIONVALUE
3348
3349   base->put(exec, propertyName, v);
3350   return v;
3351 }
3352 void ReadModifyBracketNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3353 {
3354     nodeStack.append(m_right.get());
3355     nodeStack.append(m_subscript.get());
3356     nodeStack.append(m_base.get());
3357 }
3358
3359 JSValue *ReadModifyBracketNode::evaluate(ExecState *exec)
3360 {
3361   JSValue *baseValue = m_base->evaluate(exec);
3362   KJS_CHECKEXCEPTIONVALUE
3363   JSValue *subscript = m_subscript->evaluate(exec);
3364   KJS_CHECKEXCEPTIONVALUE
3365
3366   JSObject *base = baseValue->toObject(exec);
3367
3368   uint32_t propertyIndex;
3369   if (subscript->getUInt32(propertyIndex)) {
3370     JSValue *v;
3371     ASSERT(m_oper != OpEqual);
3372     PropertySlot slot;
3373     JSValue *v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
3374     KJS_CHECKEXCEPTIONVALUE
3375     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper);
3376
3377     KJS_CHECKEXCEPTIONVALUE
3378
3379     base->put(exec, propertyIndex, v);
3380     return v;
3381   }
3382
3383   Identifier propertyName(subscript->toString(exec));
3384   JSValue *v;
3385
3386   ASSERT(m_oper != OpEqual);
3387   PropertySlot slot;
3388   JSValue *v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
3389   KJS_CHECKEXCEPTIONVALUE
3390   v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper);
3391
3392   KJS_CHECKEXCEPTIONVALUE
3393
3394   base->put(exec, propertyName, v);
3395   return v;
3396 }
3397
3398 // ------------------------------ CommaNode ------------------------------------
3399
3400 void CommaNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3401 {
3402     nodeStack.append(expr2.get());
3403     nodeStack.append(expr1.get());
3404 }
3405
3406 // ECMA 11.14
3407 JSValue* CommaNode::evaluate(ExecState *exec)
3408 {
3409     expr1->evaluate(exec);
3410     KJS_CHECKEXCEPTIONVALUE
3411     return expr2->evaluate(exec);
3412 }
3413
3414 // ------------------------------ AssignExprNode -------------------------------
3415
3416 void AssignExprNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3417 {
3418     nodeStack.append(expr.get());
3419 }
3420
3421 // ECMA 12.2
3422 JSValue* AssignExprNode::evaluate(ExecState* exec)
3423 {
3424     return expr->evaluate(exec);
3425 }
3426
3427 bool AssignExprNode::evaluateToBoolean(ExecState* exec)
3428 {
3429     return expr->evaluateToBoolean(exec);
3430 }
3431
3432 double AssignExprNode::evaluateToNumber(ExecState* exec)
3433 {
3434     return expr->evaluateToNumber(exec);
3435 }
3436
3437 int32_t AssignExprNode::evaluateToInt32(ExecState* exec)
3438 {
3439     return expr->evaluateToInt32(exec);
3440 }
3441
3442 uint32_t AssignExprNode::evaluateToUInt32(ExecState* exec)
3443 {
3444     return expr->evaluateToInt32(exec);
3445 }
3446
3447 // ------------------------------ VarDeclNode ----------------------------------
3448
3449 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t)
3450     : varType(t)
3451     , ident(id)
3452     , init(in)
3453 {
3454     m_mayHaveDeclarations = true; 
3455 }
3456
3457 void VarDeclNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3458 {
3459     if (next)
3460         nodeStack.append(next.get());
3461     if (init)
3462         nodeStack.append(init.get());
3463 }
3464
3465 void VarDeclNode::getDeclarations(DeclarationStacks& stacks)
3466 {
3467     if (next) {
3468         ASSERT(next->mayHaveDeclarations());
3469         stacks.nodeStack.append(next.get()); 
3470     }
3471
3472     // The normal check to avoid overwriting pre-existing values with variable
3473     // declarations doesn't work for the "arguments" property because we 
3474     // instantiate it lazily. So we need to check here instead.
3475     if (ident == stacks.exec->propertyNames().arguments)
3476         return;
3477
3478     stacks.varStack.append(this); 
3479 }
3480
3481 void VarDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
3482 {
3483     ScopeChainIterator iter = chain.begin();
3484     ScopeChainIterator end = chain.end();
3485     
3486     // we must always have something in the scope chain
3487     ASSERT(iter != end);
3488     
3489     PropertySlot slot;
3490     JSObject* base;
3491     
3492     do {
3493         base = *iter;
3494         if (base->getPropertySlot(exec, ident, slot))
3495             break;
3496         
3497         ++iter;
3498     } while (iter != end);
3499     
3500     unsigned flags = 0;
3501     base->getPropertyAttributes(ident, flags);
3502     if (varType == VarDeclNode::Constant)
3503         flags |= ReadOnly;
3504     
3505     base->put(exec, ident, val, flags);
3506 }
3507
3508 // ECMA 12.2
3509 inline void VarDeclNode::evaluateSingle(ExecState* exec)
3510 {
3511     const ScopeChain& chain = exec->scopeChain();
3512     JSObject* variableObject = exec->variableObject();
3513
3514     ASSERT(!chain.isEmpty());
3515
3516     bool inGlobalScope = ++chain.begin() == chain.end();
3517
3518     if (inGlobalScope && (init || !variableObject->getDirect(ident))) {
3519         JSValue* val = init ? init->evaluate(exec) : jsUndefined();
3520         int flags = Internal;
3521         if (exec->codeType() != EvalCode)
3522             flags |= DontDelete;
3523         if (varType == VarDeclNode::Constant)
3524             flags |= ReadOnly;
3525         variableObject->putDirect(ident, val, flags);
3526     } else if (init) {
3527         JSValue* val = init->evaluate(exec);
3528         KJS_CHECKEXCEPTIONVOID
3529             
3530         // if the variable object is the top of the scope chain, then that must
3531         // be where this variable is declared, processVarDecls would have put 
3532         // it there. Don't search the scope chain, to optimize this very common case.
3533         if (chain.top() != variableObject)
3534             return handleSlowCase(exec, chain, val);
3535
3536         unsigned flags = 0;
3537         variableObject->getPropertyAttributes(ident, flags);
3538         if (varType == VarDeclNode::Constant)
3539             flags |= ReadOnly;
3540         
3541         ASSERT(variableObject->hasProperty(exec, ident));
3542         variableObject->put(exec, ident, val, flags);
3543     }
3544 }
3545
3546 JSValue* VarDeclNode::evaluate(ExecState* exec)
3547 {
3548     evaluateSingle(exec);
3549
3550     if (VarDeclNode* n = next.get()) {
3551         do {
3552             n->evaluateSingle(exec);
3553             KJS_CHECKEXCEPTIONVALUE
3554             n = n->next.get();
3555         } while (n);
3556     }
3557     return jsUndefined();
3558 }
3559
3560 // ------------------------------ VarStatementNode -----------------------------
3561
3562 void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3563 {
3564     ASSERT(next);
3565     nodeStack.append(next.get());
3566 }
3567
3568 // ECMA 12.2
3569 Completion VarStatementNode::execute(ExecState *exec)
3570 {
3571     KJS_BREAKPOINT;
3572
3573     next->evaluate(exec);
3574     KJS_CHECKEXCEPTION
3575
3576     return Completion(Normal);
3577 }
3578
3579 void VarStatementNode::getDeclarations(DeclarationStacks& stacks)
3580 {
3581     ASSERT(next->mayHaveDeclarations());
3582     stacks.nodeStack.append(next.get());
3583 }
3584
3585 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
3586
3587 static inline void statementListPushFIFO(SourceElements& statements, DeclarationStacks::NodeStack& stack)
3588 {
3589     SourceElements::iterator it = statements.end();
3590     SourceElements::iterator begin = statements.begin();
3591     while (it != begin) {
3592         --it;
3593         stack.append((*it).get());
3594     }
3595 }
3596
3597 static inline void statementListGetDeclarations(SourceElements& statements, DeclarationStacks& stacks)
3598 {
3599     SourceElements::iterator it = statements.end();
3600     SourceElements::iterator begin = statements.begin();
3601     while (it != begin) {
3602         --it;
3603         if ((*it)->mayHaveDeclarations())
3604             stacks.nodeStack.append((*it).get());
3605     }
3606 }
3607
3608 static inline Node* statementListInitializeDeclarationStack(SourceElements& statements, DeclarationStacks::NodeStack& stack)
3609 {
3610     ASSERT(!stack.size()); // Otherwise, the removeLast() call might remove someone else's node.
3611     
3612     SourceElements::iterator it = statements.end();
3613     SourceElements::iterator begin = statements.begin();
3614     
3615     while (it != begin) {
3616         --it;
3617         if ((*it)->mayHaveDeclarations())
3618              stack.append((*it).get());
3619     }
3620
3621     if (!stack.size())
3622         return 0;
3623
3624     Node* n = stack.last();
3625     stack.removeLast();
3626     return n;
3627 }
3628
3629 static inline Node* statementListInitializeVariableAccessStack(SourceElements& statements, DeclarationStacks::NodeStack& stack)
3630 {
3631     if (!statements.size())
3632         return 0;
3633
3634     SourceElements::iterator it = statements.end();
3635     SourceElements::iterator begin = statements.begin();
3636     SourceElements::iterator beginPlusOne = begin + 1;
3637     
3638     while (it != beginPlusOne) {
3639         --it;
3640         stack.append((*it).get());
3641     }
3642
3643     return (*begin).get();
3644 }
3645
3646 static inline Completion statementListExecute(SourceElements& statements, ExecState* exec)
3647 {
3648     JSValue* v = 0;
3649     Completion c(Normal);
3650     const SourceElements::iterator end = statements.end();
3651     for (SourceElements::iterator ptr = statements.begin(); ptr != end; ++ptr) {
3652         c = (*ptr)->execute(exec);
3653         
3654         if (JSValue* v2 = c.value())
3655             v = v2;
3656         c.setValue(v);
3657         
3658         if (c.complType() != Normal)
3659             return c;
3660     }
3661     return c;
3662 }
3663     
3664 // ------------------------------ BlockNode ------------------------------------
3665
3666 BlockNode::BlockNode(SourceElements* children)
3667     : m_children(children)
3668 {
3669     ASSERT(m_children);
3670     m_mayHaveDeclarations = true; 
3671 }
3672
3673 void BlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3674 {
3675     statementListPushFIFO(*m_children, nodeStack);
3676 }
3677
3678 void BlockNode::getDeclarations(DeclarationStacks& stacks)
3679
3680     statementListGetDeclarations(*m_children, stacks);
3681 }
3682
3683 // ECMA 12.1
3684 Completion BlockNode::execute(ExecState *exec)
3685 {
3686     return statementListExecute(*m_children, exec);
3687 }
3688
3689 // ------------------------------ EmptyStatementNode ---------------------------
3690
3691 // ECMA 12.3
3692 Completion EmptyStatementNode::execute(ExecState *)
3693 {
3694   return Completion(Normal);
3695 }
3696
3697 // ------------------------------ ExprStatementNode ----------------------------
3698
3699 void ExprStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3700 {
3701     ASSERT(expr);
3702     nodeStack.append(expr.get());
3703 }
3704
3705 // ECMA 12.4
3706 Completion ExprStatementNode::execute(ExecState *exec)
3707 {
3708   KJS_BREAKPOINT;
3709
3710   JSValue *v = expr->evaluate(exec);
3711   KJS_CHECKEXCEPTION
3712
3713   return Completion(Normal, v);
3714 }
3715
3716 // ------------------------------ IfNode ---------------------------------------
3717
3718 void IfNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3719 {
3720     if (statement2)
3721         nodeStack.append(statement2.get());
3722     ASSERT(statement1);
3723     nodeStack.append(statement1.get());
3724     ASSERT(expr);
3725     nodeStack.append(expr.get());
3726 }
3727
3728 // ECMA 12.5
3729 Completion IfNode::execute(ExecState* exec)
3730 {
3731     KJS_BREAKPOINT;
3732
3733     bool b = expr->evaluateToBoolean(exec);
3734     KJS_CHECKEXCEPTION
3735
3736     // if ... then
3737     if (b)
3738         return statement1->execute(exec);
3739
3740     // no else
3741     if (!statement2)
3742         return Completion(Normal);
3743
3744     // else
3745     return statement2->execute(exec);
3746 }
3747
3748 void IfNode::getDeclarations(DeclarationStacks& stacks)
3749
3750     if (statement2 && statement2->mayHaveDeclarations()) 
3751         stacks.nodeStack.append(statement2.get()); 
3752     if (statement1->mayHaveDeclarations()) 
3753         stacks.nodeStack.append(statement1.get()); 
3754 }
3755
3756 // ------------------------------ DoWhileNode ----------------------------------
3757
3758 void DoWhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3759 {
3760     nodeStack.append(statement.get());
3761     nodeStack.append(expr.get());
3762 }
3763
3764 // ECMA 12.6.1
3765 Completion DoWhileNode::execute(ExecState *exec)
3766 {
3767     KJS_BREAKPOINT;
3768
3769     JSValue* value = 0;
3770
3771     while (1) {
3772         exec->pushIteration();
3773         Completion c = statement->execute(exec);
3774         exec->popIteration();
3775
3776         if (exec->dynamicGlobalObject()->timedOut())
3777             return Completion(Interrupted);
3778
3779         if (c.isValueCompletion())
3780             value = c.value();
3781
3782         if (!((c.complType() == Continue) && ls.contains(c.target()))) {
3783             if ((c.complType() == Break) && ls.contains(c.target()))
3784                 return Completion(Normal, value);
3785             if (c.complType() != Normal)
3786                 return c;
3787         }
3788
3789         bool b = expr->evaluateToBoolean(exec);
3790         KJS_CHECKEXCEPTION
3791         if (!b)
3792             return Completion(Normal, value);
3793     }
3794
3795     return Completion(); // work around gcc 4.0 bug
3796 }
3797
3798 void DoWhileNode::getDeclarations(DeclarationStacks& stacks)
3799
3800     if (statement->mayHaveDeclarations()) 
3801         stacks.nodeStack.append(statement.get()); 
3802 }
3803
3804 // ------------------------------ WhileNode ------------------------------------
3805
3806 void WhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3807 {
3808     nodeStack.append(statement.get());
3809     nodeStack.append(expr.get());
3810 }
3811
3812 // ECMA 12.6.2
3813 Completion WhileNode::execute(ExecState *exec)
3814 {
3815     KJS_BREAKPOINT;
3816
3817     JSValue* value = 0;
3818
3819     while (1) {
3820         bool b = expr->evaluateToBoolean(exec);
3821         KJS_CHECKEXCEPTION
3822         if (!b)
3823             return Completion(Normal, value);
3824
3825         exec->pushIteration();
3826         Completion c = statement->execute(exec);
3827         exec->popIteration();
3828
3829         if (exec->dynamicGlobalObject()->timedOut())
3830             return Completion(Interrupted);
3831     
3832         if (c.isValueCompletion())
3833             value = c.value();
3834
3835         if ((c.complType() == Continue) && ls.contains(c.target()))
3836             continue;
3837         if ((c.complType() == Break) && ls.contains(c.target()))
3838             return Completion(Normal, value);
3839         if (c.complType() != Normal)
3840             return c;
3841     }
3842
3843     return Completion(); // work around gcc 4.0 bug
3844 }
3845
3846 void WhileNode::getDeclarations(DeclarationStacks& stacks)
3847
3848     if (statement->mayHaveDeclarations()) 
3849         stacks.nodeStack.append(statement.get()); 
3850 }
3851
3852 // ------------------------------ ForNode --------------------------------------
3853
3854 void ForNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3855 {
3856     nodeStack.append(statement.get());
3857     if (expr3)
3858         nodeStack.append(expr3.get());
3859     if (expr2)
3860         nodeStack.append(expr2.get());
3861     if (expr1)
3862         nodeStack.append(expr1.get());
3863 }
3864
3865 // ECMA 12.6.3
3866 Completion ForNode::execute(ExecState *exec)
3867 {
3868     JSValue* cval = 0;
3869
3870     if (expr1) {
3871         expr1->evaluate(exec);
3872         KJS_CHECKEXCEPTION
3873     }
3874
3875     while (1) {
3876         if (expr2) {
3877             bool b = expr2->evaluateToBoolean(exec);
3878             KJS_CHECKEXCEPTION
3879             if (!b)
3880                 return Completion(Normal, cval);
3881         }
3882
3883         exec->pushIteration();
3884         Completion c = statement->execute(exec);
3885         exec->popIteration();
3886         if (c.isValueCompletion())
3887             cval = c.value();
3888         if (!((c.complType() == Continue) && ls.contains(c.target()))) {
3889             if ((c.complType() == Break) && ls.contains(c.target()))
3890                 return Completion(Normal, cval);
3891             if (c.complType() != Normal)
3892                 return c;
3893         }
3894
3895         if (exec->dynamicGlobalObject()->timedOut())
3896             return Completion(Interrupted);
3897
3898         if (expr3) {
3899             expr3->evaluate(exec);
3900             KJS_CHECKEXCEPTION
3901         }
3902     }
3903   
3904     return Completion(); // work around gcc 4.0 bug
3905 }
3906
3907 void ForNode::getDeclarations(DeclarationStacks& stacks)
3908
3909     if (statement->mayHaveDeclarations()) 
3910         stacks.nodeStack.append(statement.get()); 
3911     if (expr1 && expr1->mayHaveDeclarations()) 
3912         stacks.nodeStack.append(expr1.get()); 
3913 }
3914
3915 // ------------------------------ ForInNode ------------------------------------
3916
3917 ForInNode::ForInNode(ExpressionNode* l, ExpressionNode* e, StatementNode* s)
3918   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
3919 {
3920     m_mayHaveDeclarations = true; 
3921 }
3922
3923 ForInNode::ForInNode(const Identifier& i, AssignExprNode* in, ExpressionNode* e, StatementNode* s)
3924   : ident(i), init(in), expr(e), statement(s)
3925 {
3926   m_mayHaveDeclarations = true; 
3927
3928   // for( var foo = bar in baz )
3929   varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
3930   lexpr = new ResolveNode(ident);
3931 }
3932
3933 void ForInNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack& nodeStack)
3934 {
3935     nodeStack.append(statement.get());
3936     nodeStack.append(expr.get());
3937     nodeStack.append(lexpr.get());
3938     if (varDecl)
3939         nodeStack.append(varDecl.get());
3940 }
3941
3942 void ForInNode::getDeclarations(DeclarationStacks& stacks)
3943
3944     if (statement->mayHaveDeclarations()) 
3945         stacks.nodeStack.append(statement.get()); 
3946     if (varDecl && varDecl->mayHaveDeclarations())