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