2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
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.
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.
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.
29 #include "BytecodeGenerator.h"
30 #include "CallFrame.h"
31 #include "JSGlobalObject.h"
32 #include "JSStaticScopeObject.h"
33 #include "LabelScope.h"
35 #include "PropertyNameArray.h"
36 #include "RegExpObject.h"
37 #include "SamplingTool.h"
40 #include "Operations.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>
53 static void substitute(UString
& string
, const UString
& substring
) JSC_FAST_CALL
;
55 // ------------------------------ NodeReleaser --------------------------------
57 class NodeReleaser
: Noncopyable
{
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
);
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
); }
74 void adopt(PassRefPtr
<ParserRefCounted
>);
75 void adoptFunctionBodyNode(RefPtr
<FunctionBodyNode
>&);
77 typedef Vector
<RefPtr
<ParserRefCounted
> > NodeReleaseVector
;
78 OwnPtr
<NodeReleaseVector
> m_vector
;
81 void NodeReleaser::releaseAllNodes(ParserRefCounted
* root
)
84 NodeReleaser releaser
;
85 root
->releaseNodes(releaser
);
86 if (!releaser
.m_vector
)
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
);
97 void NodeReleaser::adopt(PassRefPtr
<ParserRefCounted
> node
)
100 if (!node
->hasOneRef())
103 m_vector
.set(new NodeReleaseVector
);
104 m_vector
->append(node
);
107 void NodeReleaser::adoptFunctionBodyNode(RefPtr
<FunctionBodyNode
>& functionBodyNode
)
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());
119 // ------------------------------ ParserRefCounted -----------------------------------------
122 static RefCountedLeakCounter
parserRefCountedCounter("JSC::Node");
125 ParserRefCounted::ParserRefCounted(JSGlobalData
* globalData
)
126 : m_globalData(globalData
)
129 parserRefCountedCounter
.increment();
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));
137 ParserRefCounted::~ParserRefCounted()
140 parserRefCountedCounter
.decrement();
144 void ParserRefCounted::releaseNodes(NodeReleaser
&)
148 void ParserRefCounted::ref()
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));
160 ASSERT(!m_globalData
->newParserObjects
|| !m_globalData
->newParserObjects
->contains(this));
162 if (!m_globalData
->parserObjectExtraRefCounts
)
163 m_globalData
->parserObjectExtraRefCounts
= new HashCountedSet
<ParserRefCounted
*>;
164 m_globalData
->parserObjectExtraRefCounts
->add(this);
167 void ParserRefCounted::deref()
169 ASSERT(!m_globalData
->newParserObjects
|| !m_globalData
->newParserObjects
->contains(this));
171 if (!m_globalData
->parserObjectExtraRefCounts
) {
176 HashCountedSet
<ParserRefCounted
*>::iterator it
= m_globalData
->parserObjectExtraRefCounts
->find(this);
177 if (it
== m_globalData
->parserObjectExtraRefCounts
->end())
180 m_globalData
->parserObjectExtraRefCounts
->remove(it
);
183 bool ParserRefCounted::hasOneRef()
185 if (m_globalData
->newParserObjects
&& m_globalData
->newParserObjects
->contains(this)) {
186 ASSERT(!m_globalData
->parserObjectExtraRefCounts
|| !m_globalData
->parserObjectExtraRefCounts
->contains(this));
190 ASSERT(!m_globalData
->newParserObjects
|| !m_globalData
->newParserObjects
->contains(this));
192 if (!m_globalData
->parserObjectExtraRefCounts
)
195 return !m_globalData
->parserObjectExtraRefCounts
->contains(this);
198 void ParserRefCounted::deleteNewObjects(JSGlobalData
* globalData
)
200 if (!globalData
->newParserObjects
)
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
));
208 deleteAllValues(*globalData
->newParserObjects
);
209 delete globalData
->newParserObjects
;
210 globalData
->newParserObjects
= 0;
213 // ------------------------------ Node --------------------------------
215 Node::Node(JSGlobalData
* globalData
)
216 : ParserRefCounted(globalData
)
218 m_line
= globalData
->lexer
->lineNo();
221 // ------------------------------ ThrowableExpressionData --------------------------------
223 static void substitute(UString
& string
, const UString
& substring
)
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));
233 RegisterID
* ThrowableExpressionData::emitThrowError(BytecodeGenerator
& generator
, ErrorType e
, const char* msg
)
235 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
236 RegisterID
* exception
= generator
.emitNewError(generator
.newTemporary(), e
, jsString(generator
.globalData(), msg
));
237 generator
.emitThrow(exception
);
241 RegisterID
* ThrowableExpressionData::emitThrowError(BytecodeGenerator
& generator
, ErrorType e
, const char* msg
, const Identifier
& label
)
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
);
251 // ------------------------------ StatementNode --------------------------------
253 StatementNode::StatementNode(JSGlobalData
* globalData
)
259 void StatementNode::setLoc(int firstLine
, int lastLine
)
262 m_lastLine
= lastLine
;
265 // ------------------------------ SourceElements --------------------------------
267 void SourceElements::append(PassRefPtr
<StatementNode
> statement
)
269 if (statement
->isEmptyStatement())
272 m_statements
.append(statement
);
275 // ------------------------------ NullNode -------------------------------------
277 RegisterID
* NullNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
279 if (dst
== generator
.ignoredResult())
281 return generator
.emitLoad(dst
, jsNull());
284 // ------------------------------ BooleanNode ----------------------------------
286 RegisterID
* BooleanNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
288 if (dst
== generator
.ignoredResult())
290 return generator
.emitLoad(dst
, m_value
);
293 // ------------------------------ NumberNode -----------------------------------
295 RegisterID
* NumberNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
297 if (dst
== generator
.ignoredResult())
299 return generator
.emitLoad(dst
, m_double
);
302 // ------------------------------ StringNode -----------------------------------
304 RegisterID
* StringNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
306 if (dst
== generator
.ignoredResult())
308 return generator
.emitLoad(dst
, m_value
);
311 // ------------------------------ RegExpNode -----------------------------------
313 RegisterID
* RegExpNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
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())
320 return generator
.emitNewRegExp(generator
.finalDestination(dst
), regExp
.get());
323 // ------------------------------ ThisNode -------------------------------------
325 RegisterID
* ThisNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
327 if (dst
== generator
.ignoredResult())
329 return generator
.moveToDestinationIfNeeded(dst
, generator
.thisRegister());
332 // ------------------------------ ResolveNode ----------------------------------
334 bool ResolveNode::isPure(BytecodeGenerator
& generator
) const
336 return generator
.isLocal(m_ident
);
339 RegisterID
* ResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
341 if (RegisterID
* local
= generator
.registerFor(m_ident
)) {
342 if (dst
== generator
.ignoredResult())
344 return generator
.moveToDestinationIfNeeded(dst
, local
);
347 generator
.emitExpressionInfo(m_startOffset
+ m_ident
.size(), m_ident
.size(), 0);
348 return generator
.emitResolve(generator
.finalDestination(dst
), m_ident
);
351 // ------------------------------ ElementNode ------------------------------------
353 ElementNode::~ElementNode()
355 NodeReleaser::releaseAllNodes(this);
358 void ElementNode::releaseNodes(NodeReleaser
& releaser
)
360 releaser
.release(m_next
);
361 releaser
.release(m_node
);
364 // ------------------------------ ArrayNode ------------------------------------
366 ArrayNode::~ArrayNode()
368 NodeReleaser::releaseAllNodes(this);
371 void ArrayNode::releaseNodes(NodeReleaser
& releaser
)
373 releaser
.release(m_element
);
376 RegisterID
* ArrayNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
378 // FIXME: Should we put all of this code into emitNewArray?
381 ElementNode
* firstPutElement
;
382 for (firstPutElement
= m_element
.get(); firstPutElement
; firstPutElement
= firstPutElement
->next()) {
383 if (firstPutElement
->elision())
388 if (!firstPutElement
&& !m_elision
)
389 return generator
.emitNewArray(generator
.finalDestination(dst
), m_element
.get());
391 RefPtr
<RegisterID
> array
= generator
.emitNewArray(generator
.tempDestination(dst
), m_element
.get());
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
);
400 RegisterID
* value
= generator
.emitLoad(0, jsNumber(generator
.globalData(), m_elision
+ length
));
401 generator
.emitPutById(array
.get(), generator
.propertyNames().length
, value
);
404 return generator
.moveToDestinationIfNeeded(dst
, array
.get());
407 // ------------------------------ PropertyNode ----------------------------
409 PropertyNode::~PropertyNode()
411 NodeReleaser::releaseAllNodes(this);
414 void PropertyNode::releaseNodes(NodeReleaser
& releaser
)
416 releaser
.release(m_assign
);
419 // ------------------------------ ObjectLiteralNode ----------------------------
421 ObjectLiteralNode::~ObjectLiteralNode()
423 NodeReleaser::releaseAllNodes(this);
426 void ObjectLiteralNode::releaseNodes(NodeReleaser
& releaser
)
428 releaser
.release(m_list
);
431 RegisterID
* ObjectLiteralNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
434 if (dst
== generator
.ignoredResult())
436 return generator
.emitNewObject(generator
.finalDestination(dst
));
438 return generator
.emitNode(dst
, m_list
.get());
441 // ------------------------------ PropertyListNode -----------------------------
443 PropertyListNode::~PropertyListNode()
445 NodeReleaser::releaseAllNodes(this);
448 void PropertyListNode::releaseNodes(NodeReleaser
& releaser
)
450 releaser
.release(m_node
);
451 releaser
.release(m_next
);
454 RegisterID
* PropertyListNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
456 RefPtr
<RegisterID
> newObj
= generator
.tempDestination(dst
);
458 generator
.emitNewObject(newObj
.get());
460 for (PropertyListNode
* p
= this; p
; p
= p
->m_next
.get()) {
461 RegisterID
* value
= generator
.emitNode(p
->m_node
->m_assign
.get());
463 switch (p
->m_node
->m_type
) {
464 case PropertyNode::Constant
: {
465 generator
.emitPutById(newObj
.get(), p
->m_node
->name(), value
);
468 case PropertyNode::Getter
: {
469 generator
.emitPutGetter(newObj
.get(), p
->m_node
->name(), value
);
472 case PropertyNode::Setter
: {
473 generator
.emitPutSetter(newObj
.get(), p
->m_node
->name(), value
);
477 ASSERT_NOT_REACHED();
481 return generator
.moveToDestinationIfNeeded(dst
, newObj
.get());
484 // ------------------------------ BracketAccessorNode --------------------------------
486 BracketAccessorNode::~BracketAccessorNode()
488 NodeReleaser::releaseAllNodes(this);
491 void BracketAccessorNode::releaseNodes(NodeReleaser
& releaser
)
493 releaser
.release(m_base
);
494 releaser
.release(m_subscript
);
497 RegisterID
* BracketAccessorNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
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
);
505 // ------------------------------ DotAccessorNode --------------------------------
507 DotAccessorNode::~DotAccessorNode()
509 NodeReleaser::releaseAllNodes(this);
512 void DotAccessorNode::releaseNodes(NodeReleaser
& releaser
)
514 releaser
.release(m_base
);
517 RegisterID
* DotAccessorNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
519 RegisterID
* base
= generator
.emitNode(m_base
.get());
520 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
521 return generator
.emitGetById(generator
.finalDestination(dst
), base
, m_ident
);
524 // ------------------------------ ArgumentListNode -----------------------------
526 ArgumentListNode::~ArgumentListNode()
528 NodeReleaser::releaseAllNodes(this);
531 void ArgumentListNode::releaseNodes(NodeReleaser
& releaser
)
533 releaser
.release(m_next
);
534 releaser
.release(m_expr
);
537 RegisterID
* ArgumentListNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
540 return generator
.emitNode(dst
, m_expr
.get());
543 // ------------------------------ ArgumentsNode -----------------------------
545 ArgumentsNode::~ArgumentsNode()
547 NodeReleaser::releaseAllNodes(this);
550 void ArgumentsNode::releaseNodes(NodeReleaser
& releaser
)
552 releaser
.release(m_listNode
);
555 // ------------------------------ NewExprNode ----------------------------------
557 NewExprNode::~NewExprNode()
559 NodeReleaser::releaseAllNodes(this);
562 void NewExprNode::releaseNodes(NodeReleaser
& releaser
)
564 releaser
.release(m_expr
);
565 releaser
.release(m_args
);
568 RegisterID
* NewExprNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
570 RefPtr
<RegisterID
> func
= generator
.emitNode(m_expr
.get());
571 return generator
.emitConstruct(generator
.finalDestination(dst
), func
.get(), m_args
.get(), divot(), startOffset(), endOffset());
574 // ------------------------------ EvalFunctionCallNode ----------------------------------
576 EvalFunctionCallNode::~EvalFunctionCallNode()
578 NodeReleaser::releaseAllNodes(this);
581 void EvalFunctionCallNode::releaseNodes(NodeReleaser
& releaser
)
583 releaser
.release(m_args
);
586 RegisterID
* EvalFunctionCallNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
588 RefPtr
<RegisterID
> func
= generator
.tempDestination(dst
);
589 RefPtr
<RegisterID
> thisRegister
= generator
.newTemporary();
590 generator
.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
591 generator
.emitResolveWithBase(thisRegister
.get(), func
.get(), generator
.propertyNames().eval
);
592 return generator
.emitCallEval(generator
.finalDestination(dst
, func
.get()), func
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
595 // ------------------------------ FunctionCallValueNode ----------------------------------
597 FunctionCallValueNode::~FunctionCallValueNode()
599 NodeReleaser::releaseAllNodes(this);
602 void FunctionCallValueNode::releaseNodes(NodeReleaser
& releaser
)
604 releaser
.release(m_expr
);
605 releaser
.release(m_args
);
608 RegisterID
* FunctionCallValueNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
610 RefPtr
<RegisterID
> func
= generator
.emitNode(m_expr
.get());
611 RefPtr
<RegisterID
> thisRegister
= generator
.emitLoad(generator
.newTemporary(), jsNull());
612 return generator
.emitCall(generator
.finalDestination(dst
, func
.get()), func
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
615 // ------------------------------ FunctionCallResolveNode ----------------------------------
617 FunctionCallResolveNode::~FunctionCallResolveNode()
619 NodeReleaser::releaseAllNodes(this);
622 void FunctionCallResolveNode::releaseNodes(NodeReleaser
& releaser
)
624 releaser
.release(m_args
);
627 RegisterID
* FunctionCallResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
629 if (RefPtr
<RegisterID
> local
= generator
.registerFor(m_ident
)) {
630 RefPtr
<RegisterID
> thisRegister
= generator
.emitLoad(generator
.newTemporary(), jsNull());
631 return generator
.emitCall(generator
.finalDestination(dst
, thisRegister
.get()), local
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
636 JSObject
* globalObject
= 0;
637 if (generator
.findScopedProperty(m_ident
, index
, depth
, false, globalObject
) && index
!= missingSymbolMarker()) {
638 RefPtr
<RegisterID
> func
= generator
.emitGetScopedVar(generator
.newTemporary(), depth
, index
, globalObject
);
639 RefPtr
<RegisterID
> thisRegister
= generator
.emitLoad(generator
.newTemporary(), jsNull());
640 return generator
.emitCall(generator
.finalDestination(dst
, func
.get()), func
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
643 RefPtr
<RegisterID
> func
= generator
.tempDestination(dst
);
644 RefPtr
<RegisterID
> thisRegister
= generator
.newTemporary();
645 int identifierStart
= divot() - startOffset();
646 generator
.emitExpressionInfo(identifierStart
+ m_ident
.size(), m_ident
.size(), 0);
647 generator
.emitResolveFunction(thisRegister
.get(), func
.get(), m_ident
);
648 return generator
.emitCall(generator
.finalDestination(dst
, func
.get()), func
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
651 // ------------------------------ FunctionCallBracketNode ----------------------------------
653 FunctionCallBracketNode::~FunctionCallBracketNode()
655 NodeReleaser::releaseAllNodes(this);
658 void FunctionCallBracketNode::releaseNodes(NodeReleaser
& releaser
)
660 releaser
.release(m_base
);
661 releaser
.release(m_subscript
);
662 releaser
.release(m_args
);
665 RegisterID
* FunctionCallBracketNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
667 RefPtr
<RegisterID
> base
= generator
.emitNode(m_base
.get());
668 RegisterID
* property
= generator
.emitNode(m_subscript
.get());
669 generator
.emitExpressionInfo(divot() - m_subexpressionDivotOffset
, startOffset() - m_subexpressionDivotOffset
, m_subexpressionEndOffset
);
670 RefPtr
<RegisterID
> function
= generator
.emitGetByVal(generator
.tempDestination(dst
), base
.get(), property
);
671 RefPtr
<RegisterID
> thisRegister
= generator
.emitMove(generator
.newTemporary(), base
.get());
672 return generator
.emitCall(generator
.finalDestination(dst
, function
.get()), function
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
675 // ------------------------------ FunctionCallDotNode ----------------------------------
677 FunctionCallDotNode::~FunctionCallDotNode()
679 NodeReleaser::releaseAllNodes(this);
682 void FunctionCallDotNode::releaseNodes(NodeReleaser
& releaser
)
684 releaser
.release(m_base
);
685 releaser
.release(m_args
);
688 RegisterID
* FunctionCallDotNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
690 RefPtr
<RegisterID
> base
= generator
.emitNode(m_base
.get());
691 generator
.emitExpressionInfo(divot() - m_subexpressionDivotOffset
, startOffset() - m_subexpressionDivotOffset
, m_subexpressionEndOffset
);
692 RefPtr
<RegisterID
> function
= generator
.emitGetById(generator
.tempDestination(dst
), base
.get(), m_ident
);
693 RefPtr
<RegisterID
> thisRegister
= generator
.emitMove(generator
.newTemporary(), base
.get());
694 return generator
.emitCall(generator
.finalDestination(dst
, function
.get()), function
.get(), thisRegister
.get(), m_args
.get(), divot(), startOffset(), endOffset());
697 // ------------------------------ PostfixResolveNode ----------------------------------
699 static RegisterID
* emitPreIncOrDec(BytecodeGenerator
& generator
, RegisterID
* srcDst
, Operator oper
)
701 return (oper
== OpPlusPlus
) ? generator
.emitPreInc(srcDst
) : generator
.emitPreDec(srcDst
);
704 static RegisterID
* emitPostIncOrDec(BytecodeGenerator
& generator
, RegisterID
* dst
, RegisterID
* srcDst
, Operator oper
)
706 return (oper
== OpPlusPlus
) ? generator
.emitPostInc(dst
, srcDst
) : generator
.emitPostDec(dst
, srcDst
);
709 RegisterID
* PostfixResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
711 if (RegisterID
* local
= generator
.registerFor(m_ident
)) {
712 if (generator
.isLocalConstant(m_ident
)) {
713 if (dst
== generator
.ignoredResult())
715 return generator
.emitToJSNumber(generator
.finalDestination(dst
), local
);
718 if (dst
== generator
.ignoredResult())
719 return emitPreIncOrDec(generator
, local
, m_operator
);
720 return emitPostIncOrDec(generator
, generator
.finalDestination(dst
), local
, m_operator
);
725 JSObject
* globalObject
= 0;
726 if (generator
.findScopedProperty(m_ident
, index
, depth
, true, globalObject
) && index
!= missingSymbolMarker()) {
727 RefPtr
<RegisterID
> value
= generator
.emitGetScopedVar(generator
.newTemporary(), depth
, index
, globalObject
);
728 RegisterID
* oldValue
;
729 if (dst
== generator
.ignoredResult()) {
731 emitPreIncOrDec(generator
, value
.get(), m_operator
);
733 oldValue
= emitPostIncOrDec(generator
, generator
.finalDestination(dst
), value
.get(), m_operator
);
735 generator
.emitPutScopedVar(depth
, index
, value
.get(), globalObject
);
739 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
740 RefPtr
<RegisterID
> value
= generator
.newTemporary();
741 RefPtr
<RegisterID
> base
= generator
.emitResolveWithBase(generator
.newTemporary(), value
.get(), m_ident
);
742 RegisterID
* oldValue
;
743 if (dst
== generator
.ignoredResult()) {
745 emitPreIncOrDec(generator
, value
.get(), m_operator
);
747 oldValue
= emitPostIncOrDec(generator
, generator
.finalDestination(dst
), value
.get(), m_operator
);
749 generator
.emitPutById(base
.get(), m_ident
, value
.get());
753 // ------------------------------ PostfixBracketNode ----------------------------------
755 PostfixBracketNode::~PostfixBracketNode()
757 NodeReleaser::releaseAllNodes(this);
760 void PostfixBracketNode::releaseNodes(NodeReleaser
& releaser
)
762 releaser
.release(m_base
);
763 releaser
.release(m_subscript
);
766 RegisterID
* PostfixBracketNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
768 RefPtr
<RegisterID
> base
= generator
.emitNode(m_base
.get());
769 RefPtr
<RegisterID
> property
= generator
.emitNode(m_subscript
.get());
771 generator
.emitExpressionInfo(divot() - m_subexpressionDivotOffset
, startOffset() - m_subexpressionDivotOffset
, m_subexpressionEndOffset
);
772 RefPtr
<RegisterID
> value
= generator
.emitGetByVal(generator
.newTemporary(), base
.get(), property
.get());
773 RegisterID
* oldValue
;
774 if (dst
== generator
.ignoredResult()) {
776 if (m_operator
== OpPlusPlus
)
777 generator
.emitPreInc(value
.get());
779 generator
.emitPreDec(value
.get());
781 oldValue
= (m_operator
== OpPlusPlus
) ? generator
.emitPostInc(generator
.finalDestination(dst
), value
.get()) : generator
.emitPostDec(generator
.finalDestination(dst
), value
.get());
783 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
784 generator
.emitPutByVal(base
.get(), property
.get(), value
.get());
788 // ------------------------------ PostfixDotNode ----------------------------------
790 PostfixDotNode::~PostfixDotNode()
792 NodeReleaser::releaseAllNodes(this);
795 void PostfixDotNode::releaseNodes(NodeReleaser
& releaser
)
797 releaser
.release(m_base
);
800 RegisterID
* PostfixDotNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
802 RefPtr
<RegisterID
> base
= generator
.emitNode(m_base
.get());
804 generator
.emitExpressionInfo(divot() - m_subexpressionDivotOffset
, startOffset() - m_subexpressionDivotOffset
, m_subexpressionEndOffset
);
805 RefPtr
<RegisterID
> value
= generator
.emitGetById(generator
.newTemporary(), base
.get(), m_ident
);
806 RegisterID
* oldValue
;
807 if (dst
== generator
.ignoredResult()) {
809 if (m_operator
== OpPlusPlus
)
810 generator
.emitPreInc(value
.get());
812 generator
.emitPreDec(value
.get());
814 oldValue
= (m_operator
== OpPlusPlus
) ? generator
.emitPostInc(generator
.finalDestination(dst
), value
.get()) : generator
.emitPostDec(generator
.finalDestination(dst
), value
.get());
816 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
817 generator
.emitPutById(base
.get(), m_ident
, value
.get());
821 // ------------------------------ PostfixErrorNode -----------------------------------
823 PostfixErrorNode::~PostfixErrorNode()
825 NodeReleaser::releaseAllNodes(this);
828 void PostfixErrorNode::releaseNodes(NodeReleaser
& releaser
)
830 releaser
.release(m_expr
);
833 RegisterID
* PostfixErrorNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
835 return emitThrowError(generator
, ReferenceError
, m_operator
== OpPlusPlus
? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
838 // ------------------------------ DeleteResolveNode -----------------------------------
840 RegisterID
* DeleteResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
842 if (generator
.registerFor(m_ident
))
843 return generator
.emitUnexpectedLoad(generator
.finalDestination(dst
), false);
845 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
846 RegisterID
* base
= generator
.emitResolveBase(generator
.tempDestination(dst
), m_ident
);
847 return generator
.emitDeleteById(generator
.finalDestination(dst
, base
), base
, m_ident
);
850 // ------------------------------ DeleteBracketNode -----------------------------------
852 DeleteBracketNode::~DeleteBracketNode()
854 NodeReleaser::releaseAllNodes(this);
857 void DeleteBracketNode::releaseNodes(NodeReleaser
& releaser
)
859 releaser
.release(m_base
);
860 releaser
.release(m_subscript
);
863 RegisterID
* DeleteBracketNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
865 RefPtr
<RegisterID
> r0
= generator
.emitNode(m_base
.get());
866 RegisterID
* r1
= generator
.emitNode(m_subscript
.get());
868 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
869 return generator
.emitDeleteByVal(generator
.finalDestination(dst
), r0
.get(), r1
);
872 // ------------------------------ DeleteDotNode -----------------------------------
874 DeleteDotNode::~DeleteDotNode()
876 NodeReleaser::releaseAllNodes(this);
879 void DeleteDotNode::releaseNodes(NodeReleaser
& releaser
)
881 releaser
.release(m_base
);
884 RegisterID
* DeleteDotNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
886 RegisterID
* r0
= generator
.emitNode(m_base
.get());
888 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
889 return generator
.emitDeleteById(generator
.finalDestination(dst
), r0
, m_ident
);
892 // ------------------------------ DeleteValueNode -----------------------------------
894 DeleteValueNode::~DeleteValueNode()
896 NodeReleaser::releaseAllNodes(this);
899 void DeleteValueNode::releaseNodes(NodeReleaser
& releaser
)
901 releaser
.release(m_expr
);
904 RegisterID
* DeleteValueNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
906 generator
.emitNode(generator
.ignoredResult(), m_expr
.get());
908 // delete on a non-location expression ignores the value and returns true
909 return generator
.emitUnexpectedLoad(generator
.finalDestination(dst
), true);
912 // ------------------------------ VoidNode -------------------------------------
914 VoidNode::~VoidNode()
916 NodeReleaser::releaseAllNodes(this);
919 void VoidNode::releaseNodes(NodeReleaser
& releaser
)
921 releaser
.release(m_expr
);
924 RegisterID
* VoidNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
926 if (dst
== generator
.ignoredResult()) {
927 generator
.emitNode(generator
.ignoredResult(), m_expr
.get());
930 RefPtr
<RegisterID
> r0
= generator
.emitNode(m_expr
.get());
931 return generator
.emitLoad(dst
, jsUndefined());
934 // ------------------------------ TypeOfValueNode -----------------------------------
936 RegisterID
* TypeOfResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
938 if (RegisterID
* local
= generator
.registerFor(m_ident
)) {
939 if (dst
== generator
.ignoredResult())
941 return generator
.emitTypeOf(generator
.finalDestination(dst
), local
);
944 RefPtr
<RegisterID
> scratch
= generator
.emitResolveBase(generator
.tempDestination(dst
), m_ident
);
945 generator
.emitGetById(scratch
.get(), scratch
.get(), m_ident
);
946 if (dst
== generator
.ignoredResult())
948 return generator
.emitTypeOf(generator
.finalDestination(dst
, scratch
.get()), scratch
.get());
951 // ------------------------------ TypeOfValueNode -----------------------------------
953 TypeOfValueNode::~TypeOfValueNode()
955 NodeReleaser::releaseAllNodes(this);
958 void TypeOfValueNode::releaseNodes(NodeReleaser
& releaser
)
960 releaser
.release(m_expr
);
963 RegisterID
* TypeOfValueNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
965 if (dst
== generator
.ignoredResult()) {
966 generator
.emitNode(generator
.ignoredResult(), m_expr
.get());
969 RefPtr
<RegisterID
> src
= generator
.emitNode(m_expr
.get());
970 return generator
.emitTypeOf(generator
.finalDestination(dst
), src
.get());
973 // ------------------------------ PrefixResolveNode ----------------------------------
975 RegisterID
* PrefixResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
977 if (RegisterID
* local
= generator
.registerFor(m_ident
)) {
978 if (generator
.isLocalConstant(m_ident
)) {
979 if (dst
== generator
.ignoredResult())
981 RefPtr
<RegisterID
> r0
= generator
.emitUnexpectedLoad(generator
.finalDestination(dst
), (m_operator
== OpPlusPlus
) ? 1.0 : -1.0);
982 return generator
.emitBinaryOp(op_add
, r0
.get(), local
, r0
.get(), OperandTypes());
985 emitPreIncOrDec(generator
, local
, m_operator
);
986 return generator
.moveToDestinationIfNeeded(dst
, local
);
991 JSObject
* globalObject
= 0;
992 if (generator
.findScopedProperty(m_ident
, index
, depth
, false, globalObject
) && index
!= missingSymbolMarker()) {
993 RefPtr
<RegisterID
> propDst
= generator
.emitGetScopedVar(generator
.tempDestination(dst
), depth
, index
, globalObject
);
994 emitPreIncOrDec(generator
, propDst
.get(), m_operator
);
995 generator
.emitPutScopedVar(depth
, index
, propDst
.get(), globalObject
);
996 return generator
.moveToDestinationIfNeeded(dst
, propDst
.get());
999 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1000 RefPtr
<RegisterID
> propDst
= generator
.tempDestination(dst
);
1001 RefPtr
<RegisterID
> base
= generator
.emitResolveWithBase(generator
.newTemporary(), propDst
.get(), m_ident
);
1002 emitPreIncOrDec(generator
, propDst
.get(), m_operator
);
1003 generator
.emitPutById(base
.get(), m_ident
, propDst
.get());
1004 return generator
.moveToDestinationIfNeeded(dst
, propDst
.get());
1007 // ------------------------------ PrefixBracketNode ----------------------------------
1009 PrefixBracketNode::~PrefixBracketNode()
1011 NodeReleaser::releaseAllNodes(this);
1014 void PrefixBracketNode::releaseNodes(NodeReleaser
& releaser
)
1016 releaser
.release(m_base
);
1017 releaser
.release(m_subscript
);
1020 RegisterID
* PrefixBracketNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1022 RefPtr
<RegisterID
> base
= generator
.emitNode(m_base
.get());
1023 RefPtr
<RegisterID
> property
= generator
.emitNode(m_subscript
.get());
1024 RefPtr
<RegisterID
> propDst
= generator
.tempDestination(dst
);
1026 generator
.emitExpressionInfo(divot() + m_subexpressionDivotOffset
, m_subexpressionStartOffset
, endOffset() - m_subexpressionDivotOffset
);
1027 RegisterID
* value
= generator
.emitGetByVal(propDst
.get(), base
.get(), property
.get());
1028 if (m_operator
== OpPlusPlus
)
1029 generator
.emitPreInc(value
);
1031 generator
.emitPreDec(value
);
1032 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1033 generator
.emitPutByVal(base
.get(), property
.get(), value
);
1034 return generator
.moveToDestinationIfNeeded(dst
, propDst
.get());
1037 // ------------------------------ PrefixDotNode ----------------------------------
1039 PrefixDotNode::~PrefixDotNode()
1041 NodeReleaser::releaseAllNodes(this);
1044 void PrefixDotNode::releaseNodes(NodeReleaser
& releaser
)
1046 releaser
.release(m_base
);
1049 RegisterID
* PrefixDotNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1051 RefPtr
<RegisterID
> base
= generator
.emitNode(m_base
.get());
1052 RefPtr
<RegisterID
> propDst
= generator
.tempDestination(dst
);
1054 generator
.emitExpressionInfo(divot() + m_subexpressionDivotOffset
, m_subexpressionStartOffset
, endOffset() - m_subexpressionDivotOffset
);
1055 RegisterID
* value
= generator
.emitGetById(propDst
.get(), base
.get(), m_ident
);
1056 if (m_operator
== OpPlusPlus
)
1057 generator
.emitPreInc(value
);
1059 generator
.emitPreDec(value
);
1060 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1061 generator
.emitPutById(base
.get(), m_ident
, value
);
1062 return generator
.moveToDestinationIfNeeded(dst
, propDst
.get());
1065 // ------------------------------ PrefixErrorNode -----------------------------------
1067 PrefixErrorNode::~PrefixErrorNode()
1069 NodeReleaser::releaseAllNodes(this);
1072 void PrefixErrorNode::releaseNodes(NodeReleaser
& releaser
)
1074 releaser
.release(m_expr
);
1077 RegisterID
* PrefixErrorNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
1079 return emitThrowError(generator
, ReferenceError
, m_operator
== OpPlusPlus
? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
1082 // ------------------------------ Unary Operation Nodes -----------------------------------
1084 UnaryOpNode::~UnaryOpNode()
1086 NodeReleaser::releaseAllNodes(this);
1089 void UnaryOpNode::releaseNodes(NodeReleaser
& releaser
)
1091 releaser
.release(m_expr
);
1094 RegisterID
* UnaryOpNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1096 RegisterID
* src
= generator
.emitNode(m_expr
.get());
1097 return generator
.emitUnaryOp(opcodeID(), generator
.finalDestination(dst
), src
);
1100 // ------------------------------ Binary Operation Nodes -----------------------------------
1102 BinaryOpNode::~BinaryOpNode()
1104 NodeReleaser::releaseAllNodes(this);
1107 void BinaryOpNode::releaseNodes(NodeReleaser
& releaser
)
1109 releaser
.release(m_expr1
);
1110 releaser
.release(m_expr2
);
1113 RegisterID
* BinaryOpNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1115 OpcodeID opcodeID
= this->opcodeID();
1116 if (opcodeID
== op_neq
) {
1117 if (m_expr1
->isNull() || m_expr2
->isNull()) {
1118 RefPtr
<RegisterID
> src
= generator
.tempDestination(dst
);
1119 generator
.emitNode(src
.get(), m_expr1
->isNull() ? m_expr2
.get() : m_expr1
.get());
1120 return generator
.emitUnaryOp(op_neq_null
, generator
.finalDestination(dst
, src
.get()), src
.get());
1124 RefPtr
<RegisterID
> src1
= generator
.emitNodeForLeftHandSide(m_expr1
.get(), m_rightHasAssignments
, m_expr2
->isPure(generator
));
1125 RegisterID
* src2
= generator
.emitNode(m_expr2
.get());
1126 return generator
.emitBinaryOp(opcodeID
, generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
, OperandTypes(m_expr1
->resultDescriptor(), m_expr2
->resultDescriptor()));
1129 RegisterID
* EqualNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1131 if (m_expr1
->isNull() || m_expr2
->isNull()) {
1132 RefPtr
<RegisterID
> src
= generator
.tempDestination(dst
);
1133 generator
.emitNode(src
.get(), m_expr1
->isNull() ? m_expr2
.get() : m_expr1
.get());
1134 return generator
.emitUnaryOp(op_eq_null
, generator
.finalDestination(dst
, src
.get()), src
.get());
1137 RefPtr
<RegisterID
> src1
= generator
.emitNodeForLeftHandSide(m_expr1
.get(), m_rightHasAssignments
, m_expr2
->isPure(generator
));
1138 RegisterID
* src2
= generator
.emitNode(m_expr2
.get());
1139 return generator
.emitEqualityOp(op_eq
, generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
);
1142 RegisterID
* StrictEqualNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1144 RefPtr
<RegisterID
> src1
= generator
.emitNodeForLeftHandSide(m_expr1
.get(), m_rightHasAssignments
, m_expr2
->isPure(generator
));
1145 RegisterID
* src2
= generator
.emitNode(m_expr2
.get());
1146 return generator
.emitEqualityOp(op_stricteq
, generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
);
1149 RegisterID
* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1151 RefPtr
<RegisterID
> src1
= generator
.emitNodeForLeftHandSide(m_expr1
.get(), m_rightHasAssignments
, m_expr2
->isPure(generator
));
1152 RegisterID
* src2
= generator
.emitNode(m_expr2
.get());
1153 return generator
.emitBinaryOp(opcodeID(), generator
.finalDestination(dst
, src1
.get()), src2
, src1
.get(), OperandTypes(m_expr2
->resultDescriptor(), m_expr1
->resultDescriptor()));
1156 RegisterID
* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1158 RefPtr
<RegisterID
> src1
= generator
.emitNodeForLeftHandSide(m_expr1
.get(), m_rightHasAssignments
, m_expr2
->isPure(generator
));
1159 RegisterID
* src2
= generator
.emitNode(m_expr2
.get());
1160 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1161 return generator
.emitBinaryOp(opcodeID(), generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
, OperandTypes(m_expr1
->resultDescriptor(), m_expr2
->resultDescriptor()));
1164 RegisterID
* InstanceOfNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1166 RefPtr
<RegisterID
> src1
= generator
.emitNodeForLeftHandSide(m_expr1
.get(), m_rightHasAssignments
, m_expr2
->isPure(generator
));
1167 RefPtr
<RegisterID
> src2
= generator
.emitNode(m_expr2
.get());
1169 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1170 generator
.emitGetByIdExceptionInfo(op_instanceof
);
1171 RegisterID
* src2Prototype
= generator
.emitGetById(generator
.newTemporary(), src2
.get(), generator
.globalData()->propertyNames
->prototype
);
1173 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1174 return generator
.emitInstanceOf(generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
.get(), src2Prototype
);
1177 // ------------------------------ LogicalOpNode ----------------------------
1179 LogicalOpNode::~LogicalOpNode()
1181 NodeReleaser::releaseAllNodes(this);
1184 void LogicalOpNode::releaseNodes(NodeReleaser
& releaser
)
1186 releaser
.release(m_expr1
);
1187 releaser
.release(m_expr2
);
1190 RegisterID
* LogicalOpNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1192 RefPtr
<RegisterID
> temp
= generator
.tempDestination(dst
);
1193 RefPtr
<Label
> target
= generator
.newLabel();
1195 generator
.emitNode(temp
.get(), m_expr1
.get());
1196 if (m_operator
== OpLogicalAnd
)
1197 generator
.emitJumpIfFalse(temp
.get(), target
.get());
1199 generator
.emitJumpIfTrue(temp
.get(), target
.get());
1200 generator
.emitNode(temp
.get(), m_expr2
.get());
1201 generator
.emitLabel(target
.get());
1203 return generator
.moveToDestinationIfNeeded(dst
, temp
.get());
1206 // ------------------------------ ConditionalNode ------------------------------
1208 ConditionalNode::~ConditionalNode()
1210 NodeReleaser::releaseAllNodes(this);
1213 void ConditionalNode::releaseNodes(NodeReleaser
& releaser
)
1215 releaser
.release(m_logical
);
1216 releaser
.release(m_expr1
);
1217 releaser
.release(m_expr2
);
1220 RegisterID
* ConditionalNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1222 RefPtr
<RegisterID
> newDst
= generator
.finalDestination(dst
);
1223 RefPtr
<Label
> beforeElse
= generator
.newLabel();
1224 RefPtr
<Label
> afterElse
= generator
.newLabel();
1226 RegisterID
* cond
= generator
.emitNode(m_logical
.get());
1227 generator
.emitJumpIfFalse(cond
, beforeElse
.get());
1229 generator
.emitNode(newDst
.get(), m_expr1
.get());
1230 generator
.emitJump(afterElse
.get());
1232 generator
.emitLabel(beforeElse
.get());
1233 generator
.emitNode(newDst
.get(), m_expr2
.get());
1235 generator
.emitLabel(afterElse
.get());
1237 return newDst
.get();
1240 // ------------------------------ ReadModifyResolveNode -----------------------------------
1242 ReadModifyResolveNode::~ReadModifyResolveNode()
1244 NodeReleaser::releaseAllNodes(this);
1247 void ReadModifyResolveNode::releaseNodes(NodeReleaser
& releaser
)
1249 releaser
.release(m_right
);
1252 // FIXME: should this be moved to be a method on BytecodeGenerator?
1253 static ALWAYS_INLINE RegisterID
* emitReadModifyAssignment(BytecodeGenerator
& generator
, RegisterID
* dst
, RegisterID
* src1
, RegisterID
* src2
, Operator oper
, OperandTypes types
)
1270 opcodeID
= op_lshift
;
1273 opcodeID
= op_rshift
;
1276 opcodeID
= op_urshift
;
1279 opcodeID
= op_bitand
;
1282 opcodeID
= op_bitxor
;
1285 opcodeID
= op_bitor
;
1291 ASSERT_NOT_REACHED();
1295 return generator
.emitBinaryOp(opcodeID
, dst
, src1
, src2
, types
);
1298 RegisterID
* ReadModifyResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1300 if (RegisterID
* local
= generator
.registerFor(m_ident
)) {
1301 if (generator
.isLocalConstant(m_ident
)) {
1302 RegisterID
* src2
= generator
.emitNode(m_right
.get());
1303 return emitReadModifyAssignment(generator
, generator
.finalDestination(dst
), local
, src2
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1306 if (generator
.leftHandSideNeedsCopy(m_rightHasAssignments
, m_right
->isPure(generator
))) {
1307 RefPtr
<RegisterID
> result
= generator
.newTemporary();
1308 generator
.emitMove(result
.get(), local
);
1309 RegisterID
* src2
= generator
.emitNode(m_right
.get());
1310 emitReadModifyAssignment(generator
, result
.get(), result
.get(), src2
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1311 generator
.emitMove(local
, result
.get());
1312 return generator
.moveToDestinationIfNeeded(dst
, result
.get());
1315 RegisterID
* src2
= generator
.emitNode(m_right
.get());
1316 RegisterID
* result
= emitReadModifyAssignment(generator
, local
, local
, src2
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1317 return generator
.moveToDestinationIfNeeded(dst
, result
);
1322 JSObject
* globalObject
= 0;
1323 if (generator
.findScopedProperty(m_ident
, index
, depth
, true, globalObject
) && index
!= missingSymbolMarker()) {
1324 RefPtr
<RegisterID
> src1
= generator
.emitGetScopedVar(generator
.tempDestination(dst
), depth
, index
, globalObject
);
1325 RegisterID
* src2
= generator
.emitNode(m_right
.get());
1326 RegisterID
* result
= emitReadModifyAssignment(generator
, generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1327 generator
.emitPutScopedVar(depth
, index
, result
, globalObject
);
1331 RefPtr
<RegisterID
> src1
= generator
.tempDestination(dst
);
1332 generator
.emitExpressionInfo(divot() - startOffset() + m_ident
.size(), m_ident
.size(), 0);
1333 RefPtr
<RegisterID
> base
= generator
.emitResolveWithBase(generator
.newTemporary(), src1
.get(), m_ident
);
1334 RegisterID
* src2
= generator
.emitNode(m_right
.get());
1335 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1336 RegisterID
* result
= emitReadModifyAssignment(generator
, generator
.finalDestination(dst
, src1
.get()), src1
.get(), src2
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1337 return generator
.emitPutById(base
.get(), m_ident
, result
);
1340 // ------------------------------ AssignResolveNode -----------------------------------
1342 AssignResolveNode::~AssignResolveNode()
1344 NodeReleaser::releaseAllNodes(this);
1347 void AssignResolveNode::releaseNodes(NodeReleaser
& releaser
)
1349 releaser
.release(m_right
);
1352 RegisterID
* AssignResolveNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1354 if (RegisterID
* local
= generator
.registerFor(m_ident
)) {
1355 if (generator
.isLocalConstant(m_ident
))
1356 return generator
.emitNode(dst
, m_right
.get());
1358 RegisterID
* result
= generator
.emitNode(local
, m_right
.get());
1359 return generator
.moveToDestinationIfNeeded(dst
, result
);
1364 JSObject
* globalObject
= 0;
1365 if (generator
.findScopedProperty(m_ident
, index
, depth
, true, globalObject
) && index
!= missingSymbolMarker()) {
1366 if (dst
== generator
.ignoredResult())
1368 RegisterID
* value
= generator
.emitNode(dst
, m_right
.get());
1369 generator
.emitPutScopedVar(depth
, index
, value
, globalObject
);
1373 RefPtr
<RegisterID
> base
= generator
.emitResolveBase(generator
.newTemporary(), m_ident
);
1374 if (dst
== generator
.ignoredResult())
1376 RegisterID
* value
= generator
.emitNode(dst
, m_right
.get());
1377 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1378 return generator
.emitPutById(base
.get(), m_ident
, value
);
1381 // ------------------------------ AssignDotNode -----------------------------------
1383 AssignDotNode::~AssignDotNode()
1385 NodeReleaser::releaseAllNodes(this);
1388 void AssignDotNode::releaseNodes(NodeReleaser
& releaser
)
1390 releaser
.release(m_base
);
1391 releaser
.release(m_right
);
1394 RegisterID
* AssignDotNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1396 RefPtr
<RegisterID
> base
= generator
.emitNodeForLeftHandSide(m_base
.get(), m_rightHasAssignments
, m_right
->isPure(generator
));
1397 RefPtr
<RegisterID
> value
= generator
.destinationForAssignResult(dst
);
1398 RegisterID
* result
= generator
.emitNode(value
.get(), m_right
.get());
1399 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1400 generator
.emitPutById(base
.get(), m_ident
, result
);
1401 return generator
.moveToDestinationIfNeeded(dst
, result
);
1404 // ------------------------------ ReadModifyDotNode -----------------------------------
1406 ReadModifyDotNode::~ReadModifyDotNode()
1408 NodeReleaser::releaseAllNodes(this);
1411 void ReadModifyDotNode::releaseNodes(NodeReleaser
& releaser
)
1413 releaser
.release(m_base
);
1414 releaser
.release(m_right
);
1417 RegisterID
* ReadModifyDotNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1419 RefPtr
<RegisterID
> base
= generator
.emitNodeForLeftHandSide(m_base
.get(), m_rightHasAssignments
, m_right
->isPure(generator
));
1421 generator
.emitExpressionInfo(divot() - m_subexpressionDivotOffset
, startOffset() - m_subexpressionDivotOffset
, m_subexpressionEndOffset
);
1422 RefPtr
<RegisterID
> value
= generator
.emitGetById(generator
.tempDestination(dst
), base
.get(), m_ident
);
1423 RegisterID
* change
= generator
.emitNode(m_right
.get());
1424 RegisterID
* updatedValue
= emitReadModifyAssignment(generator
, generator
.finalDestination(dst
, value
.get()), value
.get(), change
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1426 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1427 return generator
.emitPutById(base
.get(), m_ident
, updatedValue
);
1430 // ------------------------------ AssignErrorNode -----------------------------------
1432 AssignErrorNode::~AssignErrorNode()
1434 NodeReleaser::releaseAllNodes(this);
1437 void AssignErrorNode::releaseNodes(NodeReleaser
& releaser
)
1439 releaser
.release(m_left
);
1440 releaser
.release(m_right
);
1443 RegisterID
* AssignErrorNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
1445 return emitThrowError(generator
, ReferenceError
, "Left side of assignment is not a reference.");
1448 // ------------------------------ AssignBracketNode -----------------------------------
1450 AssignBracketNode::~AssignBracketNode()
1452 NodeReleaser::releaseAllNodes(this);
1455 void AssignBracketNode::releaseNodes(NodeReleaser
& releaser
)
1457 releaser
.release(m_base
);
1458 releaser
.release(m_subscript
);
1459 releaser
.release(m_right
);
1462 RegisterID
* AssignBracketNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1464 RefPtr
<RegisterID
> base
= generator
.emitNodeForLeftHandSide(m_base
.get(), m_subscriptHasAssignments
|| m_rightHasAssignments
, m_subscript
->isPure(generator
) && m_right
->isPure(generator
));
1465 RefPtr
<RegisterID
> property
= generator
.emitNodeForLeftHandSide(m_subscript
.get(), m_rightHasAssignments
, m_right
->isPure(generator
));
1466 RefPtr
<RegisterID
> value
= generator
.destinationForAssignResult(dst
);
1467 RegisterID
* result
= generator
.emitNode(value
.get(), m_right
.get());
1469 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1470 generator
.emitPutByVal(base
.get(), property
.get(), result
);
1471 return generator
.moveToDestinationIfNeeded(dst
, result
);
1474 // ------------------------------ ReadModifyBracketNode -----------------------------------
1476 ReadModifyBracketNode::~ReadModifyBracketNode()
1478 NodeReleaser::releaseAllNodes(this);
1481 void ReadModifyBracketNode::releaseNodes(NodeReleaser
& releaser
)
1483 releaser
.release(m_base
);
1484 releaser
.release(m_subscript
);
1485 releaser
.release(m_right
);
1488 RegisterID
* ReadModifyBracketNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1490 RefPtr
<RegisterID
> base
= generator
.emitNodeForLeftHandSide(m_base
.get(), m_subscriptHasAssignments
|| m_rightHasAssignments
, m_subscript
->isPure(generator
) && m_right
->isPure(generator
));
1491 RefPtr
<RegisterID
> property
= generator
.emitNodeForLeftHandSide(m_subscript
.get(), m_rightHasAssignments
, m_right
->isPure(generator
));
1493 generator
.emitExpressionInfo(divot() - m_subexpressionDivotOffset
, startOffset() - m_subexpressionDivotOffset
, m_subexpressionEndOffset
);
1494 RefPtr
<RegisterID
> value
= generator
.emitGetByVal(generator
.tempDestination(dst
), base
.get(), property
.get());
1495 RegisterID
* change
= generator
.emitNode(m_right
.get());
1496 RegisterID
* updatedValue
= emitReadModifyAssignment(generator
, generator
.finalDestination(dst
, value
.get()), value
.get(), change
, m_operator
, OperandTypes(ResultType::unknownType(), m_right
->resultDescriptor()));
1498 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1499 generator
.emitPutByVal(base
.get(), property
.get(), updatedValue
);
1501 return updatedValue
;
1504 // ------------------------------ CommaNode ------------------------------------
1506 CommaNode::~CommaNode()
1508 NodeReleaser::releaseAllNodes(this);
1511 void CommaNode::releaseNodes(NodeReleaser
& releaser
)
1513 releaser
.release(m_expr1
);
1514 releaser
.release(m_expr2
);
1517 RegisterID
* CommaNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1519 generator
.emitNode(generator
.ignoredResult(), m_expr1
.get());
1520 return generator
.emitNode(dst
, m_expr2
.get());
1523 // ------------------------------ ConstDeclNode ------------------------------------
1525 ConstDeclNode::~ConstDeclNode()
1527 NodeReleaser::releaseAllNodes(this);
1530 void ConstDeclNode::releaseNodes(NodeReleaser
& releaser
)
1532 releaser
.release(m_next
);
1533 releaser
.release(m_init
);
1536 ConstDeclNode::ConstDeclNode(JSGlobalData
* globalData
, const Identifier
& ident
, ExpressionNode
* init
)
1537 : ExpressionNode(globalData
)
1543 RegisterID
* ConstDeclNode::emitCodeSingle(BytecodeGenerator
& generator
)
1545 if (RegisterID
* local
= generator
.constRegisterFor(m_ident
)) {
1549 return generator
.emitNode(local
, m_init
.get());
1552 // FIXME: While this code should only be hit in eval code, it will potentially
1553 // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1554 RefPtr
<RegisterID
> base
= generator
.emitResolveBase(generator
.newTemporary(), m_ident
);
1555 RegisterID
* value
= m_init
? generator
.emitNode(m_init
.get()) : generator
.emitLoad(0, jsUndefined());
1556 return generator
.emitPutById(base
.get(), m_ident
, value
);
1559 RegisterID
* ConstDeclNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
1561 RegisterID
* result
= 0;
1562 for (ConstDeclNode
* n
= this; n
; n
= n
->m_next
.get())
1563 result
= n
->emitCodeSingle(generator
);
1568 // ------------------------------ ConstStatementNode -----------------------------
1570 ConstStatementNode::~ConstStatementNode()
1572 NodeReleaser::releaseAllNodes(this);
1575 void ConstStatementNode::releaseNodes(NodeReleaser
& releaser
)
1577 releaser
.release(m_next
);
1580 RegisterID
* ConstStatementNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
1582 return generator
.emitNode(m_next
.get());
1585 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1587 static inline RegisterID
* statementListEmitCode(const StatementVector
& statements
, BytecodeGenerator
& generator
, RegisterID
* dst
)
1589 StatementVector::const_iterator end
= statements
.end();
1590 for (StatementVector::const_iterator it
= statements
.begin(); it
!= end
; ++it
) {
1591 StatementNode
* n
= it
->get();
1593 generator
.emitDebugHook(WillExecuteStatement
, n
->firstLine(), n
->lastLine());
1594 generator
.emitNode(dst
, n
);
1599 // ------------------------------ BlockNode ------------------------------------
1601 BlockNode::~BlockNode()
1603 NodeReleaser::releaseAllNodes(this);
1606 void BlockNode::releaseNodes(NodeReleaser
& releaser
)
1608 size_t size
= m_children
.size();
1609 for (size_t i
= 0; i
< size
; ++i
)
1610 releaser
.release(m_children
[i
]);
1613 BlockNode::BlockNode(JSGlobalData
* globalData
, SourceElements
* children
)
1614 : StatementNode(globalData
)
1617 children
->releaseContentsIntoVector(m_children
);
1620 RegisterID
* BlockNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1622 return statementListEmitCode(m_children
, generator
, dst
);
1625 // ------------------------------ EmptyStatementNode ---------------------------
1627 RegisterID
* EmptyStatementNode::emitBytecode(BytecodeGenerator
&, RegisterID
* dst
)
1632 // ------------------------------ DebuggerStatementNode ---------------------------
1634 RegisterID
* DebuggerStatementNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1636 generator
.emitDebugHook(DidReachBreakpoint
, firstLine(), lastLine());
1640 // ------------------------------ ExprStatementNode ----------------------------
1642 RegisterID
* ExprStatementNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1645 return generator
.emitNode(dst
, m_expr
.get());
1648 // ------------------------------ VarStatementNode ----------------------------
1650 VarStatementNode::~VarStatementNode()
1652 NodeReleaser::releaseAllNodes(this);
1655 void VarStatementNode::releaseNodes(NodeReleaser
& releaser
)
1657 releaser
.release(m_expr
);
1660 RegisterID
* VarStatementNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
1663 return generator
.emitNode(m_expr
.get());
1666 // ------------------------------ IfNode ---------------------------------------
1670 NodeReleaser::releaseAllNodes(this);
1673 void IfNode::releaseNodes(NodeReleaser
& releaser
)
1675 releaser
.release(m_condition
);
1676 releaser
.release(m_ifBlock
);
1679 RegisterID
* IfNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1681 RefPtr
<Label
> afterThen
= generator
.newLabel();
1683 RegisterID
* cond
= generator
.emitNode(m_condition
.get());
1684 generator
.emitJumpIfFalse(cond
, afterThen
.get());
1686 if (!m_ifBlock
->isBlock())
1687 generator
.emitDebugHook(WillExecuteStatement
, m_ifBlock
->firstLine(), m_ifBlock
->lastLine());
1689 generator
.emitNode(dst
, m_ifBlock
.get());
1690 generator
.emitLabel(afterThen
.get());
1692 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1696 // ------------------------------ IfElseNode ---------------------------------------
1698 IfElseNode::~IfElseNode()
1700 NodeReleaser::releaseAllNodes(this);
1703 void IfElseNode::releaseNodes(NodeReleaser
& releaser
)
1705 releaser
.release(m_elseBlock
);
1706 IfNode::releaseNodes(releaser
);
1709 RegisterID
* IfElseNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1711 RefPtr
<Label
> beforeElse
= generator
.newLabel();
1712 RefPtr
<Label
> afterElse
= generator
.newLabel();
1714 RegisterID
* cond
= generator
.emitNode(m_condition
.get());
1715 generator
.emitJumpIfFalse(cond
, beforeElse
.get());
1717 if (!m_ifBlock
->isBlock())
1718 generator
.emitDebugHook(WillExecuteStatement
, m_ifBlock
->firstLine(), m_ifBlock
->lastLine());
1720 generator
.emitNode(dst
, m_ifBlock
.get());
1721 generator
.emitJump(afterElse
.get());
1723 generator
.emitLabel(beforeElse
.get());
1725 if (!m_elseBlock
->isBlock())
1726 generator
.emitDebugHook(WillExecuteStatement
, m_elseBlock
->firstLine(), m_elseBlock
->lastLine());
1728 generator
.emitNode(dst
, m_elseBlock
.get());
1730 generator
.emitLabel(afterElse
.get());
1732 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1736 // ------------------------------ DoWhileNode ----------------------------------
1738 DoWhileNode::~DoWhileNode()
1740 NodeReleaser::releaseAllNodes(this);
1743 void DoWhileNode::releaseNodes(NodeReleaser
& releaser
)
1745 releaser
.release(m_statement
);
1746 releaser
.release(m_expr
);
1749 RegisterID
* DoWhileNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1751 RefPtr
<LabelScope
> scope
= generator
.newLabelScope(LabelScope::Loop
);
1753 RefPtr
<Label
> topOfLoop
= generator
.newLabel();
1754 generator
.emitLabel(topOfLoop
.get());
1756 generator
.emitDebugHook(WillExecuteStatement
, firstLine(), lastLine());
1758 if (!m_statement
->isBlock())
1759 generator
.emitDebugHook(WillExecuteStatement
, m_statement
->firstLine(), m_statement
->lastLine());
1761 RefPtr
<RegisterID
> result
= generator
.emitNode(dst
, m_statement
.get());
1763 generator
.emitLabel(scope
->continueTarget());
1764 generator
.emitDebugHook(WillExecuteStatement
, m_expr
->lineNo(), m_expr
->lineNo());
1765 RegisterID
* cond
= generator
.emitNode(m_expr
.get());
1766 generator
.emitJumpIfTrue(cond
, topOfLoop
.get());
1768 generator
.emitLabel(scope
->breakTarget());
1769 return result
.get();
1772 // ------------------------------ WhileNode ------------------------------------
1774 WhileNode::~WhileNode()
1776 NodeReleaser::releaseAllNodes(this);
1779 void WhileNode::releaseNodes(NodeReleaser
& releaser
)
1781 releaser
.release(m_expr
);
1782 releaser
.release(m_statement
);
1785 RegisterID
* WhileNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1787 RefPtr
<LabelScope
> scope
= generator
.newLabelScope(LabelScope::Loop
);
1789 generator
.emitJump(scope
->continueTarget());
1791 RefPtr
<Label
> topOfLoop
= generator
.newLabel();
1792 generator
.emitLabel(topOfLoop
.get());
1794 if (!m_statement
->isBlock())
1795 generator
.emitDebugHook(WillExecuteStatement
, m_statement
->firstLine(), m_statement
->lastLine());
1797 generator
.emitNode(dst
, m_statement
.get());
1799 generator
.emitLabel(scope
->continueTarget());
1800 generator
.emitDebugHook(WillExecuteStatement
, m_expr
->lineNo(), m_expr
->lineNo());
1801 RegisterID
* cond
= generator
.emitNode(m_expr
.get());
1802 generator
.emitJumpIfTrue(cond
, topOfLoop
.get());
1804 generator
.emitLabel(scope
->breakTarget());
1806 // FIXME: This should return the last statement executed so that it can be returned as a Completion
1810 // ------------------------------ ForNode --------------------------------------
1814 NodeReleaser::releaseAllNodes(this);
1817 void ForNode::releaseNodes(NodeReleaser
& releaser
)
1819 releaser
.release(m_expr1
);
1820 releaser
.release(m_expr2
);
1821 releaser
.release(m_expr3
);
1822 releaser
.release(m_statement
);
1825 RegisterID
* ForNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1827 if (dst
== generator
.ignoredResult())
1830 RefPtr
<LabelScope
> scope
= generator
.newLabelScope(LabelScope::Loop
);
1832 generator
.emitDebugHook(WillExecuteStatement
, firstLine(), lastLine());
1835 generator
.emitNode(generator
.ignoredResult(), m_expr1
.get());
1837 RefPtr
<Label
> condition
= generator
.newLabel();
1838 generator
.emitJump(condition
.get());
1840 RefPtr
<Label
> topOfLoop
= generator
.newLabel();
1841 generator
.emitLabel(topOfLoop
.get());
1843 if (!m_statement
->isBlock())
1844 generator
.emitDebugHook(WillExecuteStatement
, m_statement
->firstLine(), m_statement
->lastLine());
1845 RefPtr
<RegisterID
> result
= generator
.emitNode(dst
, m_statement
.get());
1847 generator
.emitLabel(scope
->continueTarget());
1849 generator
.emitNode(generator
.ignoredResult(), m_expr3
.get());
1851 generator
.emitLabel(condition
.get());
1853 RegisterID
* cond
= generator
.emitNode(m_expr2
.get());
1854 generator
.emitJumpIfTrue(cond
, topOfLoop
.get());
1856 generator
.emitJump(topOfLoop
.get());
1858 generator
.emitLabel(scope
->breakTarget());
1859 return result
.get();
1862 // ------------------------------ ForInNode ------------------------------------
1864 ForInNode::~ForInNode()
1866 NodeReleaser::releaseAllNodes(this);
1869 void ForInNode::releaseNodes(NodeReleaser
& releaser
)
1871 releaser
.release(m_init
);
1872 releaser
.release(m_lexpr
);
1873 releaser
.release(m_expr
);
1874 releaser
.release(m_statement
);
1877 ForInNode::ForInNode(JSGlobalData
* globalData
, ExpressionNode
* l
, ExpressionNode
* expr
, StatementNode
* statement
)
1878 : StatementNode(globalData
)
1882 , m_statement(statement
)
1883 , m_identIsVarDecl(false)
1887 ForInNode::ForInNode(JSGlobalData
* globalData
, const Identifier
& ident
, ExpressionNode
* in
, ExpressionNode
* expr
, StatementNode
* statement
, int divot
, int startOffset
, int endOffset
)
1888 : StatementNode(globalData
)
1890 , m_lexpr(new ResolveNode(globalData
, ident
, divot
- startOffset
))
1892 , m_statement(statement
)
1893 , m_identIsVarDecl(true)
1896 AssignResolveNode
* node
= new AssignResolveNode(globalData
, ident
, in
, true);
1897 node
->setExceptionSourceCode(divot
, divot
- startOffset
, endOffset
- divot
);
1900 // for( var foo = bar in baz )
1903 RegisterID
* ForInNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1905 RefPtr
<LabelScope
> scope
= generator
.newLabelScope(LabelScope::Loop
);
1907 if (!m_lexpr
->isLocation())
1908 return emitThrowError(generator
, ReferenceError
, "Left side of for-in statement is not a reference.");
1910 RefPtr
<Label
> continueTarget
= generator
.newLabel();
1912 generator
.emitDebugHook(WillExecuteStatement
, firstLine(), lastLine());
1915 generator
.emitNode(generator
.ignoredResult(), m_init
.get());
1916 RegisterID
* forInBase
= generator
.emitNode(m_expr
.get());
1917 RefPtr
<RegisterID
> iter
= generator
.emitGetPropertyNames(generator
.newTemporary(), forInBase
);
1918 generator
.emitJump(scope
->continueTarget());
1920 RefPtr
<Label
> loopStart
= generator
.newLabel();
1921 generator
.emitLabel(loopStart
.get());
1923 RegisterID
* propertyName
;
1924 if (m_lexpr
->isResolveNode()) {
1925 const Identifier
& ident
= static_cast<ResolveNode
*>(m_lexpr
.get())->identifier();
1926 propertyName
= generator
.registerFor(ident
);
1927 if (!propertyName
) {
1928 propertyName
= generator
.newTemporary();
1929 RefPtr
<RegisterID
> protect
= propertyName
;
1930 RegisterID
* base
= generator
.emitResolveBase(generator
.newTemporary(), ident
);
1932 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
1933 generator
.emitPutById(base
, ident
, propertyName
);
1935 } else if (m_lexpr
->isDotAccessorNode()) {
1936 DotAccessorNode
* assignNode
= static_cast<DotAccessorNode
*>(m_lexpr
.get());
1937 const Identifier
& ident
= assignNode
->identifier();
1938 propertyName
= generator
.newTemporary();
1939 RefPtr
<RegisterID
> protect
= propertyName
;
1940 RegisterID
* base
= generator
.emitNode(assignNode
->base());
1942 generator
.emitExpressionInfo(assignNode
->divot(), assignNode
->startOffset(), assignNode
->endOffset());
1943 generator
.emitPutById(base
, ident
, propertyName
);
1945 ASSERT(m_lexpr
->isBracketAccessorNode());
1946 BracketAccessorNode
* assignNode
= static_cast<BracketAccessorNode
*>(m_lexpr
.get());
1947 propertyName
= generator
.newTemporary();
1948 RefPtr
<RegisterID
> protect
= propertyName
;
1949 RefPtr
<RegisterID
> base
= generator
.emitNode(assignNode
->base());
1950 RegisterID
* subscript
= generator
.emitNode(assignNode
->subscript());
1952 generator
.emitExpressionInfo(assignNode
->divot(), assignNode
->startOffset(), assignNode
->endOffset());
1953 generator
.emitPutByVal(base
.get(), subscript
, propertyName
);
1956 if (!m_statement
->isBlock())
1957 generator
.emitDebugHook(WillExecuteStatement
, m_statement
->firstLine(), m_statement
->lastLine());
1958 generator
.emitNode(dst
, m_statement
.get());
1960 generator
.emitLabel(scope
->continueTarget());
1961 generator
.emitNextPropertyName(propertyName
, iter
.get(), loopStart
.get());
1962 generator
.emitLabel(scope
->breakTarget());
1966 // ------------------------------ ContinueNode ---------------------------------
1969 RegisterID
* ContinueNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1971 LabelScope
* scope
= generator
.continueTarget(m_ident
);
1974 return m_ident
.isEmpty()
1975 ? emitThrowError(generator
, SyntaxError
, "Invalid continue statement.")
1976 : emitThrowError(generator
, SyntaxError
, "Undefined label: '%s'.", m_ident
);
1978 generator
.emitJumpScopes(scope
->continueTarget(), scope
->scopeDepth());
1982 // ------------------------------ BreakNode ------------------------------------
1985 RegisterID
* BreakNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
1987 LabelScope
* scope
= generator
.breakTarget(m_ident
);
1990 return m_ident
.isEmpty()
1991 ? emitThrowError(generator
, SyntaxError
, "Invalid break statement.")
1992 : emitThrowError(generator
, SyntaxError
, "Undefined label: '%s'.", m_ident
);
1994 generator
.emitJumpScopes(scope
->breakTarget(), scope
->scopeDepth());
1998 // ------------------------------ ReturnNode -----------------------------------
2000 ReturnNode::~ReturnNode()
2002 NodeReleaser::releaseAllNodes(this);
2005 void ReturnNode::releaseNodes(NodeReleaser
& releaser
)
2007 releaser
.release(m_value
);
2010 RegisterID
* ReturnNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2012 if (generator
.codeType() != FunctionCode
)
2013 return emitThrowError(generator
, SyntaxError
, "Invalid return statement.");
2015 if (dst
== generator
.ignoredResult())
2017 RegisterID
* r0
= m_value
? generator
.emitNode(dst
, m_value
.get()) : generator
.emitLoad(dst
, jsUndefined());
2018 RefPtr
<RegisterID
> returnRegister
;
2019 if (generator
.scopeDepth()) {
2020 RefPtr
<Label
> l0
= generator
.newLabel();
2021 if (generator
.hasFinaliser() && !r0
->isTemporary()) {
2022 returnRegister
= generator
.emitMove(generator
.newTemporary(), r0
);
2023 r0
= returnRegister
.get();
2025 generator
.emitJumpScopes(l0
.get(), 0);
2026 generator
.emitLabel(l0
.get());
2028 generator
.emitDebugHook(WillLeaveCallFrame
, firstLine(), lastLine());
2029 return generator
.emitReturn(r0
);
2032 // ------------------------------ WithNode -------------------------------------
2034 WithNode::~WithNode()
2036 NodeReleaser::releaseAllNodes(this);
2039 void WithNode::releaseNodes(NodeReleaser
& releaser
)
2041 releaser
.release(m_expr
);
2042 releaser
.release(m_statement
);
2045 RegisterID
* WithNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2047 RefPtr
<RegisterID
> scope
= generator
.newTemporary();
2048 generator
.emitNode(scope
.get(), m_expr
.get()); // scope must be protected until popped
2049 generator
.emitExpressionInfo(m_divot
, m_expressionLength
, 0);
2050 generator
.emitPushScope(scope
.get());
2051 RegisterID
* result
= generator
.emitNode(dst
, m_statement
.get());
2052 generator
.emitPopScope();
2056 // ------------------------------ CaseClauseNode --------------------------------
2058 CaseClauseNode::~CaseClauseNode()
2060 NodeReleaser::releaseAllNodes(this);
2063 void CaseClauseNode::releaseNodes(NodeReleaser
& releaser
)
2065 releaser
.release(m_expr
);
2068 // ------------------------------ ClauseListNode --------------------------------
2070 ClauseListNode::~ClauseListNode()
2072 NodeReleaser::releaseAllNodes(this);
2075 void ClauseListNode::releaseNodes(NodeReleaser
& releaser
)
2077 releaser
.release(m_clause
);
2078 releaser
.release(m_next
);
2081 // ------------------------------ CaseBlockNode --------------------------------
2083 CaseBlockNode::~CaseBlockNode()
2085 NodeReleaser::releaseAllNodes(this);
2088 void CaseBlockNode::releaseNodes(NodeReleaser
& releaser
)
2090 releaser
.release(m_list1
);
2091 releaser
.release(m_defaultClause
);
2092 releaser
.release(m_list2
);
2102 static void processClauseList(ClauseListNode
* list
, Vector
<ExpressionNode
*, 8>& literalVector
, SwitchKind
& typeForTable
, bool& singleCharacterSwitch
, int32_t& min_num
, int32_t& max_num
)
2104 for (; list
; list
= list
->getNext()) {
2105 ExpressionNode
* clauseExpression
= list
->getClause()->expr();
2106 literalVector
.append(clauseExpression
);
2107 if (clauseExpression
->isNumber()) {
2108 double value
= static_cast<NumberNode
*>(clauseExpression
)->value();
2109 JSValuePtr jsValue
= JSValuePtr::makeInt32Fast(static_cast<int32_t>(value
));
2110 if ((typeForTable
& ~SwitchNumber
) || !jsValue
|| (jsValue
.getInt32Fast() != value
)) {
2111 typeForTable
= SwitchNeither
;
2114 int32_t intVal
= static_cast<int32_t>(value
);
2115 ASSERT(intVal
== value
);
2116 if (intVal
< min_num
)
2118 if (intVal
> max_num
)
2120 typeForTable
= SwitchNumber
;
2123 if (clauseExpression
->isString()) {
2124 if (typeForTable
& ~SwitchString
) {
2125 typeForTable
= SwitchNeither
;
2128 const UString
& value
= static_cast<StringNode
*>(clauseExpression
)->value().ustring();
2129 if (singleCharacterSwitch
&= value
.size() == 1) {
2130 int32_t intVal
= value
.rep()->data()[0];
2131 if (intVal
< min_num
)
2133 if (intVal
> max_num
)
2136 typeForTable
= SwitchString
;
2139 typeForTable
= SwitchNeither
;
2144 SwitchInfo::SwitchType
CaseBlockNode::tryOptimizedSwitch(Vector
<ExpressionNode
*, 8>& literalVector
, int32_t& min_num
, int32_t& max_num
)
2146 SwitchKind typeForTable
= SwitchUnset
;
2147 bool singleCharacterSwitch
= true;
2149 processClauseList(m_list1
.get(), literalVector
, typeForTable
, singleCharacterSwitch
, min_num
, max_num
);
2150 processClauseList(m_list2
.get(), literalVector
, typeForTable
, singleCharacterSwitch
, min_num
, max_num
);
2152 if (typeForTable
== SwitchUnset
|| typeForTable
== SwitchNeither
)
2153 return SwitchInfo::SwitchNone
;
2155 if (typeForTable
== SwitchNumber
) {
2156 int32_t range
= max_num
- min_num
;
2157 if (min_num
<= max_num
&& range
<= 1000 && (range
/ literalVector
.size()) < 10)
2158 return SwitchInfo::SwitchImmediate
;
2159 return SwitchInfo::SwitchNone
;
2162 ASSERT(typeForTable
== SwitchString
);
2164 if (singleCharacterSwitch
) {
2165 int32_t range
= max_num
- min_num
;
2166 if (min_num
<= max_num
&& range
<= 1000 && (range
/ literalVector
.size()) < 10)
2167 return SwitchInfo::SwitchCharacter
;
2170 return SwitchInfo::SwitchString
;
2173 RegisterID
* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator
& generator
, RegisterID
* switchExpression
, RegisterID
* dst
)
2175 RefPtr
<Label
> defaultLabel
;
2176 Vector
<RefPtr
<Label
>, 8> labelVector
;
2177 Vector
<ExpressionNode
*, 8> literalVector
;
2178 int32_t min_num
= std::numeric_limits
<int32_t>::max();
2179 int32_t max_num
= std::numeric_limits
<int32_t>::min();
2180 SwitchInfo::SwitchType switchType
= tryOptimizedSwitch(literalVector
, min_num
, max_num
);
2182 if (switchType
!= SwitchInfo::SwitchNone
) {
2183 // Prepare the various labels
2184 for (uint32_t i
= 0; i
< literalVector
.size(); i
++)
2185 labelVector
.append(generator
.newLabel());
2186 defaultLabel
= generator
.newLabel();
2187 generator
.beginSwitch(switchExpression
, switchType
);
2190 for (ClauseListNode
* list
= m_list1
.get(); list
; list
= list
->getNext()) {
2191 RefPtr
<RegisterID
> clauseVal
= generator
.newTemporary();
2192 generator
.emitNode(clauseVal
.get(), list
->getClause()->expr());
2193 generator
.emitBinaryOp(op_stricteq
, clauseVal
.get(), clauseVal
.get(), switchExpression
, OperandTypes());
2194 labelVector
.append(generator
.newLabel());
2195 generator
.emitJumpIfTrue(clauseVal
.get(), labelVector
[labelVector
.size() - 1].get());
2198 for (ClauseListNode
* list
= m_list2
.get(); list
; list
= list
->getNext()) {
2199 RefPtr
<RegisterID
> clauseVal
= generator
.newTemporary();
2200 generator
.emitNode(clauseVal
.get(), list
->getClause()->expr());
2201 generator
.emitBinaryOp(op_stricteq
, clauseVal
.get(), clauseVal
.get(), switchExpression
, OperandTypes());
2202 labelVector
.append(generator
.newLabel());
2203 generator
.emitJumpIfTrue(clauseVal
.get(), labelVector
[labelVector
.size() - 1].get());
2205 defaultLabel
= generator
.newLabel();
2206 generator
.emitJump(defaultLabel
.get());
2209 RegisterID
* result
= 0;
2212 for (ClauseListNode
* list
= m_list1
.get(); list
; list
= list
->getNext()) {
2213 generator
.emitLabel(labelVector
[i
++].get());
2214 result
= statementListEmitCode(list
->getClause()->children(), generator
, dst
);
2217 if (m_defaultClause
) {
2218 generator
.emitLabel(defaultLabel
.get());
2219 result
= statementListEmitCode(m_defaultClause
->children(), generator
, dst
);
2222 for (ClauseListNode
* list
= m_list2
.get(); list
; list
= list
->getNext()) {
2223 generator
.emitLabel(labelVector
[i
++].get());
2224 result
= statementListEmitCode(list
->getClause()->children(), generator
, dst
);
2226 if (!m_defaultClause
)
2227 generator
.emitLabel(defaultLabel
.get());
2229 ASSERT(i
== labelVector
.size());
2230 if (switchType
!= SwitchInfo::SwitchNone
) {
2231 ASSERT(labelVector
.size() == literalVector
.size());
2232 generator
.endSwitch(labelVector
.size(), labelVector
.data(), literalVector
.data(), defaultLabel
.get(), min_num
, max_num
);
2237 // ------------------------------ SwitchNode -----------------------------------
2239 SwitchNode::~SwitchNode()
2241 NodeReleaser::releaseAllNodes(this);
2244 void SwitchNode::releaseNodes(NodeReleaser
& releaser
)
2246 releaser
.release(m_expr
);
2247 releaser
.release(m_block
);
2250 RegisterID
* SwitchNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2252 RefPtr
<LabelScope
> scope
= generator
.newLabelScope(LabelScope::Switch
);
2254 RefPtr
<RegisterID
> r0
= generator
.emitNode(m_expr
.get());
2255 RegisterID
* r1
= m_block
->emitBytecodeForBlock(generator
, r0
.get(), dst
);
2257 generator
.emitLabel(scope
->breakTarget());
2261 // ------------------------------ LabelNode ------------------------------------
2263 LabelNode::~LabelNode()
2265 NodeReleaser::releaseAllNodes(this);
2268 void LabelNode::releaseNodes(NodeReleaser
& releaser
)
2270 releaser
.release(m_statement
);
2273 RegisterID
* LabelNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2275 if (generator
.breakTarget(m_name
))
2276 return emitThrowError(generator
, SyntaxError
, "Duplicate label: %s.", m_name
);
2278 RefPtr
<LabelScope
> scope
= generator
.newLabelScope(LabelScope::NamedLabel
, &m_name
);
2279 RegisterID
* r0
= generator
.emitNode(dst
, m_statement
.get());
2281 generator
.emitLabel(scope
->breakTarget());
2285 // ------------------------------ ThrowNode ------------------------------------
2287 ThrowNode::~ThrowNode()
2289 NodeReleaser::releaseAllNodes(this);
2292 void ThrowNode::releaseNodes(NodeReleaser
& releaser
)
2294 releaser
.release(m_expr
);
2297 RegisterID
* ThrowNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2299 if (dst
== generator
.ignoredResult())
2301 RefPtr
<RegisterID
> expr
= generator
.emitNode(dst
, m_expr
.get());
2302 generator
.emitExpressionInfo(divot(), startOffset(), endOffset());
2303 generator
.emitThrow(expr
.get());
2307 // ------------------------------ TryNode --------------------------------------
2311 NodeReleaser::releaseAllNodes(this);
2314 void TryNode::releaseNodes(NodeReleaser
& releaser
)
2316 releaser
.release(m_tryBlock
);
2317 releaser
.release(m_catchBlock
);
2318 releaser
.release(m_finallyBlock
);
2321 RegisterID
* TryNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2323 RefPtr
<Label
> tryStartLabel
= generator
.newLabel();
2324 RefPtr
<Label
> tryEndLabel
= generator
.newLabel();
2325 RefPtr
<Label
> finallyStart
;
2326 RefPtr
<RegisterID
> finallyReturnAddr
;
2327 if (m_finallyBlock
) {
2328 finallyStart
= generator
.newLabel();
2329 finallyReturnAddr
= generator
.newTemporary();
2330 generator
.pushFinallyContext(finallyStart
.get(), finallyReturnAddr
.get());
2332 generator
.emitLabel(tryStartLabel
.get());
2333 generator
.emitNode(dst
, m_tryBlock
.get());
2334 generator
.emitLabel(tryEndLabel
.get());
2337 RefPtr
<Label
> handlerEndLabel
= generator
.newLabel();
2338 generator
.emitJump(handlerEndLabel
.get());
2339 RefPtr
<RegisterID
> exceptionRegister
= generator
.emitCatch(generator
.newTemporary(), tryStartLabel
.get(), tryEndLabel
.get());
2340 if (m_catchHasEval
) {
2341 RefPtr
<RegisterID
> dynamicScopeObject
= generator
.emitNewObject(generator
.newTemporary());
2342 generator
.emitPutById(dynamicScopeObject
.get(), m_exceptionIdent
, exceptionRegister
.get());
2343 generator
.emitMove(exceptionRegister
.get(), dynamicScopeObject
.get());
2344 generator
.emitPushScope(exceptionRegister
.get());
2346 generator
.emitPushNewScope(exceptionRegister
.get(), m_exceptionIdent
, exceptionRegister
.get());
2347 generator
.emitNode(dst
, m_catchBlock
.get());
2348 generator
.emitPopScope();
2349 generator
.emitLabel(handlerEndLabel
.get());
2352 if (m_finallyBlock
) {
2353 generator
.popFinallyContext();
2354 // there may be important registers live at the time we jump
2355 // to a finally block (such as for a return or throw) so we
2356 // ref the highest register ever used as a conservative
2357 // approach to not clobbering anything important
2358 RefPtr
<RegisterID
> highestUsedRegister
= generator
.highestUsedRegister();
2359 RefPtr
<Label
> finallyEndLabel
= generator
.newLabel();
2360 generator
.emitJumpSubroutine(finallyReturnAddr
.get(), finallyStart
.get());
2361 // Use a label to record the subtle fact that sret will return to the
2362 // next instruction. sret is the only way to jump without an explicit label.
2363 generator
.emitLabel(generator
.newLabel().get());
2364 generator
.emitJump(finallyEndLabel
.get());
2366 // Finally block for exception path
2367 RefPtr
<RegisterID
> tempExceptionRegister
= generator
.emitCatch(generator
.newTemporary(), tryStartLabel
.get(), generator
.emitLabel(generator
.newLabel().get()).get());
2368 generator
.emitJumpSubroutine(finallyReturnAddr
.get(), finallyStart
.get());
2369 // Use a label to record the subtle fact that sret will return to the
2370 // next instruction. sret is the only way to jump without an explicit label.
2371 generator
.emitLabel(generator
.newLabel().get());
2372 generator
.emitThrow(tempExceptionRegister
.get());
2374 // emit the finally block itself
2375 generator
.emitLabel(finallyStart
.get());
2376 generator
.emitNode(dst
, m_finallyBlock
.get());
2377 generator
.emitSubroutineReturn(finallyReturnAddr
.get());
2379 generator
.emitLabel(finallyEndLabel
.get());
2385 // ------------------------------ ParameterNode -----------------------------
2387 ParameterNode::~ParameterNode()
2389 NodeReleaser::releaseAllNodes(this);
2392 void ParameterNode::releaseNodes(NodeReleaser
& releaser
)
2394 releaser
.release(m_next
);
2397 // -----------------------------ScopeNodeData ---------------------------
2399 ScopeNodeData::ScopeNodeData(SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, int numConstants
)
2400 : m_numConstants(numConstants
)
2403 m_varStack
= *varStack
;
2405 m_functionStack
= *funcStack
;
2407 children
->releaseContentsIntoVector(m_children
);
2410 void ScopeNodeData::mark()
2412 FunctionStack::iterator end
= m_functionStack
.end();
2413 for (FunctionStack::iterator ptr
= m_functionStack
.begin(); ptr
!= end
; ++ptr
) {
2414 FunctionBodyNode
* body
= (*ptr
)->body();
2415 if (!body
->isGenerated())
2417 body
->generatedBytecode().mark();
2421 // ------------------------------ ScopeNode -----------------------------
2423 ScopeNode::ScopeNode(JSGlobalData
* globalData
)
2424 : StatementNode(globalData
)
2425 , m_features(NoFeatures
)
2427 #if ENABLE(OPCODE_SAMPLING)
2428 globalData
->interpreter
->sampler()->notifyOfScope(this);
2432 ScopeNode::ScopeNode(JSGlobalData
* globalData
, const SourceCode
& source
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, CodeFeatures features
, int numConstants
)
2433 : StatementNode(globalData
)
2434 , m_data(new ScopeNodeData(children
, varStack
, funcStack
, numConstants
))
2435 , m_features(features
)
2438 #if ENABLE(OPCODE_SAMPLING)
2439 globalData
->interpreter
->sampler()->notifyOfScope(this);
2443 ScopeNode::~ScopeNode()
2445 NodeReleaser::releaseAllNodes(this);
2448 void ScopeNode::releaseNodes(NodeReleaser
& releaser
)
2452 size_t size
= m_data
->m_children
.size();
2453 for (size_t i
= 0; i
< size
; ++i
)
2454 releaser
.release(m_data
->m_children
[i
]);
2457 // ------------------------------ ProgramNode -----------------------------
2459 ProgramNode::ProgramNode(JSGlobalData
* globalData
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, const SourceCode
& source
, CodeFeatures features
, int numConstants
)
2460 : ScopeNode(globalData
, source
, children
, varStack
, funcStack
, features
, numConstants
)
2464 ProgramNode
* ProgramNode::create(JSGlobalData
* globalData
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, const SourceCode
& source
, CodeFeatures features
, int numConstants
)
2466 return new ProgramNode(globalData
, children
, varStack
, funcStack
, source
, features
, numConstants
);
2469 RegisterID
* ProgramNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
2471 generator
.emitDebugHook(WillExecuteProgram
, firstLine(), lastLine());
2473 RefPtr
<RegisterID
> dstRegister
= generator
.newTemporary();
2474 generator
.emitLoad(dstRegister
.get(), jsUndefined());
2475 statementListEmitCode(children(), generator
, dstRegister
.get());
2477 generator
.emitDebugHook(DidExecuteProgram
, firstLine(), lastLine());
2478 generator
.emitEnd(dstRegister
.get());
2482 void ProgramNode::generateBytecode(ScopeChainNode
* scopeChainNode
)
2484 ScopeChain
scopeChain(scopeChainNode
);
2485 JSGlobalObject
* globalObject
= scopeChain
.globalObject();
2487 m_code
.set(new ProgramCodeBlock(this, GlobalCode
, globalObject
, source().provider()));
2489 BytecodeGenerator
generator(this, globalObject
->debugger(), scopeChain
, &globalObject
->symbolTable(), m_code
.get());
2490 generator
.generate();
2495 // ------------------------------ EvalNode -----------------------------
2497 EvalNode::EvalNode(JSGlobalData
* globalData
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, const SourceCode
& source
, CodeFeatures features
, int numConstants
)
2498 : ScopeNode(globalData
, source
, children
, varStack
, funcStack
, features
, numConstants
)
2502 EvalNode
* EvalNode::create(JSGlobalData
* globalData
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, const SourceCode
& source
, CodeFeatures features
, int numConstants
)
2504 return new EvalNode(globalData
, children
, varStack
, funcStack
, source
, features
, numConstants
);
2507 RegisterID
* EvalNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
2509 generator
.emitDebugHook(WillExecuteProgram
, firstLine(), lastLine());
2511 RefPtr
<RegisterID
> dstRegister
= generator
.newTemporary();
2512 generator
.emitLoad(dstRegister
.get(), jsUndefined());
2513 statementListEmitCode(children(), generator
, dstRegister
.get());
2515 generator
.emitDebugHook(DidExecuteProgram
, firstLine(), lastLine());
2516 generator
.emitEnd(dstRegister
.get());
2520 void EvalNode::generateBytecode(ScopeChainNode
* scopeChainNode
)
2522 ScopeChain
scopeChain(scopeChainNode
);
2523 JSGlobalObject
* globalObject
= scopeChain
.globalObject();
2525 m_code
.set(new EvalCodeBlock(this, globalObject
, source().provider(), scopeChain
.localDepth()));
2527 BytecodeGenerator
generator(this, globalObject
->debugger(), scopeChain
, &m_code
->symbolTable(), m_code
.get());
2528 generator
.generate();
2530 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2531 // so the entire ScopeNodeData cannot be destoyed.
2535 EvalCodeBlock
& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode
* scopeChainNode
, CodeBlock
* codeBlockBeingRegeneratedFrom
)
2539 ScopeChain
scopeChain(scopeChainNode
);
2540 JSGlobalObject
* globalObject
= scopeChain
.globalObject();
2542 m_code
.set(new EvalCodeBlock(this, globalObject
, source().provider(), scopeChain
.localDepth()));
2544 BytecodeGenerator
generator(this, globalObject
->debugger(), scopeChain
, &m_code
->symbolTable(), m_code
.get());
2545 generator
.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom
);
2546 generator
.generate();
2551 void EvalNode::mark()
2553 // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
2557 // ------------------------------ FunctionBodyNode -----------------------------
2559 FunctionBodyNode::FunctionBodyNode(JSGlobalData
* globalData
)
2560 : ScopeNode(globalData
)
2562 , m_parameterCount(0)
2567 FunctionBodyNode::FunctionBodyNode(JSGlobalData
* globalData
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, const SourceCode
& sourceCode
, CodeFeatures features
, int numConstants
)
2568 : ScopeNode(globalData
, sourceCode
, children
, varStack
, funcStack
, features
, numConstants
)
2570 , m_parameterCount(0)
2575 FunctionBodyNode::~FunctionBodyNode()
2577 ASSERT(!m_refCount
);
2578 for (size_t i
= 0; i
< m_parameterCount
; ++i
)
2579 m_parameters
[i
].~Identifier();
2580 fastFree(m_parameters
);
2583 void FunctionBodyNode::finishParsing(const SourceCode
& source
, ParameterNode
* firstParameter
)
2585 Vector
<Identifier
> parameters
;
2586 for (ParameterNode
* parameter
= firstParameter
; parameter
; parameter
= parameter
->nextParam())
2587 parameters
.append(parameter
->ident());
2588 size_t count
= parameters
.size();
2591 finishParsing(parameters
.releaseBuffer(), count
);
2594 void FunctionBodyNode::finishParsing(Identifier
* parameters
, size_t parameterCount
)
2596 ASSERT(!source().isNull());
2597 m_parameters
= parameters
;
2598 m_parameterCount
= parameterCount
;
2601 void FunctionBodyNode::mark()
2607 FunctionBodyNode
* FunctionBodyNode::create(JSGlobalData
* globalData
)
2609 return new FunctionBodyNode(globalData
);
2612 FunctionBodyNode
* FunctionBodyNode::create(JSGlobalData
* globalData
, SourceElements
* children
, VarStack
* varStack
, FunctionStack
* funcStack
, const SourceCode
& sourceCode
, CodeFeatures features
, int numConstants
)
2614 return new FunctionBodyNode(globalData
, children
, varStack
, funcStack
, sourceCode
, features
, numConstants
);
2617 void FunctionBodyNode::generateBytecode(ScopeChainNode
* scopeChainNode
)
2619 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2620 // calling Parser::parse<FunctionBodyNode>().
2622 scopeChainNode
->globalData
->parser
->reparseInPlace(scopeChainNode
->globalData
, this);
2625 ScopeChain
scopeChain(scopeChainNode
);
2626 JSGlobalObject
* globalObject
= scopeChain
.globalObject();
2628 m_code
.set(new CodeBlock(this, FunctionCode
, source().provider(), source().startOffset()));
2630 BytecodeGenerator
generator(this, globalObject
->debugger(), scopeChain
, &m_code
->symbolTable(), m_code
.get());
2631 generator
.generate();
2636 CodeBlock
& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode
* scopeChainNode
, CodeBlock
* codeBlockBeingRegeneratedFrom
)
2640 ScopeChain
scopeChain(scopeChainNode
);
2641 JSGlobalObject
* globalObject
= scopeChain
.globalObject();
2643 m_code
.set(new CodeBlock(this, FunctionCode
, source().provider(), source().startOffset()));
2645 BytecodeGenerator
generator(this, globalObject
->debugger(), scopeChain
, &m_code
->symbolTable(), m_code
.get());
2646 generator
.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom
);
2647 generator
.generate();
2652 RegisterID
* FunctionBodyNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
*)
2654 generator
.emitDebugHook(DidEnterCallFrame
, firstLine(), lastLine());
2655 statementListEmitCode(children(), generator
, generator
.ignoredResult());
2656 if (children().size() && children().last()->isBlock()) {
2657 BlockNode
* blockNode
= static_cast<BlockNode
*>(children().last().get());
2658 if (blockNode
->children().size() && blockNode
->children().last()->isReturnNode())
2662 RegisterID
* r0
= generator
.emitLoad(0, jsUndefined());
2663 generator
.emitDebugHook(WillLeaveCallFrame
, firstLine(), lastLine());
2664 generator
.emitReturn(r0
);
2668 UString
FunctionBodyNode::paramString() const
2671 for (size_t pos
= 0; pos
< m_parameterCount
; ++pos
) {
2674 s
+= parameters()[pos
].ustring();
2680 Identifier
* FunctionBodyNode::copyParameters()
2682 Identifier
* parameters
= static_cast<Identifier
*>(fastMalloc(m_parameterCount
* sizeof(Identifier
)));
2683 VectorCopier
<false, Identifier
>::uninitializedCopy(m_parameters
, m_parameters
+ m_parameterCount
, parameters
);
2687 // ------------------------------ FuncDeclNode ---------------------------------
2689 FuncDeclNode::~FuncDeclNode()
2691 NodeReleaser::releaseAllNodes(this);
2694 void FuncDeclNode::releaseNodes(NodeReleaser
& releaser
)
2696 releaser
.release(m_parameter
);
2697 releaser
.release(m_body
);
2700 JSFunction
* FuncDeclNode::makeFunction(ExecState
* exec
, ScopeChainNode
* scopeChain
)
2702 return new (exec
) JSFunction(exec
, m_ident
, m_body
.get(), scopeChain
);
2705 RegisterID
* FuncDeclNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2707 if (dst
== generator
.ignoredResult())
2712 // ------------------------------ FuncExprNode ---------------------------------
2714 FuncExprNode::~FuncExprNode()
2716 NodeReleaser::releaseAllNodes(this);
2719 void FuncExprNode::releaseNodes(NodeReleaser
& releaser
)
2721 releaser
.release(m_parameter
);
2722 releaser
.release(m_body
);
2725 RegisterID
* FuncExprNode::emitBytecode(BytecodeGenerator
& generator
, RegisterID
* dst
)
2727 return generator
.emitNewFunctionExpression(generator
.finalDestination(dst
), this);
2730 JSFunction
* FuncExprNode::makeFunction(ExecState
* exec
, ScopeChainNode
* scopeChain
)
2732 JSFunction
* func
= new (exec
) JSFunction(exec
, m_ident
, m_body
.get(), scopeChain
);
2735 The Identifier in a FunctionExpression can be referenced from inside
2736 the FunctionExpression's FunctionBody to allow the function to call
2737 itself recursively. However, unlike in a FunctionDeclaration, the
2738 Identifier in a FunctionExpression cannot be referenced from and
2739 does not affect the scope enclosing the FunctionExpression.
2742 if (!m_ident
.isNull()) {
2743 JSStaticScopeObject
* functionScopeObject
= new (exec
) JSStaticScopeObject(exec
, m_ident
, func
, ReadOnly
| DontDelete
);
2744 func
->scope().push(functionScopeObject
);