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
; }
133 int startOffset() const { return m_startOffset
; }
134 int lineStartOffset() const { return m_lineStartOffset
; }
139 int m_lineStartOffset
;
142 class ExpressionNode
: public Node
{
144 ExpressionNode(const JSTokenLocation
&, ResultType
= ResultType::unknownType());
147 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* destination
= 0) = 0;
149 virtual bool isNumber() const { return false; }
150 virtual bool isString() const { return false; }
151 virtual bool isNull() const { return false; }
152 virtual bool isPure(BytecodeGenerator
&) const { return false; }
153 virtual bool isConstant() const { return false; }
154 virtual bool isLocation() const { return false; }
155 virtual bool isResolveNode() const { return false; }
156 virtual bool isBracketAccessorNode() const { return false; }
157 virtual bool isDotAccessorNode() const { return false; }
158 virtual bool isFuncExprNode() const { return false; }
159 virtual bool isCommaNode() const { return false; }
160 virtual bool isSimpleArray() const { return false; }
161 virtual bool isAdd() const { return false; }
162 virtual bool isSubtract() const { return false; }
163 virtual bool isBoolean() const { return false; }
165 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
*, Label
*, FallThroughMode
);
167 virtual ExpressionNode
* stripUnaryPlus() { return this; }
169 ResultType
resultDescriptor() const { return m_resultType
; }
172 ResultType m_resultType
;
175 class StatementNode
: public Node
{
177 StatementNode(const JSTokenLocation
&);
180 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
= 0) = 0;
182 void setLoc(unsigned firstLine
, unsigned lastLine
, int startOffset
, int lineStartOffset
);
183 unsigned firstLine() const { return lineNo(); }
184 unsigned lastLine() const { return m_lastLine
; }
186 virtual bool isEmptyStatement() const { return false; }
187 virtual bool isReturnNode() const { return false; }
188 virtual bool isExprStatement() const { return false; }
189 virtual bool isBreak() const { return false; }
190 virtual bool isContinue() const { return false; }
191 virtual bool isBlock() const { return false; }
197 class ConstantNode
: public ExpressionNode
{
199 ConstantNode(const JSTokenLocation
&, ResultType
);
200 virtual bool isPure(BytecodeGenerator
&) const { return true; }
201 virtual bool isConstant() const { return true; }
202 virtual JSValue
jsValue(BytecodeGenerator
&) const = 0;
204 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
205 void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
);
208 class NullNode
: public ConstantNode
{
210 NullNode(const JSTokenLocation
&);
213 virtual bool isNull() const { return true; }
214 virtual JSValue
jsValue(BytecodeGenerator
&) const { return jsNull(); }
217 class BooleanNode
: public ConstantNode
{
219 BooleanNode(const JSTokenLocation
&, bool value
);
220 bool value() { return m_value
; }
223 virtual bool isBoolean() const { return true; }
224 virtual JSValue
jsValue(BytecodeGenerator
&) const { return jsBoolean(m_value
); }
229 class NumberNode
: public ConstantNode
{
231 NumberNode(const JSTokenLocation
&, double value
);
232 double value() { return m_value
; }
233 void setValue(double value
) { m_value
= value
; }
236 virtual bool isNumber() const { return true; }
237 virtual JSValue
jsValue(BytecodeGenerator
&) const { return jsNumber(m_value
); }
242 class StringNode
: public ConstantNode
{
244 StringNode(const JSTokenLocation
&, const Identifier
&);
245 const Identifier
& value() { return m_value
; }
248 virtual bool isString() const { return true; }
249 virtual JSValue
jsValue(BytecodeGenerator
&) const;
251 const Identifier
& m_value
;
254 class ThrowableExpressionData
{
256 ThrowableExpressionData()
257 : m_divot(static_cast<uint32_t>(-1))
258 , m_divotStartOffset(static_cast<uint16_t>(-1))
259 , m_divotEndOffset(static_cast<uint16_t>(-1))
260 , m_divotLine(static_cast<uint32_t>(-1))
261 , m_divotLineStart(static_cast<uint32_t>(-1))
265 ThrowableExpressionData(unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
)
267 , m_divotStartOffset(startOffset
)
268 , m_divotEndOffset(endOffset
)
269 , m_divotLine(divotLine
)
270 , m_divotLineStart(divotLineStart
)
272 ASSERT(m_divot
>= m_divotLineStart
);
275 void setExceptionSourceCode(unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
)
277 ASSERT(divot
>= divotLineStart
);
279 m_divotStartOffset
= startOffset
;
280 m_divotEndOffset
= endOffset
;
281 m_divotLine
= divotLine
;
282 m_divotLineStart
= divotLineStart
;
285 uint32_t divot() const { return m_divot
; }
286 uint16_t divotStartOffset() const { return m_divotStartOffset
; }
287 uint16_t divotEndOffset() const { return m_divotEndOffset
; }
288 uint32_t divotLine() const { return m_divotLine
; }
289 uint32_t divotLineStart() const { return m_divotLineStart
; }
292 RegisterID
* emitThrowReferenceError(BytecodeGenerator
&, const String
& message
);
296 uint16_t m_divotStartOffset
;
297 uint16_t m_divotEndOffset
;
298 uint32_t m_divotLine
;
299 uint32_t m_divotLineStart
;
302 class ThrowableSubExpressionData
: public ThrowableExpressionData
{
304 ThrowableSubExpressionData()
305 : m_subexpressionDivotOffset(0)
306 , m_subexpressionEndOffset(0)
307 , m_subexpressionLineOffset(0)
308 , m_subexpressionLineStartOffset(0)
312 ThrowableSubExpressionData(unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
)
313 : ThrowableExpressionData(divot
, startOffset
, endOffset
, divotLine
, divotLineStart
)
314 , m_subexpressionDivotOffset(0)
315 , m_subexpressionEndOffset(0)
316 , m_subexpressionLineOffset(0)
317 , m_subexpressionLineStartOffset(0)
321 void setSubexpressionInfo(uint32_t subexpressionDivot
, uint16_t subexpressionOffset
, uint32_t subexpressionLine
, uint32_t subexpressionLineStart
)
323 ASSERT(subexpressionDivot
<= divot());
324 // Overflow means we can't do this safely, so just point at the primary divot,
325 // divotLine, or divotLineStart.
326 if ((divot() - subexpressionDivot
) & ~0xFFFF)
328 if ((divotLine() - subexpressionLine
) & ~0xFFFF)
330 if ((divotLineStart() - subexpressionLineStart
) & ~0xFFFF)
332 m_subexpressionDivotOffset
= divot() - subexpressionDivot
;
333 m_subexpressionEndOffset
= subexpressionOffset
;
334 m_subexpressionLineOffset
= divotLine() - subexpressionLine
;
335 m_subexpressionLineStartOffset
= divotLineStart() - subexpressionLineStart
;
338 unsigned subexpressionDivot() { return divot() - m_subexpressionDivotOffset
; }
339 unsigned subexpressionStartOffset() { return divotStartOffset() - m_subexpressionDivotOffset
; }
340 unsigned subexpressionEndOffset() { return m_subexpressionEndOffset
; }
341 unsigned subexpressionLine() { return divotLine() - m_subexpressionLineOffset
; }
342 unsigned subexpressionLineStart() { return divotLineStart() - m_subexpressionLineStartOffset
; }
345 uint16_t m_subexpressionDivotOffset
;
346 uint16_t m_subexpressionEndOffset
;
347 uint16_t m_subexpressionLineOffset
;
348 uint16_t m_subexpressionLineStartOffset
;
351 class ThrowablePrefixedSubExpressionData
: public ThrowableExpressionData
{
353 ThrowablePrefixedSubExpressionData()
354 : m_subexpressionDivotOffset(0)
355 , m_subexpressionStartOffset(0)
356 , m_subexpressionLineOffset(0)
357 , m_subexpressionLineStartOffset(0)
361 ThrowablePrefixedSubExpressionData(unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
)
362 : ThrowableExpressionData(divot
, startOffset
, endOffset
, divotLine
, divotLineStart
)
363 , m_subexpressionDivotOffset(0)
364 , m_subexpressionStartOffset(0)
365 , m_subexpressionLineOffset(0)
366 , m_subexpressionLineStartOffset(0)
370 void setSubexpressionInfo(uint32_t subexpressionDivot
, uint16_t subexpressionOffset
, uint32_t subexpressionLine
, uint32_t subexpressionLineStart
)
372 ASSERT(subexpressionDivot
>= divot());
373 // Overflow means we can't do this safely, so just point at the primary divot,
374 // divotLine, or divotLineStart.
375 if ((subexpressionDivot
- divot()) & ~0xFFFF)
377 if ((subexpressionLine
- divotLine()) & ~0xFFFF)
379 if ((subexpressionLineStart
- divotLineStart()) & ~0xFFFF)
381 m_subexpressionDivotOffset
= subexpressionDivot
- divot();
382 m_subexpressionStartOffset
= subexpressionOffset
;
383 m_subexpressionLineOffset
= subexpressionLine
- divotLine();
384 m_subexpressionLineStartOffset
= subexpressionLineStart
- divotLineStart();
387 unsigned subexpressionDivot() { return divot() + m_subexpressionDivotOffset
; }
388 unsigned subexpressionStartOffset() { return m_subexpressionStartOffset
; }
389 unsigned subexpressionEndOffset() { return divotEndOffset() + m_subexpressionDivotOffset
; }
390 unsigned subexpressionLine() { return divotLine() + m_subexpressionLineOffset
; }
391 unsigned subexpressionLineStart() { return divotLineStart() + m_subexpressionLineStartOffset
; }
394 uint16_t m_subexpressionDivotOffset
;
395 uint16_t m_subexpressionStartOffset
;
396 uint16_t m_subexpressionLineOffset
;
397 uint16_t m_subexpressionLineStartOffset
;
400 class RegExpNode
: public ExpressionNode
, public ThrowableExpressionData
{
402 RegExpNode(const JSTokenLocation
&, const Identifier
& pattern
, const Identifier
& flags
);
405 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
407 const Identifier
& m_pattern
;
408 const Identifier
& m_flags
;
411 class ThisNode
: public ExpressionNode
{
413 ThisNode(const JSTokenLocation
&);
416 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
419 class ResolveNode
: public ExpressionNode
{
421 ResolveNode(const JSTokenLocation
&, const Identifier
&, unsigned startOffset
, unsigned divotLine
, unsigned divotLineStart
);
423 const Identifier
& identifier() const { return m_ident
; }
426 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
428 virtual bool isPure(BytecodeGenerator
&) const ;
429 virtual bool isLocation() const { return true; }
430 virtual bool isResolveNode() const { return true; }
432 const Identifier
& m_ident
;
433 uint32_t m_startOffset
;
434 uint32_t m_divotLine
;
435 uint32_t m_divotLineStart
;
438 class ElementNode
: public ParserArenaFreeable
{
440 ElementNode(int elision
, ExpressionNode
*);
441 ElementNode(ElementNode
*, int elision
, ExpressionNode
*);
443 int elision() const { return m_elision
; }
444 ExpressionNode
* value() { return m_node
; }
445 ElementNode
* next() { return m_next
; }
450 ExpressionNode
* m_node
;
453 class ArrayNode
: public ExpressionNode
{
455 ArrayNode(const JSTokenLocation
&, int elision
);
456 ArrayNode(const JSTokenLocation
&, ElementNode
*);
457 ArrayNode(const JSTokenLocation
&, int elision
, ElementNode
*);
459 ArgumentListNode
* toArgumentList(VM
*, int, int) const;
462 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
464 virtual bool isSimpleArray() const ;
466 ElementNode
* m_element
;
471 class PropertyNode
: public ParserArenaFreeable
{
473 enum Type
{ Constant
= 1, Getter
= 2, Setter
= 4 };
475 PropertyNode(VM
*, const Identifier
&, ExpressionNode
*, Type
);
476 PropertyNode(VM
*, double, ExpressionNode
*, Type
);
478 const Identifier
& name() const { return m_name
; }
479 Type
type() const { return m_type
; }
482 friend class PropertyListNode
;
483 const Identifier
& m_name
;
484 ExpressionNode
* m_assign
;
488 class PropertyListNode
: public ExpressionNode
{
490 PropertyListNode(const JSTokenLocation
&, PropertyNode
*);
491 PropertyListNode(const JSTokenLocation
&, PropertyNode
*, PropertyListNode
*);
493 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
496 PropertyNode
* m_node
;
497 PropertyListNode
* m_next
;
500 class ObjectLiteralNode
: public ExpressionNode
{
502 ObjectLiteralNode(const JSTokenLocation
&);
503 ObjectLiteralNode(const JSTokenLocation
&, PropertyListNode
*);
506 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
508 PropertyListNode
* m_list
;
511 class BracketAccessorNode
: public ExpressionNode
, public ThrowableExpressionData
{
513 BracketAccessorNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, bool subscriptHasAssignments
);
515 ExpressionNode
* base() const { return m_base
; }
516 ExpressionNode
* subscript() const { return m_subscript
; }
518 bool subscriptHasAssignments() const { return m_subscriptHasAssignments
; }
521 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
523 virtual bool isLocation() const { return true; }
524 virtual bool isBracketAccessorNode() const { return true; }
526 ExpressionNode
* m_base
;
527 ExpressionNode
* m_subscript
;
528 bool m_subscriptHasAssignments
;
531 class DotAccessorNode
: public ExpressionNode
, public ThrowableExpressionData
{
533 DotAccessorNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&);
535 ExpressionNode
* base() const { return m_base
; }
536 const Identifier
& identifier() const { return m_ident
; }
539 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
541 virtual bool isLocation() const { return true; }
542 virtual bool isDotAccessorNode() const { return true; }
544 ExpressionNode
* m_base
;
545 const Identifier
& m_ident
;
548 class ArgumentListNode
: public ExpressionNode
{
550 ArgumentListNode(const JSTokenLocation
&, ExpressionNode
*);
551 ArgumentListNode(const JSTokenLocation
&, ArgumentListNode
*, ExpressionNode
*);
553 ArgumentListNode
* m_next
;
554 ExpressionNode
* m_expr
;
557 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
560 class ArgumentsNode
: public ParserArenaFreeable
{
563 ArgumentsNode(ArgumentListNode
*);
565 ArgumentListNode
* m_listNode
;
568 class NewExprNode
: public ExpressionNode
, public ThrowableExpressionData
{
570 NewExprNode(const JSTokenLocation
&, ExpressionNode
*);
571 NewExprNode(const JSTokenLocation
&, ExpressionNode
*, ArgumentsNode
*);
574 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
576 ExpressionNode
* m_expr
;
577 ArgumentsNode
* m_args
;
580 class EvalFunctionCallNode
: public ExpressionNode
, public ThrowableExpressionData
{
582 EvalFunctionCallNode(const JSTokenLocation
&, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
585 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
587 ArgumentsNode
* m_args
;
590 class FunctionCallValueNode
: public ExpressionNode
, public ThrowableExpressionData
{
592 FunctionCallValueNode(const JSTokenLocation
&, ExpressionNode
*, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
595 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
597 ExpressionNode
* m_expr
;
598 ArgumentsNode
* m_args
;
601 class FunctionCallResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
603 FunctionCallResolveNode(const JSTokenLocation
&, const Identifier
&, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
606 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
608 const Identifier
& m_ident
;
609 ArgumentsNode
* m_args
;
612 class FunctionCallBracketNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
614 FunctionCallBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
617 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
619 ExpressionNode
* m_base
;
620 ExpressionNode
* m_subscript
;
621 ArgumentsNode
* m_args
;
624 class FunctionCallDotNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
626 FunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
629 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
632 ExpressionNode
* m_base
;
633 const Identifier
& m_ident
;
634 ArgumentsNode
* m_args
;
637 class CallFunctionCallDotNode
: public FunctionCallDotNode
{
639 CallFunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
642 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
645 class ApplyFunctionCallDotNode
: public FunctionCallDotNode
{
647 ApplyFunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
650 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
653 class DeleteResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
655 DeleteResolveNode(const JSTokenLocation
&, const Identifier
&, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
658 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
660 const Identifier
& m_ident
;
663 class DeleteBracketNode
: public ExpressionNode
, public ThrowableExpressionData
{
665 DeleteBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
668 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
670 ExpressionNode
* m_base
;
671 ExpressionNode
* m_subscript
;
674 class DeleteDotNode
: public ExpressionNode
, public ThrowableExpressionData
{
676 DeleteDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
679 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
681 ExpressionNode
* m_base
;
682 const Identifier
& m_ident
;
685 class DeleteValueNode
: public ExpressionNode
{
687 DeleteValueNode(const JSTokenLocation
&, ExpressionNode
*);
690 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
692 ExpressionNode
* m_expr
;
695 class VoidNode
: public ExpressionNode
{
697 VoidNode(const JSTokenLocation
&, ExpressionNode
*);
700 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
702 ExpressionNode
* m_expr
;
705 class TypeOfResolveNode
: public ExpressionNode
{
707 TypeOfResolveNode(const JSTokenLocation
&, const Identifier
&);
709 const Identifier
& identifier() const { return m_ident
; }
712 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
714 const Identifier
& m_ident
;
717 class TypeOfValueNode
: public ExpressionNode
{
719 TypeOfValueNode(const JSTokenLocation
&, ExpressionNode
*);
722 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
724 ExpressionNode
* m_expr
;
727 class PrefixNode
: public ExpressionNode
, public ThrowablePrefixedSubExpressionData
{
729 PrefixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
732 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
733 virtual RegisterID
* emitResolve(BytecodeGenerator
&, RegisterID
* = 0);
734 virtual RegisterID
* emitBracket(BytecodeGenerator
&, RegisterID
* = 0);
735 virtual RegisterID
* emitDot(BytecodeGenerator
&, RegisterID
* = 0);
737 ExpressionNode
* m_expr
;
741 class PostfixNode
: public PrefixNode
{
743 PostfixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
746 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
747 virtual RegisterID
* emitResolve(BytecodeGenerator
&, RegisterID
* = 0);
748 virtual RegisterID
* emitBracket(BytecodeGenerator
&, RegisterID
* = 0);
749 virtual RegisterID
* emitDot(BytecodeGenerator
&, RegisterID
* = 0);
752 class UnaryOpNode
: public ExpressionNode
{
754 UnaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
*, OpcodeID
);
757 ExpressionNode
* expr() { return m_expr
; }
758 const ExpressionNode
* expr() const { return m_expr
; }
761 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
763 OpcodeID
opcodeID() const { return m_opcodeID
; }
765 ExpressionNode
* m_expr
;
769 class UnaryPlusNode
: public UnaryOpNode
{
771 UnaryPlusNode(const JSTokenLocation
&, ExpressionNode
*);
774 virtual ExpressionNode
* stripUnaryPlus() { return expr(); }
777 class NegateNode
: public UnaryOpNode
{
779 NegateNode(const JSTokenLocation
&, ExpressionNode
*);
782 class BitwiseNotNode
: public ExpressionNode
{
784 BitwiseNotNode(const JSTokenLocation
&, ExpressionNode
*);
787 ExpressionNode
* expr() { return m_expr
; }
788 const ExpressionNode
* expr() const { return m_expr
; }
791 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
793 ExpressionNode
* m_expr
;
796 class LogicalNotNode
: public UnaryOpNode
{
798 LogicalNotNode(const JSTokenLocation
&, ExpressionNode
*);
800 void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
);
803 class BinaryOpNode
: public ExpressionNode
{
805 BinaryOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
806 BinaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
808 RegisterID
* emitStrcat(BytecodeGenerator
& generator
, RegisterID
* destination
, RegisterID
* lhs
= 0, ReadModifyResolveNode
* emitExpressionInfoForMe
= 0);
809 void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
);
811 ExpressionNode
* lhs() { return m_expr1
; };
812 ExpressionNode
* rhs() { return m_expr2
; };
815 void tryFoldToBranch(BytecodeGenerator
&, TriState
& branchCondition
, ExpressionNode
*& branchExpression
);
816 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
819 OpcodeID
opcodeID() const { return m_opcodeID
; }
822 ExpressionNode
* m_expr1
;
823 ExpressionNode
* m_expr2
;
827 bool m_rightHasAssignments
;
830 class MultNode
: public BinaryOpNode
{
832 MultNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
835 class DivNode
: public BinaryOpNode
{
837 DivNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
840 class ModNode
: public BinaryOpNode
{
842 ModNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
845 class AddNode
: public BinaryOpNode
{
847 AddNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
849 virtual bool isAdd() const { return true; }
852 class SubNode
: public BinaryOpNode
{
854 SubNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
856 virtual bool isSubtract() const { return true; }
859 class LeftShiftNode
: public BinaryOpNode
{
861 LeftShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
864 class RightShiftNode
: public BinaryOpNode
{
866 RightShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
869 class UnsignedRightShiftNode
: public BinaryOpNode
{
871 UnsignedRightShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
874 class LessNode
: public BinaryOpNode
{
876 LessNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
879 class GreaterNode
: public BinaryOpNode
{
881 GreaterNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
884 class LessEqNode
: public BinaryOpNode
{
886 LessEqNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
889 class GreaterEqNode
: public BinaryOpNode
{
891 GreaterEqNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
894 class ThrowableBinaryOpNode
: public BinaryOpNode
, public ThrowableExpressionData
{
896 ThrowableBinaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
897 ThrowableBinaryOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
900 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
903 class InstanceOfNode
: public ThrowableBinaryOpNode
{
905 InstanceOfNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
908 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
911 class InNode
: public ThrowableBinaryOpNode
{
913 InNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
916 class EqualNode
: public BinaryOpNode
{
918 EqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
921 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
924 class NotEqualNode
: public BinaryOpNode
{
926 NotEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
929 class StrictEqualNode
: public BinaryOpNode
{
931 StrictEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
934 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
937 class NotStrictEqualNode
: public BinaryOpNode
{
939 NotStrictEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
942 class BitAndNode
: public BinaryOpNode
{
944 BitAndNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
947 class BitOrNode
: public BinaryOpNode
{
949 BitOrNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
952 class BitXOrNode
: public BinaryOpNode
{
954 BitXOrNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
957 // m_expr1 && m_expr2, m_expr1 || m_expr2
958 class LogicalOpNode
: public ExpressionNode
{
960 LogicalOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, LogicalOperator
);
963 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
964 void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
);
966 ExpressionNode
* m_expr1
;
967 ExpressionNode
* m_expr2
;
968 LogicalOperator m_operator
;
971 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
972 class ConditionalNode
: public ExpressionNode
{
974 ConditionalNode(const JSTokenLocation
&, ExpressionNode
* logical
, ExpressionNode
* expr1
, ExpressionNode
* expr2
);
977 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
979 ExpressionNode
* m_logical
;
980 ExpressionNode
* m_expr1
;
981 ExpressionNode
* m_expr2
;
984 class ReadModifyResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
986 ReadModifyResolveNode(const JSTokenLocation
&, const Identifier
&, Operator
, ExpressionNode
* right
, bool rightHasAssignments
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned line
, unsigned lineStart
);
989 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
991 const Identifier
& m_ident
;
992 ExpressionNode
* m_right
;
994 bool m_rightHasAssignments
;
997 class AssignResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
999 AssignResolveNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
* right
);
1002 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1004 const Identifier
& m_ident
;
1005 ExpressionNode
* m_right
;
1008 class ReadModifyBracketNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
1010 ReadModifyBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, Operator
, ExpressionNode
* right
, bool subscriptHasAssignments
, bool rightHasAssignments
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
1013 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1015 ExpressionNode
* m_base
;
1016 ExpressionNode
* m_subscript
;
1017 ExpressionNode
* m_right
;
1018 Operator m_operator
: 30;
1019 bool m_subscriptHasAssignments
: 1;
1020 bool m_rightHasAssignments
: 1;
1023 class AssignBracketNode
: public ExpressionNode
, public ThrowableExpressionData
{
1025 AssignBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, ExpressionNode
* right
, bool subscriptHasAssignments
, bool rightHasAssignments
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
1028 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1030 ExpressionNode
* m_base
;
1031 ExpressionNode
* m_subscript
;
1032 ExpressionNode
* m_right
;
1033 bool m_subscriptHasAssignments
: 1;
1034 bool m_rightHasAssignments
: 1;
1037 class AssignDotNode
: public ExpressionNode
, public ThrowableExpressionData
{
1039 AssignDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ExpressionNode
* right
, bool rightHasAssignments
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
1042 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1044 ExpressionNode
* m_base
;
1045 const Identifier
& m_ident
;
1046 ExpressionNode
* m_right
;
1047 bool m_rightHasAssignments
;
1050 class ReadModifyDotNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
1052 ReadModifyDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, Operator
, ExpressionNode
* right
, bool rightHasAssignments
, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
1055 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1057 ExpressionNode
* m_base
;
1058 const Identifier
& m_ident
;
1059 ExpressionNode
* m_right
;
1060 Operator m_operator
: 31;
1061 bool m_rightHasAssignments
: 1;
1064 class AssignErrorNode
: public ExpressionNode
, public ThrowableExpressionData
{
1066 AssignErrorNode(const JSTokenLocation
&, unsigned divot
, unsigned startOffset
, unsigned endOffset
, unsigned divotLine
, unsigned divotLineStart
);
1069 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1072 typedef Vector
<ExpressionNode
*, 8> ExpressionVector
;
1074 class CommaNode
: public ExpressionNode
, public ParserArenaDeletable
{
1076 CommaNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
);
1078 using ParserArenaDeletable::operator new;
1080 void append(ExpressionNode
* expr
) { m_expressions
.append(expr
); }
1083 virtual bool isCommaNode() const { return true; }
1084 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1086 ExpressionVector m_expressions
;
1089 class ConstDeclNode
: public ExpressionNode
{
1091 ConstDeclNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
*);
1093 bool hasInitializer() const { return m_init
; }
1094 const Identifier
& ident() { return m_ident
; }
1097 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1098 virtual RegisterID
* emitCodeSingle(BytecodeGenerator
&);
1100 const Identifier
& m_ident
;
1103 ConstDeclNode
* m_next
;
1106 ExpressionNode
* m_init
;
1109 class ConstStatementNode
: public StatementNode
{
1111 ConstStatementNode(const JSTokenLocation
&, ConstDeclNode
* next
);
1114 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1116 ConstDeclNode
* m_next
;
1119 class SourceElements
: public ParserArenaDeletable
{
1123 void append(StatementNode
*);
1125 StatementNode
* singleStatement() const;
1126 StatementNode
* lastStatement() const;
1128 void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1131 Vector
<StatementNode
*> m_statements
;
1134 class BlockNode
: public StatementNode
{
1136 BlockNode(const JSTokenLocation
&, SourceElements
* = 0);
1138 StatementNode
* singleStatement() const;
1139 StatementNode
* lastStatement() const;
1142 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1144 virtual bool isBlock() const { return true; }
1146 SourceElements
* m_statements
;
1149 class EmptyStatementNode
: public StatementNode
{
1151 EmptyStatementNode(const JSTokenLocation
&);
1154 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1156 virtual bool isEmptyStatement() const { return true; }
1159 class DebuggerStatementNode
: public StatementNode
{
1161 DebuggerStatementNode(const JSTokenLocation
&);
1164 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1167 class ExprStatementNode
: public StatementNode
{
1169 ExprStatementNode(const JSTokenLocation
&, ExpressionNode
*);
1171 ExpressionNode
* expr() const { return m_expr
; }
1174 virtual bool isExprStatement() const { return true; }
1176 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1178 ExpressionNode
* m_expr
;
1181 class VarStatementNode
: public StatementNode
{
1183 VarStatementNode(const JSTokenLocation
&, ExpressionNode
*);
1185 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1187 ExpressionNode
* m_expr
;
1190 class IfElseNode
: public StatementNode
{
1192 IfElseNode(const JSTokenLocation
&, ExpressionNode
* condition
, StatementNode
* ifBlock
, StatementNode
* elseBlock
);
1195 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1196 bool tryFoldBreakAndContinue(BytecodeGenerator
&, StatementNode
* ifBlock
,
1197 Label
*& trueTarget
, FallThroughMode
&);
1199 ExpressionNode
* m_condition
;
1200 StatementNode
* m_ifBlock
;
1201 StatementNode
* m_elseBlock
;
1204 class DoWhileNode
: public StatementNode
{
1206 DoWhileNode(const JSTokenLocation
&, StatementNode
*, ExpressionNode
*);
1209 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1211 StatementNode
* m_statement
;
1212 ExpressionNode
* m_expr
;
1215 class WhileNode
: public StatementNode
{
1217 WhileNode(const JSTokenLocation
&, ExpressionNode
*, StatementNode
*);
1220 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1222 ExpressionNode
* m_expr
;
1223 StatementNode
* m_statement
;
1226 class ForNode
: public StatementNode
{
1228 ForNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, ExpressionNode
* expr3
, StatementNode
*);
1231 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1233 ExpressionNode
* m_expr1
;
1234 ExpressionNode
* m_expr2
;
1235 ExpressionNode
* m_expr3
;
1236 StatementNode
* m_statement
;
1239 class ForInNode
: public StatementNode
, public ThrowableExpressionData
{
1241 ForInNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1242 ForInNode(VM
*, const JSTokenLocation
&, const Identifier
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*, unsigned divot
, int startOffset
, int endOffset
, unsigned divotLine
, unsigned divotLineStart
);
1245 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1247 ExpressionNode
* m_init
;
1248 ExpressionNode
* m_lexpr
;
1249 ExpressionNode
* m_expr
;
1250 StatementNode
* m_statement
;
1253 class ContinueNode
: public StatementNode
, public ThrowableExpressionData
{
1255 ContinueNode(VM
*, const JSTokenLocation
&);
1256 ContinueNode(const JSTokenLocation
&, const Identifier
&);
1257 Label
* trivialTarget(BytecodeGenerator
&);
1260 virtual bool isContinue() const { return true; }
1261 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1263 const Identifier
& m_ident
;
1266 class BreakNode
: public StatementNode
, public ThrowableExpressionData
{
1268 BreakNode(VM
*, const JSTokenLocation
&);
1269 BreakNode(const JSTokenLocation
&, const Identifier
&);
1270 Label
* trivialTarget(BytecodeGenerator
&);
1273 virtual bool isBreak() const { return true; }
1274 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1276 const Identifier
& m_ident
;
1279 class ReturnNode
: public StatementNode
, public ThrowableExpressionData
{
1281 ReturnNode(const JSTokenLocation
&, ExpressionNode
* value
);
1283 ExpressionNode
* value() { return m_value
; }
1286 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1288 virtual bool isReturnNode() const { return true; }
1290 ExpressionNode
* m_value
;
1293 class WithNode
: public StatementNode
{
1295 WithNode(const JSTokenLocation
&, ExpressionNode
*, StatementNode
*, uint32_t divot
, unsigned divotLine
, unsigned divotLineStart
, uint32_t expressionLength
);
1298 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1300 ExpressionNode
* m_expr
;
1301 StatementNode
* m_statement
;
1303 uint32_t m_divotLine
;
1304 uint32_t m_divotLineStart
;
1305 uint32_t m_expressionLength
;
1308 class LabelNode
: public StatementNode
, public ThrowableExpressionData
{
1310 LabelNode(const JSTokenLocation
&, const Identifier
& name
, StatementNode
*);
1313 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1315 const Identifier
& m_name
;
1316 StatementNode
* m_statement
;
1319 class ThrowNode
: public StatementNode
, public ThrowableExpressionData
{
1321 ThrowNode(const JSTokenLocation
&, ExpressionNode
*);
1324 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1326 ExpressionNode
* m_expr
;
1329 class TryNode
: public StatementNode
{
1331 TryNode(const JSTokenLocation
&, StatementNode
* tryBlock
, const Identifier
& exceptionIdent
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
);
1334 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1336 StatementNode
* m_tryBlock
;
1337 const Identifier
& m_exceptionIdent
;
1338 StatementNode
* m_catchBlock
;
1339 StatementNode
* m_finallyBlock
;
1342 class ParameterNode
: public ParserArenaFreeable
{
1344 ParameterNode(const Identifier
&);
1345 ParameterNode(ParameterNode
*, const Identifier
&);
1347 const Identifier
& ident() const { return m_ident
; }
1348 ParameterNode
* nextParam() const { return m_next
; }
1351 const Identifier
& m_ident
;
1352 ParameterNode
* m_next
;
1355 class ScopeNode
: public StatementNode
, public ParserArenaRefCounted
{
1357 typedef DeclarationStacks::VarStack VarStack
;
1358 typedef DeclarationStacks::FunctionStack FunctionStack
;
1360 ScopeNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, bool inStrictContext
);
1361 ScopeNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, const SourceCode
&, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, CodeFeatures
, int numConstants
);
1363 using ParserArenaRefCounted::operator new;
1369 m_functionStack
.clear();
1371 m_capturedVariables
.clear();
1374 const SourceCode
& source() const { return m_source
; }
1375 const String
& sourceURL() const { return m_source
.provider()->url(); }
1376 intptr_t sourceID() const { return m_source
.providerID(); }
1378 int startLine() const { return m_startLineNumber
; }
1379 int startStartOffset() const { return m_startStartOffset
; }
1380 int startLineStartOffset() const { return m_startLineStartOffset
; }
1382 void setFeatures(CodeFeatures features
) { m_features
= features
; }
1383 CodeFeatures
features() { return m_features
; }
1385 bool usesEval() const { return m_features
& EvalFeature
; }
1386 bool usesArguments() const { return (m_features
& ArgumentsFeature
) && !(m_features
& ShadowsArgumentsFeature
); }
1387 bool isStrictMode() const { return m_features
& StrictModeFeature
; }
1388 void setUsesArguments() { m_features
|= ArgumentsFeature
; }
1389 bool usesThis() const { return m_features
& ThisFeature
; }
1390 bool needsActivationForMoreThanVariables() const { return m_features
& (EvalFeature
| WithFeature
| CatchFeature
); }
1391 bool needsActivation() const { return (hasCapturedVariables()) || (m_features
& (EvalFeature
| WithFeature
| CatchFeature
)); }
1392 bool hasCapturedVariables() const { return !!m_capturedVariables
.size(); }
1393 size_t capturedVariableCount() const { return m_capturedVariables
.size(); }
1394 bool captures(const Identifier
& ident
) { return m_capturedVariables
.contains(ident
.impl()); }
1396 VarStack
& varStack() { return m_varStack
; }
1397 FunctionStack
& functionStack() { return m_functionStack
; }
1399 int neededConstants()
1401 // We may need 2 more constants than the count given by the parser,
1402 // because of the various uses of jsUndefined() and jsNull().
1403 return m_numConstants
+ 2;
1406 StatementNode
* singleStatement() const;
1408 void emitStatementsBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1411 void setSource(const SourceCode
& source
) { m_source
= source
; }
1412 ParserArena m_arena
;
1414 int m_startLineNumber
;
1415 unsigned m_startStartOffset
;
1416 unsigned m_startLineStartOffset
;
1419 CodeFeatures m_features
;
1420 SourceCode m_source
;
1421 VarStack m_varStack
;
1422 FunctionStack m_functionStack
;
1424 SourceElements
* m_statements
;
1425 IdentifierSet m_capturedVariables
;
1428 class ProgramNode
: public ScopeNode
{
1430 static const bool isFunctionNode
= false;
1431 static PassRefPtr
<ProgramNode
> create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1433 unsigned startColumn() { return m_startColumn
; }
1435 static const bool scopeIsFunction
= false;
1438 ProgramNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1440 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1442 unsigned m_startColumn
;
1445 class EvalNode
: public ScopeNode
{
1447 static const bool isFunctionNode
= false;
1448 static PassRefPtr
<EvalNode
> create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1450 unsigned startColumn() { return 1; }
1452 static const bool scopeIsFunction
= false;
1455 EvalNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1457 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1460 class FunctionParameters
: public RefCounted
<FunctionParameters
> {
1461 WTF_MAKE_FAST_ALLOCATED
;
1463 static PassRefPtr
<FunctionParameters
> create(ParameterNode
*);
1464 ~FunctionParameters();
1466 unsigned size() const { return m_size
; }
1467 const Identifier
& at(unsigned index
) const { ASSERT(index
< m_size
); return identifiers()[index
]; }
1470 FunctionParameters(ParameterNode
*, unsigned size
);
1472 Identifier
* identifiers() { return reinterpret_cast<Identifier
*>(&m_storage
); }
1473 const Identifier
* identifiers() const { return reinterpret_cast<const Identifier
*>(&m_storage
); }
1479 class FunctionBodyNode
: public ScopeNode
{
1481 static const bool isFunctionNode
= true;
1482 static FunctionBodyNode
* create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, bool isStrictMode
);
1483 static PassRefPtr
<FunctionBodyNode
> create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1485 FunctionParameters
* parameters() const { return m_parameters
.get(); }
1486 size_t parameterCount() const { return m_parameters
->size(); }
1488 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1490 void finishParsing(const SourceCode
&, ParameterNode
*, const Identifier
&, FunctionNameIsInScopeToggle
);
1491 void finishParsing(PassRefPtr
<FunctionParameters
>, const Identifier
&, FunctionNameIsInScopeToggle
);
1493 const Identifier
& ident() { return m_ident
; }
1494 void setInferredName(const Identifier
& inferredName
) { ASSERT(!inferredName
.isNull()); m_inferredName
= inferredName
; }
1495 const Identifier
& inferredName() { return m_inferredName
.isEmpty() ? m_ident
: m_inferredName
; }
1497 bool functionNameIsInScope() { return m_functionNameIsInScopeToggle
== FunctionNameIsInScope
; }
1498 FunctionNameIsInScopeToggle
functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle
; }
1500 void setFunctionStart(int functionStart
) { m_functionStart
= functionStart
; }
1501 int functionStart() const { return m_functionStart
; }
1502 unsigned startColumn() const { return m_startColumn
; }
1504 static const bool scopeIsFunction
= true;
1507 FunctionBodyNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, bool inStrictContext
);
1508 FunctionBodyNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1511 Identifier m_inferredName
;
1512 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle
;
1513 RefPtr
<FunctionParameters
> m_parameters
;
1514 int m_functionStart
;
1515 unsigned m_startColumn
;
1518 class FuncExprNode
: public ExpressionNode
{
1520 FuncExprNode(const JSTokenLocation
&, const Identifier
&, FunctionBodyNode
*, const SourceCode
&, ParameterNode
* = 0);
1522 FunctionBodyNode
* body() { return m_body
; }
1525 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1527 virtual bool isFuncExprNode() const { return true; }
1529 FunctionBodyNode
* m_body
;
1532 class FuncDeclNode
: public StatementNode
{
1534 FuncDeclNode(const JSTokenLocation
&, const Identifier
&, FunctionBodyNode
*, const SourceCode
&, ParameterNode
* = 0);
1536 FunctionBodyNode
* body() { return m_body
; }
1539 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1541 FunctionBodyNode
* m_body
;
1544 class CaseClauseNode
: public ParserArenaFreeable
{
1546 CaseClauseNode(ExpressionNode
*, SourceElements
* = 0);
1548 ExpressionNode
* expr() const { return m_expr
; }
1550 void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1553 ExpressionNode
* m_expr
;
1554 SourceElements
* m_statements
;
1557 class ClauseListNode
: public ParserArenaFreeable
{
1559 ClauseListNode(CaseClauseNode
*);
1560 ClauseListNode(ClauseListNode
*, CaseClauseNode
*);
1562 CaseClauseNode
* getClause() const { return m_clause
; }
1563 ClauseListNode
* getNext() const { return m_next
; }
1566 CaseClauseNode
* m_clause
;
1567 ClauseListNode
* m_next
;
1570 class CaseBlockNode
: public ParserArenaFreeable
{
1572 CaseBlockNode(ClauseListNode
* list1
, CaseClauseNode
* defaultClause
, ClauseListNode
* list2
);
1574 void emitBytecodeForBlock(BytecodeGenerator
&, RegisterID
* input
, RegisterID
* destination
);
1577 SwitchInfo::SwitchType
tryTableSwitch(Vector
<ExpressionNode
*, 8>& literalVector
, int32_t& min_num
, int32_t& max_num
);
1578 static const size_t s_tableSwitchMinimum
= 10;
1579 ClauseListNode
* m_list1
;
1580 CaseClauseNode
* m_defaultClause
;
1581 ClauseListNode
* m_list2
;
1584 class SwitchNode
: public StatementNode
{
1586 SwitchNode(const JSTokenLocation
&, ExpressionNode
*, CaseBlockNode
*);
1589 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0);
1591 ExpressionNode
* m_expr
;
1592 CaseBlockNode
* m_block
;
1595 struct ElementList
{
1600 struct PropertyList
{
1601 PropertyListNode
* head
;
1602 PropertyListNode
* tail
;
1605 struct ArgumentList
{
1606 ArgumentListNode
* head
;
1607 ArgumentListNode
* tail
;
1610 struct ConstDeclList
{
1611 ConstDeclNode
* head
;
1612 ConstDeclNode
* tail
;
1615 struct ParameterList
{
1616 ParameterNode
* head
;
1617 ParameterNode
* tail
;
1621 ClauseListNode
* head
;
1622 ClauseListNode
* tail
;