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