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