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

Last change on this file since 67494 was 63244, checked in by [email protected], 15 years ago

Bug 42182 - Change how numeric compare functions are detected

Reviewed by Oliver Hunt.

JavaScriptCore:

There are three problems with the current mechanism:

  • It requires that a function executable be bytecode compiled without being JIT generated (in order to copy the bytecode from the numeric compare function). This is a problem since we have an invariant when running with the JIT that functions are never bytecode compiled without also being JIT generated (after checking the codeblock we assume the function has JIT code). To help maintain this invariant
  • This implementation will prevent us from experimenting with alternate compilation paths which do not compile via bytecode.
  • It doesn't work. Functions passing more than two arguments will match if they are comparing their last two arguments, not the first two. Generally the mapping back from bytecode to semantics may be more complex then initially expected.
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::setIsNumericCompareFunction):
(JSC::BytecodeGenerator::argumentNumberFor):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::BlockNode::singleStatement):
(JSC::FunctionBodyNode::emitBytecode):

  • parser/Nodes.h:

(JSC::ExpressionNode::isSubtract):
(JSC::BinaryOpNode::lhs):
(JSC::BinaryOpNode::rhs):
(JSC::SubNode::isSubtract):
(JSC::ReturnNode::value):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):

  • runtime/JSGlobalData.h:

LayoutTests:

Test case.

  • fast/js/array-sort-numericCompare-expected.txt: Added.
  • fast/js/array-sort-numericCompare.html: Added.
  • fast/js/script-tests/array-sort-numericCompare.js: Added.

(doSort):
(dontSort):

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