2008-07-01 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 "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         RefPtr<RegisterID> clauseVal = generator.newTemporary();
1513         generator.emitNode(clauseVal.get(), list->getClause()->expr());
1514         generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression);
1515         labelVector.append(generator.newLabel());
1516         generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1517     }
1518
1519     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
1520         RefPtr<RegisterID> clauseVal = generator.newTemporary();
1521         generator.emitNode(clauseVal.get(), list->getClause()->expr());
1522         generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression);
1523         labelVector.append(generator.newLabel());
1524         generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1525     }
1526
1527     RefPtr<LabelID> defaultLabel;
1528     defaultLabel = generator.newLabel();
1529     generator.emitJump(defaultLabel.get());
1530
1531     RegisterID* result = 0;
1532
1533     size_t i = 0;
1534     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
1535         generator.emitLabel(labelVector[i++].get());
1536         result = statementListEmitCode(list->getClause()->children(), generator, dst);
1537     }
1538
1539     if (m_defaultClause) {
1540         generator.emitLabel(defaultLabel.get());
1541         result = statementListEmitCode(m_defaultClause->children(), generator, dst);
1542     }
1543
1544     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
1545         generator.emitLabel(labelVector[i++].get());
1546         result = statementListEmitCode(list->getClause()->children(), generator, dst);
1547     }
1548     if (!m_defaultClause)
1549         generator.emitLabel(defaultLabel.get());
1550
1551     ASSERT(i == labelVector.size());
1552
1553     return result;
1554 }
1555
1556 // ------------------------------ SwitchNode -----------------------------------
1557
1558 RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1559 {
1560     RefPtr<LabelID> breakTarget = generator.newLabel();
1561
1562     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
1563     generator.pushJumpContext(&m_labelStack, 0, breakTarget.get(), true);
1564     RegisterID* r1 = m_block->emitCodeForBlock(generator, r0.get(), dst);
1565     generator.popJumpContext();
1566
1567     generator.emitLabel(breakTarget.get());
1568
1569     return r1;
1570 }
1571
1572 // ------------------------------ LabelNode ------------------------------------
1573
1574 RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1575 {
1576     if (generator.jumpContextForBreak(m_label))
1577         return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label);
1578     
1579     RefPtr<LabelID> l0 = generator.newLabel();
1580     m_labelStack.push(m_label);
1581     generator.pushJumpContext(&m_labelStack, 0, l0.get(), false);
1582     
1583     RegisterID* r0 = generator.emitNode(dst, m_statement.get());
1584     
1585     generator.popJumpContext();
1586     m_labelStack.pop();
1587     
1588     generator.emitLabel(l0.get());
1589     return r0;
1590 }
1591
1592 // ------------------------------ ThrowNode ------------------------------------
1593
1594 RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1595 {
1596     generator.emitThrow(generator.emitNode(dst, m_expr.get()));
1597     return dst;
1598 }
1599
1600 // ------------------------------ TryNode --------------------------------------
1601
1602 RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1603 {
1604     RefPtr<LabelID> tryStartLabel = generator.newLabel();
1605     RefPtr<LabelID> tryEndLabel = generator.newLabel();
1606     RefPtr<LabelID> finallyStart;
1607     RefPtr<RegisterID> finallyReturnAddr;
1608     if (m_finallyBlock) {
1609         finallyStart = generator.newLabel();
1610         finallyReturnAddr = generator.newTemporary();
1611         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
1612     }
1613     generator.emitLabel(tryStartLabel.get());
1614     generator.emitNode(dst, m_tryBlock.get());
1615     generator.emitLabel(tryEndLabel.get());
1616
1617     if (m_catchBlock) {
1618         RefPtr<LabelID> handlerEndLabel = generator.newLabel();
1619         generator.emitJump(handlerEndLabel.get());
1620         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
1621         RefPtr<RegisterID> newScope = generator.emitNewObject(generator.newTemporary()); // scope must be protected until popped
1622         generator.emitPutById(newScope.get(), m_exceptionIdent, exceptionRegister.get());
1623         exceptionRegister = 0; // Release register used for temporaries
1624         generator.emitPushScope(newScope.get());
1625         generator.emitNode(dst, m_catchBlock.get());
1626         generator.emitPopScope();
1627         generator.emitLabel(handlerEndLabel.get());
1628     }
1629
1630     if (m_finallyBlock) {
1631         generator.popFinallyContext();
1632         // there may be important registers live at the time we jump
1633         // to a finally block (such as for a return or throw) so we
1634         // ref the highest register ever used as a conservative
1635         // approach to not clobbering anything important
1636         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
1637         RefPtr<LabelID> finallyEndLabel = generator.newLabel();
1638         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1639         generator.emitJump(finallyEndLabel.get());
1640
1641         // Finally block for exception path
1642         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
1643         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1644         generator.emitThrow(tempExceptionRegister.get());
1645
1646         // emit the finally block itself
1647         generator.emitLabel(finallyStart.get());
1648         generator.emitNode(dst, m_finallyBlock.get());
1649         generator.emitSubroutineReturn(finallyReturnAddr.get());
1650
1651         generator.emitLabel(finallyEndLabel.get());
1652     }
1653
1654     return dst;
1655 }
1656
1657
1658 // ------------------------------ FunctionBodyNode -----------------------------
1659
1660 ScopeNode::ScopeNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1661     : BlockNode(globalData, children)
1662     , m_sourceURL(globalData->parser->sourceURL())
1663     , m_sourceId(globalData->parser->sourceId())
1664     , m_usesEval(usesEval)
1665     , m_needsClosure(needsClosure)
1666 {
1667     if (varStack)
1668         m_varStack = *varStack;
1669     if (funcStack)
1670         m_functionStack = *funcStack;
1671 }
1672
1673 // ------------------------------ ProgramNode -----------------------------
1674
1675 ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1676     : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure)
1677 {
1678 }
1679
1680 ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1681 {
1682     return new ProgramNode(globalData, children, varStack, funcStack, usesEval, needsClosure);
1683 }
1684
1685 // ------------------------------ EvalNode -----------------------------
1686
1687 EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1688     : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure)
1689 {
1690 }
1691
1692 RegisterID* EvalNode::emitCode(CodeGenerator& generator, RegisterID*)
1693 {
1694     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1695
1696     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1697     generator.emitLoad(dstRegister.get(), jsUndefined());
1698     statementListEmitCode(m_children, generator, dstRegister.get());
1699
1700     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1701     generator.emitEnd(dstRegister.get());
1702     return 0;
1703 }
1704
1705 void EvalNode::generateCode(ScopeChainNode* sc)
1706 {
1707     ScopeChain scopeChain(sc);
1708     JSGlobalObject* globalObject = scopeChain.globalObject();
1709
1710     SymbolTable symbolTable;
1711
1712     m_code.set(new EvalCodeBlock(this, globalObject));
1713
1714     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get());
1715     generator.generate();
1716 }
1717
1718 EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1719 {
1720     return new EvalNode(globalData, children, varStack, funcStack, usesEval, needsClosure);
1721 }
1722
1723 // ------------------------------ FunctionBodyNode -----------------------------
1724
1725 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1726     : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure)
1727 {
1728 }
1729
1730 void FunctionBodyNode::mark()
1731 {
1732     if (m_code)
1733         m_code->mark();
1734 }
1735
1736 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1737 {
1738     return new FunctionBodyNode(globalData, children, varStack, funcStack, usesEval, needsClosure);
1739 }
1740
1741 void FunctionBodyNode::generateCode(ScopeChainNode* sc)
1742 {
1743     ScopeChain scopeChain(sc);
1744     JSGlobalObject* globalObject = scopeChain.globalObject();
1745
1746     m_code.set(new CodeBlock(this, FunctionCode));
1747
1748     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get());
1749     generator.generate();
1750 }
1751
1752 RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*)
1753 {
1754     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
1755     statementListEmitCode(m_children, generator);
1756     if (!m_children.size() || !m_children.last()->isReturnNode()) {
1757         RegisterID* r0 = generator.emitLoad(generator.newTemporary(), jsUndefined());
1758         generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1759         generator.emitReturn(r0);
1760     }
1761     return 0;
1762 }
1763
1764 RegisterID* ProgramNode::emitCode(CodeGenerator& generator, RegisterID*)
1765 {
1766     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1767
1768     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1769     generator.emitLoad(dstRegister.get(), jsUndefined());
1770     statementListEmitCode(m_children, generator, dstRegister.get());
1771
1772     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1773     generator.emitEnd(dstRegister.get());
1774     return 0;
1775 }
1776
1777 void ProgramNode::generateCode(ScopeChainNode* sc)
1778 {
1779     ScopeChain scopeChain(sc);
1780     JSGlobalObject* globalObject = scopeChain.globalObject();
1781     
1782     m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject));
1783     
1784     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack);
1785     generator.generate();
1786 }
1787
1788 UString FunctionBodyNode::paramString() const
1789 {
1790     UString s("");
1791     size_t count = m_parameters.size();
1792     for (size_t pos = 0; pos < count; ++pos) {
1793         if (!s.isEmpty())
1794             s += ", ";
1795         s += m_parameters[pos].ustring();
1796     }
1797
1798     return s;
1799 }
1800
1801 // ------------------------------ FuncDeclNode ---------------------------------
1802
1803 void FuncDeclNode::addParams()
1804 {
1805     for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
1806         m_body->parameters().append(p->ident());
1807 }
1808
1809 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
1810 {
1811     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
1812
1813     JSObject* proto = constructEmptyObject(exec);
1814     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
1815     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
1816     func->putDirect(exec->propertyNames().length, jsNumber(exec, m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
1817     return func;
1818 }
1819
1820 RegisterID* FuncDeclNode::emitCode(CodeGenerator&, RegisterID* dst)
1821 {
1822     return dst;
1823 }
1824
1825 // ------------------------------ FuncExprNode ---------------------------------
1826
1827 RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1828 {
1829     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
1830 }
1831
1832 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
1833 {
1834     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
1835     JSObject* proto = constructEmptyObject(exec);
1836     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
1837     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
1838
1839     /* 
1840         The Identifier in a FunctionExpression can be referenced from inside
1841         the FunctionExpression's FunctionBody to allow the function to call
1842         itself recursively. However, unlike in a FunctionDeclaration, the
1843         Identifier in a FunctionExpression cannot be referenced from and
1844         does not affect the scope enclosing the FunctionExpression.
1845      */
1846
1847     if (!m_ident.isNull()) {
1848         JSObject* functionScopeObject = new (exec) JSObject;
1849         functionScopeObject->putDirect(m_ident, func, ReadOnly | DontDelete);
1850         func->scope().push(functionScopeObject);
1851     }
1852
1853     return func;
1854 }
1855
1856 // ECMA 13
1857 void FuncExprNode::addParams()
1858 {
1859     for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
1860         m_body->parameters().append(p->ident());
1861 }
1862
1863 } // namespace KJS