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