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