source: webkit/trunk/JavaScriptCore/parser/Nodes.cpp@ 39910

Last change on this file since 39910 was 39910, checked in by [email protected], 16 years ago

Bug 22903: REGRESSION (r36267): visiting this site reliably crashes WebKit nightly

Reviewed by Cameron Zwarich

EvalCodeBlock's do not reference the functions that are declared inside the eval
code, this means that simply marking the EvalCodeBlock through the global object
is insufficient to mark the declared functions. This patch corrects this by
explicitly marking the CodeBlocks of all the functions declared in the cached
EvalNode.

  • Property svn:eol-style set to native
File size: 95.2 KB
Line 
1/*
2* Copyright (C) 1999-2002 Harri Porten ([email protected])
3* Copyright (C) 2001 Peter Kelly ([email protected])
4* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5* Copyright (C) 2007 Cameron Zwarich ([email protected])
6* Copyright (C) 2007 Maks Orlovich
7* Copyright (C) 2007 Eric Seidel <[email protected]>
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::unknown(), 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::unknown(), 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::unknown(), 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::unknown(), 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::unknown(), 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::unknown(), 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::unknown(), 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 if (generator.scopeDepth()) {
2019 RefPtr<Label> l0 = generator.newLabel();
2020 generator.emitJumpScopes(l0.get(), 0);
2021 generator.emitLabel(l0.get());
2022 }
2023 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2024 return generator.emitReturn(r0);
2025}
2026
2027// ------------------------------ WithNode -------------------------------------
2028
2029WithNode::~WithNode()
2030{
2031 NodeReleaser::releaseAllNodes(this);
2032}
2033
2034void WithNode::releaseNodes(NodeReleaser& releaser)
2035{
2036 releaser.release(m_expr);
2037 releaser.release(m_statement);
2038}
2039
2040RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2041{
2042 RefPtr<RegisterID> scope = generator.newTemporary();
2043 generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
2044 generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2045 generator.emitPushScope(scope.get());
2046 RegisterID* result = generator.emitNode(dst, m_statement.get());
2047 generator.emitPopScope();
2048 return result;
2049}
2050
2051// ------------------------------ CaseClauseNode --------------------------------
2052
2053CaseClauseNode::~CaseClauseNode()
2054{
2055 NodeReleaser::releaseAllNodes(this);
2056}
2057
2058void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2059{
2060 releaser.release(m_expr);
2061}
2062
2063// ------------------------------ ClauseListNode --------------------------------
2064
2065ClauseListNode::~ClauseListNode()
2066{
2067 NodeReleaser::releaseAllNodes(this);
2068}
2069
2070void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2071{
2072 releaser.release(m_clause);
2073 releaser.release(m_next);
2074}
2075
2076// ------------------------------ CaseBlockNode --------------------------------
2077
2078CaseBlockNode::~CaseBlockNode()
2079{
2080 NodeReleaser::releaseAllNodes(this);
2081}
2082
2083void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2084{
2085 releaser.release(m_list1);
2086 releaser.release(m_defaultClause);
2087 releaser.release(m_list2);
2088}
2089
2090enum SwitchKind {
2091 SwitchUnset = 0,
2092 SwitchNumber = 1,
2093 SwitchString = 2,
2094 SwitchNeither = 3
2095};
2096
2097static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2098{
2099 for (; list; list = list->getNext()) {
2100 ExpressionNode* clauseExpression = list->getClause()->expr();
2101 literalVector.append(clauseExpression);
2102 if (clauseExpression->isNumber()) {
2103 double value = static_cast<NumberNode*>(clauseExpression)->value();
2104 JSValuePtr jsValue = JSValuePtr::makeInt32Fast(static_cast<int32_t>(value));
2105 if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue->getInt32Fast() != value)) {
2106 typeForTable = SwitchNeither;
2107 break;
2108 }
2109 int32_t intVal = static_cast<int32_t>(value);
2110 ASSERT(intVal == value);
2111 if (intVal < min_num)
2112 min_num = intVal;
2113 if (intVal > max_num)
2114 max_num = intVal;
2115 typeForTable = SwitchNumber;
2116 continue;
2117 }
2118 if (clauseExpression->isString()) {
2119 if (typeForTable & ~SwitchString) {
2120 typeForTable = SwitchNeither;
2121 break;
2122 }
2123 const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2124 if (singleCharacterSwitch &= value.size() == 1) {
2125 int32_t intVal = value.rep()->data()[0];
2126 if (intVal < min_num)
2127 min_num = intVal;
2128 if (intVal > max_num)
2129 max_num = intVal;
2130 }
2131 typeForTable = SwitchString;
2132 continue;
2133 }
2134 typeForTable = SwitchNeither;
2135 break;
2136 }
2137}
2138
2139SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2140{
2141 SwitchKind typeForTable = SwitchUnset;
2142 bool singleCharacterSwitch = true;
2143
2144 processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2145 processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2146
2147 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2148 return SwitchInfo::SwitchNone;
2149
2150 if (typeForTable == SwitchNumber) {
2151 int32_t range = max_num - min_num;
2152 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2153 return SwitchInfo::SwitchImmediate;
2154 return SwitchInfo::SwitchNone;
2155 }
2156
2157 ASSERT(typeForTable == SwitchString);
2158
2159 if (singleCharacterSwitch) {
2160 int32_t range = max_num - min_num;
2161 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2162 return SwitchInfo::SwitchCharacter;
2163 }
2164
2165 return SwitchInfo::SwitchString;
2166}
2167
2168RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2169{
2170 RefPtr<Label> defaultLabel;
2171 Vector<RefPtr<Label>, 8> labelVector;
2172 Vector<ExpressionNode*, 8> literalVector;
2173 int32_t min_num = std::numeric_limits<int32_t>::max();
2174 int32_t max_num = std::numeric_limits<int32_t>::min();
2175 SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2176
2177 if (switchType != SwitchInfo::SwitchNone) {
2178 // Prepare the various labels
2179 for (uint32_t i = 0; i < literalVector.size(); i++)
2180 labelVector.append(generator.newLabel());
2181 defaultLabel = generator.newLabel();
2182 generator.beginSwitch(switchExpression, switchType);
2183 } else {
2184 // Setup jumps
2185 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2186 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2187 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2188 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2189 labelVector.append(generator.newLabel());
2190 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2191 }
2192
2193 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2194 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2195 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2196 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2197 labelVector.append(generator.newLabel());
2198 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2199 }
2200 defaultLabel = generator.newLabel();
2201 generator.emitJump(defaultLabel.get());
2202 }
2203
2204 RegisterID* result = 0;
2205
2206 size_t i = 0;
2207 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2208 generator.emitLabel(labelVector[i++].get());
2209 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2210 }
2211
2212 if (m_defaultClause) {
2213 generator.emitLabel(defaultLabel.get());
2214 result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2215 }
2216
2217 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2218 generator.emitLabel(labelVector[i++].get());
2219 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2220 }
2221 if (!m_defaultClause)
2222 generator.emitLabel(defaultLabel.get());
2223
2224 ASSERT(i == labelVector.size());
2225 if (switchType != SwitchInfo::SwitchNone) {
2226 ASSERT(labelVector.size() == literalVector.size());
2227 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2228 }
2229 return result;
2230}
2231
2232// ------------------------------ SwitchNode -----------------------------------
2233
2234SwitchNode::~SwitchNode()
2235{
2236 NodeReleaser::releaseAllNodes(this);
2237}
2238
2239void SwitchNode::releaseNodes(NodeReleaser& releaser)
2240{
2241 releaser.release(m_expr);
2242 releaser.release(m_block);
2243}
2244
2245RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2246{
2247 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2248
2249 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2250 RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2251
2252 generator.emitLabel(scope->breakTarget());
2253 return r1;
2254}
2255
2256// ------------------------------ LabelNode ------------------------------------
2257
2258LabelNode::~LabelNode()
2259{
2260 NodeReleaser::releaseAllNodes(this);
2261}
2262
2263void LabelNode::releaseNodes(NodeReleaser& releaser)
2264{
2265 releaser.release(m_statement);
2266}
2267
2268RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2269{
2270 if (generator.breakTarget(m_name))
2271 return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
2272
2273 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2274 RegisterID* r0 = generator.emitNode(dst, m_statement.get());
2275
2276 generator.emitLabel(scope->breakTarget());
2277 return r0;
2278}
2279
2280// ------------------------------ ThrowNode ------------------------------------
2281
2282ThrowNode::~ThrowNode()
2283{
2284 NodeReleaser::releaseAllNodes(this);
2285}
2286
2287void ThrowNode::releaseNodes(NodeReleaser& releaser)
2288{
2289 releaser.release(m_expr);
2290}
2291
2292RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2293{
2294 if (dst == generator.ignoredResult())
2295 dst = 0;
2296 RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
2297 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2298 generator.emitThrow(expr.get());
2299 return dst;
2300}
2301
2302// ------------------------------ TryNode --------------------------------------
2303
2304TryNode::~TryNode()
2305{
2306 NodeReleaser::releaseAllNodes(this);
2307}
2308
2309void TryNode::releaseNodes(NodeReleaser& releaser)
2310{
2311 releaser.release(m_tryBlock);
2312 releaser.release(m_catchBlock);
2313 releaser.release(m_finallyBlock);
2314}
2315
2316RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2317{
2318 RefPtr<Label> tryStartLabel = generator.newLabel();
2319 RefPtr<Label> tryEndLabel = generator.newLabel();
2320 RefPtr<Label> finallyStart;
2321 RefPtr<RegisterID> finallyReturnAddr;
2322 if (m_finallyBlock) {
2323 finallyStart = generator.newLabel();
2324 finallyReturnAddr = generator.newTemporary();
2325 generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2326 }
2327 generator.emitLabel(tryStartLabel.get());
2328 generator.emitNode(dst, m_tryBlock.get());
2329 generator.emitLabel(tryEndLabel.get());
2330
2331 if (m_catchBlock) {
2332 RefPtr<Label> handlerEndLabel = generator.newLabel();
2333 generator.emitJump(handlerEndLabel.get());
2334 RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2335 if (m_catchHasEval) {
2336 RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
2337 generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
2338 generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
2339 generator.emitPushScope(exceptionRegister.get());
2340 } else
2341 generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2342 generator.emitNode(dst, m_catchBlock.get());
2343 generator.emitPopScope();
2344 generator.emitLabel(handlerEndLabel.get());
2345 }
2346
2347 if (m_finallyBlock) {
2348 generator.popFinallyContext();
2349 // there may be important registers live at the time we jump
2350 // to a finally block (such as for a return or throw) so we
2351 // ref the highest register ever used as a conservative
2352 // approach to not clobbering anything important
2353 RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2354 RefPtr<Label> finallyEndLabel = generator.newLabel();
2355 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2356 // Use a label to record the subtle fact that sret will return to the
2357 // next instruction. sret is the only way to jump without an explicit label.
2358 generator.emitLabel(generator.newLabel().get());
2359 generator.emitJump(finallyEndLabel.get());
2360
2361 // Finally block for exception path
2362 RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2363 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2364 // Use a label to record the subtle fact that sret will return to the
2365 // next instruction. sret is the only way to jump without an explicit label.
2366 generator.emitLabel(generator.newLabel().get());
2367 generator.emitThrow(tempExceptionRegister.get());
2368
2369 // emit the finally block itself
2370 generator.emitLabel(finallyStart.get());
2371 generator.emitNode(dst, m_finallyBlock.get());
2372 generator.emitSubroutineReturn(finallyReturnAddr.get());
2373
2374 generator.emitLabel(finallyEndLabel.get());
2375 }
2376
2377 return dst;
2378}
2379
2380// ------------------------------ ParameterNode -----------------------------
2381
2382ParameterNode::~ParameterNode()
2383{
2384 NodeReleaser::releaseAllNodes(this);
2385}
2386
2387void ParameterNode::releaseNodes(NodeReleaser& releaser)
2388{
2389 releaser.release(m_next);
2390}
2391
2392// -----------------------------ScopeNodeData ---------------------------
2393
2394ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2395 : m_numConstants(numConstants)
2396{
2397 if (varStack)
2398 m_varStack = *varStack;
2399 if (funcStack)
2400 m_functionStack = *funcStack;
2401 if (children)
2402 children->releaseContentsIntoVector(m_children);
2403}
2404
2405void ScopeNodeData::mark()
2406{
2407 FunctionStack::iterator end = m_functionStack.end();
2408 for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) {
2409 FunctionBodyNode* body = (*ptr)->body();
2410 if (!body->isGenerated())
2411 continue;
2412 body->generatedBytecode().mark();
2413 }
2414}
2415
2416// ------------------------------ ScopeNode -----------------------------
2417
2418ScopeNode::ScopeNode(JSGlobalData* globalData)
2419 : StatementNode(globalData)
2420 , m_features(NoFeatures)
2421{
2422#if ENABLE(OPCODE_SAMPLING)
2423 globalData->interpreter->sampler()->notifyOfScope(this);
2424#endif
2425}
2426
2427ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2428 : StatementNode(globalData)
2429 , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2430 , m_features(features)
2431 , m_source(source)
2432{
2433#if ENABLE(OPCODE_SAMPLING)
2434 globalData->interpreter->sampler()->notifyOfScope(this);
2435#endif
2436}
2437
2438ScopeNode::~ScopeNode()
2439{
2440 NodeReleaser::releaseAllNodes(this);
2441}
2442
2443void ScopeNode::releaseNodes(NodeReleaser& releaser)
2444{
2445 if (!m_data)
2446 return;
2447 size_t size = m_data->m_children.size();
2448 for (size_t i = 0; i < size; ++i)
2449 releaser.release(m_data->m_children[i]);
2450}
2451
2452// ------------------------------ ProgramNode -----------------------------
2453
2454ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2455 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2456{
2457}
2458
2459ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2460{
2461 return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2462}
2463
2464RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2465{
2466 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2467
2468 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2469 generator.emitLoad(dstRegister.get(), jsUndefined());
2470 statementListEmitCode(children(), generator, dstRegister.get());
2471
2472 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2473 generator.emitEnd(dstRegister.get());
2474 return 0;
2475}
2476
2477void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2478{
2479 ScopeChain scopeChain(scopeChainNode);
2480 JSGlobalObject* globalObject = scopeChain.globalObject();
2481
2482 m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2483
2484 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2485 generator.generate();
2486
2487 destroyData();
2488}
2489
2490// ------------------------------ EvalNode -----------------------------
2491
2492EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2493 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2494{
2495}
2496
2497EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2498{
2499 return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2500}
2501
2502RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2503{
2504 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2505
2506 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2507 generator.emitLoad(dstRegister.get(), jsUndefined());
2508 statementListEmitCode(children(), generator, dstRegister.get());
2509
2510 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2511 generator.emitEnd(dstRegister.get());
2512 return 0;
2513}
2514
2515void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2516{
2517 ScopeChain scopeChain(scopeChainNode);
2518 JSGlobalObject* globalObject = scopeChain.globalObject();
2519
2520 m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
2521
2522 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2523 generator.generate();
2524
2525 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2526 // so the entire ScopeNodeData cannot be destoyed.
2527 children().clear();
2528}
2529
2530EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
2531{
2532 ASSERT(!m_code);
2533
2534 ScopeChain scopeChain(scopeChainNode);
2535 JSGlobalObject* globalObject = scopeChain.globalObject();
2536
2537 m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
2538
2539 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2540 generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
2541 generator.generate();
2542
2543 return *m_code;
2544}
2545
2546void EvalNode::mark()
2547{
2548 // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
2549 data()->mark();
2550}
2551
2552// ------------------------------ FunctionBodyNode -----------------------------
2553
2554FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2555 : ScopeNode(globalData)
2556 , m_parameters(0)
2557 , m_parameterCount(0)
2558 , m_refCount(0)
2559{
2560}
2561
2562FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2563 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2564 , m_parameters(0)
2565 , m_parameterCount(0)
2566 , m_refCount(0)
2567{
2568}
2569
2570FunctionBodyNode::~FunctionBodyNode()
2571{
2572 ASSERT(!m_refCount);
2573 fastFree(m_parameters);
2574}
2575
2576void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2577{
2578 Vector<Identifier> parameters;
2579 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2580 parameters.append(parameter->ident());
2581 size_t count = parameters.size();
2582
2583 setSource(source);
2584 finishParsing(parameters.releaseBuffer(), count);
2585}
2586
2587void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2588{
2589 ASSERT(!source().isNull());
2590 m_parameters = parameters;
2591 m_parameterCount = parameterCount;
2592}
2593
2594void FunctionBodyNode::mark()
2595{
2596 if (m_code)
2597 m_code->mark();
2598}
2599
2600FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2601{
2602 return new FunctionBodyNode(globalData);
2603}
2604
2605FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2606{
2607 return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2608}
2609
2610void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2611{
2612 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2613 // calling Parser::parse<FunctionBodyNode>().
2614 if (!data())
2615 scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this);
2616 ASSERT(data());
2617
2618 ScopeChain scopeChain(scopeChainNode);
2619 JSGlobalObject* globalObject = scopeChain.globalObject();
2620
2621 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2622
2623 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2624 generator.generate();
2625
2626 destroyData();
2627}
2628
2629CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
2630{
2631 ASSERT(!m_code);
2632
2633 ScopeChain scopeChain(scopeChainNode);
2634 JSGlobalObject* globalObject = scopeChain.globalObject();
2635
2636 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2637
2638 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2639 generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
2640 generator.generate();
2641
2642 return *m_code;
2643}
2644
2645RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2646{
2647 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2648 statementListEmitCode(children(), generator, generator.ignoredResult());
2649 if (!children().size() || !children().last()->isReturnNode()) {
2650 RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2651 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2652 generator.emitReturn(r0);
2653 }
2654 return 0;
2655}
2656
2657UString FunctionBodyNode::paramString() const
2658{
2659 UString s("");
2660 for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2661 if (!s.isEmpty())
2662 s += ", ";
2663 s += parameters()[pos].ustring();
2664 }
2665
2666 return s;
2667}
2668
2669Identifier* FunctionBodyNode::copyParameters()
2670{
2671 Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2672 VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2673 return parameters;
2674}
2675
2676// ------------------------------ FuncDeclNode ---------------------------------
2677
2678FuncDeclNode::~FuncDeclNode()
2679{
2680 NodeReleaser::releaseAllNodes(this);
2681}
2682
2683void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2684{
2685 releaser.release(m_parameter);
2686 releaser.release(m_body);
2687}
2688
2689JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2690{
2691 return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2692}
2693
2694RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2695{
2696 if (dst == generator.ignoredResult())
2697 dst = 0;
2698 return dst;
2699}
2700
2701// ------------------------------ FuncExprNode ---------------------------------
2702
2703FuncExprNode::~FuncExprNode()
2704{
2705 NodeReleaser::releaseAllNodes(this);
2706}
2707
2708void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2709{
2710 releaser.release(m_parameter);
2711 releaser.release(m_body);
2712}
2713
2714RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2715{
2716 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2717}
2718
2719JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2720{
2721 JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2722
2723 /*
2724 The Identifier in a FunctionExpression can be referenced from inside
2725 the FunctionExpression's FunctionBody to allow the function to call
2726 itself recursively. However, unlike in a FunctionDeclaration, the
2727 Identifier in a FunctionExpression cannot be referenced from and
2728 does not affect the scope enclosing the FunctionExpression.
2729 */
2730
2731 if (!m_ident.isNull()) {
2732 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2733 func->scope().push(functionScopeObject);
2734 }
2735
2736 return func;
2737}
2738
2739} // namespace JSC
Note: See TracBrowser for help on using the repository browser.