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