2008-06-03 Cameron Zwarich <cwzwarich@uwaterloo.ca>
[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 "CodeGenerator.h"
30 #include "ExecState.h"
31 #include "JSGlobalObject.h"
32 #include "Parser.h"
33 #include "PropertyNameArray.h"
34 #include "array_object.h"
35 #include "debugger.h"
36 #include "function_object.h"
37 #include "lexer.h"
38 #include "operations.h"
39 #include "regexp_object.h"
40 #include <math.h>
41 #include <wtf/Assertions.h>
42 #include <wtf/HashCountedSet.h>
43 #include <wtf/HashSet.h>
44 #include <wtf/MathExtras.h>
45
46 namespace KJS {
47
48 #define KJS_CHECKEXCEPTION \
49 if (UNLIKELY(exec->hadException())) \
50     return rethrowException(exec);
51
52 #define KJS_CHECKEXCEPTIONVALUE \
53 if (UNLIKELY(exec->hadException())) { \
54     handleException(exec); \
55     return jsUndefined(); \
56 }
57
58 #define KJS_CHECKEXCEPTIONNUMBER \
59 if (UNLIKELY(exec->hadException())) { \
60     handleException(exec); \
61     return 0; \
62 }
63
64 #define KJS_CHECKEXCEPTIONBOOLEAN \
65 if (UNLIKELY(exec->hadException())) { \
66     handleException(exec); \
67     return false; \
68 }
69
70 #define KJS_CHECKEXCEPTIONVOID \
71 if (UNLIKELY(exec->hadException())) { \
72     handleException(exec); \
73     return; \
74 }
75
76 static inline bool isConstant(const LocalStorage& localStorage, size_t index)
77 {
78     ASSERT(index < localStorage.size());
79     return localStorage[index].attributes & ReadOnly;
80 }
81
82 static inline UString::Rep* rep(const Identifier& ident)
83 {
84     return ident.ustring().rep();
85 }
86
87 // ------------------------------ Node -----------------------------------------
88
89 #ifndef NDEBUG
90 #ifndef LOG_CHANNEL_PREFIX
91 #define LOG_CHANNEL_PREFIX Log
92 #endif
93 static WTFLogChannel LogKJSNodeLeaks = { 0x00000000, "", WTFLogChannelOn };
94
95 struct ParserRefCountedCounter {
96     static unsigned count;
97     ParserRefCountedCounter()
98     {
99         if (count)
100             LOG(KJSNodeLeaks, "LEAK: %u KJS::Node\n", count);
101     }
102 };
103 unsigned ParserRefCountedCounter::count = 0;
104 static ParserRefCountedCounter parserRefCountedCounter;
105 #endif
106
107 static HashSet<ParserRefCounted*>* newTrackedObjects;
108 static HashCountedSet<ParserRefCounted*>* trackedObjectExtraRefCounts;
109
110 ParserRefCounted::ParserRefCounted()
111 {
112 #ifndef NDEBUG
113     ++ParserRefCountedCounter::count;
114 #endif
115     if (!newTrackedObjects)
116         newTrackedObjects = new HashSet<ParserRefCounted*>;
117     newTrackedObjects->add(this);
118     ASSERT(newTrackedObjects->contains(this));
119 }
120
121 ParserRefCounted::~ParserRefCounted()
122 {
123 #ifndef NDEBUG
124     --ParserRefCountedCounter::count;
125 #endif
126 }
127
128 void ParserRefCounted::ref()
129 {
130     // bumping from 0 to 1 is just removing from the new nodes set
131     if (newTrackedObjects) {
132         HashSet<ParserRefCounted*>::iterator it = newTrackedObjects->find(this);
133         if (it != newTrackedObjects->end()) {
134             newTrackedObjects->remove(it);
135             ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(this));
136             return;
137         }
138     }
139
140     ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this));
141
142     if (!trackedObjectExtraRefCounts)
143         trackedObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>;
144     trackedObjectExtraRefCounts->add(this);
145 }
146
147 void ParserRefCounted::deref()
148 {
149     ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this));
150
151     if (!trackedObjectExtraRefCounts) {
152         delete this;
153         return;
154     }
155
156     HashCountedSet<ParserRefCounted*>::iterator it = trackedObjectExtraRefCounts->find(this);
157     if (it == trackedObjectExtraRefCounts->end())
158         delete this;
159     else
160         trackedObjectExtraRefCounts->remove(it);
161 }
162
163 unsigned ParserRefCounted::refcount()
164 {
165     if (newTrackedObjects && newTrackedObjects->contains(this)) {
166         ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(this));
167         return 0;
168     }
169
170     ASSERT(!newTrackedObjects || !newTrackedObjects->contains(this));
171
172     if (!trackedObjectExtraRefCounts)
173         return 1;
174
175     return 1 + trackedObjectExtraRefCounts->count(this);
176 }
177
178 void ParserRefCounted::deleteNewObjects()
179 {
180     if (!newTrackedObjects)
181         return;
182
183 #ifndef NDEBUG
184     HashSet<ParserRefCounted*>::iterator end = newTrackedObjects->end();
185     for (HashSet<ParserRefCounted*>::iterator it = newTrackedObjects->begin(); it != end; ++it)
186         ASSERT(!trackedObjectExtraRefCounts || !trackedObjectExtraRefCounts->contains(*it));
187 #endif
188     deleteAllValues(*newTrackedObjects);
189     delete newTrackedObjects;
190     newTrackedObjects = 0;
191 }
192
193 Node::Node()
194     : m_expectedReturnType(ObjectType)
195 {
196     m_line = lexer().lineNo();
197 }
198
199 Node::Node(JSType expectedReturn)
200     : m_expectedReturnType(expectedReturn)
201 {
202     m_line = lexer().lineNo();
203 }
204
205 static void substitute(UString& string, const UString& substring) KJS_FAST_CALL;
206 static void substitute(UString& string, const UString& substring)
207 {
208     int position = string.find("%s");
209     ASSERT(position != -1);
210     UString newString = string.substr(0, position);
211     newString.append(substring);
212     newString.append(string.substr(position + 2));
213     string = newString;
214 }
215
216 static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
217 static inline int currentSourceId(ExecState*)
218 {
219     ASSERT_NOT_REACHED();
220     return 0;
221 }
222
223 static inline const UString currentSourceURL(ExecState* exec) KJS_FAST_CALL;
224 static inline const UString currentSourceURL(ExecState*)
225 {
226     ASSERT_NOT_REACHED();
227     return UString();
228 }
229
230 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
231 {
232     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(msg));
233     generator.emitThrow(exception);
234     return exception;
235 }
236
237 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
238 {
239     UString message = msg;
240     substitute(message, label.ustring());
241     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(message));
242     generator.emitThrow(exception);
243     return exception;
244 }
245     
246 // ------------------------------ StatementNode --------------------------------
247
248 StatementNode::StatementNode()
249     : m_lastLine(-1)
250 {
251     m_line = -1;
252 }
253
254 void StatementNode::setLoc(int firstLine, int lastLine)
255 {
256     m_line = firstLine;
257     m_lastLine = lastLine;
258 }
259
260 // ------------------------------ SourceElements --------------------------------
261
262 void SourceElements::append(PassRefPtr<StatementNode> statement)
263 {
264     if (statement->isEmptyStatement())
265         return;
266
267     m_statements.append(statement);
268 }
269
270 // ------------------------------ BreakpointCheckStatement --------------------------------
271
272 BreakpointCheckStatement::BreakpointCheckStatement(PassRefPtr<StatementNode> statement)
273     : m_statement(statement)
274 {
275     ASSERT(m_statement);
276 }
277
278 void BreakpointCheckStatement::streamTo(SourceStream& stream) const
279 {
280     m_statement->streamTo(stream);
281 }
282
283 // ------------------------------ NullNode -------------------------------------
284
285 RegisterID* NullNode::emitCode(CodeGenerator& generator, RegisterID* dst)
286 {
287     return generator.emitLoad(generator.finalDestination(dst), jsNull());
288 }
289
290 // ------------------------------ FalseNode ----------------------------------
291
292 RegisterID* FalseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
293 {
294     return generator.emitLoad(generator.finalDestination(dst), false);
295 }
296
297 // ------------------------------ TrueNode ----------------------------------
298
299 RegisterID* TrueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
300 {
301     return generator.emitLoad(generator.finalDestination(dst), true);
302 }
303
304 // ------------------------------ NumberNode -----------------------------------
305
306 RegisterID* NumberNode::emitCode(CodeGenerator& generator, RegisterID* dst)
307 {
308     return generator.emitLoad(generator.finalDestination(dst), m_double);
309 }
310
311 // ------------------------------ StringNode -----------------------------------
312
313 RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
314 {
315     // FIXME: should we try to atomize constant strings?
316     return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(m_value));
317 }
318
319 // ------------------------------ RegExpNode -----------------------------------
320
321 RegisterID* RegExpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
322 {
323     if (!m_regExp->isValid())
324         return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", m_regExp->errorMessage());
325     return generator.emitNewRegExp(generator.finalDestination(dst), m_regExp.get());
326 }
327
328 // ------------------------------ ThisNode -------------------------------------
329
330 RegisterID* ThisNode::emitCode(CodeGenerator& generator, RegisterID* dst)
331 {
332     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
333 }
334
335 // ------------------------------ ResolveNode ----------------------------------
336
337 RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
338 {
339     if (RegisterID* local = generator.registerForLocal(m_ident))
340         return generator.moveToDestinationIfNeeded(dst, local);
341
342     return generator.emitResolve(generator.finalDestination(dst), m_ident);
343 }
344
345 // ------------------------------ ArrayNode ------------------------------------
346
347
348 RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
349 {
350     RefPtr<RegisterID> newArray = generator.emitNewArray(generator.tempDestination(dst));
351     unsigned length = 0;
352
353     RegisterID* value;
354     for (ElementNode* n = m_element.get(); n; n = n->m_next.get()) {
355         value = generator.emitNode(n->m_node.get());
356         length += n->m_elision;
357         generator.emitPutByIndex(newArray.get(), length++, value);
358     }
359
360     value = generator.emitLoad(generator.newTemporary(), jsNumber(m_elision + length));
361     generator.emitPutById(newArray.get(), generator.propertyNames().length, value);
362
363     return generator.moveToDestinationIfNeeded(dst, newArray.get());
364 }
365
366 // ------------------------------ ObjectLiteralNode ----------------------------
367
368 RegisterID* ObjectLiteralNode::emitCode(CodeGenerator& generator, RegisterID* dst)
369 {
370     if (m_list)
371         return generator.emitNode(dst, m_list.get());
372     else
373         return generator.emitNewObject(generator.finalDestination(dst));
374 }
375
376 // ------------------------------ PropertyListNode -----------------------------
377
378 RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
379 {
380     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
381     
382     generator.emitNewObject(newObj.get());
383     
384     for (PropertyListNode* p = this; p; p = p->m_next.get()) {
385         RegisterID* value = generator.emitNode(p->m_node->m_assign.get());
386         
387         switch (p->m_node->m_type) {
388             case PropertyNode::Constant: {
389                 generator.emitPutById(newObj.get(), p->m_node->name(), value);
390                 break;
391             }
392             case PropertyNode::Getter: {
393                 generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
394                 break;
395             }
396             case PropertyNode::Setter: {
397                 generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
398                 break;
399             }
400             default:
401                 ASSERT_NOT_REACHED();
402         }
403     }
404     
405     return generator.moveToDestinationIfNeeded(dst, newObj.get());
406 }
407
408 // ------------------------------ BracketAccessorNode --------------------------------
409
410 RegisterID* BracketAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
411 {
412     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
413     RegisterID* property = generator.emitNode(m_subscript.get());
414
415     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
416 }
417
418 // ------------------------------ DotAccessorNode --------------------------------
419
420 RegisterID* DotAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
421 {
422     RegisterID* base = generator.emitNode(m_base.get());
423     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
424 }
425
426 // ------------------------------ ArgumentListNode -----------------------------
427
428 RegisterID* ArgumentListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
429 {
430     ASSERT(m_expr);
431     return generator.emitNode(dst, m_expr.get());
432 }
433
434 // ------------------------------ NewExprNode ----------------------------------
435
436 RegisterID* NewExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
437 {
438     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
439     return generator.emitConstruct(generator.finalDestination(dst), r0.get(), m_args.get());
440 }
441
442 RegisterID* EvalFunctionCallNode::emitCode(CodeGenerator& generator, RegisterID* dst)
443 {
444     RefPtr<RegisterID> base = generator.tempDestination(dst);
445     RegisterID* func = generator.newTemporary();
446     generator.emitResolveWithBase(base.get(), func, CommonIdentifiers::shared()->eval);
447     return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
448 }
449
450 RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
451 {
452     RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
453     return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get());
454 }
455
456 RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
457 {
458     if (RegisterID* local = generator.registerForLocal(m_ident))
459         return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get());
460
461     int index = 0;
462     size_t depth = 0;
463     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
464         RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
465         return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get());
466     }
467
468     RefPtr<RegisterID> base = generator.tempDestination(dst);
469     RegisterID* func = generator.newTemporary();
470     generator.emitResolveFunction(base.get(), func, m_ident);
471     return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
472 }
473
474 RegisterID* FunctionCallBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
475 {
476     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
477     RegisterID* property = generator.emitNode(m_subscript.get());
478     RegisterID* function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
479     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
480 }
481
482 RegisterID* FunctionCallDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
483 {
484     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
485     RegisterID* function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
486     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
487 }
488
489 // ------------------------------ PostfixResolveNode ----------------------------------
490
491 RegisterID* PostIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
492 {
493     // FIXME: I think we can detect the absense of dependent expressions here, 
494     // and emit a PreInc instead of a PostInc. A post-pass to eliminate dead
495     // code would work, too.
496     if (RegisterID* local = generator.registerForLocal(m_ident)) {
497         if (generator.isLocalConstant(m_ident))
498             return generator.emitToJSNumber(generator.finalDestination(dst), local);
499         
500         return generator.emitPostInc(generator.finalDestination(dst), local);
501     }
502
503     int index = 0;
504     size_t depth = 0;
505     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
506         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
507         RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
508         generator.emitPutScopedVar(depth, index, value.get());
509         return oldValue;
510     }
511
512     RefPtr<RegisterID> value = generator.newTemporary();
513     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
514     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
515     generator.emitPutById(base.get(), m_ident, value.get());
516     return oldValue;
517 }
518
519 RegisterID* PostDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
520 {
521     // FIXME: I think we can detect the absense of dependent expressions here, 
522     // and emit a PreDec instead of a PostDec. A post-pass to eliminate dead
523     // code would work, too.
524     if (RegisterID* local = generator.registerForLocal(m_ident)) {
525         if (generator.isLocalConstant(m_ident))
526             return generator.emitToJSNumber(generator.finalDestination(dst), local);
527         
528         return generator.emitPostDec(generator.finalDestination(dst), local);
529     }
530
531     int index = 0;
532     size_t depth = 0;
533     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
534         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
535         RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
536         generator.emitPutScopedVar(depth, index, value.get());
537         return oldValue;
538     }
539
540     RefPtr<RegisterID> value = generator.newTemporary();
541     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
542     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
543     generator.emitPutById(base.get(), m_ident, value.get());
544     return oldValue;
545 }
546
547 // ------------------------------ PostfixBracketNode ----------------------------------
548
549 RegisterID* PostIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
550 {
551     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
552     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
553     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
554     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
555     generator.emitPutByVal(base.get(), property.get(), value.get());
556     return oldValue;
557 }
558
559 RegisterID* PostDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
560 {
561     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
562     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
563     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
564     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
565     generator.emitPutByVal(base.get(), property.get(), value.get());
566     return oldValue;
567 }
568
569 // ------------------------------ PostfixDotNode ----------------------------------
570
571 RegisterID* PostIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
572 {
573     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
574     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
575     RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
576     generator.emitPutById(base.get(), m_ident, value.get());
577     return oldValue;
578 }
579
580 RegisterID* PostDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
581 {
582     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
583     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
584     RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
585     generator.emitPutById(base.get(), m_ident, value.get());
586     return oldValue;
587 }
588
589 // ------------------------------ PostfixErrorNode -----------------------------------
590
591 RegisterID* PostfixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
592 {
593     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
594 }
595
596 // ------------------------------ DeleteResolveNode -----------------------------------
597
598 RegisterID* DeleteResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
599 {
600     if (generator.registerForLocal(m_ident))
601         return generator.emitLoad(generator.finalDestination(dst), false);
602
603     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
604     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
605 }
606
607 // ------------------------------ DeleteBracketNode -----------------------------------
608
609 RegisterID* DeleteBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
610 {
611     RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
612     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript.get());
613     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
614 }
615
616 // ------------------------------ DeleteDotNode -----------------------------------
617
618 RegisterID* DeleteDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
619 {
620     RegisterID* r0 = generator.emitNode(m_base.get());
621     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
622 }
623
624 // ------------------------------ DeleteValueNode -----------------------------------
625
626 RegisterID* DeleteValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
627 {
628     generator.emitNode(m_expr.get());
629
630     // delete on a non-location expression ignores the value and returns true
631     return generator.emitLoad(generator.finalDestination(dst), true);
632 }
633
634 // ------------------------------ VoidNode -------------------------------------
635
636 RegisterID* VoidNode::emitCode(CodeGenerator& generator, RegisterID* dst)
637 {
638     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
639     return generator.emitLoad(generator.finalDestination(dst, r0.get()), jsUndefined());
640 }
641
642 // ------------------------------ TypeOfValueNode -----------------------------------
643
644 RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
645 {
646     if (RegisterID* local = generator.registerForLocal(m_ident))
647         return generator.emitTypeOf(generator.finalDestination(dst), local);
648
649     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
650     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
651     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
652 }
653
654 // ------------------------------ TypeOfValueNode -----------------------------------
655
656 RegisterID* TypeOfValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
657 {
658     RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
659     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
660 }
661
662 // ------------------------------ PrefixResolveNode ----------------------------------
663
664 RegisterID* PreIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
665 {
666     if (RegisterID* local = generator.registerForLocal(m_ident)) {
667         if (generator.isLocalConstant(m_ident)) {
668             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), 1.0);
669             return generator.emitAdd(r0.get(), local, r0.get());
670         }
671         
672         generator.emitPreInc(local);
673         return generator.moveToDestinationIfNeeded(dst, local);
674     }
675
676     int index = 0;
677     size_t depth = 0;
678     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
679         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
680         generator.emitPreInc(propDst.get());
681         generator.emitPutScopedVar(depth, index, propDst.get());
682         return generator.moveToDestinationIfNeeded(dst, propDst.get());;
683     }
684
685     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
686     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
687     generator.emitPreInc(propDst.get());
688     generator.emitPutById(base.get(), m_ident, propDst.get());
689     return generator.moveToDestinationIfNeeded(dst, propDst.get());
690 }
691
692 RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
693 {
694     if (RegisterID* local = generator.registerForLocal(m_ident)) {
695         if (generator.isLocalConstant(m_ident)) {
696             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), -1.0);
697             return generator.emitAdd(r0.get(), local, r0.get());
698         }
699         
700         generator.emitPreDec(local);
701         return generator.moveToDestinationIfNeeded(dst, local);
702     }
703
704     int index = 0;
705     size_t depth = 0;
706     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
707         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
708         generator.emitPreDec(propDst.get());
709         generator.emitPutScopedVar(depth, index, propDst.get());
710         return generator.moveToDestinationIfNeeded(dst, propDst.get());;
711     }
712
713     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
714     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
715     generator.emitPreDec(propDst.get());
716     generator.emitPutById(base.get(), m_ident, propDst.get());
717     return generator.moveToDestinationIfNeeded(dst, propDst.get());
718 }
719
720 // ------------------------------ PrefixBracketNode ----------------------------------
721
722 RegisterID* PreIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
723 {
724     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
725     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
726     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
727     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
728     generator.emitPreInc(value);
729     generator.emitPutByVal(base.get(), property.get(), value);
730     return generator.moveToDestinationIfNeeded(dst, propDst.get());
731 }
732
733 RegisterID* PreDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
734 {
735     
736     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
737     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
738     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
739     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
740     generator.emitPreDec(value);
741     generator.emitPutByVal(base.get(), property.get(), value);
742     return generator.moveToDestinationIfNeeded(dst, propDst.get());
743 }
744
745 // ------------------------------ PrefixDotNode ----------------------------------
746
747 RegisterID* PreIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
748 {
749     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
750     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
751     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
752     generator.emitPreInc(value);
753     generator.emitPutById(base.get(), m_ident, value);
754     return generator.moveToDestinationIfNeeded(dst, propDst.get());
755 }
756
757 RegisterID* PreDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
758 {
759     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
760     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
761     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
762     generator.emitPreDec(value);
763     generator.emitPutById(base.get(), m_ident, value);
764     return generator.moveToDestinationIfNeeded(dst, propDst.get());
765 }
766
767 // ------------------------------ PrefixErrorNode -----------------------------------
768
769 RegisterID* PrefixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
770 {
771     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
772 }
773
774 // ------------------------------ UnaryPlusNode --------------------------------
775
776 RegisterID* UnaryPlusNode::emitCode(CodeGenerator& generator, RegisterID* dst)
777 {
778     RegisterID* src = generator.emitNode(m_expr.get());
779     return generator.emitToJSNumber(generator.finalDestination(dst), src);
780 }
781
782 // ------------------------------ NegateNode -----------------------------------
783
784 RegisterID* NegateNode::emitCode(CodeGenerator& generator, RegisterID* dst)
785 {
786     RegisterID* src = generator.emitNode(m_expr.get());
787     return generator.emitNegate(generator.finalDestination(dst), src);
788 }
789
790 // ------------------------------ BitwiseNotNode -------------------------------
791
792 RegisterID* BitwiseNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
793 {
794     RegisterID* src = generator.emitNode(m_expr.get());
795     return generator.emitBitNot(generator.finalDestination(dst), src);
796 }
797
798 // ------------------------------ LogicalNotNode -------------------------------
799
800 RegisterID* LogicalNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
801 {
802     RegisterID* src = generator.emitNode(m_expr.get());
803     return generator.emitNot(generator.finalDestination(dst), src);
804 }
805
806 // ------------------------------ Multiplicative Nodes -----------------------------------
807
808 RegisterID* MultNode::emitCode(CodeGenerator& generator, RegisterID* dst)
809 {
810     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
811     RegisterID* src2 = generator.emitNode(m_term2.get());
812     return generator.emitMul(generator.finalDestination(dst, src1.get()), src1.get(), src2);
813 }
814
815 RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst)
816 {
817     RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
818     RegisterID* divisor = generator.emitNode(m_term2.get());
819     return generator.emitDiv(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
820 }
821
822 RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
823 {
824     RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
825     RegisterID* divisor = generator.emitNode(m_term2.get());
826     return generator.emitMod(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
827 }
828
829 // ------------------------------ Additive Nodes --------------------------------------
830
831 RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
832 {
833     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
834     RegisterID* src2 = generator.emitNode(m_term2.get());
835     return generator.emitAdd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
836 }
837
838 RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
839 {
840     RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
841     RegisterID* src2 = generator.emitNode(m_term2.get());
842     return generator.emitSub(generator.finalDestination(dst, src1.get()), src1.get(), src2);
843 }
844
845 // ------------------------------ Shift Nodes ------------------------------------
846
847 RegisterID* LeftShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
848 {
849     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
850     RegisterID* shift = generator.emitNode(m_term2.get());
851     return generator.emitLeftShift(generator.finalDestination(dst, val.get()), val.get(), shift);
852 }
853
854 RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
855 {
856     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
857     RegisterID* shift = generator.emitNode(m_term2.get());
858     return generator.emitRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
859 }
860
861 RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
862 {
863     RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
864     RegisterID* shift = generator.emitNode(m_term2.get());
865     return generator.emitUnsignedRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
866 }
867
868 // ------------------------------ Relational Nodes -------------------------------
869
870 RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst)
871 {
872     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
873     RegisterID* src2 = generator.emitNode(m_expr2.get());
874     return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
875 }
876
877 RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst)
878 {
879     RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
880     RegisterID* src2 = generator.emitNode(m_expr1.get());
881     return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
882 }
883
884 RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
885 {
886     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
887     RegisterID* src2 = generator.emitNode(m_expr2.get());
888     return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
889 }
890
891 RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
892 {
893     RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
894     RegisterID* src2 = generator.emitNode(m_expr1.get());
895     return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
896 }
897
898 RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
899 {
900     RefPtr<RegisterID> value = generator.emitNode(m_expr1.get());
901     RegisterID* base = generator.emitNode(m_expr2.get());
902     return generator.emitInstanceOf(generator.finalDestination(dst, value.get()), value.get(), base);
903 }
904
905 RegisterID* InNode::emitCode(CodeGenerator& generator, RegisterID* dst)
906 {
907     RefPtr<RegisterID> property = generator.emitNode(m_expr1.get());
908     RegisterID* base = generator.emitNode(m_expr2.get());
909     return generator.emitIn(generator.finalDestination(dst, property.get()), property.get(), base);
910 }
911
912 // ------------------------------ Equality Nodes ------------------------------------
913
914 RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
915 {
916     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
917     RegisterID* src2 = generator.emitNode(m_expr2.get());
918     return generator.emitEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
919 }
920
921 RegisterID* NotEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
922 {
923     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
924     RegisterID* src2 = generator.emitNode(m_expr2.get());
925     return generator.emitNotEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
926 }
927
928 RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
929 {
930     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
931     RegisterID* src2 = generator.emitNode(m_expr2.get());
932     return generator.emitStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
933 }
934
935 RegisterID* NotStrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
936 {
937     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
938     RegisterID* src2 = generator.emitNode(m_expr2.get());
939     return generator.emitNotStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
940 }
941
942 // ------------------------------ Bit Operation Nodes ----------------------------------
943
944 RegisterID* BitAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
945 {
946     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
947     RegisterID* src2 = generator.emitNode(m_expr2.get());
948     return generator.emitBitAnd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
949 }
950
951 RegisterID* BitXOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
952 {
953     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
954     RegisterID* src2 = generator.emitNode(m_expr2.get());
955     return generator.emitBitXOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
956 }
957
958 RegisterID* BitOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
959 {
960     RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
961     RegisterID* src2 = generator.emitNode(m_expr2.get());
962     return generator.emitBitOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
963 }
964
965 // ------------------------------ Binary Logical Nodes ----------------------------
966
967 RegisterID* LogicalAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
968 {
969     RefPtr<RegisterID> temp = generator.tempDestination(dst);
970     RefPtr<LabelID> target = generator.newLabel();
971     
972     generator.emitNode(temp.get(), m_expr1.get());
973     generator.emitJumpIfFalse(temp.get(), target.get());
974     generator.emitNode(temp.get(), m_expr2.get());
975     generator.emitLabel(target.get());
976
977     return generator.moveToDestinationIfNeeded(dst, temp.get());
978 }
979
980 RegisterID* LogicalOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
981 {
982     RefPtr<RegisterID> temp = generator.tempDestination(dst);
983     RefPtr<LabelID> target = generator.newLabel();
984     
985     generator.emitNode(temp.get(), m_expr1.get());
986     generator.emitJumpIfTrue(temp.get(), target.get());
987     generator.emitNode(temp.get(), m_expr2.get());
988     generator.emitLabel(target.get());
989
990     return generator.moveToDestinationIfNeeded(dst, temp.get());
991 }
992
993 // ------------------------------ ConditionalNode ------------------------------
994
995 RegisterID* ConditionalNode::emitCode(CodeGenerator& generator, RegisterID* dst)
996 {
997     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
998     RefPtr<LabelID> beforeElse = generator.newLabel();
999     RefPtr<LabelID> afterElse = generator.newLabel();
1000
1001     RegisterID* cond = generator.emitNode(m_logical.get());
1002     generator.emitJumpIfFalse(cond, beforeElse.get());
1003
1004     generator.emitNode(newDst.get(), m_expr1.get());
1005     generator.emitJump(afterElse.get());
1006
1007     generator.emitLabel(beforeElse.get());
1008     generator.emitNode(newDst.get(), m_expr2.get());
1009
1010     generator.emitLabel(afterElse.get());
1011
1012     return newDst.get();
1013 }
1014
1015 // ------------------------------ ReadModifyResolveNode -----------------------------------
1016
1017 // FIXME: should this be moved to be a method on CodeGenerator?
1018 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(CodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper)
1019 {
1020     switch (oper) {
1021         case OpMultEq:
1022             return generator.emitMul(dst, src1, src2);
1023         case OpDivEq:
1024             return generator.emitDiv(dst, src1, src2);
1025         case OpPlusEq:
1026             return generator.emitAdd(dst, src1, src2);
1027         case OpMinusEq:
1028             return generator.emitSub(dst, src1, src2);
1029         case OpLShift:
1030             return generator.emitLeftShift(dst, src1, src2);
1031         case OpRShift:
1032             return generator.emitRightShift(dst, src1, src2);
1033         case OpURShift:
1034             return generator.emitUnsignedRightShift(dst, src1, src2);
1035         case OpAndEq:
1036             return generator.emitBitAnd(dst, src1, src2);
1037         case OpXOrEq:
1038             return generator.emitBitXOr(dst, src1, src2);
1039         case OpOrEq:
1040             return generator.emitBitOr(dst, src1, src2);
1041         case OpModEq:
1042             return generator.emitMod(dst, src1, src2);
1043         default:
1044             ASSERT_NOT_REACHED();
1045     }
1046
1047     return dst;
1048 }
1049
1050 RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1051 {
1052     if (RegisterID* local = generator.registerForLocal(m_ident)) {
1053         if (generator.isLocalConstant(m_ident)) {
1054             RegisterID* src2 = generator.emitNode(m_right.get());
1055             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator);
1056         }
1057         
1058         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments) && !m_right.get()->isNumber()) {
1059             RefPtr<RegisterID> result = generator.newTemporary();
1060             generator.emitMove(result.get(), local);
1061             RegisterID* src2 = generator.emitNode(m_right.get());
1062             emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator);
1063             generator.emitMove(local, result.get());
1064             return generator.moveToDestinationIfNeeded(dst, result.get());
1065         }
1066         
1067         RegisterID* src2 = generator.emitNode(m_right.get());
1068         RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator);
1069         return generator.moveToDestinationIfNeeded(dst, result);
1070     }
1071
1072     int index = 0;
1073     size_t depth = 0;
1074     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
1075         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
1076         RegisterID* src2 = generator.emitNode(m_right.get());
1077         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
1078         generator.emitPutScopedVar(depth, index, result);
1079         return result;
1080     }
1081
1082     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1083     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1084     RegisterID* src2 = generator.emitNode(m_right.get());
1085     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
1086     return generator.emitPutById(base.get(), m_ident, result);
1087 }
1088
1089 // ------------------------------ AssignResolveNode -----------------------------------
1090
1091 RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1092 {
1093     if (RegisterID* local = generator.registerForLocal(m_ident)) {
1094         if (generator.isLocalConstant(m_ident))
1095             return generator.emitNode(dst, m_right.get());
1096         
1097         RegisterID* result = generator.emitNode(local, m_right.get());
1098         return generator.moveToDestinationIfNeeded(dst, result);
1099     }
1100
1101     int index = 0;
1102     size_t depth = 0;
1103     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
1104         RegisterID* value = generator.emitNode(dst, m_right.get());
1105         generator.emitPutScopedVar(depth, index, value);
1106         return value;
1107     }
1108
1109     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1110     RegisterID* value = generator.emitNode(dst, m_right.get());
1111     return generator.emitPutById(base.get(), m_ident, value);
1112 }
1113
1114 // ------------------------------ AssignDotNode -----------------------------------
1115
1116 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1117 {
1118     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
1119     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1120     RegisterID* result = generator.emitNode(value.get(), m_right.get());
1121     generator.emitPutById(base.get(), m_ident, result);
1122     return generator.moveToDestinationIfNeeded(dst, result);
1123 }
1124
1125 // ------------------------------ ReadModifyDotNode -----------------------------------
1126
1127 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1128 {
1129     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
1130     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1131     RegisterID* change = generator.emitNode(m_right.get());
1132     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
1133     return generator.emitPutById(base.get(), m_ident, updatedValue);
1134 }
1135
1136 // ------------------------------ AssignErrorNode -----------------------------------
1137
1138 RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
1139 {
1140     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1141 }
1142
1143 // ------------------------------ AssignBracketNode -----------------------------------
1144
1145 RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1146 {
1147     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
1148     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
1149     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1150     RegisterID* result = generator.emitNode(value.get(), m_right.get());
1151     generator.emitPutByVal(base.get(), property.get(), result);
1152     return generator.moveToDestinationIfNeeded(dst, result);
1153 }
1154
1155 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1156 {
1157     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
1158     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
1159
1160     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1161     RegisterID* change = generator.emitNode(m_right.get());
1162     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
1163
1164     generator.emitPutByVal(base.get(), property.get(), updatedValue);
1165
1166     return updatedValue;
1167 }
1168
1169 // ------------------------------ CommaNode ------------------------------------
1170
1171 RegisterID* CommaNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1172 {
1173     generator.emitNode(m_expr1.get());
1174     return generator.emitNode(dst, m_expr2.get());
1175 }
1176
1177 // ------------------------------ ConstDeclNode ----------------------------------
1178
1179 ConstDeclNode::ConstDeclNode(const Identifier& ident, ExpressionNode* init)
1180     : m_ident(ident)
1181     , m_init(init)
1182 {
1183 }
1184
1185 RegisterID* ConstDeclNode::emitCodeSingle(CodeGenerator& generator)
1186 {
1187     if (RegisterID* local = generator.registerForLocalConstInit(m_ident)) {
1188         if (!m_init)
1189             return local;
1190
1191         return generator.emitNode(local, m_init.get());
1192     }
1193     
1194     // FIXME: While this code should only be hit in eval code, it will potentially
1195     // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1196     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1197     RegisterID* value = generator.emitNode(m_init.get());
1198     return generator.emitPutById(base.get(), m_ident, value);
1199 }
1200
1201 RegisterID* ConstDeclNode::emitCode(CodeGenerator& generator, RegisterID*)
1202 {
1203     RegisterID* result = 0;
1204     for (ConstDeclNode* n = this; n; n = n->m_next.get())
1205         result = n->emitCodeSingle(generator);
1206
1207     return result;
1208 }
1209
1210 // ------------------------------ ConstStatementNode -----------------------------
1211
1212 RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
1213 {
1214     return generator.emitNode(m_next.get());
1215 }
1216
1217 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1218
1219 static inline RegisterID* statementListEmitCode(StatementVector& statements, CodeGenerator& generator, RegisterID* dst = 0)
1220 {
1221     RefPtr<RegisterID> r0 = dst;
1222
1223     StatementVector::iterator end = statements.end();
1224     for (StatementVector::iterator it = statements.begin(); it != end; ++it) {
1225         StatementNode* n = it->get();
1226         generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1227         if (RegisterID* r1 = generator.emitNode(dst, n))
1228             r0 = r1;
1229     }
1230     
1231     return r0.get();
1232 }
1233
1234 static inline void statementListPushFIFO(StatementVector& statements, DeclarationStacks::NodeStack& stack)
1235 {
1236     StatementVector::iterator it = statements.end();
1237     StatementVector::iterator begin = statements.begin();
1238     while (it != begin) {
1239         --it;
1240         stack.append((*it).get());
1241     }
1242 }
1243
1244 static inline Node* statementListInitializeVariableAccessStack(StatementVector& statements, DeclarationStacks::NodeStack& stack)
1245 {
1246     if (statements.isEmpty())
1247         return 0;
1248
1249     StatementVector::iterator it = statements.end();
1250     StatementVector::iterator begin = statements.begin();
1251     StatementVector::iterator beginPlusOne = begin + 1;
1252
1253     while (it != beginPlusOne) {
1254         --it;
1255         stack.append((*it).get());
1256     }
1257
1258     return (*begin).get();
1259 }
1260
1261 // ------------------------------ BlockNode ------------------------------------
1262
1263 BlockNode::BlockNode(SourceElements* children)
1264 {
1265     if (children)
1266         children->releaseContentsIntoVector(m_children);
1267 }
1268
1269 RegisterID* BlockNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1270 {
1271     return statementListEmitCode(m_children, generator, dst);
1272 }
1273
1274 // ------------------------------ EmptyStatementNode ---------------------------
1275
1276 RegisterID* EmptyStatementNode::emitCode(CodeGenerator&, RegisterID* dst)
1277 {
1278     return dst;
1279 }
1280
1281 // ------------------------------ DebuggerStatementNode ---------------------------
1282
1283 RegisterID* DebuggerStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1284 {
1285     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1286     return dst;
1287 }
1288
1289 // ------------------------------ ExprStatementNode ----------------------------
1290
1291 RegisterID* ExprStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1292 {
1293     ASSERT(m_expr);
1294     return generator.emitNode(dst, m_expr.get());
1295 }
1296
1297 // ------------------------------ VarStatementNode ----------------------------
1298
1299 RegisterID* VarStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
1300 {
1301     ASSERT(m_expr);
1302     return generator.emitNode(m_expr.get());
1303 }
1304
1305 // ------------------------------ IfNode ---------------------------------------
1306
1307 RegisterID* IfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1308 {
1309     RefPtr<LabelID> afterThen = generator.newLabel();
1310
1311     RegisterID* cond = generator.emitNode(m_condition.get());
1312     generator.emitJumpIfFalse(cond, afterThen.get());
1313
1314     generator.emitNode(dst, m_ifBlock.get());
1315     generator.emitLabel(afterThen.get());
1316
1317     // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
1318     return 0;
1319 }
1320
1321 RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1322 {
1323     RefPtr<LabelID> beforeElse = generator.newLabel();
1324     RefPtr<LabelID> afterElse = generator.newLabel();
1325
1326     RegisterID* cond = generator.emitNode(m_condition.get());
1327     generator.emitJumpIfFalse(cond, beforeElse.get());
1328
1329     generator.emitNode(dst, m_ifBlock.get());
1330     generator.emitJump(afterElse.get());
1331
1332     generator.emitLabel(beforeElse.get());
1333     generator.emitNode(dst, m_elseBlock.get());
1334
1335     generator.emitLabel(afterElse.get());
1336
1337     // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
1338     return 0;
1339 }
1340
1341 // ------------------------------ DoWhileNode ----------------------------------
1342
1343 RegisterID* DoWhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1344 {
1345     RefPtr<LabelID> topOfLoop = generator.newLabel();
1346     generator.emitLabel(topOfLoop.get());
1347
1348     RefPtr<LabelID> continueTarget = generator.newLabel();
1349     RefPtr<LabelID> breakTarget = generator.newLabel();
1350     
1351     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1352     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1353     generator.popJumpContext();
1354     
1355     generator.emitLabel(continueTarget.get());
1356     RegisterID* cond = generator.emitNode(m_expr.get());
1357     generator.emitJumpIfTrue(cond, topOfLoop.get());
1358     generator.emitLabel(breakTarget.get());
1359     return result.get();
1360 }
1361
1362 // ------------------------------ WhileNode ------------------------------------
1363
1364 RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1365 {
1366     RefPtr<LabelID> topOfLoop = generator.newLabel();
1367     RefPtr<LabelID> continueTarget = generator.newLabel();
1368     RefPtr<LabelID> breakTarget = generator.newLabel();
1369
1370     generator.emitJump(continueTarget.get());
1371     generator.emitLabel(topOfLoop.get());
1372     
1373     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1374     generator.emitNode(dst, m_statement.get());
1375     generator.popJumpContext();
1376
1377     generator.emitLabel(continueTarget.get());
1378     RegisterID* cond = generator.emitNode(m_expr.get());
1379     generator.emitJumpIfTrue(cond, topOfLoop.get());
1380
1381     generator.emitLabel(breakTarget.get());
1382     
1383     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1384     return 0;
1385 }
1386
1387 // ------------------------------ ForNode --------------------------------------
1388
1389 RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1390 {
1391     if (m_expr1)
1392         generator.emitNode(m_expr1.get());
1393     
1394     RefPtr<LabelID> topOfLoop = generator.newLabel();
1395     RefPtr<LabelID> beforeCondition = generator.newLabel();
1396     RefPtr<LabelID> continueTarget = generator.newLabel(); 
1397     RefPtr<LabelID> breakTarget = generator.newLabel(); 
1398     generator.emitJump(beforeCondition.get());
1399
1400     generator.emitLabel(topOfLoop.get());
1401     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1402     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1403     generator.popJumpContext();
1404     generator.emitLabel(continueTarget.get());
1405     if (m_expr3)
1406         generator.emitNode(m_expr3.get());
1407
1408     generator.emitLabel(beforeCondition.get());
1409     if (m_expr2) {
1410         RegisterID* cond = generator.emitNode(m_expr2.get());
1411         generator.emitJumpIfTrue(cond, topOfLoop.get());
1412     } else {
1413         generator.emitJump(topOfLoop.get());
1414     }
1415     generator.emitLabel(breakTarget.get());
1416     return result.get();
1417 }
1418
1419 // ------------------------------ ForInNode ------------------------------------
1420
1421 ForInNode::ForInNode(ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1422     : m_init(0L)
1423     , m_lexpr(l)
1424     , m_expr(expr)
1425     , m_statement(statement)
1426     , m_identIsVarDecl(false)
1427 {
1428 }
1429
1430 ForInNode::ForInNode(const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement)
1431     : m_ident(ident)
1432     , m_lexpr(new ResolveNode(ident))
1433     , m_expr(expr)
1434     , m_statement(statement)
1435     , m_identIsVarDecl(true)
1436 {
1437     if (in)
1438         m_init = new AssignResolveNode(ident, in, true);
1439     // for( var foo = bar in baz )
1440 }
1441
1442 RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1443 {
1444     RefPtr<LabelID> loopStart = generator.newLabel();
1445     RefPtr<LabelID> continueTarget = generator.newLabel(); 
1446     RefPtr<LabelID> breakTarget = generator.newLabel(); 
1447
1448     if (m_init)
1449         generator.emitNode(m_init.get());
1450     RegisterID* forInBase = generator.emitNode(m_expr.get());
1451     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1452     generator.emitJump(continueTarget.get());
1453     generator.emitLabel(loopStart.get());
1454     RegisterID* propertyName;
1455     if (m_lexpr->isResolveNode()) {
1456         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1457         propertyName = generator.registerForLocal(ident);
1458         if (!propertyName) {
1459             propertyName = generator.newTemporary();
1460             RefPtr<RegisterID> protect = propertyName;
1461             RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1462             generator.emitPutById(base, ident, propertyName);
1463         }
1464     } else if (m_lexpr->isDotAccessorNode()) {
1465         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1466         const Identifier& ident = assignNode->identifier();
1467         propertyName = generator.newTemporary();
1468         RefPtr<RegisterID> protect = propertyName;
1469         RegisterID* base = generator.emitNode(assignNode->base());
1470         generator.emitPutById(base, ident, propertyName);
1471     } else {
1472         ASSERT(m_lexpr->isBracketAccessorNode());
1473         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1474         propertyName = generator.newTemporary();
1475         RefPtr<RegisterID> protect = propertyName;
1476         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1477         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1478         generator.emitPutByVal(base.get(), subscript, propertyName);
1479     }   
1480     
1481     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1482     generator.emitNode(dst, m_statement.get());
1483     generator.popJumpContext();
1484
1485     generator.emitLabel(continueTarget.get());
1486     generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1487     generator.emitLabel(breakTarget.get());
1488     return dst;
1489 }
1490
1491 // ------------------------------ ContinueNode ---------------------------------
1492
1493 // ECMA 12.7
1494 RegisterID* ContinueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1495 {
1496     if (!generator.inContinueContext())
1497         return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
1498
1499     JumpContext* targetContext = generator.jumpContextForContinue(m_ident);
1500
1501     if (!targetContext) {
1502         if (m_ident.isEmpty())
1503             return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
1504         else
1505             return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
1506     }
1507
1508     if (!targetContext->continueTarget)
1509         return emitThrowError(generator, SyntaxError, "Invalid continue statement.");        
1510
1511     generator.emitJumpScopes(targetContext->continueTarget, targetContext->scopeDepth);
1512     
1513     return dst;
1514 }
1515
1516 // ------------------------------ BreakNode ------------------------------------
1517
1518 // ECMA 12.8
1519 RegisterID* BreakNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1520 {
1521     if (!generator.inJumpContext())
1522         return emitThrowError(generator, SyntaxError, "Invalid break statement.");
1523     
1524     JumpContext* targetContext = generator.jumpContextForBreak(m_ident);
1525     
1526     if (!targetContext) {
1527         if (m_ident.isEmpty())
1528             return emitThrowError(generator, SyntaxError, "Invalid break statement.");
1529         else
1530             return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
1531     }
1532
1533     ASSERT(targetContext->breakTarget);
1534
1535     generator.emitJumpScopes(targetContext->breakTarget, targetContext->scopeDepth);
1536
1537     return dst;
1538 }
1539
1540 // ------------------------------ ReturnNode -----------------------------------
1541
1542 RegisterID* ReturnNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1543 {
1544     if (generator.codeType() != FunctionCode)
1545         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
1546         
1547     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(generator.finalDestination(dst), jsUndefined());
1548     if (generator.scopeDepth()) {
1549         RefPtr<LabelID> l0 = generator.newLabel();
1550         generator.emitJumpScopes(l0.get(), 0);
1551         generator.emitLabel(l0.get());
1552     }
1553     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1554     return generator.emitReturn(r0);
1555 }
1556
1557 // ------------------------------ WithNode -------------------------------------
1558
1559 RegisterID* WithNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1560 {
1561     RefPtr<RegisterID> scope = generator.emitNode(m_expr.get()); // scope must be protected until popped
1562     generator.emitPushScope(scope.get());
1563     RegisterID* result = generator.emitNode(dst, m_statement.get());
1564     generator.emitPopScope();
1565     return result;
1566 }
1567
1568 // ------------------------------ CaseBlockNode --------------------------------
1569
1570 RegisterID* CaseBlockNode::emitCodeForBlock(CodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
1571 {
1572     Vector<RefPtr<LabelID>, 8> labelVector;
1573
1574     // Setup jumps
1575     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
1576         RegisterID* clauseVal = generator.emitNode(list->getClause()->expr());
1577         generator.emitStrictEqual(clauseVal, clauseVal, switchExpression);
1578         labelVector.append(generator.newLabel());
1579         generator.emitJumpIfTrue(clauseVal, labelVector[labelVector.size() - 1].get());
1580     }
1581
1582     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
1583         RegisterID* clauseVal = generator.emitNode(list->getClause()->expr());
1584         generator.emitStrictEqual(clauseVal, clauseVal, switchExpression);
1585         labelVector.append(generator.newLabel());
1586         generator.emitJumpIfTrue(clauseVal, labelVector[labelVector.size() - 1].get());
1587     }
1588
1589     RefPtr<LabelID> defaultLabel;
1590     defaultLabel = generator.newLabel();
1591     generator.emitJump(defaultLabel.get());
1592
1593     RegisterID* result = 0;
1594
1595     size_t i = 0;
1596     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
1597         generator.emitLabel(labelVector[i++].get());
1598         result = statementListEmitCode(list->getClause()->children(), generator, dst);
1599     }
1600
1601     if (m_defaultClause) {
1602         generator.emitLabel(defaultLabel.get());
1603         result = statementListEmitCode(m_defaultClause->children(), generator, dst);
1604     }
1605
1606     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
1607         generator.emitLabel(labelVector[i++].get());
1608         result = statementListEmitCode(list->getClause()->children(), generator, dst);
1609     }
1610     if (!m_defaultClause)
1611         generator.emitLabel(defaultLabel.get());
1612
1613     ASSERT(i == labelVector.size());
1614
1615     return result;
1616 }
1617
1618 // ------------------------------ SwitchNode -----------------------------------
1619
1620 RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1621 {
1622     RefPtr<LabelID> breakTarget = generator.newLabel();
1623
1624     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
1625     generator.pushJumpContext(&m_labelStack, 0, breakTarget.get(), true);
1626     RegisterID* r1 = m_block->emitCodeForBlock(generator, r0.get(), dst);
1627     generator.popJumpContext();
1628
1629     generator.emitLabel(breakTarget.get());
1630
1631     return r1;
1632 }
1633
1634 // ------------------------------ LabelNode ------------------------------------
1635
1636 RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1637 {
1638     if (generator.jumpContextForBreak(m_label))
1639         return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label);
1640     
1641     RefPtr<LabelID> l0 = generator.newLabel();
1642     m_labelStack.push(m_label);
1643     generator.pushJumpContext(&m_labelStack, 0, l0.get(), false);
1644     
1645     RegisterID* r0 = generator.emitNode(dst, m_statement.get());
1646     
1647     generator.popJumpContext();
1648     m_labelStack.pop();
1649     
1650     generator.emitLabel(l0.get());
1651     return r0;
1652 }
1653
1654 // ------------------------------ ThrowNode ------------------------------------
1655
1656 RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1657 {
1658     generator.emitThrow(generator.emitNode(dst, m_expr.get()));
1659     return dst;
1660 }
1661
1662 // ------------------------------ TryNode --------------------------------------
1663
1664 RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1665 {
1666     RefPtr<LabelID> tryStartLabel = generator.newLabel();
1667     RefPtr<LabelID> tryEndLabel = generator.newLabel();
1668     RefPtr<LabelID> finallyStart;
1669     RefPtr<RegisterID> finallyReturnAddr;
1670     if (m_finallyBlock) {
1671         finallyStart = generator.newLabel();
1672         finallyReturnAddr = generator.newTemporary();
1673         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
1674     }
1675     generator.emitLabel(tryStartLabel.get());
1676     generator.emitNode(dst, m_tryBlock.get());
1677     generator.emitLabel(tryEndLabel.get());
1678
1679     if (m_catchBlock) {
1680         RefPtr<LabelID> handlerEndLabel = generator.newLabel();
1681         generator.emitJump(handlerEndLabel.get());
1682         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
1683         RefPtr<RegisterID> newScope = generator.emitNewObject(generator.newTemporary()); // scope must be protected until popped
1684         generator.emitPutById(newScope.get(), m_exceptionIdent, exceptionRegister.get());
1685         exceptionRegister = 0; // Release register used for temporaries
1686         generator.emitPushScope(newScope.get());
1687         generator.emitNode(dst, m_catchBlock.get());
1688         generator.emitPopScope();
1689         generator.emitLabel(handlerEndLabel.get());
1690     }
1691
1692     if (m_finallyBlock) {
1693         generator.popFinallyContext();
1694         // there may be important registers live at the time we jump
1695         // to a finally block (such as for a return or throw) so we
1696         // ref the highest register ever used as a conservative
1697         // approach to not clobbering anything important
1698         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
1699         RefPtr<LabelID> finallyEndLabel = generator.newLabel();
1700         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1701         generator.emitJump(finallyEndLabel.get());
1702
1703         // Finally block for exception path
1704         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
1705         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1706         generator.emitThrow(tempExceptionRegister.get());
1707
1708         // emit the finally block itself
1709         generator.emitLabel(finallyStart.get());
1710         generator.emitNode(dst, m_finallyBlock.get());
1711         generator.emitSubroutineReturn(finallyReturnAddr.get());
1712
1713         generator.emitLabel(finallyEndLabel.get());
1714     }
1715
1716     return dst;
1717 }
1718
1719
1720 // ------------------------------ FunctionBodyNode -----------------------------
1721
1722 ScopeNode::ScopeNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1723     : BlockNode(children)
1724     , m_sourceURL(parser().sourceURL())
1725     , m_sourceId(parser().sourceId())
1726     , m_usesEval(usesEval)
1727     , m_needsClosure(needsClosure)
1728 {
1729     if (varStack)
1730         m_varStack = *varStack;
1731     if (funcStack)
1732         m_functionStack = *funcStack;
1733 }
1734
1735 // ------------------------------ ProgramNode -----------------------------
1736
1737 ProgramNode::ProgramNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1738     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
1739 {
1740 }
1741
1742 ProgramNode::~ProgramNode()
1743 {
1744 }
1745
1746 ProgramNode* ProgramNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1747 {
1748     return new ProgramNode(children, varStack, funcStack, usesEval, needsClosure);
1749 }
1750
1751 // ------------------------------ EvalNode -----------------------------
1752
1753 EvalNode::EvalNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1754     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
1755 {
1756 }
1757
1758 EvalNode::~EvalNode()
1759 {
1760 }
1761
1762 RegisterID* EvalNode::emitCode(CodeGenerator& generator, RegisterID*)
1763 {
1764     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1765
1766     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1767     generator.emitLoad(dstRegister.get(), jsUndefined());
1768     statementListEmitCode(m_children, generator, dstRegister.get());
1769
1770     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1771     generator.emitEnd(dstRegister.get());
1772     return 0;
1773 }
1774
1775 void EvalNode::generateCode(ScopeChainNode* sc)
1776 {
1777     ScopeChain scopeChain(sc);
1778     JSGlobalObject* globalObject = scopeChain.globalObject();
1779
1780     SymbolTable symbolTable;
1781
1782     m_code.set(new EvalCodeBlock(this, globalObject));
1783
1784     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get());
1785     generator.generate();
1786 }
1787
1788 EvalNode* EvalNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1789 {
1790     return new EvalNode(children, varStack, funcStack, usesEval, needsClosure);
1791 }
1792
1793 // ------------------------------ FunctionBodyNode -----------------------------
1794
1795 FunctionBodyNode::FunctionBodyNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1796     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
1797 {
1798 }
1799
1800 FunctionBodyNode::~FunctionBodyNode()
1801 {
1802 }
1803
1804 void FunctionBodyNode::mark()
1805 {
1806     if (m_code)
1807         m_code->mark();
1808 }
1809
1810 FunctionBodyNode* FunctionBodyNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1811 {
1812     return new FunctionBodyNode(children, varStack, funcStack, usesEval, needsClosure);
1813 }
1814
1815 void FunctionBodyNode::generateCode(ScopeChainNode* sc)
1816 {
1817     ScopeChain scopeChain(sc);
1818     JSGlobalObject* globalObject = scopeChain.globalObject();
1819
1820     m_code.set(new CodeBlock(this));
1821
1822     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get());
1823     generator.generate();
1824 }
1825
1826 RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*)
1827 {
1828     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
1829     statementListEmitCode(m_children, generator);
1830     if (!m_children.size() || !m_children.last()->isReturnNode()) {
1831         RegisterID* r0 = generator.emitLoad(generator.newTemporary(), jsUndefined());
1832         generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1833         generator.emitReturn(r0);
1834     }
1835     return 0;
1836 }
1837
1838 RegisterID* ProgramNode::emitCode(CodeGenerator& generator, RegisterID*)
1839 {
1840     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1841
1842     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1843     generator.emitLoad(dstRegister.get(), jsUndefined());
1844     statementListEmitCode(m_children, generator, dstRegister.get());
1845
1846     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1847     generator.emitEnd(dstRegister.get());
1848     return 0;
1849 }
1850
1851 void ProgramNode::generateCode(ScopeChainNode* sc, bool canCreateGlobals)
1852 {
1853     ScopeChain scopeChain(sc);
1854     JSGlobalObject* globalObject = scopeChain.globalObject();
1855     
1856     m_code.set(new ProgramCodeBlock(this, globalObject));
1857     
1858     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack, canCreateGlobals);
1859     generator.generate();
1860 }
1861
1862 UString FunctionBodyNode::paramString() const
1863 {
1864     UString s("");
1865     size_t count = m_parameters.size();
1866     for (size_t pos = 0; pos < count; ++pos) {
1867         if (!s.isEmpty())
1868             s += ", ";
1869         s += m_parameters[pos].ustring();
1870     }
1871
1872     return s;
1873 }
1874
1875 // ------------------------------ FuncDeclNode ---------------------------------
1876
1877 void FuncDeclNode::addParams()
1878 {
1879     for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
1880         m_body->parameters().append(p->ident());
1881 }
1882
1883 FunctionImp* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
1884 {
1885     FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), scopeChain);
1886
1887     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
1888     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
1889     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
1890     func->putDirect(exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
1891     return func;
1892 }
1893
1894 RegisterID* FuncDeclNode::emitCode(CodeGenerator&, RegisterID* dst)
1895 {
1896     return dst;
1897 }
1898
1899 // ------------------------------ FuncExprNode ---------------------------------
1900
1901 RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1902 {
1903     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
1904 }
1905
1906 FunctionImp* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
1907 {
1908     FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), scopeChain);
1909     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
1910     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
1911     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
1912
1913     /* 
1914         The Identifier in a FunctionExpression can be referenced from inside
1915         the FunctionExpression's FunctionBody to allow the function to call
1916         itself recursively. However, unlike in a FunctionDeclaration, the
1917         Identifier in a FunctionExpression cannot be referenced from and
1918         does not affect the scope enclosing the FunctionExpression.
1919      */
1920
1921     if (!m_ident.isNull()) {
1922         JSObject* functionScopeObject = new JSObject;
1923         functionScopeObject->putDirect(m_ident, func, ReadOnly | DontDelete);
1924         func->scope().push(functionScopeObject);
1925     }
1926
1927     return func;
1928 }
1929
1930 // ECMA 13
1931 void FuncExprNode::addParams()
1932 {
1933     for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
1934         m_body->parameters().append(p->ident());
1935 }
1936
1937 } // namespace KJS