6066c168cfef1cd58c34e48ed5c0d3f0591af7cf
[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(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(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(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(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     switch (oper) {
818         case OpMultEq:
819             return generator.emitBinaryOp(op_mul, dst, src1, src2);
820         case OpDivEq:
821             return generator.emitBinaryOp(op_div, dst, src1, src2);
822         case OpPlusEq:
823             return generator.emitBinaryOp(op_add, dst, src1, src2);
824         case OpMinusEq:
825             return generator.emitBinaryOp(op_sub, dst, src1, src2);
826         case OpLShift:
827             return generator.emitBinaryOp(op_lshift, dst, src1, src2);
828         case OpRShift:
829             return generator.emitBinaryOp(op_rshift, dst, src1, src2);
830         case OpURShift:
831             return generator.emitBinaryOp(op_urshift, dst, src1, src2);
832         case OpAndEq:
833             return generator.emitBinaryOp(op_bitand, dst, src1, src2);
834         case OpXOrEq:
835             return generator.emitBinaryOp(op_bitxor, dst, src1, src2);
836         case OpOrEq:
837             return generator.emitBinaryOp(op_bitor, dst, src1, src2);
838         case OpModEq:
839             return generator.emitBinaryOp(op_mod, dst, src1, src2);
840         default:
841             ASSERT_NOT_REACHED();
842     }
843
844     return dst;
845 }
846
847 RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
848 {
849     if (RegisterID* local = generator.registerForLocal(m_ident)) {
850         if (generator.isLocalConstant(m_ident)) {
851             RegisterID* src2 = generator.emitNode(m_right.get());
852             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator);
853         }
854         
855         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
856             RefPtr<RegisterID> result = generator.newTemporary();
857             generator.emitMove(result.get(), local);
858             RegisterID* src2 = generator.emitNode(m_right.get());
859             emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator);
860             generator.emitMove(local, result.get());
861             return generator.moveToDestinationIfNeeded(dst, result.get());
862         }
863         
864         RegisterID* src2 = generator.emitNode(m_right.get());
865         RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator);
866         return generator.moveToDestinationIfNeeded(dst, result);
867     }
868
869     int index = 0;
870     size_t depth = 0;
871     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
872         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index);
873         RegisterID* src2 = generator.emitNode(m_right.get());
874         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
875         generator.emitPutScopedVar(depth, index, result);
876         return result;
877     }
878
879     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
880     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
881     RegisterID* src2 = generator.emitNode(m_right.get());
882     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
883     return generator.emitPutById(base.get(), m_ident, result);
884 }
885
886 // ------------------------------ AssignResolveNode -----------------------------------
887
888 RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
889 {
890     if (RegisterID* local = generator.registerForLocal(m_ident)) {
891         if (generator.isLocalConstant(m_ident))
892             return generator.emitNode(dst, m_right.get());
893         
894         RegisterID* result = generator.emitNode(local, m_right.get());
895         return generator.moveToDestinationIfNeeded(dst, result);
896     }
897
898     int index = 0;
899     size_t depth = 0;
900     if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
901         RegisterID* value = generator.emitNode(dst, m_right.get());
902         generator.emitPutScopedVar(depth, index, value);
903         return value;
904     }
905
906     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
907     RegisterID* value = generator.emitNode(dst, m_right.get());
908     return generator.emitPutById(base.get(), m_ident, value);
909 }
910
911 // ------------------------------ AssignDotNode -----------------------------------
912
913 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
914 {
915     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
916     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
917     RegisterID* result = generator.emitNode(value.get(), m_right.get());
918     generator.emitPutById(base.get(), m_ident, result);
919     return generator.moveToDestinationIfNeeded(dst, result);
920 }
921
922 // ------------------------------ ReadModifyDotNode -----------------------------------
923
924 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
925 {
926     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
927     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
928     RegisterID* change = generator.emitNode(m_right.get());
929     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
930     return generator.emitPutById(base.get(), m_ident, updatedValue);
931 }
932
933 // ------------------------------ AssignErrorNode -----------------------------------
934
935 RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
936 {
937     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
938 }
939
940 // ------------------------------ AssignBracketNode -----------------------------------
941
942 RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
943 {
944     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
945     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.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.emitPutByVal(base.get(), property.get(), result);
949     return generator.moveToDestinationIfNeeded(dst, result);
950 }
951
952 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
953 {
954     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
955     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
956
957     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
958     RegisterID* change = generator.emitNode(m_right.get());
959     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
960
961     generator.emitPutByVal(base.get(), property.get(), updatedValue);
962
963     return updatedValue;
964 }
965
966 // ------------------------------ CommaNode ------------------------------------
967
968 RegisterID* CommaNode::emitCode(CodeGenerator& generator, RegisterID* dst)
969 {
970     generator.emitNode(m_expr1.get());
971     return generator.emitNode(dst, m_expr2.get());
972 }
973
974 // ------------------------------ ConstDeclNode ----------------------------------
975
976 ConstDeclNode::ConstDeclNode(const Identifier& ident, ExpressionNode* init)
977     : m_ident(ident)
978     , m_init(init)
979 {
980 }
981
982 RegisterID* ConstDeclNode::emitCodeSingle(CodeGenerator& generator)
983 {
984     if (RegisterID* local = generator.registerForLocalConstInit(m_ident)) {
985         if (!m_init)
986             return local;
987
988         return generator.emitNode(local, m_init.get());
989     }
990     
991     // FIXME: While this code should only be hit in eval code, it will potentially
992     // assign to the wrong base if m_ident exists in an intervening dynamic scope.
993     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
994     RegisterID* value = generator.emitNode(m_init.get());
995     return generator.emitPutById(base.get(), m_ident, value);
996 }
997
998 RegisterID* ConstDeclNode::emitCode(CodeGenerator& generator, RegisterID*)
999 {
1000     RegisterID* result = 0;
1001     for (ConstDeclNode* n = this; n; n = n->m_next.get())
1002         result = n->emitCodeSingle(generator);
1003
1004     return result;
1005 }
1006
1007 // ------------------------------ ConstStatementNode -----------------------------
1008
1009 RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
1010 {
1011     return generator.emitNode(m_next.get());
1012 }
1013
1014 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1015
1016 static inline RegisterID* statementListEmitCode(StatementVector& statements, CodeGenerator& generator, RegisterID* dst = 0)
1017 {
1018     RefPtr<RegisterID> r0 = dst;
1019
1020     StatementVector::iterator end = statements.end();
1021     for (StatementVector::iterator it = statements.begin(); it != end; ++it) {
1022         StatementNode* n = it->get();
1023         generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1024         if (RegisterID* r1 = generator.emitNode(dst, n))
1025             r0 = r1;
1026     }
1027     
1028     return r0.get();
1029 }
1030
1031 static inline void statementListPushFIFO(StatementVector& statements, DeclarationStacks::NodeStack& stack)
1032 {
1033     StatementVector::iterator it = statements.end();
1034     StatementVector::iterator begin = statements.begin();
1035     while (it != begin) {
1036         --it;
1037         stack.append((*it).get());
1038     }
1039 }
1040
1041 static inline Node* statementListInitializeVariableAccessStack(StatementVector& statements, DeclarationStacks::NodeStack& stack)
1042 {
1043     if (statements.isEmpty())
1044         return 0;
1045
1046     StatementVector::iterator it = statements.end();
1047     StatementVector::iterator begin = statements.begin();
1048     StatementVector::iterator beginPlusOne = begin + 1;
1049
1050     while (it != beginPlusOne) {
1051         --it;
1052         stack.append((*it).get());
1053     }
1054
1055     return (*begin).get();
1056 }
1057
1058 // ------------------------------ BlockNode ------------------------------------
1059
1060 BlockNode::BlockNode(SourceElements* children)
1061 {
1062     if (children)
1063         children->releaseContentsIntoVector(m_children);
1064 }
1065
1066 RegisterID* BlockNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1067 {
1068     return statementListEmitCode(m_children, generator, dst);
1069 }
1070
1071 // ------------------------------ EmptyStatementNode ---------------------------
1072
1073 RegisterID* EmptyStatementNode::emitCode(CodeGenerator&, RegisterID* dst)
1074 {
1075     return dst;
1076 }
1077
1078 // ------------------------------ DebuggerStatementNode ---------------------------
1079
1080 RegisterID* DebuggerStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1081 {
1082     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1083     return dst;
1084 }
1085
1086 // ------------------------------ ExprStatementNode ----------------------------
1087
1088 RegisterID* ExprStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1089 {
1090     ASSERT(m_expr);
1091     return generator.emitNode(dst, m_expr.get());
1092 }
1093
1094 // ------------------------------ VarStatementNode ----------------------------
1095
1096 RegisterID* VarStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
1097 {
1098     ASSERT(m_expr);
1099     return generator.emitNode(m_expr.get());
1100 }
1101
1102 // ------------------------------ IfNode ---------------------------------------
1103
1104 RegisterID* IfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1105 {
1106     RefPtr<LabelID> afterThen = generator.newLabel();
1107
1108     RegisterID* cond = generator.emitNode(m_condition.get());
1109     generator.emitJumpIfFalse(cond, afterThen.get());
1110
1111     generator.emitNode(dst, m_ifBlock.get());
1112     generator.emitLabel(afterThen.get());
1113
1114     // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
1115     return 0;
1116 }
1117
1118 RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1119 {
1120     RefPtr<LabelID> beforeElse = generator.newLabel();
1121     RefPtr<LabelID> afterElse = generator.newLabel();
1122
1123     RegisterID* cond = generator.emitNode(m_condition.get());
1124     generator.emitJumpIfFalse(cond, beforeElse.get());
1125
1126     generator.emitNode(dst, m_ifBlock.get());
1127     generator.emitJump(afterElse.get());
1128
1129     generator.emitLabel(beforeElse.get());
1130     generator.emitNode(dst, m_elseBlock.get());
1131
1132     generator.emitLabel(afterElse.get());
1133
1134     // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
1135     return 0;
1136 }
1137
1138 // ------------------------------ DoWhileNode ----------------------------------
1139
1140 RegisterID* DoWhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1141 {
1142     RefPtr<LabelID> topOfLoop = generator.newLabel();
1143     generator.emitLabel(topOfLoop.get());
1144
1145     RefPtr<LabelID> continueTarget = generator.newLabel();
1146     RefPtr<LabelID> breakTarget = generator.newLabel();
1147     
1148     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1149     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1150     generator.popJumpContext();
1151     
1152     generator.emitLabel(continueTarget.get());
1153     RegisterID* cond = generator.emitNode(m_expr.get());
1154     generator.emitJumpIfTrueMayCombine(cond, topOfLoop.get());
1155     generator.emitLabel(breakTarget.get());
1156     return result.get();
1157 }
1158
1159 // ------------------------------ WhileNode ------------------------------------
1160
1161 RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1162 {
1163     RefPtr<LabelID> topOfLoop = generator.newLabel();
1164     RefPtr<LabelID> continueTarget = generator.newLabel();
1165     RefPtr<LabelID> breakTarget = generator.newLabel();
1166
1167     generator.emitJump(continueTarget.get());
1168     generator.emitLabel(topOfLoop.get());
1169     
1170     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1171     generator.emitNode(dst, m_statement.get());
1172     generator.popJumpContext();
1173
1174     generator.emitLabel(continueTarget.get());
1175     RegisterID* cond = generator.emitNode(m_expr.get());
1176     generator.emitJumpIfTrueMayCombine(cond, topOfLoop.get());
1177
1178     generator.emitLabel(breakTarget.get());
1179     
1180     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1181     return 0;
1182 }
1183
1184 // ------------------------------ ForNode --------------------------------------
1185
1186 RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1187 {
1188     if (m_expr1)
1189         generator.emitNode(m_expr1.get());
1190     
1191     RefPtr<LabelID> topOfLoop = generator.newLabel();
1192     RefPtr<LabelID> beforeCondition = generator.newLabel();
1193     RefPtr<LabelID> continueTarget = generator.newLabel(); 
1194     RefPtr<LabelID> breakTarget = generator.newLabel(); 
1195     generator.emitJump(beforeCondition.get());
1196
1197     generator.emitLabel(topOfLoop.get());
1198     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1199     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1200     generator.popJumpContext();
1201     generator.emitLabel(continueTarget.get());
1202     if (m_expr3)
1203         generator.emitNode(m_expr3.get());
1204
1205     generator.emitLabel(beforeCondition.get());
1206     if (m_expr2) {
1207         RegisterID* cond = generator.emitNode(m_expr2.get());
1208         generator.emitJumpIfTrueMayCombine(cond, topOfLoop.get());
1209     } else {
1210         generator.emitJump(topOfLoop.get());
1211     }
1212     generator.emitLabel(breakTarget.get());
1213     return result.get();
1214 }
1215
1216 // ------------------------------ ForInNode ------------------------------------
1217
1218 ForInNode::ForInNode(ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1219     : m_init(0L)
1220     , m_lexpr(l)
1221     , m_expr(expr)
1222     , m_statement(statement)
1223     , m_identIsVarDecl(false)
1224 {
1225 }
1226
1227 ForInNode::ForInNode(const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement)
1228     : m_ident(ident)
1229     , m_lexpr(new ResolveNode(ident))
1230     , m_expr(expr)
1231     , m_statement(statement)
1232     , m_identIsVarDecl(true)
1233 {
1234     if (in)
1235         m_init = new AssignResolveNode(ident, in, true);
1236     // for( var foo = bar in baz )
1237 }
1238
1239 RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1240 {
1241     RefPtr<LabelID> loopStart = generator.newLabel();
1242     RefPtr<LabelID> continueTarget = generator.newLabel(); 
1243     RefPtr<LabelID> breakTarget = generator.newLabel(); 
1244
1245     if (m_init)
1246         generator.emitNode(m_init.get());
1247     RegisterID* forInBase = generator.emitNode(m_expr.get());
1248     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1249     generator.emitJump(continueTarget.get());
1250     generator.emitLabel(loopStart.get());
1251     RegisterID* propertyName;
1252     if (m_lexpr->isResolveNode()) {
1253         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1254         propertyName = generator.registerForLocal(ident);
1255         if (!propertyName) {
1256             propertyName = generator.newTemporary();
1257             RefPtr<RegisterID> protect = propertyName;
1258             RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1259             generator.emitPutById(base, ident, propertyName);
1260         }
1261     } else if (m_lexpr->isDotAccessorNode()) {
1262         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1263         const Identifier& ident = assignNode->identifier();
1264         propertyName = generator.newTemporary();
1265         RefPtr<RegisterID> protect = propertyName;
1266         RegisterID* base = generator.emitNode(assignNode->base());
1267         generator.emitPutById(base, ident, propertyName);
1268     } else {
1269         ASSERT(m_lexpr->isBracketAccessorNode());
1270         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1271         propertyName = generator.newTemporary();
1272         RefPtr<RegisterID> protect = propertyName;
1273         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1274         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1275         generator.emitPutByVal(base.get(), subscript, propertyName);
1276     }   
1277     
1278     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
1279     generator.emitNode(dst, m_statement.get());
1280     generator.popJumpContext();
1281
1282     generator.emitLabel(continueTarget.get());
1283     generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1284     generator.emitLabel(breakTarget.get());
1285     return dst;
1286 }
1287
1288 // ------------------------------ ContinueNode ---------------------------------
1289
1290 // ECMA 12.7
1291 RegisterID* ContinueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1292 {
1293     if (!generator.inContinueContext())
1294         return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
1295
1296     JumpContext* targetContext = generator.jumpContextForContinue(m_ident);
1297
1298     if (!targetContext) {
1299         if (m_ident.isEmpty())
1300             return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
1301         else
1302             return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
1303     }
1304
1305     if (!targetContext->continueTarget)
1306         return emitThrowError(generator, SyntaxError, "Invalid continue statement.");        
1307
1308     generator.emitJumpScopes(targetContext->continueTarget, targetContext->scopeDepth);
1309     
1310     return dst;
1311 }
1312
1313 // ------------------------------ BreakNode ------------------------------------
1314
1315 // ECMA 12.8
1316 RegisterID* BreakNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1317 {
1318     if (!generator.inJumpContext())
1319         return emitThrowError(generator, SyntaxError, "Invalid break statement.");
1320     
1321     JumpContext* targetContext = generator.jumpContextForBreak(m_ident);
1322     
1323     if (!targetContext) {
1324         if (m_ident.isEmpty())
1325             return emitThrowError(generator, SyntaxError, "Invalid break statement.");
1326         else
1327             return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
1328     }
1329
1330     ASSERT(targetContext->breakTarget);
1331
1332     generator.emitJumpScopes(targetContext->breakTarget, targetContext->scopeDepth);
1333
1334     return dst;
1335 }
1336
1337 // ------------------------------ ReturnNode -----------------------------------
1338
1339 RegisterID* ReturnNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1340 {
1341     if (generator.codeType() != FunctionCode)
1342         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
1343         
1344     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(generator.finalDestination(dst), jsUndefined());
1345     if (generator.scopeDepth()) {
1346         RefPtr<LabelID> l0 = generator.newLabel();
1347         generator.emitJumpScopes(l0.get(), 0);
1348         generator.emitLabel(l0.get());
1349     }
1350     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1351     return generator.emitReturn(r0);
1352 }
1353
1354 // ------------------------------ WithNode -------------------------------------
1355
1356 RegisterID* WithNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1357 {
1358     RefPtr<RegisterID> scope = generator.emitNode(m_expr.get()); // scope must be protected until popped
1359     generator.emitPushScope(scope.get());
1360     RegisterID* result = generator.emitNode(dst, m_statement.get());
1361     generator.emitPopScope();
1362     return result;
1363 }
1364
1365 // ------------------------------ CaseBlockNode --------------------------------
1366
1367 RegisterID* CaseBlockNode::emitCodeForBlock(CodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
1368 {
1369     Vector<RefPtr<LabelID>, 8> labelVector;
1370
1371     // Setup jumps
1372     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
1373         RegisterID* clauseVal = generator.emitNode(list->getClause()->expr());
1374         generator.emitBinaryOp(op_stricteq, clauseVal, clauseVal, switchExpression);
1375         labelVector.append(generator.newLabel());
1376         generator.emitJumpIfTrueMayCombine(clauseVal, labelVector[labelVector.size() - 1].get());
1377     }
1378
1379     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
1380         RegisterID* clauseVal = generator.emitNode(list->getClause()->expr());
1381         generator.emitBinaryOp(op_stricteq, clauseVal, clauseVal, switchExpression);
1382         labelVector.append(generator.newLabel());
1383         generator.emitJumpIfTrueMayCombine(clauseVal, labelVector[labelVector.size() - 1].get());
1384     }
1385
1386     RefPtr<LabelID> defaultLabel;
1387     defaultLabel = generator.newLabel();
1388     generator.emitJump(defaultLabel.get());
1389
1390     RegisterID* result = 0;
1391
1392     size_t i = 0;
1393     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
1394         generator.emitLabel(labelVector[i++].get());
1395         result = statementListEmitCode(list->getClause()->children(), generator, dst);
1396     }
1397
1398     if (m_defaultClause) {
1399         generator.emitLabel(defaultLabel.get());
1400         result = statementListEmitCode(m_defaultClause->children(), generator, dst);
1401     }
1402
1403     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
1404         generator.emitLabel(labelVector[i++].get());
1405         result = statementListEmitCode(list->getClause()->children(), generator, dst);
1406     }
1407     if (!m_defaultClause)
1408         generator.emitLabel(defaultLabel.get());
1409
1410     ASSERT(i == labelVector.size());
1411
1412     return result;
1413 }
1414
1415 // ------------------------------ SwitchNode -----------------------------------
1416
1417 RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1418 {
1419     RefPtr<LabelID> breakTarget = generator.newLabel();
1420
1421     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
1422     generator.pushJumpContext(&m_labelStack, 0, breakTarget.get(), true);
1423     RegisterID* r1 = m_block->emitCodeForBlock(generator, r0.get(), dst);
1424     generator.popJumpContext();
1425
1426     generator.emitLabel(breakTarget.get());
1427
1428     return r1;
1429 }
1430
1431 // ------------------------------ LabelNode ------------------------------------
1432
1433 RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1434 {
1435     if (generator.jumpContextForBreak(m_label))
1436         return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label);
1437     
1438     RefPtr<LabelID> l0 = generator.newLabel();
1439     m_labelStack.push(m_label);
1440     generator.pushJumpContext(&m_labelStack, 0, l0.get(), false);
1441     
1442     RegisterID* r0 = generator.emitNode(dst, m_statement.get());
1443     
1444     generator.popJumpContext();
1445     m_labelStack.pop();
1446     
1447     generator.emitLabel(l0.get());
1448     return r0;
1449 }
1450
1451 // ------------------------------ ThrowNode ------------------------------------
1452
1453 RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1454 {
1455     generator.emitThrow(generator.emitNode(dst, m_expr.get()));
1456     return dst;
1457 }
1458
1459 // ------------------------------ TryNode --------------------------------------
1460
1461 RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1462 {
1463     RefPtr<LabelID> tryStartLabel = generator.newLabel();
1464     RefPtr<LabelID> tryEndLabel = generator.newLabel();
1465     RefPtr<LabelID> finallyStart;
1466     RefPtr<RegisterID> finallyReturnAddr;
1467     if (m_finallyBlock) {
1468         finallyStart = generator.newLabel();
1469         finallyReturnAddr = generator.newTemporary();
1470         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
1471     }
1472     generator.emitLabel(tryStartLabel.get());
1473     generator.emitNode(dst, m_tryBlock.get());
1474     generator.emitLabel(tryEndLabel.get());
1475
1476     if (m_catchBlock) {
1477         RefPtr<LabelID> handlerEndLabel = generator.newLabel();
1478         generator.emitJump(handlerEndLabel.get());
1479         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
1480         RefPtr<RegisterID> newScope = generator.emitNewObject(generator.newTemporary()); // scope must be protected until popped
1481         generator.emitPutById(newScope.get(), m_exceptionIdent, exceptionRegister.get());
1482         exceptionRegister = 0; // Release register used for temporaries
1483         generator.emitPushScope(newScope.get());
1484         generator.emitNode(dst, m_catchBlock.get());
1485         generator.emitPopScope();
1486         generator.emitLabel(handlerEndLabel.get());
1487     }
1488
1489     if (m_finallyBlock) {
1490         generator.popFinallyContext();
1491         // there may be important registers live at the time we jump
1492         // to a finally block (such as for a return or throw) so we
1493         // ref the highest register ever used as a conservative
1494         // approach to not clobbering anything important
1495         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
1496         RefPtr<LabelID> finallyEndLabel = generator.newLabel();
1497         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1498         generator.emitJump(finallyEndLabel.get());
1499
1500         // Finally block for exception path
1501         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
1502         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1503         generator.emitThrow(tempExceptionRegister.get());
1504
1505         // emit the finally block itself
1506         generator.emitLabel(finallyStart.get());
1507         generator.emitNode(dst, m_finallyBlock.get());
1508         generator.emitSubroutineReturn(finallyReturnAddr.get());
1509
1510         generator.emitLabel(finallyEndLabel.get());
1511     }
1512
1513     return dst;
1514 }
1515
1516
1517 // ------------------------------ FunctionBodyNode -----------------------------
1518
1519 ScopeNode::ScopeNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1520     : BlockNode(children)
1521     , m_sourceURL(JSGlobalData::threadInstance().parser->sourceURL())
1522     , m_sourceId(JSGlobalData::threadInstance().parser->sourceId())
1523     , m_usesEval(usesEval)
1524     , m_needsClosure(needsClosure)
1525 {
1526     if (varStack)
1527         m_varStack = *varStack;
1528     if (funcStack)
1529         m_functionStack = *funcStack;
1530 }
1531
1532 // ------------------------------ ProgramNode -----------------------------
1533
1534 ProgramNode::ProgramNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1535     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
1536 {
1537 }
1538
1539 ProgramNode::~ProgramNode()
1540 {
1541 }
1542
1543 ProgramNode* ProgramNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1544 {
1545     return new ProgramNode(children, varStack, funcStack, usesEval, needsClosure);
1546 }
1547
1548 // ------------------------------ EvalNode -----------------------------
1549
1550 EvalNode::EvalNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1551     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
1552 {
1553 }
1554
1555 EvalNode::~EvalNode()
1556 {
1557 }
1558
1559 RegisterID* EvalNode::emitCode(CodeGenerator& generator, RegisterID*)
1560 {
1561     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1562
1563     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1564     generator.emitLoad(dstRegister.get(), jsUndefined());
1565     statementListEmitCode(m_children, generator, dstRegister.get());
1566
1567     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1568     generator.emitEnd(dstRegister.get());
1569     return 0;
1570 }
1571
1572 void EvalNode::generateCode(ScopeChainNode* sc)
1573 {
1574     ScopeChain scopeChain(sc);
1575     JSGlobalObject* globalObject = scopeChain.globalObject();
1576
1577     SymbolTable symbolTable;
1578
1579     m_code.set(new EvalCodeBlock(this, globalObject));
1580
1581     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get());
1582     generator.generate();
1583 }
1584
1585 EvalNode* EvalNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1586 {
1587     return new EvalNode(children, varStack, funcStack, usesEval, needsClosure);
1588 }
1589
1590 // ------------------------------ FunctionBodyNode -----------------------------
1591
1592 FunctionBodyNode::FunctionBodyNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1593     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
1594 {
1595 }
1596
1597 FunctionBodyNode::~FunctionBodyNode()
1598 {
1599 }
1600
1601 void FunctionBodyNode::mark()
1602 {
1603     if (m_code)
1604         m_code->mark();
1605 }
1606
1607 FunctionBodyNode* FunctionBodyNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
1608 {
1609     return new FunctionBodyNode(children, varStack, funcStack, usesEval, needsClosure);
1610 }
1611
1612 void FunctionBodyNode::generateCode(ScopeChainNode* sc)
1613 {
1614     ScopeChain scopeChain(sc);
1615     JSGlobalObject* globalObject = scopeChain.globalObject();
1616
1617     m_code.set(new CodeBlock(this, FunctionCode));
1618
1619     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get());
1620     generator.generate();
1621 }
1622
1623 RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*)
1624 {
1625     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
1626     statementListEmitCode(m_children, generator);
1627     if (!m_children.size() || !m_children.last()->isReturnNode()) {
1628         RegisterID* r0 = generator.emitLoad(generator.newTemporary(), jsUndefined());
1629         generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1630         generator.emitReturn(r0);
1631     }
1632     return 0;
1633 }
1634
1635 RegisterID* ProgramNode::emitCode(CodeGenerator& generator, RegisterID*)
1636 {
1637     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1638
1639     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1640     generator.emitLoad(dstRegister.get(), jsUndefined());
1641     statementListEmitCode(m_children, generator, dstRegister.get());
1642
1643     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1644     generator.emitEnd(dstRegister.get());
1645     return 0;
1646 }
1647
1648 void ProgramNode::generateCode(ScopeChainNode* sc, bool canCreateGlobals)
1649 {
1650     ScopeChain scopeChain(sc);
1651     JSGlobalObject* globalObject = scopeChain.globalObject();
1652     
1653     m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject));
1654     
1655     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack, canCreateGlobals);
1656     generator.generate();
1657 }
1658
1659 UString FunctionBodyNode::paramString() const
1660 {
1661     UString s("");
1662     size_t count = m_parameters.size();
1663     for (size_t pos = 0; pos < count; ++pos) {
1664         if (!s.isEmpty())
1665             s += ", ";
1666         s += m_parameters[pos].ustring();
1667     }
1668
1669     return s;
1670 }
1671
1672 // ------------------------------ FuncDeclNode ---------------------------------
1673
1674 void FuncDeclNode::addParams()
1675 {
1676     for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
1677         m_body->parameters().append(p->ident());
1678 }
1679
1680 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
1681 {
1682     JSFunction* func = new JSFunction(exec, m_ident, m_body.get(), scopeChain);
1683
1684     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
1685     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
1686     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
1687     func->putDirect(exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
1688     return func;
1689 }
1690
1691 RegisterID* FuncDeclNode::emitCode(CodeGenerator&, RegisterID* dst)
1692 {
1693     return dst;
1694 }
1695
1696 // ------------------------------ FuncExprNode ---------------------------------
1697
1698 RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
1699 {
1700     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
1701 }
1702
1703 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
1704 {
1705     JSFunction* func = new JSFunction(exec, m_ident, m_body.get(), scopeChain);
1706     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
1707     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
1708     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
1709
1710     /* 
1711         The Identifier in a FunctionExpression can be referenced from inside
1712         the FunctionExpression's FunctionBody to allow the function to call
1713         itself recursively. However, unlike in a FunctionDeclaration, the
1714         Identifier in a FunctionExpression cannot be referenced from and
1715         does not affect the scope enclosing the FunctionExpression.
1716      */
1717
1718     if (!m_ident.isNull()) {
1719         JSObject* functionScopeObject = new JSObject;
1720         functionScopeObject->putDirect(m_ident, func, ReadOnly | DontDelete);
1721         func->scope().push(functionScopeObject);
1722     }
1723
1724     return func;
1725 }
1726
1727 // ECMA 13
1728 void FuncExprNode::addParams()
1729 {
1730     for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
1731         m_body->parameters().append(p->ident());
1732 }
1733
1734 } // namespace KJS