source: webkit/trunk/JavaScriptCore/parser/Nodes.h@ 47022

Last change on this file since 47022 was 47022, checked in by [email protected], 16 years ago

Stack overflow crash in JavaScript garbage collector mark pass
https://bugs.webkit.org/show_bug.cgi?id=12216

Reviewed by Gavin Barraclough and Sam Weinig

Make the GC mark phase iterative by using an explicit mark stack.
To do this marking any single object is performed in multiple stages

  • The object is appended to the MarkStack, this sets the marked bit for the object using the new markDirect() function, and then returns
  • When the MarkStack is drain()ed the object is popped off the stack and markChildren(MarkStack&) is called on the object to collect all of its children. drain() then repeats until the stack is empty.

Additionally I renamed a number of methods from 'mark' to 'markAggregate'
in order to make it more clear that marking of those object was not
going to result in an actual recursive mark.

  • Property svn:eol-style set to native
File size: 54.6 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <[email protected]>
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 "ResultType.h"
34#include "SourceCode.h"
35#include "SymbolTable.h"
36#include <wtf/MathExtras.h>
37#include <wtf/OwnPtr.h>
38
39namespace JSC {
40
41 class ArgumentListNode;
42 class CodeBlock;
43 class BytecodeGenerator;
44 class FuncDeclNode;
45 class EvalCodeBlock;
46 class JSFunction;
47 class ProgramCodeBlock;
48 class PropertyListNode;
49 class ReadModifyResolveNode;
50 class RegisterID;
51 class ScopeChainNode;
52
53 typedef unsigned CodeFeatures;
54
55 const CodeFeatures NoFeatures = 0;
56 const CodeFeatures EvalFeature = 1 << 0;
57 const CodeFeatures ClosureFeature = 1 << 1;
58 const CodeFeatures AssignFeature = 1 << 2;
59 const CodeFeatures ArgumentsFeature = 1 << 3;
60 const CodeFeatures WithFeature = 1 << 4;
61 const CodeFeatures CatchFeature = 1 << 5;
62 const CodeFeatures ThisFeature = 1 << 6;
63 const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature;
64
65 enum Operator {
66 OpEqual,
67 OpPlusEq,
68 OpMinusEq,
69 OpMultEq,
70 OpDivEq,
71 OpPlusPlus,
72 OpMinusMinus,
73 OpAndEq,
74 OpXOrEq,
75 OpOrEq,
76 OpModEq,
77 OpLShift,
78 OpRShift,
79 OpURShift
80 };
81
82 enum LogicalOperator {
83 OpLogicalAnd,
84 OpLogicalOr
85 };
86
87 namespace DeclarationStacks {
88 enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
89 typedef Vector<std::pair<Identifier, unsigned> > VarStack;
90 typedef Vector<FuncDeclNode*> FunctionStack;
91 }
92
93 struct SwitchInfo {
94 enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
95 uint32_t bytecodeOffset;
96 SwitchType switchType;
97 };
98
99 class ParserArenaDeletable {
100 protected:
101 ParserArenaDeletable() { }
102
103 public:
104 virtual ~ParserArenaDeletable() { }
105
106 // Objects created with this version of new are deleted when the arena is deleted.
107 void* operator new(size_t, JSGlobalData*);
108
109 // Objects created with this version of new are not deleted when the arena is deleted.
110 // Other arrangements must be made.
111 void* operator new(size_t);
112
113 void operator delete(void*);
114 };
115
116 class ParserArenaRefCounted : public RefCountedCustomAllocated<ParserArenaRefCounted> {
117 protected:
118 ParserArenaRefCounted(JSGlobalData*);
119
120 public:
121 virtual ~ParserArenaRefCounted()
122 {
123 ASSERT(deletionHasBegun());
124 }
125 };
126
127 class Node : public ParserArenaDeletable {
128 protected:
129 Node(JSGlobalData*);
130
131 public:
132 /*
133 Return value: The register holding the production's value.
134 dst: An optional parameter specifying the most efficient
135 destination at which to store the production's value.
136 The callee must honor dst.
137
138 dst provides for a crude form of copy propagation. For example,
139
140 x = 1
141
142 becomes
143
144 load r[x], 1
145
146 instead of
147
148 load r0, 1
149 mov r[x], r0
150
151 because the assignment node, "x =", passes r[x] as dst to the number
152 node, "1".
153 */
154 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) = 0;
155
156 int lineNo() const { return m_line; }
157
158 protected:
159 int m_line;
160 };
161
162 class ExpressionNode : public Node {
163 public:
164 ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
165
166 virtual bool isNumber() const { return false; }
167 virtual bool isString() const { return false; }
168 virtual bool isNull() const { return false; }
169 virtual bool isPure(BytecodeGenerator&) const { return false; }
170 virtual bool isLocation() const { return false; }
171 virtual bool isResolveNode() const { return false; }
172 virtual bool isBracketAccessorNode() const { return false; }
173 virtual bool isDotAccessorNode() const { return false; }
174 virtual bool isFuncExprNode() const { return false; }
175 virtual bool isCommaNode() const { return false; }
176 virtual bool isSimpleArray() const { return false; }
177 virtual bool isAdd() const { return false; }
178
179 virtual ExpressionNode* stripUnaryPlus() { return this; }
180
181 ResultType resultDescriptor() const { return m_resultType; }
182
183 // This needs to be in public in order to compile using GCC 3.x
184 typedef enum { EvalOperator, FunctionCall } CallerType;
185
186 private:
187 ResultType m_resultType;
188 };
189
190 class StatementNode : public Node {
191 public:
192 StatementNode(JSGlobalData*);
193
194 void setLoc(int line0, int line1);
195 int firstLine() const { return lineNo(); }
196 int lastLine() const { return m_lastLine; }
197
198 virtual bool isEmptyStatement() const { return false; }
199 virtual bool isReturnNode() const { return false; }
200 virtual bool isExprStatement() const { return false; }
201
202 virtual bool isBlock() const { return false; }
203
204 private:
205 int m_lastLine;
206 };
207
208 class NullNode : public ExpressionNode {
209 public:
210 NullNode(JSGlobalData*);
211
212 private:
213 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
214
215 virtual bool isNull() const { return true; }
216 };
217
218 class BooleanNode : public ExpressionNode {
219 public:
220 BooleanNode(JSGlobalData*, bool value);
221
222 private:
223 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
224
225 virtual bool isPure(BytecodeGenerator&) const { return true; }
226
227 bool m_value;
228 };
229
230 class NumberNode : public ExpressionNode {
231 public:
232 NumberNode(JSGlobalData*, double v);
233
234 double value() const { return m_double; }
235 void setValue(double d) { m_double = d; }
236
237 private:
238 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
239
240 virtual bool isNumber() const { return true; }
241 virtual bool isPure(BytecodeGenerator&) const { return true; }
242
243 double m_double;
244 };
245
246 class StringNode : public ExpressionNode {
247 public:
248 StringNode(JSGlobalData*, const Identifier& v);
249
250 const Identifier& value() { return m_value; }
251 virtual bool isPure(BytecodeGenerator&) const { return true; }
252
253 private:
254 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
255
256 virtual bool isString() const { return true; }
257
258 Identifier m_value;
259 };
260
261 class ThrowableExpressionData {
262 public:
263 ThrowableExpressionData()
264 : m_divot(static_cast<uint32_t>(-1))
265 , m_startOffset(static_cast<uint16_t>(-1))
266 , m_endOffset(static_cast<uint16_t>(-1))
267 {
268 }
269
270 ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
271 : m_divot(divot)
272 , m_startOffset(startOffset)
273 , m_endOffset(endOffset)
274 {
275 }
276
277 void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
278 {
279 m_divot = divot;
280 m_startOffset = startOffset;
281 m_endOffset = endOffset;
282 }
283
284 uint32_t divot() const { return m_divot; }
285 uint16_t startOffset() const { return m_startOffset; }
286 uint16_t endOffset() const { return m_endOffset; }
287
288 protected:
289 RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg);
290 RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&);
291
292 private:
293 uint32_t m_divot;
294 uint16_t m_startOffset;
295 uint16_t m_endOffset;
296 };
297
298 class ThrowableSubExpressionData : public ThrowableExpressionData {
299 public:
300 ThrowableSubExpressionData()
301 : ThrowableExpressionData()
302 , m_subexpressionDivotOffset(0)
303 , m_subexpressionEndOffset(0)
304 {
305 }
306
307 ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
308 : ThrowableExpressionData(divot, startOffset, endOffset)
309 , m_subexpressionDivotOffset(0)
310 , m_subexpressionEndOffset(0)
311 {
312 }
313
314 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
315 {
316 ASSERT(subexpressionDivot <= divot());
317 if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
318 return;
319 m_subexpressionDivotOffset = divot() - subexpressionDivot;
320 m_subexpressionEndOffset = subexpressionOffset;
321 }
322
323 protected:
324 uint16_t m_subexpressionDivotOffset;
325 uint16_t m_subexpressionEndOffset;
326 };
327
328 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
329 public:
330 ThrowablePrefixedSubExpressionData()
331 : ThrowableExpressionData()
332 , m_subexpressionDivotOffset(0)
333 , m_subexpressionStartOffset(0)
334 {
335 }
336
337 ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
338 : ThrowableExpressionData(divot, startOffset, endOffset)
339 , m_subexpressionDivotOffset(0)
340 , m_subexpressionStartOffset(0)
341 {
342 }
343
344 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
345 {
346 ASSERT(subexpressionDivot >= divot());
347 if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
348 return;
349 m_subexpressionDivotOffset = subexpressionDivot - divot();
350 m_subexpressionStartOffset = subexpressionOffset;
351 }
352
353 protected:
354 uint16_t m_subexpressionDivotOffset;
355 uint16_t m_subexpressionStartOffset;
356 };
357
358 class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
359 public:
360 RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags);
361
362 private:
363 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
364
365 UString m_pattern;
366 UString m_flags;
367 };
368
369 class ThisNode : public ExpressionNode {
370 public:
371 ThisNode(JSGlobalData*);
372
373 private:
374 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
375 };
376
377 class ResolveNode : public ExpressionNode {
378 public:
379 ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
380
381 const Identifier& identifier() const { return m_ident; }
382
383 private:
384 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
385
386 virtual bool isPure(BytecodeGenerator&) const ;
387 virtual bool isLocation() const { return true; }
388 virtual bool isResolveNode() const { return true; }
389
390 Identifier m_ident;
391 int32_t m_startOffset;
392 };
393
394 class ElementNode : public ParserArenaDeletable {
395 public:
396 ElementNode(JSGlobalData*, int elision, ExpressionNode*);
397 ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
398
399 int elision() const { return m_elision; }
400 ExpressionNode* value() { return m_node; }
401 ElementNode* next() { return m_next; }
402
403 private:
404 ElementNode* m_next;
405 int m_elision;
406 ExpressionNode* m_node;
407 };
408
409 class ArrayNode : public ExpressionNode {
410 public:
411 ArrayNode(JSGlobalData*, int elision);
412 ArrayNode(JSGlobalData*, ElementNode*);
413 ArrayNode(JSGlobalData*, int elision, ElementNode*);
414
415 ArgumentListNode* toArgumentList(JSGlobalData*) const;
416
417 private:
418 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
419
420 virtual bool isSimpleArray() const ;
421
422 ElementNode* m_element;
423 int m_elision;
424 bool m_optional;
425 };
426
427 class PropertyNode : public ParserArenaDeletable {
428 public:
429 enum Type { Constant, Getter, Setter };
430
431 PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
432
433 const Identifier& name() const { return m_name; }
434
435 private:
436 friend class PropertyListNode;
437 Identifier m_name;
438 ExpressionNode* m_assign;
439 Type m_type;
440 };
441
442 class PropertyListNode : public Node {
443 public:
444 PropertyListNode(JSGlobalData*, PropertyNode*);
445 PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*);
446
447 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
448
449 private:
450 PropertyNode* m_node;
451 PropertyListNode* m_next;
452 };
453
454 class ObjectLiteralNode : public ExpressionNode {
455 public:
456 ObjectLiteralNode(JSGlobalData*);
457 ObjectLiteralNode(JSGlobalData*, PropertyListNode*);
458
459 private:
460 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
461
462 PropertyListNode* m_list;
463 };
464
465 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
466 public:
467 BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
468
469 ExpressionNode* base() const { return m_base; }
470 ExpressionNode* subscript() const { return m_subscript; }
471
472 private:
473 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
474
475 virtual bool isLocation() const { return true; }
476 virtual bool isBracketAccessorNode() const { return true; }
477
478 ExpressionNode* m_base;
479 ExpressionNode* m_subscript;
480 bool m_subscriptHasAssignments;
481 };
482
483 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
484 public:
485 DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
486
487 ExpressionNode* base() const { return m_base; }
488 const Identifier& identifier() const { return m_ident; }
489
490 private:
491 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
492
493 virtual bool isLocation() const { return true; }
494 virtual bool isDotAccessorNode() const { return true; }
495
496 ExpressionNode* m_base;
497 Identifier m_ident;
498 };
499
500 class ArgumentListNode : public Node {
501 public:
502 ArgumentListNode(JSGlobalData*, ExpressionNode*);
503 ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*);
504
505 ArgumentListNode* m_next;
506 ExpressionNode* m_expr;
507
508 private:
509 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
510 };
511
512 class ArgumentsNode : public ParserArenaDeletable {
513 public:
514 ArgumentsNode(JSGlobalData*);
515 ArgumentsNode(JSGlobalData*, ArgumentListNode*);
516
517 ArgumentListNode* m_listNode;
518 };
519
520 class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
521 public:
522 NewExprNode(JSGlobalData*, ExpressionNode*);
523 NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*);
524
525 private:
526 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
527
528 ExpressionNode* m_expr;
529 ArgumentsNode* m_args;
530 };
531
532 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
533 public:
534 EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
535
536 private:
537 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
538
539 ArgumentsNode* m_args;
540 };
541
542 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
543 public:
544 FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
545
546 private:
547 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
548
549 ExpressionNode* m_expr;
550 ArgumentsNode* m_args;
551 };
552
553 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
554 public:
555 FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
556
557 private:
558 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
559
560 Identifier m_ident;
561 ArgumentsNode* m_args;
562 size_t m_index; // Used by LocalVarFunctionCallNode.
563 size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
564 };
565
566 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
567 public:
568 FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
569
570 private:
571 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
572
573 ExpressionNode* m_base;
574 ExpressionNode* m_subscript;
575 ArgumentsNode* m_args;
576 };
577
578 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
579 public:
580 FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
581
582 private:
583 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
584
585 protected:
586 ExpressionNode* m_base;
587 const Identifier m_ident;
588 ArgumentsNode* m_args;
589 };
590
591 class CallFunctionCallDotNode : public FunctionCallDotNode {
592 public:
593 CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
594
595 private:
596 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
597 };
598
599 class ApplyFunctionCallDotNode : public FunctionCallDotNode {
600 public:
601 ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
602
603 private:
604 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
605 };
606
607 class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
608 public:
609 PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
610
611 protected:
612 const Identifier m_ident;
613 };
614
615 class PostfixResolveNode : public PrePostResolveNode {
616 public:
617 PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
618
619 private:
620 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
621
622 Operator m_operator;
623 };
624
625 class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
626 public:
627 PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
628
629 private:
630 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
631
632 ExpressionNode* m_base;
633 ExpressionNode* m_subscript;
634 Operator m_operator;
635 };
636
637 class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
638 public:
639 PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
640
641 private:
642 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
643
644 ExpressionNode* m_base;
645 Identifier m_ident;
646 Operator m_operator;
647 };
648
649 class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
650 public:
651 PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
652
653 private:
654 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
655
656 ExpressionNode* m_expr;
657 Operator m_operator;
658 };
659
660 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
661 public:
662 DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
663
664 private:
665 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
666
667 Identifier m_ident;
668 };
669
670 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
671 public:
672 DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
673
674 private:
675 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
676
677 ExpressionNode* m_base;
678 ExpressionNode* m_subscript;
679 };
680
681 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
682 public:
683 DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
684
685 private:
686 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
687
688 ExpressionNode* m_base;
689 Identifier m_ident;
690 };
691
692 class DeleteValueNode : public ExpressionNode {
693 public:
694 DeleteValueNode(JSGlobalData*, ExpressionNode*);
695
696 private:
697 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
698
699 ExpressionNode* m_expr;
700 };
701
702 class VoidNode : public ExpressionNode {
703 public:
704 VoidNode(JSGlobalData*, ExpressionNode*);
705
706 private:
707 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
708
709 ExpressionNode* m_expr;
710 };
711
712 class TypeOfResolveNode : public ExpressionNode {
713 public:
714 TypeOfResolveNode(JSGlobalData*, const Identifier&);
715
716 const Identifier& identifier() const { return m_ident; }
717
718 private:
719 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
720
721 Identifier m_ident;
722 };
723
724 class TypeOfValueNode : public ExpressionNode {
725 public:
726 TypeOfValueNode(JSGlobalData*, ExpressionNode*);
727
728 private:
729 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
730
731 ExpressionNode* m_expr;
732 };
733
734 class PrefixResolveNode : public PrePostResolveNode {
735 public:
736 PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
737
738 private:
739 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
740
741 Operator m_operator;
742 };
743
744 class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
745 public:
746 PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
747
748 private:
749 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
750
751 ExpressionNode* m_base;
752 ExpressionNode* m_subscript;
753 Operator m_operator;
754 };
755
756 class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
757 public:
758 PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
759
760 private:
761 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
762
763 ExpressionNode* m_base;
764 Identifier m_ident;
765 Operator m_operator;
766 };
767
768 class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
769 public:
770 PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
771
772 private:
773 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
774
775 ExpressionNode* m_expr;
776 Operator m_operator;
777 };
778
779 class UnaryOpNode : public ExpressionNode {
780 public:
781 UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID);
782
783 protected:
784 ExpressionNode* expr() { return m_expr; }
785
786 private:
787 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
788
789 OpcodeID opcodeID() const { return m_opcodeID; }
790
791 ExpressionNode* m_expr;
792 OpcodeID m_opcodeID;
793 };
794
795 class UnaryPlusNode : public UnaryOpNode {
796 public:
797 UnaryPlusNode(JSGlobalData*, ExpressionNode*);
798
799 private:
800 virtual ExpressionNode* stripUnaryPlus() { return expr(); }
801 };
802
803 class NegateNode : public UnaryOpNode {
804 public:
805 NegateNode(JSGlobalData*, ExpressionNode*);
806 };
807
808 class BitwiseNotNode : public UnaryOpNode {
809 public:
810 BitwiseNotNode(JSGlobalData*, ExpressionNode*);
811 };
812
813 class LogicalNotNode : public UnaryOpNode {
814 public:
815 LogicalNotNode(JSGlobalData*, ExpressionNode*);
816 };
817
818 class BinaryOpNode : public ExpressionNode {
819 public:
820 BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
821 BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
822
823 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
824
825 private:
826 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
827
828 protected:
829 OpcodeID opcodeID() const { return m_opcodeID; }
830
831 protected:
832 ExpressionNode* m_expr1;
833 ExpressionNode* m_expr2;
834 private:
835 OpcodeID m_opcodeID;
836 protected:
837 bool m_rightHasAssignments;
838 };
839
840 class ReverseBinaryOpNode : public BinaryOpNode {
841 public:
842 ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
843 ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
844
845 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
846 };
847
848 class MultNode : public BinaryOpNode {
849 public:
850 MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
851 };
852
853 class DivNode : public BinaryOpNode {
854 public:
855 DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
856 };
857
858 class ModNode : public BinaryOpNode {
859 public:
860 ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
861 };
862
863 class AddNode : public BinaryOpNode {
864 public:
865 AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
866
867 virtual bool isAdd() const { return true; }
868 };
869
870 class SubNode : public BinaryOpNode {
871 public:
872 SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
873 };
874
875 class LeftShiftNode : public BinaryOpNode {
876 public:
877 LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
878 };
879
880 class RightShiftNode : public BinaryOpNode {
881 public:
882 RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
883 };
884
885 class UnsignedRightShiftNode : public BinaryOpNode {
886 public:
887 UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
888 };
889
890 class LessNode : public BinaryOpNode {
891 public:
892 LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
893 };
894
895 class GreaterNode : public ReverseBinaryOpNode {
896 public:
897 GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
898 };
899
900 class LessEqNode : public BinaryOpNode {
901 public:
902 LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
903 };
904
905 class GreaterEqNode : public ReverseBinaryOpNode {
906 public:
907 GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
908 };
909
910 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
911 public:
912 ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
913 ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
914
915 private:
916 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
917 };
918
919 class InstanceOfNode : public ThrowableBinaryOpNode {
920 public:
921 InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
922
923 private:
924 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
925 };
926
927 class InNode : public ThrowableBinaryOpNode {
928 public:
929 InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
930 };
931
932 class EqualNode : public BinaryOpNode {
933 public:
934 EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
935
936 private:
937 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
938 };
939
940 class NotEqualNode : public BinaryOpNode {
941 public:
942 NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
943 };
944
945 class StrictEqualNode : public BinaryOpNode {
946 public:
947 StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
948
949 private:
950 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
951 };
952
953 class NotStrictEqualNode : public BinaryOpNode {
954 public:
955 NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
956 };
957
958 class BitAndNode : public BinaryOpNode {
959 public:
960 BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
961 };
962
963 class BitOrNode : public BinaryOpNode {
964 public:
965 BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
966 };
967
968 class BitXOrNode : public BinaryOpNode {
969 public:
970 BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
971 };
972
973 // m_expr1 && m_expr2, m_expr1 || m_expr2
974 class LogicalOpNode : public ExpressionNode {
975 public:
976 LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
977
978 private:
979 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
980
981 ExpressionNode* m_expr1;
982 ExpressionNode* m_expr2;
983 LogicalOperator m_operator;
984 };
985
986 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
987 class ConditionalNode : public ExpressionNode {
988 public:
989 ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
990
991 private:
992 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
993
994 ExpressionNode* m_logical;
995 ExpressionNode* m_expr1;
996 ExpressionNode* m_expr2;
997 };
998
999 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
1000 public:
1001 ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1002
1003 private:
1004 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1005
1006 Identifier m_ident;
1007 ExpressionNode* m_right;
1008 size_t m_index; // Used by ReadModifyLocalVarNode.
1009 Operator m_operator;
1010 bool m_rightHasAssignments;
1011 };
1012
1013 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
1014 public:
1015 AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
1016
1017 private:
1018 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1019
1020 Identifier m_ident;
1021 ExpressionNode* m_right;
1022 size_t m_index; // Used by ReadModifyLocalVarNode.
1023 bool m_rightHasAssignments;
1024 };
1025
1026 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1027 public:
1028 ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1029
1030 private:
1031 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1032
1033 ExpressionNode* m_base;
1034 ExpressionNode* m_subscript;
1035 ExpressionNode* m_right;
1036 Operator m_operator : 30;
1037 bool m_subscriptHasAssignments : 1;
1038 bool m_rightHasAssignments : 1;
1039 };
1040
1041 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1042 public:
1043 AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1044
1045 private:
1046 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1047
1048 ExpressionNode* m_base;
1049 ExpressionNode* m_subscript;
1050 ExpressionNode* m_right;
1051 bool m_subscriptHasAssignments : 1;
1052 bool m_rightHasAssignments : 1;
1053 };
1054
1055 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1056 public:
1057 AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1058
1059 private:
1060 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1061
1062 ExpressionNode* m_base;
1063 Identifier m_ident;
1064 ExpressionNode* m_right;
1065 bool m_rightHasAssignments;
1066 };
1067
1068 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1069 public:
1070 ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1071
1072 private:
1073 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1074
1075 ExpressionNode* m_base;
1076 Identifier m_ident;
1077 ExpressionNode* m_right;
1078 Operator m_operator : 31;
1079 bool m_rightHasAssignments : 1;
1080 };
1081
1082 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1083 public:
1084 AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
1085
1086 private:
1087 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1088
1089 ExpressionNode* m_left;
1090 Operator m_operator;
1091 ExpressionNode* m_right;
1092 };
1093
1094 typedef Vector<ExpressionNode*, 8> ExpressionVector;
1095
1096 class CommaNode : public ExpressionNode {
1097 public:
1098 CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
1099
1100 void append(ExpressionNode* expr) { m_expressions.append(expr); }
1101
1102 private:
1103 virtual bool isCommaNode() const { return true; }
1104 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1105
1106 ExpressionVector m_expressions;
1107 };
1108
1109 class ConstDeclNode : public ExpressionNode {
1110 public:
1111 ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*);
1112
1113 bool hasInitializer() const { return m_init; }
1114 const Identifier& ident() { return m_ident; }
1115
1116 private:
1117 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1118 virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
1119
1120 Identifier m_ident;
1121
1122 public:
1123 ConstDeclNode* m_next;
1124
1125 private:
1126 ExpressionNode* m_init;
1127 };
1128
1129 class ConstStatementNode : public StatementNode {
1130 public:
1131 ConstStatementNode(JSGlobalData*, ConstDeclNode* next);
1132
1133 private:
1134 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1135
1136 ConstDeclNode* m_next;
1137 };
1138
1139 typedef Vector<StatementNode*> StatementVector;
1140
1141 class SourceElements : public ParserArenaDeletable {
1142 public:
1143 SourceElements(JSGlobalData*);
1144
1145 void append(StatementNode*);
1146 void releaseContentsIntoVector(StatementVector& destination)
1147 {
1148 ASSERT(destination.isEmpty());
1149 m_statements.swap(destination);
1150 destination.shrinkToFit();
1151 }
1152
1153 private:
1154 StatementVector m_statements;
1155 };
1156
1157 class BlockNode : public StatementNode {
1158 public:
1159 BlockNode(JSGlobalData*, SourceElements* children);
1160
1161 StatementVector& children() { return m_children; }
1162
1163 private:
1164 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1165
1166 virtual bool isBlock() const { return true; }
1167
1168 StatementVector m_children;
1169 };
1170
1171 class EmptyStatementNode : public StatementNode {
1172 public:
1173 EmptyStatementNode(JSGlobalData*);
1174
1175 private:
1176 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1177
1178 virtual bool isEmptyStatement() const { return true; }
1179 };
1180
1181 class DebuggerStatementNode : public StatementNode {
1182 public:
1183 DebuggerStatementNode(JSGlobalData*);
1184
1185 private:
1186 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1187 };
1188
1189 class ExprStatementNode : public StatementNode {
1190 public:
1191 ExprStatementNode(JSGlobalData*, ExpressionNode*);
1192
1193 ExpressionNode* expr() const { return m_expr; }
1194
1195 private:
1196 virtual bool isExprStatement() const { return true; }
1197
1198 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1199
1200 ExpressionNode* m_expr;
1201 };
1202
1203 class VarStatementNode : public StatementNode {
1204 public:
1205 VarStatementNode(JSGlobalData*, ExpressionNode*);
1206
1207 private:
1208 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1209
1210 ExpressionNode* m_expr;
1211 };
1212
1213 class IfNode : public StatementNode {
1214 public:
1215 IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock);
1216
1217 protected:
1218 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1219
1220 ExpressionNode* m_condition;
1221 StatementNode* m_ifBlock;
1222 };
1223
1224 class IfElseNode : public IfNode {
1225 public:
1226 IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1227
1228 private:
1229 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1230
1231 StatementNode* m_elseBlock;
1232 };
1233
1234 class DoWhileNode : public StatementNode {
1235 public:
1236 DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*);
1237
1238 private:
1239 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1240
1241 StatementNode* m_statement;
1242 ExpressionNode* m_expr;
1243 };
1244
1245 class WhileNode : public StatementNode {
1246 public:
1247 WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement);
1248
1249 private:
1250 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1251
1252 ExpressionNode* m_expr;
1253 StatementNode* m_statement;
1254 };
1255
1256 class ForNode : public StatementNode {
1257 public:
1258 ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl);
1259
1260 private:
1261 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1262
1263 ExpressionNode* m_expr1;
1264 ExpressionNode* m_expr2;
1265 ExpressionNode* m_expr3;
1266 StatementNode* m_statement;
1267 bool m_expr1WasVarDecl;
1268 };
1269
1270 class ForInNode : public StatementNode, public ThrowableExpressionData {
1271 public:
1272 ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*);
1273 ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
1274
1275 private:
1276 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1277
1278 Identifier m_ident;
1279 ExpressionNode* m_init;
1280 ExpressionNode* m_lexpr;
1281 ExpressionNode* m_expr;
1282 StatementNode* m_statement;
1283 bool m_identIsVarDecl;
1284 };
1285
1286 class ContinueNode : public StatementNode, public ThrowableExpressionData {
1287 public:
1288 ContinueNode(JSGlobalData*);
1289 ContinueNode(JSGlobalData*, const Identifier&);
1290
1291 private:
1292 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1293
1294 Identifier m_ident;
1295 };
1296
1297 class BreakNode : public StatementNode, public ThrowableExpressionData {
1298 public:
1299 BreakNode(JSGlobalData*);
1300 BreakNode(JSGlobalData*, const Identifier&);
1301
1302 private:
1303 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1304
1305 Identifier m_ident;
1306 };
1307
1308 class ReturnNode : public StatementNode, public ThrowableExpressionData {
1309 public:
1310 ReturnNode(JSGlobalData*, ExpressionNode* value);
1311
1312 private:
1313 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1314
1315 virtual bool isReturnNode() const { return true; }
1316
1317 ExpressionNode* m_value;
1318 };
1319
1320 class WithNode : public StatementNode {
1321 public:
1322 WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
1323
1324 private:
1325 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1326
1327 ExpressionNode* m_expr;
1328 StatementNode* m_statement;
1329 uint32_t m_divot;
1330 uint32_t m_expressionLength;
1331 };
1332
1333 class LabelNode : public StatementNode, public ThrowableExpressionData {
1334 public:
1335 LabelNode(JSGlobalData*, const Identifier& name, StatementNode*);
1336
1337 private:
1338 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1339
1340 Identifier m_name;
1341 StatementNode* m_statement;
1342 };
1343
1344 class ThrowNode : public StatementNode, public ThrowableExpressionData {
1345 public:
1346 ThrowNode(JSGlobalData*, ExpressionNode*);
1347
1348 private:
1349 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1350
1351 ExpressionNode* m_expr;
1352 };
1353
1354 class TryNode : public StatementNode {
1355 public:
1356 TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
1357
1358 private:
1359 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0);
1360
1361 StatementNode* m_tryBlock;
1362 Identifier m_exceptionIdent;
1363 StatementNode* m_catchBlock;
1364 StatementNode* m_finallyBlock;
1365 bool m_catchHasEval;
1366 };
1367
1368 class ParameterNode : public ParserArenaDeletable {
1369 public:
1370 ParameterNode(JSGlobalData*, const Identifier&);
1371 ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
1372
1373 const Identifier& ident() const { return m_ident; }
1374 ParameterNode* nextParam() const { return m_next; }
1375
1376 private:
1377 Identifier m_ident;
1378 ParameterNode* m_next;
1379 };
1380
1381 struct ScopeNodeData : FastAllocBase {
1382 typedef DeclarationStacks::VarStack VarStack;
1383 typedef DeclarationStacks::FunctionStack FunctionStack;
1384
1385 ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);
1386
1387 ParserArena m_arena;
1388 VarStack m_varStack;
1389 FunctionStack m_functionStack;
1390 int m_numConstants;
1391 StatementVector m_children;
1392
1393 void markAggregate(MarkStack&);
1394 };
1395
1396 class ScopeNode : public StatementNode, public ParserArenaRefCounted {
1397 public:
1398 typedef DeclarationStacks::VarStack VarStack;
1399 typedef DeclarationStacks::FunctionStack FunctionStack;
1400
1401 ScopeNode(JSGlobalData*);
1402 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants);
1403
1404 void adoptData(std::auto_ptr<ScopeNodeData> data)
1405 {
1406 ASSERT(!data->m_arena.contains(this));
1407 ASSERT(!m_data);
1408 m_data.adopt(data);
1409 }
1410 ScopeNodeData* data() const { return m_data.get(); }
1411 void destroyData() { m_data.clear(); }
1412
1413 const SourceCode& source() const { return m_source; }
1414 const UString& sourceURL() const { return m_source.provider()->url(); }
1415 intptr_t sourceID() const { return m_source.provider()->asID(); }
1416
1417 void setFeatures(CodeFeatures features) { m_features = features; }
1418 CodeFeatures features() { return m_features; }
1419
1420 bool usesEval() const { return m_features & EvalFeature; }
1421 bool usesArguments() const { return m_features & ArgumentsFeature; }
1422 void setUsesArguments() { m_features |= ArgumentsFeature; }
1423 bool usesThis() const { return m_features & ThisFeature; }
1424 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
1425
1426 VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
1427 FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
1428
1429 StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
1430
1431 int neededConstants()
1432 {
1433 ASSERT(m_data);
1434 // We may need 2 more constants than the count given by the parser,
1435 // because of the various uses of jsUndefined() and jsNull().
1436 return m_data->m_numConstants + 2;
1437 }
1438
1439 virtual void markAggregate(MarkStack&) { }
1440
1441#if ENABLE(JIT)
1442 JITCode& generatedJITCode()
1443 {
1444 ASSERT(m_jitCode);
1445 return m_jitCode;
1446 }
1447
1448 ExecutablePool* getExecutablePool()
1449 {
1450 return m_jitCode.getExecutablePool();
1451 }
1452
1453 void setJITCode(const JITCode jitCode)
1454 {
1455 m_jitCode = jitCode;
1456 }
1457#endif
1458
1459 protected:
1460 void setSource(const SourceCode& source) { m_source = source; }
1461
1462#if ENABLE(JIT)
1463 JITCode m_jitCode;
1464#endif
1465
1466 private:
1467 OwnPtr<ScopeNodeData> m_data;
1468 CodeFeatures m_features;
1469 SourceCode m_source;
1470 };
1471
1472 class ProgramNode : public ScopeNode {
1473 public:
1474 static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1475
1476 ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain)
1477 {
1478 if (!m_code)
1479 generateBytecode(scopeChain);
1480 return *m_code;
1481 }
1482
1483#if ENABLE(JIT)
1484 JITCode& jitCode(ScopeChainNode* scopeChain)
1485 {
1486 if (!m_jitCode)
1487 generateJITCode(scopeChain);
1488 return m_jitCode;
1489 }
1490#endif
1491
1492 private:
1493 ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1494
1495 void generateBytecode(ScopeChainNode*);
1496 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1497
1498#if ENABLE(JIT)
1499 void generateJITCode(ScopeChainNode*);
1500#endif
1501
1502 OwnPtr<ProgramCodeBlock> m_code;
1503 };
1504
1505 class EvalNode : public ScopeNode {
1506 public:
1507 static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1508
1509 EvalCodeBlock& bytecode(ScopeChainNode* scopeChain)
1510 {
1511 if (!m_code)
1512 generateBytecode(scopeChain);
1513 return *m_code;
1514 }
1515
1516 EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
1517
1518 virtual void markAggregate(MarkStack&);
1519
1520#if ENABLE(JIT)
1521 JITCode& jitCode(ScopeChainNode* scopeChain)
1522 {
1523 if (!m_jitCode)
1524 generateJITCode(scopeChain);
1525 return m_jitCode;
1526 }
1527#endif
1528
1529 private:
1530 EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1531
1532 void generateBytecode(ScopeChainNode*);
1533 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1534
1535#if ENABLE(JIT)
1536 void generateJITCode(ScopeChainNode*);
1537#endif
1538
1539 OwnPtr<EvalCodeBlock> m_code;
1540 };
1541
1542 class FunctionBodyNode : public ScopeNode {
1543 friend class JIT;
1544 public:
1545#if ENABLE(JIT)
1546 static PassRefPtr<FunctionBodyNode> createNativeThunk(JSGlobalData*);
1547#endif
1548 static FunctionBodyNode* create(JSGlobalData*);
1549 static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1550 virtual ~FunctionBodyNode();
1551
1552 const Identifier* parameters() const { return m_parameters; }
1553 size_t parameterCount() const { return m_parameterCount; }
1554 UString paramString() const ;
1555 Identifier* copyParameters();
1556
1557 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1558
1559 bool isGenerated() const
1560 {
1561 return m_code;
1562 }
1563
1564 bool isHostFunction() const;
1565
1566 virtual void markAggregate(MarkStack&);
1567
1568 void finishParsing(const SourceCode&, ParameterNode*);
1569 void finishParsing(Identifier* parameters, size_t parameterCount);
1570
1571 UString toSourceString() const { return source().toString(); }
1572
1573 CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
1574#if ENABLE(JIT)
1575 JITCode& jitCode(ScopeChainNode* scopeChain)
1576 {
1577 if (!m_jitCode)
1578 generateJITCode(scopeChain);
1579 return m_jitCode;
1580 }
1581#endif
1582
1583 CodeBlock& bytecode(ScopeChainNode* scopeChain)
1584 {
1585 ASSERT(scopeChain);
1586 if (!m_code)
1587 generateBytecode(scopeChain);
1588 return *m_code;
1589 }
1590
1591 CodeBlock& generatedBytecode()
1592 {
1593 ASSERT(m_code);
1594 return *m_code;
1595 }
1596
1597 private:
1598 FunctionBodyNode(JSGlobalData*);
1599 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1600
1601 void generateBytecode(ScopeChainNode*);
1602#if ENABLE(JIT)
1603 void generateJITCode(ScopeChainNode*);
1604#endif
1605 Identifier* m_parameters;
1606 size_t m_parameterCount;
1607 OwnPtr<CodeBlock> m_code;
1608 };
1609
1610 class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted {
1611 public:
1612 FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
1613
1614 JSFunction* makeFunction(ExecState*, ScopeChainNode*);
1615
1616 FunctionBodyNode* body() { return m_body.get(); }
1617
1618 private:
1619 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1620
1621 virtual bool isFuncExprNode() const { return true; }
1622
1623 Identifier m_ident;
1624 RefPtr<FunctionBodyNode> m_body;
1625 };
1626
1627 class FuncDeclNode : public StatementNode, public ParserArenaRefCounted {
1628 public:
1629 FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1630
1631 JSFunction* makeFunction(ExecState*, ScopeChainNode*);
1632
1633 Identifier m_ident;
1634
1635 FunctionBodyNode* body() { return m_body.get(); }
1636
1637 private:
1638 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1639
1640 RefPtr<FunctionBodyNode> m_body;
1641 };
1642
1643 class CaseClauseNode : public ParserArenaDeletable {
1644 public:
1645 CaseClauseNode(JSGlobalData*, ExpressionNode*);
1646 CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements*);
1647
1648 ExpressionNode* expr() const { return m_expr; }
1649 StatementVector& children() { return m_children; }
1650
1651 private:
1652 ExpressionNode* m_expr;
1653 StatementVector m_children;
1654 };
1655
1656 class ClauseListNode : public ParserArenaDeletable {
1657 public:
1658 ClauseListNode(JSGlobalData*, CaseClauseNode*);
1659 ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
1660
1661 CaseClauseNode* getClause() const { return m_clause; }
1662 ClauseListNode* getNext() const { return m_next; }
1663
1664 private:
1665 CaseClauseNode* m_clause;
1666 ClauseListNode* m_next;
1667 };
1668
1669 class CaseBlockNode : public ParserArenaDeletable {
1670 public:
1671 CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1672
1673 RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0);
1674
1675 private:
1676 SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
1677 ClauseListNode* m_list1;
1678 CaseClauseNode* m_defaultClause;
1679 ClauseListNode* m_list2;
1680 };
1681
1682 class SwitchNode : public StatementNode {
1683 public:
1684 SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*);
1685
1686 private:
1687 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1688
1689 ExpressionNode* m_expr;
1690 CaseBlockNode* m_block;
1691 };
1692
1693 struct ElementList {
1694 ElementNode* head;
1695 ElementNode* tail;
1696 };
1697
1698 struct PropertyList {
1699 PropertyListNode* head;
1700 PropertyListNode* tail;
1701 };
1702
1703 struct ArgumentList {
1704 ArgumentListNode* head;
1705 ArgumentListNode* tail;
1706 };
1707
1708 struct ConstDeclList {
1709 ConstDeclNode* head;
1710 ConstDeclNode* tail;
1711 };
1712
1713 struct ParameterList {
1714 ParameterNode* head;
1715 ParameterNode* tail;
1716 };
1717
1718 struct ClauseList {
1719 ClauseListNode* head;
1720 ClauseListNode* tail;
1721 };
1722
1723} // namespace JSC
1724
1725#endif // Nodes_h
Note: See TracBrowser for help on using the repository browser.