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