324b3ee64bbd18508152930578237916e3fc70af
[WebKit-https.git] / JavaScriptCore / parser / 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 "BytecodeGenerator.h"
30 #include "CallFrame.h"
31 #include "JSGlobalObject.h"
32 #include "JSStaticScopeObject.h"
33 #include "LabelScope.h"
34 #include "Parser.h"
35 #include "PropertyNameArray.h"
36 #include "RegExpObject.h"
37 #include "SamplingTool.h"
38 #include "Debugger.h"
39 #include "Lexer.h"
40 #include "Operations.h"
41 #include <math.h>
42 #include <wtf/Assertions.h>
43 #include <wtf/HashCountedSet.h>
44 #include <wtf/HashSet.h>
45 #include <wtf/MathExtras.h>
46 #include <wtf/RefCountedLeakCounter.h>
47 #include <wtf/Threading.h>
48
49 using namespace WTF;
50
51 namespace JSC {
52
53 static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
54
55 // ------------------------------ NodeReleaser --------------------------------
56
57 class NodeReleaser : Noncopyable {
58 public:
59     // Call this function inside the destructor of a class derived from Node.
60     // This will traverse the tree below this node, destroying all of those nodes,
61     // but without relying on recursion.
62     static void releaseAllNodes(ParserRefCounted* root);
63
64     // Call this on each node in a the releaseNodes virtual function.
65     // It gives the node to the NodeReleaser, which will then release the
66     // node later at the end of the releaseAllNodes process.
67     template <typename T> void release(RefPtr<T>& node) { if (node) adopt(node.release()); }
68     void release(RefPtr<FunctionBodyNode>& node) { if (node) adoptFunctionBodyNode(node); }
69
70 private:
71     NodeReleaser() { }
72     ~NodeReleaser() { }
73
74     void adopt(PassRefPtr<ParserRefCounted>);
75     void adoptFunctionBodyNode(RefPtr<FunctionBodyNode>&);
76
77     typedef Vector<RefPtr<ParserRefCounted> > NodeReleaseVector;
78     OwnPtr<NodeReleaseVector> m_vector;
79 };
80
81 void NodeReleaser::releaseAllNodes(ParserRefCounted* root)
82 {
83     ASSERT(root);
84     NodeReleaser releaser;
85     root->releaseNodes(releaser);
86     if (!releaser.m_vector)
87         return;
88     // Note: The call to release.m_vector->size() is intentionally inside
89     // the loop, since calls to releaseNodes are expected to increase the size.
90     for (size_t i = 0; i < releaser.m_vector->size(); ++i) {
91         ParserRefCounted* node = (*releaser.m_vector)[i].get();
92         if (node->hasOneRef())
93             node->releaseNodes(releaser);
94     }
95 }
96
97 void NodeReleaser::adopt(PassRefPtr<ParserRefCounted> node)
98 {
99     ASSERT(node);
100     if (!node->hasOneRef())
101         return;
102     if (!m_vector)
103         m_vector.set(new NodeReleaseVector);
104     m_vector->append(node);
105 }
106
107 void NodeReleaser::adoptFunctionBodyNode(RefPtr<FunctionBodyNode>& functionBodyNode)
108 {
109     // This sidesteps a problem where if you assign a PassRefPtr<FunctionBodyNode>
110     // to a PassRefPtr<Node> we leave the two reference counts (FunctionBodyNode
111     // and ParserRefCounted) unbalanced. It would be nice to fix this problem in
112     // a cleaner way -- perhaps we could remove the FunctionBodyNode reference
113     // count at some point.
114     RefPtr<Node> node = functionBodyNode;
115     functionBodyNode = 0;
116     adopt(node.release());
117 }
118
119 // ------------------------------ ParserRefCounted -----------------------------------------
120
121 #ifndef NDEBUG
122 static RefCountedLeakCounter parserRefCountedCounter("JSC::Node");
123 #endif
124
125 ParserRefCounted::ParserRefCounted(JSGlobalData* globalData)
126     : m_globalData(globalData)
127 {
128 #ifndef NDEBUG
129     parserRefCountedCounter.increment();
130 #endif
131     if (!m_globalData->newParserObjects)
132         m_globalData->newParserObjects = new HashSet<ParserRefCounted*>;
133     m_globalData->newParserObjects->add(this);
134     ASSERT(m_globalData->newParserObjects->contains(this));
135 }
136
137 ParserRefCounted::~ParserRefCounted()
138 {
139 #ifndef NDEBUG
140     parserRefCountedCounter.decrement();
141 #endif
142 }
143
144 void ParserRefCounted::releaseNodes(NodeReleaser&)
145 {
146 }
147
148 void ParserRefCounted::ref()
149 {
150     // bumping from 0 to 1 is just removing from the new nodes set
151     if (m_globalData->newParserObjects) {
152         HashSet<ParserRefCounted*>::iterator it = m_globalData->newParserObjects->find(this);
153         if (it != m_globalData->newParserObjects->end()) {
154             m_globalData->newParserObjects->remove(it);
155             ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));
156             return;
157         }
158     }
159
160     ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
161
162     if (!m_globalData->parserObjectExtraRefCounts)
163         m_globalData->parserObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>;
164     m_globalData->parserObjectExtraRefCounts->add(this);
165 }
166
167 void ParserRefCounted::deref()
168 {
169     ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
170
171     if (!m_globalData->parserObjectExtraRefCounts) {
172         delete this;
173         return;
174     }
175
176     HashCountedSet<ParserRefCounted*>::iterator it = m_globalData->parserObjectExtraRefCounts->find(this);
177     if (it == m_globalData->parserObjectExtraRefCounts->end())
178         delete this;
179     else
180         m_globalData->parserObjectExtraRefCounts->remove(it);
181 }
182
183 bool ParserRefCounted::hasOneRef()
184 {
185     if (m_globalData->newParserObjects && m_globalData->newParserObjects->contains(this)) {
186         ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));
187         return false;
188     }
189
190     ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
191
192     if (!m_globalData->parserObjectExtraRefCounts)
193         return true;
194
195     return !m_globalData->parserObjectExtraRefCounts->contains(this);
196 }
197
198 void ParserRefCounted::deleteNewObjects(JSGlobalData* globalData)
199 {
200     if (!globalData->newParserObjects)
201         return;
202
203 #ifndef NDEBUG
204     HashSet<ParserRefCounted*>::iterator end = globalData->newParserObjects->end();
205     for (HashSet<ParserRefCounted*>::iterator it = globalData->newParserObjects->begin(); it != end; ++it)
206         ASSERT(!globalData->parserObjectExtraRefCounts || !globalData->parserObjectExtraRefCounts->contains(*it));
207 #endif
208     deleteAllValues(*globalData->newParserObjects);
209     delete globalData->newParserObjects;
210     globalData->newParserObjects = 0;
211 }
212
213 // ------------------------------ Node --------------------------------
214
215 Node::Node(JSGlobalData* globalData)
216     : ParserRefCounted(globalData)
217 {
218     m_line = globalData->lexer->lineNo();
219 }
220
221 // ------------------------------ ThrowableExpressionData --------------------------------
222
223 static void substitute(UString& string, const UString& substring)
224 {
225     int position = string.find("%s");
226     ASSERT(position != -1);
227     UString newString = string.substr(0, position);
228     newString.append(substring);
229     newString.append(string.substr(position + 2));
230     string = newString;
231 }
232
233 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg)
234 {
235     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
236     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg));
237     generator.emitThrow(exception);
238     return exception;
239 }
240
241 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
242 {
243     UString message = msg;
244     substitute(message, label.ustring());
245     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
246     RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message));
247     generator.emitThrow(exception);
248     return exception;
249 }
250     
251 // ------------------------------ StatementNode --------------------------------
252
253 StatementNode::StatementNode(JSGlobalData* globalData)
254     : Node(globalData)
255     , m_lastLine(-1)
256 {
257 }
258
259 void StatementNode::setLoc(int firstLine, int lastLine)
260 {
261     m_line = firstLine;
262     m_lastLine = lastLine;
263 }
264
265 // ------------------------------ SourceElements --------------------------------
266
267 void SourceElements::append(PassRefPtr<StatementNode> statement)
268 {
269     if (statement->isEmptyStatement())
270         return;
271
272     m_statements.append(statement);
273 }
274
275 // ------------------------------ NullNode -------------------------------------
276
277 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
278 {
279     if (dst == ignoredResult())
280         return 0;
281     return generator.emitLoad(dst, jsNull());
282 }
283
284 // ------------------------------ BooleanNode ----------------------------------
285
286 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
287 {
288     if (dst == ignoredResult())
289         return 0;
290     return generator.emitLoad(dst, m_value);
291 }
292
293 // ------------------------------ NumberNode -----------------------------------
294
295 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
296 {
297     if (dst == ignoredResult())
298         return 0;
299     return generator.emitLoad(dst, m_double);
300 }
301
302 // ------------------------------ StringNode -----------------------------------
303
304 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
305 {
306     if (dst == ignoredResult())
307         return 0;
308     return generator.emitLoad(dst, m_value);
309 }
310
311 // ------------------------------ RegExpNode -----------------------------------
312
313 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
314 {
315     RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags);
316     if (!regExp->isValid())
317         return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str());
318     if (dst == ignoredResult())
319         return 0;
320     return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
321 }
322
323 // ------------------------------ ThisNode -------------------------------------
324
325 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
326 {
327     if (dst == ignoredResult())
328         return 0;
329     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
330 }
331
332 // ------------------------------ ResolveNode ----------------------------------
333
334 bool ResolveNode::isPure(BytecodeGenerator& generator) const
335 {
336     return generator.isLocal(m_ident);
337 }
338
339 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
340 {
341     if (RegisterID* local = generator.registerFor(m_ident)) {
342         if (dst == ignoredResult())
343             return 0;
344         return generator.moveToDestinationIfNeeded(dst, local);
345     }
346     
347     generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);
348     return generator.emitResolve(generator.finalDestination(dst), m_ident);
349 }
350
351 // ------------------------------ ElementNode ------------------------------------
352
353 ElementNode::~ElementNode()
354 {
355     NodeReleaser::releaseAllNodes(this);
356 }
357
358 void ElementNode::releaseNodes(NodeReleaser& releaser)
359 {
360     releaser.release(m_next);
361     releaser.release(m_node);
362 }
363
364 // ------------------------------ ArrayNode ------------------------------------
365
366 ArrayNode::~ArrayNode()
367 {
368     NodeReleaser::releaseAllNodes(this);
369 }
370
371 void ArrayNode::releaseNodes(NodeReleaser& releaser)
372 {
373     releaser.release(m_element);
374 }
375
376 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
377 {
378     // FIXME: Should we put all of this code into emitNewArray?
379
380     unsigned length = 0;
381     ElementNode* firstPutElement;
382     for (firstPutElement = m_element.get(); firstPutElement; firstPutElement = firstPutElement->next()) {
383         if (firstPutElement->elision())
384             break;
385         ++length;
386     }
387
388     if (!firstPutElement && !m_elision)
389         return generator.emitNewArray(generator.finalDestination(dst), m_element.get());
390
391     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element.get());
392
393     for (ElementNode* n = firstPutElement; n; n = n->next()) {
394         RegisterID* value = generator.emitNode(n->value());
395         length += n->elision();
396         generator.emitPutByIndex(array.get(), length++, value);
397     }
398
399     if (m_elision) {
400         RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length));
401         generator.emitPutById(array.get(), generator.propertyNames().length, value);
402     }
403
404     return generator.moveToDestinationIfNeeded(dst, array.get());
405 }
406
407 // ------------------------------ PropertyNode ----------------------------
408
409 PropertyNode::~PropertyNode()
410 {
411     NodeReleaser::releaseAllNodes(this);
412 }
413
414 void PropertyNode::releaseNodes(NodeReleaser& releaser)
415 {
416     releaser.release(m_assign);
417 }
418
419 // ------------------------------ ObjectLiteralNode ----------------------------
420
421 ObjectLiteralNode::~ObjectLiteralNode()
422 {
423     NodeReleaser::releaseAllNodes(this);
424 }
425
426 void ObjectLiteralNode::releaseNodes(NodeReleaser& releaser)
427 {
428     releaser.release(m_list);
429 }
430
431 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
432 {
433      if (!m_list) {
434          if (dst == ignoredResult())
435              return 0;
436          return generator.emitNewObject(generator.finalDestination(dst));
437      }
438      return generator.emitNode(dst, m_list.get());
439 }
440
441 // ------------------------------ PropertyListNode -----------------------------
442
443 PropertyListNode::~PropertyListNode()
444 {
445     NodeReleaser::releaseAllNodes(this);
446 }
447
448 void PropertyListNode::releaseNodes(NodeReleaser& releaser)
449 {
450     releaser.release(m_node);
451     releaser.release(m_next);
452 }
453
454 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
455 {
456     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
457     
458     generator.emitNewObject(newObj.get());
459     
460     for (PropertyListNode* p = this; p; p = p->m_next.get()) {
461         RegisterID* value = generator.emitNode(p->m_node->m_assign.get());
462         
463         switch (p->m_node->m_type) {
464             case PropertyNode::Constant: {
465                 generator.emitPutById(newObj.get(), p->m_node->name(), value);
466                 break;
467             }
468             case PropertyNode::Getter: {
469                 generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
470                 break;
471             }
472             case PropertyNode::Setter: {
473                 generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
474                 break;
475             }
476             default:
477                 ASSERT_NOT_REACHED();
478         }
479     }
480     
481     return generator.moveToDestinationIfNeeded(dst, newObj.get());
482 }
483
484 // ------------------------------ BracketAccessorNode --------------------------------
485
486 BracketAccessorNode::~BracketAccessorNode()
487 {
488     NodeReleaser::releaseAllNodes(this);
489 }
490
491 void BracketAccessorNode::releaseNodes(NodeReleaser& releaser)
492 {
493     releaser.release(m_base);
494     releaser.release(m_subscript);
495 }
496
497 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
498 {
499     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript->isPure(generator));
500     RegisterID* property = generator.emitNode(m_subscript.get());
501     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
502     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
503 }
504
505 // ------------------------------ DotAccessorNode --------------------------------
506
507 DotAccessorNode::~DotAccessorNode()
508 {
509     NodeReleaser::releaseAllNodes(this);
510 }
511
512 void DotAccessorNode::releaseNodes(NodeReleaser& releaser)
513 {
514     releaser.release(m_base);
515 }
516
517 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
518 {
519     RegisterID* base = generator.emitNode(m_base.get());
520     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
521     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
522 }
523
524 // ------------------------------ ArgumentListNode -----------------------------
525
526 ArgumentListNode::~ArgumentListNode()
527 {
528     NodeReleaser::releaseAllNodes(this);
529 }
530
531 void ArgumentListNode::releaseNodes(NodeReleaser& releaser)
532 {
533     releaser.release(m_next);
534     releaser.release(m_expr);
535 }
536
537 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
538 {
539     ASSERT(m_expr);
540     return generator.emitNode(dst, m_expr.get());
541 }
542
543 // ------------------------------ ArgumentsNode -----------------------------
544
545 ArgumentsNode::~ArgumentsNode()
546 {
547     NodeReleaser::releaseAllNodes(this);
548 }
549
550 void ArgumentsNode::releaseNodes(NodeReleaser& releaser)
551 {
552     releaser.release(m_listNode);
553 }
554
555 // ------------------------------ NewExprNode ----------------------------------
556
557 NewExprNode::~NewExprNode()
558 {
559     NodeReleaser::releaseAllNodes(this);
560 }
561
562 void NewExprNode::releaseNodes(NodeReleaser& releaser)
563 {
564     releaser.release(m_expr);
565     releaser.release(m_args);
566 }
567
568 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
569 {
570     RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
571     return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args.get(), divot(), startOffset(), endOffset());
572 }
573
574 // ------------------------------ EvalFunctionCallNode ----------------------------------
575
576 EvalFunctionCallNode::~EvalFunctionCallNode()
577 {
578     NodeReleaser::releaseAllNodes(this);
579 }
580
581 void EvalFunctionCallNode::releaseNodes(NodeReleaser& releaser)
582 {
583     releaser.release(m_args);
584 }
585
586 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
587 {
588     RefPtr<RegisterID> func = generator.tempDestination(dst);
589     RefPtr<RegisterID> thisRegister = generator.newTemporary();
590     generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
591     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
592 }
593
594 // ------------------------------ FunctionCallValueNode ----------------------------------
595
596 FunctionCallValueNode::~FunctionCallValueNode()
597 {
598     NodeReleaser::releaseAllNodes(this);
599 }
600
601 void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
602 {
603     releaser.release(m_expr);
604     releaser.release(m_args);
605 }
606
607 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
608 {
609     RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
610     RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
611     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
612 }
613
614 // ------------------------------ FunctionCallResolveNode ----------------------------------
615
616 FunctionCallResolveNode::~FunctionCallResolveNode()
617 {
618     NodeReleaser::releaseAllNodes(this);
619 }
620
621 void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
622 {
623     releaser.release(m_args);
624 }
625
626 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
627 {
628     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
629         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
630         return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
631     }
632
633     int index = 0;
634     size_t depth = 0;
635     JSObject* globalObject = 0;
636     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
637         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
638         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
639         return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
640     }
641
642     RefPtr<RegisterID> func = generator.tempDestination(dst);
643     RefPtr<RegisterID> thisRegister = generator.newTemporary();
644     int identifierStart = divot() - startOffset();
645     generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
646     generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
647     return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
648 }
649
650 // ------------------------------ FunctionCallBracketNode ----------------------------------
651
652 FunctionCallBracketNode::~FunctionCallBracketNode()
653 {
654     NodeReleaser::releaseAllNodes(this);
655 }
656
657 void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
658 {
659     releaser.release(m_base);
660     releaser.release(m_subscript);
661     releaser.release(m_args);
662 }
663
664 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
665 {
666     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
667     RegisterID* property = generator.emitNode(m_subscript.get());
668     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
669     RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
670     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
671     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
672 }
673
674 // ------------------------------ FunctionCallDotNode ----------------------------------
675
676 FunctionCallDotNode::~FunctionCallDotNode()
677 {
678     NodeReleaser::releaseAllNodes(this);
679 }
680
681 void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
682 {
683     releaser.release(m_base);
684     releaser.release(m_args);
685 }
686
687 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
688 {
689     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
690     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
691     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
692     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
693     return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
694 }
695
696 // ------------------------------ PostfixResolveNode ----------------------------------
697
698 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
699 {
700     return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
701 }
702
703 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
704 {
705     return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
706 }
707
708 RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
709 {
710     if (RegisterID* local = generator.registerFor(m_ident)) {
711         if (generator.isLocalConstant(m_ident)) {
712             if (dst == ignoredResult())
713                 return 0;
714             return generator.emitToJSNumber(generator.finalDestination(dst), local);
715         }
716
717         if (dst == ignoredResult())
718             return emitPreIncOrDec(generator, local, m_operator);
719         return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
720     }
721
722     int index = 0;
723     size_t depth = 0;
724     JSObject* globalObject = 0;
725     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
726         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
727         RegisterID* oldValue;
728         if (dst == ignoredResult()) {
729             oldValue = 0;
730             emitPreIncOrDec(generator, value.get(), m_operator);
731         } else {
732             oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
733         }
734         generator.emitPutScopedVar(depth, index, value.get(), globalObject);
735         return oldValue;
736     }
737
738     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
739     RefPtr<RegisterID> value = generator.newTemporary();
740     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
741     RegisterID* oldValue;
742     if (dst == ignoredResult()) {
743         oldValue = 0;
744         emitPreIncOrDec(generator, value.get(), m_operator);
745     } else {
746         oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
747     }
748     generator.emitPutById(base.get(), m_ident, value.get());
749     return oldValue;
750 }
751
752 // ------------------------------ PostfixBracketNode ----------------------------------
753
754 PostfixBracketNode::~PostfixBracketNode()
755 {
756     NodeReleaser::releaseAllNodes(this);
757 }
758
759 void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
760 {
761     releaser.release(m_base);
762     releaser.release(m_subscript);
763 }
764
765 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
766 {
767     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
768     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
769
770     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
771     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
772     RegisterID* oldValue;
773     if (dst == ignoredResult()) {
774         oldValue = 0;
775         if (m_operator == OpPlusPlus)
776             generator.emitPreInc(value.get());
777         else
778             generator.emitPreDec(value.get());
779     } else {
780         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
781     }
782     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
783     generator.emitPutByVal(base.get(), property.get(), value.get());
784     return oldValue;
785 }
786
787 // ------------------------------ PostfixDotNode ----------------------------------
788
789 PostfixDotNode::~PostfixDotNode()
790 {
791     NodeReleaser::releaseAllNodes(this);
792 }
793
794 void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
795 {
796     releaser.release(m_base);
797 }
798
799 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
800 {
801     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
802
803     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
804     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
805     RegisterID* oldValue;
806     if (dst == ignoredResult()) {
807         oldValue = 0;
808         if (m_operator == OpPlusPlus)
809             generator.emitPreInc(value.get());
810         else
811             generator.emitPreDec(value.get());
812     } else {
813         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
814     }
815     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
816     generator.emitPutById(base.get(), m_ident, value.get());
817     return oldValue;
818 }
819
820 // ------------------------------ PostfixErrorNode -----------------------------------
821
822 PostfixErrorNode::~PostfixErrorNode()
823 {
824     NodeReleaser::releaseAllNodes(this);
825 }
826
827 void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
828 {
829     releaser.release(m_expr);
830 }
831
832 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
833 {
834     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.");
835 }
836
837 // ------------------------------ DeleteResolveNode -----------------------------------
838
839 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
840 {
841     if (generator.registerFor(m_ident))
842         return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
843
844     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
845     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
846     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
847 }
848
849 // ------------------------------ DeleteBracketNode -----------------------------------
850
851 DeleteBracketNode::~DeleteBracketNode()
852 {
853     NodeReleaser::releaseAllNodes(this);
854 }
855
856 void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
857 {
858     releaser.release(m_base);
859     releaser.release(m_subscript);
860 }
861
862 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
863 {
864     RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
865     RegisterID* r1 = generator.emitNode(m_subscript.get());
866
867     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
868     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
869 }
870
871 // ------------------------------ DeleteDotNode -----------------------------------
872
873 DeleteDotNode::~DeleteDotNode()
874 {
875     NodeReleaser::releaseAllNodes(this);
876 }
877
878 void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
879 {
880     releaser.release(m_base);
881 }
882
883 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
884 {
885     RegisterID* r0 = generator.emitNode(m_base.get());
886
887     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
888     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
889 }
890
891 // ------------------------------ DeleteValueNode -----------------------------------
892
893 DeleteValueNode::~DeleteValueNode()
894 {
895     NodeReleaser::releaseAllNodes(this);
896 }
897
898 void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
899 {
900     releaser.release(m_expr);
901 }
902
903 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
904 {
905     generator.emitNode(ignoredResult(), m_expr.get());
906
907     // delete on a non-location expression ignores the value and returns true
908     return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
909 }
910
911 // ------------------------------ VoidNode -------------------------------------
912
913 VoidNode::~VoidNode()
914 {
915     NodeReleaser::releaseAllNodes(this);
916 }
917
918 void VoidNode::releaseNodes(NodeReleaser& releaser)
919 {
920     releaser.release(m_expr);
921 }
922
923 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
924 {
925     if (dst == ignoredResult()) {
926         generator.emitNode(ignoredResult(), m_expr.get());
927         return 0;
928     }
929     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
930     return generator.emitLoad(dst, jsUndefined());
931 }
932
933 // ------------------------------ TypeOfValueNode -----------------------------------
934
935 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
936 {
937     if (RegisterID* local = generator.registerFor(m_ident)) {
938         if (dst == ignoredResult())
939             return 0;
940         return generator.emitTypeOf(generator.finalDestination(dst), local);
941     }
942
943     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
944     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
945     if (dst == ignoredResult())
946         return 0;
947     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
948 }
949
950 // ------------------------------ TypeOfValueNode -----------------------------------
951
952 TypeOfValueNode::~TypeOfValueNode()
953 {
954     NodeReleaser::releaseAllNodes(this);
955 }
956
957 void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
958 {
959     releaser.release(m_expr);
960 }
961
962 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
963 {
964     if (dst == ignoredResult()) {
965         generator.emitNode(ignoredResult(), m_expr.get());
966         return 0;
967     }
968     RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
969     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
970 }
971
972 // ------------------------------ PrefixResolveNode ----------------------------------
973
974 RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
975 {
976     if (RegisterID* local = generator.registerFor(m_ident)) {
977         if (generator.isLocalConstant(m_ident)) {
978             if (dst == ignoredResult())
979                 return 0;
980             RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
981             return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
982         }
983
984         emitPreIncOrDec(generator, local, m_operator);
985         return generator.moveToDestinationIfNeeded(dst, local);
986     }
987
988     int index = 0;
989     size_t depth = 0;
990     JSObject* globalObject = 0;
991     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
992         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
993         emitPreIncOrDec(generator, propDst.get(), m_operator);
994         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
995         return generator.moveToDestinationIfNeeded(dst, propDst.get());
996     }
997
998     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
999     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1000     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
1001     emitPreIncOrDec(generator, propDst.get(), m_operator);
1002     generator.emitPutById(base.get(), m_ident, propDst.get());
1003     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1004 }
1005
1006 // ------------------------------ PrefixBracketNode ----------------------------------
1007
1008 PrefixBracketNode::~PrefixBracketNode()
1009 {
1010     NodeReleaser::releaseAllNodes(this);
1011 }
1012
1013 void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
1014 {
1015     releaser.release(m_base);
1016     releaser.release(m_subscript);
1017 }
1018
1019 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1020 {
1021     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1022     RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1023     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1024
1025     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1026     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1027     if (m_operator == OpPlusPlus)
1028         generator.emitPreInc(value);
1029     else
1030         generator.emitPreDec(value);
1031     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1032     generator.emitPutByVal(base.get(), property.get(), value);
1033     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1034 }
1035
1036 // ------------------------------ PrefixDotNode ----------------------------------
1037
1038 PrefixDotNode::~PrefixDotNode()
1039 {
1040     NodeReleaser::releaseAllNodes(this);
1041 }
1042
1043 void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
1044 {
1045     releaser.release(m_base);
1046 }
1047
1048 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1049 {
1050     RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1051     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1052
1053     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1054     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
1055     if (m_operator == OpPlusPlus)
1056         generator.emitPreInc(value);
1057     else
1058         generator.emitPreDec(value);
1059     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1060     generator.emitPutById(base.get(), m_ident, value);
1061     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1062 }
1063
1064 // ------------------------------ PrefixErrorNode -----------------------------------
1065
1066 PrefixErrorNode::~PrefixErrorNode()
1067 {
1068     NodeReleaser::releaseAllNodes(this);
1069 }
1070
1071 void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
1072 {
1073     releaser.release(m_expr);
1074 }
1075
1076 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1077 {
1078     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.");
1079 }
1080
1081 // ------------------------------ Unary Operation Nodes -----------------------------------
1082
1083 UnaryOpNode::~UnaryOpNode()
1084 {
1085     NodeReleaser::releaseAllNodes(this);
1086 }
1087
1088 void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
1089 {
1090     releaser.release(m_expr);
1091 }
1092
1093 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1094 {
1095     RegisterID* src = generator.emitNode(m_expr.get());
1096     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src, m_expr->resultDescriptor());
1097 }
1098
1099 // ------------------------------ Binary Operation Nodes -----------------------------------
1100
1101 BinaryOpNode::~BinaryOpNode()
1102 {
1103     NodeReleaser::releaseAllNodes(this);
1104 }
1105
1106 void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
1107 {
1108     releaser.release(m_expr1);
1109     releaser.release(m_expr2);
1110 }
1111
1112 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1113 {
1114     OpcodeID opcodeID = this->opcodeID();
1115     if (opcodeID == op_neq) {
1116         if (m_expr1->isNull() || m_expr2->isNull()) {
1117             RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1118             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
1119         }
1120     }
1121
1122     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1123     RegisterID* src2 = generator.emitNode(m_expr2.get());
1124     return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1125 }
1126
1127 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1128 {
1129     if (m_expr1->isNull() || m_expr2->isNull()) {
1130         RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1131         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
1132     }
1133
1134     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1135     RegisterID* src2 = generator.emitNode(m_expr2.get());
1136     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1137 }
1138
1139 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1140 {
1141     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1142     RegisterID* src2 = generator.emitNode(m_expr2.get());
1143     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1144 }
1145
1146 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1147 {
1148     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1149     RegisterID* src2 = generator.emitNode(m_expr2.get());
1150     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
1151 }
1152
1153 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1154 {
1155     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1156     RegisterID* src2 = generator.emitNode(m_expr2.get());
1157     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1158     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1159 }
1160
1161 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1162 {
1163     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1164     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
1165
1166     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1167     RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
1168
1169     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1170     return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
1171 }
1172
1173 // ------------------------------ LogicalOpNode ----------------------------
1174
1175 LogicalOpNode::~LogicalOpNode()
1176 {
1177     NodeReleaser::releaseAllNodes(this);
1178 }
1179
1180 void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
1181 {
1182     releaser.release(m_expr1);
1183     releaser.release(m_expr2);
1184 }
1185
1186 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1187 {
1188     RefPtr<RegisterID> temp = generator.tempDestination(dst);
1189     RefPtr<Label> target = generator.newLabel();
1190     
1191     generator.emitNode(temp.get(), m_expr1.get());
1192     if (m_operator == OpLogicalAnd)
1193         generator.emitJumpIfFalse(temp.get(), target.get());
1194     else
1195         generator.emitJumpIfTrue(temp.get(), target.get());
1196     generator.emitNode(temp.get(), m_expr2.get());
1197     generator.emitLabel(target.get());
1198
1199     return generator.moveToDestinationIfNeeded(dst, temp.get());
1200 }
1201
1202 // ------------------------------ ConditionalNode ------------------------------
1203
1204 ConditionalNode::~ConditionalNode()
1205 {
1206     NodeReleaser::releaseAllNodes(this);
1207 }
1208
1209 void ConditionalNode::releaseNodes(NodeReleaser& releaser)
1210 {
1211     releaser.release(m_logical);
1212     releaser.release(m_expr1);
1213     releaser.release(m_expr2);
1214 }
1215
1216 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1217 {
1218     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1219     RefPtr<Label> beforeElse = generator.newLabel();
1220     RefPtr<Label> afterElse = generator.newLabel();
1221
1222     RegisterID* cond = generator.emitNode(m_logical.get());
1223     generator.emitJumpIfFalse(cond, beforeElse.get());
1224
1225     generator.emitNode(newDst.get(), m_expr1.get());
1226     generator.emitJump(afterElse.get());
1227
1228     generator.emitLabel(beforeElse.get());
1229     generator.emitNode(newDst.get(), m_expr2.get());
1230
1231     generator.emitLabel(afterElse.get());
1232
1233     return newDst.get();
1234 }
1235
1236 // ------------------------------ ReadModifyResolveNode -----------------------------------
1237
1238 ReadModifyResolveNode::~ReadModifyResolveNode()
1239 {
1240     NodeReleaser::releaseAllNodes(this);
1241 }
1242
1243 void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
1244 {
1245     releaser.release(m_right);
1246 }
1247
1248 // FIXME: should this be moved to be a method on BytecodeGenerator?
1249 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
1250 {
1251     OpcodeID opcodeID;
1252     switch (oper) {
1253         case OpMultEq:
1254             opcodeID = op_mul;
1255             break;
1256         case OpDivEq:
1257             opcodeID = op_div;
1258             break;
1259         case OpPlusEq:
1260             opcodeID = op_add;
1261             break;
1262         case OpMinusEq:
1263             opcodeID = op_sub;
1264             break;
1265         case OpLShift:
1266             opcodeID = op_lshift;
1267             break;
1268         case OpRShift:
1269             opcodeID = op_rshift;
1270             break;
1271         case OpURShift:
1272             opcodeID = op_urshift;
1273             break;
1274         case OpAndEq:
1275             opcodeID = op_bitand;
1276             break;
1277         case OpXOrEq:
1278             opcodeID = op_bitxor;
1279             break;
1280         case OpOrEq:
1281             opcodeID = op_bitor;
1282             break;
1283         case OpModEq:
1284             opcodeID = op_mod;
1285             break;
1286         default:
1287             ASSERT_NOT_REACHED();
1288             return dst;
1289     }
1290     
1291     return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1292 }
1293
1294 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1295 {
1296     if (RegisterID* local = generator.registerFor(m_ident)) {
1297         if (generator.isLocalConstant(m_ident)) {
1298             RegisterID* src2 = generator.emitNode(m_right.get());
1299             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1300         }
1301         
1302         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1303             RefPtr<RegisterID> result = generator.newTemporary();
1304             generator.emitMove(result.get(), local);
1305             RegisterID* src2 = generator.emitNode(m_right.get());
1306             emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1307             generator.emitMove(local, result.get());
1308             return generator.moveToDestinationIfNeeded(dst, result.get());
1309         }
1310         
1311         RegisterID* src2 = generator.emitNode(m_right.get());
1312         RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1313         return generator.moveToDestinationIfNeeded(dst, result);
1314     }
1315
1316     int index = 0;
1317     size_t depth = 0;
1318     JSObject* globalObject = 0;
1319     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1320         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1321         RegisterID* src2 = generator.emitNode(m_right.get());
1322         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1323         generator.emitPutScopedVar(depth, index, result, globalObject);
1324         return result;
1325     }
1326
1327     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1328     generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
1329     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1330     RegisterID* src2 = generator.emitNode(m_right.get());
1331     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1332     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1333     return generator.emitPutById(base.get(), m_ident, result);
1334 }
1335
1336 // ------------------------------ AssignResolveNode -----------------------------------
1337
1338 AssignResolveNode::~AssignResolveNode()
1339 {
1340     NodeReleaser::releaseAllNodes(this);
1341 }
1342
1343 void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
1344 {
1345     releaser.release(m_right);
1346 }
1347
1348 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1349 {
1350     if (RegisterID* local = generator.registerFor(m_ident)) {
1351         if (generator.isLocalConstant(m_ident))
1352             return generator.emitNode(dst, m_right.get());
1353         
1354         RegisterID* result = generator.emitNode(local, m_right.get());
1355         return generator.moveToDestinationIfNeeded(dst, result);
1356     }
1357
1358     int index = 0;
1359     size_t depth = 0;
1360     JSObject* globalObject = 0;
1361     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1362         if (dst == ignoredResult())
1363             dst = 0;
1364         RegisterID* value = generator.emitNode(dst, m_right.get());
1365         generator.emitPutScopedVar(depth, index, value, globalObject);
1366         return value;
1367     }
1368
1369     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1370     if (dst == ignoredResult())
1371         dst = 0;
1372     RegisterID* value = generator.emitNode(dst, m_right.get());
1373     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1374     return generator.emitPutById(base.get(), m_ident, value);
1375 }
1376
1377 // ------------------------------ AssignDotNode -----------------------------------
1378
1379 AssignDotNode::~AssignDotNode()
1380 {
1381     NodeReleaser::releaseAllNodes(this);
1382 }
1383
1384 void AssignDotNode::releaseNodes(NodeReleaser& releaser)
1385 {
1386     releaser.release(m_base);
1387     releaser.release(m_right);
1388 }
1389
1390 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1391 {
1392     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1393     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1394     RegisterID* result = generator.emitNode(value.get(), m_right.get());
1395     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1396     generator.emitPutById(base.get(), m_ident, result);
1397     return generator.moveToDestinationIfNeeded(dst, result);
1398 }
1399
1400 // ------------------------------ ReadModifyDotNode -----------------------------------
1401
1402 ReadModifyDotNode::~ReadModifyDotNode()
1403 {
1404     NodeReleaser::releaseAllNodes(this);
1405 }
1406
1407 void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
1408 {
1409     releaser.release(m_base);
1410     releaser.release(m_right);
1411 }
1412
1413 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1414 {
1415     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1416
1417     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1418     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1419     RegisterID* change = generator.emitNode(m_right.get());
1420     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1421
1422     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1423     return generator.emitPutById(base.get(), m_ident, updatedValue);
1424 }
1425
1426 // ------------------------------ AssignErrorNode -----------------------------------
1427
1428 AssignErrorNode::~AssignErrorNode()
1429 {
1430     NodeReleaser::releaseAllNodes(this);
1431 }
1432
1433 void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
1434 {
1435     releaser.release(m_left);
1436     releaser.release(m_right);
1437 }
1438
1439 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1440 {
1441     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1442 }
1443
1444 // ------------------------------ AssignBracketNode -----------------------------------
1445
1446 AssignBracketNode::~AssignBracketNode()
1447 {
1448     NodeReleaser::releaseAllNodes(this);
1449 }
1450
1451 void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
1452 {
1453     releaser.release(m_base);
1454     releaser.release(m_subscript);
1455     releaser.release(m_right);
1456 }
1457
1458 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1459 {
1460     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1461     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1462     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1463     RegisterID* result = generator.emitNode(value.get(), m_right.get());
1464
1465     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1466     generator.emitPutByVal(base.get(), property.get(), result);
1467     return generator.moveToDestinationIfNeeded(dst, result);
1468 }
1469
1470 // ------------------------------ ReadModifyBracketNode -----------------------------------
1471
1472 ReadModifyBracketNode::~ReadModifyBracketNode()
1473 {
1474     NodeReleaser::releaseAllNodes(this);
1475 }
1476
1477 void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
1478 {
1479     releaser.release(m_base);
1480     releaser.release(m_subscript);
1481     releaser.release(m_right);
1482 }
1483
1484 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1485 {
1486     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1487     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1488
1489     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1490     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1491     RegisterID* change = generator.emitNode(m_right.get());
1492     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1493
1494     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1495     generator.emitPutByVal(base.get(), property.get(), updatedValue);
1496
1497     return updatedValue;
1498 }
1499
1500 // ------------------------------ CommaNode ------------------------------------
1501
1502 CommaNode::~CommaNode()
1503 {
1504     NodeReleaser::releaseAllNodes(this);
1505 }
1506
1507 void CommaNode::releaseNodes(NodeReleaser& releaser)
1508 {
1509     releaser.release(m_expr1);
1510     releaser.release(m_expr2);
1511 }
1512
1513 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1514 {
1515     generator.emitNode(ignoredResult(), m_expr1.get());
1516     return generator.emitNode(dst, m_expr2.get());
1517 }
1518
1519 // ------------------------------ ConstDeclNode ------------------------------------
1520
1521 ConstDeclNode::~ConstDeclNode()
1522 {
1523     NodeReleaser::releaseAllNodes(this);
1524 }
1525
1526 void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
1527 {
1528     releaser.release(m_next);
1529     releaser.release(m_init);
1530 }
1531
1532 ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
1533     : ExpressionNode(globalData)
1534     , m_ident(ident)
1535     , m_init(init)
1536 {
1537 }
1538
1539 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1540 {
1541     if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1542         if (!m_init)
1543             return local;
1544
1545         return generator.emitNode(local, m_init.get());
1546     }
1547     
1548     // FIXME: While this code should only be hit in eval code, it will potentially
1549     // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1550     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1551     RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined());
1552     return generator.emitPutById(base.get(), m_ident, value);
1553 }
1554
1555 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1556 {
1557     RegisterID* result = 0;
1558     for (ConstDeclNode* n = this; n; n = n->m_next.get())
1559         result = n->emitCodeSingle(generator);
1560
1561     return result;
1562 }
1563
1564 // ------------------------------ ConstStatementNode -----------------------------
1565
1566 ConstStatementNode::~ConstStatementNode()
1567 {
1568     NodeReleaser::releaseAllNodes(this);
1569 }
1570
1571 void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
1572 {
1573     releaser.release(m_next);
1574 }
1575
1576 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1577 {
1578     return generator.emitNode(m_next.get());
1579 }
1580
1581 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1582
1583 static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
1584 {
1585     StatementVector::const_iterator end = statements.end();
1586     for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
1587         StatementNode* n = it->get();
1588         if (!n->isLoop())
1589             generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1590         generator.emitNode(dst, n);
1591     }
1592     return 0;
1593 }
1594
1595 // ------------------------------ BlockNode ------------------------------------
1596
1597 BlockNode::~BlockNode()
1598 {
1599     NodeReleaser::releaseAllNodes(this);
1600 }
1601
1602 void BlockNode::releaseNodes(NodeReleaser& releaser)
1603 {
1604     size_t size = m_children.size();
1605     for (size_t i = 0; i < size; ++i)
1606         releaser.release(m_children[i]);
1607 }
1608
1609 BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
1610     : StatementNode(globalData)
1611 {
1612     if (children)
1613         children->releaseContentsIntoVector(m_children);
1614 }
1615
1616 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1617 {
1618     return statementListEmitCode(m_children, generator, dst);
1619 }
1620
1621 // ------------------------------ EmptyStatementNode ---------------------------
1622
1623 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
1624 {
1625     return dst;
1626 }
1627
1628 // ------------------------------ DebuggerStatementNode ---------------------------
1629
1630 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1631 {
1632     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1633     return dst;
1634 }
1635
1636 // ------------------------------ ExprStatementNode ----------------------------
1637
1638 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1639 {
1640     ASSERT(m_expr);
1641     return generator.emitNode(dst, m_expr.get());
1642 }
1643
1644 // ------------------------------ VarStatementNode ----------------------------
1645
1646 VarStatementNode::~VarStatementNode()
1647 {
1648     NodeReleaser::releaseAllNodes(this);
1649 }
1650
1651 void VarStatementNode::releaseNodes(NodeReleaser& releaser)
1652 {
1653     releaser.release(m_expr);
1654 }
1655
1656 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1657 {
1658     ASSERT(m_expr);
1659     return generator.emitNode(m_expr.get());
1660 }
1661
1662 // ------------------------------ IfNode ---------------------------------------
1663
1664 IfNode::~IfNode()
1665 {
1666     NodeReleaser::releaseAllNodes(this);
1667 }
1668
1669 void IfNode::releaseNodes(NodeReleaser& releaser)
1670 {
1671     releaser.release(m_condition);
1672     releaser.release(m_ifBlock);
1673 }
1674
1675 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1676 {
1677     RefPtr<Label> afterThen = generator.newLabel();
1678
1679     RegisterID* cond = generator.emitNode(m_condition.get());
1680     generator.emitJumpIfFalse(cond, afterThen.get());
1681
1682     if (!m_ifBlock->isBlock())
1683         generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1684
1685     generator.emitNode(dst, m_ifBlock.get());
1686     generator.emitLabel(afterThen.get());
1687
1688     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1689     return 0;
1690 }
1691
1692 // ------------------------------ IfElseNode ---------------------------------------
1693
1694 IfElseNode::~IfElseNode()
1695 {
1696     NodeReleaser::releaseAllNodes(this);
1697 }
1698
1699 void IfElseNode::releaseNodes(NodeReleaser& releaser)
1700 {
1701     releaser.release(m_elseBlock);
1702     IfNode::releaseNodes(releaser);
1703 }
1704
1705 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1706 {
1707     RefPtr<Label> beforeElse = generator.newLabel();
1708     RefPtr<Label> afterElse = generator.newLabel();
1709
1710     RegisterID* cond = generator.emitNode(m_condition.get());
1711     generator.emitJumpIfFalse(cond, beforeElse.get());
1712
1713     if (!m_ifBlock->isBlock())
1714         generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1715
1716     generator.emitNode(dst, m_ifBlock.get());
1717     generator.emitJump(afterElse.get());
1718
1719     generator.emitLabel(beforeElse.get());
1720
1721     if (!m_elseBlock->isBlock())
1722         generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
1723
1724     generator.emitNode(dst, m_elseBlock.get());
1725
1726     generator.emitLabel(afterElse.get());
1727
1728     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1729     return 0;
1730 }
1731
1732 // ------------------------------ DoWhileNode ----------------------------------
1733
1734 DoWhileNode::~DoWhileNode()
1735 {
1736     NodeReleaser::releaseAllNodes(this);
1737 }
1738
1739 void DoWhileNode::releaseNodes(NodeReleaser& releaser)
1740 {
1741     releaser.release(m_statement);
1742     releaser.release(m_expr);
1743 }
1744
1745 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1746 {
1747     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1748
1749     RefPtr<Label> topOfLoop = generator.newLabel();
1750     generator.emitLabel(topOfLoop.get());
1751
1752     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1753
1754     if (!m_statement->isBlock())
1755         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1756         
1757     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1758
1759     generator.emitLabel(scope->continueTarget());
1760     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1761     RegisterID* cond = generator.emitNode(m_expr.get());
1762     generator.emitJumpIfTrue(cond, topOfLoop.get());
1763
1764     generator.emitLabel(scope->breakTarget());
1765     return result.get();
1766 }
1767
1768 // ------------------------------ WhileNode ------------------------------------
1769
1770 WhileNode::~WhileNode()
1771 {
1772     NodeReleaser::releaseAllNodes(this);
1773 }
1774
1775 void WhileNode::releaseNodes(NodeReleaser& releaser)
1776 {
1777     releaser.release(m_expr);
1778     releaser.release(m_statement);
1779 }
1780
1781 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1782 {
1783     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1784
1785     generator.emitJump(scope->continueTarget());
1786
1787     RefPtr<Label> topOfLoop = generator.newLabel();
1788     generator.emitLabel(topOfLoop.get());
1789
1790     if (!m_statement->isBlock())
1791         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1792  
1793     generator.emitNode(dst, m_statement.get());
1794
1795     generator.emitLabel(scope->continueTarget());
1796     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1797     RegisterID* cond = generator.emitNode(m_expr.get());
1798     generator.emitJumpIfTrue(cond, topOfLoop.get());
1799
1800     generator.emitLabel(scope->breakTarget());
1801     
1802     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1803     return 0;
1804 }
1805
1806 // ------------------------------ ForNode --------------------------------------
1807
1808 ForNode::~ForNode()
1809 {
1810     NodeReleaser::releaseAllNodes(this);
1811 }
1812
1813 void ForNode::releaseNodes(NodeReleaser& releaser)
1814 {
1815     releaser.release(m_expr1);
1816     releaser.release(m_expr2);
1817     releaser.release(m_expr3);
1818     releaser.release(m_statement);
1819 }
1820
1821 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1822 {
1823     if (dst == ignoredResult())
1824         dst = 0;
1825
1826     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1827
1828     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1829
1830     if (m_expr1)
1831         generator.emitNode(ignoredResult(), m_expr1.get());
1832
1833     RefPtr<Label> condition = generator.newLabel();
1834     generator.emitJump(condition.get());
1835
1836     RefPtr<Label> topOfLoop = generator.newLabel();
1837     generator.emitLabel(topOfLoop.get());
1838
1839     if (!m_statement->isBlock())
1840         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1841     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1842
1843     generator.emitLabel(scope->continueTarget());
1844     if (m_expr3)
1845         generator.emitNode(ignoredResult(), m_expr3.get());
1846
1847     generator.emitLabel(condition.get());
1848     if (m_expr2) {
1849         RegisterID* cond = generator.emitNode(m_expr2.get());
1850         generator.emitJumpIfTrue(cond, topOfLoop.get());
1851     } else
1852         generator.emitJump(topOfLoop.get());
1853
1854     generator.emitLabel(scope->breakTarget());
1855     return result.get();
1856 }
1857
1858 // ------------------------------ ForInNode ------------------------------------
1859
1860 ForInNode::~ForInNode()
1861 {
1862     NodeReleaser::releaseAllNodes(this);
1863 }
1864
1865 void ForInNode::releaseNodes(NodeReleaser& releaser)
1866 {
1867     releaser.release(m_init);
1868     releaser.release(m_lexpr);
1869     releaser.release(m_expr);
1870     releaser.release(m_statement);
1871 }
1872
1873 ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1874     : StatementNode(globalData)
1875     , m_init(0L)
1876     , m_lexpr(l)
1877     , m_expr(expr)
1878     , m_statement(statement)
1879     , m_identIsVarDecl(false)
1880 {
1881 }
1882
1883 ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
1884     : StatementNode(globalData)
1885     , m_ident(ident)
1886     , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
1887     , m_expr(expr)
1888     , m_statement(statement)
1889     , m_identIsVarDecl(true)
1890 {
1891     if (in) {
1892         AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
1893         node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
1894         m_init = node;
1895     }
1896     // for( var foo = bar in baz )
1897 }
1898
1899 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1900 {
1901     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1902
1903     if (!m_lexpr->isLocation())
1904         return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1905
1906     RefPtr<Label> continueTarget = generator.newLabel(); 
1907
1908     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1909
1910     if (m_init)
1911         generator.emitNode(ignoredResult(), m_init.get());
1912     RegisterID* forInBase = generator.emitNode(m_expr.get());
1913     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1914     generator.emitJump(scope->continueTarget());
1915
1916     RefPtr<Label> loopStart = generator.newLabel();
1917     generator.emitLabel(loopStart.get());
1918
1919     RegisterID* propertyName;
1920     if (m_lexpr->isResolveNode()) {
1921         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1922         propertyName = generator.registerFor(ident);
1923         if (!propertyName) {
1924             propertyName = generator.newTemporary();
1925             RefPtr<RegisterID> protect = propertyName;
1926             RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1927
1928             generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1929             generator.emitPutById(base, ident, propertyName);
1930         }
1931     } else if (m_lexpr->isDotAccessorNode()) {
1932         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1933         const Identifier& ident = assignNode->identifier();
1934         propertyName = generator.newTemporary();
1935         RefPtr<RegisterID> protect = propertyName;
1936         RegisterID* base = generator.emitNode(assignNode->base());
1937
1938         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1939         generator.emitPutById(base, ident, propertyName);
1940     } else {
1941         ASSERT(m_lexpr->isBracketAccessorNode());
1942         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1943         propertyName = generator.newTemporary();
1944         RefPtr<RegisterID> protect = propertyName;
1945         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1946         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1947         
1948         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1949         generator.emitPutByVal(base.get(), subscript, propertyName);
1950     }   
1951
1952     if (!m_statement->isBlock())
1953         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1954     generator.emitNode(dst, m_statement.get());
1955
1956     generator.emitLabel(scope->continueTarget());
1957     generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1958     generator.emitLabel(scope->breakTarget());
1959     return dst;
1960 }
1961
1962 // ------------------------------ ContinueNode ---------------------------------
1963
1964 // ECMA 12.7
1965 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1966 {
1967     LabelScope* scope = generator.continueTarget(m_ident);
1968
1969     if (!scope)
1970         return m_ident.isEmpty()
1971             ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1972             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1973
1974     generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1975     return dst;
1976 }
1977
1978 // ------------------------------ BreakNode ------------------------------------
1979
1980 // ECMA 12.8
1981 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1982 {
1983     LabelScope* scope = generator.breakTarget(m_ident);
1984     
1985     if (!scope)
1986         return m_ident.isEmpty()
1987             ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1988             : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1989
1990     generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1991     return dst;
1992 }
1993
1994 // ------------------------------ ReturnNode -----------------------------------
1995
1996 ReturnNode::~ReturnNode()
1997 {
1998     NodeReleaser::releaseAllNodes(this);
1999 }
2000
2001 void ReturnNode::releaseNodes(NodeReleaser& releaser)
2002 {
2003     releaser.release(m_value);
2004 }
2005
2006 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2007 {
2008     if (generator.codeType() != FunctionCode)
2009         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
2010
2011     if (dst == ignoredResult())
2012         dst = 0;
2013     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
2014     if (generator.scopeDepth()) {
2015         RefPtr<Label> l0 = generator.newLabel();
2016         generator.emitJumpScopes(l0.get(), 0);
2017         generator.emitLabel(l0.get());
2018     }
2019     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2020     return generator.emitReturn(r0);
2021 }
2022
2023 // ------------------------------ WithNode -------------------------------------
2024
2025 WithNode::~WithNode()
2026 {
2027     NodeReleaser::releaseAllNodes(this);
2028 }
2029
2030 void WithNode::releaseNodes(NodeReleaser& releaser)
2031 {
2032     releaser.release(m_expr);
2033     releaser.release(m_statement);
2034 }
2035
2036 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2037 {
2038     RefPtr<RegisterID> scope = generator.emitNode(m_expr.get()); // scope must be protected until popped
2039     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2040     generator.emitPushScope(scope.get());
2041     RegisterID* result = generator.emitNode(dst, m_statement.get());
2042     generator.emitPopScope();
2043     return result;
2044 }
2045
2046 // ------------------------------ CaseClauseNode --------------------------------
2047
2048 CaseClauseNode::~CaseClauseNode()
2049 {
2050     NodeReleaser::releaseAllNodes(this);
2051 }
2052
2053 void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2054 {
2055     releaser.release(m_expr);
2056 }
2057
2058 // ------------------------------ ClauseListNode --------------------------------
2059
2060 ClauseListNode::~ClauseListNode()
2061 {
2062     NodeReleaser::releaseAllNodes(this);
2063 }
2064
2065 void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2066 {
2067     releaser.release(m_clause);
2068     releaser.release(m_next);
2069 }
2070
2071 // ------------------------------ CaseBlockNode --------------------------------
2072
2073 CaseBlockNode::~CaseBlockNode()
2074 {
2075     NodeReleaser::releaseAllNodes(this);
2076 }
2077
2078 void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2079 {
2080     releaser.release(m_list1);
2081     releaser.release(m_defaultClause);
2082     releaser.release(m_list2);
2083 }
2084
2085 enum SwitchKind { 
2086     SwitchUnset = 0,
2087     SwitchNumber = 1, 
2088     SwitchString = 2, 
2089     SwitchNeither = 3 
2090 };
2091
2092 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2093 {
2094     for (; list; list = list->getNext()) {
2095         ExpressionNode* clauseExpression = list->getClause()->expr();
2096         literalVector.append(clauseExpression);
2097         if (clauseExpression->isNumber()) {
2098             double value = static_cast<NumberNode*>(clauseExpression)->value();
2099             if ((typeForTable & ~SwitchNumber) || !JSImmediate::from(value)) {
2100                 typeForTable = SwitchNeither;
2101                 break;
2102             }
2103             int32_t intVal = static_cast<int32_t>(value);
2104             ASSERT(intVal == value);
2105             if (intVal < min_num)
2106                 min_num = intVal;
2107             if (intVal > max_num)
2108                 max_num = intVal;
2109             typeForTable = SwitchNumber;
2110             continue;
2111         }
2112         if (clauseExpression->isString()) {
2113             if (typeForTable & ~SwitchString) {
2114                 typeForTable = SwitchNeither;
2115                 break;
2116             }
2117             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2118             if (singleCharacterSwitch &= value.size() == 1) {
2119                 int32_t intVal = value.rep()->data()[0];
2120                 if (intVal < min_num)
2121                     min_num = intVal;
2122                 if (intVal > max_num)
2123                     max_num = intVal;
2124             }
2125             typeForTable = SwitchString;
2126             continue;
2127         }
2128         typeForTable = SwitchNeither;
2129         break;        
2130     }
2131 }
2132     
2133 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2134 {
2135     SwitchKind typeForTable = SwitchUnset;
2136     bool singleCharacterSwitch = true;
2137     
2138     processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2139     processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2140     
2141     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2142         return SwitchInfo::SwitchNone;
2143     
2144     if (typeForTable == SwitchNumber) {
2145         int32_t range = max_num - min_num;
2146         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2147             return SwitchInfo::SwitchImmediate;
2148         return SwitchInfo::SwitchNone;
2149     } 
2150     
2151     ASSERT(typeForTable == SwitchString);
2152     
2153     if (singleCharacterSwitch) {
2154         int32_t range = max_num - min_num;
2155         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2156             return SwitchInfo::SwitchCharacter;
2157     }
2158
2159     return SwitchInfo::SwitchString;
2160 }
2161
2162 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2163 {
2164     RefPtr<Label> defaultLabel;
2165     Vector<RefPtr<Label>, 8> labelVector;
2166     Vector<ExpressionNode*, 8> literalVector;
2167     int32_t min_num = std::numeric_limits<int32_t>::max();
2168     int32_t max_num = std::numeric_limits<int32_t>::min();
2169     SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2170
2171     if (switchType != SwitchInfo::SwitchNone) {
2172         // Prepare the various labels
2173         for (uint32_t i = 0; i < literalVector.size(); i++)
2174             labelVector.append(generator.newLabel());
2175         defaultLabel = generator.newLabel();
2176         generator.beginSwitch(switchExpression, switchType);
2177     } else {
2178         // Setup jumps
2179         for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2180             RefPtr<RegisterID> clauseVal = generator.newTemporary();
2181             generator.emitNode(clauseVal.get(), list->getClause()->expr());
2182             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2183             labelVector.append(generator.newLabel());
2184             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2185         }
2186         
2187         for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2188             RefPtr<RegisterID> clauseVal = generator.newTemporary();
2189             generator.emitNode(clauseVal.get(), list->getClause()->expr());
2190             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2191             labelVector.append(generator.newLabel());
2192             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2193         }
2194         defaultLabel = generator.newLabel();
2195         generator.emitJump(defaultLabel.get());
2196     }
2197
2198     RegisterID* result = 0;
2199
2200     size_t i = 0;
2201     for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2202         generator.emitLabel(labelVector[i++].get());
2203         result = statementListEmitCode(list->getClause()->children(), generator, dst);
2204     }
2205
2206     if (m_defaultClause) {
2207         generator.emitLabel(defaultLabel.get());
2208         result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2209     }
2210
2211     for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2212         generator.emitLabel(labelVector[i++].get());
2213         result = statementListEmitCode(list->getClause()->children(), generator, dst);
2214     }
2215     if (!m_defaultClause)
2216         generator.emitLabel(defaultLabel.get());
2217
2218     ASSERT(i == labelVector.size());
2219     if (switchType != SwitchInfo::SwitchNone) {
2220         ASSERT(labelVector.size() == literalVector.size());
2221         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2222     }
2223     return result;
2224 }
2225
2226 // ------------------------------ SwitchNode -----------------------------------
2227
2228 SwitchNode::~SwitchNode()
2229 {
2230     NodeReleaser::releaseAllNodes(this);
2231 }
2232
2233 void SwitchNode::releaseNodes(NodeReleaser& releaser)
2234 {
2235     releaser.release(m_expr);
2236     releaser.release(m_block);
2237 }
2238
2239 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2240 {
2241     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2242
2243     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2244     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2245
2246     generator.emitLabel(scope->breakTarget());
2247     return r1;
2248 }
2249
2250 // ------------------------------ LabelNode ------------------------------------
2251
2252 LabelNode::~LabelNode()
2253 {
2254     NodeReleaser::releaseAllNodes(this);
2255 }
2256
2257 void LabelNode::releaseNodes(NodeReleaser& releaser)
2258 {
2259     releaser.release(m_statement);
2260 }
2261
2262 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2263 {
2264     if (generator.breakTarget(m_name))
2265         return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
2266
2267     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2268     RegisterID* r0 = generator.emitNode(dst, m_statement.get());
2269
2270     generator.emitLabel(scope->breakTarget());
2271     return r0;
2272 }
2273
2274 // ------------------------------ ThrowNode ------------------------------------
2275
2276 ThrowNode::~ThrowNode()
2277 {
2278     NodeReleaser::releaseAllNodes(this);
2279 }
2280
2281 void ThrowNode::releaseNodes(NodeReleaser& releaser)
2282 {
2283     releaser.release(m_expr);
2284 }
2285
2286 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2287 {
2288     if (dst == ignoredResult())
2289         dst = 0;
2290     RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
2291     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2292     generator.emitThrow(expr.get());
2293     return dst;
2294 }
2295
2296 // ------------------------------ TryNode --------------------------------------
2297
2298 TryNode::~TryNode()
2299 {
2300     NodeReleaser::releaseAllNodes(this);
2301 }
2302
2303 void TryNode::releaseNodes(NodeReleaser& releaser)
2304 {
2305     releaser.release(m_tryBlock);
2306     releaser.release(m_catchBlock);
2307     releaser.release(m_finallyBlock);
2308 }
2309
2310 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2311 {
2312     RefPtr<Label> tryStartLabel = generator.newLabel();
2313     RefPtr<Label> tryEndLabel = generator.newLabel();
2314     RefPtr<Label> finallyStart;
2315     RefPtr<RegisterID> finallyReturnAddr;
2316     if (m_finallyBlock) {
2317         finallyStart = generator.newLabel();
2318         finallyReturnAddr = generator.newTemporary();
2319         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2320     }
2321     generator.emitLabel(tryStartLabel.get());
2322     generator.emitNode(dst, m_tryBlock.get());
2323     generator.emitLabel(tryEndLabel.get());
2324
2325     if (m_catchBlock) {
2326         RefPtr<Label> handlerEndLabel = generator.newLabel();
2327         generator.emitJump(handlerEndLabel.get());
2328         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2329         generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2330         generator.emitNode(dst, m_catchBlock.get());
2331         generator.emitPopScope();
2332         generator.emitLabel(handlerEndLabel.get());
2333     }
2334
2335     if (m_finallyBlock) {
2336         generator.popFinallyContext();
2337         // there may be important registers live at the time we jump
2338         // to a finally block (such as for a return or throw) so we
2339         // ref the highest register ever used as a conservative
2340         // approach to not clobbering anything important
2341         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2342         RefPtr<Label> finallyEndLabel = generator.newLabel();
2343         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2344         // Use a label to record the subtle fact that sret will return to the
2345         // next instruction. sret is the only way to jump without an explicit label.
2346         generator.emitLabel(generator.newLabel().get());
2347         generator.emitJump(finallyEndLabel.get());
2348
2349         // Finally block for exception path
2350         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2351         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2352         // Use a label to record the subtle fact that sret will return to the
2353         // next instruction. sret is the only way to jump without an explicit label.
2354         generator.emitLabel(generator.newLabel().get());
2355         generator.emitThrow(tempExceptionRegister.get());
2356
2357         // emit the finally block itself
2358         generator.emitLabel(finallyStart.get());
2359         generator.emitNode(dst, m_finallyBlock.get());
2360         generator.emitSubroutineReturn(finallyReturnAddr.get());
2361
2362         generator.emitLabel(finallyEndLabel.get());
2363     }
2364
2365     return dst;
2366 }
2367
2368 // ------------------------------ ParameterNode -----------------------------
2369
2370 ParameterNode::~ParameterNode()
2371 {
2372     NodeReleaser::releaseAllNodes(this);
2373 }
2374
2375 void ParameterNode::releaseNodes(NodeReleaser& releaser)
2376 {
2377     releaser.release(m_next);
2378 }
2379
2380 // -----------------------------ScopeNodeData ---------------------------
2381
2382 ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2383     : m_numConstants(numConstants)
2384 {
2385     if (varStack)
2386         m_varStack = *varStack;
2387     if (funcStack)
2388         m_functionStack = *funcStack;
2389     if (children)
2390         children->releaseContentsIntoVector(m_children);
2391 }
2392
2393 // ------------------------------ ScopeNode -----------------------------
2394
2395 ScopeNode::ScopeNode(JSGlobalData* globalData)
2396     : StatementNode(globalData)
2397     , m_features(NoFeatures)
2398 {
2399 #if ENABLE(OPCODE_SAMPLING)
2400     globalData->interpreter->sampler()->notifyOfScope(this);
2401 #endif
2402 }
2403
2404 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2405     : StatementNode(globalData)
2406     , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2407     , m_features(features)
2408     , m_source(source)
2409 {
2410 #if ENABLE(OPCODE_SAMPLING)
2411     globalData->interpreter->sampler()->notifyOfScope(this);
2412 #endif
2413 }
2414
2415 ScopeNode::~ScopeNode()
2416 {
2417     NodeReleaser::releaseAllNodes(this);
2418 }
2419
2420 void ScopeNode::releaseNodes(NodeReleaser& releaser)
2421 {
2422     if (!m_data)
2423         return;
2424     size_t size = m_data->m_children.size();
2425     for (size_t i = 0; i < size; ++i)
2426         releaser.release(m_data->m_children[i]);
2427 }
2428
2429 // ------------------------------ ProgramNode -----------------------------
2430
2431 ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2432     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2433 {
2434 }
2435
2436 ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2437 {
2438     return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2439 }
2440
2441 // ------------------------------ EvalNode -----------------------------
2442
2443 EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2444     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2445 {
2446 }
2447
2448 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2449 {
2450     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2451
2452     RefPtr<RegisterID> dstRegister = generator.newTemporary();
2453     generator.emitLoad(dstRegister.get(), jsUndefined());
2454     statementListEmitCode(children(), generator, dstRegister.get());
2455
2456     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2457     generator.emitEnd(dstRegister.get());
2458     return 0;
2459 }
2460
2461 void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2462 {
2463     ScopeChain scopeChain(scopeChainNode);
2464     JSGlobalObject* globalObject = scopeChain.globalObject();
2465
2466     m_code.set(new EvalCodeBlock(this, globalObject, source().provider()));
2467
2468     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get());
2469     generator.generate();
2470
2471     // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2472     // so the entire ScopeNodeData cannot be destoyed.
2473     children().clear();
2474 }
2475
2476 EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2477 {
2478     return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2479 }
2480
2481 // ------------------------------ FunctionBodyNode -----------------------------
2482
2483 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2484     : ScopeNode(globalData)
2485     , m_parameters(0)
2486     , m_parameterCount(0)
2487     , m_refCount(0)
2488 {
2489 }
2490
2491 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2492     : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2493     , m_parameters(0)
2494     , m_parameterCount(0)
2495     , m_refCount(0)
2496 {
2497 }
2498
2499 FunctionBodyNode::~FunctionBodyNode()
2500 {
2501     ASSERT(!m_refCount);
2502     fastFree(m_parameters);
2503 }
2504
2505 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2506 {
2507     Vector<Identifier> parameters;
2508     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2509         parameters.append(parameter->ident());
2510     size_t count = parameters.size();
2511
2512     setSource(source);
2513     finishParsing(parameters.releaseBuffer(), count);
2514 }
2515
2516 void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2517 {
2518     ASSERT(!source().isNull());
2519     m_parameters = parameters;
2520     m_parameterCount = parameterCount;
2521 }
2522
2523 void FunctionBodyNode::mark()
2524 {
2525     if (m_code)
2526         m_code->mark();
2527 }
2528
2529 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2530 {
2531     return new FunctionBodyNode(globalData);
2532 }
2533
2534 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2535 {
2536     return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2537 }
2538
2539 void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2540 {
2541     // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2542     // calling Parser::parse<FunctionBodyNode>().   
2543     if (!data())
2544         scopeChainNode->globalData->parser->reparse(scopeChainNode->globalData, this);
2545     ASSERT(data());
2546
2547     ScopeChain scopeChain(scopeChainNode);
2548     JSGlobalObject* globalObject = scopeChain.globalObject();
2549
2550     m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2551
2552     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable, m_code.get());
2553     generator.generate();
2554
2555     destroyData();
2556 }
2557
2558 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2559 {
2560     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2561     statementListEmitCode(children(), generator, ignoredResult());
2562     if (!children().size() || !children().last()->isReturnNode()) {
2563         RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2564         generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2565         generator.emitReturn(r0);
2566     }
2567     return 0;
2568 }
2569
2570 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2571 {
2572     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2573
2574     RefPtr<RegisterID> dstRegister = generator.newTemporary();
2575     generator.emitLoad(dstRegister.get(), jsUndefined());
2576     statementListEmitCode(children(), generator, dstRegister.get());
2577
2578     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2579     generator.emitEnd(dstRegister.get());
2580     return 0;
2581 }
2582
2583 void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2584 {
2585     ScopeChain scopeChain(scopeChainNode);
2586     JSGlobalObject* globalObject = scopeChain.globalObject();
2587     
2588     m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2589     
2590     BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2591     generator.generate();
2592
2593     destroyData();
2594 }
2595
2596 UString FunctionBodyNode::paramString() const
2597 {
2598     UString s("");
2599     for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2600         if (!s.isEmpty())
2601             s += ", ";
2602         s += parameters()[pos].ustring();
2603     }
2604
2605     return s;
2606 }
2607
2608 Identifier* FunctionBodyNode::copyParameters()
2609 {
2610     Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2611     VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2612     return parameters;
2613 }
2614
2615 // ------------------------------ FuncDeclNode ---------------------------------
2616
2617 FuncDeclNode::~FuncDeclNode()
2618 {
2619     NodeReleaser::releaseAllNodes(this);
2620 }
2621
2622 void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2623 {
2624     releaser.release(m_parameter);
2625     releaser.release(m_body);
2626 }
2627
2628 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2629 {
2630     return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2631 }
2632
2633 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
2634 {
2635     if (dst == ignoredResult())
2636         dst = 0;
2637     return dst;
2638 }
2639
2640 // ------------------------------ FuncExprNode ---------------------------------
2641
2642 FuncExprNode::~FuncExprNode()
2643 {
2644     NodeReleaser::releaseAllNodes(this);
2645 }
2646
2647 void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2648 {
2649     releaser.release(m_parameter);
2650     releaser.release(m_body);
2651 }
2652
2653 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2654 {
2655     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2656 }
2657
2658 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2659 {
2660     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2661
2662     /* 
2663         The Identifier in a FunctionExpression can be referenced from inside
2664         the FunctionExpression's FunctionBody to allow the function to call
2665         itself recursively. However, unlike in a FunctionDeclaration, the
2666         Identifier in a FunctionExpression cannot be referenced from and
2667         does not affect the scope enclosing the FunctionExpression.
2668      */
2669
2670     if (!m_ident.isNull()) {
2671         JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2672         func->scope().push(functionScopeObject);
2673     }
2674
2675     return func;
2676 }
2677
2678 } // namespace JSC