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