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