]> git.saurik.com Git - apple/javascriptcore.git/blob - parser/Nodes.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / parser / Nodes.h
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
39 namespace 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<const 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 protected:
116 ParserArenaRefCounted(VM*);
117
118 public:
119 virtual ~ParserArenaRefCounted()
120 {
121 ASSERT(deletionHasBegun());
122 }
123 };
124
125 class Node : public ParserArenaFreeable {
126 protected:
127 Node(const JSTokenLocation&);
128
129 public:
130 virtual ~Node() { }
131
132 int lineNo() const { return m_lineNumber; }
133 int startOffset() const { return m_startOffset; }
134 int lineStartOffset() const { return m_lineStartOffset; }
135
136 protected:
137 int m_lineNumber;
138 int m_startOffset;
139 int m_lineStartOffset;
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 isResolveNode() const { return false; }
156 virtual bool isBracketAccessorNode() const { return false; }
157 virtual bool isDotAccessorNode() const { return false; }
158 virtual bool isFuncExprNode() const { return false; }
159 virtual bool isCommaNode() const { return false; }
160 virtual bool isSimpleArray() const { return false; }
161 virtual bool isAdd() const { return false; }
162 virtual bool isSubtract() const { return false; }
163 virtual bool isBoolean() const { return false; }
164
165 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
166
167 virtual ExpressionNode* stripUnaryPlus() { return this; }
168
169 ResultType resultDescriptor() const { return m_resultType; }
170
171 private:
172 ResultType m_resultType;
173 };
174
175 class StatementNode : public Node {
176 protected:
177 StatementNode(const JSTokenLocation&);
178
179 public:
180 virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
181
182 void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
183 unsigned firstLine() const { return lineNo(); }
184 unsigned lastLine() const { return m_lastLine; }
185
186 virtual bool isEmptyStatement() const { return false; }
187 virtual bool isReturnNode() const { return false; }
188 virtual bool isExprStatement() const { return false; }
189 virtual bool isBreak() const { return false; }
190 virtual bool isContinue() const { return false; }
191 virtual bool isBlock() const { return false; }
192
193 private:
194 int m_lastLine;
195 };
196
197 class ConstantNode : public ExpressionNode {
198 public:
199 ConstantNode(const JSTokenLocation&, ResultType);
200 virtual bool isPure(BytecodeGenerator&) const { return true; }
201 virtual bool isConstant() const { return true; }
202 virtual JSValue jsValue(BytecodeGenerator&) const = 0;
203 private:
204 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
205 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
206 };
207
208 class NullNode : public ConstantNode {
209 public:
210 NullNode(const JSTokenLocation&);
211
212 private:
213 virtual bool isNull() const { return true; }
214 virtual JSValue jsValue(BytecodeGenerator&) const { return jsNull(); }
215 };
216
217 class BooleanNode : public ConstantNode {
218 public:
219 BooleanNode(const JSTokenLocation&, bool value);
220 bool value() { return m_value; }
221
222 private:
223 virtual bool isBoolean() const { return true; }
224 virtual JSValue jsValue(BytecodeGenerator&) const { return jsBoolean(m_value); }
225
226 bool m_value;
227 };
228
229 class NumberNode : public ConstantNode {
230 public:
231 NumberNode(const JSTokenLocation&, double value);
232 double value() { return m_value; }
233 void setValue(double value) { m_value = value; }
234
235 private:
236 virtual bool isNumber() const { return true; }
237 virtual JSValue jsValue(BytecodeGenerator&) const { return jsNumber(m_value); }
238
239 double m_value;
240 };
241
242 class StringNode : public ConstantNode {
243 public:
244 StringNode(const JSTokenLocation&, const Identifier&);
245 const Identifier& value() { return m_value; }
246
247 private:
248 virtual bool isString() const { return true; }
249 virtual JSValue jsValue(BytecodeGenerator&) const;
250
251 const Identifier& m_value;
252 };
253
254 class ThrowableExpressionData {
255 public:
256 ThrowableExpressionData()
257 : m_divot(static_cast<uint32_t>(-1))
258 , m_divotStartOffset(static_cast<uint16_t>(-1))
259 , m_divotEndOffset(static_cast<uint16_t>(-1))
260 , m_divotLine(static_cast<uint32_t>(-1))
261 , m_divotLineStart(static_cast<uint32_t>(-1))
262 {
263 }
264
265 ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
266 : m_divot(divot)
267 , m_divotStartOffset(startOffset)
268 , m_divotEndOffset(endOffset)
269 , m_divotLine(divotLine)
270 , m_divotLineStart(divotLineStart)
271 {
272 ASSERT(m_divot >= m_divotLineStart);
273 }
274
275 void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
276 {
277 ASSERT(divot >= divotLineStart);
278 m_divot = divot;
279 m_divotStartOffset = startOffset;
280 m_divotEndOffset = endOffset;
281 m_divotLine = divotLine;
282 m_divotLineStart = divotLineStart;
283 }
284
285 uint32_t divot() const { return m_divot; }
286 uint16_t divotStartOffset() const { return m_divotStartOffset; }
287 uint16_t divotEndOffset() const { return m_divotEndOffset; }
288 uint32_t divotLine() const { return m_divotLine; }
289 uint32_t divotLineStart() const { return m_divotLineStart; }
290
291 protected:
292 RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
293
294 private:
295 uint32_t m_divot;
296 uint16_t m_divotStartOffset;
297 uint16_t m_divotEndOffset;
298 uint32_t m_divotLine;
299 uint32_t m_divotLineStart;
300 };
301
302 class ThrowableSubExpressionData : public ThrowableExpressionData {
303 public:
304 ThrowableSubExpressionData()
305 : m_subexpressionDivotOffset(0)
306 , m_subexpressionEndOffset(0)
307 , m_subexpressionLineOffset(0)
308 , m_subexpressionLineStartOffset(0)
309 {
310 }
311
312 ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
313 : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
314 , m_subexpressionDivotOffset(0)
315 , m_subexpressionEndOffset(0)
316 , m_subexpressionLineOffset(0)
317 , m_subexpressionLineStartOffset(0)
318 {
319 }
320
321 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
322 {
323 ASSERT(subexpressionDivot <= divot());
324 // Overflow means we can't do this safely, so just point at the primary divot,
325 // divotLine, or divotLineStart.
326 if ((divot() - subexpressionDivot) & ~0xFFFF)
327 return;
328 if ((divotLine() - subexpressionLine) & ~0xFFFF)
329 return;
330 if ((divotLineStart() - subexpressionLineStart) & ~0xFFFF)
331 return;
332 m_subexpressionDivotOffset = divot() - subexpressionDivot;
333 m_subexpressionEndOffset = subexpressionOffset;
334 m_subexpressionLineOffset = divotLine() - subexpressionLine;
335 m_subexpressionLineStartOffset = divotLineStart() - subexpressionLineStart;
336 }
337
338 unsigned subexpressionDivot() { return divot() - m_subexpressionDivotOffset; }
339 unsigned subexpressionStartOffset() { return divotStartOffset() - m_subexpressionDivotOffset; }
340 unsigned subexpressionEndOffset() { return m_subexpressionEndOffset; }
341 unsigned subexpressionLine() { return divotLine() - m_subexpressionLineOffset; }
342 unsigned subexpressionLineStart() { return divotLineStart() - m_subexpressionLineStartOffset; }
343
344 protected:
345 uint16_t m_subexpressionDivotOffset;
346 uint16_t m_subexpressionEndOffset;
347 uint16_t m_subexpressionLineOffset;
348 uint16_t m_subexpressionLineStartOffset;
349 };
350
351 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
352 public:
353 ThrowablePrefixedSubExpressionData()
354 : m_subexpressionDivotOffset(0)
355 , m_subexpressionStartOffset(0)
356 , m_subexpressionLineOffset(0)
357 , m_subexpressionLineStartOffset(0)
358 {
359 }
360
361 ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
362 : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
363 , m_subexpressionDivotOffset(0)
364 , m_subexpressionStartOffset(0)
365 , m_subexpressionLineOffset(0)
366 , m_subexpressionLineStartOffset(0)
367 {
368 }
369
370 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
371 {
372 ASSERT(subexpressionDivot >= divot());
373 // Overflow means we can't do this safely, so just point at the primary divot,
374 // divotLine, or divotLineStart.
375 if ((subexpressionDivot - divot()) & ~0xFFFF)
376 return;
377 if ((subexpressionLine - divotLine()) & ~0xFFFF)
378 return;
379 if ((subexpressionLineStart - divotLineStart()) & ~0xFFFF)
380 return;
381 m_subexpressionDivotOffset = subexpressionDivot - divot();
382 m_subexpressionStartOffset = subexpressionOffset;
383 m_subexpressionLineOffset = subexpressionLine - divotLine();
384 m_subexpressionLineStartOffset = subexpressionLineStart - divotLineStart();
385 }
386
387 unsigned subexpressionDivot() { return divot() + m_subexpressionDivotOffset; }
388 unsigned subexpressionStartOffset() { return m_subexpressionStartOffset; }
389 unsigned subexpressionEndOffset() { return divotEndOffset() + m_subexpressionDivotOffset; }
390 unsigned subexpressionLine() { return divotLine() + m_subexpressionLineOffset; }
391 unsigned subexpressionLineStart() { return divotLineStart() + m_subexpressionLineStartOffset; }
392
393 protected:
394 uint16_t m_subexpressionDivotOffset;
395 uint16_t m_subexpressionStartOffset;
396 uint16_t m_subexpressionLineOffset;
397 uint16_t m_subexpressionLineStartOffset;
398 };
399
400 class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
401 public:
402 RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
403
404 private:
405 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
406
407 const Identifier& m_pattern;
408 const Identifier& m_flags;
409 };
410
411 class ThisNode : public ExpressionNode {
412 public:
413 ThisNode(const JSTokenLocation&);
414
415 private:
416 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
417 };
418
419 class ResolveNode : public ExpressionNode {
420 public:
421 ResolveNode(const JSTokenLocation&, const Identifier&, unsigned startOffset, unsigned divotLine, unsigned divotLineStart);
422
423 const Identifier& identifier() const { return m_ident; }
424
425 private:
426 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
427
428 virtual bool isPure(BytecodeGenerator&) const ;
429 virtual bool isLocation() const { return true; }
430 virtual bool isResolveNode() const { return true; }
431
432 const Identifier& m_ident;
433 uint32_t m_startOffset;
434 uint32_t m_divotLine;
435 uint32_t m_divotLineStart;
436 };
437
438 class ElementNode : public ParserArenaFreeable {
439 public:
440 ElementNode(int elision, ExpressionNode*);
441 ElementNode(ElementNode*, int elision, ExpressionNode*);
442
443 int elision() const { return m_elision; }
444 ExpressionNode* value() { return m_node; }
445 ElementNode* next() { return m_next; }
446
447 private:
448 ElementNode* m_next;
449 int m_elision;
450 ExpressionNode* m_node;
451 };
452
453 class ArrayNode : public ExpressionNode {
454 public:
455 ArrayNode(const JSTokenLocation&, int elision);
456 ArrayNode(const JSTokenLocation&, ElementNode*);
457 ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
458
459 ArgumentListNode* toArgumentList(VM*, int, int) const;
460
461 private:
462 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
463
464 virtual bool isSimpleArray() const ;
465
466 ElementNode* m_element;
467 int m_elision;
468 bool m_optional;
469 };
470
471 class PropertyNode : public ParserArenaFreeable {
472 public:
473 enum Type { Constant = 1, Getter = 2, Setter = 4 };
474
475 PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
476 PropertyNode(VM*, double, ExpressionNode*, Type);
477
478 const Identifier& name() const { return m_name; }
479 Type type() const { return m_type; }
480
481 private:
482 friend class PropertyListNode;
483 const Identifier& m_name;
484 ExpressionNode* m_assign;
485 Type m_type;
486 };
487
488 class PropertyListNode : public ExpressionNode {
489 public:
490 PropertyListNode(const JSTokenLocation&, PropertyNode*);
491 PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
492
493 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
494
495 private:
496 PropertyNode* m_node;
497 PropertyListNode* m_next;
498 };
499
500 class ObjectLiteralNode : public ExpressionNode {
501 public:
502 ObjectLiteralNode(const JSTokenLocation&);
503 ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
504
505 private:
506 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
507
508 PropertyListNode* m_list;
509 };
510
511 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
512 public:
513 BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
514
515 ExpressionNode* base() const { return m_base; }
516 ExpressionNode* subscript() const { return m_subscript; }
517
518 bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
519
520 private:
521 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
522
523 virtual bool isLocation() const { return true; }
524 virtual bool isBracketAccessorNode() const { return true; }
525
526 ExpressionNode* m_base;
527 ExpressionNode* m_subscript;
528 bool m_subscriptHasAssignments;
529 };
530
531 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
532 public:
533 DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
534
535 ExpressionNode* base() const { return m_base; }
536 const Identifier& identifier() const { return m_ident; }
537
538 private:
539 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
540
541 virtual bool isLocation() const { return true; }
542 virtual bool isDotAccessorNode() const { return true; }
543
544 ExpressionNode* m_base;
545 const Identifier& m_ident;
546 };
547
548 class ArgumentListNode : public ExpressionNode {
549 public:
550 ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
551 ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
552
553 ArgumentListNode* m_next;
554 ExpressionNode* m_expr;
555
556 private:
557 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
558 };
559
560 class ArgumentsNode : public ParserArenaFreeable {
561 public:
562 ArgumentsNode();
563 ArgumentsNode(ArgumentListNode*);
564
565 ArgumentListNode* m_listNode;
566 };
567
568 class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
569 public:
570 NewExprNode(const JSTokenLocation&, ExpressionNode*);
571 NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
572
573 private:
574 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
575
576 ExpressionNode* m_expr;
577 ArgumentsNode* m_args;
578 };
579
580 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
581 public:
582 EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
583
584 private:
585 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
586
587 ArgumentsNode* m_args;
588 };
589
590 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
591 public:
592 FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
593
594 private:
595 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
596
597 ExpressionNode* m_expr;
598 ArgumentsNode* m_args;
599 };
600
601 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
602 public:
603 FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
604
605 private:
606 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
607
608 const Identifier& m_ident;
609 ArgumentsNode* m_args;
610 };
611
612 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
613 public:
614 FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
615
616 private:
617 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
618
619 ExpressionNode* m_base;
620 ExpressionNode* m_subscript;
621 ArgumentsNode* m_args;
622 };
623
624 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
625 public:
626 FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
627
628 private:
629 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
630
631 protected:
632 ExpressionNode* m_base;
633 const Identifier& m_ident;
634 ArgumentsNode* m_args;
635 };
636
637 class CallFunctionCallDotNode : public FunctionCallDotNode {
638 public:
639 CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
640
641 private:
642 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
643 };
644
645 class ApplyFunctionCallDotNode : public FunctionCallDotNode {
646 public:
647 ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
648
649 private:
650 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
651 };
652
653 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
654 public:
655 DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
656
657 private:
658 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
659
660 const Identifier& m_ident;
661 };
662
663 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
664 public:
665 DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
666
667 private:
668 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
669
670 ExpressionNode* m_base;
671 ExpressionNode* m_subscript;
672 };
673
674 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
675 public:
676 DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
677
678 private:
679 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
680
681 ExpressionNode* m_base;
682 const Identifier& m_ident;
683 };
684
685 class DeleteValueNode : public ExpressionNode {
686 public:
687 DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
688
689 private:
690 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
691
692 ExpressionNode* m_expr;
693 };
694
695 class VoidNode : public ExpressionNode {
696 public:
697 VoidNode(const JSTokenLocation&, ExpressionNode*);
698
699 private:
700 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
701
702 ExpressionNode* m_expr;
703 };
704
705 class TypeOfResolveNode : public ExpressionNode {
706 public:
707 TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
708
709 const Identifier& identifier() const { return m_ident; }
710
711 private:
712 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
713
714 const Identifier& m_ident;
715 };
716
717 class TypeOfValueNode : public ExpressionNode {
718 public:
719 TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
720
721 private:
722 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
723
724 ExpressionNode* m_expr;
725 };
726
727 class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
728 public:
729 PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
730
731 protected:
732 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
733 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
734 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
735 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
736
737 ExpressionNode* m_expr;
738 Operator m_operator;
739 };
740
741 class PostfixNode : public PrefixNode {
742 public:
743 PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
744
745 private:
746 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
747 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
748 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
749 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
750 };
751
752 class UnaryOpNode : public ExpressionNode {
753 public:
754 UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
755
756 protected:
757 ExpressionNode* expr() { return m_expr; }
758 const ExpressionNode* expr() const { return m_expr; }
759
760 private:
761 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
762
763 OpcodeID opcodeID() const { return m_opcodeID; }
764
765 ExpressionNode* m_expr;
766 OpcodeID m_opcodeID;
767 };
768
769 class UnaryPlusNode : public UnaryOpNode {
770 public:
771 UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
772
773 private:
774 virtual ExpressionNode* stripUnaryPlus() { return expr(); }
775 };
776
777 class NegateNode : public UnaryOpNode {
778 public:
779 NegateNode(const JSTokenLocation&, ExpressionNode*);
780 };
781
782 class BitwiseNotNode : public ExpressionNode {
783 public:
784 BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
785
786 protected:
787 ExpressionNode* expr() { return m_expr; }
788 const ExpressionNode* expr() const { return m_expr; }
789
790 private:
791 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
792
793 ExpressionNode* m_expr;
794 };
795
796 class LogicalNotNode : public UnaryOpNode {
797 public:
798 LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
799 private:
800 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
801 };
802
803 class BinaryOpNode : public ExpressionNode {
804 public:
805 BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
806 BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
807
808 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
809 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
810
811 ExpressionNode* lhs() { return m_expr1; };
812 ExpressionNode* rhs() { return m_expr2; };
813
814 private:
815 void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
816 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
817
818 protected:
819 OpcodeID opcodeID() const { return m_opcodeID; }
820
821 protected:
822 ExpressionNode* m_expr1;
823 ExpressionNode* m_expr2;
824 private:
825 OpcodeID m_opcodeID;
826 protected:
827 bool m_rightHasAssignments;
828 };
829
830 class MultNode : public BinaryOpNode {
831 public:
832 MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
833 };
834
835 class DivNode : public BinaryOpNode {
836 public:
837 DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
838 };
839
840 class ModNode : public BinaryOpNode {
841 public:
842 ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
843 };
844
845 class AddNode : public BinaryOpNode {
846 public:
847 AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
848
849 virtual bool isAdd() const { return true; }
850 };
851
852 class SubNode : public BinaryOpNode {
853 public:
854 SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
855
856 virtual bool isSubtract() const { return true; }
857 };
858
859 class LeftShiftNode : public BinaryOpNode {
860 public:
861 LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
862 };
863
864 class RightShiftNode : public BinaryOpNode {
865 public:
866 RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
867 };
868
869 class UnsignedRightShiftNode : public BinaryOpNode {
870 public:
871 UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
872 };
873
874 class LessNode : public BinaryOpNode {
875 public:
876 LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
877 };
878
879 class GreaterNode : public BinaryOpNode {
880 public:
881 GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
882 };
883
884 class LessEqNode : public BinaryOpNode {
885 public:
886 LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
887 };
888
889 class GreaterEqNode : public BinaryOpNode {
890 public:
891 GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
892 };
893
894 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
895 public:
896 ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
897 ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
898
899 private:
900 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
901 };
902
903 class InstanceOfNode : public ThrowableBinaryOpNode {
904 public:
905 InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
906
907 private:
908 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
909 };
910
911 class InNode : public ThrowableBinaryOpNode {
912 public:
913 InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
914 };
915
916 class EqualNode : public BinaryOpNode {
917 public:
918 EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
919
920 private:
921 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
922 };
923
924 class NotEqualNode : public BinaryOpNode {
925 public:
926 NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
927 };
928
929 class StrictEqualNode : public BinaryOpNode {
930 public:
931 StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
932
933 private:
934 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
935 };
936
937 class NotStrictEqualNode : public BinaryOpNode {
938 public:
939 NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
940 };
941
942 class BitAndNode : public BinaryOpNode {
943 public:
944 BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
945 };
946
947 class BitOrNode : public BinaryOpNode {
948 public:
949 BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
950 };
951
952 class BitXOrNode : public BinaryOpNode {
953 public:
954 BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
955 };
956
957 // m_expr1 && m_expr2, m_expr1 || m_expr2
958 class LogicalOpNode : public ExpressionNode {
959 public:
960 LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
961
962 private:
963 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
964 void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
965
966 ExpressionNode* m_expr1;
967 ExpressionNode* m_expr2;
968 LogicalOperator m_operator;
969 };
970
971 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
972 class ConditionalNode : public ExpressionNode {
973 public:
974 ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
975
976 private:
977 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
978
979 ExpressionNode* m_logical;
980 ExpressionNode* m_expr1;
981 ExpressionNode* m_expr2;
982 };
983
984 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
985 public:
986 ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
987
988 private:
989 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
990
991 const Identifier& m_ident;
992 ExpressionNode* m_right;
993 Operator m_operator;
994 bool m_rightHasAssignments;
995 };
996
997 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
998 public:
999 AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
1000
1001 private:
1002 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1003
1004 const Identifier& m_ident;
1005 ExpressionNode* m_right;
1006 };
1007
1008 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1009 public:
1010 ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
1011
1012 private:
1013 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1014
1015 ExpressionNode* m_base;
1016 ExpressionNode* m_subscript;
1017 ExpressionNode* m_right;
1018 Operator m_operator : 30;
1019 bool m_subscriptHasAssignments : 1;
1020 bool m_rightHasAssignments : 1;
1021 };
1022
1023 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1024 public:
1025 AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
1026
1027 private:
1028 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1029
1030 ExpressionNode* m_base;
1031 ExpressionNode* m_subscript;
1032 ExpressionNode* m_right;
1033 bool m_subscriptHasAssignments : 1;
1034 bool m_rightHasAssignments : 1;
1035 };
1036
1037 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1038 public:
1039 AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
1040
1041 private:
1042 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1043
1044 ExpressionNode* m_base;
1045 const Identifier& m_ident;
1046 ExpressionNode* m_right;
1047 bool m_rightHasAssignments;
1048 };
1049
1050 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1051 public:
1052 ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
1053
1054 private:
1055 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1056
1057 ExpressionNode* m_base;
1058 const Identifier& m_ident;
1059 ExpressionNode* m_right;
1060 Operator m_operator : 31;
1061 bool m_rightHasAssignments : 1;
1062 };
1063
1064 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1065 public:
1066 AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
1067
1068 private:
1069 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1070 };
1071
1072 typedef Vector<ExpressionNode*, 8> ExpressionVector;
1073
1074 class CommaNode : public ExpressionNode, public ParserArenaDeletable {
1075 public:
1076 CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
1077
1078 using ParserArenaDeletable::operator new;
1079
1080 void append(ExpressionNode* expr) { m_expressions.append(expr); }
1081
1082 private:
1083 virtual bool isCommaNode() const { return true; }
1084 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1085
1086 ExpressionVector m_expressions;
1087 };
1088
1089 class ConstDeclNode : public ExpressionNode {
1090 public:
1091 ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
1092
1093 bool hasInitializer() const { return m_init; }
1094 const Identifier& ident() { return m_ident; }
1095
1096 private:
1097 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1098 virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
1099
1100 const Identifier& m_ident;
1101
1102 public:
1103 ConstDeclNode* m_next;
1104
1105 private:
1106 ExpressionNode* m_init;
1107 };
1108
1109 class ConstStatementNode : public StatementNode {
1110 public:
1111 ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
1112
1113 private:
1114 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1115
1116 ConstDeclNode* m_next;
1117 };
1118
1119 class SourceElements : public ParserArenaDeletable {
1120 public:
1121 SourceElements();
1122
1123 void append(StatementNode*);
1124
1125 StatementNode* singleStatement() const;
1126 StatementNode* lastStatement() const;
1127
1128 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1129
1130 private:
1131 Vector<StatementNode*> m_statements;
1132 };
1133
1134 class BlockNode : public StatementNode {
1135 public:
1136 BlockNode(const JSTokenLocation&, SourceElements* = 0);
1137
1138 StatementNode* singleStatement() const;
1139 StatementNode* lastStatement() const;
1140
1141 private:
1142 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1143
1144 virtual bool isBlock() const { return true; }
1145
1146 SourceElements* m_statements;
1147 };
1148
1149 class EmptyStatementNode : public StatementNode {
1150 public:
1151 EmptyStatementNode(const JSTokenLocation&);
1152
1153 private:
1154 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1155
1156 virtual bool isEmptyStatement() const { return true; }
1157 };
1158
1159 class DebuggerStatementNode : public StatementNode {
1160 public:
1161 DebuggerStatementNode(const JSTokenLocation&);
1162
1163 private:
1164 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1165 };
1166
1167 class ExprStatementNode : public StatementNode {
1168 public:
1169 ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
1170
1171 ExpressionNode* expr() const { return m_expr; }
1172
1173 private:
1174 virtual bool isExprStatement() const { return true; }
1175
1176 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1177
1178 ExpressionNode* m_expr;
1179 };
1180
1181 class VarStatementNode : public StatementNode {
1182 public:
1183 VarStatementNode(const JSTokenLocation&, ExpressionNode*);
1184 private:
1185 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1186
1187 ExpressionNode* m_expr;
1188 };
1189
1190 class IfElseNode : public StatementNode {
1191 public:
1192 IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1193
1194 private:
1195 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1196 bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
1197 Label*& trueTarget, FallThroughMode&);
1198
1199 ExpressionNode* m_condition;
1200 StatementNode* m_ifBlock;
1201 StatementNode* m_elseBlock;
1202 };
1203
1204 class DoWhileNode : public StatementNode {
1205 public:
1206 DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
1207
1208 private:
1209 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1210
1211 StatementNode* m_statement;
1212 ExpressionNode* m_expr;
1213 };
1214
1215 class WhileNode : public StatementNode {
1216 public:
1217 WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
1218
1219 private:
1220 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1221
1222 ExpressionNode* m_expr;
1223 StatementNode* m_statement;
1224 };
1225
1226 class ForNode : public StatementNode {
1227 public:
1228 ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
1229
1230 private:
1231 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1232
1233 ExpressionNode* m_expr1;
1234 ExpressionNode* m_expr2;
1235 ExpressionNode* m_expr3;
1236 StatementNode* m_statement;
1237 };
1238
1239 class ForInNode : public StatementNode, public ThrowableExpressionData {
1240 public:
1241 ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1242 ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart);
1243
1244 private:
1245 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1246
1247 ExpressionNode* m_init;
1248 ExpressionNode* m_lexpr;
1249 ExpressionNode* m_expr;
1250 StatementNode* m_statement;
1251 };
1252
1253 class ContinueNode : public StatementNode, public ThrowableExpressionData {
1254 public:
1255 ContinueNode(VM*, const JSTokenLocation&);
1256 ContinueNode(const JSTokenLocation&, const Identifier&);
1257 Label* trivialTarget(BytecodeGenerator&);
1258
1259 private:
1260 virtual bool isContinue() const { return true; }
1261 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1262
1263 const Identifier& m_ident;
1264 };
1265
1266 class BreakNode : public StatementNode, public ThrowableExpressionData {
1267 public:
1268 BreakNode(VM*, const JSTokenLocation&);
1269 BreakNode(const JSTokenLocation&, const Identifier&);
1270 Label* trivialTarget(BytecodeGenerator&);
1271
1272 private:
1273 virtual bool isBreak() const { return true; }
1274 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1275
1276 const Identifier& m_ident;
1277 };
1278
1279 class ReturnNode : public StatementNode, public ThrowableExpressionData {
1280 public:
1281 ReturnNode(const JSTokenLocation&, ExpressionNode* value);
1282
1283 ExpressionNode* value() { return m_value; }
1284
1285 private:
1286 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1287
1288 virtual bool isReturnNode() const { return true; }
1289
1290 ExpressionNode* m_value;
1291 };
1292
1293 class WithNode : public StatementNode {
1294 public:
1295 WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength);
1296
1297 private:
1298 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1299
1300 ExpressionNode* m_expr;
1301 StatementNode* m_statement;
1302 uint32_t m_divot;
1303 uint32_t m_divotLine;
1304 uint32_t m_divotLineStart;
1305 uint32_t m_expressionLength;
1306 };
1307
1308 class LabelNode : public StatementNode, public ThrowableExpressionData {
1309 public:
1310 LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
1311
1312 private:
1313 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1314
1315 const Identifier& m_name;
1316 StatementNode* m_statement;
1317 };
1318
1319 class ThrowNode : public StatementNode, public ThrowableExpressionData {
1320 public:
1321 ThrowNode(const JSTokenLocation&, ExpressionNode*);
1322
1323 private:
1324 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1325
1326 ExpressionNode* m_expr;
1327 };
1328
1329 class TryNode : public StatementNode {
1330 public:
1331 TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
1332
1333 private:
1334 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1335
1336 StatementNode* m_tryBlock;
1337 const Identifier& m_exceptionIdent;
1338 StatementNode* m_catchBlock;
1339 StatementNode* m_finallyBlock;
1340 };
1341
1342 class ParameterNode : public ParserArenaFreeable {
1343 public:
1344 ParameterNode(const Identifier&);
1345 ParameterNode(ParameterNode*, const Identifier&);
1346
1347 const Identifier& ident() const { return m_ident; }
1348 ParameterNode* nextParam() const { return m_next; }
1349
1350 private:
1351 const Identifier& m_ident;
1352 ParameterNode* m_next;
1353 };
1354
1355 class ScopeNode : public StatementNode, public ParserArenaRefCounted {
1356 public:
1357 typedef DeclarationStacks::VarStack VarStack;
1358 typedef DeclarationStacks::FunctionStack FunctionStack;
1359
1360 ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
1361 ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
1362
1363 using ParserArenaRefCounted::operator new;
1364
1365 void destroyData()
1366 {
1367 m_arena.reset();
1368 m_varStack.clear();
1369 m_functionStack.clear();
1370 m_statements = 0;
1371 m_capturedVariables.clear();
1372 }
1373
1374 const SourceCode& source() const { return m_source; }
1375 const String& sourceURL() const { return m_source.provider()->url(); }
1376 intptr_t sourceID() const { return m_source.providerID(); }
1377
1378 int startLine() const { return m_startLineNumber; }
1379 int startStartOffset() const { return m_startStartOffset; }
1380 int startLineStartOffset() const { return m_startLineStartOffset; }
1381
1382 void setFeatures(CodeFeatures features) { m_features = features; }
1383 CodeFeatures features() { return m_features; }
1384
1385 bool usesEval() const { return m_features & EvalFeature; }
1386 bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
1387 bool isStrictMode() const { return m_features & StrictModeFeature; }
1388 void setUsesArguments() { m_features |= ArgumentsFeature; }
1389 bool usesThis() const { return m_features & ThisFeature; }
1390 bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
1391 bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
1392 bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
1393 size_t capturedVariableCount() const { return m_capturedVariables.size(); }
1394 bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
1395
1396 VarStack& varStack() { return m_varStack; }
1397 FunctionStack& functionStack() { return m_functionStack; }
1398
1399 int neededConstants()
1400 {
1401 // We may need 2 more constants than the count given by the parser,
1402 // because of the various uses of jsUndefined() and jsNull().
1403 return m_numConstants + 2;
1404 }
1405
1406 StatementNode* singleStatement() const;
1407
1408 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
1409
1410 protected:
1411 void setSource(const SourceCode& source) { m_source = source; }
1412 ParserArena m_arena;
1413
1414 int m_startLineNumber;
1415 unsigned m_startStartOffset;
1416 unsigned m_startLineStartOffset;
1417
1418 private:
1419 CodeFeatures m_features;
1420 SourceCode m_source;
1421 VarStack m_varStack;
1422 FunctionStack m_functionStack;
1423 int m_numConstants;
1424 SourceElements* m_statements;
1425 IdentifierSet m_capturedVariables;
1426 };
1427
1428 class ProgramNode : public ScopeNode {
1429 public:
1430 static const bool isFunctionNode = false;
1431 static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1432
1433 unsigned startColumn() { return m_startColumn; }
1434
1435 static const bool scopeIsFunction = false;
1436
1437 private:
1438 ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1439
1440 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1441
1442 unsigned m_startColumn;
1443 };
1444
1445 class EvalNode : public ScopeNode {
1446 public:
1447 static const bool isFunctionNode = false;
1448 static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1449
1450 unsigned startColumn() { return 1; }
1451
1452 static const bool scopeIsFunction = false;
1453
1454 private:
1455 EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1456
1457 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1458 };
1459
1460 class FunctionParameters : public RefCounted<FunctionParameters> {
1461 WTF_MAKE_FAST_ALLOCATED;
1462 public:
1463 static PassRefPtr<FunctionParameters> create(ParameterNode*);
1464 ~FunctionParameters();
1465
1466 unsigned size() const { return m_size; }
1467 const Identifier& at(unsigned index) const { ASSERT(index < m_size); return identifiers()[index]; }
1468
1469 private:
1470 FunctionParameters(ParameterNode*, unsigned size);
1471
1472 Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
1473 const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
1474
1475 unsigned m_size;
1476 void* m_storage;
1477 };
1478
1479 class FunctionBodyNode : public ScopeNode {
1480 public:
1481 static const bool isFunctionNode = true;
1482 static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool isStrictMode);
1483 static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1484
1485 FunctionParameters* parameters() const { return m_parameters.get(); }
1486 size_t parameterCount() const { return m_parameters->size(); }
1487
1488 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1489
1490 void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
1491 void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
1492
1493 const Identifier& ident() { return m_ident; }
1494 void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
1495 const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
1496
1497 bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; }
1498 FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
1499
1500 void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
1501 int functionStart() const { return m_functionStart; }
1502 unsigned startColumn() const { return m_startColumn; }
1503
1504 static const bool scopeIsFunction = true;
1505
1506 private:
1507 FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool inStrictContext);
1508 FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1509
1510 Identifier m_ident;
1511 Identifier m_inferredName;
1512 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
1513 RefPtr<FunctionParameters> m_parameters;
1514 int m_functionStart;
1515 unsigned m_startColumn;
1516 };
1517
1518 class FuncExprNode : public ExpressionNode {
1519 public:
1520 FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1521
1522 FunctionBodyNode* body() { return m_body; }
1523
1524 private:
1525 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1526
1527 virtual bool isFuncExprNode() const { return true; }
1528
1529 FunctionBodyNode* m_body;
1530 };
1531
1532 class FuncDeclNode : public StatementNode {
1533 public:
1534 FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1535
1536 FunctionBodyNode* body() { return m_body; }
1537
1538 private:
1539 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1540
1541 FunctionBodyNode* m_body;
1542 };
1543
1544 class CaseClauseNode : public ParserArenaFreeable {
1545 public:
1546 CaseClauseNode(ExpressionNode*, SourceElements* = 0);
1547
1548 ExpressionNode* expr() const { return m_expr; }
1549
1550 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1551
1552 private:
1553 ExpressionNode* m_expr;
1554 SourceElements* m_statements;
1555 };
1556
1557 class ClauseListNode : public ParserArenaFreeable {
1558 public:
1559 ClauseListNode(CaseClauseNode*);
1560 ClauseListNode(ClauseListNode*, CaseClauseNode*);
1561
1562 CaseClauseNode* getClause() const { return m_clause; }
1563 ClauseListNode* getNext() const { return m_next; }
1564
1565 private:
1566 CaseClauseNode* m_clause;
1567 ClauseListNode* m_next;
1568 };
1569
1570 class CaseBlockNode : public ParserArenaFreeable {
1571 public:
1572 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1573
1574 void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
1575
1576 private:
1577 SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
1578 static const size_t s_tableSwitchMinimum = 10;
1579 ClauseListNode* m_list1;
1580 CaseClauseNode* m_defaultClause;
1581 ClauseListNode* m_list2;
1582 };
1583
1584 class SwitchNode : public StatementNode {
1585 public:
1586 SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
1587
1588 private:
1589 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1590
1591 ExpressionNode* m_expr;
1592 CaseBlockNode* m_block;
1593 };
1594
1595 struct ElementList {
1596 ElementNode* head;
1597 ElementNode* tail;
1598 };
1599
1600 struct PropertyList {
1601 PropertyListNode* head;
1602 PropertyListNode* tail;
1603 };
1604
1605 struct ArgumentList {
1606 ArgumentListNode* head;
1607 ArgumentListNode* tail;
1608 };
1609
1610 struct ConstDeclList {
1611 ConstDeclNode* head;
1612 ConstDeclNode* tail;
1613 };
1614
1615 struct ParameterList {
1616 ParameterNode* head;
1617 ParameterNode* tail;
1618 };
1619
1620 struct ClauseList {
1621 ClauseListNode* head;
1622 ClauseListNode* tail;
1623 };
1624
1625 } // namespace JSC
1626
1627 #endif // Nodes_h