2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
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.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
591 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
594 // ------------------------------ FunctionCallValueNode ----------------------------------
596 FunctionCallValueNode::~FunctionCallValueNode()
598 NodeReleaser::releaseAllNodes(this);
601 void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
603 releaser.release(m_expr);
604 releaser.release(m_args);
607 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
609 RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
610 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
611 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
614 // ------------------------------ FunctionCallResolveNode ----------------------------------
616 FunctionCallResolveNode::~FunctionCallResolveNode()
618 NodeReleaser::releaseAllNodes(this);
621 void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
623 releaser.release(m_args);
626 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
628 if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
629 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
630 return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
635 JSObject* globalObject = 0;
636 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
637 RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
638 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
639 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
642 RefPtr<RegisterID> func = generator.tempDestination(dst);
643 RefPtr<RegisterID> thisRegister = generator.newTemporary();
644 int identifierStart = divot() - startOffset();
645 generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
646 generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
647 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
650 // ------------------------------ FunctionCallBracketNode ----------------------------------
652 FunctionCallBracketNode::~FunctionCallBracketNode()
654 NodeReleaser::releaseAllNodes(this);
657 void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
659 releaser.release(m_base);
660 releaser.release(m_subscript);
661 releaser.release(m_args);
664 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
666 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
667 RegisterID* property = generator.emitNode(m_subscript.get());
668 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
669 RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
670 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
671 return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
674 // ------------------------------ FunctionCallDotNode ----------------------------------
676 FunctionCallDotNode::~FunctionCallDotNode()
678 NodeReleaser::releaseAllNodes(this);
681 void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
683 releaser.release(m_base);
684 releaser.release(m_args);
687 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
689 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
690 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
691 RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
692 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
693 return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
696 // ------------------------------ PostfixResolveNode ----------------------------------
698 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
700 return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
703 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
705 return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
708 RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
710 if (RegisterID* local = generator.registerFor(m_ident)) {
711 if (generator.isLocalConstant(m_ident)) {
712 if (dst == generator.ignoredResult())
714 return generator.emitToJSNumber(generator.finalDestination(dst), local);
717 if (dst == generator.ignoredResult())
718 return emitPreIncOrDec(generator, local, m_operator);
719 return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
724 JSObject* globalObject = 0;
725 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
726 RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
727 RegisterID* oldValue;
728 if (dst == generator.ignoredResult()) {
730 emitPreIncOrDec(generator, value.get(), m_operator);
732 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
734 generator.emitPutScopedVar(depth, index, value.get(), globalObject);
738 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
739 RefPtr<RegisterID> value = generator.newTemporary();
740 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
741 RegisterID* oldValue;
742 if (dst == generator.ignoredResult()) {
744 emitPreIncOrDec(generator, value.get(), m_operator);
746 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
748 generator.emitPutById(base.get(), m_ident, value.get());
752 // ------------------------------ PostfixBracketNode ----------------------------------
754 PostfixBracketNode::~PostfixBracketNode()
756 NodeReleaser::releaseAllNodes(this);
759 void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
761 releaser.release(m_base);
762 releaser.release(m_subscript);
765 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
767 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
768 RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
770 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
771 RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
772 RegisterID* oldValue;
773 if (dst == generator.ignoredResult()) {
775 if (m_operator == OpPlusPlus)
776 generator.emitPreInc(value.get());
778 generator.emitPreDec(value.get());
780 oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
782 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
783 generator.emitPutByVal(base.get(), property.get(), value.get());
787 // ------------------------------ PostfixDotNode ----------------------------------
789 PostfixDotNode::~PostfixDotNode()
791 NodeReleaser::releaseAllNodes(this);
794 void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
796 releaser.release(m_base);
799 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
801 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
803 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
804 RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
805 RegisterID* oldValue;
806 if (dst == generator.ignoredResult()) {
808 if (m_operator == OpPlusPlus)
809 generator.emitPreInc(value.get());
811 generator.emitPreDec(value.get());
813 oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
815 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
816 generator.emitPutById(base.get(), m_ident, value.get());
820 // ------------------------------ PostfixErrorNode -----------------------------------
822 PostfixErrorNode::~PostfixErrorNode()
824 NodeReleaser::releaseAllNodes(this);
827 void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
829 releaser.release(m_expr);
832 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
834 return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
837 // ------------------------------ DeleteResolveNode -----------------------------------
839 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
841 if (generator.registerFor(m_ident))
842 return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
844 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
845 RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
846 return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
849 // ------------------------------ DeleteBracketNode -----------------------------------
851 DeleteBracketNode::~DeleteBracketNode()
853 NodeReleaser::releaseAllNodes(this);
856 void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
858 releaser.release(m_base);
859 releaser.release(m_subscript);
862 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
864 RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
865 RegisterID* r1 = generator.emitNode(m_subscript.get());
867 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
868 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
871 // ------------------------------ DeleteDotNode -----------------------------------
873 DeleteDotNode::~DeleteDotNode()
875 NodeReleaser::releaseAllNodes(this);
878 void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
880 releaser.release(m_base);
883 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
885 RegisterID* r0 = generator.emitNode(m_base.get());
887 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
888 return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
891 // ------------------------------ DeleteValueNode -----------------------------------
893 DeleteValueNode::~DeleteValueNode()
895 NodeReleaser::releaseAllNodes(this);
898 void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
900 releaser.release(m_expr);
903 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
905 generator.emitNode(generator.ignoredResult(), m_expr.get());
907 // delete on a non-location expression ignores the value and returns true
908 return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
911 // ------------------------------ VoidNode -------------------------------------
913 VoidNode::~VoidNode()
915 NodeReleaser::releaseAllNodes(this);
918 void VoidNode::releaseNodes(NodeReleaser& releaser)
920 releaser.release(m_expr);
923 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
925 if (dst == generator.ignoredResult()) {
926 generator.emitNode(generator.ignoredResult(), m_expr.get());
929 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
930 return generator.emitLoad(dst, jsUndefined());
933 // ------------------------------ TypeOfValueNode -----------------------------------
935 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
937 if (RegisterID* local = generator.registerFor(m_ident)) {
938 if (dst == generator.ignoredResult())
940 return generator.emitTypeOf(generator.finalDestination(dst), local);
943 RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
944 generator.emitGetById(scratch.get(), scratch.get(), m_ident);
945 if (dst == generator.ignoredResult())
947 return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
950 // ------------------------------ TypeOfValueNode -----------------------------------
952 TypeOfValueNode::~TypeOfValueNode()
954 NodeReleaser::releaseAllNodes(this);
957 void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
959 releaser.release(m_expr);
962 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
964 if (dst == generator.ignoredResult()) {
965 generator.emitNode(generator.ignoredResult(), m_expr.get());
968 RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
969 return generator.emitTypeOf(generator.finalDestination(dst), src.get());
972 // ------------------------------ PrefixResolveNode ----------------------------------
974 RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
976 if (RegisterID* local = generator.registerFor(m_ident)) {
977 if (generator.isLocalConstant(m_ident)) {
978 if (dst == generator.ignoredResult())
980 RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
981 return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
984 emitPreIncOrDec(generator, local, m_operator);
985 return generator.moveToDestinationIfNeeded(dst, local);
990 JSObject* globalObject = 0;
991 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
992 RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
993 emitPreIncOrDec(generator, propDst.get(), m_operator);
994 generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
995 return generator.moveToDestinationIfNeeded(dst, propDst.get());
998 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
999 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1000 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
1001 emitPreIncOrDec(generator, propDst.get(), m_operator);
1002 generator.emitPutById(base.get(), m_ident, propDst.get());
1003 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1006 // ------------------------------ PrefixBracketNode ----------------------------------
1008 PrefixBracketNode::~PrefixBracketNode()
1010 NodeReleaser::releaseAllNodes(this);
1013 void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
1015 releaser.release(m_base);
1016 releaser.release(m_subscript);
1019 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1021 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1022 RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
1023 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1025 generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1026 RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1027 if (m_operator == OpPlusPlus)
1028 generator.emitPreInc(value);
1030 generator.emitPreDec(value);
1031 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1032 generator.emitPutByVal(base.get(), property.get(), value);
1033 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1036 // ------------------------------ PrefixDotNode ----------------------------------
1038 PrefixDotNode::~PrefixDotNode()
1040 NodeReleaser::releaseAllNodes(this);
1043 void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
1045 releaser.release(m_base);
1048 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1050 RefPtr<RegisterID> base = generator.emitNode(m_base.get());
1051 RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1053 generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
1054 RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
1055 if (m_operator == OpPlusPlus)
1056 generator.emitPreInc(value);
1058 generator.emitPreDec(value);
1059 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1060 generator.emitPutById(base.get(), m_ident, value);
1061 return generator.moveToDestinationIfNeeded(dst, propDst.get());
1064 // ------------------------------ PrefixErrorNode -----------------------------------
1066 PrefixErrorNode::~PrefixErrorNode()
1068 NodeReleaser::releaseAllNodes(this);
1071 void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
1073 releaser.release(m_expr);
1076 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1078 return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
1081 // ------------------------------ Unary Operation Nodes -----------------------------------
1083 UnaryOpNode::~UnaryOpNode()
1085 NodeReleaser::releaseAllNodes(this);
1088 void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
1090 releaser.release(m_expr);
1093 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1095 RegisterID* src = generator.emitNode(m_expr.get());
1096 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
1099 // ------------------------------ Binary Operation Nodes -----------------------------------
1101 BinaryOpNode::~BinaryOpNode()
1103 NodeReleaser::releaseAllNodes(this);
1106 void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
1108 releaser.release(m_expr1);
1109 releaser.release(m_expr2);
1112 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1114 OpcodeID opcodeID = this->opcodeID();
1115 if (opcodeID == op_neq) {
1116 if (m_expr1->isNull() || m_expr2->isNull()) {
1117 RefPtr<RegisterID> src = generator.tempDestination(dst);
1118 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1119 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1123 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1124 RegisterID* src2 = generator.emitNode(m_expr2.get());
1125 return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1128 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1130 if (m_expr1->isNull() || m_expr2->isNull()) {
1131 RefPtr<RegisterID> src = generator.tempDestination(dst);
1132 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
1133 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1136 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1137 RegisterID* src2 = generator.emitNode(m_expr2.get());
1138 return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1141 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1143 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1144 RegisterID* src2 = generator.emitNode(m_expr2.get());
1145 return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
1148 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1150 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1151 RegisterID* src2 = generator.emitNode(m_expr2.get());
1152 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
1155 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1157 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1158 RegisterID* src2 = generator.emitNode(m_expr2.get());
1159 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1160 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1163 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1165 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
1166 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
1168 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1169 generator.emitGetByIdExceptionInfo(op_instanceof);
1170 RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
1172 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1173 return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
1176 // ------------------------------ LogicalOpNode ----------------------------
1178 LogicalOpNode::~LogicalOpNode()
1180 NodeReleaser::releaseAllNodes(this);
1183 void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
1185 releaser.release(m_expr1);
1186 releaser.release(m_expr2);
1189 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1191 RefPtr<RegisterID> temp = generator.tempDestination(dst);
1192 RefPtr<Label> target = generator.newLabel();
1194 generator.emitNode(temp.get(), m_expr1.get());
1195 if (m_operator == OpLogicalAnd)
1196 generator.emitJumpIfFalse(temp.get(), target.get());
1198 generator.emitJumpIfTrue(temp.get(), target.get());
1199 generator.emitNode(temp.get(), m_expr2.get());
1200 generator.emitLabel(target.get());
1202 return generator.moveToDestinationIfNeeded(dst, temp.get());
1205 // ------------------------------ ConditionalNode ------------------------------
1207 ConditionalNode::~ConditionalNode()
1209 NodeReleaser::releaseAllNodes(this);
1212 void ConditionalNode::releaseNodes(NodeReleaser& releaser)
1214 releaser.release(m_logical);
1215 releaser.release(m_expr1);
1216 releaser.release(m_expr2);
1219 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1221 RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1222 RefPtr<Label> beforeElse = generator.newLabel();
1223 RefPtr<Label> afterElse = generator.newLabel();
1225 RegisterID* cond = generator.emitNode(m_logical.get());
1226 generator.emitJumpIfFalse(cond, beforeElse.get());
1228 generator.emitNode(newDst.get(), m_expr1.get());
1229 generator.emitJump(afterElse.get());
1231 generator.emitLabel(beforeElse.get());
1232 generator.emitNode(newDst.get(), m_expr2.get());
1234 generator.emitLabel(afterElse.get());
1236 return newDst.get();
1239 // ------------------------------ ReadModifyResolveNode -----------------------------------
1241 ReadModifyResolveNode::~ReadModifyResolveNode()
1243 NodeReleaser::releaseAllNodes(this);
1246 void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
1248 releaser.release(m_right);
1251 // FIXME: should this be moved to be a method on BytecodeGenerator?
1252 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
1269 opcodeID = op_lshift;
1272 opcodeID = op_rshift;
1275 opcodeID = op_urshift;
1278 opcodeID = op_bitand;
1281 opcodeID = op_bitxor;
1284 opcodeID = op_bitor;
1290 ASSERT_NOT_REACHED();
1294 return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1297 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1299 if (RegisterID* local = generator.registerFor(m_ident)) {
1300 if (generator.isLocalConstant(m_ident)) {
1301 RegisterID* src2 = generator.emitNode(m_right.get());
1302 return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1305 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1306 RefPtr<RegisterID> result = generator.newTemporary();
1307 generator.emitMove(result.get(), local);
1308 RegisterID* src2 = generator.emitNode(m_right.get());
1309 emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1310 generator.emitMove(local, result.get());
1311 return generator.moveToDestinationIfNeeded(dst, result.get());
1314 RegisterID* src2 = generator.emitNode(m_right.get());
1315 RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1316 return generator.moveToDestinationIfNeeded(dst, result);
1321 JSObject* globalObject = 0;
1322 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1323 RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1324 RegisterID* src2 = generator.emitNode(m_right.get());
1325 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1326 generator.emitPutScopedVar(depth, index, result, globalObject);
1330 RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1331 generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
1332 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1333 RegisterID* src2 = generator.emitNode(m_right.get());
1334 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1335 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1336 return generator.emitPutById(base.get(), m_ident, result);
1339 // ------------------------------ AssignResolveNode -----------------------------------
1341 AssignResolveNode::~AssignResolveNode()
1343 NodeReleaser::releaseAllNodes(this);
1346 void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
1348 releaser.release(m_right);
1351 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1353 if (RegisterID* local = generator.registerFor(m_ident)) {
1354 if (generator.isLocalConstant(m_ident))
1355 return generator.emitNode(dst, m_right.get());
1357 RegisterID* result = generator.emitNode(local, m_right.get());
1358 return generator.moveToDestinationIfNeeded(dst, result);
1363 JSObject* globalObject = 0;
1364 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
1365 if (dst == generator.ignoredResult())
1367 RegisterID* value = generator.emitNode(dst, m_right.get());
1368 generator.emitPutScopedVar(depth, index, value, globalObject);
1372 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1373 if (dst == generator.ignoredResult())
1375 RegisterID* value = generator.emitNode(dst, m_right.get());
1376 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1377 return generator.emitPutById(base.get(), m_ident, value);
1380 // ------------------------------ AssignDotNode -----------------------------------
1382 AssignDotNode::~AssignDotNode()
1384 NodeReleaser::releaseAllNodes(this);
1387 void AssignDotNode::releaseNodes(NodeReleaser& releaser)
1389 releaser.release(m_base);
1390 releaser.release(m_right);
1393 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1395 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1396 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1397 RegisterID* result = generator.emitNode(value.get(), m_right.get());
1398 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1399 generator.emitPutById(base.get(), m_ident, result);
1400 return generator.moveToDestinationIfNeeded(dst, result);
1403 // ------------------------------ ReadModifyDotNode -----------------------------------
1405 ReadModifyDotNode::~ReadModifyDotNode()
1407 NodeReleaser::releaseAllNodes(this);
1410 void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
1412 releaser.release(m_base);
1413 releaser.release(m_right);
1416 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1418 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
1420 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1421 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1422 RegisterID* change = generator.emitNode(m_right.get());
1423 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1425 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1426 return generator.emitPutById(base.get(), m_ident, updatedValue);
1429 // ------------------------------ AssignErrorNode -----------------------------------
1431 AssignErrorNode::~AssignErrorNode()
1433 NodeReleaser::releaseAllNodes(this);
1436 void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
1438 releaser.release(m_left);
1439 releaser.release(m_right);
1442 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1444 return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
1447 // ------------------------------ AssignBracketNode -----------------------------------
1449 AssignBracketNode::~AssignBracketNode()
1451 NodeReleaser::releaseAllNodes(this);
1454 void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
1456 releaser.release(m_base);
1457 releaser.release(m_subscript);
1458 releaser.release(m_right);
1461 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1463 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1464 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1465 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1466 RegisterID* result = generator.emitNode(value.get(), m_right.get());
1468 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1469 generator.emitPutByVal(base.get(), property.get(), result);
1470 return generator.moveToDestinationIfNeeded(dst, result);
1473 // ------------------------------ ReadModifyBracketNode -----------------------------------
1475 ReadModifyBracketNode::~ReadModifyBracketNode()
1477 NodeReleaser::releaseAllNodes(this);
1480 void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
1482 releaser.release(m_base);
1483 releaser.release(m_subscript);
1484 releaser.release(m_right);
1487 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1489 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1490 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
1492 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1493 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1494 RegisterID* change = generator.emitNode(m_right.get());
1495 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
1497 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1498 generator.emitPutByVal(base.get(), property.get(), updatedValue);
1500 return updatedValue;
1503 // ------------------------------ CommaNode ------------------------------------
1505 CommaNode::~CommaNode()
1507 NodeReleaser::releaseAllNodes(this);
1510 void CommaNode::releaseNodes(NodeReleaser& releaser)
1512 releaser.release(m_expr1);
1513 releaser.release(m_expr2);
1516 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1518 generator.emitNode(generator.ignoredResult(), m_expr1.get());
1519 return generator.emitNode(dst, m_expr2.get());
1522 // ------------------------------ ConstDeclNode ------------------------------------
1524 ConstDeclNode::~ConstDeclNode()
1526 NodeReleaser::releaseAllNodes(this);
1529 void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
1531 releaser.release(m_next);
1532 releaser.release(m_init);
1535 ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
1536 : ExpressionNode(globalData)
1542 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1544 if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1548 return generator.emitNode(local, m_init.get());
1551 // FIXME: While this code should only be hit in eval code, it will potentially
1552 // assign to the wrong base if m_ident exists in an intervening dynamic scope.
1553 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1554 RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined());
1555 return generator.emitPutById(base.get(), m_ident, value);
1558 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1560 RegisterID* result = 0;
1561 for (ConstDeclNode* n = this; n; n = n->m_next.get())
1562 result = n->emitCodeSingle(generator);
1567 // ------------------------------ ConstStatementNode -----------------------------
1569 ConstStatementNode::~ConstStatementNode()
1571 NodeReleaser::releaseAllNodes(this);
1574 void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
1576 releaser.release(m_next);
1579 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1581 return generator.emitNode(m_next.get());
1584 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
1586 static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
1588 StatementVector::const_iterator end = statements.end();
1589 for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
1590 StatementNode* n = it->get();
1592 generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
1593 generator.emitNode(dst, n);
1598 // ------------------------------ BlockNode ------------------------------------
1600 BlockNode::~BlockNode()
1602 NodeReleaser::releaseAllNodes(this);
1605 void BlockNode::releaseNodes(NodeReleaser& releaser)
1607 size_t size = m_children.size();
1608 for (size_t i = 0; i < size; ++i)
1609 releaser.release(m_children[i]);
1612 BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
1613 : StatementNode(globalData)
1616 children->releaseContentsIntoVector(m_children);
1619 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1621 return statementListEmitCode(m_children, generator, dst);
1624 // ------------------------------ EmptyStatementNode ---------------------------
1626 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
1631 // ------------------------------ DebuggerStatementNode ---------------------------
1633 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1635 generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1639 // ------------------------------ ExprStatementNode ----------------------------
1641 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1644 return generator.emitNode(dst, m_expr.get());
1647 // ------------------------------ VarStatementNode ----------------------------
1649 VarStatementNode::~VarStatementNode()
1651 NodeReleaser::releaseAllNodes(this);
1654 void VarStatementNode::releaseNodes(NodeReleaser& releaser)
1656 releaser.release(m_expr);
1659 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1662 return generator.emitNode(m_expr.get());
1665 // ------------------------------ IfNode ---------------------------------------
1669 NodeReleaser::releaseAllNodes(this);
1672 void IfNode::releaseNodes(NodeReleaser& releaser)
1674 releaser.release(m_condition);
1675 releaser.release(m_ifBlock);
1678 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1680 RefPtr<Label> afterThen = generator.newLabel();
1682 RegisterID* cond = generator.emitNode(m_condition.get());
1683 generator.emitJumpIfFalse(cond, afterThen.get());
1685 if (!m_ifBlock->isBlock())
1686 generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1688 generator.emitNode(dst, m_ifBlock.get());
1689 generator.emitLabel(afterThen.get());
1691 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1695 // ------------------------------ IfElseNode ---------------------------------------
1697 IfElseNode::~IfElseNode()
1699 NodeReleaser::releaseAllNodes(this);
1702 void IfElseNode::releaseNodes(NodeReleaser& releaser)
1704 releaser.release(m_elseBlock);
1705 IfNode::releaseNodes(releaser);
1708 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1710 RefPtr<Label> beforeElse = generator.newLabel();
1711 RefPtr<Label> afterElse = generator.newLabel();
1713 RegisterID* cond = generator.emitNode(m_condition.get());
1714 generator.emitJumpIfFalse(cond, beforeElse.get());
1716 if (!m_ifBlock->isBlock())
1717 generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
1719 generator.emitNode(dst, m_ifBlock.get());
1720 generator.emitJump(afterElse.get());
1722 generator.emitLabel(beforeElse.get());
1724 if (!m_elseBlock->isBlock())
1725 generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
1727 generator.emitNode(dst, m_elseBlock.get());
1729 generator.emitLabel(afterElse.get());
1731 // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1735 // ------------------------------ DoWhileNode ----------------------------------
1737 DoWhileNode::~DoWhileNode()
1739 NodeReleaser::releaseAllNodes(this);
1742 void DoWhileNode::releaseNodes(NodeReleaser& releaser)
1744 releaser.release(m_statement);
1745 releaser.release(m_expr);
1748 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1750 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1752 RefPtr<Label> topOfLoop = generator.newLabel();
1753 generator.emitLabel(topOfLoop.get());
1755 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1757 if (!m_statement->isBlock())
1758 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1760 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1762 generator.emitLabel(scope->continueTarget());
1763 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1764 RegisterID* cond = generator.emitNode(m_expr.get());
1765 generator.emitJumpIfTrue(cond, topOfLoop.get());
1767 generator.emitLabel(scope->breakTarget());
1768 return result.get();
1771 // ------------------------------ WhileNode ------------------------------------
1773 WhileNode::~WhileNode()
1775 NodeReleaser::releaseAllNodes(this);
1778 void WhileNode::releaseNodes(NodeReleaser& releaser)
1780 releaser.release(m_expr);
1781 releaser.release(m_statement);
1784 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1786 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1788 generator.emitJump(scope->continueTarget());
1790 RefPtr<Label> topOfLoop = generator.newLabel();
1791 generator.emitLabel(topOfLoop.get());
1793 if (!m_statement->isBlock())
1794 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1796 generator.emitNode(dst, m_statement.get());
1798 generator.emitLabel(scope->continueTarget());
1799 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1800 RegisterID* cond = generator.emitNode(m_expr.get());
1801 generator.emitJumpIfTrue(cond, topOfLoop.get());
1803 generator.emitLabel(scope->breakTarget());
1805 // FIXME: This should return the last statement executed so that it can be returned as a Completion
1809 // ------------------------------ ForNode --------------------------------------
1813 NodeReleaser::releaseAllNodes(this);
1816 void ForNode::releaseNodes(NodeReleaser& releaser)
1818 releaser.release(m_expr1);
1819 releaser.release(m_expr2);
1820 releaser.release(m_expr3);
1821 releaser.release(m_statement);
1824 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1826 if (dst == generator.ignoredResult())
1829 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1831 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1834 generator.emitNode(generator.ignoredResult(), m_expr1.get());
1836 RefPtr<Label> condition = generator.newLabel();
1837 generator.emitJump(condition.get());
1839 RefPtr<Label> topOfLoop = generator.newLabel();
1840 generator.emitLabel(topOfLoop.get());
1842 if (!m_statement->isBlock())
1843 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1844 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
1846 generator.emitLabel(scope->continueTarget());
1848 generator.emitNode(generator.ignoredResult(), m_expr3.get());
1850 generator.emitLabel(condition.get());
1852 RegisterID* cond = generator.emitNode(m_expr2.get());
1853 generator.emitJumpIfTrue(cond, topOfLoop.get());
1855 generator.emitJump(topOfLoop.get());
1857 generator.emitLabel(scope->breakTarget());
1858 return result.get();
1861 // ------------------------------ ForInNode ------------------------------------
1863 ForInNode::~ForInNode()
1865 NodeReleaser::releaseAllNodes(this);
1868 void ForInNode::releaseNodes(NodeReleaser& releaser)
1870 releaser.release(m_init);
1871 releaser.release(m_lexpr);
1872 releaser.release(m_expr);
1873 releaser.release(m_statement);
1876 ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
1877 : StatementNode(globalData)
1881 , m_statement(statement)
1882 , m_identIsVarDecl(false)
1886 ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
1887 : StatementNode(globalData)
1889 , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
1891 , m_statement(statement)
1892 , m_identIsVarDecl(true)
1895 AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
1896 node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
1899 // for( var foo = bar in baz )
1902 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1904 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1906 if (!m_lexpr->isLocation())
1907 return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
1909 RefPtr<Label> continueTarget = generator.newLabel();
1911 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1914 generator.emitNode(generator.ignoredResult(), m_init.get());
1915 RegisterID* forInBase = generator.emitNode(m_expr.get());
1916 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
1917 generator.emitJump(scope->continueTarget());
1919 RefPtr<Label> loopStart = generator.newLabel();
1920 generator.emitLabel(loopStart.get());
1922 RegisterID* propertyName;
1923 if (m_lexpr->isResolveNode()) {
1924 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
1925 propertyName = generator.registerFor(ident);
1926 if (!propertyName) {
1927 propertyName = generator.newTemporary();
1928 RefPtr<RegisterID> protect = propertyName;
1929 RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
1931 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1932 generator.emitPutById(base, ident, propertyName);
1934 } else if (m_lexpr->isDotAccessorNode()) {
1935 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
1936 const Identifier& ident = assignNode->identifier();
1937 propertyName = generator.newTemporary();
1938 RefPtr<RegisterID> protect = propertyName;
1939 RegisterID* base = generator.emitNode(assignNode->base());
1941 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1942 generator.emitPutById(base, ident, propertyName);
1944 ASSERT(m_lexpr->isBracketAccessorNode());
1945 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
1946 propertyName = generator.newTemporary();
1947 RefPtr<RegisterID> protect = propertyName;
1948 RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1949 RegisterID* subscript = generator.emitNode(assignNode->subscript());
1951 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1952 generator.emitPutByVal(base.get(), subscript, propertyName);
1955 if (!m_statement->isBlock())
1956 generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
1957 generator.emitNode(dst, m_statement.get());
1959 generator.emitLabel(scope->continueTarget());
1960 generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
1961 generator.emitLabel(scope->breakTarget());
1965 // ------------------------------ ContinueNode ---------------------------------
1968 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1970 LabelScope* scope = generator.continueTarget(m_ident);
1973 return m_ident.isEmpty()
1974 ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
1975 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1977 generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1981 // ------------------------------ BreakNode ------------------------------------
1984 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1986 LabelScope* scope = generator.breakTarget(m_ident);
1989 return m_ident.isEmpty()
1990 ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
1991 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
1993 generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1997 // ------------------------------ ReturnNode -----------------------------------
1999 ReturnNode::~ReturnNode()
2001 NodeReleaser::releaseAllNodes(this);
2004 void ReturnNode::releaseNodes(NodeReleaser& releaser)
2006 releaser.release(m_value);
2009 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2011 if (generator.codeType() != FunctionCode)
2012 return emitThrowError(generator, SyntaxError, "Invalid return statement.");
2014 if (dst == generator.ignoredResult())
2016 RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
2017 if (generator.scopeDepth()) {
2018 RefPtr<Label> l0 = generator.newLabel();
2019 generator.emitJumpScopes(l0.get(), 0);
2020 generator.emitLabel(l0.get());
2022 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2023 return generator.emitReturn(r0);
2026 // ------------------------------ WithNode -------------------------------------
2028 WithNode::~WithNode()
2030 NodeReleaser::releaseAllNodes(this);
2033 void WithNode::releaseNodes(NodeReleaser& releaser)
2035 releaser.release(m_expr);
2036 releaser.release(m_statement);
2039 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2041 RefPtr<RegisterID> scope = generator.newTemporary();
2042 generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
2043 generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
2044 generator.emitPushScope(scope.get());
2045 RegisterID* result = generator.emitNode(dst, m_statement.get());
2046 generator.emitPopScope();
2050 // ------------------------------ CaseClauseNode --------------------------------
2052 CaseClauseNode::~CaseClauseNode()
2054 NodeReleaser::releaseAllNodes(this);
2057 void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
2059 releaser.release(m_expr);
2062 // ------------------------------ ClauseListNode --------------------------------
2064 ClauseListNode::~ClauseListNode()
2066 NodeReleaser::releaseAllNodes(this);
2069 void ClauseListNode::releaseNodes(NodeReleaser& releaser)
2071 releaser.release(m_clause);
2072 releaser.release(m_next);
2075 // ------------------------------ CaseBlockNode --------------------------------
2077 CaseBlockNode::~CaseBlockNode()
2079 NodeReleaser::releaseAllNodes(this);
2082 void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
2084 releaser.release(m_list1);
2085 releaser.release(m_defaultClause);
2086 releaser.release(m_list2);
2096 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2098 for (; list; list = list->getNext()) {
2099 ExpressionNode* clauseExpression = list->getClause()->expr();
2100 literalVector.append(clauseExpression);
2101 if (clauseExpression->isNumber()) {
2102 double value = static_cast<NumberNode*>(clauseExpression)->value();
2103 if ((typeForTable & ~SwitchNumber) || !JSImmediate::from(value)) {
2104 typeForTable = SwitchNeither;
2107 int32_t intVal = static_cast<int32_t>(value);
2108 ASSERT(intVal == value);
2109 if (intVal < min_num)
2111 if (intVal > max_num)
2113 typeForTable = SwitchNumber;
2116 if (clauseExpression->isString()) {
2117 if (typeForTable & ~SwitchString) {
2118 typeForTable = SwitchNeither;
2121 const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
2122 if (singleCharacterSwitch &= value.size() == 1) {
2123 int32_t intVal = value.rep()->data()[0];
2124 if (intVal < min_num)
2126 if (intVal > max_num)
2129 typeForTable = SwitchString;
2132 typeForTable = SwitchNeither;
2137 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2139 SwitchKind typeForTable = SwitchUnset;
2140 bool singleCharacterSwitch = true;
2142 processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2143 processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2145 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2146 return SwitchInfo::SwitchNone;
2148 if (typeForTable == SwitchNumber) {
2149 int32_t range = max_num - min_num;
2150 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2151 return SwitchInfo::SwitchImmediate;
2152 return SwitchInfo::SwitchNone;
2155 ASSERT(typeForTable == SwitchString);
2157 if (singleCharacterSwitch) {
2158 int32_t range = max_num - min_num;
2159 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2160 return SwitchInfo::SwitchCharacter;
2163 return SwitchInfo::SwitchString;
2166 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2168 RefPtr<Label> defaultLabel;
2169 Vector<RefPtr<Label>, 8> labelVector;
2170 Vector<ExpressionNode*, 8> literalVector;
2171 int32_t min_num = std::numeric_limits<int32_t>::max();
2172 int32_t max_num = std::numeric_limits<int32_t>::min();
2173 SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
2175 if (switchType != SwitchInfo::SwitchNone) {
2176 // Prepare the various labels
2177 for (uint32_t i = 0; i < literalVector.size(); i++)
2178 labelVector.append(generator.newLabel());
2179 defaultLabel = generator.newLabel();
2180 generator.beginSwitch(switchExpression, switchType);
2183 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2184 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2185 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2186 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2187 labelVector.append(generator.newLabel());
2188 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2191 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2192 RefPtr<RegisterID> clauseVal = generator.newTemporary();
2193 generator.emitNode(clauseVal.get(), list->getClause()->expr());
2194 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2195 labelVector.append(generator.newLabel());
2196 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2198 defaultLabel = generator.newLabel();
2199 generator.emitJump(defaultLabel.get());
2202 RegisterID* result = 0;
2205 for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
2206 generator.emitLabel(labelVector[i++].get());
2207 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2210 if (m_defaultClause) {
2211 generator.emitLabel(defaultLabel.get());
2212 result = statementListEmitCode(m_defaultClause->children(), generator, dst);
2215 for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
2216 generator.emitLabel(labelVector[i++].get());
2217 result = statementListEmitCode(list->getClause()->children(), generator, dst);
2219 if (!m_defaultClause)
2220 generator.emitLabel(defaultLabel.get());
2222 ASSERT(i == labelVector.size());
2223 if (switchType != SwitchInfo::SwitchNone) {
2224 ASSERT(labelVector.size() == literalVector.size());
2225 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2230 // ------------------------------ SwitchNode -----------------------------------
2232 SwitchNode::~SwitchNode()
2234 NodeReleaser::releaseAllNodes(this);
2237 void SwitchNode::releaseNodes(NodeReleaser& releaser)
2239 releaser.release(m_expr);
2240 releaser.release(m_block);
2243 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2245 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
2247 RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
2248 RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2250 generator.emitLabel(scope->breakTarget());
2254 // ------------------------------ LabelNode ------------------------------------
2256 LabelNode::~LabelNode()
2258 NodeReleaser::releaseAllNodes(this);
2261 void LabelNode::releaseNodes(NodeReleaser& releaser)
2263 releaser.release(m_statement);
2266 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2268 if (generator.breakTarget(m_name))
2269 return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
2271 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2272 RegisterID* r0 = generator.emitNode(dst, m_statement.get());
2274 generator.emitLabel(scope->breakTarget());
2278 // ------------------------------ ThrowNode ------------------------------------
2280 ThrowNode::~ThrowNode()
2282 NodeReleaser::releaseAllNodes(this);
2285 void ThrowNode::releaseNodes(NodeReleaser& releaser)
2287 releaser.release(m_expr);
2290 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2292 if (dst == generator.ignoredResult())
2294 RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
2295 generator.emitExpressionInfo(divot(), startOffset(), endOffset());
2296 generator.emitThrow(expr.get());
2300 // ------------------------------ TryNode --------------------------------------
2304 NodeReleaser::releaseAllNodes(this);
2307 void TryNode::releaseNodes(NodeReleaser& releaser)
2309 releaser.release(m_tryBlock);
2310 releaser.release(m_catchBlock);
2311 releaser.release(m_finallyBlock);
2314 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2316 RefPtr<Label> tryStartLabel = generator.newLabel();
2317 RefPtr<Label> tryEndLabel = generator.newLabel();
2318 RefPtr<Label> finallyStart;
2319 RefPtr<RegisterID> finallyReturnAddr;
2320 if (m_finallyBlock) {
2321 finallyStart = generator.newLabel();
2322 finallyReturnAddr = generator.newTemporary();
2323 generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
2325 generator.emitLabel(tryStartLabel.get());
2326 generator.emitNode(dst, m_tryBlock.get());
2327 generator.emitLabel(tryEndLabel.get());
2330 RefPtr<Label> handlerEndLabel = generator.newLabel();
2331 generator.emitJump(handlerEndLabel.get());
2332 RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
2333 generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
2334 generator.emitNode(dst, m_catchBlock.get());
2335 generator.emitPopScope();
2336 generator.emitLabel(handlerEndLabel.get());
2339 if (m_finallyBlock) {
2340 generator.popFinallyContext();
2341 // there may be important registers live at the time we jump
2342 // to a finally block (such as for a return or throw) so we
2343 // ref the highest register ever used as a conservative
2344 // approach to not clobbering anything important
2345 RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
2346 RefPtr<Label> finallyEndLabel = generator.newLabel();
2347 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2348 // Use a label to record the subtle fact that sret will return to the
2349 // next instruction. sret is the only way to jump without an explicit label.
2350 generator.emitLabel(generator.newLabel().get());
2351 generator.emitJump(finallyEndLabel.get());
2353 // Finally block for exception path
2354 RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
2355 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
2356 // Use a label to record the subtle fact that sret will return to the
2357 // next instruction. sret is the only way to jump without an explicit label.
2358 generator.emitLabel(generator.newLabel().get());
2359 generator.emitThrow(tempExceptionRegister.get());
2361 // emit the finally block itself
2362 generator.emitLabel(finallyStart.get());
2363 generator.emitNode(dst, m_finallyBlock.get());
2364 generator.emitSubroutineReturn(finallyReturnAddr.get());
2366 generator.emitLabel(finallyEndLabel.get());
2372 // ------------------------------ ParameterNode -----------------------------
2374 ParameterNode::~ParameterNode()
2376 NodeReleaser::releaseAllNodes(this);
2379 void ParameterNode::releaseNodes(NodeReleaser& releaser)
2381 releaser.release(m_next);
2384 // -----------------------------ScopeNodeData ---------------------------
2386 ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
2387 : m_numConstants(numConstants)
2390 m_varStack = *varStack;
2392 m_functionStack = *funcStack;
2394 children->releaseContentsIntoVector(m_children);
2397 // ------------------------------ ScopeNode -----------------------------
2399 ScopeNode::ScopeNode(JSGlobalData* globalData)
2400 : StatementNode(globalData)
2401 , m_features(NoFeatures)
2403 #if ENABLE(OPCODE_SAMPLING)
2404 globalData->interpreter->sampler()->notifyOfScope(this);
2408 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
2409 : StatementNode(globalData)
2410 , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
2411 , m_features(features)
2414 #if ENABLE(OPCODE_SAMPLING)
2415 globalData->interpreter->sampler()->notifyOfScope(this);
2419 ScopeNode::~ScopeNode()
2421 NodeReleaser::releaseAllNodes(this);
2424 void ScopeNode::releaseNodes(NodeReleaser& releaser)
2428 size_t size = m_data->m_children.size();
2429 for (size_t i = 0; i < size; ++i)
2430 releaser.release(m_data->m_children[i]);
2433 // ------------------------------ ProgramNode -----------------------------
2435 ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2436 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2440 ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2442 return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
2445 // ------------------------------ EvalNode -----------------------------
2447 EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2448 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
2452 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2454 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2456 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2457 generator.emitLoad(dstRegister.get(), jsUndefined());
2458 statementListEmitCode(children(), generator, dstRegister.get());
2460 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2461 generator.emitEnd(dstRegister.get());
2465 void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
2467 ScopeChain scopeChain(scopeChainNode);
2468 JSGlobalObject* globalObject = scopeChain.globalObject();
2470 m_code.set(new EvalCodeBlock(this, globalObject, source().provider()));
2472 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2473 generator.generate();
2475 // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
2476 // so the entire ScopeNodeData cannot be destoyed.
2480 EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
2482 return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
2485 // ------------------------------ FunctionBodyNode -----------------------------
2487 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
2488 : ScopeNode(globalData)
2490 , m_parameterCount(0)
2495 FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2496 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
2498 , m_parameterCount(0)
2503 FunctionBodyNode::~FunctionBodyNode()
2505 ASSERT(!m_refCount);
2506 fastFree(m_parameters);
2509 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
2511 Vector<Identifier> parameters;
2512 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
2513 parameters.append(parameter->ident());
2514 size_t count = parameters.size();
2517 finishParsing(parameters.releaseBuffer(), count);
2520 void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
2522 ASSERT(!source().isNull());
2523 m_parameters = parameters;
2524 m_parameterCount = parameterCount;
2527 void FunctionBodyNode::mark()
2533 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
2535 return new FunctionBodyNode(globalData);
2538 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
2540 return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
2543 void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
2545 // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
2546 // calling Parser::parse<FunctionBodyNode>().
2548 scopeChainNode->globalData->parser->reparse(scopeChainNode->globalData, this);
2551 ScopeChain scopeChain(scopeChainNode);
2552 JSGlobalObject* globalObject = scopeChain.globalObject();
2554 m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
2556 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
2557 generator.generate();
2562 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2564 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2565 statementListEmitCode(children(), generator, generator.ignoredResult());
2566 if (!children().size() || !children().last()->isReturnNode()) {
2567 RegisterID* r0 = generator.emitLoad(0, jsUndefined());
2568 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2569 generator.emitReturn(r0);
2574 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2576 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
2578 RefPtr<RegisterID> dstRegister = generator.newTemporary();
2579 generator.emitLoad(dstRegister.get(), jsUndefined());
2580 statementListEmitCode(children(), generator, dstRegister.get());
2582 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2583 generator.emitEnd(dstRegister.get());
2587 void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
2589 ScopeChain scopeChain(scopeChainNode);
2590 JSGlobalObject* globalObject = scopeChain.globalObject();
2592 m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
2594 BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
2595 generator.generate();
2600 UString FunctionBodyNode::paramString() const
2603 for (size_t pos = 0; pos < m_parameterCount; ++pos) {
2606 s += parameters()[pos].ustring();
2612 Identifier* FunctionBodyNode::copyParameters()
2614 Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
2615 VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
2619 // ------------------------------ FuncDeclNode ---------------------------------
2621 FuncDeclNode::~FuncDeclNode()
2623 NodeReleaser::releaseAllNodes(this);
2626 void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
2628 releaser.release(m_parameter);
2629 releaser.release(m_body);
2632 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2634 return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2637 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2639 if (dst == generator.ignoredResult())
2644 // ------------------------------ FuncExprNode ---------------------------------
2646 FuncExprNode::~FuncExprNode()
2648 NodeReleaser::releaseAllNodes(this);
2651 void FuncExprNode::releaseNodes(NodeReleaser& releaser)
2653 releaser.release(m_parameter);
2654 releaser.release(m_body);
2657 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2659 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2662 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
2664 JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
2667 The Identifier in a FunctionExpression can be referenced from inside
2668 the FunctionExpression's FunctionBody to allow the function to call
2669 itself recursively. However, unlike in a FunctionDeclaration, the
2670 Identifier in a FunctionExpression cannot be referenced from and
2671 does not affect the scope enclosing the FunctionExpression.
2674 if (!m_ident.isNull()) {
2675 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
2676 func->scope().push(functionScopeObject);