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