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
<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
> {
115 WTF_MAKE_FAST_ALLOCATED
;
117 ParserArenaRefCounted(VM
*);
120 virtual ~ParserArenaRefCounted()
122 ASSERT(deletionHasBegun());
126 class Node
: public ParserArenaFreeable
{
128 Node(const JSTokenLocation
&);
133 int lineNo() const { return m_position
.line
; }
134 int startOffset() const { return m_position
.offset
; }
135 int lineStartOffset() const { return m_position
.lineStartOffset
; }
136 const JSTextPosition
& position() const { return m_position
; }
139 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 isDeconstructionNode() 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; }
168 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
*, Label
*, FallThroughMode
);
170 virtual ExpressionNode
* stripUnaryPlus() { return this; }
172 ResultType
resultDescriptor() const { return m_resultType
; }
175 ResultType m_resultType
;
178 class StatementNode
: public Node
{
180 StatementNode(const JSTokenLocation
&);
183 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
= 0) = 0;
185 void setLoc(unsigned firstLine
, unsigned lastLine
, int startOffset
, int lineStartOffset
);
186 unsigned firstLine() const { return lineNo(); }
187 unsigned lastLine() const { return m_lastLine
; }
189 virtual bool isEmptyStatement() const { return false; }
190 virtual bool isReturnNode() const { return false; }
191 virtual bool isExprStatement() const { return false; }
192 virtual bool isBreak() const { return false; }
193 virtual bool isContinue() const { return false; }
194 virtual bool isBlock() const { return false; }
200 class ConstantNode
: public ExpressionNode
{
202 ConstantNode(const JSTokenLocation
&, ResultType
);
203 virtual bool isPure(BytecodeGenerator
&) const override
{ return true; }
204 virtual bool isConstant() const override
{ return true; }
205 virtual JSValue
jsValue(BytecodeGenerator
&) const = 0;
207 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
208 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
211 class NullNode
: public ConstantNode
{
213 NullNode(const JSTokenLocation
&);
216 virtual bool isNull() const override
{ return true; }
217 virtual JSValue
jsValue(BytecodeGenerator
&) const override
{ return jsNull(); }
220 class BooleanNode
: public ConstantNode
{
222 BooleanNode(const JSTokenLocation
&, bool value
);
223 bool value() { return m_value
; }
226 virtual bool isBoolean() const override
{ return true; }
227 virtual JSValue
jsValue(BytecodeGenerator
&) const override
{ return jsBoolean(m_value
); }
232 class NumberNode
: public ConstantNode
{
234 NumberNode(const JSTokenLocation
&, double value
);
235 double value() { return m_value
; }
236 void setValue(double value
) { m_value
= value
; }
239 virtual bool isNumber() const override
{ return true; }
240 virtual JSValue
jsValue(BytecodeGenerator
&) const override
{ return jsNumber(m_value
); }
245 class StringNode
: public ConstantNode
{
247 StringNode(const JSTokenLocation
&, const Identifier
&);
248 const Identifier
& value() { return m_value
; }
251 virtual bool isString() const override
{ return true; }
252 virtual JSValue
jsValue(BytecodeGenerator
&) const override
;
254 const Identifier
& m_value
;
257 class ThrowableExpressionData
{
259 ThrowableExpressionData()
260 : m_divot(-1, -1, -1)
261 , m_divotStart(-1, -1, -1)
262 , m_divotEnd(-1, -1, -1)
266 ThrowableExpressionData(const JSTextPosition
& divot
, const JSTextPosition
& start
, const JSTextPosition
& end
)
268 , m_divotStart(start
)
271 ASSERT(m_divot
.offset
>= m_divot
.lineStartOffset
);
272 ASSERT(m_divotStart
.offset
>= m_divotStart
.lineStartOffset
);
273 ASSERT(m_divotEnd
.offset
>= m_divotEnd
.lineStartOffset
);
276 void setExceptionSourceCode(const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
)
278 ASSERT(divot
.offset
>= divot
.lineStartOffset
);
279 ASSERT(divotStart
.offset
>= divotStart
.lineStartOffset
);
280 ASSERT(divotEnd
.offset
>= divotEnd
.lineStartOffset
);
282 m_divotStart
= divotStart
;
283 m_divotEnd
= divotEnd
;
286 const JSTextPosition
& divot() const { return m_divot
; }
287 const JSTextPosition
& divotStart() const { return m_divotStart
; }
288 const JSTextPosition
& divotEnd() const { return m_divotEnd
; }
291 RegisterID
* emitThrowReferenceError(BytecodeGenerator
&, const String
& message
);
294 JSTextPosition m_divot
;
295 JSTextPosition m_divotStart
;
296 JSTextPosition m_divotEnd
;
299 class ThrowableSubExpressionData
: public ThrowableExpressionData
{
301 ThrowableSubExpressionData()
302 : m_subexpressionDivotOffset(0)
303 , m_subexpressionEndOffset(0)
304 , m_subexpressionLineOffset(0)
305 , m_subexpressionLineStartOffset(0)
309 ThrowableSubExpressionData(const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
)
310 : ThrowableExpressionData(divot
, divotStart
, divotEnd
)
311 , m_subexpressionDivotOffset(0)
312 , m_subexpressionEndOffset(0)
313 , m_subexpressionLineOffset(0)
314 , m_subexpressionLineStartOffset(0)
318 void setSubexpressionInfo(const JSTextPosition
& subexpressionDivot
, int subexpressionOffset
)
320 ASSERT(subexpressionDivot
.offset
<= divot().offset
);
321 // Overflow means we can't do this safely, so just point at the primary divot,
322 // divotLine, or divotLineStart.
323 if ((divot() - subexpressionDivot
.offset
) & ~0xFFFF)
325 if ((divot().line
- subexpressionDivot
.line
) & ~0xFFFF)
327 if ((divot().lineStartOffset
- subexpressionDivot
.lineStartOffset
) & ~0xFFFF)
329 if ((divotEnd() - subexpressionOffset
) & ~0xFFFF)
331 m_subexpressionDivotOffset
= divot() - subexpressionDivot
.offset
;
332 m_subexpressionEndOffset
= divotEnd() - subexpressionOffset
;
333 m_subexpressionLineOffset
= divot().line
- subexpressionDivot
.line
;
334 m_subexpressionLineStartOffset
= divot().lineStartOffset
- subexpressionDivot
.lineStartOffset
;
337 JSTextPosition
subexpressionDivot()
339 int newLine
= divot().line
- m_subexpressionLineOffset
;
340 int newOffset
= divot().offset
- m_subexpressionDivotOffset
;
341 int newLineStartOffset
= divot().lineStartOffset
- m_subexpressionLineStartOffset
;
342 return JSTextPosition(newLine
, newOffset
, newLineStartOffset
);
344 JSTextPosition
subexpressionStart() { return divotStart(); }
345 JSTextPosition
subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset
); }
348 uint16_t m_subexpressionDivotOffset
;
349 uint16_t m_subexpressionEndOffset
;
350 uint16_t m_subexpressionLineOffset
;
351 uint16_t m_subexpressionLineStartOffset
;
354 class ThrowablePrefixedSubExpressionData
: public ThrowableExpressionData
{
356 ThrowablePrefixedSubExpressionData()
357 : m_subexpressionDivotOffset(0)
358 , m_subexpressionStartOffset(0)
359 , m_subexpressionLineOffset(0)
360 , m_subexpressionLineStartOffset(0)
364 ThrowablePrefixedSubExpressionData(const JSTextPosition
& divot
, const JSTextPosition
& start
, const JSTextPosition
& end
)
365 : ThrowableExpressionData(divot
, start
, end
)
366 , m_subexpressionDivotOffset(0)
367 , m_subexpressionStartOffset(0)
368 , m_subexpressionLineOffset(0)
369 , m_subexpressionLineStartOffset(0)
373 void setSubexpressionInfo(const JSTextPosition
& subexpressionDivot
, int subexpressionOffset
)
375 ASSERT(subexpressionDivot
.offset
>= divot().offset
);
376 // Overflow means we can't do this safely, so just point at the primary divot,
377 // divotLine, or divotLineStart.
378 if ((subexpressionDivot
.offset
- divot()) & ~0xFFFF)
380 if ((subexpressionDivot
.line
- divot().line
) & ~0xFFFF)
382 if ((subexpressionDivot
.lineStartOffset
- divot().lineStartOffset
) & ~0xFFFF)
384 if ((subexpressionOffset
- divotStart()) & ~0xFFFF)
386 m_subexpressionDivotOffset
= subexpressionDivot
.offset
- divot();
387 m_subexpressionStartOffset
= subexpressionOffset
- divotStart();
388 m_subexpressionLineOffset
= subexpressionDivot
.line
- divot().line
;
389 m_subexpressionLineStartOffset
= subexpressionDivot
.lineStartOffset
- divot().lineStartOffset
;
392 JSTextPosition
subexpressionDivot()
394 int newLine
= divot().line
+ m_subexpressionLineOffset
;
395 int newOffset
= divot().offset
+ m_subexpressionDivotOffset
;
396 int newLineStartOffset
= divot().lineStartOffset
+ m_subexpressionLineStartOffset
;
397 return JSTextPosition(newLine
, newOffset
, newLineStartOffset
);
399 JSTextPosition
subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset
); }
400 JSTextPosition
subexpressionEnd() { return divotEnd(); }
403 uint16_t m_subexpressionDivotOffset
;
404 uint16_t m_subexpressionStartOffset
;
405 uint16_t m_subexpressionLineOffset
;
406 uint16_t m_subexpressionLineStartOffset
;
409 class RegExpNode
: public ExpressionNode
, public ThrowableExpressionData
{
411 RegExpNode(const JSTokenLocation
&, const Identifier
& pattern
, const Identifier
& flags
);
414 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
416 const Identifier
& m_pattern
;
417 const Identifier
& m_flags
;
420 class ThisNode
: public ExpressionNode
{
422 ThisNode(const JSTokenLocation
&);
425 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
428 class ResolveNode
: public ExpressionNode
{
430 ResolveNode(const JSTokenLocation
&, const Identifier
&, const JSTextPosition
& start
);
432 const Identifier
& identifier() const { return m_ident
; }
435 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
437 virtual bool isPure(BytecodeGenerator
&) const override
;
438 virtual bool isLocation() const override
{ return true; }
439 virtual bool isResolveNode() const override
{ return true; }
441 const Identifier
& m_ident
;
442 JSTextPosition m_start
;
445 class ElementNode
: public ParserArenaFreeable
{
447 ElementNode(int elision
, ExpressionNode
*);
448 ElementNode(ElementNode
*, int elision
, ExpressionNode
*);
450 int elision() const { return m_elision
; }
451 ExpressionNode
* value() { return m_node
; }
452 ElementNode
* next() { return m_next
; }
457 ExpressionNode
* m_node
;
460 class ArrayNode
: public ExpressionNode
{
462 ArrayNode(const JSTokenLocation
&, int elision
);
463 ArrayNode(const JSTokenLocation
&, ElementNode
*);
464 ArrayNode(const JSTokenLocation
&, int elision
, ElementNode
*);
466 ArgumentListNode
* toArgumentList(VM
*, int, int) const;
468 ElementNode
* elements() const { ASSERT(isSimpleArray()); return m_element
; }
470 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
472 virtual bool isSimpleArray() const override
;
474 ElementNode
* m_element
;
479 class PropertyNode
: public ParserArenaFreeable
{
481 enum Type
{ Constant
= 1, Getter
= 2, Setter
= 4 };
483 PropertyNode(VM
*, const Identifier
&, ExpressionNode
*, Type
);
484 PropertyNode(VM
*, double, ExpressionNode
*, Type
);
485 PropertyNode(VM
*, ExpressionNode
* propertyName
, ExpressionNode
*, Type
);
487 ExpressionNode
* expressionName() const { return m_expression
; }
488 const Identifier
* name() const { return m_name
; }
490 Type
type() const { return m_type
; }
493 friend class PropertyListNode
;
494 const Identifier
* m_name
;
495 ExpressionNode
* m_expression
;
496 ExpressionNode
* m_assign
;
500 class PropertyListNode
: public ExpressionNode
{
502 PropertyListNode(const JSTokenLocation
&, PropertyNode
*);
503 PropertyListNode(const JSTokenLocation
&, PropertyNode
*, PropertyListNode
*);
505 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
508 PropertyNode
* m_node
;
509 PropertyListNode
* m_next
;
512 class ObjectLiteralNode
: public ExpressionNode
{
514 ObjectLiteralNode(const JSTokenLocation
&);
515 ObjectLiteralNode(const JSTokenLocation
&, PropertyListNode
*);
518 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
520 PropertyListNode
* m_list
;
523 class BracketAccessorNode
: public ExpressionNode
, public ThrowableExpressionData
{
525 BracketAccessorNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, bool subscriptHasAssignments
);
527 ExpressionNode
* base() const { return m_base
; }
528 ExpressionNode
* subscript() const { return m_subscript
; }
530 bool subscriptHasAssignments() const { return m_subscriptHasAssignments
; }
533 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
535 virtual bool isLocation() const override
{ return true; }
536 virtual bool isBracketAccessorNode() const override
{ return true; }
538 ExpressionNode
* m_base
;
539 ExpressionNode
* m_subscript
;
540 bool m_subscriptHasAssignments
;
543 class DotAccessorNode
: public ExpressionNode
, public ThrowableExpressionData
{
545 DotAccessorNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&);
547 ExpressionNode
* base() const { return m_base
; }
548 const Identifier
& identifier() const { return m_ident
; }
551 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
553 virtual bool isLocation() const override
{ return true; }
554 virtual bool isDotAccessorNode() const override
{ return true; }
556 ExpressionNode
* m_base
;
557 const Identifier
& m_ident
;
560 class SpreadExpressionNode
: public ExpressionNode
, public ThrowableExpressionData
{
562 SpreadExpressionNode(const JSTokenLocation
&, ExpressionNode
*);
564 ExpressionNode
* expression() const { return m_expression
; }
567 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
569 virtual bool isSpreadExpression() const override
{ return true; }
570 ExpressionNode
* m_expression
;
573 class ArgumentListNode
: public ExpressionNode
{
575 ArgumentListNode(const JSTokenLocation
&, ExpressionNode
*);
576 ArgumentListNode(const JSTokenLocation
&, ArgumentListNode
*, ExpressionNode
*);
578 ArgumentListNode
* m_next
;
579 ExpressionNode
* m_expr
;
582 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
585 class ArgumentsNode
: public ParserArenaFreeable
{
588 ArgumentsNode(ArgumentListNode
*);
590 ArgumentListNode
* m_listNode
;
593 class NewExprNode
: public ExpressionNode
, public ThrowableExpressionData
{
595 NewExprNode(const JSTokenLocation
&, ExpressionNode
*);
596 NewExprNode(const JSTokenLocation
&, ExpressionNode
*, ArgumentsNode
*);
599 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
601 ExpressionNode
* m_expr
;
602 ArgumentsNode
* m_args
;
605 class EvalFunctionCallNode
: public ExpressionNode
, public ThrowableExpressionData
{
607 EvalFunctionCallNode(const JSTokenLocation
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
610 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
612 ArgumentsNode
* m_args
;
615 class FunctionCallValueNode
: public ExpressionNode
, public ThrowableExpressionData
{
617 FunctionCallValueNode(const JSTokenLocation
&, ExpressionNode
*, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
620 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
622 ExpressionNode
* m_expr
;
623 ArgumentsNode
* m_args
;
626 class FunctionCallResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
628 FunctionCallResolveNode(const JSTokenLocation
&, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
631 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
633 const Identifier
& m_ident
;
634 ArgumentsNode
* m_args
;
637 class FunctionCallBracketNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
639 FunctionCallBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
642 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
644 ExpressionNode
* m_base
;
645 ExpressionNode
* m_subscript
;
646 ArgumentsNode
* m_args
;
649 class FunctionCallDotNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
651 FunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
654 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
657 ExpressionNode
* m_base
;
658 const Identifier
& m_ident
;
659 ArgumentsNode
* m_args
;
662 class CallFunctionCallDotNode
: public FunctionCallDotNode
{
664 CallFunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
667 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
670 class ApplyFunctionCallDotNode
: public FunctionCallDotNode
{
672 ApplyFunctionCallDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ArgumentsNode
*, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
675 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
678 class DeleteResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
680 DeleteResolveNode(const JSTokenLocation
&, const Identifier
&, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
683 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
685 const Identifier
& m_ident
;
688 class DeleteBracketNode
: public ExpressionNode
, public ThrowableExpressionData
{
690 DeleteBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
693 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
695 ExpressionNode
* m_base
;
696 ExpressionNode
* m_subscript
;
699 class DeleteDotNode
: public ExpressionNode
, public ThrowableExpressionData
{
701 DeleteDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
704 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
706 ExpressionNode
* m_base
;
707 const Identifier
& m_ident
;
710 class DeleteValueNode
: public ExpressionNode
{
712 DeleteValueNode(const JSTokenLocation
&, ExpressionNode
*);
715 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
717 ExpressionNode
* m_expr
;
720 class VoidNode
: public ExpressionNode
{
722 VoidNode(const JSTokenLocation
&, ExpressionNode
*);
725 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
727 ExpressionNode
* m_expr
;
730 class TypeOfResolveNode
: public ExpressionNode
{
732 TypeOfResolveNode(const JSTokenLocation
&, const Identifier
&);
734 const Identifier
& identifier() const { return m_ident
; }
737 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
739 const Identifier
& m_ident
;
742 class TypeOfValueNode
: public ExpressionNode
{
744 TypeOfValueNode(const JSTokenLocation
&, ExpressionNode
*);
747 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
749 ExpressionNode
* m_expr
;
752 class PrefixNode
: public ExpressionNode
, public ThrowablePrefixedSubExpressionData
{
754 PrefixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
757 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
758 virtual RegisterID
* emitResolve(BytecodeGenerator
&, RegisterID
* = 0);
759 virtual RegisterID
* emitBracket(BytecodeGenerator
&, RegisterID
* = 0);
760 virtual RegisterID
* emitDot(BytecodeGenerator
&, RegisterID
* = 0);
762 ExpressionNode
* m_expr
;
766 class PostfixNode
: public PrefixNode
{
768 PostfixNode(const JSTokenLocation
&, ExpressionNode
*, Operator
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
771 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
772 virtual RegisterID
* emitResolve(BytecodeGenerator
&, RegisterID
* = 0) override
;
773 virtual RegisterID
* emitBracket(BytecodeGenerator
&, RegisterID
* = 0) override
;
774 virtual RegisterID
* emitDot(BytecodeGenerator
&, RegisterID
* = 0) override
;
777 class UnaryOpNode
: public ExpressionNode
{
779 UnaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
*, OpcodeID
);
782 ExpressionNode
* expr() { return m_expr
; }
783 const ExpressionNode
* expr() const { return m_expr
; }
786 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
788 OpcodeID
opcodeID() const { return m_opcodeID
; }
790 ExpressionNode
* m_expr
;
794 class UnaryPlusNode
: public UnaryOpNode
{
796 UnaryPlusNode(const JSTokenLocation
&, ExpressionNode
*);
799 virtual ExpressionNode
* stripUnaryPlus() override
{ return expr(); }
802 class NegateNode
: public UnaryOpNode
{
804 NegateNode(const JSTokenLocation
&, ExpressionNode
*);
807 class BitwiseNotNode
: public ExpressionNode
{
809 BitwiseNotNode(const JSTokenLocation
&, ExpressionNode
*);
812 ExpressionNode
* expr() { return m_expr
; }
813 const ExpressionNode
* expr() const { return m_expr
; }
816 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
818 ExpressionNode
* m_expr
;
821 class LogicalNotNode
: public UnaryOpNode
{
823 LogicalNotNode(const JSTokenLocation
&, ExpressionNode
*);
825 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
828 class BinaryOpNode
: public ExpressionNode
{
830 BinaryOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
831 BinaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
833 RegisterID
* emitStrcat(BytecodeGenerator
& generator
, RegisterID
* destination
, RegisterID
* lhs
= 0, ReadModifyResolveNode
* emitExpressionInfoForMe
= 0);
834 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
836 ExpressionNode
* lhs() { return m_expr1
; };
837 ExpressionNode
* rhs() { return m_expr2
; };
840 void tryFoldToBranch(BytecodeGenerator
&, TriState
& branchCondition
, ExpressionNode
*& branchExpression
);
841 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
844 OpcodeID
opcodeID() const { return m_opcodeID
; }
847 ExpressionNode
* m_expr1
;
848 ExpressionNode
* m_expr2
;
852 bool m_rightHasAssignments
;
855 class MultNode
: public BinaryOpNode
{
857 MultNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
860 class DivNode
: public BinaryOpNode
{
862 DivNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
865 class ModNode
: public BinaryOpNode
{
867 ModNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
870 class AddNode
: public BinaryOpNode
{
872 AddNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
874 virtual bool isAdd() const override
{ return true; }
877 class SubNode
: public BinaryOpNode
{
879 SubNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
881 virtual bool isSubtract() const override
{ return true; }
884 class LeftShiftNode
: public BinaryOpNode
{
886 LeftShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
889 class RightShiftNode
: public BinaryOpNode
{
891 RightShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
894 class UnsignedRightShiftNode
: public BinaryOpNode
{
896 UnsignedRightShiftNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
899 class LessNode
: public BinaryOpNode
{
901 LessNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
904 class GreaterNode
: public BinaryOpNode
{
906 GreaterNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
909 class LessEqNode
: public BinaryOpNode
{
911 LessEqNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
914 class GreaterEqNode
: public BinaryOpNode
{
916 GreaterEqNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
919 class ThrowableBinaryOpNode
: public BinaryOpNode
, public ThrowableExpressionData
{
921 ThrowableBinaryOpNode(const JSTokenLocation
&, ResultType
, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
922 ThrowableBinaryOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, OpcodeID
, bool rightHasAssignments
);
925 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
928 class InstanceOfNode
: public ThrowableBinaryOpNode
{
930 InstanceOfNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
933 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
936 class InNode
: public ThrowableBinaryOpNode
{
938 InNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
941 class EqualNode
: public BinaryOpNode
{
943 EqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
946 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
949 class NotEqualNode
: public BinaryOpNode
{
951 NotEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
954 class StrictEqualNode
: public BinaryOpNode
{
956 StrictEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
959 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
962 class NotStrictEqualNode
: public BinaryOpNode
{
964 NotStrictEqualNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
967 class BitAndNode
: public BinaryOpNode
{
969 BitAndNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
972 class BitOrNode
: public BinaryOpNode
{
974 BitOrNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
977 class BitXOrNode
: public BinaryOpNode
{
979 BitXOrNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, bool rightHasAssignments
);
982 // m_expr1 && m_expr2, m_expr1 || m_expr2
983 class LogicalOpNode
: public ExpressionNode
{
985 LogicalOpNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, LogicalOperator
);
988 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
989 virtual void emitBytecodeInConditionContext(BytecodeGenerator
&, Label
* trueTarget
, Label
* falseTarget
, FallThroughMode
) override
;
991 ExpressionNode
* m_expr1
;
992 ExpressionNode
* m_expr2
;
993 LogicalOperator m_operator
;
996 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
997 class ConditionalNode
: public ExpressionNode
{
999 ConditionalNode(const JSTokenLocation
&, ExpressionNode
* logical
, ExpressionNode
* expr1
, ExpressionNode
* expr2
);
1002 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1004 ExpressionNode
* m_logical
;
1005 ExpressionNode
* m_expr1
;
1006 ExpressionNode
* m_expr2
;
1009 class ReadModifyResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
1011 ReadModifyResolveNode(const JSTokenLocation
&, const Identifier
&, Operator
, ExpressionNode
* right
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1014 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1016 const Identifier
& m_ident
;
1017 ExpressionNode
* m_right
;
1018 Operator m_operator
;
1019 bool m_rightHasAssignments
;
1022 class AssignResolveNode
: public ExpressionNode
, public ThrowableExpressionData
{
1024 AssignResolveNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
* right
);
1027 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1029 const Identifier
& m_ident
;
1030 ExpressionNode
* m_right
;
1033 class ReadModifyBracketNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
1035 ReadModifyBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, Operator
, ExpressionNode
* right
, bool subscriptHasAssignments
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1038 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1040 ExpressionNode
* m_base
;
1041 ExpressionNode
* m_subscript
;
1042 ExpressionNode
* m_right
;
1043 unsigned m_operator
: 30;
1044 bool m_subscriptHasAssignments
: 1;
1045 bool m_rightHasAssignments
: 1;
1048 class AssignBracketNode
: public ExpressionNode
, public ThrowableExpressionData
{
1050 AssignBracketNode(const JSTokenLocation
&, ExpressionNode
* base
, ExpressionNode
* subscript
, ExpressionNode
* right
, bool subscriptHasAssignments
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1053 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1055 ExpressionNode
* m_base
;
1056 ExpressionNode
* m_subscript
;
1057 ExpressionNode
* m_right
;
1058 bool m_subscriptHasAssignments
: 1;
1059 bool m_rightHasAssignments
: 1;
1062 class AssignDotNode
: public ExpressionNode
, public ThrowableExpressionData
{
1064 AssignDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, ExpressionNode
* right
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1067 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1069 ExpressionNode
* m_base
;
1070 const Identifier
& m_ident
;
1071 ExpressionNode
* m_right
;
1072 bool m_rightHasAssignments
;
1075 class ReadModifyDotNode
: public ExpressionNode
, public ThrowableSubExpressionData
{
1077 ReadModifyDotNode(const JSTokenLocation
&, ExpressionNode
* base
, const Identifier
&, Operator
, ExpressionNode
* right
, bool rightHasAssignments
, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1080 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1082 ExpressionNode
* m_base
;
1083 const Identifier
& m_ident
;
1084 ExpressionNode
* m_right
;
1085 unsigned m_operator
: 31;
1086 bool m_rightHasAssignments
: 1;
1089 class AssignErrorNode
: public ExpressionNode
, public ThrowableExpressionData
{
1091 AssignErrorNode(const JSTokenLocation
&, const JSTextPosition
& divot
, const JSTextPosition
& divotStart
, const JSTextPosition
& divotEnd
);
1094 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1097 typedef Vector
<ExpressionNode
*, 8> ExpressionVector
;
1099 class CommaNode
: public ExpressionNode
, public ParserArenaDeletable
{
1101 CommaNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
);
1103 using ParserArenaDeletable::operator new;
1105 void append(ExpressionNode
* expr
) { ASSERT(expr
); m_expressions
.append(expr
); }
1108 virtual bool isCommaNode() const override
{ return true; }
1109 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1111 ExpressionVector m_expressions
;
1114 class ConstDeclNode
: public ExpressionNode
{
1116 ConstDeclNode(const JSTokenLocation
&, const Identifier
&, ExpressionNode
*);
1118 bool hasInitializer() const { return m_init
; }
1119 const Identifier
& ident() { return m_ident
; }
1122 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1123 virtual RegisterID
* emitCodeSingle(BytecodeGenerator
&);
1125 const Identifier
& m_ident
;
1128 ConstDeclNode
* m_next
;
1131 ExpressionNode
* m_init
;
1134 class ConstStatementNode
: public StatementNode
{
1136 ConstStatementNode(const JSTokenLocation
&, ConstDeclNode
* next
);
1139 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1141 ConstDeclNode
* m_next
;
1144 class SourceElements
: public ParserArenaDeletable
{
1148 void append(StatementNode
*);
1150 StatementNode
* singleStatement() const;
1151 StatementNode
* lastStatement() const;
1153 void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1156 Vector
<StatementNode
*> m_statements
;
1159 class BlockNode
: public StatementNode
{
1161 BlockNode(const JSTokenLocation
&, SourceElements
* = 0);
1163 StatementNode
* singleStatement() const;
1164 StatementNode
* lastStatement() const;
1167 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1169 virtual bool isBlock() const override
{ return true; }
1171 SourceElements
* m_statements
;
1174 class EmptyStatementNode
: public StatementNode
{
1176 EmptyStatementNode(const JSTokenLocation
&);
1179 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1181 virtual bool isEmptyStatement() const override
{ return true; }
1184 class DebuggerStatementNode
: public StatementNode
{
1186 DebuggerStatementNode(const JSTokenLocation
&);
1189 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1192 class ExprStatementNode
: public StatementNode
{
1194 ExprStatementNode(const JSTokenLocation
&, ExpressionNode
*);
1196 ExpressionNode
* expr() const { return m_expr
; }
1199 virtual bool isExprStatement() const override
{ return true; }
1201 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1203 ExpressionNode
* m_expr
;
1206 class VarStatementNode
: public StatementNode
{
1208 VarStatementNode(const JSTokenLocation
&, ExpressionNode
*);
1210 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1212 ExpressionNode
* m_expr
;
1215 class IfElseNode
: public StatementNode
{
1217 IfElseNode(const JSTokenLocation
&, ExpressionNode
* condition
, StatementNode
* ifBlock
, StatementNode
* elseBlock
);
1220 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1221 bool tryFoldBreakAndContinue(BytecodeGenerator
&, StatementNode
* ifBlock
,
1222 Label
*& trueTarget
, FallThroughMode
&);
1224 ExpressionNode
* m_condition
;
1225 StatementNode
* m_ifBlock
;
1226 StatementNode
* m_elseBlock
;
1229 class DoWhileNode
: public StatementNode
{
1231 DoWhileNode(const JSTokenLocation
&, StatementNode
*, ExpressionNode
*);
1234 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1236 StatementNode
* m_statement
;
1237 ExpressionNode
* m_expr
;
1240 class WhileNode
: public StatementNode
{
1242 WhileNode(const JSTokenLocation
&, ExpressionNode
*, StatementNode
*);
1245 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1247 ExpressionNode
* m_expr
;
1248 StatementNode
* m_statement
;
1251 class ForNode
: public StatementNode
{
1253 ForNode(const JSTokenLocation
&, ExpressionNode
* expr1
, ExpressionNode
* expr2
, ExpressionNode
* expr3
, StatementNode
*);
1256 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1258 ExpressionNode
* m_expr1
;
1259 ExpressionNode
* m_expr2
;
1260 ExpressionNode
* m_expr3
;
1261 StatementNode
* m_statement
;
1264 class DeconstructionPatternNode
;
1266 class EnumerationNode
: public StatementNode
, public ThrowableExpressionData
{
1268 EnumerationNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1269 EnumerationNode(VM
*, const JSTokenLocation
&, DeconstructionPatternNode
*, ExpressionNode
*, StatementNode
*);
1272 ExpressionNode
* m_lexpr
;
1273 ExpressionNode
* m_expr
;
1274 StatementNode
* m_statement
;
1277 class ForInNode
: public EnumerationNode
{
1279 ForInNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1280 ForInNode(VM
*, const JSTokenLocation
&, DeconstructionPatternNode
*, ExpressionNode
*, StatementNode
*);
1283 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1286 class ForOfNode
: public EnumerationNode
{
1288 ForOfNode(const JSTokenLocation
&, ExpressionNode
*, ExpressionNode
*, StatementNode
*);
1289 ForOfNode(VM
*, const JSTokenLocation
&, DeconstructionPatternNode
*, ExpressionNode
*, StatementNode
*);
1292 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1295 class ContinueNode
: public StatementNode
, public ThrowableExpressionData
{
1297 ContinueNode(VM
*, const JSTokenLocation
&);
1298 ContinueNode(const JSTokenLocation
&, const Identifier
&);
1299 Label
* trivialTarget(BytecodeGenerator
&);
1302 virtual bool isContinue() const override
{ return true; }
1303 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1305 const Identifier
& m_ident
;
1308 class BreakNode
: public StatementNode
, public ThrowableExpressionData
{
1310 BreakNode(VM
*, const JSTokenLocation
&);
1311 BreakNode(const JSTokenLocation
&, const Identifier
&);
1312 Label
* trivialTarget(BytecodeGenerator
&);
1315 virtual bool isBreak() const override
{ return true; }
1316 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1318 const Identifier
& m_ident
;
1321 class ReturnNode
: public StatementNode
, public ThrowableExpressionData
{
1323 ReturnNode(const JSTokenLocation
&, ExpressionNode
* value
);
1325 ExpressionNode
* value() { return m_value
; }
1328 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1330 virtual bool isReturnNode() const override
{ return true; }
1332 ExpressionNode
* m_value
;
1335 class WithNode
: public StatementNode
{
1337 WithNode(const JSTokenLocation
&, ExpressionNode
*, StatementNode
*, const JSTextPosition
& divot
, uint32_t expressionLength
);
1340 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1342 ExpressionNode
* m_expr
;
1343 StatementNode
* m_statement
;
1344 JSTextPosition m_divot
;
1345 uint32_t m_expressionLength
;
1348 class LabelNode
: public StatementNode
, public ThrowableExpressionData
{
1350 LabelNode(const JSTokenLocation
&, const Identifier
& name
, StatementNode
*);
1353 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1355 const Identifier
& m_name
;
1356 StatementNode
* m_statement
;
1359 class ThrowNode
: public StatementNode
, public ThrowableExpressionData
{
1361 ThrowNode(const JSTokenLocation
&, ExpressionNode
*);
1364 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1366 ExpressionNode
* m_expr
;
1369 class TryNode
: public StatementNode
{
1371 TryNode(const JSTokenLocation
&, StatementNode
* tryBlock
, const Identifier
& exceptionIdent
, StatementNode
* catchBlock
, StatementNode
* finallyBlock
);
1374 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1376 StatementNode
* m_tryBlock
;
1377 const Identifier
& m_exceptionIdent
;
1378 StatementNode
* m_catchBlock
;
1379 StatementNode
* m_finallyBlock
;
1382 class ParameterNode
: public ParserArenaDeletable
{
1384 ParameterNode(PassRefPtr
<DeconstructionPatternNode
>);
1385 ParameterNode(ParameterNode
*, PassRefPtr
<DeconstructionPatternNode
>);
1387 DeconstructionPatternNode
* pattern() const { return m_pattern
.get(); }
1388 ParameterNode
* nextParam() const { return m_next
; }
1391 RefPtr
<DeconstructionPatternNode
> m_pattern
;
1392 ParameterNode
* m_next
;
1395 class ScopeNode
: public StatementNode
, public ParserArenaRefCounted
{
1397 typedef DeclarationStacks::VarStack VarStack
;
1398 typedef DeclarationStacks::FunctionStack FunctionStack
;
1400 ScopeNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, bool inStrictContext
);
1401 ScopeNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, const SourceCode
&, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, CodeFeatures
, int numConstants
);
1403 using ParserArenaRefCounted::operator new;
1409 m_functionStack
.clear();
1411 m_capturedVariables
.clear();
1414 const SourceCode
& source() const { return m_source
; }
1415 const String
& sourceURL() const { return m_source
.provider()->url(); }
1416 intptr_t sourceID() const { return m_source
.providerID(); }
1418 int startLine() const { return m_startLineNumber
; }
1419 int startStartOffset() const { return m_startStartOffset
; }
1420 int startLineStartOffset() const { return m_startLineStartOffset
; }
1422 void setFeatures(CodeFeatures features
) { m_features
= features
; }
1423 CodeFeatures
features() { return m_features
; }
1425 bool usesEval() const { return m_features
& EvalFeature
; }
1426 bool usesArguments() const { return (m_features
& ArgumentsFeature
) && !(m_features
& ShadowsArgumentsFeature
); }
1427 bool modifiesParameter() const { return m_features
& ModifiedParameterFeature
; }
1428 bool isStrictMode() const { return m_features
& StrictModeFeature
; }
1429 void setUsesArguments() { m_features
|= ArgumentsFeature
; }
1430 bool usesThis() const { return m_features
& ThisFeature
; }
1431 bool needsActivationForMoreThanVariables() const { return m_features
& (EvalFeature
| WithFeature
| CatchFeature
); }
1432 bool needsActivation() const { return (hasCapturedVariables()) || (m_features
& (EvalFeature
| WithFeature
| CatchFeature
)); }
1433 bool hasCapturedVariables() const { return !!m_capturedVariables
.size(); }
1434 size_t capturedVariableCount() const { return m_capturedVariables
.size(); }
1435 const IdentifierSet
& capturedVariables() const { return m_capturedVariables
; }
1436 bool captures(const Identifier
& ident
) { return m_capturedVariables
.contains(ident
.impl()); }
1438 VarStack
& varStack() { return m_varStack
; }
1439 FunctionStack
& functionStack() { return m_functionStack
; }
1441 int neededConstants()
1443 // We may need 2 more constants than the count given by the parser,
1444 // because of the various uses of jsUndefined() and jsNull().
1445 return m_numConstants
+ 2;
1448 StatementNode
* singleStatement() const;
1450 void emitStatementsBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1452 void setClosedVariables(Vector
<RefPtr
<StringImpl
>>&&) { }
1455 void setSource(const SourceCode
& source
) { m_source
= source
; }
1456 ParserArena m_arena
;
1458 int m_startLineNumber
;
1459 unsigned m_startStartOffset
;
1460 unsigned m_startLineStartOffset
;
1463 CodeFeatures m_features
;
1464 SourceCode m_source
;
1465 VarStack m_varStack
;
1466 FunctionStack m_functionStack
;
1468 SourceElements
* m_statements
;
1469 IdentifierSet m_capturedVariables
;
1472 class ProgramNode
: public ScopeNode
{
1474 static const bool isFunctionNode
= false;
1475 static PassRefPtr
<ProgramNode
> create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1477 unsigned startColumn() const { return m_startColumn
; }
1478 unsigned endColumn() const { return m_endColumn
; }
1480 static const bool scopeIsFunction
= false;
1482 void setClosedVariables(Vector
<RefPtr
<StringImpl
>>&&);
1483 const Vector
<RefPtr
<StringImpl
>>& closedVariables() const { return m_closedVariables
; }
1485 ProgramNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1487 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1488 Vector
<RefPtr
<StringImpl
>> m_closedVariables
;
1489 unsigned m_startColumn
;
1490 unsigned m_endColumn
;
1493 class EvalNode
: public ScopeNode
{
1495 static const bool isFunctionNode
= false;
1496 static PassRefPtr
<EvalNode
> create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned, unsigned endColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1498 ALWAYS_INLINE
unsigned startColumn() const { return 0; }
1499 unsigned endColumn() const { return m_endColumn
; }
1501 static const bool scopeIsFunction
= false;
1504 EvalNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned endColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1506 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1508 unsigned m_endColumn
;
1511 class FunctionParameters
: public RefCounted
<FunctionParameters
> {
1512 WTF_MAKE_FAST_ALLOCATED
;
1513 WTF_MAKE_NONCOPYABLE(FunctionParameters
);
1515 static PassRefPtr
<FunctionParameters
> create(ParameterNode
*);
1516 ~FunctionParameters();
1518 unsigned size() const { return m_size
; }
1519 DeconstructionPatternNode
* at(unsigned index
) { ASSERT(index
< m_size
); return patterns()[index
]; }
1522 FunctionParameters(ParameterNode
*, unsigned size
);
1524 DeconstructionPatternNode
** patterns() { return &m_storage
; }
1527 DeconstructionPatternNode
* m_storage
;
1530 class FunctionBodyNode
: public ScopeNode
{
1532 static const bool isFunctionNode
= true;
1533 static FunctionBodyNode
* create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, bool isStrictMode
);
1534 static PassRefPtr
<FunctionBodyNode
> create(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1536 FunctionParameters
* parameters() const { return m_parameters
.get(); }
1537 size_t parameterCount() const { return m_parameters
->size(); }
1539 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1541 void finishParsing(const SourceCode
&, ParameterNode
*, const Identifier
&, FunctionMode
);
1542 void finishParsing(PassRefPtr
<FunctionParameters
>, const Identifier
&, FunctionMode
);
1544 void overrideName(const Identifier
& ident
) { m_ident
= ident
; }
1545 const Identifier
& ident() { return m_ident
; }
1546 void setInferredName(const Identifier
& inferredName
) { ASSERT(!inferredName
.isNull()); m_inferredName
= inferredName
; }
1547 const Identifier
& inferredName() { return m_inferredName
.isEmpty() ? m_ident
: m_inferredName
; }
1549 FunctionMode
functionMode() { return m_functionMode
; }
1551 void setFunctionNameStart(int functionNameStart
) { m_functionNameStart
= functionNameStart
; }
1552 int functionNameStart() const { return m_functionNameStart
; }
1553 unsigned startColumn() const { return m_startColumn
; }
1554 unsigned endColumn() const { return m_endColumn
; }
1556 void setEndPosition(JSTextPosition
);
1558 static const bool scopeIsFunction
= true;
1561 FunctionBodyNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, bool inStrictContext
);
1562 FunctionBodyNode(VM
*, const JSTokenLocation
& start
, const JSTokenLocation
& end
, unsigned startColumn
, unsigned endColumn
, SourceElements
*, VarStack
*, FunctionStack
*, IdentifierSet
&, const SourceCode
&, CodeFeatures
, int numConstants
);
1565 Identifier m_inferredName
;
1566 FunctionMode m_functionMode
;
1567 RefPtr
<FunctionParameters
> m_parameters
;
1568 int m_functionNameStart
;
1569 unsigned m_startColumn
;
1570 unsigned m_endColumn
;
1573 class FuncExprNode
: public ExpressionNode
{
1575 FuncExprNode(const JSTokenLocation
&, const Identifier
&, FunctionBodyNode
*, const SourceCode
&, ParameterNode
* = 0);
1577 FunctionBodyNode
* body() { return m_body
; }
1580 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1582 virtual bool isFuncExprNode() const override
{ return true; }
1584 FunctionBodyNode
* m_body
;
1587 class DeconstructionPatternNode
: public RefCounted
<DeconstructionPatternNode
> {
1588 WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode
);
1589 WTF_MAKE_FAST_ALLOCATED
;
1592 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const = 0;
1593 virtual void bindValue(BytecodeGenerator
&, RegisterID
* source
) const = 0;
1594 virtual void toString(StringBuilder
&) const = 0;
1596 virtual bool isBindingNode() const { return false; }
1597 virtual RegisterID
* emitDirectBinding(BytecodeGenerator
&, RegisterID
*, ExpressionNode
*) { return 0; }
1599 virtual ~DeconstructionPatternNode() = 0;
1602 DeconstructionPatternNode(VM
*);
1605 class ArrayPatternNode
: public DeconstructionPatternNode
{
1607 static PassRefPtr
<ArrayPatternNode
> create(VM
*);
1608 void appendIndex(const JSTokenLocation
&, DeconstructionPatternNode
* node
)
1610 m_targetPatterns
.append(node
);
1614 ArrayPatternNode(VM
*);
1615 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const override
;
1616 virtual void bindValue(BytecodeGenerator
&, RegisterID
*) const override
;
1617 virtual RegisterID
* emitDirectBinding(BytecodeGenerator
&, RegisterID
* dst
, ExpressionNode
*) override
;
1618 virtual void toString(StringBuilder
&) const override
;
1620 Vector
<RefPtr
<DeconstructionPatternNode
>> m_targetPatterns
;
1623 class ObjectPatternNode
: public DeconstructionPatternNode
{
1625 static PassRefPtr
<ObjectPatternNode
> create(VM
*);
1626 void appendEntry(const JSTokenLocation
&, const Identifier
& identifier
, bool wasString
, DeconstructionPatternNode
* pattern
)
1628 m_targetPatterns
.append(Entry(identifier
, wasString
, pattern
));
1632 ObjectPatternNode(VM
*);
1633 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const override
;
1634 virtual void bindValue(BytecodeGenerator
&, RegisterID
*) const override
;
1635 virtual void toString(StringBuilder
&) const override
;
1637 Entry(const Identifier
& propertyName
, bool wasString
, DeconstructionPatternNode
* pattern
)
1638 : propertyName(propertyName
)
1639 , wasString(wasString
)
1643 Identifier propertyName
;
1645 RefPtr
<DeconstructionPatternNode
> pattern
;
1647 Vector
<Entry
> m_targetPatterns
;
1650 class BindingNode
: public DeconstructionPatternNode
{
1652 static PassRefPtr
<BindingNode
> create(VM
*, const Identifier
& boundProperty
, const JSTextPosition
& start
, const JSTextPosition
& end
);
1653 const Identifier
& boundProperty() const { return m_boundProperty
; }
1655 const JSTextPosition
& divotStart() const { return m_divotStart
; }
1656 const JSTextPosition
& divotEnd() const { return m_divotEnd
; }
1659 BindingNode(VM
*, const Identifier
& boundProperty
, const JSTextPosition
& start
, const JSTextPosition
& end
);
1661 virtual void collectBoundIdentifiers(Vector
<Identifier
>&) const override
;
1662 virtual void bindValue(BytecodeGenerator
&, RegisterID
*) const override
;
1663 virtual void toString(StringBuilder
&) const override
;
1665 virtual bool isBindingNode() const override
{ return true; }
1667 JSTextPosition m_divotStart
;
1668 JSTextPosition m_divotEnd
;
1669 Identifier m_boundProperty
;
1672 class DeconstructingAssignmentNode
: public ExpressionNode
, public ParserArenaDeletable
{
1674 DeconstructingAssignmentNode(const JSTokenLocation
&, PassRefPtr
<DeconstructionPatternNode
>, ExpressionNode
*);
1675 DeconstructionPatternNode
* bindings() { return m_bindings
.get(); }
1677 using ParserArenaDeletable::operator new;
1680 virtual bool isAssignmentLocation() const override
{ return true; }
1681 virtual bool isDeconstructionNode() const override
{ return true; }
1682 virtual RegisterID
* emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1684 RefPtr
<DeconstructionPatternNode
> m_bindings
;
1685 ExpressionNode
* m_initializer
;
1688 class FuncDeclNode
: public StatementNode
{
1690 FuncDeclNode(const JSTokenLocation
&, const Identifier
&, FunctionBodyNode
*, const SourceCode
&, ParameterNode
* = 0);
1692 FunctionBodyNode
* body() { return m_body
; }
1695 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1697 FunctionBodyNode
* m_body
;
1700 class CaseClauseNode
: public ParserArenaFreeable
{
1702 CaseClauseNode(ExpressionNode
*, SourceElements
* = 0);
1704 ExpressionNode
* expr() const { return m_expr
; }
1706 void emitBytecode(BytecodeGenerator
&, RegisterID
* destination
);
1709 ExpressionNode
* m_expr
;
1710 SourceElements
* m_statements
;
1713 class ClauseListNode
: public ParserArenaFreeable
{
1715 ClauseListNode(CaseClauseNode
*);
1716 ClauseListNode(ClauseListNode
*, CaseClauseNode
*);
1718 CaseClauseNode
* getClause() const { return m_clause
; }
1719 ClauseListNode
* getNext() const { return m_next
; }
1722 CaseClauseNode
* m_clause
;
1723 ClauseListNode
* m_next
;
1726 class CaseBlockNode
: public ParserArenaFreeable
{
1728 CaseBlockNode(ClauseListNode
* list1
, CaseClauseNode
* defaultClause
, ClauseListNode
* list2
);
1730 void emitBytecodeForBlock(BytecodeGenerator
&, RegisterID
* input
, RegisterID
* destination
);
1733 SwitchInfo::SwitchType
tryTableSwitch(Vector
<ExpressionNode
*, 8>& literalVector
, int32_t& min_num
, int32_t& max_num
);
1734 static const size_t s_tableSwitchMinimum
= 3;
1735 ClauseListNode
* m_list1
;
1736 CaseClauseNode
* m_defaultClause
;
1737 ClauseListNode
* m_list2
;
1740 class SwitchNode
: public StatementNode
{
1742 SwitchNode(const JSTokenLocation
&, ExpressionNode
*, CaseBlockNode
*);
1745 virtual void emitBytecode(BytecodeGenerator
&, RegisterID
* = 0) override
;
1747 ExpressionNode
* m_expr
;
1748 CaseBlockNode
* m_block
;
1751 struct ElementList
{
1756 struct PropertyList
{
1757 PropertyListNode
* head
;
1758 PropertyListNode
* tail
;
1761 struct ArgumentList
{
1762 ArgumentListNode
* head
;
1763 ArgumentListNode
* tail
;
1766 struct ConstDeclList
{
1767 ConstDeclNode
* head
;
1768 ConstDeclNode
* tail
;
1771 struct ParameterList
{
1772 ParameterNode
* head
;
1773 ParameterNode
* tail
;
1777 ClauseListNode
* head
;
1778 ClauseListNode
* tail
;