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