Optimise multi-scope function call resolution
[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             JSObject* thisObj = base;
1126             // ECMA 11.2.3 says that in this situation the this value should be null.
1127             // However, section 10.2.3 says that in the case where the value provided
1128             // by the caller is null, the global object should be used. It also says
1129             // that the section does not apply to internal functions, but for simplicity
1130             // of implementation we use the global object anyway here. This guarantees
1131             // that in host objects you always get a valid object for this.
1132             if (thisObj->isActivationObject())
1133                 thisObj = exec->dynamicGlobalObject();
1134
1135             if (callerType == EvalOperator) {
1136                 if (base == exec->lexicalGlobalObject() && func == exec->lexicalGlobalObject()->evalFunction()) {
1137                     exec->dynamicGlobalObject()->tearOffActivation(exec);
1138                     return eval(exec, exec->scopeChain(), exec->variableObject(), exec->dynamicGlobalObject(), exec->thisValue(), argList);
1139                 }
1140             }
1141             return func->call(exec, thisObj, argList);
1142         }
1143         ++iter;
1144     } while (iter != end);
1145
1146     return throwUndefinedVariableError(exec, ident);
1147 }
1148
1149 void EvalFunctionCallNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1150 {
1151     nodeStack.append(m_args.get());
1152 }
1153
1154 JSValue* EvalFunctionCallNode::evaluate(ExecState* exec)
1155 {
1156     return resolveAndCall<EvalOperator, true>(exec, exec->propertyNames().eval, m_args.get());
1157 }
1158
1159 void FunctionCallValueNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1160 {
1161     nodeStack.append(m_args.get());
1162     nodeStack.append(m_expr.get());
1163 }
1164
1165 // ECMA 11.2.3
1166 JSValue* FunctionCallValueNode::evaluate(ExecState* exec)
1167 {
1168     JSValue* v = m_expr->evaluate(exec);
1169     KJS_CHECKEXCEPTIONVALUE
1170
1171     if (!v->isObject()) {
1172         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_expr.get());
1173     }
1174
1175     JSObject* func = static_cast<JSObject*>(v);
1176
1177     if (!func->implementsCall()) {
1178         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_expr.get());
1179     }
1180
1181     List argList;
1182     m_args->evaluateList(exec, argList);
1183     KJS_CHECKEXCEPTIONVALUE
1184
1185     JSObject* thisObj =  exec->dynamicGlobalObject();
1186
1187     return func->call(exec, thisObj, argList);
1188 }
1189
1190 void FunctionCallResolveNode::optimizeVariableAccess(ExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack& nodeStack)
1191 {
1192     nodeStack.append(m_args.get());
1193
1194     size_t depth = 0;
1195     size_t index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
1196     if (index != missingSymbolMarker()) {
1197         if (!depth)
1198             new (this) LocalVarFunctionCallNode(index);
1199         else
1200             new (this) ScopedVarFunctionCallNode(index, depth);
1201         return;
1202     }
1203     
1204     if (!depth)
1205         return;
1206     
1207     new (this) NonLocalVarFunctionCallNode(depth);
1208 }
1209
1210 // ECMA 11.2.3
1211 JSValue* FunctionCallResolveNode::inlineEvaluate(ExecState* exec)
1212 {
1213     // Check for missed optimization opportunity.
1214     ASSERT(!canSkipLookup(exec, m_ident));
1215
1216     return resolveAndCall<FunctionCall, true>(exec, m_ident, m_args.get());
1217 }
1218
1219 JSValue* FunctionCallResolveNode::evaluate(ExecState* exec)
1220 {
1221     return inlineEvaluate(exec);
1222 }
1223
1224 double FunctionCallResolveNode::evaluateToNumber(ExecState* exec)
1225 {
1226     JSValue* v = inlineEvaluate(exec);
1227     KJS_CHECKEXCEPTIONNUMBER
1228     return v->toNumber(exec);
1229 }
1230
1231 bool FunctionCallResolveNode::evaluateToBoolean(ExecState* exec)
1232 {
1233     JSValue* v = inlineEvaluate(exec);
1234     KJS_CHECKEXCEPTIONBOOLEAN
1235     return v->toBoolean(exec);
1236 }
1237
1238 int32_t FunctionCallResolveNode::evaluateToInt32(ExecState* exec)
1239 {
1240     JSValue* v = inlineEvaluate(exec);
1241     KJS_CHECKEXCEPTIONNUMBER
1242     return v->toInt32(exec);
1243 }
1244
1245 uint32_t FunctionCallResolveNode::evaluateToUInt32(ExecState* exec)
1246 {
1247     JSValue* v = inlineEvaluate(exec);
1248     KJS_CHECKEXCEPTIONNUMBER
1249     return v->toUInt32(exec);
1250 }
1251
1252 JSValue* LocalVarFunctionCallNode::inlineEvaluate(ExecState* exec)
1253 {
1254     ASSERT(exec->variableObject() == exec->scopeChain().top());
1255
1256     JSValue* v = exec->localStorage()[m_index].value;
1257
1258     if (!v->isObject())
1259         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);
1260
1261     JSObject* func = static_cast<JSObject*>(v);
1262     if (!func->implementsCall())
1263         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);
1264
1265     List argList;
1266     m_args->evaluateList(exec, argList);
1267     KJS_CHECKEXCEPTIONVALUE
1268
1269     return func->call(exec, exec->dynamicGlobalObject(), argList);
1270 }
1271
1272 JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec)
1273 {
1274     return inlineEvaluate(exec);
1275 }
1276
1277 double LocalVarFunctionCallNode::evaluateToNumber(ExecState* exec)
1278 {
1279     JSValue* v = inlineEvaluate(exec);
1280     KJS_CHECKEXCEPTIONNUMBER
1281     return v->toNumber(exec);
1282 }
1283
1284 bool LocalVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
1285 {
1286     JSValue* v = inlineEvaluate(exec);
1287     KJS_CHECKEXCEPTIONBOOLEAN
1288     return v->toBoolean(exec);
1289 }
1290
1291 int32_t LocalVarFunctionCallNode::evaluateToInt32(ExecState* exec)
1292 {
1293     JSValue* v = inlineEvaluate(exec);
1294     KJS_CHECKEXCEPTIONNUMBER
1295     return v->toInt32(exec);
1296 }
1297
1298 uint32_t LocalVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
1299 {
1300     JSValue* v = inlineEvaluate(exec);
1301     KJS_CHECKEXCEPTIONNUMBER
1302     return v->toUInt32(exec);
1303 }
1304
1305 JSValue* ScopedVarFunctionCallNode::inlineEvaluate(ExecState* exec)
1306 {
1307     ASSERT(exec->variableObject() == exec->scopeChain().top());
1308     
1309     JSValue* v = getNonLocalSymbol(exec, m_index, m_scopeDepth);
1310     
1311     if (!v->isObject())
1312         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, m_ident);
1313     
1314     JSObject* func = static_cast<JSObject*>(v);
1315     if (!func->implementsCall())
1316         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, m_ident);
1317     
1318     List argList;
1319     m_args->evaluateList(exec, argList);
1320     KJS_CHECKEXCEPTIONVALUE
1321     
1322     return func->call(exec, exec->dynamicGlobalObject(), argList);
1323 }
1324
1325 JSValue* ScopedVarFunctionCallNode::evaluate(ExecState* exec)
1326 {
1327     return inlineEvaluate(exec);
1328 }
1329
1330 double ScopedVarFunctionCallNode::evaluateToNumber(ExecState* exec)
1331 {
1332     JSValue* v = inlineEvaluate(exec);
1333     KJS_CHECKEXCEPTIONNUMBER
1334     return v->toNumber(exec);
1335 }
1336
1337 bool ScopedVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
1338 {
1339     JSValue* v = inlineEvaluate(exec);
1340     KJS_CHECKEXCEPTIONBOOLEAN
1341     return v->toBoolean(exec);
1342 }
1343
1344 int32_t ScopedVarFunctionCallNode::evaluateToInt32(ExecState* exec)
1345 {
1346     JSValue* v = inlineEvaluate(exec);
1347     KJS_CHECKEXCEPTIONNUMBER
1348     return v->toInt32(exec);
1349 }
1350
1351 uint32_t ScopedVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
1352 {
1353     JSValue* v = inlineEvaluate(exec);
1354     KJS_CHECKEXCEPTIONNUMBER
1355     return v->toUInt32(exec);
1356 }
1357
1358 JSValue* NonLocalVarFunctionCallNode::inlineEvaluate(ExecState* exec)
1359 {
1360     // Check for missed optimization opportunity.
1361     ASSERT(!canSkipLookup(exec, m_ident));
1362     
1363     return resolveAndCall<FunctionCall, false>(exec, m_ident, m_args.get(), m_scopeDepth);
1364 }
1365
1366 JSValue* NonLocalVarFunctionCallNode::evaluate(ExecState* exec)
1367 {
1368     return inlineEvaluate(exec);
1369 }
1370
1371 double NonLocalVarFunctionCallNode::evaluateToNumber(ExecState* exec)
1372 {
1373     JSValue* v = inlineEvaluate(exec);
1374     KJS_CHECKEXCEPTIONNUMBER
1375     return v->toNumber(exec);
1376 }
1377
1378 bool NonLocalVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
1379 {
1380     JSValue* v = inlineEvaluate(exec);
1381     KJS_CHECKEXCEPTIONBOOLEAN
1382     return v->toBoolean(exec);
1383 }
1384
1385 int32_t NonLocalVarFunctionCallNode::evaluateToInt32(ExecState* exec)
1386 {
1387     JSValue* v = inlineEvaluate(exec);
1388     KJS_CHECKEXCEPTIONNUMBER
1389     return v->toInt32(exec);
1390 }
1391
1392 uint32_t NonLocalVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
1393 {
1394     JSValue* v = inlineEvaluate(exec);
1395     KJS_CHECKEXCEPTIONNUMBER
1396     return v->toUInt32(exec);
1397 }
1398
1399 void FunctionCallBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1400 {
1401     nodeStack.append(m_args.get());
1402     nodeStack.append(m_subscript.get());
1403     nodeStack.append(m_base.get());
1404 }
1405
1406 // ECMA 11.2.3
1407 JSValue* FunctionCallBracketNode::evaluate(ExecState* exec)
1408 {
1409     JSValue* baseVal = m_base->evaluate(exec);
1410     KJS_CHECKEXCEPTIONVALUE
1411
1412     JSValue* subscriptVal = m_subscript->evaluate(exec);
1413
1414     JSObject* baseObj = baseVal->toObject(exec);
1415     uint32_t i;
1416     PropertySlot slot;
1417
1418     JSValue* funcVal;
1419     if (subscriptVal->getUInt32(i)) {
1420         if (baseObj->getPropertySlot(exec, i, slot))
1421             funcVal = slot.getValue(exec, baseObj, i);
1422         else
1423             funcVal = jsUndefined();
1424     } else {
1425         Identifier ident(subscriptVal->toString(exec));
1426         if (baseObj->getPropertySlot(exec, ident, slot))
1427             funcVal = baseObj->get(exec, ident);
1428         else
1429             funcVal = jsUndefined();
1430     }
1431
1432     KJS_CHECKEXCEPTIONVALUE
1433
1434     if (!funcVal->isObject())
1435         return throwError(exec, TypeError, "Value %s (result of expression %s[%s]) is not object.", funcVal, m_base.get(), m_subscript.get());
1436
1437     JSObject* func = static_cast<JSObject*>(funcVal);
1438
1439     if (!func->implementsCall())
1440         return throwError(exec, TypeError, "Object %s (result of expression %s[%s]) does not allow calls.", funcVal, m_base.get(), m_subscript.get());
1441
1442     List argList;
1443     m_args->evaluateList(exec, argList);
1444     KJS_CHECKEXCEPTIONVALUE
1445
1446     JSObject* thisObj = baseObj;
1447     ASSERT(thisObj);
1448     ASSERT(thisObj->isObject());
1449     ASSERT(!thisObj->isActivationObject());
1450
1451     return func->call(exec, thisObj, argList);
1452 }
1453
1454 static const char* dotExprNotAnObjectString() KJS_FAST_CALL;
1455 static const char* dotExprNotAnObjectString()
1456 {
1457     return "Value %s (result of expression %s.%s) is not object.";
1458 }
1459
1460 static const char* dotExprDoesNotAllowCallsString() KJS_FAST_CALL;
1461 static const char* dotExprDoesNotAllowCallsString()
1462 {
1463     return "Object %s (result of expression %s.%s) does not allow calls.";
1464 }
1465
1466 void FunctionCallDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1467 {
1468     nodeStack.append(m_args.get());
1469     nodeStack.append(m_base.get());
1470 }
1471
1472 // ECMA 11.2.3
1473 JSValue* FunctionCallDotNode::inlineEvaluate(ExecState* exec)
1474 {
1475     JSValue* baseVal = m_base->evaluate(exec);
1476     KJS_CHECKEXCEPTIONVALUE
1477
1478     JSObject* baseObj = baseVal->toObject(exec);
1479     PropertySlot slot;
1480     JSValue* funcVal = baseObj->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, baseObj, m_ident) : jsUndefined();
1481     KJS_CHECKEXCEPTIONVALUE
1482
1483     if (!funcVal->isObject())
1484         return throwError(exec, TypeError, dotExprNotAnObjectString(), funcVal, m_base.get(), m_ident);
1485
1486     JSObject* func = static_cast<JSObject*>(funcVal);
1487
1488     if (!func->implementsCall())
1489         return throwError(exec, TypeError, dotExprDoesNotAllowCallsString(), funcVal, m_base.get(), m_ident);
1490
1491     List argList;
1492     m_args->evaluateList(exec, argList);
1493     KJS_CHECKEXCEPTIONVALUE
1494
1495     JSObject* thisObj = baseObj;
1496     ASSERT(thisObj);
1497     ASSERT(thisObj->isObject());
1498     ASSERT(!thisObj->isActivationObject());
1499
1500     return func->call(exec, thisObj, argList);
1501 }
1502
1503 JSValue* FunctionCallDotNode::evaluate(ExecState* exec)
1504 {
1505     return inlineEvaluate(exec);
1506 }
1507
1508 double FunctionCallDotNode::evaluateToNumber(ExecState* exec)
1509 {
1510     JSValue* v = inlineEvaluate(exec);
1511     KJS_CHECKEXCEPTIONNUMBER
1512     return v->toNumber(exec);
1513 }
1514
1515 bool FunctionCallDotNode::evaluateToBoolean(ExecState* exec)
1516 {
1517     JSValue* v = inlineEvaluate(exec);
1518     KJS_CHECKEXCEPTIONBOOLEAN
1519     return v->toBoolean(exec);
1520 }
1521
1522 int32_t FunctionCallDotNode::evaluateToInt32(ExecState* exec)
1523 {
1524     JSValue* v = inlineEvaluate(exec);
1525     KJS_CHECKEXCEPTIONNUMBER
1526     return v->toInt32(exec);
1527 }
1528
1529 uint32_t FunctionCallDotNode::evaluateToUInt32(ExecState* exec)
1530 {
1531     JSValue* v = inlineEvaluate(exec);
1532     KJS_CHECKEXCEPTIONNUMBER
1533     return v->toUInt32(exec);
1534 }
1535
1536 // ECMA 11.3
1537
1538 // ------------------------------ PostfixResolveNode ----------------------------------
1539
1540 // Increment
1541 void PostIncResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
1542 {
1543     size_t index = symbolTable.get(m_ident.ustring().rep());
1544     if (index != missingSymbolMarker()) {
1545         if (isConstant(localStorage, index))
1546             new (this) PostIncConstNode(index);
1547         else
1548             new (this) PostIncLocalVarNode(index);
1549     }
1550 }
1551
1552 JSValue* PostIncResolveNode::evaluate(ExecState* exec)
1553 {
1554     // Check for missed optimization opportunity.
1555     ASSERT(!canSkipLookup(exec, m_ident));
1556
1557     const ScopeChain& chain = exec->scopeChain();
1558     ScopeChainIterator iter = chain.begin();
1559     ScopeChainIterator end = chain.end();
1560
1561     // we must always have something in the scope chain
1562     ASSERT(iter != end);
1563
1564     PropertySlot slot;
1565     do {
1566         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
1567             // If m_ident is 'arguments', the base->getPropertySlot() may cause 
1568             // base (which must be an ActivationImp in such this case) to be torn
1569             // off from the activation stack, in which case we need to get it again
1570             // from the ScopeChainIterator.
1571             
1572             JSObject* base = *iter;
1573             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1574             base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
1575             return v;
1576         }
1577
1578         ++iter;
1579     } while (iter != end);
1580
1581     return throwUndefinedVariableError(exec, m_ident);
1582 }
1583
1584 void PostIncResolveNode::optimizeForUnnecessaryResult()
1585 {
1586     new (this) PreIncResolveNode(PlacementNewAdopt);
1587 }
1588
1589 JSValue* PostIncLocalVarNode::evaluate(ExecState* exec)
1590 {
1591     ASSERT(exec->variableObject() == exec->scopeChain().top());
1592
1593     JSValue** slot = &exec->localStorage()[m_index].value;
1594     JSValue* v = (*slot)->toJSNumber(exec);
1595     *slot = jsNumber(v->toNumber(exec) + 1);
1596     return v;
1597 }
1598
1599 void PostIncLocalVarNode::optimizeForUnnecessaryResult()
1600 {
1601     new (this) PreIncLocalVarNode(m_index);
1602 }
1603
1604 // Decrement
1605 void PostDecResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
1606 {
1607     size_t index = symbolTable.get(m_ident.ustring().rep());
1608     if (index != missingSymbolMarker()) {
1609         if (isConstant(localStorage, index))
1610             new (this) PostDecConstNode(index);
1611         else
1612             new (this) PostDecLocalVarNode(index);
1613     }
1614 }
1615
1616 JSValue* PostDecResolveNode::evaluate(ExecState* exec)
1617 {
1618     // Check for missed optimization opportunity.
1619     ASSERT(!canSkipLookup(exec, m_ident));
1620
1621     const ScopeChain& chain = exec->scopeChain();
1622     ScopeChainIterator iter = chain.begin();
1623     ScopeChainIterator end = chain.end();
1624
1625     // we must always have something in the scope chain
1626     ASSERT(iter != end);
1627
1628     PropertySlot slot;
1629     do {
1630         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
1631             // See the comment in PostIncResolveNode::evaluate().
1632
1633             JSObject* base = *iter;
1634             JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
1635             base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
1636             return v;
1637         }
1638
1639         ++iter;
1640     } while (iter != end);
1641
1642     return throwUndefinedVariableError(exec, m_ident);
1643 }
1644
1645 void PostDecResolveNode::optimizeForUnnecessaryResult()
1646 {
1647     new (this) PreDecResolveNode(PlacementNewAdopt);
1648 }
1649
1650 JSValue* PostDecLocalVarNode::evaluate(ExecState* exec)
1651 {
1652     ASSERT(exec->variableObject() == exec->scopeChain().top());
1653
1654     JSValue** slot = &exec->localStorage()[m_index].value;
1655     JSValue* v = (*slot)->toJSNumber(exec);
1656     *slot = jsNumber(v->toNumber(exec) - 1);
1657     return v;
1658 }
1659
1660 double PostDecLocalVarNode::inlineEvaluateToNumber(ExecState* exec)
1661 {
1662     ASSERT(exec->variableObject() == exec->scopeChain().top());
1663
1664     JSValue** slot = &exec->localStorage()[m_index].value;
1665     double n = (*slot)->toNumber(exec);
1666     *slot = jsNumber(n - 1);
1667     return n;
1668 }
1669
1670 double PostDecLocalVarNode::evaluateToNumber(ExecState* exec)
1671 {
1672     return inlineEvaluateToNumber(exec);
1673 }
1674
1675 bool PostDecLocalVarNode::evaluateToBoolean(ExecState* exec)
1676 {
1677     double result = inlineEvaluateToNumber(exec);
1678     return  result > 0.0 || 0.0 > result; // NaN produces false as well
1679 }
1680
1681 int32_t PostDecLocalVarNode::evaluateToInt32(ExecState* exec)
1682 {
1683     return JSValue::toInt32(inlineEvaluateToNumber(exec));
1684 }
1685
1686 uint32_t PostDecLocalVarNode::evaluateToUInt32(ExecState* exec)
1687 {
1688     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
1689 }
1690
1691 void PostDecLocalVarNode::optimizeForUnnecessaryResult()
1692 {
1693     new (this) PreDecLocalVarNode(m_index);
1694 }
1695
1696 // ------------------------------ PostfixBracketNode ----------------------------------
1697
1698 void PostfixBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1699 {
1700     nodeStack.append(m_subscript.get());
1701     nodeStack.append(m_base.get());
1702 }
1703
1704 JSValue* PostIncBracketNode::evaluate(ExecState* exec)
1705 {
1706     JSValue* baseValue = m_base->evaluate(exec);
1707     KJS_CHECKEXCEPTIONVALUE
1708     JSValue* subscript = m_subscript->evaluate(exec);
1709     KJS_CHECKEXCEPTIONVALUE
1710
1711     JSObject* base = baseValue->toObject(exec);
1712
1713     uint32_t propertyIndex;
1714     if (subscript->getUInt32(propertyIndex)) {
1715         PropertySlot slot;
1716         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1717         KJS_CHECKEXCEPTIONVALUE
1718
1719         JSValue* v2 = v->toJSNumber(exec);
1720         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1));
1721
1722         return v2;
1723     }
1724
1725     Identifier propertyName(subscript->toString(exec));
1726     PropertySlot slot;
1727     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1728     KJS_CHECKEXCEPTIONVALUE
1729
1730     JSValue* v2 = v->toJSNumber(exec);
1731     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));
1732     return v2;
1733 }
1734
1735 JSValue* PostDecBracketNode::evaluate(ExecState* exec)
1736 {
1737     JSValue* baseValue = m_base->evaluate(exec);
1738     KJS_CHECKEXCEPTIONVALUE
1739     JSValue* subscript = m_subscript->evaluate(exec);
1740     KJS_CHECKEXCEPTIONVALUE
1741
1742     JSObject* base = baseValue->toObject(exec);
1743
1744     uint32_t propertyIndex;
1745     if (subscript->getUInt32(propertyIndex)) {
1746         PropertySlot slot;
1747         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
1748         KJS_CHECKEXCEPTIONVALUE
1749
1750         JSValue* v2 = v->toJSNumber(exec);
1751         base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1));
1752         return v2;
1753     }
1754
1755     Identifier propertyName(subscript->toString(exec));
1756     PropertySlot slot;
1757     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
1758     KJS_CHECKEXCEPTIONVALUE
1759
1760     JSValue* v2 = v->toJSNumber(exec);
1761     base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));
1762     return v2;
1763 }
1764
1765 // ------------------------------ PostfixDotNode ----------------------------------
1766
1767 void PostfixDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1768 {
1769     nodeStack.append(m_base.get());
1770 }
1771
1772 JSValue* PostIncDotNode::evaluate(ExecState* exec)
1773 {
1774     JSValue* baseValue = m_base->evaluate(exec);
1775     KJS_CHECKEXCEPTIONVALUE
1776     JSObject* base = baseValue->toObject(exec);
1777
1778     PropertySlot slot;
1779     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1780     KJS_CHECKEXCEPTIONVALUE
1781
1782     JSValue* v2 = v->toJSNumber(exec);
1783     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));
1784     return v2;
1785 }
1786
1787 JSValue* PostDecDotNode::evaluate(ExecState* exec)
1788 {
1789     JSValue* baseValue = m_base->evaluate(exec);
1790     KJS_CHECKEXCEPTIONVALUE
1791     JSObject* base = baseValue->toObject(exec);
1792
1793     PropertySlot slot;
1794     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
1795     KJS_CHECKEXCEPTIONVALUE
1796
1797     JSValue* v2 = v->toJSNumber(exec);
1798     base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));
1799     return v2;
1800 }
1801
1802 // ------------------------------ PostfixErrorNode -----------------------------------
1803
1804 JSValue* PostfixErrorNode::evaluate(ExecState* exec)
1805 {
1806     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
1807                m_operator == OpPlusPlus ? "++" : "--");
1808     handleException(exec);
1809     return jsUndefined();
1810 }
1811
1812 // ------------------------------ DeleteResolveNode -----------------------------------
1813
1814 void DeleteResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
1815 {
1816     size_t index = symbolTable.get(m_ident.ustring().rep());
1817     if (index != missingSymbolMarker())
1818         new (this) LocalVarDeleteNode();
1819 }
1820
1821 // ECMA 11.4.1
1822
1823 JSValue* DeleteResolveNode::evaluate(ExecState* exec)
1824 {
1825     // Check for missed optimization opportunity.
1826     ASSERT(!canSkipLookup(exec, m_ident));
1827
1828     const ScopeChain& chain = exec->scopeChain();
1829     ScopeChainIterator iter = chain.begin();
1830     ScopeChainIterator end = chain.end();
1831
1832     // We must always have something in the scope chain
1833     ASSERT(iter != end);
1834
1835     PropertySlot slot;
1836     JSObject* base;
1837     do {
1838         base = *iter;
1839         if (base->getPropertySlot(exec, m_ident, slot))
1840             return jsBoolean(base->deleteProperty(exec, m_ident));
1841
1842         ++iter;
1843     } while (iter != end);
1844
1845     return jsBoolean(true);
1846 }
1847
1848 JSValue* LocalVarDeleteNode::evaluate(ExecState*)
1849 {
1850     return jsBoolean(false);
1851 }
1852
1853 // ------------------------------ DeleteBracketNode -----------------------------------
1854
1855 void DeleteBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1856 {
1857     nodeStack.append(m_subscript.get());
1858     nodeStack.append(m_base.get());
1859 }
1860
1861 JSValue* DeleteBracketNode::evaluate(ExecState* exec)
1862 {
1863     JSValue* baseValue = m_base->evaluate(exec);
1864     KJS_CHECKEXCEPTIONVALUE
1865     JSValue* subscript = m_subscript->evaluate(exec);
1866     KJS_CHECKEXCEPTIONVALUE
1867
1868     JSObject* base = baseValue->toObject(exec);
1869
1870     uint32_t propertyIndex;
1871     if (subscript->getUInt32(propertyIndex))
1872         return jsBoolean(base->deleteProperty(exec, propertyIndex));
1873
1874     Identifier propertyName(subscript->toString(exec));
1875     return jsBoolean(base->deleteProperty(exec, propertyName));
1876 }
1877
1878 // ------------------------------ DeleteDotNode -----------------------------------
1879
1880 void DeleteDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1881 {
1882     nodeStack.append(m_base.get());
1883 }
1884
1885 JSValue* DeleteDotNode::evaluate(ExecState* exec)
1886 {
1887     JSValue* baseValue = m_base->evaluate(exec);
1888     JSObject* base = baseValue->toObject(exec);
1889     KJS_CHECKEXCEPTIONVALUE
1890
1891     return jsBoolean(base->deleteProperty(exec, m_ident));
1892 }
1893
1894 // ------------------------------ DeleteValueNode -----------------------------------
1895
1896 void DeleteValueNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1897 {
1898     nodeStack.append(m_expr.get());
1899 }
1900
1901 JSValue* DeleteValueNode::evaluate(ExecState* exec)
1902 {
1903     m_expr->evaluate(exec);
1904     KJS_CHECKEXCEPTIONVALUE
1905
1906     // delete on a non-location expression ignores the value and returns true
1907     return jsBoolean(true);
1908 }
1909
1910 // ------------------------------ VoidNode -------------------------------------
1911
1912 void VoidNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1913 {
1914     nodeStack.append(m_expr.get());
1915 }
1916
1917 // ECMA 11.4.2
1918 JSValue* VoidNode::evaluate(ExecState* exec)
1919 {
1920     m_expr->evaluate(exec);
1921     KJS_CHECKEXCEPTIONVALUE
1922
1923     return jsUndefined();
1924 }
1925
1926 // ECMA 11.4.3
1927
1928 // ------------------------------ TypeOfValueNode -----------------------------------
1929
1930 void TypeOfValueNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
1931 {
1932     nodeStack.append(m_expr.get());
1933 }
1934
1935 static JSValue* typeStringForValue(JSValue* v) KJS_FAST_CALL;
1936 static JSValue* typeStringForValue(JSValue* v)
1937 {
1938     switch (v->type()) {
1939         case UndefinedType:
1940             return jsString("undefined");
1941         case NullType:
1942             return jsString("object");
1943         case BooleanType:
1944             return jsString("boolean");
1945         case NumberType:
1946             return jsString("number");
1947         case StringType:
1948             return jsString("string");
1949         default:
1950             if (v->isObject()) {
1951                 // Return "undefined" for objects that should be treated
1952                 // as null when doing comparisons.
1953                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
1954                     return jsString("undefined");
1955                 else if (static_cast<JSObject*>(v)->implementsCall())
1956                     return jsString("function");
1957             }
1958
1959             return jsString("object");
1960     }
1961 }
1962
1963 void TypeOfResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
1964 {
1965     size_t index = symbolTable.get(m_ident.ustring().rep());
1966     if (index != missingSymbolMarker())
1967         new (this) LocalVarTypeOfNode(index);
1968 }
1969
1970 JSValue* LocalVarTypeOfNode::evaluate(ExecState* exec)
1971 {
1972     ASSERT(exec->variableObject() == exec->scopeChain().top());
1973
1974     return typeStringForValue(exec->localStorage()[m_index].value);
1975 }
1976
1977 JSValue* TypeOfResolveNode::evaluate(ExecState* exec)
1978 {
1979     const ScopeChain& chain = exec->scopeChain();
1980     ScopeChainIterator iter = chain.begin();
1981     ScopeChainIterator end = chain.end();
1982
1983     // We must always have something in the scope chain
1984     ASSERT(iter != end);
1985
1986     PropertySlot slot;
1987     JSObject* base;
1988     do {
1989         base = *iter;
1990         if (base->getPropertySlot(exec, m_ident, slot)) {
1991             JSValue* v = slot.getValue(exec, base, m_ident);
1992             return typeStringForValue(v);
1993         }
1994
1995         ++iter;
1996     } while (iter != end);
1997
1998     return jsString("undefined");
1999 }
2000
2001 // ------------------------------ TypeOfValueNode -----------------------------------
2002
2003 JSValue* TypeOfValueNode::evaluate(ExecState* exec)
2004 {
2005     JSValue* v = m_expr->evaluate(exec);
2006     KJS_CHECKEXCEPTIONVALUE
2007
2008     return typeStringForValue(v);
2009 }
2010
2011 // ECMA 11.4.4 and 11.4.5
2012
2013 // ------------------------------ PrefixResolveNode ----------------------------------
2014
2015 void PreIncResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
2016 {
2017     size_t index = symbolTable.get(m_ident.ustring().rep());
2018     if (index != missingSymbolMarker()) {
2019         if (isConstant(localStorage, index))
2020             new (this) PreIncConstNode(index);
2021         else
2022             new (this) PreIncLocalVarNode(index);
2023     }
2024 }
2025
2026 JSValue* PreIncLocalVarNode::evaluate(ExecState* exec)
2027 {
2028     ASSERT(exec->variableObject() == exec->scopeChain().top());
2029     JSValue** slot = &exec->localStorage()[m_index].value;
2030
2031     double n = (*slot)->toNumber(exec);
2032     JSValue* n2 = jsNumber(n + 1);
2033     *slot = n2;
2034     return n2;
2035 }
2036
2037 JSValue* PreIncResolveNode::evaluate(ExecState* exec)
2038 {
2039     const ScopeChain& chain = exec->scopeChain();
2040     ScopeChainIterator iter = chain.begin();
2041     ScopeChainIterator end = chain.end();
2042
2043     // we must always have something in the scope chain
2044     ASSERT(iter != end);
2045
2046     PropertySlot slot;
2047     do {
2048         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
2049             // See the comment in PostIncResolveNode::evaluate().
2050
2051             JSObject* base = *iter;
2052             JSValue* v = slot.getValue(exec, base, m_ident);
2053
2054             double n = v->toNumber(exec);
2055             JSValue* n2 = jsNumber(n + 1);
2056             base->put(exec, m_ident, n2);
2057
2058             return n2;
2059         }
2060
2061         ++iter;
2062     } while (iter != end);
2063
2064     return throwUndefinedVariableError(exec, m_ident);
2065 }
2066
2067 void PreDecResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
2068 {
2069     size_t index = symbolTable.get(m_ident.ustring().rep());
2070     if (index != missingSymbolMarker()) {
2071         if (isConstant(localStorage, index))
2072             new (this) PreDecConstNode(index);
2073         else
2074             new (this) PreDecLocalVarNode(index);
2075     }
2076 }
2077
2078 JSValue* PreDecLocalVarNode::evaluate(ExecState* exec)
2079 {
2080     ASSERT(exec->variableObject() == exec->scopeChain().top());
2081     JSValue** slot = &exec->localStorage()[m_index].value;
2082
2083     double n = (*slot)->toNumber(exec);
2084     JSValue* n2 = jsNumber(n - 1);
2085     *slot = n2;
2086     return n2;
2087 }
2088
2089 JSValue* PreDecResolveNode::evaluate(ExecState* exec)
2090 {
2091     const ScopeChain& chain = exec->scopeChain();
2092     ScopeChainIterator iter = chain.begin();
2093     ScopeChainIterator end = chain.end();
2094
2095     // we must always have something in the scope chain
2096     ASSERT(iter != end);
2097
2098     PropertySlot slot;
2099     do {
2100         if ((*iter)->getPropertySlot(exec, m_ident, slot)) {
2101             // See the comment in PostIncResolveNode::evaluate().
2102
2103             JSObject* base = *iter;
2104             JSValue* v = slot.getValue(exec, base, m_ident);
2105
2106             double n = v->toNumber(exec);
2107             JSValue* n2 = jsNumber(n - 1);
2108             base->put(exec, m_ident, n2);
2109
2110             return n2;
2111         }
2112
2113         ++iter;
2114     } while (iter != end);
2115
2116     return throwUndefinedVariableError(exec, m_ident);
2117 }
2118
2119 // ------------------------------ PreIncConstNode ----------------------------------
2120
2121 JSValue* PreIncConstNode::evaluate(ExecState* exec)
2122 {
2123     ASSERT(exec->variableObject() == exec->scopeChain().top());
2124     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) + 1);
2125 }
2126
2127 // ------------------------------ PreDecConstNode ----------------------------------
2128
2129 JSValue* PreDecConstNode::evaluate(ExecState* exec)
2130 {
2131     ASSERT(exec->variableObject() == exec->scopeChain().top());
2132     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) - 1);
2133 }
2134
2135 // ------------------------------ PostIncConstNode ----------------------------------
2136
2137 JSValue* PostIncConstNode::evaluate(ExecState* exec)
2138 {
2139     ASSERT(exec->variableObject() == exec->scopeChain().top());
2140     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
2141 }
2142
2143 // ------------------------------ PostDecConstNode ----------------------------------
2144
2145 JSValue* PostDecConstNode::evaluate(ExecState* exec)
2146 {
2147     ASSERT(exec->variableObject() == exec->scopeChain().top());
2148     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
2149 }
2150
2151 // ------------------------------ PrefixBracketNode ----------------------------------
2152
2153 void PrefixBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2154 {
2155     nodeStack.append(m_subscript.get());
2156     nodeStack.append(m_base.get());
2157 }
2158
2159 JSValue* PreIncBracketNode::evaluate(ExecState* exec)
2160 {
2161     JSValue* baseValue = m_base->evaluate(exec);
2162     KJS_CHECKEXCEPTIONVALUE
2163     JSValue* subscript = m_subscript->evaluate(exec);
2164     KJS_CHECKEXCEPTIONVALUE
2165
2166     JSObject* base = baseValue->toObject(exec);
2167
2168     uint32_t propertyIndex;
2169     if (subscript->getUInt32(propertyIndex)) {
2170         PropertySlot slot;
2171         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2172         KJS_CHECKEXCEPTIONVALUE
2173
2174         JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
2175         base->put(exec, propertyIndex, n2);
2176
2177         return n2;
2178     }
2179
2180     Identifier propertyName(subscript->toString(exec));
2181     PropertySlot slot;
2182     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2183     KJS_CHECKEXCEPTIONVALUE
2184
2185     JSValue* n2 = jsNumber(v->toNumber(exec) + 1);
2186     base->put(exec, propertyName, n2);
2187
2188     return n2;
2189 }
2190
2191 JSValue* PreDecBracketNode::evaluate(ExecState* exec)
2192 {
2193     JSValue* baseValue = m_base->evaluate(exec);
2194     KJS_CHECKEXCEPTIONVALUE
2195     JSValue* subscript = m_subscript->evaluate(exec);
2196     KJS_CHECKEXCEPTIONVALUE
2197
2198     JSObject* base = baseValue->toObject(exec);
2199
2200     uint32_t propertyIndex;
2201     if (subscript->getUInt32(propertyIndex)) {
2202         PropertySlot slot;
2203         JSValue* v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
2204         KJS_CHECKEXCEPTIONVALUE
2205
2206         JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
2207         base->put(exec, propertyIndex, n2);
2208
2209         return n2;
2210     }
2211
2212     Identifier propertyName(subscript->toString(exec));
2213     PropertySlot slot;
2214     JSValue* v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
2215     KJS_CHECKEXCEPTIONVALUE
2216
2217     JSValue* n2 = jsNumber(v->toNumber(exec) - 1);
2218     base->put(exec, propertyName, n2);
2219
2220     return n2;
2221 }
2222
2223 // ------------------------------ PrefixDotNode ----------------------------------
2224
2225 void PrefixDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2226 {
2227     nodeStack.append(m_base.get());
2228 }
2229
2230 JSValue* PreIncDotNode::evaluate(ExecState* exec)
2231 {
2232     JSValue* baseValue = m_base->evaluate(exec);
2233     KJS_CHECKEXCEPTIONVALUE
2234     JSObject* base = baseValue->toObject(exec);
2235
2236     PropertySlot slot;
2237     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2238     KJS_CHECKEXCEPTIONVALUE
2239
2240     double n = v->toNumber(exec);
2241     JSValue* n2 = jsNumber(n + 1);
2242     base->put(exec, m_ident, n2);
2243
2244     return n2;
2245 }
2246
2247 JSValue* PreDecDotNode::evaluate(ExecState* exec)
2248 {
2249     JSValue* baseValue = m_base->evaluate(exec);
2250     KJS_CHECKEXCEPTIONVALUE
2251     JSObject* base = baseValue->toObject(exec);
2252
2253     PropertySlot slot;
2254     JSValue* v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
2255     KJS_CHECKEXCEPTIONVALUE
2256
2257     double n = v->toNumber(exec);
2258     JSValue* n2 = jsNumber(n - 1);
2259     base->put(exec, m_ident, n2);
2260
2261     return n2;
2262 }
2263
2264 // ------------------------------ PrefixErrorNode -----------------------------------
2265
2266 JSValue* PrefixErrorNode::evaluate(ExecState* exec)
2267 {
2268     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
2269                m_operator == OpPlusPlus ? "++" : "--");
2270     handleException(exec);
2271     return jsUndefined();
2272 }
2273
2274 // ------------------------------ UnaryPlusNode --------------------------------
2275
2276 void UnaryPlusNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2277 {
2278     nodeStack.append(m_expr.get());
2279 }
2280
2281 // ECMA 11.4.6
2282 JSValue* UnaryPlusNode::evaluate(ExecState* exec)
2283 {
2284     JSValue* v = m_expr->evaluate(exec);
2285     KJS_CHECKEXCEPTIONVALUE
2286     return v->toJSNumber(exec);
2287 }
2288
2289 bool UnaryPlusNode::evaluateToBoolean(ExecState* exec)
2290 {
2291     return m_expr->evaluateToBoolean(exec);
2292 }
2293
2294 double UnaryPlusNode::evaluateToNumber(ExecState* exec)
2295 {
2296     return m_expr->evaluateToNumber(exec);
2297 }
2298
2299 int32_t UnaryPlusNode::evaluateToInt32(ExecState* exec)
2300 {
2301     return m_expr->evaluateToInt32(exec);
2302 }
2303
2304 uint32_t UnaryPlusNode::evaluateToUInt32(ExecState* exec)
2305 {
2306     return m_expr->evaluateToInt32(exec);
2307 }
2308
2309 // ------------------------------ NegateNode -----------------------------------
2310
2311 void NegateNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2312 {
2313     nodeStack.append(m_expr.get());
2314 }
2315
2316 // ECMA 11.4.7
2317 JSValue* NegateNode::evaluate(ExecState* exec)
2318 {
2319     // No need to check exception, caller will do so right after evaluate()
2320     return jsNumber(-m_expr->evaluateToNumber(exec));
2321 }
2322
2323 double NegateNode::evaluateToNumber(ExecState* exec)
2324 {
2325     // No need to check exception, caller will do so right after evaluateToNumber()
2326     return -m_expr->evaluateToNumber(exec);
2327 }
2328
2329 // ------------------------------ BitwiseNotNode -------------------------------
2330
2331 void BitwiseNotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2332 {
2333     nodeStack.append(m_expr.get());
2334 }
2335
2336 // ECMA 11.4.8
2337 int32_t BitwiseNotNode::inlineEvaluateToInt32(ExecState* exec)
2338 {
2339     return ~m_expr->evaluateToInt32(exec);
2340 }
2341
2342 JSValue* BitwiseNotNode::evaluate(ExecState* exec)
2343 {
2344     return jsNumber(inlineEvaluateToInt32(exec));
2345 }
2346
2347 double BitwiseNotNode::evaluateToNumber(ExecState* exec)
2348 {
2349     return inlineEvaluateToInt32(exec);
2350 }
2351
2352 bool BitwiseNotNode::evaluateToBoolean(ExecState* exec)
2353 {
2354     return inlineEvaluateToInt32(exec);
2355 }
2356
2357 int32_t BitwiseNotNode::evaluateToInt32(ExecState* exec)
2358 {
2359     return inlineEvaluateToInt32(exec);
2360 }
2361
2362 uint32_t BitwiseNotNode::evaluateToUInt32(ExecState* exec)
2363 {
2364     return inlineEvaluateToInt32(exec);
2365 }
2366
2367 // ------------------------------ LogicalNotNode -------------------------------
2368
2369 void LogicalNotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2370 {
2371     nodeStack.append(m_expr.get());
2372 }
2373
2374 // ECMA 11.4.9
2375 JSValue* LogicalNotNode::evaluate(ExecState* exec)
2376 {
2377     return jsBoolean(!m_expr->evaluateToBoolean(exec));
2378 }
2379
2380 bool LogicalNotNode::evaluateToBoolean(ExecState* exec)
2381 {
2382     return !m_expr->evaluateToBoolean(exec);
2383 }
2384
2385 // ------------------------------ Multiplicative Nodes -----------------------------------
2386
2387 void MultNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2388 {
2389     nodeStack.append(m_term1.get());
2390     nodeStack.append(m_term2.get());
2391 }
2392
2393 // ECMA 11.5.1
2394 double MultNode::inlineEvaluateToNumber(ExecState* exec)
2395 {
2396     double n1 = m_term1->evaluateToNumber(exec);
2397     KJS_CHECKEXCEPTIONNUMBER
2398     double n2 = m_term2->evaluateToNumber(exec);
2399     return n1 * n2;
2400 }
2401
2402 JSValue* MultNode::evaluate(ExecState* exec)
2403 {
2404     return jsNumber(inlineEvaluateToNumber(exec));
2405 }
2406
2407 double MultNode::evaluateToNumber(ExecState* exec)
2408 {
2409     return inlineEvaluateToNumber(exec);
2410 }
2411
2412 bool MultNode::evaluateToBoolean(ExecState* exec)
2413 {
2414     double result = inlineEvaluateToNumber(exec);
2415     return  result > 0.0 || 0.0 > result; // NaN produces false as well
2416 }
2417
2418 int32_t MultNode::evaluateToInt32(ExecState* exec)
2419 {
2420     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2421 }
2422
2423 uint32_t MultNode::evaluateToUInt32(ExecState* exec)
2424 {
2425     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2426 }
2427
2428 void DivNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2429 {
2430     nodeStack.append(m_term1.get());
2431     nodeStack.append(m_term2.get());
2432 }
2433
2434 // ECMA 11.5.2
2435 double DivNode::inlineEvaluateToNumber(ExecState* exec)
2436 {
2437     double n1 = m_term1->evaluateToNumber(exec);
2438     KJS_CHECKEXCEPTIONNUMBER
2439     double n2 = m_term2->evaluateToNumber(exec);
2440     return n1 / n2;
2441 }
2442
2443 JSValue* DivNode::evaluate(ExecState* exec)
2444 {
2445     return jsNumber(inlineEvaluateToNumber(exec));
2446 }
2447
2448 double DivNode::evaluateToNumber(ExecState* exec)
2449 {
2450     return inlineEvaluateToNumber(exec);
2451 }
2452
2453 int32_t DivNode::evaluateToInt32(ExecState* exec)
2454 {
2455     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2456 }
2457
2458 uint32_t DivNode::evaluateToUInt32(ExecState* exec)
2459 {
2460     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2461 }
2462
2463 void ModNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2464 {
2465     nodeStack.append(m_term1.get());
2466     nodeStack.append(m_term2.get());
2467 }
2468
2469 // ECMA 11.5.3
2470 double ModNode::inlineEvaluateToNumber(ExecState* exec)
2471 {
2472     double n1 = m_term1->evaluateToNumber(exec);
2473     KJS_CHECKEXCEPTIONNUMBER
2474     double n2 = m_term2->evaluateToNumber(exec);
2475     return fmod(n1, n2);
2476 }
2477
2478 JSValue* ModNode::evaluate(ExecState* exec)
2479 {
2480     return jsNumber(inlineEvaluateToNumber(exec));
2481 }
2482
2483 double ModNode::evaluateToNumber(ExecState* exec)
2484 {
2485     return inlineEvaluateToNumber(exec);
2486 }
2487
2488 bool ModNode::evaluateToBoolean(ExecState* exec)
2489 {
2490     double result = inlineEvaluateToNumber(exec);
2491     return  result > 0.0 || 0.0 > result; // NaN produces false as well
2492 }
2493
2494 int32_t ModNode::evaluateToInt32(ExecState* exec)
2495 {
2496     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2497 }
2498
2499 uint32_t ModNode::evaluateToUInt32(ExecState* exec)
2500 {
2501     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2502 }
2503
2504 // ------------------------------ Additive Nodes --------------------------------------
2505
2506 static JSValue* throwOutOfMemoryError(ExecState* exec)
2507 {
2508     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
2509     exec->setException(error);
2510     return error;
2511 }
2512
2513 static double throwOutOfMemoryErrorToNumber(ExecState* exec)
2514 {
2515     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
2516     exec->setException(error);
2517     return 0.0;
2518 }
2519
2520 // ECMA 11.6
2521 static JSValue* addSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
2522 {
2523     // exception for the Date exception in defaultValue()
2524     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
2525     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
2526
2527     if (p1->isString() || p2->isString()) {
2528         UString value = p1->toString(exec) + p2->toString(exec);
2529         if (value.isNull())
2530             return throwOutOfMemoryError(exec);
2531         return jsString(value);
2532     }
2533
2534     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
2535 }
2536
2537 static double addSlowCaseToNumber(ExecState* exec, JSValue* v1, JSValue* v2)
2538 {
2539     // exception for the Date exception in defaultValue()
2540     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
2541     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
2542
2543     if (p1->isString() || p2->isString()) {
2544         UString value = p1->toString(exec) + p2->toString(exec);
2545         if (value.isNull())
2546             return throwOutOfMemoryErrorToNumber(exec);
2547         return value.toDouble();
2548     }
2549
2550     return p1->toNumber(exec) + p2->toNumber(exec);
2551 }
2552
2553 // Fast-path choices here are based on frequency data from SunSpider:
2554 //    <times> Add case: <t1> <t2>
2555 //    ---------------------------
2556 //    5627160 Add case: 1 1
2557 //    247427  Add case: 5 5
2558 //    20901   Add case: 5 6
2559 //    13978   Add case: 5 1
2560 //    4000    Add case: 1 5
2561 //    1       Add case: 3 5
2562
2563 static inline JSValue* add(ExecState* exec, JSValue* v1, JSValue* v2)
2564 {
2565     JSType t1 = v1->type();
2566     JSType t2 = v2->type();
2567     const unsigned bothTypes = (t1 << 3) | t2;
2568
2569     if (bothTypes == ((NumberType << 3) | NumberType))
2570         return jsNumber(v1->toNumber(exec) + v2->toNumber(exec));
2571     if (bothTypes == ((StringType << 3) | StringType)) {
2572         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
2573         if (value.isNull())
2574             return throwOutOfMemoryError(exec);
2575         return jsString(value);
2576     }
2577
2578     // All other cases are pretty uncommon
2579     return addSlowCase(exec, v1, v2);
2580 }
2581
2582 static inline double addToNumber(ExecState* exec, JSValue* v1, JSValue* v2)
2583 {
2584     JSType t1 = v1->type();
2585     JSType t2 = v2->type();
2586     const unsigned bothTypes = (t1 << 3) | t2;
2587
2588     if (bothTypes == ((NumberType << 3) | NumberType))
2589         return v1->toNumber(exec) + v2->toNumber(exec);
2590     if (bothTypes == ((StringType << 3) | StringType)) {
2591         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
2592         if (value.isNull())
2593             return throwOutOfMemoryErrorToNumber(exec);
2594         return value.toDouble();
2595     }
2596
2597     // All other cases are pretty uncommon
2598     return addSlowCaseToNumber(exec, v1, v2);
2599 }
2600
2601 void AddNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2602 {
2603     nodeStack.append(m_term1.get());
2604     nodeStack.append(m_term2.get());
2605 }
2606
2607 // ECMA 11.6.1
2608 JSValue* AddNode::evaluate(ExecState* exec)
2609 {
2610     JSValue* v1 = m_term1->evaluate(exec);
2611     KJS_CHECKEXCEPTIONVALUE
2612
2613     JSValue* v2 = m_term2->evaluate(exec);
2614     KJS_CHECKEXCEPTIONVALUE
2615
2616     return add(exec, v1, v2);
2617 }
2618
2619 double AddNode::inlineEvaluateToNumber(ExecState* exec)
2620 {
2621     JSValue* v1 = m_term1->evaluate(exec);
2622     KJS_CHECKEXCEPTIONNUMBER
2623
2624     JSValue* v2 = m_term2->evaluate(exec);
2625     KJS_CHECKEXCEPTIONNUMBER
2626
2627     return addToNumber(exec, v1, v2);
2628 }
2629
2630 double AddNode::evaluateToNumber(ExecState* exec)
2631 {
2632     return inlineEvaluateToNumber(exec);
2633 }
2634
2635 int32_t AddNode::evaluateToInt32(ExecState* exec)
2636 {
2637     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2638 }
2639
2640 uint32_t AddNode::evaluateToUInt32(ExecState* exec)
2641 {
2642     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2643 }
2644
2645 double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec)
2646 {
2647     double n1 = m_term1->evaluateToNumber(exec);
2648     KJS_CHECKEXCEPTIONNUMBER
2649     double n2 = m_term2->evaluateToNumber(exec);
2650     return n1 + n2;
2651 }
2652
2653 JSValue* AddNumbersNode::evaluate(ExecState* exec)
2654 {
2655     return jsNumber(inlineEvaluateToNumber(exec));
2656 }
2657
2658 double AddNumbersNode::evaluateToNumber(ExecState* exec)
2659 {
2660     return inlineEvaluateToNumber(exec);
2661 }
2662
2663 int32_t AddNumbersNode::evaluateToInt32(ExecState* exec)
2664 {
2665     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2666 }
2667
2668 uint32_t AddNumbersNode::evaluateToUInt32(ExecState* exec)
2669 {
2670     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2671 }
2672
2673 JSValue* AddStringsNode::evaluate(ExecState* exec)
2674 {
2675     JSValue* v1 = m_term1->evaluate(exec);
2676     KJS_CHECKEXCEPTIONVALUE
2677
2678     JSValue* v2 = m_term2->evaluate(exec);
2679     KJS_CHECKEXCEPTIONVALUE
2680
2681     return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
2682 }
2683
2684 JSValue* AddStringLeftNode::evaluate(ExecState* exec)
2685 {
2686     JSValue* v1 = m_term1->evaluate(exec);
2687     KJS_CHECKEXCEPTIONVALUE
2688
2689     JSValue* v2 = m_term2->evaluate(exec);
2690     KJS_CHECKEXCEPTIONVALUE
2691
2692     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
2693     return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
2694 }
2695
2696 JSValue* AddStringRightNode::evaluate(ExecState* exec)
2697 {
2698     JSValue* v1 = m_term1->evaluate(exec);
2699     KJS_CHECKEXCEPTIONVALUE
2700
2701     JSValue* v2 = m_term2->evaluate(exec);
2702     KJS_CHECKEXCEPTIONVALUE
2703
2704     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
2705     return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
2706 }
2707
2708 void SubNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2709 {
2710     nodeStack.append(m_term1.get());
2711     nodeStack.append(m_term2.get());
2712 }
2713
2714 // ECMA 11.6.2
2715 double SubNode::inlineEvaluateToNumber(ExecState* exec)
2716 {
2717     double n1 = m_term1->evaluateToNumber(exec);
2718     KJS_CHECKEXCEPTIONNUMBER
2719     double n2 = m_term2->evaluateToNumber(exec);
2720     return n1 - n2;
2721 }
2722
2723 JSValue* SubNode::evaluate(ExecState* exec)
2724 {
2725     return jsNumber(inlineEvaluateToNumber(exec));
2726 }
2727
2728 double SubNode::evaluateToNumber(ExecState* exec)
2729 {
2730     return inlineEvaluateToNumber(exec);
2731 }
2732
2733 int32_t SubNode::evaluateToInt32(ExecState* exec)
2734 {
2735     return JSValue::toInt32(inlineEvaluateToNumber(exec));
2736 }
2737
2738 uint32_t SubNode::evaluateToUInt32(ExecState* exec)
2739 {
2740     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
2741 }
2742
2743 // ------------------------------ Shift Nodes ------------------------------------
2744
2745 void LeftShiftNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2746 {
2747     nodeStack.append(m_term1.get());
2748     nodeStack.append(m_term2.get());
2749 }
2750
2751 // ECMA 11.7.1
2752 int32_t LeftShiftNode::inlineEvaluateToInt32(ExecState* exec)
2753 {
2754     int i1 = m_term1->evaluateToInt32(exec);
2755     KJS_CHECKEXCEPTIONNUMBER
2756     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
2757     return (i1 << i2);
2758 }
2759
2760 JSValue* LeftShiftNode::evaluate(ExecState* exec)
2761 {
2762     return jsNumber(inlineEvaluateToInt32(exec));
2763 }
2764
2765 double LeftShiftNode::evaluateToNumber(ExecState* exec)
2766 {
2767     return inlineEvaluateToInt32(exec);
2768 }
2769
2770 int32_t LeftShiftNode::evaluateToInt32(ExecState* exec)
2771 {
2772     return inlineEvaluateToInt32(exec);
2773 }
2774
2775 uint32_t LeftShiftNode::evaluateToUInt32(ExecState* exec)
2776 {
2777     return inlineEvaluateToInt32(exec);
2778 }
2779
2780 void RightShiftNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2781 {
2782     nodeStack.append(m_term1.get());
2783     nodeStack.append(m_term2.get());
2784 }
2785
2786 // ECMA 11.7.2
2787 int32_t RightShiftNode::inlineEvaluateToInt32(ExecState* exec)
2788 {
2789     int i1 = m_term1->evaluateToInt32(exec);
2790     KJS_CHECKEXCEPTIONNUMBER
2791     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
2792     return (i1 >> i2);
2793 }
2794
2795 JSValue* RightShiftNode::evaluate(ExecState* exec)
2796 {
2797     return jsNumber(inlineEvaluateToInt32(exec));
2798 }
2799
2800 double RightShiftNode::evaluateToNumber(ExecState* exec)
2801 {
2802     return inlineEvaluateToInt32(exec);
2803 }
2804
2805 int32_t RightShiftNode::evaluateToInt32(ExecState* exec)
2806 {
2807     return inlineEvaluateToInt32(exec);
2808 }
2809
2810 uint32_t RightShiftNode::evaluateToUInt32(ExecState* exec)
2811 {
2812     return inlineEvaluateToInt32(exec);
2813 }
2814
2815 void UnsignedRightShiftNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2816 {
2817     nodeStack.append(m_term1.get());
2818     nodeStack.append(m_term2.get());
2819 }
2820
2821 // ECMA 11.7.3
2822 uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(ExecState* exec)
2823 {
2824     unsigned int i1 = m_term1->evaluateToUInt32(exec);
2825     KJS_CHECKEXCEPTIONNUMBER
2826     unsigned int i2 = m_term2->evaluateToUInt32(exec) & 0x1f;
2827     return (i1 >> i2);
2828 }
2829
2830 JSValue* UnsignedRightShiftNode::evaluate(ExecState* exec)
2831 {
2832     return jsNumber(inlineEvaluateToUInt32(exec));
2833 }
2834
2835 double UnsignedRightShiftNode::evaluateToNumber(ExecState* exec)
2836 {
2837     return inlineEvaluateToUInt32(exec);
2838 }
2839
2840 int32_t UnsignedRightShiftNode::evaluateToInt32(ExecState* exec)
2841 {
2842     return inlineEvaluateToUInt32(exec);
2843 }
2844
2845 uint32_t UnsignedRightShiftNode::evaluateToUInt32(ExecState* exec)
2846 {
2847     return inlineEvaluateToUInt32(exec);
2848 }
2849
2850 // ------------------------------ Relational Nodes -------------------------------
2851
2852 static inline bool lessThan(ExecState* exec, JSValue* v1, JSValue* v2)
2853 {
2854     double n1;
2855     double n2;
2856     JSValue* p1;
2857     JSValue* p2;
2858     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
2859     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
2860
2861     if (wasNotString1 | wasNotString2)
2862         return n1 < n2;
2863
2864     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
2865 }
2866
2867 static inline bool lessThanEq(ExecState* exec, JSValue* v1, JSValue* v2)
2868 {
2869     double n1;
2870     double n2;
2871     JSValue* p1;
2872     JSValue* p2;
2873     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
2874     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
2875
2876     if (wasNotString1 | wasNotString2)
2877         return n1 <= n2;
2878
2879     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
2880 }
2881
2882 void LessNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2883 {
2884     nodeStack.append(m_expr2.get());
2885     nodeStack.append(m_expr1.get());
2886 }
2887
2888 // ECMA 11.8.1
2889 bool LessNode::inlineEvaluateToBoolean(ExecState* exec)
2890 {
2891     JSValue* v1 = m_expr1->evaluate(exec);
2892     KJS_CHECKEXCEPTIONBOOLEAN
2893     JSValue* v2 = m_expr2->evaluate(exec);
2894     KJS_CHECKEXCEPTIONBOOLEAN
2895     return lessThan(exec, v1, v2);
2896 }
2897
2898 JSValue* LessNode::evaluate(ExecState* exec)
2899 {
2900     return jsBoolean(inlineEvaluateToBoolean(exec));
2901 }
2902
2903 bool LessNode::evaluateToBoolean(ExecState* exec)
2904 {
2905     return inlineEvaluateToBoolean(exec);
2906 }
2907
2908 bool LessNumbersNode::inlineEvaluateToBoolean(ExecState* exec)
2909 {
2910     double n1 = m_expr1->evaluateToNumber(exec);
2911     KJS_CHECKEXCEPTIONVALUE
2912     double n2 = m_expr2->evaluateToNumber(exec);
2913     return n1 < n2;
2914 }
2915
2916 JSValue* LessNumbersNode::evaluate(ExecState* exec)
2917 {
2918     return jsBoolean(inlineEvaluateToBoolean(exec));
2919 }
2920
2921 bool LessNumbersNode::evaluateToBoolean(ExecState* exec)
2922 {
2923     return inlineEvaluateToBoolean(exec);
2924 }
2925
2926 bool LessStringsNode::inlineEvaluateToBoolean(ExecState* exec)
2927 {
2928     JSValue* v1 = m_expr1->evaluate(exec);
2929     KJS_CHECKEXCEPTIONVALUE
2930     JSValue* v2 = m_expr2->evaluate(exec);
2931     return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
2932 }
2933
2934 JSValue* LessStringsNode::evaluate(ExecState* exec)
2935 {
2936     return jsBoolean(inlineEvaluateToBoolean(exec));
2937 }
2938
2939 bool LessStringsNode::evaluateToBoolean(ExecState* exec)
2940 {
2941     return inlineEvaluateToBoolean(exec);
2942 }
2943
2944 void GreaterNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2945 {
2946     nodeStack.append(m_expr2.get());
2947     nodeStack.append(m_expr1.get());
2948 }
2949
2950 // ECMA 11.8.2
2951 bool GreaterNode::inlineEvaluateToBoolean(ExecState* exec)
2952 {
2953     JSValue* v1 = m_expr1->evaluate(exec);
2954     KJS_CHECKEXCEPTIONBOOLEAN
2955     JSValue* v2 = m_expr2->evaluate(exec);
2956     KJS_CHECKEXCEPTIONBOOLEAN
2957     return lessThan(exec, v2, v1);
2958 }
2959
2960 JSValue* GreaterNode::evaluate(ExecState* exec)
2961 {
2962     return jsBoolean(inlineEvaluateToBoolean(exec));
2963 }
2964
2965 bool GreaterNode::evaluateToBoolean(ExecState* exec)
2966 {
2967     return inlineEvaluateToBoolean(exec);
2968 }
2969
2970 void LessEqNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2971 {
2972     nodeStack.append(m_expr2.get());
2973     nodeStack.append(m_expr1.get());
2974 }
2975
2976 // ECMA 11.8.3
2977 bool LessEqNode::inlineEvaluateToBoolean(ExecState* exec)
2978 {
2979     JSValue* v1 = m_expr1->evaluate(exec);
2980     KJS_CHECKEXCEPTIONBOOLEAN
2981     JSValue* v2 = m_expr2->evaluate(exec);
2982     KJS_CHECKEXCEPTIONBOOLEAN
2983     return lessThanEq(exec, v1, v2);
2984 }
2985
2986 JSValue* LessEqNode::evaluate(ExecState* exec)
2987 {
2988     return jsBoolean(inlineEvaluateToBoolean(exec));
2989 }
2990
2991 bool LessEqNode::evaluateToBoolean(ExecState* exec)
2992 {
2993     return inlineEvaluateToBoolean(exec);
2994 }
2995
2996 void GreaterEqNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
2997 {
2998     nodeStack.append(m_expr2.get());
2999     nodeStack.append(m_expr1.get());
3000 }
3001
3002 // ECMA 11.8.4
3003 bool GreaterEqNode::inlineEvaluateToBoolean(ExecState* exec)
3004 {
3005     JSValue* v1 = m_expr1->evaluate(exec);
3006     KJS_CHECKEXCEPTIONBOOLEAN
3007     JSValue* v2 = m_expr2->evaluate(exec);
3008     KJS_CHECKEXCEPTIONBOOLEAN
3009     return lessThanEq(exec, v2, v1);
3010 }
3011
3012 JSValue* GreaterEqNode::evaluate(ExecState* exec)
3013 {
3014     return jsBoolean(inlineEvaluateToBoolean(exec));
3015 }
3016
3017 bool GreaterEqNode::evaluateToBoolean(ExecState* exec)
3018 {
3019     return inlineEvaluateToBoolean(exec);
3020 }
3021
3022 void InstanceOfNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3023 {
3024     nodeStack.append(m_expr2.get());
3025     nodeStack.append(m_expr1.get());
3026 }
3027
3028 // ECMA 11.8.6
3029 JSValue* InstanceOfNode::evaluate(ExecState* exec)
3030 {
3031     JSValue* v1 = m_expr1->evaluate(exec);
3032     KJS_CHECKEXCEPTIONVALUE
3033     JSValue* v2 = m_expr2->evaluate(exec);
3034     KJS_CHECKEXCEPTIONVALUE
3035
3036     if (!v2->isObject())
3037         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, m_expr2.get());
3038
3039     JSObject* o2 = static_cast<JSObject*>(v2);
3040
3041     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
3042     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
3043     // property. It seems that all objects have the property, but not all implement it, so in this
3044     // case we return false (consistent with Mozilla).
3045     if (!o2->implementsHasInstance())
3046         return jsBoolean(false);
3047
3048     return jsBoolean(o2->hasInstance(exec, v1));
3049 }
3050
3051 bool InstanceOfNode::evaluateToBoolean(ExecState* exec)
3052 {
3053     JSValue* v1 = m_expr1->evaluate(exec);
3054     KJS_CHECKEXCEPTIONBOOLEAN
3055     JSValue* v2 = m_expr2->evaluate(exec);
3056     KJS_CHECKEXCEPTIONBOOLEAN
3057
3058     if (!v2->isObject()) {
3059         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'instanceof' operator.", v2, m_expr2.get());
3060         return false;
3061     }
3062
3063     JSObject* o2 = static_cast<JSObject*>(v2);
3064
3065     // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
3066     // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
3067     // property. It seems that all objects have the property, but not all implement it, so in this
3068     // case we return false (consistent with Mozilla).
3069     if (!o2->implementsHasInstance())
3070         return false;
3071
3072     return o2->hasInstance(exec, v1);
3073 }
3074
3075 void InNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3076 {
3077     nodeStack.append(m_expr2.get());
3078     nodeStack.append(m_expr1.get());
3079 }
3080
3081 // ECMA 11.8.7
3082 JSValue* InNode::evaluate(ExecState* exec)
3083 {
3084     JSValue* v1 = m_expr1->evaluate(exec);
3085     KJS_CHECKEXCEPTIONVALUE
3086     JSValue* v2 = m_expr2->evaluate(exec);
3087     KJS_CHECKEXCEPTIONVALUE
3088
3089     if (!v2->isObject())
3090         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
3091
3092     return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
3093 }
3094
3095 bool InNode::evaluateToBoolean(ExecState* exec)
3096 {
3097     JSValue* v1 = m_expr1->evaluate(exec);
3098     KJS_CHECKEXCEPTIONBOOLEAN
3099     JSValue* v2 = m_expr2->evaluate(exec);
3100     KJS_CHECKEXCEPTIONBOOLEAN
3101
3102     if (!v2->isObject()) {
3103         throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, m_expr2.get());
3104         return false;
3105     }
3106
3107     return static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec)));
3108 }
3109
3110 // ------------------------------ Equality Nodes ------------------------------------
3111
3112 void EqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3113 {
3114     nodeStack.append(m_expr2.get());
3115     nodeStack.append(m_expr1.get());
3116 }
3117
3118 // ECMA 11.9.1
3119 bool EqualNode::inlineEvaluateToBoolean(ExecState* exec)
3120 {
3121     JSValue* v1 = m_expr1->evaluate(exec);
3122     KJS_CHECKEXCEPTIONBOOLEAN
3123     JSValue* v2 = m_expr2->evaluate(exec);
3124     KJS_CHECKEXCEPTIONBOOLEAN
3125
3126     return equal(exec, v1, v2);
3127 }
3128
3129 JSValue* EqualNode::evaluate(ExecState* exec)
3130 {
3131     return jsBoolean(inlineEvaluateToBoolean(exec));
3132 }
3133
3134 bool EqualNode::evaluateToBoolean(ExecState* exec)
3135 {
3136     return inlineEvaluateToBoolean(exec);
3137 }
3138
3139 void NotEqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3140 {
3141     nodeStack.append(m_expr2.get());
3142     nodeStack.append(m_expr1.get());
3143 }
3144
3145 // ECMA 11.9.2
3146 bool NotEqualNode::inlineEvaluateToBoolean(ExecState* exec)
3147 {
3148     JSValue* v1 = m_expr1->evaluate(exec);
3149     KJS_CHECKEXCEPTIONBOOLEAN
3150     JSValue* v2 = m_expr2->evaluate(exec);
3151     KJS_CHECKEXCEPTIONBOOLEAN
3152
3153     return !equal(exec,v1, v2);
3154 }
3155
3156 JSValue* NotEqualNode::evaluate(ExecState* exec)
3157 {
3158     return jsBoolean(inlineEvaluateToBoolean(exec));
3159 }
3160
3161 bool NotEqualNode::evaluateToBoolean(ExecState* exec)
3162 {
3163     return inlineEvaluateToBoolean(exec);
3164 }
3165
3166 void StrictEqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3167 {
3168     nodeStack.append(m_expr2.get());
3169     nodeStack.append(m_expr1.get());
3170 }
3171
3172 // ECMA 11.9.4
3173 bool StrictEqualNode::inlineEvaluateToBoolean(ExecState* exec)
3174 {
3175     JSValue* v1 = m_expr1->evaluate(exec);
3176     KJS_CHECKEXCEPTIONBOOLEAN
3177     JSValue* v2 = m_expr2->evaluate(exec);
3178     KJS_CHECKEXCEPTIONBOOLEAN
3179
3180     return strictEqual(exec,v1, v2);
3181 }
3182
3183 JSValue* StrictEqualNode::evaluate(ExecState* exec)
3184 {
3185     return jsBoolean(inlineEvaluateToBoolean(exec));
3186 }
3187
3188 bool StrictEqualNode::evaluateToBoolean(ExecState* exec)
3189 {
3190     return inlineEvaluateToBoolean(exec);
3191 }
3192
3193 void NotStrictEqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3194 {
3195     nodeStack.append(m_expr2.get());
3196     nodeStack.append(m_expr1.get());
3197 }
3198
3199 // ECMA 11.9.5
3200 bool NotStrictEqualNode::inlineEvaluateToBoolean(ExecState* exec)
3201 {
3202     JSValue* v1 = m_expr1->evaluate(exec);
3203     KJS_CHECKEXCEPTIONBOOLEAN
3204     JSValue* v2 = m_expr2->evaluate(exec);
3205     KJS_CHECKEXCEPTIONBOOLEAN
3206
3207     return !strictEqual(exec,v1, v2);
3208 }
3209
3210 JSValue* NotStrictEqualNode::evaluate(ExecState* exec)
3211 {
3212     return jsBoolean(inlineEvaluateToBoolean(exec));
3213 }
3214
3215 bool NotStrictEqualNode::evaluateToBoolean(ExecState* exec)
3216 {
3217     return inlineEvaluateToBoolean(exec);
3218 }
3219
3220 // ------------------------------ Bit Operation Nodes ----------------------------------
3221
3222 void BitAndNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3223 {
3224     nodeStack.append(m_expr2.get());
3225     nodeStack.append(m_expr1.get());
3226 }
3227
3228 // ECMA 11.10
3229 JSValue* BitAndNode::evaluate(ExecState* exec)
3230 {
3231     JSValue* v1 = m_expr1->evaluate(exec);
3232     KJS_CHECKEXCEPTIONVALUE
3233     JSValue* v2 = m_expr2->evaluate(exec);
3234     KJS_CHECKEXCEPTIONVALUE
3235
3236     return jsNumberFromAnd(exec, v1, v2);
3237 }
3238
3239 int32_t BitAndNode::inlineEvaluateToInt32(ExecState* exec)
3240 {
3241     int32_t i1 = m_expr1->evaluateToInt32(exec);
3242     KJS_CHECKEXCEPTIONNUMBER
3243     int32_t i2 = m_expr2->evaluateToInt32(exec);
3244     return (i1 & i2);
3245 }
3246
3247 double BitAndNode::evaluateToNumber(ExecState* exec)
3248 {
3249     return inlineEvaluateToInt32(exec);
3250 }
3251
3252 bool BitAndNode::evaluateToBoolean(ExecState* exec)
3253 {
3254     return inlineEvaluateToInt32(exec);
3255 }
3256
3257 int32_t BitAndNode::evaluateToInt32(ExecState* exec)
3258 {
3259     return inlineEvaluateToInt32(exec);
3260 }
3261
3262 uint32_t BitAndNode::evaluateToUInt32(ExecState* exec)
3263 {
3264     return inlineEvaluateToInt32(exec);
3265 }
3266
3267 void BitXOrNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3268 {
3269     nodeStack.append(m_expr2.get());
3270     nodeStack.append(m_expr1.get());
3271 }
3272
3273 int32_t BitXOrNode::inlineEvaluateToInt32(ExecState* exec)
3274 {
3275     int i1 = m_expr1->evaluateToInt32(exec);
3276     KJS_CHECKEXCEPTIONNUMBER
3277     int i2 = m_expr2->evaluateToInt32(exec);
3278     return (i1 ^ i2);
3279 }
3280
3281 JSValue* BitXOrNode::evaluate(ExecState* exec)
3282 {
3283     return jsNumber(inlineEvaluateToInt32(exec));
3284 }
3285
3286 double BitXOrNode::evaluateToNumber(ExecState* exec)
3287 {
3288     return inlineEvaluateToInt32(exec);
3289 }
3290
3291 bool BitXOrNode::evaluateToBoolean(ExecState* exec)
3292 {
3293     return inlineEvaluateToInt32(exec);
3294 }
3295
3296 int32_t BitXOrNode::evaluateToInt32(ExecState* exec)
3297 {
3298     return inlineEvaluateToInt32(exec);
3299 }
3300
3301 uint32_t BitXOrNode::evaluateToUInt32(ExecState* exec)
3302 {
3303     return inlineEvaluateToInt32(exec);
3304 }
3305
3306 void BitOrNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3307 {
3308     nodeStack.append(m_expr2.get());
3309     nodeStack.append(m_expr1.get());
3310 }
3311
3312 int32_t BitOrNode::inlineEvaluateToInt32(ExecState* exec)
3313 {
3314     int i1 = m_expr1->evaluateToInt32(exec);
3315     KJS_CHECKEXCEPTIONNUMBER
3316     int i2 = m_expr2->evaluateToInt32(exec);
3317     return (i1 | i2);
3318 }
3319
3320 JSValue* BitOrNode::evaluate(ExecState* exec)
3321 {
3322     return jsNumber(inlineEvaluateToInt32(exec));
3323 }
3324
3325 double BitOrNode::evaluateToNumber(ExecState* exec)
3326 {
3327     return inlineEvaluateToInt32(exec);
3328 }
3329
3330 bool BitOrNode::evaluateToBoolean(ExecState* exec)
3331 {
3332     return inlineEvaluateToInt32(exec);
3333 }
3334
3335 int32_t BitOrNode::evaluateToInt32(ExecState* exec)
3336 {
3337     return inlineEvaluateToInt32(exec);
3338 }
3339
3340 uint32_t BitOrNode::evaluateToUInt32(ExecState* exec)
3341 {
3342     return inlineEvaluateToInt32(exec);
3343 }
3344
3345 // ------------------------------ Binary Logical Nodes ----------------------------
3346
3347 void LogicalAndNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3348 {
3349     nodeStack.append(m_expr2.get());
3350     nodeStack.append(m_expr1.get());
3351 }
3352
3353 // ECMA 11.11
3354 JSValue* LogicalAndNode::evaluate(ExecState* exec)
3355 {
3356     JSValue* v1 = m_expr1->evaluate(exec);
3357     KJS_CHECKEXCEPTIONVALUE
3358     bool b1 = v1->toBoolean(exec);
3359     KJS_CHECKEXCEPTIONVALUE
3360     if (!b1)
3361         return v1;
3362     JSValue* v2 = m_expr2->evaluate(exec);
3363     KJS_CHECKEXCEPTIONVALUE
3364     return v2;
3365 }
3366
3367 bool LogicalAndNode::evaluateToBoolean(ExecState* exec)
3368 {
3369     bool b = m_expr1->evaluateToBoolean(exec);
3370     KJS_CHECKEXCEPTIONBOOLEAN
3371     return b && m_expr2->evaluateToBoolean(exec);
3372 }
3373
3374 void LogicalOrNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3375 {
3376     nodeStack.append(m_expr2.get());
3377     nodeStack.append(m_expr1.get());
3378 }
3379
3380 JSValue* LogicalOrNode::evaluate(ExecState* exec)
3381 {
3382     JSValue* v1 = m_expr1->evaluate(exec);
3383     KJS_CHECKEXCEPTIONVALUE
3384     if (v1->toBoolean(exec))
3385         return v1;
3386     return m_expr2->evaluate(exec);
3387 }
3388
3389 bool LogicalOrNode::evaluateToBoolean(ExecState* exec)
3390 {
3391     bool b = m_expr1->evaluateToBoolean(exec);
3392     KJS_CHECKEXCEPTIONBOOLEAN
3393     return b || m_expr2->evaluateToBoolean(exec);
3394 }
3395
3396 // ------------------------------ ConditionalNode ------------------------------
3397
3398 void ConditionalNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3399 {
3400     nodeStack.append(m_expr2.get());
3401     nodeStack.append(m_expr1.get());
3402     nodeStack.append(m_logical.get());
3403 }
3404
3405 // ECMA 11.12
3406 JSValue* ConditionalNode::evaluate(ExecState* exec)
3407 {
3408     bool b = m_logical->evaluateToBoolean(exec);
3409     KJS_CHECKEXCEPTIONVALUE
3410     return b ? m_expr1->evaluate(exec) : m_expr2->evaluate(exec);
3411 }
3412
3413 bool ConditionalNode::evaluateToBoolean(ExecState* exec)
3414 {
3415     bool b = m_logical->evaluateToBoolean(exec);
3416     KJS_CHECKEXCEPTIONBOOLEAN
3417     return b ? m_expr1->evaluateToBoolean(exec) : m_expr2->evaluateToBoolean(exec);
3418 }
3419
3420 double ConditionalNode::evaluateToNumber(ExecState* exec)
3421 {
3422     bool b = m_logical->evaluateToBoolean(exec);
3423     KJS_CHECKEXCEPTIONNUMBER
3424     return b ? m_expr1->evaluateToNumber(exec) : m_expr2->evaluateToNumber(exec);
3425 }
3426
3427 int32_t ConditionalNode::evaluateToInt32(ExecState* exec)
3428 {
3429     bool b = m_logical->evaluateToBoolean(exec);
3430     KJS_CHECKEXCEPTIONNUMBER
3431     return b ? m_expr1->evaluateToInt32(exec) : m_expr2->evaluateToInt32(exec);
3432 }
3433
3434 uint32_t ConditionalNode::evaluateToUInt32(ExecState* exec)
3435 {
3436     bool b = m_logical->evaluateToBoolean(exec);
3437     KJS_CHECKEXCEPTIONNUMBER
3438     return b ? m_expr1->evaluateToUInt32(exec) : m_expr2->evaluateToUInt32(exec);
3439 }
3440
3441 // ECMA 11.13
3442
3443 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
3444 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
3445 {
3446     JSValue* v;
3447     int i1;
3448     int i2;
3449     unsigned int ui;
3450     switch (oper) {
3451         case OpMultEq:
3452             v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec));
3453             break;
3454         case OpDivEq:
3455             v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec));
3456             break;
3457         case OpPlusEq:
3458             v = add(exec, current, right->evaluate(exec));
3459             break;
3460         case OpMinusEq:
3461             v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec));
3462             break;
3463         case OpLShift:
3464             i1 = current->toInt32(exec);
3465             i2 = right->evaluateToInt32(exec);
3466             v = jsNumber(i1 << i2);
3467             break;
3468         case OpRShift:
3469             i1 = current->toInt32(exec);
3470             i2 = right->evaluateToInt32(exec);
3471             v = jsNumber(i1 >> i2);
3472             break;
3473         case OpURShift:
3474             ui = current->toUInt32(exec);
3475             i2 = right->evaluateToInt32(exec);
3476             v = jsNumber(ui >> i2);
3477             break;
3478         case OpAndEq:
3479             i1 = current->toInt32(exec);
3480             i2 = right->evaluateToInt32(exec);
3481             v = jsNumber(i1 & i2);
3482             break;
3483         case OpXOrEq:
3484             i1 = current->toInt32(exec);
3485             i2 = right->evaluateToInt32(exec);
3486             v = jsNumber(i1 ^ i2);
3487             break;
3488         case OpOrEq:
3489             i1 = current->toInt32(exec);
3490             i2 = right->evaluateToInt32(exec);
3491             v = jsNumber(i1 | i2);
3492             break;
3493         case OpModEq: {
3494             double d1 = current->toNumber(exec);
3495             double d2 = right->evaluateToNumber(exec);
3496             v = jsNumber(fmod(d1, d2));
3497         }
3498             break;
3499         default:
3500             ASSERT_NOT_REACHED();
3501             v = jsUndefined();
3502     }
3503
3504     return v;
3505 }
3506
3507 // ------------------------------ ReadModifyResolveNode -----------------------------------
3508
3509 void ReadModifyResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
3510 {
3511     nodeStack.append(m_right.get());
3512     size_t index = symbolTable.get(m_ident.ustring().rep());
3513     if (index != missingSymbolMarker()) {
3514         if (isConstant(localStorage, index))
3515             new (this) ReadModifyConstNode(index);
3516         else
3517             new (this) ReadModifyLocalVarNode(index);
3518     }
3519 }
3520
3521 // ------------------------------ AssignResolveNode -----------------------------------
3522
3523 void AssignResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
3524 {
3525     nodeStack.append(m_right.get());
3526     size_t index = symbolTable.get(m_ident.ustring().rep());
3527     if (index != missingSymbolMarker()) {
3528         if (isConstant(localStorage, index))
3529             new (this) AssignConstNode;
3530         else
3531             new (this) AssignLocalVarNode(index);
3532     }
3533 }
3534
3535 // ------------------------------ ReadModifyLocalVarNode -----------------------------------
3536
3537 JSValue* ReadModifyLocalVarNode::evaluate(ExecState* exec)
3538 {
3539     ASSERT(exec->variableObject() == exec->scopeChain().top());
3540
3541     ASSERT(m_operator != OpEqual);
3542     JSValue* v = valueForReadModifyAssignment(exec, exec->localStorage()[m_index].value, m_right.get(), m_operator);
3543
3544     KJS_CHECKEXCEPTIONVALUE
3545     
3546     // We can't store a pointer into localStorage() and use it throughout the function
3547     // body, because valueForReadModifyAssignment() might cause an ActivationImp tear-off,
3548     // changing the value of localStorage().
3549     
3550     exec->localStorage()[m_index].value = v;
3551     return v;
3552 }
3553
3554 // ------------------------------ AssignLocalVarNode -----------------------------------
3555
3556 JSValue* AssignLocalVarNode::evaluate(ExecState* exec)
3557 {
3558     ASSERT(exec->variableObject() == exec->scopeChain().top());
3559     JSValue* v = m_right->evaluate(exec);
3560
3561     KJS_CHECKEXCEPTIONVALUE
3562
3563     exec->localStorage()[m_index].value = v;
3564
3565     return v;
3566 }
3567
3568 // ------------------------------ ReadModifyConstNode -----------------------------------
3569
3570 JSValue* ReadModifyConstNode::evaluate(ExecState* exec)
3571 {
3572     ASSERT(exec->variableObject() == exec->scopeChain().top());
3573     JSValue* left = exec->localStorage()[m_index].value;
3574     ASSERT(m_operator != OpEqual);
3575     JSValue* result = valueForReadModifyAssignment(exec, left, m_right.get(), m_operator);
3576     KJS_CHECKEXCEPTIONVALUE
3577     return result;
3578 }
3579
3580 // ------------------------------ AssignConstNode -----------------------------------
3581
3582 JSValue* AssignConstNode::evaluate(ExecState* exec)
3583 {
3584     return m_right->evaluate(exec);
3585 }
3586
3587 JSValue* ReadModifyResolveNode::evaluate(ExecState* exec)
3588 {
3589     const ScopeChain& chain = exec->scopeChain();
3590     ScopeChainIterator iter = chain.begin();
3591     ScopeChainIterator end = chain.end();
3592
3593     // We must always have something in the scope chain
3594     ASSERT(iter != end);
3595
3596     PropertySlot slot;
3597     JSObject* base;
3598     do {
3599         base = *iter;
3600         if (base->getPropertySlot(exec, m_ident, slot)) {
3601             // See the comment in PostIncResolveNode::evaluate().
3602
3603             base = *iter;
3604             goto found;
3605         }
3606
3607         ++iter;
3608     } while (iter != end);
3609
3610     ASSERT(m_operator != OpEqual);
3611     return throwUndefinedVariableError(exec, m_ident);
3612
3613 found:
3614     JSValue* v;
3615
3616     ASSERT(m_operator != OpEqual);
3617     JSValue* v1 = slot.getValue(exec, base, m_ident);
3618     KJS_CHECKEXCEPTIONVALUE
3619     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
3620
3621     KJS_CHECKEXCEPTIONVALUE
3622     
3623     // Since valueForReadModifyAssignment() might cause an ActivationImp tear-off,
3624     // we need to get the base from the ScopeChainIterator again.
3625     
3626     (*iter)->put(exec, m_ident, v);
3627     return v;
3628 }
3629
3630 JSValue* AssignResolveNode::evaluate(ExecState* exec)
3631 {
3632     const ScopeChain& chain = exec->scopeChain();
3633     ScopeChainIterator iter = chain.begin();
3634     ScopeChainIterator end = chain.end();
3635
3636     // we must always have something in the scope chain
3637     ASSERT(iter != end);
3638
3639     PropertySlot slot;
3640     JSObject* base;
3641     do {
3642         base = *iter;
3643         if (base->getPropertySlot(exec, m_ident, slot)) {
3644             // See the comment in PostIncResolveNode::evaluate().
3645
3646             base = *iter;
3647             goto found;
3648         }
3649
3650         ++iter;
3651     } while (iter != end);
3652
3653 found:
3654     JSValue* v = m_right->evaluate(exec);
3655
3656     KJS_CHECKEXCEPTIONVALUE
3657
3658     base->put(exec, m_ident, v);
3659     return v;
3660 }
3661
3662 // ------------------------------ ReadModifyDotNode -----------------------------------
3663
3664 void AssignDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3665 {
3666     nodeStack.append(m_right.get());
3667     nodeStack.append(m_base.get());
3668 }
3669
3670 JSValue* AssignDotNode::evaluate(ExecState* exec)
3671 {
3672     JSValue* baseValue = m_base->evaluate(exec);
3673     KJS_CHECKEXCEPTIONVALUE
3674     JSObject* base = baseValue->toObject(exec);
3675
3676     JSValue* v = m_right->evaluate(exec);
3677
3678     KJS_CHECKEXCEPTIONVALUE
3679
3680     base->put(exec, m_ident, v);
3681     return v;
3682 }
3683
3684 void ReadModifyDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3685 {
3686     nodeStack.append(m_right.get());
3687     nodeStack.append(m_base.get());
3688 }
3689
3690 JSValue* ReadModifyDotNode::evaluate(ExecState* exec)
3691 {
3692     JSValue* baseValue = m_base->evaluate(exec);
3693     KJS_CHECKEXCEPTIONVALUE
3694     JSObject* base = baseValue->toObject(exec);
3695
3696     JSValue* v;
3697
3698     ASSERT(m_operator != OpEqual);
3699     PropertySlot slot;
3700     JSValue* v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
3701     KJS_CHECKEXCEPTIONVALUE
3702     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
3703
3704     KJS_CHECKEXCEPTIONVALUE
3705
3706     base->put(exec, m_ident, v);
3707     return v;
3708 }
3709
3710 // ------------------------------ AssignErrorNode -----------------------------------
3711
3712 JSValue* AssignErrorNode::evaluate(ExecState* exec)
3713 {
3714     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
3715     handleException(exec);
3716     return jsUndefined();
3717 }
3718
3719 // ------------------------------ AssignBracketNode -----------------------------------
3720
3721 void AssignBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3722 {
3723     nodeStack.append(m_right.get());
3724     nodeStack.append(m_subscript.get());
3725     nodeStack.append(m_base.get());
3726 }
3727
3728 JSValue* AssignBracketNode::evaluate(ExecState* exec)
3729 {
3730     JSValue* baseValue = m_base->evaluate(exec);
3731     KJS_CHECKEXCEPTIONVALUE
3732     JSValue* subscript = m_subscript->evaluate(exec);
3733     KJS_CHECKEXCEPTIONVALUE
3734
3735     JSObject* base = baseValue->toObject(exec);
3736
3737     uint32_t propertyIndex;
3738     if (subscript->getUInt32(propertyIndex)) {
3739         JSValue* v = m_right->evaluate(exec);
3740         KJS_CHECKEXCEPTIONVALUE
3741
3742         base->put(exec, propertyIndex, v);
3743         return v;
3744     }
3745
3746     Identifier propertyName(subscript->toString(exec));
3747     JSValue* v = m_right->evaluate(exec);
3748     KJS_CHECKEXCEPTIONVALUE
3749
3750     base->put(exec, propertyName, v);
3751     return v;
3752 }
3753 void ReadModifyBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3754 {
3755     nodeStack.append(m_right.get());
3756     nodeStack.append(m_subscript.get());
3757     nodeStack.append(m_base.get());
3758 }
3759
3760 JSValue* ReadModifyBracketNode::evaluate(ExecState* exec)
3761 {
3762     JSValue* baseValue = m_base->evaluate(exec);
3763     KJS_CHECKEXCEPTIONVALUE
3764     JSValue* subscript = m_subscript->evaluate(exec);
3765     KJS_CHECKEXCEPTIONVALUE
3766
3767     JSObject* base = baseValue->toObject(exec);
3768
3769     uint32_t propertyIndex;
3770     if (subscript->getUInt32(propertyIndex)) {
3771         JSValue* v;
3772         ASSERT(m_operator != OpEqual);
3773         PropertySlot slot;
3774         JSValue* v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
3775         KJS_CHECKEXCEPTIONVALUE
3776         v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
3777
3778         KJS_CHECKEXCEPTIONVALUE
3779
3780         base->put(exec, propertyIndex, v);
3781         return v;
3782     }
3783
3784     Identifier propertyName(subscript->toString(exec));
3785     JSValue* v;
3786
3787     ASSERT(m_operator != OpEqual);
3788     PropertySlot slot;
3789     JSValue* v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
3790     KJS_CHECKEXCEPTIONVALUE
3791     v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_operator);
3792
3793     KJS_CHECKEXCEPTIONVALUE
3794
3795     base->put(exec, propertyName, v);
3796     return v;
3797 }
3798
3799 // ------------------------------ CommaNode ------------------------------------
3800
3801 void CommaNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3802 {
3803     nodeStack.append(m_expr2.get());
3804     nodeStack.append(m_expr1.get());
3805 }
3806
3807 // ECMA 11.14
3808 JSValue* CommaNode::evaluate(ExecState* exec)
3809 {
3810     m_expr1->evaluate(exec);
3811     KJS_CHECKEXCEPTIONVALUE
3812     return m_expr2->evaluate(exec);
3813 }
3814
3815 // ------------------------------ ConstDeclNode ----------------------------------
3816
3817 ConstDeclNode::ConstDeclNode(const Identifier& ident, ExpressionNode* init)
3818     : m_ident(ident)
3819     , m_init(init)
3820 {
3821 }
3822
3823 void ConstDeclNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
3824 {
3825     if (m_next)
3826         nodeStack.append(m_next.get());
3827     if (m_init)
3828         nodeStack.append(m_init.get());
3829 }
3830
3831 void ConstDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
3832 {
3833     ScopeChainIterator iter = chain.begin();
3834     ScopeChainIterator end = chain.end();
3835
3836     // We must always have something in the scope chain
3837     ASSERT(iter != end);
3838
3839     PropertySlot slot;
3840     JSObject* base;
3841
3842     do {
3843         base = *iter;
3844         if (base->getPropertySlot(exec, m_ident, slot))
3845             break;
3846         ++iter;
3847     } while (iter != end);
3848
3849     ASSERT(base->isActivationObject() || base->isGlobalObject());
3850
3851     static_cast<JSVariableObject*>(base)->initializeVariable(exec, m_ident, val, ReadOnly);
3852 }
3853
3854 // ECMA 12.2
3855 inline void ConstDeclNode::evaluateSingle(ExecState* exec)
3856 {
3857     ASSERT(exec->variableObject()->hasOwnProperty(exec, m_ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations.
3858     const ScopeChain& chain = exec->scopeChain();
3859     JSVariableObject* variableObject = exec->variableObject();
3860
3861     ASSERT(!chain.isEmpty());
3862
3863     bool inGlobalScope = ++chain.begin() == chain.end();
3864
3865     if (m_init) {
3866         if (inGlobalScope) {
3867             JSValue* val = m_init->evaluate(exec);
3868             unsigned attributes = ReadOnly;
3869             if (exec->codeType() != EvalCode)
3870                 attributes |= DontDelete;
3871             variableObject->initializeVariable(exec, m_ident, val, attributes);
3872         } else {
3873             JSValue* val = m_init->evaluate(exec);
3874             KJS_CHECKEXCEPTIONVOID
3875
3876             // if the variable object is the top of the scope chain, then that must
3877             // be where this variable is declared, processVarDecls would have put
3878             // it there. Don't search the scope chain, to optimize this very common case.
3879             if (chain.top() != variableObject)
38