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