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