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