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