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