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