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, 2015 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
<UniquedStringImpl
>, IdentifierRepHash
> IdentifierSet
;
81 namespace DeclarationStacks
{
82 enum VarAttrs
{ IsConstant
= 1, HasInitializer
= 2 };
83 typedef Vector
<std::pair
<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, ParserArena
&);
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, ParserArena
&);
109 class ParserArenaRoot
{
110 WTF_MAKE_FAST_ALLOCATED
;
112 ParserArenaRoot(ParserArena
&);
115 ParserArena
& parserArena() { return m_arena
; }
116 virtual ~ParserArenaRoot() { }
122 class Node
: public ParserArenaFreeable
{
124 Node(const JSTokenLocation
&);
129 int firstLine() const { return m_position
.line
; }
130 int startOffset() const { return m_position
.offset
; }
131 int endOffset() const { return m_endOffset
; }
132 int lineStartOffset() const { return m_position
.lineStartOffset
; }
133 const JSTextPosition
& position() const { return m_position
; }
134 void setEndOffset(int offset
) { m_endOffset
= offset
; }
135 void setStartOffset(int offset
) { m_position
.offset
= offset
; }
138 JSTextPosition m_position
;
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 isAssignmentLocation() const { return isLocation(); }
156 virtual bool isResolveNode() const { return false; }
157 virtual bool isBracketAccessorNode() const { return false; }
158 virtual bool isDotAccessorNode() const { return false; }
159 virtual bool isDestructuringNode() const { return false; }
160 virtual bool isFuncExprNode() const { return false; }
161 virtual bool isCommaNode() const { return false; }
162 virtual bool isSimpleArray() const { return false; }
163 virtual bool isAdd() const { return false; }
164 virtual bool isSubtract() const { return false; }
165 virtual bool isBoolean() const { return false; }
166 virtual bool isSpreadExpression() const { return false; }
167 virtual bool isSuperNode() const { return false; }
169 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
*, Label
*, FallThroughMode
);
171 virtual ExpressionNode
* stripUnaryPlus() { return this; }
173 ResultType
resultDescriptor() const { return m_resultType
; }
176 ResultType m_resultType
;
179 class StatementNode
: public Node
{
181 StatementNode(const JSTokenLocation
&);
184 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
= 0) = 0;
186 void setLoc(unsigned firstLine
, unsigned lastLine
, int startOffset
, int lineStartOffset
);
187 unsigned lastLine() const { return m_lastLine
; }
189 StatementNode
* next() { return m_next
; }
190 void setNext(StatementNode
* next
) { m_next
= next
; }
192 virtual bool isEmptyStatement() const { return false; }
193 virtual bool isReturnNode() const { return false; }
194 virtual bool isExprStatement() const { return false; }
195 virtual bool isBreak() const { return false; }
196 virtual bool isContinue() const { return false; }
197 virtual bool isBlock() const { return false; }
198 virtual bool isFuncDeclNode() const { return false; }
201 StatementNode
* m_next
;
205 class ConstantNode
: public ExpressionNode
{
207 ConstantNode(const JSTokenLocation
&, ResultType
);
208 virtual bool isPure(BytecodeGenerator
&) const override
{ return true; }
209 virtual bool isConstant() const override
{ return true; }
210 virtual JSValue
jsValue(BytecodeGenerator
&) const = 0;
212 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
213 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
216 class NullNode
: public ConstantNode
{
218 NullNode(const JSTokenLocation
&);
221 virtual bool isNull() const override
{ return true; }
222 virtual JSValue
jsValue(BytecodeGenerator
&) const override
{ return jsNull(); }
225 class BooleanNode
: public ConstantNode
{
227 BooleanNode(const JSTokenLocation
&, bool value
);
228 bool value() { return m_value
; }
231 virtual bool isBoolean() const override
{ return true; }
232 virtual JSValue
jsValue(BytecodeGenerator
&) const override
{ return jsBoolean(m_value
); }
237 class NumberNode
: public ConstantNode
{
239 NumberNode(const JSTokenLocation
&, double value
);
240 double value() const { return m_value
; }
241 virtual bool isIntegerNode() const = 0;
242 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override final
;
245 virtual bool isNumber() const override final
{ return true; }
246 virtual JSValue
jsValue(BytecodeGenerator
&) const override
{ return jsNumber(m_value
); }
251 class DoubleNode
: public NumberNode
{
253 DoubleNode(const JSTokenLocation
&, double value
);
256 virtual bool isIntegerNode() const override
{ return false; }
259 // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0)
260 class IntegerNode
: public DoubleNode
{
262 IntegerNode(const JSTokenLocation
&, double value
);
263 virtual bool isIntegerNode() const override final
{ return true; }
266 class StringNode
: public ConstantNode
{
268 StringNode(const JSTokenLocation
&, const Identifier
&);
269 const Identifier
& value() { return m_value
; }
272 virtual bool isString() const override
{ return true; }
273 virtual JSValue
jsValue(BytecodeGenerator
&) const override
;
275 const Identifier
& m_value
;
278 class ThrowableExpressionData
{
280 ThrowableExpressionData()
281 : m_divot(-1, -1, -1)
282 , m_divotStart(-1, -1, -1)
283 , m_divotEnd(-1, -1, -1)
287 ThrowableExpressionData(const JSTextPosition
& divot
, const JSTextPosition
& start
, const JSTextPosition
& end
)
289 , m_divotStart(start
)
292 ASSERT(m_divot
.offset
>= m_divot
.lineStartOffset
);
293 ASSERT(m_divotStart
.offset
>= m_divotStart
.lineStartOffset
);
294 ASSERT(m_divotEnd
.offset
>= m_divotEnd
.lineStartOffset
);
297 void setExceptionSourceCode(const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
)
299 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
300 ASSERT(divotStart
.offset
>= divotStart
.lineStartOffset
);
301 ASSERT(divotEnd
.offset
>= divotEnd
.lineStartOffset
);
303 m_divotStart
= divotStart
;
304 m_divotEnd
= divotEnd
;
307 const JSTextPosition
& divot() const { return m_divot
; }
308 const JSTextPosition
& divotStart() const { return m_divotStart
; }
309 const JSTextPosition
& divotEnd() const { return m_divotEnd
; }
312 RegisterID
* emitThrowReferenceError(BytecodeGenerator
&, const String
& message
);
315 JSTextPosition m_divot
;
316 JSTextPosition m_divotStart
;
317 JSTextPosition m_divotEnd
;
320 class ThrowableSubExpressionData
: public ThrowableExpressionData
{
322 ThrowableSubExpressionData()
323 : m_subexpressionDivotOffset(0)
324 , m_subexpressionEndOffset(0)
325 , m_subexpressionLineOffset(0)
326 , m_subexpressionLineStartOffset(0)
330 ThrowableSubExpressionData(const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
)
331 : ThrowableExpressionData(divot
, divotStart
, divotEnd
)
332 , m_subexpressionDivotOffset(0)
333 , m_subexpressionEndOffset(0)
334 , m_subexpressionLineOffset(0)
335 , m_subexpressionLineStartOffset(0)
339 void setSubexpressionInfo(const JSTextPosition
& subexpressionDivot
, int subexpressionOffset
)
341 ASSERT(subexpressionDivot
.offset
<= divot().offset
);
342 // Overflow means we can't do this safely, so just point at the primary divot,
343 // divotLine, or divotLineStart.
344 if ((divot() - subexpressionDivot
.offset
) & ~0xFFFF)
346 if ((divot().line
- subexpressionDivot
.line
) & ~0xFFFF)
348 if ((divot().lineStartOffset
- subexpressionDivot
.lineStartOffset
) & ~0xFFFF)
350 if ((divotEnd() - subexpressionOffset
) & ~0xFFFF)
352 m_subexpressionDivotOffset
= divot() - subexpressionDivot
.offset
;
353 m_subexpressionEndOffset
= divotEnd() - subexpressionOffset
;
354 m_subexpressionLineOffset
= divot().line
- subexpressionDivot
.line
;
355 m_subexpressionLineStartOffset
= divot().lineStartOffset
- subexpressionDivot
.lineStartOffset
;
358 JSTextPosition
subexpressionDivot()
360 int newLine
= divot().line
- m_subexpressionLineOffset
;
361 int newOffset
= divot().offset
- m_subexpressionDivotOffset
;
362 int newLineStartOffset
= divot().lineStartOffset
- m_subexpressionLineStartOffset
;
363 return JSTextPosition(newLine
, newOffset
, newLineStartOffset
);
365 JSTextPosition
subexpressionStart() { return divotStart(); }
366 JSTextPosition
subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset
); }
369 uint16_t m_subexpressionDivotOffset
;
370 uint16_t m_subexpressionEndOffset
;
371 uint16_t m_subexpressionLineOffset
;
372 uint16_t m_subexpressionLineStartOffset
;
375 class ThrowablePrefixedSubExpressionData
: public ThrowableExpressionData
{
377 ThrowablePrefixedSubExpressionData()
378 : m_subexpressionDivotOffset(0)
379 , m_subexpressionStartOffset(0)
380 , m_subexpressionLineOffset(0)
381 , m_subexpressionLineStartOffset(0)
385 ThrowablePrefixedSubExpressionData(const JSTextPosition
& divot
, const JSTextPosition
& start
, const JSTextPosition
& end
)
386 : ThrowableExpressionData(divot
, start
, end
)
387 , m_subexpressionDivotOffset(0)
388 , m_subexpressionStartOffset(0)
389 , m_subexpressionLineOffset(0)
390 , m_subexpressionLineStartOffset(0)
394 void setSubexpressionInfo(const JSTextPosition
& subexpressionDivot
, int subexpressionOffset
)
396 ASSERT(subexpressionDivot
.offset
>= divot().offset
);
397 // Overflow means we can't do this safely, so just point at the primary divot,
398 // divotLine, or divotLineStart.
399 if ((subexpressionDivot
.offset
- divot()) & ~0xFFFF)
401 if ((subexpressionDivot
.line
- divot().line
) & ~0xFFFF)
403 if ((subexpressionDivot
.lineStartOffset
- divot().lineStartOffset
) & ~0xFFFF)
405 if ((subexpressionOffset
- divotStart()) & ~0xFFFF)
407 m_subexpressionDivotOffset
= subexpressionDivot
.offset
- divot();
408 m_subexpressionStartOffset
= subexpressionOffset
- divotStart();
409 m_subexpressionLineOffset
= subexpressionDivot
.line
- divot().line
;
410 m_subexpressionLineStartOffset
= subexpressionDivot
.lineStartOffset
- divot().lineStartOffset
;
413 JSTextPosition
subexpressionDivot()
415 int newLine
= divot().line
+ m_subexpressionLineOffset
;
416 int newOffset
= divot().offset
+ m_subexpressionDivotOffset
;
417 int newLineStartOffset
= divot().lineStartOffset
+ m_subexpressionLineStartOffset
;
418 return JSTextPosition(newLine
, newOffset
, newLineStartOffset
);
420 JSTextPosition
subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset
); }
421 JSTextPosition
subexpressionEnd() { return divotEnd(); }
424 uint16_t m_subexpressionDivotOffset
;
425 uint16_t m_subexpressionStartOffset
;
426 uint16_t m_subexpressionLineOffset
;
427 uint16_t m_subexpressionLineStartOffset
;
430 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
431 class TemplateExpressionListNode
: public ParserArenaFreeable
{
433 TemplateExpressionListNode(ExpressionNode
*);
434 TemplateExpressionListNode(TemplateExpressionListNode
*, ExpressionNode
*);
436 ExpressionNode
* value() { return m_node
; }
437 TemplateExpressionListNode
* next() { return m_next
; }
440 TemplateExpressionListNode
* m_next
{ nullptr };
441 ExpressionNode
* m_node
{ nullptr };
444 class TemplateStringNode
: public ExpressionNode
{
446 TemplateStringNode(const JSTokenLocation
&, const Identifier
& cooked
, const Identifier
& raw
);
448 const Identifier
& cooked() { return m_cooked
; }
449 const Identifier
& raw() { return m_raw
; }
452 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
454 const Identifier
& m_cooked
;
455 const Identifier
& m_raw
;
458 class TemplateStringListNode
: public ParserArenaFreeable
{
460 TemplateStringListNode(TemplateStringNode
*);
461 TemplateStringListNode(TemplateStringListNode
*, TemplateStringNode
*);
463 TemplateStringNode
* value() { return m_node
; }
464 TemplateStringListNode
* next() { return m_next
; }
467 TemplateStringListNode
* m_next
{ nullptr };
468 TemplateStringNode
* m_node
{ nullptr };
471 class TemplateLiteralNode
: public ExpressionNode
{
473 TemplateLiteralNode(const JSTokenLocation
&, TemplateStringListNode
*);
474 TemplateLiteralNode(const JSTokenLocation
&, TemplateStringListNode
*, TemplateExpressionListNode
*);
476 TemplateStringListNode
* templateStrings() const { return m_templateStrings
; }
477 TemplateExpressionListNode
* templateExpressions() const { return m_templateExpressions
; }
480 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
482 TemplateStringListNode
* m_templateStrings
;
483 TemplateExpressionListNode
* m_templateExpressions
;
486 class TaggedTemplateNode
: public ExpressionNode
, public ThrowableExpressionData
{
488 TaggedTemplateNode(const JSTokenLocation
&, ExpressionNode
*, TemplateLiteralNode
*);
490 TemplateLiteralNode
* templateLiteral() const { return m_templateLiteral
; }
493 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
495 ExpressionNode
* m_tag
;
496 TemplateLiteralNode
* m_templateLiteral
;
500 class RegExpNode
: public ExpressionNode
, public ThrowableExpressionData
{
502 RegExpNode(const JSTokenLocation
&, const Identifier
& pattern
, const Identifier
& flags
);
505 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
507 const Identifier
& m_pattern
;
508 const Identifier
& m_flags
;
511 class ThisNode
: public ExpressionNode
{
513 ThisNode(const JSTokenLocation
&, ThisTDZMode
);
516 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
518 bool m_shouldAlwaysEmitTDZCheck
;
521 class SuperNode final
: public ExpressionNode
{
523 SuperNode(const JSTokenLocation
&);
526 virtual bool isSuperNode() const override
{ return true; }
527 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
530 class ResolveNode
: public ExpressionNode
{
532 ResolveNode(const JSTokenLocation
&, const Identifier
&, const JSTextPosition
& start
);
534 const Identifier
& identifier() const { return m_ident
; }
537 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
539 virtual bool isPure(BytecodeGenerator
&) const override
;
540 virtual bool isLocation() const override
{ return true; }
541 virtual bool isResolveNode() const override
{ return true; }
543 const Identifier
& m_ident
;
544 JSTextPosition m_start
;
547 class ElementNode
: public ParserArenaFreeable
{
549 ElementNode(int elision
, ExpressionNode
*);
550 ElementNode(ElementNode
*, int elision
, ExpressionNode
*);
552 int elision() const { return m_elision
; }
553 ExpressionNode
* value() { return m_node
; }
554 ElementNode
* next() { return m_next
; }
559 ExpressionNode
* m_node
;
562 class ArrayNode
: public ExpressionNode
{
564 ArrayNode(const JSTokenLocation
&, int elision
);
565 ArrayNode(const JSTokenLocation
&, ElementNode
*);
566 ArrayNode(const JSTokenLocation
&, int elision
, ElementNode
*);
568 ArgumentListNode
* toArgumentList(ParserArena
&, int, int) const;
570 ElementNode
* elements() const { ASSERT(isSimpleArray()); return m_element
; }
572 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
574 virtual bool isSimpleArray() const override
;
576 ElementNode
* m_element
;
581 class PropertyNode
: public ParserArenaFreeable
{
583 enum Type
{ Constant
= 1, Getter
= 2, Setter
= 4, Computed
= 8, Shorthand
= 16 };
584 enum PutType
{ Unknown
, KnownDirect
};
586 PropertyNode(const Identifier
&, ExpressionNode
*, Type
, PutType
, SuperBinding
);
587 PropertyNode(ExpressionNode
* propertyName
, ExpressionNode
*, Type
, PutType
);
589 ExpressionNode
* expressionName() const { return m_expression
; }
590 const Identifier
* name() const { return m_name
; }
592 Type
type() const { return static_cast<Type
>(m_type
); }
593 bool needsSuperBinding() const { return m_needsSuperBinding
; }
594 PutType
putType() const { return static_cast<PutType
>(m_putType
); }
597 friend class PropertyListNode
;
598 const Identifier
* m_name
;
599 ExpressionNode
* m_expression
;
600 ExpressionNode
* m_assign
;
602 unsigned m_needsSuperBinding
: 1;
603 unsigned m_putType
: 1;
606 class PropertyListNode
: public ExpressionNode
{
608 PropertyListNode(const JSTokenLocation
&, PropertyNode
*);
609 PropertyListNode(const JSTokenLocation
&, PropertyNode
*, PropertyListNode
*);
612 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
613 void emitPutConstantProperty(BytecodeGenerator
&, RegisterID
*, PropertyNode
&);
615 PropertyNode
* m_node
;
616 PropertyListNode
* m_next
;
619 class ObjectLiteralNode
: public ExpressionNode
{
621 ObjectLiteralNode(const JSTokenLocation
&);
622 ObjectLiteralNode(const JSTokenLocation
&, PropertyListNode
*);
625 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
627 PropertyListNode
* m_list
;
630 class BracketAccessorNode
: public ExpressionNode
, public ThrowableExpressionData
{
632 BracketAccessorNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, bool subscriptHasAssignments
);
634 ExpressionNode
* base() const { return m_base
; }
635 ExpressionNode
* subscript() const { return m_subscript
; }
637 bool subscriptHasAssignments() const { return m_subscriptHasAssignments
; }
640 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
642 virtual bool isLocation() const override
{ return true; }
643 virtual bool isBracketAccessorNode() const override
{ return true; }
645 ExpressionNode
* m_base
;
646 ExpressionNode
* m_subscript
;
647 bool m_subscriptHasAssignments
;
650 class DotAccessorNode
: public ExpressionNode
, public ThrowableExpressionData
{
652 DotAccessorNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&);
654 ExpressionNode
* base() const { return m_base
; }
655 const Identifier
& identifier() const { return m_ident
; }
658 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
660 virtual bool isLocation() const override
{ return true; }
661 virtual bool isDotAccessorNode() const override
{ return true; }
663 ExpressionNode
* m_base
;
664 const Identifier
& m_ident
;
667 class SpreadExpressionNode
: public ExpressionNode
, public ThrowableExpressionData
{
669 SpreadExpressionNode(const JSTokenLocation
&, ExpressionNode
*);
671 ExpressionNode
* expression() const { return m_expression
; }
674 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
676 virtual bool isSpreadExpression() const override
{ return true; }
677 ExpressionNode
* m_expression
;
680 class ArgumentListNode
: public ExpressionNode
{
682 ArgumentListNode(const JSTokenLocation
&, ExpressionNode
*);
683 ArgumentListNode(const JSTokenLocation
&, ArgumentListNode
*, ExpressionNode
*);
685 ArgumentListNode
* m_next
;
686 ExpressionNode
* m_expr
;
689 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
692 class ArgumentsNode
: public ParserArenaFreeable
{
695 ArgumentsNode(ArgumentListNode
*);
697 ArgumentListNode
* m_listNode
;
700 class NewExprNode
: public ExpressionNode
, public ThrowableExpressionData
{
702 NewExprNode(const JSTokenLocation
&, ExpressionNode
*);
703 NewExprNode(const JSTokenLocation
&, ExpressionNode
*, ArgumentsNode
*);
706 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
708 ExpressionNode
* m_expr
;
709 ArgumentsNode
* m_args
;
712 class EvalFunctionCallNode
: public ExpressionNode
, public ThrowableExpressionData
{
714 EvalFunctionCallNode(const JSTokenLocation
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
717 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
719 ArgumentsNode
* m_args
;
722 class FunctionCallValueNode
: public ExpressionNode
, public ThrowableExpressionData
{
724 FunctionCallValueNode(const JSTokenLocation
&, ExpressionNode
*, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
727 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
729 ExpressionNode
* m_expr
;
730 ArgumentsNode
* m_args
;
733 class FunctionCallResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
735 FunctionCallResolveNode(const JSTokenLocation
&, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
738 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
740 const Identifier
& m_ident
;
741 ArgumentsNode
* m_args
;
744 class FunctionCallBracketNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
746 FunctionCallBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, bool subscriptHasAssignments
, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
749 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
751 ExpressionNode
* m_base
;
752 ExpressionNode
* m_subscript
;
753 ArgumentsNode
* m_args
;
754 bool m_subscriptHasAssignments
;
757 class FunctionCallDotNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
759 FunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
762 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
765 ExpressionNode
* m_base
;
766 const Identifier
& m_ident
;
767 ArgumentsNode
* m_args
;
770 class BytecodeIntrinsicNode
: public ExpressionNode
, public ThrowableExpressionData
{
772 typedef RegisterID
* (BytecodeIntrinsicNode::* EmitterType
)(BytecodeGenerator
&, RegisterID
*);
774 BytecodeIntrinsicNode(const JSTokenLocation
&, EmitterType
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
776 const Identifier
& identifier() const { return m_ident
; }
778 #define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*);
779 JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
)
780 #undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
783 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
785 EmitterType m_emitter
;
786 const Identifier
& m_ident
;
787 ArgumentsNode
* m_args
;
790 class CallFunctionCallDotNode
: public FunctionCallDotNode
{
792 CallFunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
795 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
798 class ApplyFunctionCallDotNode
: public FunctionCallDotNode
{
800 ApplyFunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
803 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
806 class DeleteResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
808 DeleteResolveNode(const JSTokenLocation
&, const Identifier
&, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
811 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
813 const Identifier
& m_ident
;
816 class DeleteBracketNode
: public ExpressionNode
, public ThrowableExpressionData
{
818 DeleteBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
821 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
823 ExpressionNode
* m_base
;
824 ExpressionNode
* m_subscript
;
827 class DeleteDotNode
: public ExpressionNode
, public ThrowableExpressionData
{
829 DeleteDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
832 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
834 ExpressionNode
* m_base
;
835 const Identifier
& m_ident
;
838 class DeleteValueNode
: public ExpressionNode
{
840 DeleteValueNode(const JSTokenLocation
&, ExpressionNode
*);
843 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
845 ExpressionNode
* m_expr
;
848 class VoidNode
: public ExpressionNode
{
850 VoidNode(const JSTokenLocation
&, ExpressionNode
*);
853 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
855 ExpressionNode
* m_expr
;
858 class TypeOfResolveNode
: public ExpressionNode
{
860 TypeOfResolveNode(const JSTokenLocation
&, const Identifier
&);
862 const Identifier
& identifier() const { return m_ident
; }
865 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
867 const Identifier
& m_ident
;
870 class TypeOfValueNode
: public ExpressionNode
{
872 TypeOfValueNode(const JSTokenLocation
&, ExpressionNode
*);
875 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
877 ExpressionNode
* m_expr
;
880 class PrefixNode
: public ExpressionNode
, public ThrowablePrefixedSubExpressionData
{
882 PrefixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
885 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
886 virtual RegisterID
* emitResolve(BytecodeGenerator
&, RegisterID
* = 0);
887 virtual RegisterID
* emitBracket(BytecodeGenerator
&, RegisterID
* = 0);
888 virtual RegisterID
* emitDot(BytecodeGenerator
&, RegisterID
* = 0);
890 ExpressionNode
* m_expr
;
894 class PostfixNode
: public PrefixNode
{
896 PostfixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
899 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
900 virtual RegisterID
* emitResolve(BytecodeGenerator
&, RegisterID
* = 0) override
;
901 virtual RegisterID
* emitBracket(BytecodeGenerator
&, RegisterID
* = 0) override
;
902 virtual RegisterID
* emitDot(BytecodeGenerator
&, RegisterID
* = 0) override
;
905 class UnaryOpNode
: public ExpressionNode
{
907 UnaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
*, OpcodeID
);
910 ExpressionNode
* expr() { return m_expr
; }
911 const ExpressionNode
* expr() const { return m_expr
; }
914 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
916 OpcodeID
opcodeID() const { return m_opcodeID
; }
918 ExpressionNode
* m_expr
;
922 class UnaryPlusNode
: public UnaryOpNode
{
924 UnaryPlusNode(const JSTokenLocation
&, ExpressionNode
*);
927 virtual ExpressionNode
* stripUnaryPlus() override
{ return expr(); }
930 class NegateNode
: public UnaryOpNode
{
932 NegateNode(const JSTokenLocation
&, ExpressionNode
*);
935 class BitwiseNotNode
: public ExpressionNode
{
937 BitwiseNotNode(const JSTokenLocation
&, ExpressionNode
*);
940 ExpressionNode
* expr() { return m_expr
; }
941 const ExpressionNode
* expr() const { return m_expr
; }
944 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
946 ExpressionNode
* m_expr
;
949 class LogicalNotNode
: public UnaryOpNode
{
951 LogicalNotNode(const JSTokenLocation
&, ExpressionNode
*);
953 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
956 class BinaryOpNode
: public ExpressionNode
{
958 BinaryOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
959 BinaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
961 RegisterID
* emitStrcat(BytecodeGenerator
& generator
, RegisterID
* destination
, RegisterID
* lhs
= 0, ReadModifyResolveNode
* emitExpressionInfoForMe
= 0);
962 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
964 ExpressionNode
* lhs() { return m_expr1
; };
965 ExpressionNode
* rhs() { return m_expr2
; };
968 void tryFoldToBranch(BytecodeGenerator
&, TriState
& branchCondition
, ExpressionNode
*& branchExpression
);
969 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
972 OpcodeID
opcodeID() const { return m_opcodeID
; }
975 ExpressionNode
* m_expr1
;
976 ExpressionNode
* m_expr2
;
980 bool m_rightHasAssignments
;
983 class MultNode
: public BinaryOpNode
{
985 MultNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
988 class DivNode
: public BinaryOpNode
{
990 DivNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
993 class ModNode
: public BinaryOpNode
{
995 ModNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
998 class AddNode
: public BinaryOpNode
{
1000 AddNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1002 virtual bool isAdd() const override
{ return true; }
1005 class SubNode
: public BinaryOpNode
{
1007 SubNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1009 virtual bool isSubtract() const override
{ return true; }
1012 class LeftShiftNode
: public BinaryOpNode
{
1014 LeftShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1017 class RightShiftNode
: public BinaryOpNode
{
1019 RightShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1022 class UnsignedRightShiftNode
: public BinaryOpNode
{
1024 UnsignedRightShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1027 class LessNode
: public BinaryOpNode
{
1029 LessNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1032 class GreaterNode
: public BinaryOpNode
{
1034 GreaterNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1037 class LessEqNode
: public BinaryOpNode
{
1039 LessEqNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1042 class GreaterEqNode
: public BinaryOpNode
{
1044 GreaterEqNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1047 class ThrowableBinaryOpNode
: public BinaryOpNode
, public ThrowableExpressionData
{
1049 ThrowableBinaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
1050 ThrowableBinaryOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
1053 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1056 class InstanceOfNode
: public ThrowableBinaryOpNode
{
1058 InstanceOfNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1061 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1064 class InNode
: public ThrowableBinaryOpNode
{
1066 InNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1069 class EqualNode
: public BinaryOpNode
{
1071 EqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1074 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1077 class NotEqualNode
: public BinaryOpNode
{
1079 NotEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1082 class StrictEqualNode
: public BinaryOpNode
{
1084 StrictEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1087 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1090 class NotStrictEqualNode
: public BinaryOpNode
{
1092 NotStrictEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1095 class BitAndNode
: public BinaryOpNode
{
1097 BitAndNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1100 class BitOrNode
: public BinaryOpNode
{
1102 BitOrNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1105 class BitXOrNode
: public BinaryOpNode
{
1107 BitXOrNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
1110 // m_expr1 && m_expr2, m_expr1 || m_expr2
1111 class LogicalOpNode
: public ExpressionNode
{
1113 LogicalOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, LogicalOperator
);
1116 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1117 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
1119 ExpressionNode
* m_expr1
;
1120 ExpressionNode
* m_expr2
;
1121 LogicalOperator m_operator
;
1124 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
1125 class ConditionalNode
: public ExpressionNode
{
1127 ConditionalNode(const JSTokenLocation
&, ExpressionNode
* logical
, ExpressionNode
* expr1
, ExpressionNode
* expr2
);
1130 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1132 ExpressionNode
* m_logical
;
1133 ExpressionNode
* m_expr1
;
1134 ExpressionNode
* m_expr2
;
1137 class ReadModifyResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
1139 ReadModifyResolveNode(const JSTokenLocation
&, const Identifier
&, Operator
, ExpressionNode
* right
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1142 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1144 const Identifier
& m_ident
;
1145 ExpressionNode
* m_right
;
1146 Operator m_operator
;
1147 bool m_rightHasAssignments
;
1150 class AssignResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
1152 AssignResolveNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
* right
);
1155 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1157 const Identifier
& m_ident
;
1158 ExpressionNode
* m_right
;
1161 class ReadModifyBracketNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
1163 ReadModifyBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, Operator
, ExpressionNode
* right
, bool subscriptHasAssignments
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1166 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1168 ExpressionNode
* m_base
;
1169 ExpressionNode
* m_subscript
;
1170 ExpressionNode
* m_right
;
1171 unsigned m_operator
: 30;
1172 bool m_subscriptHasAssignments
: 1;
1173 bool m_rightHasAssignments
: 1;
1176 class AssignBracketNode
: public ExpressionNode
, public ThrowableExpressionData
{
1178 AssignBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, ExpressionNode
* right
, bool subscriptHasAssignments
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1181 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1183 ExpressionNode
* m_base
;
1184 ExpressionNode
* m_subscript
;
1185 ExpressionNode
* m_right
;
1186 bool m_subscriptHasAssignments
: 1;
1187 bool m_rightHasAssignments
: 1;
1190 class AssignDotNode
: public ExpressionNode
, public ThrowableExpressionData
{
1192 AssignDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ExpressionNode
* right
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1195 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1197 ExpressionNode
* m_base
;
1198 const Identifier
& m_ident
;
1199 ExpressionNode
* m_right
;
1200 bool m_rightHasAssignments
;
1203 class ReadModifyDotNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
1205 ReadModifyDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, Operator
, ExpressionNode
* right
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1208 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1210 ExpressionNode
* m_base
;
1211 const Identifier
& m_ident
;
1212 ExpressionNode
* m_right
;
1213 unsigned m_operator
: 31;
1214 bool m_rightHasAssignments
: 1;
1217 class AssignErrorNode
: public ExpressionNode
, public ThrowableExpressionData
{
1219 AssignErrorNode(const JSTokenLocation
&, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1222 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1225 class CommaNode final
: public ExpressionNode
{
1227 CommaNode(const JSTokenLocation
&, ExpressionNode
*);
1229 void setNext(CommaNode
* next
) { m_next
= next
; }
1230 CommaNode
* next() { return m_next
; }
1233 virtual bool isCommaNode() const override
{ return true; }
1234 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1236 ExpressionNode
* m_expr
;
1240 class ConstDeclNode
: public ExpressionNode
{
1242 ConstDeclNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
*);
1244 bool hasInitializer() const { return m_init
; }
1245 const Identifier
& ident() { return m_ident
; }
1248 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1249 virtual RegisterID
* emitCodeSingle(BytecodeGenerator
&);
1251 const Identifier
& m_ident
;
1254 ConstDeclNode
* m_next
;
1257 ExpressionNode
* m_init
;
1260 class ConstStatementNode
: public StatementNode
{
1262 ConstStatementNode(const JSTokenLocation
&, ConstDeclNode
* next
);
1265 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1267 ConstDeclNode
* m_next
;
1270 class SourceElements final
: public ParserArenaFreeable
{
1274 void append(StatementNode
*);
1276 StatementNode
* singleStatement() const;
1277 StatementNode
* lastStatement() const;
1279 void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1282 StatementNode
* m_head
;
1283 StatementNode
* m_tail
;
1286 class BlockNode
: public StatementNode
{
1288 BlockNode(const JSTokenLocation
&, SourceElements
* = 0);
1290 StatementNode
* singleStatement() const;
1291 StatementNode
* lastStatement() const;
1294 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1296 virtual bool isBlock() const override
{ return true; }
1298 SourceElements
* m_statements
;
1301 class EmptyStatementNode
: public StatementNode
{
1303 EmptyStatementNode(const JSTokenLocation
&);
1306 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1308 virtual bool isEmptyStatement() const override
{ return true; }
1311 class DebuggerStatementNode
: public StatementNode
{
1313 DebuggerStatementNode(const JSTokenLocation
&);
1316 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1319 class ExprStatementNode
: public StatementNode
{
1321 ExprStatementNode(const JSTokenLocation
&, ExpressionNode
*);
1323 ExpressionNode
* expr() const { return m_expr
; }
1326 virtual bool isExprStatement() const override
{ return true; }
1328 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1330 ExpressionNode
* m_expr
;
1333 class VarStatementNode
: public StatementNode
{
1335 VarStatementNode(const JSTokenLocation
&, ExpressionNode
*);
1337 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1339 ExpressionNode
* m_expr
;
1342 class EmptyVarExpression
: public ExpressionNode
{
1344 EmptyVarExpression(const JSTokenLocation
&, const Identifier
&);
1347 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1349 const Identifier
& m_ident
;
1353 class IfElseNode
: public StatementNode
{
1355 IfElseNode(const JSTokenLocation
&, ExpressionNode
* condition
, StatementNode
* ifBlock
, StatementNode
* elseBlock
);
1358 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1359 bool tryFoldBreakAndContinue(BytecodeGenerator
&, StatementNode
* ifBlock
,
1360 Label
*& trueTarget
, FallThroughMode
&);
1362 ExpressionNode
* m_condition
;
1363 StatementNode
* m_ifBlock
;
1364 StatementNode
* m_elseBlock
;
1367 class DoWhileNode
: public StatementNode
{
1369 DoWhileNode(const JSTokenLocation
&, StatementNode
*, ExpressionNode
*);
1372 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1374 StatementNode
* m_statement
;
1375 ExpressionNode
* m_expr
;
1378 class WhileNode
: public StatementNode
{
1380 WhileNode(const JSTokenLocation
&, ExpressionNode
*, StatementNode
*);
1383 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1385 ExpressionNode
* m_expr
;
1386 StatementNode
* m_statement
;
1389 class ForNode
: public StatementNode
{
1391 ForNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, ExpressionNode
* expr3
, StatementNode
*);
1394 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1396 ExpressionNode
* m_expr1
;
1397 ExpressionNode
* m_expr2
;
1398 ExpressionNode
* m_expr3
;
1399 StatementNode
* m_statement
;
1402 class DestructuringPatternNode
;
1404 class EnumerationNode
: public StatementNode
, public ThrowableExpressionData
{
1406 EnumerationNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1409 ExpressionNode
* m_lexpr
;
1410 ExpressionNode
* m_expr
;
1411 StatementNode
* m_statement
;
1414 class ForInNode
: public EnumerationNode
{
1416 ForInNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1419 RegisterID
* tryGetBoundLocal(BytecodeGenerator
&);
1420 void emitLoopHeader(BytecodeGenerator
&, RegisterID
* propertyName
);
1421 void emitMultiLoopBytecode(BytecodeGenerator
&, RegisterID
* dst
);
1423 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1426 class ForOfNode
: public EnumerationNode
{
1428 ForOfNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1431 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1434 class ContinueNode
: public StatementNode
, public ThrowableExpressionData
{
1436 ContinueNode(const JSTokenLocation
&, const Identifier
&);
1437 Label
* trivialTarget(BytecodeGenerator
&);
1440 virtual bool isContinue() const override
{ return true; }
1441 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1443 const Identifier
& m_ident
;
1446 class BreakNode
: public StatementNode
, public ThrowableExpressionData
{
1448 BreakNode(const JSTokenLocation
&, const Identifier
&);
1449 Label
* trivialTarget(BytecodeGenerator
&);
1452 virtual bool isBreak() const override
{ return true; }
1453 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1455 const Identifier
& m_ident
;
1458 class ReturnNode
: public StatementNode
, public ThrowableExpressionData
{
1460 ReturnNode(const JSTokenLocation
&, ExpressionNode
* value
);
1462 ExpressionNode
* value() { return m_value
; }
1465 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1467 virtual bool isReturnNode() const override
{ return true; }
1469 ExpressionNode
* m_value
;
1472 class WithNode
: public StatementNode
{
1474 WithNode(const JSTokenLocation
&, ExpressionNode
*, StatementNode
*, const JSTextPosition
& divot
, uint32_t expressionLength
);
1477 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1479 ExpressionNode
* m_expr
;
1480 StatementNode
* m_statement
;
1481 JSTextPosition m_divot
;
1482 uint32_t m_expressionLength
;
1485 class LabelNode
: public StatementNode
, public ThrowableExpressionData
{
1487 LabelNode(const JSTokenLocation
&, const Identifier
& name
, StatementNode
*);
1490 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1492 const Identifier
& m_name
;
1493 StatementNode
* m_statement
;
1496 class ThrowNode
: public StatementNode
, public ThrowableExpressionData
{
1498 ThrowNode(const JSTokenLocation
&, ExpressionNode
*);
1501 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1503 ExpressionNode
* m_expr
;
1506 class TryNode
: public StatementNode
{
1508 TryNode(const JSTokenLocation
&, StatementNode
* tryBlock
, const Identifier
& exceptionIdent
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
);
1511 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1513 StatementNode
* m_tryBlock
;
1514 const Identifier
& m_thrownValueIdent
;
1515 StatementNode
* m_catchBlock
;
1516 StatementNode
* m_finallyBlock
;
1519 class ParameterNode
: public ParserArenaDeletable
{
1521 ParameterNode(PassRefPtr
<DestructuringPatternNode
>);
1522 ParameterNode(ParameterNode
*, PassRefPtr
<DestructuringPatternNode
>);
1524 DestructuringPatternNode
* pattern() const { return m_pattern
.get(); }
1525 ParameterNode
* nextParam() const { return m_next
; }
1528 RefPtr
<DestructuringPatternNode
> m_pattern
;
1529 ParameterNode
* m_next
;
1532 class ScopeNode
: public StatementNode
, public ParserArenaRoot
{
1534 typedef DeclarationStacks::VarStack VarStack
;
1535 typedef DeclarationStacks::FunctionStack FunctionStack
;
1537 ScopeNode(ParserArena
&, const JSTokenLocation
& start
, const JSTokenLocation
& end
, bool inStrictContext
);
1538 ScopeNode(ParserArena
&, const JSTokenLocation
& start
, const JSTokenLocation
& end
, const SourceCode
&, SourceElements
*, VarStack
&, FunctionStack
&, IdentifierSet
&, CodeFeatures
, int numConstants
);
1540 using ParserArenaRoot::operator new;
1542 const SourceCode
& source() const { return m_source
; }
1543 const String
& sourceURL() const { return m_source
.provider()->url(); }
1544 intptr_t sourceID() const { return m_source
.providerID(); }
1546 int startLine() const { return m_startLineNumber
; }
1547 int startStartOffset() const { return m_startStartOffset
; }
1548 int startLineStartOffset() const { return m_startLineStartOffset
; }
1550 void setFeatures(CodeFeatures features
) { m_features
= features
; }
1551 CodeFeatures
features() { return m_features
; }
1553 bool usesEval() const { return m_features
& EvalFeature
; }
1554 bool usesArguments() const { return (m_features
& ArgumentsFeature
) && !(m_features
& ShadowsArgumentsFeature
); }
1555 bool modifiesParameter() const { return m_features
& ModifiedParameterFeature
; }
1556 bool modifiesArguments() const { return m_features
& (EvalFeature
| ModifiedArgumentsFeature
); }
1557 bool isStrictMode() const { return m_features
& StrictModeFeature
; }
1558 void setUsesArguments() { m_features
|= ArgumentsFeature
; }
1559 bool usesThis() const { return m_features
& ThisFeature
; }
1560 bool needsActivationForMoreThanVariables() const { return m_features
& (EvalFeature
| WithFeature
| CatchFeature
); }
1561 bool needsActivation() const { return (hasCapturedVariables()) || (m_features
& (EvalFeature
| WithFeature
| CatchFeature
)); }
1562 bool hasCapturedVariables() const { return !!m_capturedVariables
.size(); }
1563 size_t capturedVariableCount() const { return m_capturedVariables
.size(); }
1564 const IdentifierSet
& capturedVariables() const { return m_capturedVariables
; }
1565 bool captures(UniquedStringImpl
* uid
) { return m_capturedVariables
.contains(uid
); }
1566 bool captures(const Identifier
& ident
) { return captures(ident
.impl()); }
1568 VarStack
& varStack() { return m_varStack
; }
1569 FunctionStack
& functionStack() { return m_functionStack
; }
1571 int neededConstants()
1573 // We may need 2 more constants than the count given by the parser,
1574 // because of the various uses of jsUndefined() and jsNull().
1575 return m_numConstants
+ 2;
1578 StatementNode
* singleStatement() const;
1580 void emitStatementsBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1582 void setClosedVariables(Vector
<RefPtr
<UniquedStringImpl
>>&&) { }
1585 int m_startLineNumber
;
1586 unsigned m_startStartOffset
;
1587 unsigned m_startLineStartOffset
;
1590 CodeFeatures m_features
;
1591 SourceCode m_source
;
1592 VarStack m_varStack
;
1593 FunctionStack m_functionStack
;
1595 SourceElements
* m_statements
;
1596 IdentifierSet m_capturedVariables
;
1599 class ProgramNode
: public ScopeNode
{
1601 ProgramNode(ParserArena
&, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
&, FunctionStack
&, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1603 unsigned startColumn() const { return m_startColumn
; }
1604 unsigned endColumn() const { return m_endColumn
; }
1606 static const bool scopeIsFunction
= false;
1608 void setClosedVariables(Vector
<RefPtr
<UniquedStringImpl
>>&&);
1609 const Vector
<RefPtr
<UniquedStringImpl
>>& closedVariables() const { return m_closedVariables
; }
1612 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1613 Vector
<RefPtr
<UniquedStringImpl
>> m_closedVariables
;
1614 unsigned m_startColumn
;
1615 unsigned m_endColumn
;
1618 class EvalNode
: public ScopeNode
{
1620 EvalNode(ParserArena
&, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
&, FunctionStack
&, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1622 ALWAYS_INLINE
unsigned startColumn() const { return 0; }
1623 unsigned endColumn() const { return m_endColumn
; }
1625 static const bool scopeIsFunction
= false;
1628 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1630 unsigned m_endColumn
;
1633 class FunctionParameters
: public RefCounted
<FunctionParameters
> {
1634 WTF_MAKE_FAST_ALLOCATED
;
1635 WTF_MAKE_NONCOPYABLE(FunctionParameters
);
1637 static Ref
<FunctionParameters
> create(ParameterNode
*);
1638 ~FunctionParameters();
1640 unsigned size() const { return m_size
; }
1641 DestructuringPatternNode
* at(unsigned index
) { ASSERT(index
< m_size
); return patterns()[index
]; }
1644 FunctionParameters(ParameterNode
*, unsigned size
);
1646 DestructuringPatternNode
** patterns() { return &m_storage
; }
1649 DestructuringPatternNode
* m_storage
;
1652 class FunctionBodyNode final
: public StatementNode
, public ParserArenaDeletable
{
1654 using ParserArenaDeletable::operator new;
1657 ParserArena
&, const JSTokenLocation
& start
, const JSTokenLocation
& end
,
1658 unsigned startColumn
, unsigned endColumn
, int functionKeywordStart
,
1659 int functionNameStart
, int parametersStart
, bool isInStrictContext
,
1662 FunctionParameters
* parameters() const { return m_parameters
.get(); }
1664 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1666 void finishParsing(const SourceCode
&, ParameterNode
*, const Identifier
&, FunctionMode
);
1668 void overrideName(const Identifier
& ident
) { m_ident
= ident
; }
1669 const Identifier
& ident() { return m_ident
; }
1670 void setInferredName(const Identifier
& inferredName
) { ASSERT(!inferredName
.isNull()); m_inferredName
= inferredName
; }
1671 const Identifier
& inferredName() { return m_inferredName
.isEmpty() ? m_ident
: m_inferredName
; }
1673 FunctionMode
functionMode() { return m_functionMode
; }
1675 int functionNameStart() const { return m_functionNameStart
; }
1676 int functionKeywordStart() const { return m_functionKeywordStart
; }
1677 int parametersStart() const { return m_parametersStart
; }
1678 unsigned startColumn() const { return m_startColumn
; }
1679 unsigned endColumn() const { return m_endColumn
; }
1681 void setEndPosition(JSTextPosition
);
1683 const SourceCode
& source() const { return m_source
; }
1685 int startStartOffset() const { return m_startStartOffset
; }
1686 bool isInStrictContext() const { return m_isInStrictContext
; }
1687 ConstructorKind
constructorKind() { return static_cast<ConstructorKind
>(m_constructorKind
); }
1691 Identifier m_inferredName
;
1692 FunctionMode m_functionMode
;
1693 RefPtr
<FunctionParameters
> m_parameters
;
1694 unsigned m_startColumn
;
1695 unsigned m_endColumn
;
1696 int m_functionKeywordStart
;
1697 int m_functionNameStart
;
1698 int m_parametersStart
;
1699 SourceCode m_source
;
1700 int m_startStartOffset
;
1701 unsigned m_isInStrictContext
: 1;
1702 unsigned m_constructorKind
: 2;
1705 class FunctionNode final
: public ScopeNode
{
1707 FunctionNode(ParserArena
&, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
&, FunctionStack
&, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1709 FunctionParameters
* parameters() const { return m_parameters
.get(); }
1711 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1713 void finishParsing(PassRefPtr
<FunctionParameters
>, const Identifier
&, FunctionMode
);
1715 const Identifier
& ident() { return m_ident
; }
1717 FunctionMode
functionMode() { return m_functionMode
; }
1719 unsigned startColumn() const { return m_startColumn
; }
1720 unsigned endColumn() const { return m_endColumn
; }
1722 static const bool scopeIsFunction
= true;
1726 FunctionMode m_functionMode
;
1727 RefPtr
<FunctionParameters
> m_parameters
;
1728 unsigned m_startColumn
;
1729 unsigned m_endColumn
;
1732 class FuncExprNode
: public ExpressionNode
{
1734 FuncExprNode(const JSTokenLocation
&, const Identifier
&, FunctionBodyNode
*, const SourceCode
&, ParameterNode
* = 0);
1736 FunctionBodyNode
* body() { return m_body
; }
1739 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1741 virtual bool isFuncExprNode() const override
{ return true; }
1743 FunctionBodyNode
* m_body
;
1746 #if ENABLE(ES6_CLASS_SYNTAX)
1747 class ClassExprNode final
: public ExpressionNode
{
1749 ClassExprNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
* constructorExpresssion
,
1750 ExpressionNode
* parentClass
, PropertyListNode
* instanceMethods
, PropertyListNode
* staticMethods
);
1752 const Identifier
& name() { return m_name
; }
1755 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1757 const Identifier
& m_name
;
1758 ExpressionNode
* m_constructorExpression
;
1759 ExpressionNode
* m_classHeritage
;
1760 PropertyListNode
* m_instanceMethods
;
1761 PropertyListNode
* m_staticMethods
;
1765 class DestructuringPatternNode
: public RefCounted
<DestructuringPatternNode
> {
1766 WTF_MAKE_NONCOPYABLE(DestructuringPatternNode
);
1767 WTF_MAKE_FAST_ALLOCATED
;
1770 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const = 0;
1771 virtual void bindValue(BytecodeGenerator
&, RegisterID
* source
) const = 0;
1772 virtual void toString(StringBuilder
&) const = 0;
1774 virtual bool isBindingNode() const { return false; }
1775 virtual RegisterID
* emitDirectBinding(BytecodeGenerator
&, RegisterID
*, ExpressionNode
*) { return 0; }
1777 virtual ~DestructuringPatternNode() = 0;
1780 DestructuringPatternNode();
1783 class ArrayPatternNode
: public DestructuringPatternNode
, public ThrowableExpressionData
{
1785 enum class BindingType
{
1791 static Ref
<ArrayPatternNode
> create();
1792 void appendIndex(BindingType bindingType
, const JSTokenLocation
&, DestructuringPatternNode
* node
, ExpressionNode
* defaultValue
)
1794 m_targetPatterns
.append({ bindingType
, node
, defaultValue
});
1799 BindingType bindingType
;
1800 RefPtr
<DestructuringPatternNode
> pattern
;
1801 ExpressionNode
* defaultValue
;
1804 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const override
;
1805 virtual void bindValue(BytecodeGenerator
&, RegisterID
*) const override
;
1806 virtual RegisterID
* emitDirectBinding(BytecodeGenerator
&, RegisterID
* dst
, ExpressionNode
*) override
;
1807 virtual void toString(StringBuilder
&) const override
;
1809 Vector
<Entry
> m_targetPatterns
;
1812 class ObjectPatternNode
: public DestructuringPatternNode
{
1814 static Ref
<ObjectPatternNode
> create();
1815 void appendEntry(const JSTokenLocation
&, const Identifier
& identifier
, bool wasString
, DestructuringPatternNode
* pattern
, ExpressionNode
* defaultValue
)
1817 m_targetPatterns
.append(Entry
{ identifier
, wasString
, pattern
, defaultValue
});
1821 ObjectPatternNode();
1822 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const override
;
1823 virtual void bindValue(BytecodeGenerator
&, RegisterID
*) const override
;
1824 virtual void toString(StringBuilder
&) const override
;
1826 Identifier propertyName
;
1828 RefPtr
<DestructuringPatternNode
> pattern
;
1829 ExpressionNode
* defaultValue
;
1831 Vector
<Entry
> m_targetPatterns
;
1834 class BindingNode
: public DestructuringPatternNode
{
1836 static Ref
<BindingNode
> create(const Identifier
& boundProperty
, const JSTextPosition
& start
, const JSTextPosition
& end
);
1837 const Identifier
& boundProperty() const { return m_boundProperty
; }
1839 const JSTextPosition
& divotStart() const { return m_divotStart
; }
1840 const JSTextPosition
& divotEnd() const { return m_divotEnd
; }
1843 BindingNode(const Identifier
& boundProperty
, const JSTextPosition
& start
, const JSTextPosition
& end
);
1845 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const override
;
1846 virtual void bindValue(BytecodeGenerator
&, RegisterID
*) const override
;
1847 virtual void toString(StringBuilder
&) const override
;
1849 virtual bool isBindingNode() const override
{ return true; }
1851 JSTextPosition m_divotStart
;
1852 JSTextPosition m_divotEnd
;
1853 Identifier m_boundProperty
;
1856 class DestructuringAssignmentNode
: public ExpressionNode
, public ParserArenaDeletable
{
1858 DestructuringAssignmentNode(const JSTokenLocation
&, PassRefPtr
<DestructuringPatternNode
>, ExpressionNode
*);
1859 DestructuringPatternNode
* bindings() { return m_bindings
.get(); }
1861 using ParserArenaDeletable::operator new;
1864 virtual bool isAssignmentLocation() const override
{ return true; }
1865 virtual bool isDestructuringNode() const override
{ return true; }
1866 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1868 RefPtr
<DestructuringPatternNode
> m_bindings
;
1869 ExpressionNode
* m_initializer
;
1872 class FuncDeclNode
: public StatementNode
{
1874 FuncDeclNode(const JSTokenLocation
&, const Identifier
&, FunctionBodyNode
*, const SourceCode
&, ParameterNode
* = 0);
1876 virtual bool isFuncDeclNode() const override
{ return true; }
1877 FunctionBodyNode
* body() { return m_body
; }
1880 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1882 FunctionBodyNode
* m_body
;
1885 #if ENABLE(ES6_CLASS_SYNTAX)
1886 class ClassDeclNode final
: public StatementNode
{
1888 ClassDeclNode(const JSTokenLocation
&, ExpressionNode
* classExpression
);
1891 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1893 ExpressionNode
* m_classDeclaration
;
1897 class CaseClauseNode
: public ParserArenaFreeable
{
1899 CaseClauseNode(ExpressionNode
*, SourceElements
* = 0);
1901 ExpressionNode
* expr() const { return m_expr
; }
1903 void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1904 void setStartOffset(int offset
) { m_startOffset
= offset
; }
1907 ExpressionNode
* m_expr
;
1908 SourceElements
* m_statements
;
1912 class ClauseListNode
: public ParserArenaFreeable
{
1914 ClauseListNode(CaseClauseNode
*);
1915 ClauseListNode(ClauseListNode
*, CaseClauseNode
*);
1917 CaseClauseNode
* getClause() const { return m_clause
; }
1918 ClauseListNode
* getNext() const { return m_next
; }
1921 CaseClauseNode
* m_clause
;
1922 ClauseListNode
* m_next
;
1925 class CaseBlockNode
: public ParserArenaFreeable
{
1927 CaseBlockNode(ClauseListNode
* list1
, CaseClauseNode
* defaultClause
, ClauseListNode
* list2
);
1929 void emitBytecodeForBlock(BytecodeGenerator
&, RegisterID
* input
, RegisterID
* destination
);
1932 SwitchInfo::SwitchType
tryTableSwitch(Vector
<ExpressionNode
*, 8>& literalVector
, int32_t& min_num
, int32_t& max_num
);
1933 static const size_t s_tableSwitchMinimum
= 3;
1934 ClauseListNode
* m_list1
;
1935 CaseClauseNode
* m_defaultClause
;
1936 ClauseListNode
* m_list2
;
1939 class SwitchNode
: public StatementNode
{
1941 SwitchNode(const JSTokenLocation
&, ExpressionNode
*, CaseBlockNode
*);
1944 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1946 ExpressionNode
* m_expr
;
1947 CaseBlockNode
* m_block
;
1950 struct ElementList
{
1955 struct PropertyList
{
1956 PropertyListNode
* head
;
1957 PropertyListNode
* tail
;
1960 struct ArgumentList
{
1961 ArgumentListNode
* head
;
1962 ArgumentListNode
* tail
;
1965 struct ConstDeclList
{
1966 ConstDeclNode
* head
;
1967 ConstDeclNode
* tail
;
1970 struct ParameterList
{
1971 ParameterNode
* head
;
1972 ParameterNode
* tail
;
1976 ClauseListNode
* head
;
1977 ClauseListNode
* tail
;