2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 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.
32 #include "ParserArena.h"
33 #include "ParserTokens.h"
34 #include "ResultType.h"
35 #include "SourceCode.h"
36 #include "SymbolTable.h"
37 #include <wtf/MathExtras.h>
41 class ArgumentListNode;
42 class BytecodeGenerator;
43 class FunctionBodyNode;
45 class PropertyListNode;
46 class ReadModifyResolveNode;
68 enum LogicalOperator {
73 enum FallThroughMode {
74 FallThroughMeansTrue = 0,
75 FallThroughMeansFalse = 1
77 inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
79 typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
81 namespace DeclarationStacks {
82 enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
83 typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
84 typedef Vector<FunctionBodyNode*> FunctionStack;
88 enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
89 uint32_t bytecodeOffset;
90 SwitchType switchType;
93 class ParserArenaFreeable {
95 // ParserArenaFreeable objects are are freed when the arena is deleted.
96 // Destructors are not called. Clients must not call delete on such objects.
97 void* operator new(size_t, VM*);
100 class ParserArenaDeletable {
102 virtual ~ParserArenaDeletable() { }
104 // ParserArenaDeletable objects are deleted when the arena is deleted.
105 // Clients must not call delete directly on such objects.
106 void* operator new(size_t, VM*);
109 template <typename T>
110 struct ParserArenaData : ParserArenaDeletable {
114 class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
116 ParserArenaRefCounted(VM*);
119 virtual ~ParserArenaRefCounted()
121 ASSERT(deletionHasBegun());
125 class Node : public ParserArenaFreeable {
127 Node(const JSTokenLocation&);
132 int lineNo() const { return m_lineNumber; }
134 int charPosition() const { return m_charPosition; }
141 class ExpressionNode : public Node {
143 ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
146 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
148 virtual bool isNumber() const { return false; }
149 virtual bool isString() const { return false; }
150 virtual bool isNull() const { return false; }
151 virtual bool isPure(BytecodeGenerator&) const { return false; }
152 virtual bool isConstant() const { return false; }
153 virtual bool isLocation() const { return false; }
154 virtual bool isResolveNode() const { return false; }
155 virtual bool isBracketAccessorNode() const { return false; }
156 virtual bool isDotAccessorNode() const { return false; }
157 virtual bool isFuncExprNode() const { return false; }
158 virtual bool isCommaNode() const { return false; }
159 virtual bool isSimpleArray() const { return false; }
160 virtual bool isAdd() const { return false; }
161 virtual bool isSubtract() const { return false; }
162 virtual bool isBoolean() const { return false; }
164 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
166 virtual ExpressionNode* stripUnaryPlus() { return this; }
168 ResultType resultDescriptor() const { return m_resultType; }
171 ResultType m_resultType;
174 class StatementNode : public Node {
176 StatementNode(const JSTokenLocation&);
179 virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
181 void setLoc(int firstLine, int lastLine, int charPosition);
182 int firstLine() const { return lineNo(); }
183 int lastLine() const { return m_lastLine; }
185 virtual bool isEmptyStatement() const { return false; }
186 virtual bool isReturnNode() const { return false; }
187 virtual bool isExprStatement() const { return false; }
188 virtual bool isBreak() const { return false; }
189 virtual bool isContinue() const { return false; }
190 virtual bool isBlock() const { return false; }
196 class ConstantNode : public ExpressionNode {
198 ConstantNode(const JSTokenLocation&, ResultType);
199 virtual bool isPure(BytecodeGenerator&) const { return true; }
200 virtual bool isConstant() const { return true; }
201 virtual JSValue jsValue(BytecodeGenerator&) const = 0;
203 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
204 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
207 class NullNode : public ConstantNode {
209 NullNode(const JSTokenLocation&);
212 virtual bool isNull() const { return true; }
213 virtual JSValue jsValue(BytecodeGenerator&) const { return jsNull(); }
216 class BooleanNode : public ConstantNode {
218 BooleanNode(const JSTokenLocation&, bool value);
219 bool value() { return m_value; }
222 virtual bool isBoolean() const { return true; }
223 virtual JSValue jsValue(BytecodeGenerator&) const { return jsBoolean(m_value); }
228 class NumberNode : public ConstantNode {
230 NumberNode(const JSTokenLocation&, double value);
231 double value() { return m_value; }
232 void setValue(double value) { m_value = value; }
235 virtual bool isNumber() const { return true; }
236 virtual JSValue jsValue(BytecodeGenerator&) const { return jsNumber(m_value); }
241 class StringNode : public ConstantNode {
243 StringNode(const JSTokenLocation&, const Identifier&);
244 const Identifier& value() { return m_value; }
247 virtual bool isString() const { return true; }
248 virtual JSValue jsValue(BytecodeGenerator&) const;
250 const Identifier& m_value;
253 class ThrowableExpressionData {
255 ThrowableExpressionData()
256 : m_divot(static_cast<uint32_t>(-1))
257 , m_startOffset(static_cast<uint16_t>(-1))
258 , m_endOffset(static_cast<uint16_t>(-1))
262 ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
264 , m_startOffset(startOffset)
265 , m_endOffset(endOffset)
269 void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
272 m_startOffset = startOffset;
273 m_endOffset = endOffset;
276 uint32_t divot() const { return m_divot; }
277 uint16_t startOffset() const { return m_startOffset; }
278 uint16_t endOffset() const { return m_endOffset; }
281 RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
285 uint16_t m_startOffset;
286 uint16_t m_endOffset;
289 class ThrowableSubExpressionData : public ThrowableExpressionData {
291 ThrowableSubExpressionData()
292 : m_subexpressionDivotOffset(0)
293 , m_subexpressionEndOffset(0)
297 ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
298 : ThrowableExpressionData(divot, startOffset, endOffset)
299 , m_subexpressionDivotOffset(0)
300 , m_subexpressionEndOffset(0)
304 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
306 ASSERT(subexpressionDivot <= divot());
307 if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
309 m_subexpressionDivotOffset = divot() - subexpressionDivot;
310 m_subexpressionEndOffset = subexpressionOffset;
314 uint16_t m_subexpressionDivotOffset;
315 uint16_t m_subexpressionEndOffset;
318 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
320 ThrowablePrefixedSubExpressionData()
321 : m_subexpressionDivotOffset(0)
322 , m_subexpressionStartOffset(0)
326 ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
327 : ThrowableExpressionData(divot, startOffset, endOffset)
328 , m_subexpressionDivotOffset(0)
329 , m_subexpressionStartOffset(0)
333 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
335 ASSERT(subexpressionDivot >= divot());
336 if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
338 m_subexpressionDivotOffset = subexpressionDivot - divot();
339 m_subexpressionStartOffset = subexpressionOffset;
343 uint16_t m_subexpressionDivotOffset;
344 uint16_t m_subexpressionStartOffset;
347 class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
349 RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
352 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
354 const Identifier& m_pattern;
355 const Identifier& m_flags;
358 class ThisNode : public ExpressionNode {
360 ThisNode(const JSTokenLocation&);
363 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
366 class ResolveNode : public ExpressionNode {
368 ResolveNode(const JSTokenLocation&, const Identifier&, int startOffset);
370 const Identifier& identifier() const { return m_ident; }
373 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
375 virtual bool isPure(BytecodeGenerator&) const ;
376 virtual bool isLocation() const { return true; }
377 virtual bool isResolveNode() const { return true; }
379 const Identifier& m_ident;
380 int32_t m_startOffset;
383 class ElementNode : public ParserArenaFreeable {
385 ElementNode(int elision, ExpressionNode*);
386 ElementNode(ElementNode*, int elision, ExpressionNode*);
388 int elision() const { return m_elision; }
389 ExpressionNode* value() { return m_node; }
390 ElementNode* next() { return m_next; }
395 ExpressionNode* m_node;
398 class ArrayNode : public ExpressionNode {
400 ArrayNode(const JSTokenLocation&, int elision);
401 ArrayNode(const JSTokenLocation&, ElementNode*);
402 ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
404 ArgumentListNode* toArgumentList(VM*, int, int) const;
407 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
409 virtual bool isSimpleArray() const ;
411 ElementNode* m_element;
416 class PropertyNode : public ParserArenaFreeable {
418 enum Type { Constant = 1, Getter = 2, Setter = 4 };
420 PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
421 PropertyNode(VM*, double, ExpressionNode*, Type);
423 const Identifier& name() const { return m_name; }
424 Type type() const { return m_type; }
427 friend class PropertyListNode;
428 const Identifier& m_name;
429 ExpressionNode* m_assign;
433 class PropertyListNode : public ExpressionNode {
435 PropertyListNode(const JSTokenLocation&, PropertyNode*);
436 PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
438 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
441 PropertyNode* m_node;
442 PropertyListNode* m_next;
445 class ObjectLiteralNode : public ExpressionNode {
447 ObjectLiteralNode(const JSTokenLocation&);
448 ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
451 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
453 PropertyListNode* m_list;
456 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
458 BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
460 ExpressionNode* base() const { return m_base; }
461 ExpressionNode* subscript() const { return m_subscript; }
463 bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
466 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
468 virtual bool isLocation() const { return true; }
469 virtual bool isBracketAccessorNode() const { return true; }
471 ExpressionNode* m_base;
472 ExpressionNode* m_subscript;
473 bool m_subscriptHasAssignments;
476 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
478 DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
480 ExpressionNode* base() const { return m_base; }
481 const Identifier& identifier() const { return m_ident; }
484 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
486 virtual bool isLocation() const { return true; }
487 virtual bool isDotAccessorNode() const { return true; }
489 ExpressionNode* m_base;
490 const Identifier& m_ident;
493 class ArgumentListNode : public ExpressionNode {
495 ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
496 ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
498 ArgumentListNode* m_next;
499 ExpressionNode* m_expr;
502 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
505 class ArgumentsNode : public ParserArenaFreeable {
508 ArgumentsNode(ArgumentListNode*);
510 ArgumentListNode* m_listNode;
513 class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
515 NewExprNode(const JSTokenLocation&, ExpressionNode*);
516 NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
519 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
521 ExpressionNode* m_expr;
522 ArgumentsNode* m_args;
525 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
527 EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
530 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
532 ArgumentsNode* m_args;
535 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
537 FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
540 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
542 ExpressionNode* m_expr;
543 ArgumentsNode* m_args;
546 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
548 FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
551 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
553 const Identifier& m_ident;
554 ArgumentsNode* m_args;
557 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
559 FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
562 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
564 ExpressionNode* m_base;
565 ExpressionNode* m_subscript;
566 ArgumentsNode* m_args;
569 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
571 FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
574 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
577 ExpressionNode* m_base;
578 const Identifier& m_ident;
579 ArgumentsNode* m_args;
582 class CallFunctionCallDotNode : public FunctionCallDotNode {
584 CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
587 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
590 class ApplyFunctionCallDotNode : public FunctionCallDotNode {
592 ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
595 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
598 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
600 DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
603 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
605 const Identifier& m_ident;
608 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
610 DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
613 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
615 ExpressionNode* m_base;
616 ExpressionNode* m_subscript;
619 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
621 DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
624 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
626 ExpressionNode* m_base;
627 const Identifier& m_ident;
630 class DeleteValueNode : public ExpressionNode {
632 DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
635 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
637 ExpressionNode* m_expr;
640 class VoidNode : public ExpressionNode {
642 VoidNode(const JSTokenLocation&, ExpressionNode*);
645 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
647 ExpressionNode* m_expr;
650 class TypeOfResolveNode : public ExpressionNode {
652 TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
654 const Identifier& identifier() const { return m_ident; }
657 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
659 const Identifier& m_ident;
662 class TypeOfValueNode : public ExpressionNode {
664 TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
667 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
669 ExpressionNode* m_expr;
672 class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
674 PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
677 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
678 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
679 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
680 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
682 ExpressionNode* m_expr;
686 class PostfixNode : public PrefixNode {
688 PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
691 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
692 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
693 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
694 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
697 class UnaryOpNode : public ExpressionNode {
699 UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
702 ExpressionNode* expr() { return m_expr; }
703 const ExpressionNode* expr() const { return m_expr; }
706 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
708 OpcodeID opcodeID() const { return m_opcodeID; }
710 ExpressionNode* m_expr;
714 class UnaryPlusNode : public UnaryOpNode {
716 UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
719 virtual ExpressionNode* stripUnaryPlus() { return expr(); }
722 class NegateNode : public UnaryOpNode {
724 NegateNode(const JSTokenLocation&, ExpressionNode*);
727 class BitwiseNotNode : public ExpressionNode {
729 BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
732 ExpressionNode* expr() { return m_expr; }
733 const ExpressionNode* expr() const { return m_expr; }
736 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
738 ExpressionNode* m_expr;
741 class LogicalNotNode : public UnaryOpNode {
743 LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
745 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
748 class BinaryOpNode : public ExpressionNode {
750 BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
751 BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
753 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
754 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
756 ExpressionNode* lhs() { return m_expr1; };
757 ExpressionNode* rhs() { return m_expr2; };
760 void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
761 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
764 OpcodeID opcodeID() const { return m_opcodeID; }
767 ExpressionNode* m_expr1;
768 ExpressionNode* m_expr2;
772 bool m_rightHasAssignments;
775 class MultNode : public BinaryOpNode {
777 MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
780 class DivNode : public BinaryOpNode {
782 DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
785 class ModNode : public BinaryOpNode {
787 ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
790 class AddNode : public BinaryOpNode {
792 AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
794 virtual bool isAdd() const { return true; }
797 class SubNode : public BinaryOpNode {
799 SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
801 virtual bool isSubtract() const { return true; }
804 class LeftShiftNode : public BinaryOpNode {
806 LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
809 class RightShiftNode : public BinaryOpNode {
811 RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
814 class UnsignedRightShiftNode : public BinaryOpNode {
816 UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
819 class LessNode : public BinaryOpNode {
821 LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
824 class GreaterNode : public BinaryOpNode {
826 GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
829 class LessEqNode : public BinaryOpNode {
831 LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
834 class GreaterEqNode : public BinaryOpNode {
836 GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
839 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
841 ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
842 ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
845 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
848 class InstanceOfNode : public ThrowableBinaryOpNode {
850 InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
853 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
856 class InNode : public ThrowableBinaryOpNode {
858 InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
861 class EqualNode : public BinaryOpNode {
863 EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
866 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
869 class NotEqualNode : public BinaryOpNode {
871 NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
874 class StrictEqualNode : public BinaryOpNode {
876 StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
879 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
882 class NotStrictEqualNode : public BinaryOpNode {
884 NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
887 class BitAndNode : public BinaryOpNode {
889 BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
892 class BitOrNode : public BinaryOpNode {
894 BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
897 class BitXOrNode : public BinaryOpNode {
899 BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
902 // m_expr1 && m_expr2, m_expr1 || m_expr2
903 class LogicalOpNode : public ExpressionNode {
905 LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
908 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
909 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
911 ExpressionNode* m_expr1;
912 ExpressionNode* m_expr2;
913 LogicalOperator m_operator;
916 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
917 class ConditionalNode : public ExpressionNode {
919 ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
922 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
924 ExpressionNode* m_logical;
925 ExpressionNode* m_expr1;
926 ExpressionNode* m_expr2;
929 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
931 ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
934 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
936 const Identifier& m_ident;
937 ExpressionNode* m_right;
939 bool m_rightHasAssignments;
942 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
944 AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
947 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
949 const Identifier& m_ident;
950 ExpressionNode* m_right;
953 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
955 ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
958 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
960 ExpressionNode* m_base;
961 ExpressionNode* m_subscript;
962 ExpressionNode* m_right;
963 Operator m_operator : 30;
964 bool m_subscriptHasAssignments : 1;
965 bool m_rightHasAssignments : 1;
968 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
970 AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
973 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
975 ExpressionNode* m_base;
976 ExpressionNode* m_subscript;
977 ExpressionNode* m_right;
978 bool m_subscriptHasAssignments : 1;
979 bool m_rightHasAssignments : 1;
982 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
984 AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
987 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
989 ExpressionNode* m_base;
990 const Identifier& m_ident;
991 ExpressionNode* m_right;
992 bool m_rightHasAssignments;
995 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
997 ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1000 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1002 ExpressionNode* m_base;
1003 const Identifier& m_ident;
1004 ExpressionNode* m_right;
1005 Operator m_operator : 31;
1006 bool m_rightHasAssignments : 1;
1009 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1011 AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset);
1014 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1017 typedef Vector<ExpressionNode*, 8> ExpressionVector;
1019 class CommaNode : public ExpressionNode, public ParserArenaDeletable {
1021 CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
1023 using ParserArenaDeletable::operator new;
1025 void append(ExpressionNode* expr) { m_expressions.append(expr); }
1028 virtual bool isCommaNode() const { return true; }
1029 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1031 ExpressionVector m_expressions;
1034 class ConstDeclNode : public ExpressionNode {
1036 ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
1038 bool hasInitializer() const { return m_init; }
1039 const Identifier& ident() { return m_ident; }
1042 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1043 virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
1045 const Identifier& m_ident;
1048 ConstDeclNode* m_next;
1051 ExpressionNode* m_init;
1054 class ConstStatementNode : public StatementNode {
1056 ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
1059 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1061 ConstDeclNode* m_next;
1064 class SourceElements : public ParserArenaDeletable {
1068 void append(StatementNode*);
1070 StatementNode* singleStatement() const;
1071 StatementNode* lastStatement() const;
1073 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1076 Vector<StatementNode*> m_statements;
1079 class BlockNode : public StatementNode {
1081 BlockNode(const JSTokenLocation&, SourceElements* = 0);
1083 StatementNode* singleStatement() const;
1084 StatementNode* lastStatement() const;
1087 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1089 virtual bool isBlock() const { return true; }
1091 SourceElements* m_statements;
1094 class EmptyStatementNode : public StatementNode {
1096 EmptyStatementNode(const JSTokenLocation&);
1099 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1101 virtual bool isEmptyStatement() const { return true; }
1104 class DebuggerStatementNode : public StatementNode {
1106 DebuggerStatementNode(const JSTokenLocation&);
1109 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1112 class ExprStatementNode : public StatementNode {
1114 ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
1116 ExpressionNode* expr() const { return m_expr; }
1119 virtual bool isExprStatement() const { return true; }
1121 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1123 ExpressionNode* m_expr;
1126 class VarStatementNode : public StatementNode {
1128 VarStatementNode(const JSTokenLocation&, ExpressionNode*);
1130 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1132 ExpressionNode* m_expr;
1135 class IfElseNode : public StatementNode {
1137 IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1140 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1141 bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
1142 Label*& trueTarget, FallThroughMode&);
1144 ExpressionNode* m_condition;
1145 StatementNode* m_ifBlock;
1146 StatementNode* m_elseBlock;
1149 class DoWhileNode : public StatementNode {
1151 DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
1154 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1156 StatementNode* m_statement;
1157 ExpressionNode* m_expr;
1160 class WhileNode : public StatementNode {
1162 WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
1165 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1167 ExpressionNode* m_expr;
1168 StatementNode* m_statement;
1171 class ForNode : public StatementNode {
1173 ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
1176 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1178 ExpressionNode* m_expr1;
1179 ExpressionNode* m_expr2;
1180 ExpressionNode* m_expr3;
1181 StatementNode* m_statement;
1184 class ForInNode : public StatementNode, public ThrowableExpressionData {
1186 ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1187 ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
1190 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1192 ExpressionNode* m_init;
1193 ExpressionNode* m_lexpr;
1194 ExpressionNode* m_expr;
1195 StatementNode* m_statement;
1198 class ContinueNode : public StatementNode, public ThrowableExpressionData {
1200 ContinueNode(VM*, const JSTokenLocation&);
1201 ContinueNode(const JSTokenLocation&, const Identifier&);
1202 Label* trivialTarget(BytecodeGenerator&);
1205 virtual bool isContinue() const { return true; }
1206 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1208 const Identifier& m_ident;
1211 class BreakNode : public StatementNode, public ThrowableExpressionData {
1213 BreakNode(VM*, const JSTokenLocation&);
1214 BreakNode(const JSTokenLocation&, const Identifier&);
1215 Label* trivialTarget(BytecodeGenerator&);
1218 virtual bool isBreak() const { return true; }
1219 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1221 const Identifier& m_ident;
1224 class ReturnNode : public StatementNode, public ThrowableExpressionData {
1226 ReturnNode(const JSTokenLocation&, ExpressionNode* value);
1228 ExpressionNode* value() { return m_value; }
1231 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1233 virtual bool isReturnNode() const { return true; }
1235 ExpressionNode* m_value;
1238 class WithNode : public StatementNode {
1240 WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
1243 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1245 ExpressionNode* m_expr;
1246 StatementNode* m_statement;
1248 uint32_t m_expressionLength;
1251 class LabelNode : public StatementNode, public ThrowableExpressionData {
1253 LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
1256 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1258 const Identifier& m_name;
1259 StatementNode* m_statement;
1262 class ThrowNode : public StatementNode, public ThrowableExpressionData {
1264 ThrowNode(const JSTokenLocation&, ExpressionNode*);
1267 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1269 ExpressionNode* m_expr;
1272 class TryNode : public StatementNode {
1274 TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
1277 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1279 StatementNode* m_tryBlock;
1280 const Identifier& m_exceptionIdent;
1281 StatementNode* m_catchBlock;
1282 StatementNode* m_finallyBlock;
1285 class ParameterNode : public ParserArenaFreeable {
1287 ParameterNode(const Identifier&);
1288 ParameterNode(ParameterNode*, const Identifier&);
1290 const Identifier& ident() const { return m_ident; }
1291 ParameterNode* nextParam() const { return m_next; }
1294 const Identifier& m_ident;
1295 ParameterNode* m_next;
1298 class ScopeNode : public StatementNode, public ParserArenaRefCounted {
1300 typedef DeclarationStacks::VarStack VarStack;
1301 typedef DeclarationStacks::FunctionStack FunctionStack;
1303 ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
1304 ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
1306 using ParserArenaRefCounted::operator new;
1312 m_functionStack.clear();
1314 m_capturedVariables.clear();
1317 const SourceCode& source() const { return m_source; }
1318 const String& sourceURL() const { return m_source.provider()->url(); }
1319 intptr_t sourceID() const { return m_source.providerID(); }
1321 int startLine() const { return m_startLineNumber; }
1322 int startCharPosition() const { return m_startCharPosition;}
1324 void setFeatures(CodeFeatures features) { m_features = features; }
1325 CodeFeatures features() { return m_features; }
1327 bool usesEval() const { return m_features & EvalFeature; }
1328 bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
1329 bool isStrictMode() const { return m_features & StrictModeFeature; }
1330 void setUsesArguments() { m_features |= ArgumentsFeature; }
1331 bool usesThis() const { return m_features & ThisFeature; }
1332 bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
1333 bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
1334 bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
1335 size_t capturedVariableCount() const { return m_capturedVariables.size(); }
1336 bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
1338 VarStack& varStack() { return m_varStack; }
1339 FunctionStack& functionStack() { return m_functionStack; }
1341 int neededConstants()
1343 // We may need 2 more constants than the count given by the parser,
1344 // because of the various uses of jsUndefined() and jsNull().
1345 return m_numConstants + 2;
1348 StatementNode* singleStatement() const;
1350 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
1353 void setSource(const SourceCode& source) { m_source = source; }
1354 ParserArena m_arena;
1356 int m_startLineNumber;
1357 int m_startCharPosition;
1360 CodeFeatures m_features;
1361 SourceCode m_source;
1362 VarStack m_varStack;
1363 FunctionStack m_functionStack;
1365 SourceElements* m_statements;
1366 IdentifierSet m_capturedVariables;
1369 class ProgramNode : public ScopeNode {
1371 static const bool isFunctionNode = false;
1372 static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1374 static const bool scopeIsFunction = false;
1377 ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1379 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1382 class EvalNode : public ScopeNode {
1384 static const bool isFunctionNode = false;
1385 static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1387 static const bool scopeIsFunction = false;
1390 EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1392 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1395 class FunctionParameters : public RefCounted<FunctionParameters> {
1396 WTF_MAKE_FAST_ALLOCATED;
1398 static PassRefPtr<FunctionParameters> create(ParameterNode*);
1399 ~FunctionParameters();
1401 unsigned size() const { return m_size; }
1402 const Identifier& at(unsigned index) const { ASSERT(index < m_size); return identifiers()[index]; }
1405 FunctionParameters(ParameterNode*, unsigned size);
1407 Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
1408 const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
1414 class FunctionBodyNode : public ScopeNode {
1416 static const bool isFunctionNode = true;
1417 static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool isStrictMode);
1418 static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1420 FunctionParameters* parameters() const { return m_parameters.get(); }
1421 size_t parameterCount() const { return m_parameters->size(); }
1423 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1425 void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
1426 void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
1428 const Identifier& ident() { return m_ident; }
1429 void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
1430 const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
1432 bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; }
1433 FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
1435 void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
1436 int functionStart() const { return m_functionStart; }
1438 static const bool scopeIsFunction = true;
1441 FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
1442 FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1445 Identifier m_inferredName;
1446 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
1447 RefPtr<FunctionParameters> m_parameters;
1448 int m_functionStart;
1451 class FuncExprNode : public ExpressionNode {
1453 FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1455 FunctionBodyNode* body() { return m_body; }
1458 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1460 virtual bool isFuncExprNode() const { return true; }
1462 FunctionBodyNode* m_body;
1465 class FuncDeclNode : public StatementNode {
1467 FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1469 FunctionBodyNode* body() { return m_body; }
1472 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1474 FunctionBodyNode* m_body;
1477 class CaseClauseNode : public ParserArenaFreeable {
1479 CaseClauseNode(ExpressionNode*, SourceElements* = 0);
1481 ExpressionNode* expr() const { return m_expr; }
1483 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1486 ExpressionNode* m_expr;
1487 SourceElements* m_statements;
1490 class ClauseListNode : public ParserArenaFreeable {
1492 ClauseListNode(CaseClauseNode*);
1493 ClauseListNode(ClauseListNode*, CaseClauseNode*);
1495 CaseClauseNode* getClause() const { return m_clause; }
1496 ClauseListNode* getNext() const { return m_next; }
1499 CaseClauseNode* m_clause;
1500 ClauseListNode* m_next;
1503 class CaseBlockNode : public ParserArenaFreeable {
1505 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1507 void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
1510 SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
1511 static const size_t s_tableSwitchMinimum = 10;
1512 ClauseListNode* m_list1;
1513 CaseClauseNode* m_defaultClause;
1514 ClauseListNode* m_list2;
1517 class SwitchNode : public StatementNode {
1519 SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
1522 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1524 ExpressionNode* m_expr;
1525 CaseBlockNode* m_block;
1528 struct ElementList {
1533 struct PropertyList {
1534 PropertyListNode* head;
1535 PropertyListNode* tail;
1538 struct ArgumentList {
1539 ArgumentListNode* head;
1540 ArgumentListNode* tail;
1543 struct ConstDeclList {
1544 ConstDeclNode* head;
1545 ConstDeclNode* tail;
1548 struct ParameterList {
1549 ParameterNode* head;
1550 ParameterNode* tail;
1554 ClauseListNode* head;
1555 ClauseListNode* tail;