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

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

How many copies of the parameters do you need?
https://bugs.webkit.org/show_bug.cgi?id=28701

Reviewed by Darin Adler.

The function parameters in JSC get copied a lot - and unnecessarily so.

Originally this happened due to duplicating FunctionBodyNodes on recompilation,
though the problem has been exacerbated by copying the parameters from the
original function body onto the executable, then back onto the real body that
will be generated (this happens on every function). And this is all made worse
since the data structures in question are a little ugly - C style arrays of C++
objects containing ref counts, so they need a full copy-construct (rather than
a simple memcpy).

This can all be greatly simplified by just punting the parameters off into
their own ref-counted object, and forgoing all the copying.

~no performance change, possible slight progression.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::makeFunction):

  • parser/Nodes.cpp:

(JSC::FunctionParameters::FunctionParameters):
(JSC::FunctionBodyNode::FunctionBodyNode):
(JSC::FunctionBodyNode::finishParsing):

  • parser/Nodes.h:

(JSC::FunctionBodyNode::parameters):
(JSC::FunctionBodyNode::parameterCount):

  • runtime/Executable.cpp:

(JSC::FunctionExecutable::~FunctionExecutable):
(JSC::FunctionExecutable::compile):
(JSC::FunctionExecutable::reparseExceptionInfo):
(JSC::FunctionExecutable::fromGlobalCode):
(JSC::FunctionExecutable::paramString):

  • runtime/Executable.h:

(JSC::FunctionExecutable::FunctionExecutable):
(JSC::FunctionExecutable::parameterCount):

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