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

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

2008-12-12 Cameron Zwarich <[email protected]>

Reviewed by Oliver Hunt.

Bug 22835: Crash during bytecode generation when comparing to null
<https://bugs.webkit.org/show_bug.cgi?id=22835>
<rdar://problem/6286749>

Change the special cases in bytecode generation for comparison to null
to use tempDestination().

JavaScriptCore:

  • parser/Nodes.cpp: (JSC::BinaryOpNode::emitBytecode): (JSC::EqualNode::emitBytecode):

LayoutTests:

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