]> git.saurik.com Git - apple/javascriptcore.git/blame_incremental - parser/Nodes.h
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / parser / Nodes.h
... / ...
CommitLineData
1/*
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>
8 *
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.
13 *
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.
18 *
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.
23 *
24 */
25
26#ifndef Nodes_h
27#define Nodes_h
28
29#include "Error.h"
30#include "JITCode.h"
31#include "Opcode.h"
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>
38
39namespace JSC {
40
41 class ArgumentListNode;
42 class BytecodeGenerator;
43 class FunctionBodyNode;
44 class Label;
45 class PropertyListNode;
46 class ReadModifyResolveNode;
47 class RegisterID;
48 class JSScope;
49 class ScopeNode;
50
51 enum Operator {
52 OpEqual,
53 OpPlusEq,
54 OpMinusEq,
55 OpMultEq,
56 OpDivEq,
57 OpPlusPlus,
58 OpMinusMinus,
59 OpAndEq,
60 OpXOrEq,
61 OpOrEq,
62 OpModEq,
63 OpLShift,
64 OpRShift,
65 OpURShift
66 };
67
68 enum LogicalOperator {
69 OpLogicalAnd,
70 OpLogicalOr
71 };
72
73 enum FallThroughMode {
74 FallThroughMeansTrue = 0,
75 FallThroughMeansFalse = 1
76 };
77 inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
78
79 typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
80
81 namespace DeclarationStacks {
82 enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
83 typedef Vector<std::pair<Identifier, unsigned>> VarStack;
84 typedef Vector<FunctionBodyNode*> FunctionStack;
85 }
86
87 struct SwitchInfo {
88 enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
89 uint32_t bytecodeOffset;
90 SwitchType switchType;
91 };
92
93 class ParserArenaFreeable {
94 public:
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*);
98 };
99
100 class ParserArenaDeletable {
101 public:
102 virtual ~ParserArenaDeletable() { }
103
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*);
107 };
108
109 template <typename T>
110 struct ParserArenaData : ParserArenaDeletable {
111 T data;
112 };
113
114 class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
115 WTF_MAKE_FAST_ALLOCATED;
116 protected:
117 ParserArenaRefCounted(VM*);
118
119 public:
120 virtual ~ParserArenaRefCounted()
121 {
122 ASSERT(deletionHasBegun());
123 }
124 };
125
126 class Node : public ParserArenaFreeable {
127 protected:
128 Node(const JSTokenLocation&);
129
130 public:
131 virtual ~Node() { }
132
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; }
137
138 protected:
139 JSTextPosition m_position;
140 };
141
142 class ExpressionNode : public Node {
143 protected:
144 ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
145
146 public:
147 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
148
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; }
167
168 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
169
170 virtual ExpressionNode* stripUnaryPlus() { return this; }
171
172 ResultType resultDescriptor() const { return m_resultType; }
173
174 private:
175 ResultType m_resultType;
176 };
177
178 class StatementNode : public Node {
179 protected:
180 StatementNode(const JSTokenLocation&);
181
182 public:
183 virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
184
185 void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
186 unsigned firstLine() const { return lineNo(); }
187 unsigned lastLine() const { return m_lastLine; }
188
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; }
195
196 protected:
197 int m_lastLine;
198 };
199
200 class ConstantNode : public ExpressionNode {
201 public:
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;
206 private:
207 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
208 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
209 };
210
211 class NullNode : public ConstantNode {
212 public:
213 NullNode(const JSTokenLocation&);
214
215 private:
216 virtual bool isNull() const override { return true; }
217 virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
218 };
219
220 class BooleanNode : public ConstantNode {
221 public:
222 BooleanNode(const JSTokenLocation&, bool value);
223 bool value() { return m_value; }
224
225 private:
226 virtual bool isBoolean() const override { return true; }
227 virtual JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
228
229 bool m_value;
230 };
231
232 class NumberNode : public ConstantNode {
233 public:
234 NumberNode(const JSTokenLocation&, double value);
235 double value() { return m_value; }
236 void setValue(double value) { m_value = value; }
237
238 private:
239 virtual bool isNumber() const override { return true; }
240 virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
241
242 double m_value;
243 };
244
245 class StringNode : public ConstantNode {
246 public:
247 StringNode(const JSTokenLocation&, const Identifier&);
248 const Identifier& value() { return m_value; }
249
250 private:
251 virtual bool isString() const override { return true; }
252 virtual JSValue jsValue(BytecodeGenerator&) const override;
253
254 const Identifier& m_value;
255 };
256
257 class ThrowableExpressionData {
258 public:
259 ThrowableExpressionData()
260 : m_divot(-1, -1, -1)
261 , m_divotStart(-1, -1, -1)
262 , m_divotEnd(-1, -1, -1)
263 {
264 }
265
266 ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
267 : m_divot(divot)
268 , m_divotStart(start)
269 , m_divotEnd(end)
270 {
271 ASSERT(m_divot.offset >= m_divot.lineStartOffset);
272 ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset);
273 ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset);
274 }
275
276 void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
277 {
278 ASSERT(divot.offset >= divot.lineStartOffset);
279 ASSERT(divotStart.offset >= divotStart.lineStartOffset);
280 ASSERT(divotEnd.offset >= divotEnd.lineStartOffset);
281 m_divot = divot;
282 m_divotStart = divotStart;
283 m_divotEnd = divotEnd;
284 }
285
286 const JSTextPosition& divot() const { return m_divot; }
287 const JSTextPosition& divotStart() const { return m_divotStart; }
288 const JSTextPosition& divotEnd() const { return m_divotEnd; }
289
290 protected:
291 RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
292
293 private:
294 JSTextPosition m_divot;
295 JSTextPosition m_divotStart;
296 JSTextPosition m_divotEnd;
297 };
298
299 class ThrowableSubExpressionData : public ThrowableExpressionData {
300 public:
301 ThrowableSubExpressionData()
302 : m_subexpressionDivotOffset(0)
303 , m_subexpressionEndOffset(0)
304 , m_subexpressionLineOffset(0)
305 , m_subexpressionLineStartOffset(0)
306 {
307 }
308
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)
315 {
316 }
317
318 void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
319 {
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)
324 return;
325 if ((divot().line - subexpressionDivot.line) & ~0xFFFF)
326 return;
327 if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF)
328 return;
329 if ((divotEnd() - subexpressionOffset) & ~0xFFFF)
330 return;
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;
335 }
336
337 JSTextPosition subexpressionDivot()
338 {
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);
343 }
344 JSTextPosition subexpressionStart() { return divotStart(); }
345 JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); }
346
347 protected:
348 uint16_t m_subexpressionDivotOffset;
349 uint16_t m_subexpressionEndOffset;
350 uint16_t m_subexpressionLineOffset;
351 uint16_t m_subexpressionLineStartOffset;
352 };
353
354 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
355 public:
356 ThrowablePrefixedSubExpressionData()
357 : m_subexpressionDivotOffset(0)
358 , m_subexpressionStartOffset(0)
359 , m_subexpressionLineOffset(0)
360 , m_subexpressionLineStartOffset(0)
361 {
362 }
363
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)
370 {
371 }
372
373 void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
374 {
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)
379 return;
380 if ((subexpressionDivot.line - divot().line) & ~0xFFFF)
381 return;
382 if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF)
383 return;
384 if ((subexpressionOffset - divotStart()) & ~0xFFFF)
385 return;
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;
390 }
391
392 JSTextPosition subexpressionDivot()
393 {
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);
398 }
399 JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); }
400 JSTextPosition subexpressionEnd() { return divotEnd(); }
401
402 protected:
403 uint16_t m_subexpressionDivotOffset;
404 uint16_t m_subexpressionStartOffset;
405 uint16_t m_subexpressionLineOffset;
406 uint16_t m_subexpressionLineStartOffset;
407 };
408
409 class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
410 public:
411 RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
412
413 private:
414 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
415
416 const Identifier& m_pattern;
417 const Identifier& m_flags;
418 };
419
420 class ThisNode : public ExpressionNode {
421 public:
422 ThisNode(const JSTokenLocation&);
423
424 private:
425 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
426 };
427
428 class ResolveNode : public ExpressionNode {
429 public:
430 ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start);
431
432 const Identifier& identifier() const { return m_ident; }
433
434 private:
435 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
436
437 virtual bool isPure(BytecodeGenerator&) const override;
438 virtual bool isLocation() const override { return true; }
439 virtual bool isResolveNode() const override { return true; }
440
441 const Identifier& m_ident;
442 JSTextPosition m_start;
443 };
444
445 class ElementNode : public ParserArenaFreeable {
446 public:
447 ElementNode(int elision, ExpressionNode*);
448 ElementNode(ElementNode*, int elision, ExpressionNode*);
449
450 int elision() const { return m_elision; }
451 ExpressionNode* value() { return m_node; }
452 ElementNode* next() { return m_next; }
453
454 private:
455 ElementNode* m_next;
456 int m_elision;
457 ExpressionNode* m_node;
458 };
459
460 class ArrayNode : public ExpressionNode {
461 public:
462 ArrayNode(const JSTokenLocation&, int elision);
463 ArrayNode(const JSTokenLocation&, ElementNode*);
464 ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
465
466 ArgumentListNode* toArgumentList(VM*, int, int) const;
467
468 ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
469 private:
470 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
471
472 virtual bool isSimpleArray() const override;
473
474 ElementNode* m_element;
475 int m_elision;
476 bool m_optional;
477 };
478
479 class PropertyNode : public ParserArenaFreeable {
480 public:
481 enum Type { Constant = 1, Getter = 2, Setter = 4 };
482
483 PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
484 PropertyNode(VM*, double, ExpressionNode*, Type);
485 PropertyNode(VM*, ExpressionNode* propertyName, ExpressionNode*, Type);
486
487 ExpressionNode* expressionName() const { return m_expression; }
488 const Identifier* name() const { return m_name; }
489
490 Type type() const { return m_type; }
491
492 private:
493 friend class PropertyListNode;
494 const Identifier* m_name;
495 ExpressionNode* m_expression;
496 ExpressionNode* m_assign;
497 Type m_type;
498 };
499
500 class PropertyListNode : public ExpressionNode {
501 public:
502 PropertyListNode(const JSTokenLocation&, PropertyNode*);
503 PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
504
505 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
506
507 private:
508 PropertyNode* m_node;
509 PropertyListNode* m_next;
510 };
511
512 class ObjectLiteralNode : public ExpressionNode {
513 public:
514 ObjectLiteralNode(const JSTokenLocation&);
515 ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
516
517 private:
518 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
519
520 PropertyListNode* m_list;
521 };
522
523 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
524 public:
525 BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
526
527 ExpressionNode* base() const { return m_base; }
528 ExpressionNode* subscript() const { return m_subscript; }
529
530 bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
531
532 private:
533 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
534
535 virtual bool isLocation() const override { return true; }
536 virtual bool isBracketAccessorNode() const override { return true; }
537
538 ExpressionNode* m_base;
539 ExpressionNode* m_subscript;
540 bool m_subscriptHasAssignments;
541 };
542
543 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
544 public:
545 DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
546
547 ExpressionNode* base() const { return m_base; }
548 const Identifier& identifier() const { return m_ident; }
549
550 private:
551 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
552
553 virtual bool isLocation() const override { return true; }
554 virtual bool isDotAccessorNode() const override { return true; }
555
556 ExpressionNode* m_base;
557 const Identifier& m_ident;
558 };
559
560 class SpreadExpressionNode : public ExpressionNode, public ThrowableExpressionData {
561 public:
562 SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
563
564 ExpressionNode* expression() const { return m_expression; }
565
566 private:
567 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
568
569 virtual bool isSpreadExpression() const override { return true; }
570 ExpressionNode* m_expression;
571 };
572
573 class ArgumentListNode : public ExpressionNode {
574 public:
575 ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
576 ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
577
578 ArgumentListNode* m_next;
579 ExpressionNode* m_expr;
580
581 private:
582 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
583 };
584
585 class ArgumentsNode : public ParserArenaFreeable {
586 public:
587 ArgumentsNode();
588 ArgumentsNode(ArgumentListNode*);
589
590 ArgumentListNode* m_listNode;
591 };
592
593 class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
594 public:
595 NewExprNode(const JSTokenLocation&, ExpressionNode*);
596 NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
597
598 private:
599 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
600
601 ExpressionNode* m_expr;
602 ArgumentsNode* m_args;
603 };
604
605 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
606 public:
607 EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
608
609 private:
610 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
611
612 ArgumentsNode* m_args;
613 };
614
615 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
616 public:
617 FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
618
619 private:
620 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
621
622 ExpressionNode* m_expr;
623 ArgumentsNode* m_args;
624 };
625
626 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
627 public:
628 FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
629
630 private:
631 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
632
633 const Identifier& m_ident;
634 ArgumentsNode* m_args;
635 };
636
637 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
638 public:
639 FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
640
641 private:
642 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
643
644 ExpressionNode* m_base;
645 ExpressionNode* m_subscript;
646 ArgumentsNode* m_args;
647 };
648
649 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
650 public:
651 FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
652
653 private:
654 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
655
656 protected:
657 ExpressionNode* m_base;
658 const Identifier& m_ident;
659 ArgumentsNode* m_args;
660 };
661
662 class CallFunctionCallDotNode : public FunctionCallDotNode {
663 public:
664 CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
665
666 private:
667 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
668 };
669
670 class ApplyFunctionCallDotNode : public FunctionCallDotNode {
671 public:
672 ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
673
674 private:
675 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
676 };
677
678 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
679 public:
680 DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
681
682 private:
683 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
684
685 const Identifier& m_ident;
686 };
687
688 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
689 public:
690 DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
691
692 private:
693 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
694
695 ExpressionNode* m_base;
696 ExpressionNode* m_subscript;
697 };
698
699 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
700 public:
701 DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
702
703 private:
704 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
705
706 ExpressionNode* m_base;
707 const Identifier& m_ident;
708 };
709
710 class DeleteValueNode : public ExpressionNode {
711 public:
712 DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
713
714 private:
715 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
716
717 ExpressionNode* m_expr;
718 };
719
720 class VoidNode : public ExpressionNode {
721 public:
722 VoidNode(const JSTokenLocation&, ExpressionNode*);
723
724 private:
725 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
726
727 ExpressionNode* m_expr;
728 };
729
730 class TypeOfResolveNode : public ExpressionNode {
731 public:
732 TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
733
734 const Identifier& identifier() const { return m_ident; }
735
736 private:
737 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
738
739 const Identifier& m_ident;
740 };
741
742 class TypeOfValueNode : public ExpressionNode {
743 public:
744 TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
745
746 private:
747 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
748
749 ExpressionNode* m_expr;
750 };
751
752 class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
753 public:
754 PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
755
756 protected:
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);
761
762 ExpressionNode* m_expr;
763 Operator m_operator;
764 };
765
766 class PostfixNode : public PrefixNode {
767 public:
768 PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
769
770 private:
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;
775 };
776
777 class UnaryOpNode : public ExpressionNode {
778 public:
779 UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
780
781 protected:
782 ExpressionNode* expr() { return m_expr; }
783 const ExpressionNode* expr() const { return m_expr; }
784
785 private:
786 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
787
788 OpcodeID opcodeID() const { return m_opcodeID; }
789
790 ExpressionNode* m_expr;
791 OpcodeID m_opcodeID;
792 };
793
794 class UnaryPlusNode : public UnaryOpNode {
795 public:
796 UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
797
798 private:
799 virtual ExpressionNode* stripUnaryPlus() override { return expr(); }
800 };
801
802 class NegateNode : public UnaryOpNode {
803 public:
804 NegateNode(const JSTokenLocation&, ExpressionNode*);
805 };
806
807 class BitwiseNotNode : public ExpressionNode {
808 public:
809 BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
810
811 protected:
812 ExpressionNode* expr() { return m_expr; }
813 const ExpressionNode* expr() const { return m_expr; }
814
815 private:
816 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
817
818 ExpressionNode* m_expr;
819 };
820
821 class LogicalNotNode : public UnaryOpNode {
822 public:
823 LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
824 private:
825 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
826 };
827
828 class BinaryOpNode : public ExpressionNode {
829 public:
830 BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
831 BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
832
833 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
834 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
835
836 ExpressionNode* lhs() { return m_expr1; };
837 ExpressionNode* rhs() { return m_expr2; };
838
839 private:
840 void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
841 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
842
843 protected:
844 OpcodeID opcodeID() const { return m_opcodeID; }
845
846 protected:
847 ExpressionNode* m_expr1;
848 ExpressionNode* m_expr2;
849 private:
850 OpcodeID m_opcodeID;
851 protected:
852 bool m_rightHasAssignments;
853 };
854
855 class MultNode : public BinaryOpNode {
856 public:
857 MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
858 };
859
860 class DivNode : public BinaryOpNode {
861 public:
862 DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
863 };
864
865 class ModNode : public BinaryOpNode {
866 public:
867 ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
868 };
869
870 class AddNode : public BinaryOpNode {
871 public:
872 AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
873
874 virtual bool isAdd() const override { return true; }
875 };
876
877 class SubNode : public BinaryOpNode {
878 public:
879 SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
880
881 virtual bool isSubtract() const override { return true; }
882 };
883
884 class LeftShiftNode : public BinaryOpNode {
885 public:
886 LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
887 };
888
889 class RightShiftNode : public BinaryOpNode {
890 public:
891 RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
892 };
893
894 class UnsignedRightShiftNode : public BinaryOpNode {
895 public:
896 UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
897 };
898
899 class LessNode : public BinaryOpNode {
900 public:
901 LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
902 };
903
904 class GreaterNode : public BinaryOpNode {
905 public:
906 GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
907 };
908
909 class LessEqNode : public BinaryOpNode {
910 public:
911 LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
912 };
913
914 class GreaterEqNode : public BinaryOpNode {
915 public:
916 GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
917 };
918
919 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
920 public:
921 ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
922 ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
923
924 private:
925 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
926 };
927
928 class InstanceOfNode : public ThrowableBinaryOpNode {
929 public:
930 InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
931
932 private:
933 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
934 };
935
936 class InNode : public ThrowableBinaryOpNode {
937 public:
938 InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
939 };
940
941 class EqualNode : public BinaryOpNode {
942 public:
943 EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
944
945 private:
946 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
947 };
948
949 class NotEqualNode : public BinaryOpNode {
950 public:
951 NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
952 };
953
954 class StrictEqualNode : public BinaryOpNode {
955 public:
956 StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
957
958 private:
959 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
960 };
961
962 class NotStrictEqualNode : public BinaryOpNode {
963 public:
964 NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
965 };
966
967 class BitAndNode : public BinaryOpNode {
968 public:
969 BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
970 };
971
972 class BitOrNode : public BinaryOpNode {
973 public:
974 BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
975 };
976
977 class BitXOrNode : public BinaryOpNode {
978 public:
979 BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
980 };
981
982 // m_expr1 && m_expr2, m_expr1 || m_expr2
983 class LogicalOpNode : public ExpressionNode {
984 public:
985 LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
986
987 private:
988 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
989 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
990
991 ExpressionNode* m_expr1;
992 ExpressionNode* m_expr2;
993 LogicalOperator m_operator;
994 };
995
996 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
997 class ConditionalNode : public ExpressionNode {
998 public:
999 ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
1000
1001 private:
1002 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1003
1004 ExpressionNode* m_logical;
1005 ExpressionNode* m_expr1;
1006 ExpressionNode* m_expr2;
1007 };
1008
1009 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
1010 public:
1011 ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1012
1013 private:
1014 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1015
1016 const Identifier& m_ident;
1017 ExpressionNode* m_right;
1018 Operator m_operator;
1019 bool m_rightHasAssignments;
1020 };
1021
1022 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
1023 public:
1024 AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
1025
1026 private:
1027 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1028
1029 const Identifier& m_ident;
1030 ExpressionNode* m_right;
1031 };
1032
1033 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1034 public:
1035 ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1036
1037 private:
1038 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1039
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;
1046 };
1047
1048 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1049 public:
1050 AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1051
1052 private:
1053 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1054
1055 ExpressionNode* m_base;
1056 ExpressionNode* m_subscript;
1057 ExpressionNode* m_right;
1058 bool m_subscriptHasAssignments : 1;
1059 bool m_rightHasAssignments : 1;
1060 };
1061
1062 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1063 public:
1064 AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1065
1066 private:
1067 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1068
1069 ExpressionNode* m_base;
1070 const Identifier& m_ident;
1071 ExpressionNode* m_right;
1072 bool m_rightHasAssignments;
1073 };
1074
1075 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1076 public:
1077 ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1078
1079 private:
1080 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1081
1082 ExpressionNode* m_base;
1083 const Identifier& m_ident;
1084 ExpressionNode* m_right;
1085 unsigned m_operator : 31;
1086 bool m_rightHasAssignments : 1;
1087 };
1088
1089 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1090 public:
1091 AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1092
1093 private:
1094 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1095 };
1096
1097 typedef Vector<ExpressionNode*, 8> ExpressionVector;
1098
1099 class CommaNode : public ExpressionNode, public ParserArenaDeletable {
1100 public:
1101 CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
1102
1103 using ParserArenaDeletable::operator new;
1104
1105 void append(ExpressionNode* expr) { ASSERT(expr); m_expressions.append(expr); }
1106
1107 private:
1108 virtual bool isCommaNode() const override { return true; }
1109 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1110
1111 ExpressionVector m_expressions;
1112 };
1113
1114 class ConstDeclNode : public ExpressionNode {
1115 public:
1116 ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
1117
1118 bool hasInitializer() const { return m_init; }
1119 const Identifier& ident() { return m_ident; }
1120
1121 private:
1122 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1123 virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
1124
1125 const Identifier& m_ident;
1126
1127 public:
1128 ConstDeclNode* m_next;
1129
1130 private:
1131 ExpressionNode* m_init;
1132 };
1133
1134 class ConstStatementNode : public StatementNode {
1135 public:
1136 ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
1137
1138 private:
1139 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1140
1141 ConstDeclNode* m_next;
1142 };
1143
1144 class SourceElements : public ParserArenaDeletable {
1145 public:
1146 SourceElements();
1147
1148 void append(StatementNode*);
1149
1150 StatementNode* singleStatement() const;
1151 StatementNode* lastStatement() const;
1152
1153 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1154
1155 private:
1156 Vector<StatementNode*> m_statements;
1157 };
1158
1159 class BlockNode : public StatementNode {
1160 public:
1161 BlockNode(const JSTokenLocation&, SourceElements* = 0);
1162
1163 StatementNode* singleStatement() const;
1164 StatementNode* lastStatement() const;
1165
1166 private:
1167 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1168
1169 virtual bool isBlock() const override { return true; }
1170
1171 SourceElements* m_statements;
1172 };
1173
1174 class EmptyStatementNode : public StatementNode {
1175 public:
1176 EmptyStatementNode(const JSTokenLocation&);
1177
1178 private:
1179 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1180
1181 virtual bool isEmptyStatement() const override { return true; }
1182 };
1183
1184 class DebuggerStatementNode : public StatementNode {
1185 public:
1186 DebuggerStatementNode(const JSTokenLocation&);
1187
1188 private:
1189 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1190 };
1191
1192 class ExprStatementNode : public StatementNode {
1193 public:
1194 ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
1195
1196 ExpressionNode* expr() const { return m_expr; }
1197
1198 private:
1199 virtual bool isExprStatement() const override { return true; }
1200
1201 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1202
1203 ExpressionNode* m_expr;
1204 };
1205
1206 class VarStatementNode : public StatementNode {
1207 public:
1208 VarStatementNode(const JSTokenLocation&, ExpressionNode*);
1209 private:
1210 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1211
1212 ExpressionNode* m_expr;
1213 };
1214
1215 class IfElseNode : public StatementNode {
1216 public:
1217 IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1218
1219 private:
1220 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1221 bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
1222 Label*& trueTarget, FallThroughMode&);
1223
1224 ExpressionNode* m_condition;
1225 StatementNode* m_ifBlock;
1226 StatementNode* m_elseBlock;
1227 };
1228
1229 class DoWhileNode : public StatementNode {
1230 public:
1231 DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
1232
1233 private:
1234 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1235
1236 StatementNode* m_statement;
1237 ExpressionNode* m_expr;
1238 };
1239
1240 class WhileNode : public StatementNode {
1241 public:
1242 WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
1243
1244 private:
1245 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1246
1247 ExpressionNode* m_expr;
1248 StatementNode* m_statement;
1249 };
1250
1251 class ForNode : public StatementNode {
1252 public:
1253 ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
1254
1255 private:
1256 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1257
1258 ExpressionNode* m_expr1;
1259 ExpressionNode* m_expr2;
1260 ExpressionNode* m_expr3;
1261 StatementNode* m_statement;
1262 };
1263
1264 class DeconstructionPatternNode;
1265
1266 class EnumerationNode : public StatementNode, public ThrowableExpressionData {
1267 public:
1268 EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1269 EnumerationNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
1270
1271 protected:
1272 ExpressionNode* m_lexpr;
1273 ExpressionNode* m_expr;
1274 StatementNode* m_statement;
1275 };
1276
1277 class ForInNode : public EnumerationNode {
1278 public:
1279 ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1280 ForInNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
1281
1282 private:
1283 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1284 };
1285
1286 class ForOfNode : public EnumerationNode {
1287 public:
1288 ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1289 ForOfNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
1290
1291 private:
1292 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1293 };
1294
1295 class ContinueNode : public StatementNode, public ThrowableExpressionData {
1296 public:
1297 ContinueNode(VM*, const JSTokenLocation&);
1298 ContinueNode(const JSTokenLocation&, const Identifier&);
1299 Label* trivialTarget(BytecodeGenerator&);
1300
1301 private:
1302 virtual bool isContinue() const override { return true; }
1303 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1304
1305 const Identifier& m_ident;
1306 };
1307
1308 class BreakNode : public StatementNode, public ThrowableExpressionData {
1309 public:
1310 BreakNode(VM*, const JSTokenLocation&);
1311 BreakNode(const JSTokenLocation&, const Identifier&);
1312 Label* trivialTarget(BytecodeGenerator&);
1313
1314 private:
1315 virtual bool isBreak() const override { return true; }
1316 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1317
1318 const Identifier& m_ident;
1319 };
1320
1321 class ReturnNode : public StatementNode, public ThrowableExpressionData {
1322 public:
1323 ReturnNode(const JSTokenLocation&, ExpressionNode* value);
1324
1325 ExpressionNode* value() { return m_value; }
1326
1327 private:
1328 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1329
1330 virtual bool isReturnNode() const override { return true; }
1331
1332 ExpressionNode* m_value;
1333 };
1334
1335 class WithNode : public StatementNode {
1336 public:
1337 WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength);
1338
1339 private:
1340 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1341
1342 ExpressionNode* m_expr;
1343 StatementNode* m_statement;
1344 JSTextPosition m_divot;
1345 uint32_t m_expressionLength;
1346 };
1347
1348 class LabelNode : public StatementNode, public ThrowableExpressionData {
1349 public:
1350 LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
1351
1352 private:
1353 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1354
1355 const Identifier& m_name;
1356 StatementNode* m_statement;
1357 };
1358
1359 class ThrowNode : public StatementNode, public ThrowableExpressionData {
1360 public:
1361 ThrowNode(const JSTokenLocation&, ExpressionNode*);
1362
1363 private:
1364 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1365
1366 ExpressionNode* m_expr;
1367 };
1368
1369 class TryNode : public StatementNode {
1370 public:
1371 TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
1372
1373 private:
1374 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1375
1376 StatementNode* m_tryBlock;
1377 const Identifier& m_exceptionIdent;
1378 StatementNode* m_catchBlock;
1379 StatementNode* m_finallyBlock;
1380 };
1381
1382 class ParameterNode : public ParserArenaDeletable {
1383 public:
1384 ParameterNode(PassRefPtr<DeconstructionPatternNode>);
1385 ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>);
1386
1387 DeconstructionPatternNode* pattern() const { return m_pattern.get(); }
1388 ParameterNode* nextParam() const { return m_next; }
1389
1390 private:
1391 RefPtr<DeconstructionPatternNode> m_pattern;
1392 ParameterNode* m_next;
1393 };
1394
1395 class ScopeNode : public StatementNode, public ParserArenaRefCounted {
1396 public:
1397 typedef DeclarationStacks::VarStack VarStack;
1398 typedef DeclarationStacks::FunctionStack FunctionStack;
1399
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);
1402
1403 using ParserArenaRefCounted::operator new;
1404
1405 void destroyData()
1406 {
1407 m_arena.reset();
1408 m_varStack.clear();
1409 m_functionStack.clear();
1410 m_statements = 0;
1411 m_capturedVariables.clear();
1412 }
1413
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(); }
1417
1418 int startLine() const { return m_startLineNumber; }
1419 int startStartOffset() const { return m_startStartOffset; }
1420 int startLineStartOffset() const { return m_startLineStartOffset; }
1421
1422 void setFeatures(CodeFeatures features) { m_features = features; }
1423 CodeFeatures features() { return m_features; }
1424
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()); }
1437
1438 VarStack& varStack() { return m_varStack; }
1439 FunctionStack& functionStack() { return m_functionStack; }
1440
1441 int neededConstants()
1442 {
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;
1446 }
1447
1448 StatementNode* singleStatement() const;
1449
1450 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
1451
1452 void setClosedVariables(Vector<RefPtr<StringImpl>>&&) { }
1453
1454 protected:
1455 void setSource(const SourceCode& source) { m_source = source; }
1456 ParserArena m_arena;
1457
1458 int m_startLineNumber;
1459 unsigned m_startStartOffset;
1460 unsigned m_startLineStartOffset;
1461
1462 private:
1463 CodeFeatures m_features;
1464 SourceCode m_source;
1465 VarStack m_varStack;
1466 FunctionStack m_functionStack;
1467 int m_numConstants;
1468 SourceElements* m_statements;
1469 IdentifierSet m_capturedVariables;
1470 };
1471
1472 class ProgramNode : public ScopeNode {
1473 public:
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);
1476
1477 unsigned startColumn() const { return m_startColumn; }
1478 unsigned endColumn() const { return m_endColumn; }
1479
1480 static const bool scopeIsFunction = false;
1481
1482 void setClosedVariables(Vector<RefPtr<StringImpl>>&&);
1483 const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; }
1484 private:
1485 ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1486
1487 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1488 Vector<RefPtr<StringImpl>> m_closedVariables;
1489 unsigned m_startColumn;
1490 unsigned m_endColumn;
1491 };
1492
1493 class EvalNode : public ScopeNode {
1494 public:
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);
1497
1498 ALWAYS_INLINE unsigned startColumn() const { return 0; }
1499 unsigned endColumn() const { return m_endColumn; }
1500
1501 static const bool scopeIsFunction = false;
1502
1503 private:
1504 EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1505
1506 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1507
1508 unsigned m_endColumn;
1509 };
1510
1511 class FunctionParameters : public RefCounted<FunctionParameters> {
1512 WTF_MAKE_FAST_ALLOCATED;
1513 WTF_MAKE_NONCOPYABLE(FunctionParameters);
1514 public:
1515 static PassRefPtr<FunctionParameters> create(ParameterNode*);
1516 ~FunctionParameters();
1517
1518 unsigned size() const { return m_size; }
1519 DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
1520
1521 private:
1522 FunctionParameters(ParameterNode*, unsigned size);
1523
1524 DeconstructionPatternNode** patterns() { return &m_storage; }
1525
1526 unsigned m_size;
1527 DeconstructionPatternNode* m_storage;
1528 };
1529
1530 class FunctionBodyNode : public ScopeNode {
1531 public:
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);
1535
1536 FunctionParameters* parameters() const { return m_parameters.get(); }
1537 size_t parameterCount() const { return m_parameters->size(); }
1538
1539 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1540
1541 void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode);
1542 void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
1543
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; }
1548
1549 FunctionMode functionMode() { return m_functionMode; }
1550
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; }
1555
1556 void setEndPosition(JSTextPosition);
1557
1558 static const bool scopeIsFunction = true;
1559
1560 private:
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);
1563
1564 Identifier m_ident;
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;
1571 };
1572
1573 class FuncExprNode : public ExpressionNode {
1574 public:
1575 FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1576
1577 FunctionBodyNode* body() { return m_body; }
1578
1579 private:
1580 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1581
1582 virtual bool isFuncExprNode() const override { return true; }
1583
1584 FunctionBodyNode* m_body;
1585 };
1586
1587 class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
1588 WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
1589 WTF_MAKE_FAST_ALLOCATED;
1590
1591 public:
1592 virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0;
1593 virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0;
1594 virtual void toString(StringBuilder&) const = 0;
1595
1596 virtual bool isBindingNode() const { return false; }
1597 virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
1598
1599 virtual ~DeconstructionPatternNode() = 0;
1600
1601 protected:
1602 DeconstructionPatternNode(VM*);
1603 };
1604
1605 class ArrayPatternNode : public DeconstructionPatternNode {
1606 public:
1607 static PassRefPtr<ArrayPatternNode> create(VM*);
1608 void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
1609 {
1610 m_targetPatterns.append(node);
1611 }
1612
1613 private:
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;
1619
1620 Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
1621 };
1622
1623 class ObjectPatternNode : public DeconstructionPatternNode {
1624 public:
1625 static PassRefPtr<ObjectPatternNode> create(VM*);
1626 void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
1627 {
1628 m_targetPatterns.append(Entry(identifier, wasString, pattern));
1629 }
1630
1631 private:
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;
1636 struct Entry {
1637 Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
1638 : propertyName(propertyName)
1639 , wasString(wasString)
1640 , pattern(pattern)
1641 {
1642 }
1643 Identifier propertyName;
1644 bool wasString;
1645 RefPtr<DeconstructionPatternNode> pattern;
1646 };
1647 Vector<Entry> m_targetPatterns;
1648 };
1649
1650 class BindingNode : public DeconstructionPatternNode {
1651 public:
1652 static PassRefPtr<BindingNode> create(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
1653 const Identifier& boundProperty() const { return m_boundProperty; }
1654
1655 const JSTextPosition& divotStart() const { return m_divotStart; }
1656 const JSTextPosition& divotEnd() const { return m_divotEnd; }
1657
1658 private:
1659 BindingNode(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
1660
1661 virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
1662 virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
1663 virtual void toString(StringBuilder&) const override;
1664
1665 virtual bool isBindingNode() const override { return true; }
1666
1667 JSTextPosition m_divotStart;
1668 JSTextPosition m_divotEnd;
1669 Identifier m_boundProperty;
1670 };
1671
1672 class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
1673 public:
1674 DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
1675 DeconstructionPatternNode* bindings() { return m_bindings.get(); }
1676
1677 using ParserArenaDeletable::operator new;
1678
1679 private:
1680 virtual bool isAssignmentLocation() const override { return true; }
1681 virtual bool isDeconstructionNode() const override { return true; }
1682 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1683
1684 RefPtr<DeconstructionPatternNode> m_bindings;
1685 ExpressionNode* m_initializer;
1686 };
1687
1688 class FuncDeclNode : public StatementNode {
1689 public:
1690 FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1691
1692 FunctionBodyNode* body() { return m_body; }
1693
1694 private:
1695 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1696
1697 FunctionBodyNode* m_body;
1698 };
1699
1700 class CaseClauseNode : public ParserArenaFreeable {
1701 public:
1702 CaseClauseNode(ExpressionNode*, SourceElements* = 0);
1703
1704 ExpressionNode* expr() const { return m_expr; }
1705
1706 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1707
1708 private:
1709 ExpressionNode* m_expr;
1710 SourceElements* m_statements;
1711 };
1712
1713 class ClauseListNode : public ParserArenaFreeable {
1714 public:
1715 ClauseListNode(CaseClauseNode*);
1716 ClauseListNode(ClauseListNode*, CaseClauseNode*);
1717
1718 CaseClauseNode* getClause() const { return m_clause; }
1719 ClauseListNode* getNext() const { return m_next; }
1720
1721 private:
1722 CaseClauseNode* m_clause;
1723 ClauseListNode* m_next;
1724 };
1725
1726 class CaseBlockNode : public ParserArenaFreeable {
1727 public:
1728 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1729
1730 void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
1731
1732 private:
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;
1738 };
1739
1740 class SwitchNode : public StatementNode {
1741 public:
1742 SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
1743
1744 private:
1745 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1746
1747 ExpressionNode* m_expr;
1748 CaseBlockNode* m_block;
1749 };
1750
1751 struct ElementList {
1752 ElementNode* head;
1753 ElementNode* tail;
1754 };
1755
1756 struct PropertyList {
1757 PropertyListNode* head;
1758 PropertyListNode* tail;
1759 };
1760
1761 struct ArgumentList {
1762 ArgumentListNode* head;
1763 ArgumentListNode* tail;
1764 };
1765
1766 struct ConstDeclList {
1767 ConstDeclNode* head;
1768 ConstDeclNode* tail;
1769 };
1770
1771 struct ParameterList {
1772 ParameterNode* head;
1773 ParameterNode* tail;
1774 };
1775
1776 struct ClauseList {
1777 ClauseListNode* head;
1778 ClauseListNode* tail;
1779 };
1780
1781} // namespace JSC
1782
1783#endif // Nodes_h