source: webkit/trunk/JavaScriptCore/kjs/nodes.h@ 38061

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

2008-10-31 Cameron Zwarich <[email protected]>

Rubber-stamped by Geoff Garen.

Rename SourceRange.h to SourceCode.h.

JavaScriptCore:

  • API/JSBase.cpp:
  • GNUmakefile.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • VM/CodeBlock.h:
  • kjs/SourceCode.h: Copied from kjs/SourceRange.h.
  • kjs/SourceRange.h: Removed.
  • kjs/grammar.y:
  • kjs/lexer.h:
  • kjs/nodes.cpp: (JSC::ForInNode::ForInNode):
  • kjs/nodes.h: (JSC::ThrowableExpressionData::setExceptionSourceCode):

WebCore:

  • ForwardingHeaders/kjs/SourceCode.h: Copied from ForwardingHeaders/kjs/SourceRange.h.
  • ForwardingHeaders/kjs/SourceRange.h: Removed.
  • bindings/js/StringSourceProvider.h:
  • bridge/NP_jsobject.cpp:
  • Property svn:eol-style set to native
File size: 89.3 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 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 "JSString.h"
31#include "JSType.h"
32#include "Opcode.h"
33#include "RegisterID.h"
34#include "ResultType.h"
35#include "SourceCode.h"
36#include "SymbolTable.h"
37#include "regexp.h"
38#include <wtf/ListRefPtr.h>
39#include <wtf/MathExtras.h>
40#include <wtf/OwnPtr.h>
41#include <wtf/UnusedParam.h>
42#include <wtf/Vector.h>
43
44#if PLATFORM(X86) && COMPILER(GCC)
45#define JSC_FAST_CALL __attribute__((regparm(3)))
46#else
47#define JSC_FAST_CALL
48#endif
49
50namespace JSC {
51
52 class CodeBlock;
53 class CodeGenerator;
54 class FuncDeclNode;
55 class Node;
56 class EvalCodeBlock;
57 class JSFunction;
58 class ProgramCodeBlock;
59 class PropertyListNode;
60 class SourceStream;
61
62 typedef unsigned int CodeFeatures;
63
64 const CodeFeatures NoFeatures = 0;
65 const CodeFeatures EvalFeature = 1 << 0;
66 const CodeFeatures ClosureFeature = 1 << 1;
67 const CodeFeatures AssignFeature = 1 << 2;
68 const CodeFeatures ArgumentsFeature = 1 << 3;
69 const CodeFeatures WithFeature = 1 << 4;
70 const CodeFeatures CatchFeature = 1 << 5;
71 const CodeFeatures ThisFeature = 1 << 6;
72 const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature;
73
74 enum Operator {
75 OpEqual,
76 OpPlusEq,
77 OpMinusEq,
78 OpMultEq,
79 OpDivEq,
80 OpPlusPlus,
81 OpMinusMinus,
82 OpAndEq,
83 OpXOrEq,
84 OpOrEq,
85 OpModEq,
86 OpLShift,
87 OpRShift,
88 OpURShift
89 };
90
91 enum LogicalOperator {
92 OpLogicalAnd,
93 OpLogicalOr
94 };
95
96 enum Precedence {
97 PrecPrimary,
98 PrecMember,
99 PrecCall,
100 PrecLeftHandSide,
101 PrecPostfix,
102 PrecUnary,
103 PrecMultiplicative,
104 PrecAdditive,
105 PrecShift,
106 PrecRelational,
107 PrecEquality,
108 PrecBitwiseAnd,
109 PrecBitwiseXor,
110 PrecBitwiseOr,
111 PrecLogicalAnd,
112 PrecLogicalOr,
113 PrecConditional,
114 PrecAssignment,
115 PrecExpression
116 };
117
118 namespace DeclarationStacks {
119 typedef Vector<Node*, 16> NodeStack;
120 enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
121 typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
122 typedef Vector<RefPtr<FuncDeclNode>, 16> FunctionStack;
123 }
124
125 struct SwitchInfo {
126 enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
127 uint32_t opcodeOffset;
128 SwitchType switchType;
129 };
130
131 class ParserRefCounted : Noncopyable {
132 protected:
133 ParserRefCounted(JSGlobalData*) JSC_FAST_CALL;
134
135 JSGlobalData* m_globalData;
136
137 public:
138 void ref() JSC_FAST_CALL;
139 void deref() JSC_FAST_CALL;
140 bool hasOneRef() JSC_FAST_CALL;
141
142 static void deleteNewObjects(JSGlobalData*) JSC_FAST_CALL;
143
144 virtual ~ParserRefCounted();
145 };
146
147 class Node : public ParserRefCounted {
148 public:
149 typedef DeclarationStacks::NodeStack NodeStack;
150 typedef DeclarationStacks::VarStack VarStack;
151 typedef DeclarationStacks::FunctionStack FunctionStack;
152
153 Node(JSGlobalData*) JSC_FAST_CALL;
154
155 /*
156 Return value: The register holding the production's value.
157 dst: An optional parameter specifying the most efficient
158 destination at which to store the production's value.
159 The callee must honor dst.
160
161 dst provides for a crude form of copy propagation. For example,
162
163 x = 1
164
165 becomes
166
167 load r[x], 1
168
169 instead of
170
171 load r0, 1
172 mov r[x], r0
173
174 because the assignment node, "x =", passes r[x] as dst to the number
175 node, "1".
176 */
177 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL
178 {
179 ASSERT_WITH_MESSAGE(0, "Don't know how to generate code for:\n%s\n", toString().ascii());
180 UNUSED_PARAM(dst);
181 return 0;
182 } // FIXME: Make this pure virtual.
183
184 UString toString() const JSC_FAST_CALL;
185 int lineNo() const { return m_line; }
186
187 virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
188
189 // Serialization.
190 virtual void streamTo(SourceStream&) const JSC_FAST_CALL = 0;
191 virtual Precedence precedence() const = 0;
192 virtual bool needsParensIfLeftmost() const { return false; }
193
194 protected:
195 int m_line;
196 };
197
198 class ExpressionNode : public Node {
199 public:
200 ExpressionNode(JSGlobalData* globalData, ResultType resultDesc = ResultType::unknown()) JSC_FAST_CALL
201 : Node(globalData)
202 , m_resultDesc(resultDesc)
203 {
204 }
205
206 virtual bool isNumber() const JSC_FAST_CALL { return false; }
207 virtual bool isString() const JSC_FAST_CALL { return false; }
208 virtual bool isNull() const JSC_FAST_CALL { return false; }
209 virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return false; }
210 virtual bool isLocation() const JSC_FAST_CALL { return false; }
211 virtual bool isResolveNode() const JSC_FAST_CALL { return false; }
212 virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; }
213 virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
214
215 virtual ExpressionNode* stripUnaryPlus() { return this; }
216
217 ResultType resultDescriptor() const JSC_FAST_CALL { return m_resultDesc; }
218
219 // This needs to be in public in order to compile using GCC 3.x
220 typedef enum { EvalOperator, FunctionCall } CallerType;
221
222 private:
223 ResultType m_resultDesc;
224 };
225
226 class StatementNode : public Node {
227 public:
228 StatementNode(JSGlobalData*) JSC_FAST_CALL;
229 void setLoc(int line0, int line1) JSC_FAST_CALL;
230 int firstLine() const JSC_FAST_CALL { return lineNo(); }
231 int lastLine() const JSC_FAST_CALL { return m_lastLine; }
232
233 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
234 virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; }
235
236 virtual bool isBlock() const JSC_FAST_CALL { return false; }
237 virtual bool isLoop() const JSC_FAST_CALL { return false; }
238
239 private:
240 int m_lastLine;
241 };
242
243 class NullNode : public ExpressionNode {
244 public:
245 NullNode(JSGlobalData* globalData) JSC_FAST_CALL
246 : ExpressionNode(globalData, ResultType::nullType())
247 {
248 }
249
250 virtual bool isNull() const JSC_FAST_CALL { return true; }
251
252 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
253
254 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
255 virtual Precedence precedence() const { return PrecPrimary; }
256 };
257
258 class BooleanNode : public ExpressionNode {
259 public:
260 BooleanNode(JSGlobalData* globalData, bool value) JSC_FAST_CALL
261 : ExpressionNode(globalData, ResultType::boolean())
262 , m_value(value)
263 {
264 }
265
266 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
267
268 virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return true; }
269 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
270 virtual Precedence precedence() const { return PrecPrimary; }
271
272 protected:
273 bool m_value;
274 };
275
276 class NumberNode : public ExpressionNode {
277 public:
278 NumberNode(JSGlobalData* globalData, double v) JSC_FAST_CALL
279 : ExpressionNode(globalData, ResultType::constNumber())
280 , m_double(v)
281 {
282 }
283
284 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
285
286 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
287 virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
288
289 virtual bool isNumber() const JSC_FAST_CALL { return true; }
290 virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return true; }
291 double value() const JSC_FAST_CALL { return m_double; }
292 virtual void setValue(double d) JSC_FAST_CALL { m_double = d; }
293
294 protected:
295 double m_double;
296 };
297
298 class ImmediateNumberNode : public NumberNode {
299 public:
300 ImmediateNumberNode(JSGlobalData* globalData, JSValue* v, double d) JSC_FAST_CALL
301 : NumberNode(globalData, d)
302 , m_value(v)
303 {
304 ASSERT(v == JSImmediate::from(d));
305 }
306
307 virtual void setValue(double d) JSC_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
308
309 private:
310 JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
311 };
312
313 class StringNode : public ExpressionNode {
314 public:
315 StringNode(JSGlobalData* globalData, const Identifier& v) JSC_FAST_CALL
316 : ExpressionNode(globalData, ResultType::string())
317 , m_value(v)
318 {
319 }
320
321 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
322
323 virtual bool isString() const JSC_FAST_CALL { return true; }
324 const Identifier& value() { return m_value; }
325 virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return true; }
326 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
327 virtual Precedence precedence() const { return PrecPrimary; }
328
329 private:
330 Identifier m_value;
331 };
332
333 class ThrowableExpressionData {
334 public:
335 ThrowableExpressionData()
336 : m_divot(static_cast<uint32_t>(-1))
337 , m_startOffset(static_cast<uint16_t>(-1))
338 , m_endOffset(static_cast<uint16_t>(-1))
339 {
340 }
341
342 ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
343 : m_divot(divot)
344 , m_startOffset(startOffset)
345 , m_endOffset(endOffset)
346 {
347 }
348
349 void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
350 {
351 m_divot = divot;
352 m_startOffset = startOffset;
353 m_endOffset = endOffset;
354 }
355
356 uint32_t divot() const { return m_divot; }
357 uint16_t startOffset() const { return m_startOffset; }
358 uint16_t endOffset() const { return m_endOffset; }
359
360 protected:
361 RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg);
362 RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&);
363 uint32_t m_divot;
364 uint16_t m_startOffset;
365 uint16_t m_endOffset;
366 };
367
368 class ThrowableSubExpressionData : public ThrowableExpressionData {
369 public:
370 ThrowableSubExpressionData()
371 : ThrowableExpressionData()
372 , m_subexpressionDivotOffset(0)
373 , m_subexpressionEndOffset(0)
374 {
375 }
376
377 ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
378 : ThrowableExpressionData(divot, startOffset, endOffset)
379 , m_subexpressionDivotOffset(0)
380 , m_subexpressionEndOffset(0)
381 {
382 }
383
384 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) {
385 ASSERT(subexpressionDivot <= m_divot);
386 if ((m_divot - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
387 return;
388 m_subexpressionDivotOffset = m_divot - subexpressionDivot;
389 m_subexpressionEndOffset = subexpressionOffset;
390 }
391
392 protected:
393 uint16_t m_subexpressionDivotOffset;
394 uint16_t m_subexpressionEndOffset;
395 };
396
397 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
398 public:
399 ThrowablePrefixedSubExpressionData()
400 : ThrowableExpressionData()
401 , m_subexpressionDivotOffset(0)
402 , m_subexpressionStartOffset(0)
403 {
404 }
405
406 ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
407 : ThrowableExpressionData(divot, startOffset, endOffset)
408 , m_subexpressionDivotOffset(0)
409 , m_subexpressionStartOffset(0)
410 {
411 }
412
413 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) {
414 ASSERT(subexpressionDivot >= m_divot);
415 if ((subexpressionDivot - m_divot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
416 return;
417 m_subexpressionDivotOffset = subexpressionDivot - m_divot;
418 m_subexpressionStartOffset = subexpressionOffset;
419 }
420
421 protected:
422 uint16_t m_subexpressionDivotOffset;
423 uint16_t m_subexpressionStartOffset;
424 };
425
426 class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
427 public:
428 RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) JSC_FAST_CALL
429 : ExpressionNode(globalData)
430 , m_pattern(pattern)
431 , m_flags(flags)
432 {
433 }
434
435 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
436
437 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
438 virtual Precedence precedence() const { return PrecPrimary; }
439
440 private:
441 UString m_pattern;
442 UString m_flags;
443 };
444
445 class ThisNode : public ExpressionNode {
446 public:
447 ThisNode(JSGlobalData* globalData) JSC_FAST_CALL
448 : ExpressionNode(globalData)
449 {
450 }
451
452 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
453
454 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
455 virtual Precedence precedence() const { return PrecPrimary; }
456 };
457
458 class ResolveNode : public ExpressionNode {
459 public:
460 ResolveNode(JSGlobalData* globalData, const Identifier& ident, int startOffset) JSC_FAST_CALL
461 : ExpressionNode(globalData)
462 , m_ident(ident)
463 , m_startOffset(startOffset)
464 {
465 }
466
467 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
468
469 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
470 virtual Precedence precedence() const { return PrecPrimary; }
471
472 virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL;
473 virtual bool isLocation() const JSC_FAST_CALL { return true; }
474 virtual bool isResolveNode() const JSC_FAST_CALL { return true; }
475 const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
476
477 protected:
478 Identifier m_ident;
479 int32_t m_startOffset;
480
481 };
482
483 class ElementNode : public Node {
484 public:
485 ElementNode(JSGlobalData* globalData, int elision, ExpressionNode* node) JSC_FAST_CALL
486 : Node(globalData)
487 , m_elision(elision)
488 , m_node(node)
489 {
490 }
491
492 ElementNode(JSGlobalData* globalData, ElementNode* l, int elision, ExpressionNode* node) JSC_FAST_CALL
493 : Node(globalData)
494 , m_elision(elision)
495 , m_node(node)
496 {
497 l->m_next = this;
498 }
499
500 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
501 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
502
503 int elision() const { return m_elision; }
504 ExpressionNode* value() { return m_node.get(); }
505
506 ElementNode* next() { return m_next.get(); }
507 PassRefPtr<ElementNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
508
509 private:
510 ListRefPtr<ElementNode> m_next;
511 int m_elision;
512 RefPtr<ExpressionNode> m_node;
513 };
514
515 class ArrayNode : public ExpressionNode {
516 public:
517 ArrayNode(JSGlobalData* globalData, int elision) JSC_FAST_CALL
518 : ExpressionNode(globalData)
519 , m_elision(elision)
520 , m_optional(true)
521 {
522 }
523
524 ArrayNode(JSGlobalData* globalData, ElementNode* element) JSC_FAST_CALL
525 : ExpressionNode(globalData)
526 , m_element(element)
527 , m_elision(0)
528 , m_optional(false)
529 {
530 }
531
532 ArrayNode(JSGlobalData* globalData, int elision, ElementNode* element) JSC_FAST_CALL
533 : ExpressionNode(globalData)
534 , m_element(element)
535 , m_elision(elision)
536 , m_optional(true)
537 {
538 }
539
540 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
541
542 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
543 virtual Precedence precedence() const { return PrecPrimary; }
544
545 private:
546 RefPtr<ElementNode> m_element;
547 int m_elision;
548 bool m_optional;
549 };
550
551 class PropertyNode : public Node {
552 public:
553 enum Type { Constant, Getter, Setter };
554
555 PropertyNode(JSGlobalData* globalData, const Identifier& name, ExpressionNode* assign, Type type) JSC_FAST_CALL
556 : Node(globalData)
557 , m_name(name)
558 , m_assign(assign)
559 , m_type(type)
560 {
561 }
562
563 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
564 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
565
566 const Identifier& name() const { return m_name; }
567
568 private:
569 friend class PropertyListNode;
570 Identifier m_name;
571 RefPtr<ExpressionNode> m_assign;
572 Type m_type;
573 };
574
575 class PropertyListNode : public Node {
576 public:
577 PropertyListNode(JSGlobalData* globalData, PropertyNode* node) JSC_FAST_CALL
578 : Node(globalData)
579 , m_node(node)
580 {
581 }
582
583 PropertyListNode(JSGlobalData* globalData, PropertyNode* node, PropertyListNode* list) JSC_FAST_CALL
584 : Node(globalData)
585 , m_node(node)
586 {
587 list->m_next = this;
588 }
589
590 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
591 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
592 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
593
594 PassRefPtr<PropertyListNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
595
596 private:
597 friend class ObjectLiteralNode;
598 RefPtr<PropertyNode> m_node;
599 ListRefPtr<PropertyListNode> m_next;
600 };
601
602 class ObjectLiteralNode : public ExpressionNode {
603 public:
604 ObjectLiteralNode(JSGlobalData* globalData) JSC_FAST_CALL
605 : ExpressionNode(globalData)
606 {
607 }
608
609 ObjectLiteralNode(JSGlobalData* globalData, PropertyListNode* list) JSC_FAST_CALL
610 : ExpressionNode(globalData)
611 , m_list(list)
612 {
613 }
614
615 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
616 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
617 virtual Precedence precedence() const { return PrecPrimary; }
618 virtual bool needsParensIfLeftmost() const { return true; }
619
620 private:
621 RefPtr<PropertyListNode> m_list;
622 };
623
624 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
625 public:
626 BracketAccessorNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments) JSC_FAST_CALL
627 : ExpressionNode(globalData)
628 , m_base(base)
629 , m_subscript(subscript)
630 , m_subscriptHasAssignments(subscriptHasAssignments)
631 {
632 }
633
634 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
635
636 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
637 virtual Precedence precedence() const { return PrecMember; }
638
639 virtual bool isLocation() const JSC_FAST_CALL { return true; }
640 virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return true; }
641 ExpressionNode* base() JSC_FAST_CALL { return m_base.get(); }
642 ExpressionNode* subscript() JSC_FAST_CALL { return m_subscript.get(); }
643
644 private:
645 RefPtr<ExpressionNode> m_base;
646 RefPtr<ExpressionNode> m_subscript;
647 bool m_subscriptHasAssignments;
648 };
649
650 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
651 public:
652 DotAccessorNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident) JSC_FAST_CALL
653 : ExpressionNode(globalData)
654 , m_base(base)
655 , m_ident(ident)
656 {
657 }
658
659 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
660 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
661 virtual Precedence precedence() const { return PrecMember; }
662
663 virtual bool isLocation() const JSC_FAST_CALL { return true; }
664 virtual bool isDotAccessorNode() const JSC_FAST_CALL { return true; }
665 ExpressionNode* base() const JSC_FAST_CALL { return m_base.get(); }
666 const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
667
668 private:
669 RefPtr<ExpressionNode> m_base;
670 Identifier m_ident;
671 };
672
673 class ArgumentListNode : public Node {
674 public:
675 ArgumentListNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
676 : Node(globalData)
677 , m_expr(expr)
678 {
679 }
680
681 ArgumentListNode(JSGlobalData* globalData, ArgumentListNode* listNode, ExpressionNode* expr) JSC_FAST_CALL
682 : Node(globalData)
683 , m_expr(expr)
684 {
685 listNode->m_next = this;
686 }
687
688 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
689 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
690 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
691
692 PassRefPtr<ArgumentListNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
693
694 ListRefPtr<ArgumentListNode> m_next;
695 RefPtr<ExpressionNode> m_expr;
696 };
697
698 class ArgumentsNode : public Node {
699 public:
700 ArgumentsNode(JSGlobalData* globalData) JSC_FAST_CALL
701 : Node(globalData)
702 {
703 }
704
705 ArgumentsNode(JSGlobalData* globalData, ArgumentListNode* listNode) JSC_FAST_CALL
706 : Node(globalData)
707 , m_listNode(listNode)
708 {
709 }
710
711 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
712 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
713
714 RefPtr<ArgumentListNode> m_listNode;
715 };
716
717 class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
718 public:
719 NewExprNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
720 : ExpressionNode(globalData)
721 , m_expr(expr)
722 {
723 }
724
725 NewExprNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args) JSC_FAST_CALL
726 : ExpressionNode(globalData)
727 , m_expr(expr)
728 , m_args(args)
729 {
730 }
731
732 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
733
734 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
735 virtual Precedence precedence() const { return PrecLeftHandSide; }
736
737 private:
738 RefPtr<ExpressionNode> m_expr;
739 RefPtr<ArgumentsNode> m_args;
740 };
741
742 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
743 public:
744 EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
745 : ExpressionNode(globalData)
746 , ThrowableExpressionData(divot, startOffset, endOffset)
747 , m_args(args)
748 {
749 }
750
751 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
752 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
753 virtual Precedence precedence() const { return PrecCall; }
754
755 private:
756 RefPtr<ArgumentsNode> m_args;
757 };
758
759 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
760 public:
761 FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
762 : ExpressionNode(globalData)
763 , ThrowableExpressionData(divot, startOffset, endOffset)
764 , m_expr(expr)
765 , m_args(args)
766 {
767 }
768
769 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
770 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
771 virtual Precedence precedence() const { return PrecCall; }
772
773 private:
774 RefPtr<ExpressionNode> m_expr;
775 RefPtr<ArgumentsNode> m_args;
776 };
777
778 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
779 public:
780 FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
781 : ExpressionNode(globalData)
782 , ThrowableExpressionData(divot, startOffset, endOffset)
783 , m_ident(ident)
784 , m_args(args)
785 {
786 }
787
788 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
789
790 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
791 virtual Precedence precedence() const { return PrecCall; }
792
793 protected:
794 Identifier m_ident;
795 RefPtr<ArgumentsNode> m_args;
796 size_t m_index; // Used by LocalVarFunctionCallNode.
797 size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
798 };
799
800 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
801 public:
802 FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
803 : ExpressionNode(globalData)
804 , ThrowableSubExpressionData(divot, startOffset, endOffset)
805 , m_base(base)
806 , m_subscript(subscript)
807 , m_args(args)
808 {
809 }
810
811 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
812 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
813 virtual Precedence precedence() const { return PrecCall; }
814
815 protected:
816 RefPtr<ExpressionNode> m_base;
817 RefPtr<ExpressionNode> m_subscript;
818 RefPtr<ArgumentsNode> m_args;
819 };
820
821 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
822 public:
823 FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
824 : ExpressionNode(globalData)
825 , ThrowableSubExpressionData(divot, startOffset, endOffset)
826 , m_base(base)
827 , m_ident(ident)
828 , m_args(args)
829 {
830 }
831
832 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
833 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
834 virtual Precedence precedence() const { return PrecCall; }
835
836 private:
837 RefPtr<ExpressionNode> m_base;
838 Identifier m_ident;
839 RefPtr<ArgumentsNode> m_args;
840 };
841
842 class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
843 public:
844 PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
845 : ExpressionNode(globalData, ResultType::constNumber()) // could be reusable for pre?
846 , ThrowableExpressionData(divot, startOffset, endOffset)
847 , m_ident(ident)
848 {
849 }
850
851 protected:
852 Identifier m_ident;
853 };
854
855 class PostfixResolveNode : public PrePostResolveNode {
856 public:
857 PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
858 : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
859 , m_operator(oper)
860 {
861 }
862
863 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
864 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
865 virtual Precedence precedence() const { return PrecPostfix; }
866
867 protected:
868 Operator m_operator;
869 };
870
871 class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
872 public:
873 PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
874 : ExpressionNode(globalData)
875 , ThrowableSubExpressionData(divot, startOffset, endOffset)
876 , m_base(base)
877 , m_subscript(subscript)
878 , m_operator(oper)
879 {
880 }
881
882 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
883 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
884 virtual Precedence precedence() const { return PrecPostfix; }
885
886 protected:
887 RefPtr<ExpressionNode> m_base;
888 RefPtr<ExpressionNode> m_subscript;
889 Operator m_operator;
890 };
891
892 class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
893 public:
894 PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
895 : ExpressionNode(globalData)
896 , ThrowableSubExpressionData(divot, startOffset, endOffset)
897 , m_base(base)
898 , m_ident(ident)
899 , m_operator(oper)
900 {
901 }
902
903 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
904 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
905 virtual Precedence precedence() const { return PrecPostfix; }
906
907 protected:
908 RefPtr<ExpressionNode> m_base;
909 Identifier m_ident;
910 Operator m_operator;
911 };
912
913 class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
914 public:
915 PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
916 : ExpressionNode(globalData)
917 , ThrowableSubExpressionData(divot, startOffset, endOffset)
918 , m_expr(expr)
919 , m_operator(oper)
920 {
921 }
922
923 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
924 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
925 virtual Precedence precedence() const { return PrecPostfix; }
926
927 private:
928 RefPtr<ExpressionNode> m_expr;
929 Operator m_operator;
930 };
931
932 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
933 public:
934 DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
935 : ExpressionNode(globalData)
936 , ThrowableExpressionData(divot, startOffset, endOffset)
937 , m_ident(ident)
938 {
939 }
940
941 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
942
943 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
944 virtual Precedence precedence() const { return PrecUnary; }
945
946 private:
947 Identifier m_ident;
948 };
949
950 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
951 public:
952 DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
953 : ExpressionNode(globalData)
954 , ThrowableExpressionData(divot, startOffset, endOffset)
955 , m_base(base)
956 , m_subscript(subscript)
957 {
958 }
959
960 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
961
962 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
963 virtual Precedence precedence() const { return PrecUnary; }
964
965 private:
966 RefPtr<ExpressionNode> m_base;
967 RefPtr<ExpressionNode> m_subscript;
968 };
969
970 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
971 public:
972 DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
973 : ExpressionNode(globalData)
974 , ThrowableExpressionData(divot, startOffset, endOffset)
975 , m_base(base)
976 , m_ident(ident)
977 {
978 }
979
980 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
981
982 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
983 virtual Precedence precedence() const { return PrecUnary; }
984
985 private:
986 RefPtr<ExpressionNode> m_base;
987 Identifier m_ident;
988 };
989
990 class DeleteValueNode : public ExpressionNode {
991 public:
992 DeleteValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
993 : ExpressionNode(globalData)
994 , m_expr(expr)
995 {
996 }
997
998 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
999
1000 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1001 virtual Precedence precedence() const { return PrecUnary; }
1002
1003 private:
1004 RefPtr<ExpressionNode> m_expr;
1005 };
1006
1007 class VoidNode : public ExpressionNode {
1008 public:
1009 VoidNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1010 : ExpressionNode(globalData)
1011 , m_expr(expr)
1012 {
1013 }
1014
1015 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1016
1017 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1018 virtual Precedence precedence() const { return PrecUnary; }
1019
1020 private:
1021 RefPtr<ExpressionNode> m_expr;
1022 };
1023
1024 class TypeOfResolveNode : public ExpressionNode {
1025 public:
1026 TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
1027 : ExpressionNode(globalData, ResultType::string())
1028 , m_ident(ident)
1029 {
1030 }
1031
1032 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1033
1034 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1035 virtual Precedence precedence() const { return PrecUnary; }
1036
1037 const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
1038
1039 protected:
1040 Identifier m_ident;
1041 size_t m_index; // Used by LocalTypeOfNode.
1042 };
1043
1044 class TypeOfValueNode : public ExpressionNode {
1045 public:
1046 TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1047 : ExpressionNode(globalData, ResultType::string())
1048 , m_expr(expr)
1049 {
1050 }
1051
1052 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1053
1054 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1055 virtual Precedence precedence() const { return PrecUnary; }
1056
1057 private:
1058 RefPtr<ExpressionNode> m_expr;
1059 };
1060
1061 class PrefixResolveNode : public PrePostResolveNode {
1062 public:
1063 PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1064 : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
1065 , m_operator(oper)
1066 {
1067 }
1068
1069 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1070
1071 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1072 virtual Precedence precedence() const { return PrecUnary; }
1073
1074 protected:
1075 Operator m_operator;
1076 };
1077
1078 class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
1079 public:
1080 PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1081 : ExpressionNode(globalData)
1082 , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
1083 , m_base(base)
1084 , m_subscript(subscript)
1085 , m_operator(oper)
1086 {
1087 }
1088
1089 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1090 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1091 virtual Precedence precedence() const { return PrecUnary; }
1092
1093 protected:
1094 RefPtr<ExpressionNode> m_base;
1095 RefPtr<ExpressionNode> m_subscript;
1096 Operator m_operator;
1097 };
1098
1099 class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
1100 public:
1101 PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1102 : ExpressionNode(globalData)
1103 , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
1104 , m_base(base)
1105 , m_ident(ident)
1106 , m_operator(oper)
1107 {
1108 }
1109
1110 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1111 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1112 virtual Precedence precedence() const { return PrecPostfix; }
1113
1114 protected:
1115 RefPtr<ExpressionNode> m_base;
1116 Identifier m_ident;
1117 Operator m_operator;
1118 };
1119
1120 class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
1121 public:
1122 PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1123 : ExpressionNode(globalData)
1124 , ThrowableExpressionData(divot, startOffset, endOffset)
1125 , m_expr(expr)
1126 , m_operator(oper)
1127 {
1128 }
1129
1130 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1131 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1132 virtual Precedence precedence() const { return PrecUnary; }
1133
1134 private:
1135 RefPtr<ExpressionNode> m_expr;
1136 Operator m_operator;
1137 };
1138
1139 class UnaryOpNode : public ExpressionNode {
1140 public:
1141 UnaryOpNode(JSGlobalData* globalData, ExpressionNode* expr)
1142 : ExpressionNode(globalData)
1143 , m_expr(expr)
1144 {
1145 }
1146
1147 UnaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr)
1148 : ExpressionNode(globalData, type)
1149 , m_expr(expr)
1150 {
1151 }
1152
1153 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1154 virtual OpcodeID opcode() const JSC_FAST_CALL = 0;
1155
1156 protected:
1157 RefPtr<ExpressionNode> m_expr;
1158 };
1159
1160 class UnaryPlusNode : public UnaryOpNode {
1161 public:
1162 UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1163 : UnaryOpNode(globalData, ResultType::constNumber(), expr)
1164 {
1165 }
1166
1167 virtual ExpressionNode* stripUnaryPlus() { return m_expr.get(); }
1168
1169 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_to_jsnumber; }
1170 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1171 virtual Precedence precedence() const { return PrecUnary; }
1172 };
1173
1174 class NegateNode : public UnaryOpNode {
1175 public:
1176 NegateNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1177 : UnaryOpNode(globalData, ResultType::reusableNumber(), expr)
1178 {
1179 }
1180
1181 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_negate; }
1182 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1183 virtual Precedence precedence() const { return PrecUnary; }
1184 };
1185
1186 class BitwiseNotNode : public UnaryOpNode {
1187 public:
1188 BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1189 : UnaryOpNode(globalData, ResultType::reusableNumber(), expr)
1190 {
1191 }
1192
1193 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitnot; }
1194 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1195 virtual Precedence precedence() const { return PrecUnary; }
1196 };
1197
1198 class LogicalNotNode : public UnaryOpNode {
1199 public:
1200 LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1201 : UnaryOpNode(globalData, ResultType::boolean(), expr)
1202 {
1203 }
1204
1205 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_not; }
1206 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1207 virtual Precedence precedence() const { return PrecUnary; }
1208 };
1209
1210 class BinaryOpNode : public ExpressionNode {
1211 public:
1212 BinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1213 : ExpressionNode(globalData)
1214 , m_expr1(expr1)
1215 , m_expr2(expr2)
1216 , m_rightHasAssignments(rightHasAssignments)
1217 {
1218 }
1219
1220 BinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1221 : ExpressionNode(globalData, type)
1222 , m_expr1(expr1)
1223 , m_expr2(expr2)
1224 , m_rightHasAssignments(rightHasAssignments)
1225 {
1226 }
1227
1228 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1229 virtual OpcodeID opcode() const JSC_FAST_CALL = 0;
1230
1231 protected:
1232 RefPtr<ExpressionNode> m_expr1;
1233 RefPtr<ExpressionNode> m_expr2;
1234 bool m_rightHasAssignments;
1235 };
1236
1237 class ReverseBinaryOpNode : public ExpressionNode {
1238 public:
1239 ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1240 : ExpressionNode(globalData)
1241 , m_expr1(expr1)
1242 , m_expr2(expr2)
1243 , m_rightHasAssignments(rightHasAssignments)
1244 {
1245 }
1246
1247 ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1248 : ExpressionNode(globalData, type)
1249 , m_expr1(expr1)
1250 , m_expr2(expr2)
1251 , m_rightHasAssignments(rightHasAssignments)
1252 {
1253 }
1254
1255 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1256 virtual OpcodeID opcode() const JSC_FAST_CALL = 0;
1257
1258 protected:
1259 RefPtr<ExpressionNode> m_expr1;
1260 RefPtr<ExpressionNode> m_expr2;
1261 bool m_rightHasAssignments;
1262 };
1263
1264 class MultNode : public BinaryOpNode {
1265 public:
1266 MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1267 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1268 {
1269 }
1270
1271 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_mul; }
1272 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1273 virtual Precedence precedence() const { return PrecMultiplicative; }
1274 };
1275
1276 class DivNode : public BinaryOpNode {
1277 public:
1278 DivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1279 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1280 {
1281 }
1282
1283 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_div; }
1284 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1285 virtual Precedence precedence() const { return PrecMultiplicative; }
1286 };
1287
1288 class ModNode : public BinaryOpNode {
1289 public:
1290 ModNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1291 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1292 {
1293 }
1294
1295 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_mod; }
1296 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1297 virtual Precedence precedence() const { return PrecMultiplicative; }
1298 };
1299
1300 class AddNode : public BinaryOpNode {
1301 public:
1302 AddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1303 : BinaryOpNode(globalData, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, rightHasAssignments)
1304 {
1305 }
1306
1307 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_add; }
1308 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1309 virtual Precedence precedence() const { return PrecAdditive; }
1310 };
1311
1312 class SubNode : public BinaryOpNode {
1313 public:
1314 SubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1315 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1316 {
1317 }
1318
1319 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_sub; }
1320 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1321 virtual Precedence precedence() const { return PrecAdditive; }
1322 };
1323
1324 class LeftShiftNode : public BinaryOpNode {
1325 public:
1326 LeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1327 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1328 {
1329 }
1330
1331 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_lshift; }
1332 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1333 virtual Precedence precedence() const { return PrecShift; }
1334 };
1335
1336 class RightShiftNode : public BinaryOpNode {
1337 public:
1338 RightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1339 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1340 {
1341 }
1342
1343 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_rshift; }
1344 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1345 virtual Precedence precedence() const { return PrecShift; }
1346 };
1347
1348 class UnsignedRightShiftNode : public BinaryOpNode {
1349 public:
1350 UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1351 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1352 {
1353 }
1354
1355 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_urshift; }
1356 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1357 virtual Precedence precedence() const { return PrecShift; }
1358 };
1359
1360 class LessNode : public BinaryOpNode {
1361 public:
1362 LessNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1363 : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1364 {
1365 }
1366
1367 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_less; }
1368 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1369 virtual Precedence precedence() const { return PrecRelational; }
1370 };
1371
1372 class GreaterNode : public ReverseBinaryOpNode {
1373 public:
1374 GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1375 : ReverseBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1376 {
1377 }
1378
1379 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_less; }
1380 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1381 virtual Precedence precedence() const { return PrecRelational; }
1382 };
1383
1384 class LessEqNode : public BinaryOpNode {
1385 public:
1386 LessEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1387 : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1388 {
1389 }
1390
1391 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_lesseq; }
1392 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1393 virtual Precedence precedence() const { return PrecRelational; }
1394 };
1395
1396 class GreaterEqNode : public ReverseBinaryOpNode {
1397 public:
1398 GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1399 : ReverseBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1400 {
1401 }
1402
1403 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_lesseq; }
1404 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1405 virtual Precedence precedence() const { return PrecRelational; }
1406 };
1407
1408 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
1409 public:
1410 ThrowableBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1411 : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
1412 {
1413 }
1414 ThrowableBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1415 : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
1416 {
1417 }
1418 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1419 };
1420
1421 class InstanceOfNode : public ThrowableBinaryOpNode {
1422 public:
1423 InstanceOfNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1424 : ThrowableBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1425 {
1426 }
1427
1428 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_instanceof; }
1429 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1430 virtual Precedence precedence() const { return PrecRelational; }
1431
1432 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1433 };
1434
1435 class InNode : public ThrowableBinaryOpNode {
1436 public:
1437 InNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1438 : ThrowableBinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
1439 {
1440 }
1441
1442 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_in; }
1443 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1444 virtual Precedence precedence() const { return PrecRelational; }
1445 };
1446
1447 class EqualNode : public BinaryOpNode {
1448 public:
1449 EqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1450 : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1451 {
1452 }
1453
1454 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1455 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_eq; }
1456 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1457 virtual Precedence precedence() const { return PrecEquality; }
1458 };
1459
1460 class NotEqualNode : public BinaryOpNode {
1461 public:
1462 NotEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1463 : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1464 {
1465 }
1466
1467 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_neq; }
1468 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1469 virtual Precedence precedence() const { return PrecEquality; }
1470 };
1471
1472 class StrictEqualNode : public BinaryOpNode {
1473 public:
1474 StrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1475 : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1476 {
1477 }
1478
1479 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1480 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_stricteq; }
1481 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1482 virtual Precedence precedence() const { return PrecEquality; }
1483 };
1484
1485 class NotStrictEqualNode : public BinaryOpNode {
1486 public:
1487 NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1488 : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
1489 {
1490 }
1491
1492 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_nstricteq; }
1493 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1494 virtual Precedence precedence() const { return PrecEquality; }
1495 };
1496
1497 class BitAndNode : public BinaryOpNode {
1498 public:
1499 BitAndNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1500 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1501 {
1502 }
1503
1504 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitand; }
1505 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1506 virtual Precedence precedence() const { return PrecBitwiseAnd; }
1507 };
1508
1509 class BitOrNode : public BinaryOpNode {
1510 public:
1511 BitOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1512 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1513 {
1514 }
1515
1516 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitor; }
1517 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1518 virtual Precedence precedence() const { return PrecBitwiseOr; }
1519 };
1520
1521 class BitXOrNode : public BinaryOpNode {
1522 public:
1523 BitXOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
1524 : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
1525 {
1526 }
1527
1528 virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitxor; }
1529 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1530 virtual Precedence precedence() const { return PrecBitwiseXor; }
1531 };
1532
1533 /**
1534 * m_expr1 && m_expr2, m_expr1 || m_expr2
1535 */
1536 class LogicalOpNode : public ExpressionNode {
1537 public:
1538 LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper) JSC_FAST_CALL
1539 : ExpressionNode(globalData, ResultType::boolean())
1540 , m_expr1(expr1)
1541 , m_expr2(expr2)
1542 , m_operator(oper)
1543 {
1544 }
1545
1546 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1547 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1548 virtual Precedence precedence() const { return (m_operator == OpLogicalAnd) ? PrecLogicalAnd : PrecLogicalOr; }
1549
1550 private:
1551 RefPtr<ExpressionNode> m_expr1;
1552 RefPtr<ExpressionNode> m_expr2;
1553 LogicalOperator m_operator;
1554 };
1555
1556 /**
1557 * The ternary operator, "m_logical ? m_expr1 : m_expr2"
1558 */
1559 class ConditionalNode : public ExpressionNode {
1560 public:
1561 ConditionalNode(JSGlobalData* globalData, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
1562 : ExpressionNode(globalData)
1563 , m_logical(logical)
1564 , m_expr1(expr1)
1565 , m_expr2(expr2)
1566 {
1567 }
1568
1569 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1570 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1571 virtual Precedence precedence() const { return PrecConditional; }
1572
1573 private:
1574 RefPtr<ExpressionNode> m_logical;
1575 RefPtr<ExpressionNode> m_expr1;
1576 RefPtr<ExpressionNode> m_expr2;
1577 };
1578
1579 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
1580 public:
1581 ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1582 : ExpressionNode(globalData)
1583 , ThrowableExpressionData(divot, startOffset, endOffset)
1584 , m_ident(ident)
1585 , m_right(right)
1586 , m_operator(oper)
1587 , m_rightHasAssignments(rightHasAssignments)
1588 {
1589 }
1590
1591 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1592
1593 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1594 virtual Precedence precedence() const { return PrecAssignment; }
1595
1596 protected:
1597 Identifier m_ident;
1598 RefPtr<ExpressionNode> m_right;
1599 size_t m_index; // Used by ReadModifyLocalVarNode.
1600 Operator m_operator : 31;
1601 bool m_rightHasAssignments : 1;
1602 };
1603
1604 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
1605 public:
1606 AssignResolveNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) JSC_FAST_CALL
1607 : ExpressionNode(globalData)
1608 , m_ident(ident)
1609 , m_right(right)
1610 , m_rightHasAssignments(rightHasAssignments)
1611 {
1612 }
1613
1614 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1615
1616 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1617 virtual Precedence precedence() const { return PrecAssignment; }
1618
1619 protected:
1620 Identifier m_ident;
1621 RefPtr<ExpressionNode> m_right;
1622 size_t m_index; // Used by ReadModifyLocalVarNode.
1623 bool m_rightHasAssignments;
1624 };
1625
1626 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1627 public:
1628 ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1629 : ExpressionNode(globalData)
1630 , ThrowableSubExpressionData(divot, startOffset, endOffset)
1631 , m_base(base)
1632 , m_subscript(subscript)
1633 , m_right(right)
1634 , m_operator(oper)
1635 , m_subscriptHasAssignments(subscriptHasAssignments)
1636 , m_rightHasAssignments(rightHasAssignments)
1637 {
1638 }
1639
1640 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1641
1642 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1643 virtual Precedence precedence() const { return PrecAssignment; }
1644
1645 protected:
1646 RefPtr<ExpressionNode> m_base;
1647 RefPtr<ExpressionNode> m_subscript;
1648 RefPtr<ExpressionNode> m_right;
1649 Operator m_operator : 30;
1650 bool m_subscriptHasAssignments : 1;
1651 bool m_rightHasAssignments : 1;
1652 };
1653
1654 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1655 public:
1656 AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1657 : ExpressionNode(globalData)
1658 , ThrowableExpressionData(divot, startOffset, endOffset)
1659 , m_base(base)
1660 , m_subscript(subscript)
1661 , m_right(right)
1662 , m_subscriptHasAssignments(subscriptHasAssignments)
1663 , m_rightHasAssignments(rightHasAssignments)
1664 {
1665 }
1666
1667 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1668
1669 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1670 virtual Precedence precedence() const { return PrecAssignment; }
1671
1672 protected:
1673 RefPtr<ExpressionNode> m_base;
1674 RefPtr<ExpressionNode> m_subscript;
1675 RefPtr<ExpressionNode> m_right;
1676 bool m_subscriptHasAssignments : 1;
1677 bool m_rightHasAssignments : 1;
1678 };
1679
1680 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1681 public:
1682 AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1683 : ExpressionNode(globalData)
1684 , ThrowableExpressionData(divot, startOffset, endOffset)
1685 , m_base(base)
1686 , m_ident(ident)
1687 , m_right(right)
1688 , m_rightHasAssignments(rightHasAssignments)
1689 {
1690 }
1691
1692 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1693 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1694 virtual Precedence precedence() const { return PrecAssignment; }
1695
1696 protected:
1697 RefPtr<ExpressionNode> m_base;
1698 Identifier m_ident;
1699 RefPtr<ExpressionNode> m_right;
1700 bool m_rightHasAssignments;
1701 };
1702
1703 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1704 public:
1705 ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1706 : ExpressionNode(globalData)
1707 , ThrowableSubExpressionData(divot, startOffset, endOffset)
1708 , m_base(base)
1709 , m_ident(ident)
1710 , m_right(right)
1711 , m_operator(oper)
1712 , m_rightHasAssignments(rightHasAssignments)
1713 {
1714 }
1715
1716 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1717
1718 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1719 virtual Precedence precedence() const { return PrecAssignment; }
1720
1721 protected:
1722 RefPtr<ExpressionNode> m_base;
1723 Identifier m_ident;
1724 RefPtr<ExpressionNode> m_right;
1725 Operator m_operator : 31;
1726 bool m_rightHasAssignments : 1;
1727 };
1728
1729 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1730 public:
1731 AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
1732 : ExpressionNode(globalData)
1733 , ThrowableExpressionData(divot, startOffset, endOffset)
1734 , m_left(left)
1735 , m_operator(oper)
1736 , m_right(right)
1737 {
1738 }
1739
1740 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1741 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1742 virtual Precedence precedence() const { return PrecAssignment; }
1743
1744 protected:
1745 RefPtr<ExpressionNode> m_left;
1746 Operator m_operator;
1747 RefPtr<ExpressionNode> m_right;
1748 };
1749
1750 class CommaNode : public ExpressionNode {
1751 public:
1752 CommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
1753 : ExpressionNode(globalData)
1754 , m_expr1(expr1)
1755 , m_expr2(expr2)
1756 {
1757 }
1758
1759 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1760 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1761 virtual Precedence precedence() const { return PrecExpression; }
1762
1763 private:
1764 RefPtr<ExpressionNode> m_expr1;
1765 RefPtr<ExpressionNode> m_expr2;
1766 };
1767
1768 class VarDeclCommaNode : public CommaNode {
1769 public:
1770 VarDeclCommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
1771 : CommaNode(globalData, expr1, expr2)
1772 {
1773 }
1774 virtual Precedence precedence() const { return PrecAssignment; }
1775 };
1776
1777 class ConstDeclNode : public ExpressionNode {
1778 public:
1779 ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in) JSC_FAST_CALL;
1780
1781 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1782 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1783 PassRefPtr<ConstDeclNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
1784
1785 Identifier m_ident;
1786 ListRefPtr<ConstDeclNode> m_next;
1787 RefPtr<ExpressionNode> m_init;
1788
1789 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1790 virtual RegisterID* emitCodeSingle(CodeGenerator&) JSC_FAST_CALL;
1791 };
1792
1793 class ConstStatementNode : public StatementNode {
1794 public:
1795 ConstStatementNode(JSGlobalData* globalData, ConstDeclNode* next) JSC_FAST_CALL
1796 : StatementNode(globalData)
1797 , m_next(next)
1798 {
1799 }
1800
1801 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1802
1803 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1804
1805 private:
1806 RefPtr<ConstDeclNode> m_next;
1807 };
1808
1809 typedef Vector<RefPtr<StatementNode> > StatementVector;
1810
1811 class SourceElements : public ParserRefCounted {
1812 public:
1813 SourceElements(JSGlobalData* globalData) : ParserRefCounted(globalData) {}
1814
1815 void append(PassRefPtr<StatementNode>);
1816 void releaseContentsIntoVector(StatementVector& destination)
1817 {
1818 ASSERT(destination.isEmpty());
1819 m_statements.swap(destination);
1820 }
1821
1822 private:
1823 StatementVector m_statements;
1824 };
1825
1826 class BlockNode : public StatementNode {
1827 public:
1828 BlockNode(JSGlobalData*, SourceElements* children) JSC_FAST_CALL;
1829
1830 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1831 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1832
1833 StatementVector& children() { return m_children; }
1834
1835 virtual bool isBlock() const JSC_FAST_CALL { return true; }
1836 protected:
1837 StatementVector m_children;
1838 };
1839
1840 class EmptyStatementNode : public StatementNode {
1841 public:
1842 EmptyStatementNode(JSGlobalData* globalData) JSC_FAST_CALL // debug
1843 : StatementNode(globalData)
1844 {
1845 }
1846
1847 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1848
1849 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1850 virtual bool isEmptyStatement() const JSC_FAST_CALL { return true; }
1851 };
1852
1853 class DebuggerStatementNode : public StatementNode {
1854 public:
1855 DebuggerStatementNode(JSGlobalData* globalData) JSC_FAST_CALL
1856 : StatementNode(globalData)
1857 {
1858 }
1859
1860 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1861
1862 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1863 };
1864
1865 class ExprStatementNode : public StatementNode {
1866 public:
1867 ExprStatementNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1868 : StatementNode(globalData)
1869 , m_expr(expr)
1870 {
1871 }
1872
1873 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1874 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1875
1876 private:
1877 RefPtr<ExpressionNode> m_expr;
1878 };
1879
1880 class VarStatementNode : public StatementNode {
1881 public:
1882 VarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
1883 : StatementNode(globalData)
1884 , m_expr(expr)
1885 {
1886 }
1887
1888 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1889
1890 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1891
1892 private:
1893 RefPtr<ExpressionNode> m_expr;
1894 };
1895
1896 class IfNode : public StatementNode {
1897 public:
1898 IfNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock) JSC_FAST_CALL
1899 : StatementNode(globalData)
1900 , m_condition(condition)
1901 , m_ifBlock(ifBlock)
1902 {
1903 }
1904
1905 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1906 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1907
1908 protected:
1909 RefPtr<ExpressionNode> m_condition;
1910 RefPtr<StatementNode> m_ifBlock;
1911 };
1912
1913 class IfElseNode : public IfNode {
1914 public:
1915 IfElseNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock) JSC_FAST_CALL
1916 : IfNode(globalData, condition, ifBlock)
1917 , m_elseBlock(elseBlock)
1918 {
1919 }
1920
1921 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1922 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1923
1924 private:
1925 RefPtr<StatementNode> m_elseBlock;
1926 };
1927
1928 class DoWhileNode : public StatementNode {
1929 public:
1930 DoWhileNode(JSGlobalData* globalData, StatementNode* statement, ExpressionNode* expr) JSC_FAST_CALL
1931 : StatementNode(globalData)
1932 , m_statement(statement)
1933 , m_expr(expr)
1934 {
1935 }
1936
1937 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1938 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1939
1940 virtual bool isLoop() const JSC_FAST_CALL { return true; }
1941 private:
1942 RefPtr<StatementNode> m_statement;
1943 RefPtr<ExpressionNode> m_expr;
1944 };
1945
1946 class WhileNode : public StatementNode {
1947 public:
1948 WhileNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement) JSC_FAST_CALL
1949 : StatementNode(globalData)
1950 , m_expr(expr)
1951 , m_statement(statement)
1952 {
1953 }
1954
1955 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1956 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1957
1958 virtual bool isLoop() const JSC_FAST_CALL { return true; }
1959 private:
1960 RefPtr<ExpressionNode> m_expr;
1961 RefPtr<StatementNode> m_statement;
1962 };
1963
1964 class ForNode : public StatementNode {
1965 public:
1966 ForNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) JSC_FAST_CALL
1967 : StatementNode(globalData)
1968 , m_expr1(expr1)
1969 , m_expr2(expr2)
1970 , m_expr3(expr3)
1971 , m_statement(statement)
1972 , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
1973 {
1974 ASSERT(statement);
1975 }
1976
1977 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1978 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1979
1980 virtual bool isLoop() const JSC_FAST_CALL { return true; }
1981 private:
1982 RefPtr<ExpressionNode> m_expr1;
1983 RefPtr<ExpressionNode> m_expr2;
1984 RefPtr<ExpressionNode> m_expr3;
1985 RefPtr<StatementNode> m_statement;
1986 bool m_expr1WasVarDecl;
1987 };
1988
1989 class ForInNode : public StatementNode, public ThrowableExpressionData {
1990 public:
1991 ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*) JSC_FAST_CALL;
1992 ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset) JSC_FAST_CALL;
1993
1994 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1995 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
1996
1997 virtual bool isLoop() const JSC_FAST_CALL { return true; }
1998 private:
1999 Identifier m_ident;
2000 RefPtr<ExpressionNode> m_init;
2001 RefPtr<ExpressionNode> m_lexpr;
2002 RefPtr<ExpressionNode> m_expr;
2003 RefPtr<StatementNode> m_statement;
2004 bool m_identIsVarDecl;
2005 };
2006
2007 class ContinueNode : public StatementNode, public ThrowableExpressionData {
2008 public:
2009 ContinueNode(JSGlobalData* globalData) JSC_FAST_CALL
2010 : StatementNode(globalData)
2011 {
2012 }
2013
2014 ContinueNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
2015 : StatementNode(globalData)
2016 , m_ident(ident)
2017 {
2018 }
2019
2020 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2021 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2022
2023 private:
2024 Identifier m_ident;
2025 };
2026
2027 class BreakNode : public StatementNode, public ThrowableExpressionData {
2028 public:
2029 BreakNode(JSGlobalData* globalData) JSC_FAST_CALL
2030 : StatementNode(globalData)
2031 {
2032 }
2033
2034 BreakNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
2035 : StatementNode(globalData)
2036 , m_ident(ident)
2037 {
2038 }
2039
2040 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2041 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2042
2043 private:
2044 Identifier m_ident;
2045 };
2046
2047 class ReturnNode : public StatementNode, public ThrowableExpressionData {
2048 public:
2049 ReturnNode(JSGlobalData* globalData, ExpressionNode* value) JSC_FAST_CALL
2050 : StatementNode(globalData)
2051 , m_value(value)
2052 {
2053 }
2054
2055 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2056 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2057 virtual bool isReturnNode() const JSC_FAST_CALL { return true; }
2058
2059 private:
2060 RefPtr<ExpressionNode> m_value;
2061 };
2062
2063 class WithNode : public StatementNode {
2064 public:
2065 WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength) JSC_FAST_CALL
2066 : StatementNode(globalData)
2067 , m_expr(expr)
2068 , m_statement(statement)
2069 , m_divot(divot)
2070 , m_expressionLength(expressionLength)
2071 {
2072 }
2073
2074 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2075 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2076
2077 private:
2078 RefPtr<ExpressionNode> m_expr;
2079 RefPtr<StatementNode> m_statement;
2080 uint32_t m_divot;
2081 uint32_t m_expressionLength;
2082 };
2083
2084 class LabelNode : public StatementNode, public ThrowableExpressionData {
2085 public:
2086 LabelNode(JSGlobalData* globalData, const Identifier& name, StatementNode* statement) JSC_FAST_CALL
2087 : StatementNode(globalData)
2088 , m_name(name)
2089 , m_statement(statement)
2090 {
2091 }
2092
2093 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2094 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2095
2096 private:
2097 Identifier m_name;
2098 RefPtr<StatementNode> m_statement;
2099 };
2100
2101 class ThrowNode : public StatementNode, public ThrowableExpressionData {
2102 public:
2103 ThrowNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
2104 : StatementNode(globalData)
2105 , m_expr(expr)
2106 {
2107 }
2108
2109 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2110 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2111
2112 private:
2113 RefPtr<ExpressionNode> m_expr;
2114 };
2115
2116 class TryNode : public StatementNode {
2117 public:
2118 TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) JSC_FAST_CALL
2119 : StatementNode(globalData)
2120 , m_tryBlock(tryBlock)
2121 , m_exceptionIdent(exceptionIdent)
2122 , m_catchBlock(catchBlock)
2123 , m_finallyBlock(finallyBlock)
2124 {
2125 }
2126
2127 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2128
2129 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL;
2130
2131 private:
2132 RefPtr<StatementNode> m_tryBlock;
2133 Identifier m_exceptionIdent;
2134 RefPtr<StatementNode> m_catchBlock;
2135 RefPtr<StatementNode> m_finallyBlock;
2136 };
2137
2138 class ParameterNode : public Node {
2139 public:
2140 ParameterNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
2141 : Node(globalData)
2142 , m_ident(ident)
2143 {
2144 }
2145
2146 ParameterNode(JSGlobalData* globalData, ParameterNode* l, const Identifier& ident) JSC_FAST_CALL
2147 : Node(globalData)
2148 , m_ident(ident)
2149 {
2150 l->m_next = this;
2151 }
2152
2153 Identifier ident() JSC_FAST_CALL { return m_ident; }
2154 ParameterNode *nextParam() JSC_FAST_CALL { return m_next.get(); }
2155 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2156 PassRefPtr<ParameterNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
2157 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2158
2159 private:
2160 friend class FuncDeclNode;
2161 friend class FuncExprNode;
2162 Identifier m_ident;
2163 ListRefPtr<ParameterNode> m_next;
2164 };
2165
2166 class ScopeNode : public BlockNode {
2167 public:
2168 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
2169
2170 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2171
2172 const SourceCode& source() const { return m_source; }
2173 const UString& sourceURL() const JSC_FAST_CALL { return m_source.provider()->url(); }
2174 intptr_t sourceID() const { return m_source.provider()->asID(); }
2175
2176 bool usesEval() const { return m_features & EvalFeature; }
2177 bool usesArguments() const { return m_features & ArgumentsFeature; }
2178 void setUsesArguments() { m_features |= ArgumentsFeature; }
2179 bool usesThis() const { return m_features & ThisFeature; }
2180 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
2181
2182 VarStack& varStack() { return m_varStack; }
2183 FunctionStack& functionStack() { return m_functionStack; }
2184
2185 int neededConstants()
2186 {
2187 // We may need 1 more constant than the count given by the parser,
2188 // because of the various uses of jsUndefined().
2189 return m_numConstants + 1;
2190 }
2191
2192 protected:
2193 void setSource(const SourceCode& source) { m_source = source; }
2194
2195 VarStack m_varStack;
2196 FunctionStack m_functionStack;
2197
2198 private:
2199 SourceCode m_source;
2200 CodeFeatures m_features;
2201 int m_numConstants;
2202 };
2203
2204 class ProgramNode : public ScopeNode {
2205 public:
2206 static ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
2207
2208 ProgramCodeBlock& byteCode(ScopeChainNode* scopeChain) JSC_FAST_CALL
2209 {
2210 if (!m_code)
2211 generateCode(scopeChain);
2212 return *m_code;
2213 }
2214
2215 private:
2216 ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
2217
2218 void generateCode(ScopeChainNode*) JSC_FAST_CALL;
2219 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2220
2221 Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
2222 Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
2223
2224 OwnPtr<ProgramCodeBlock> m_code;
2225 };
2226
2227 class EvalNode : public ScopeNode {
2228 public:
2229 static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
2230
2231 EvalCodeBlock& byteCode(ScopeChainNode* scopeChain) JSC_FAST_CALL
2232 {
2233 if (!m_code)
2234 generateCode(scopeChain);
2235 return *m_code;
2236 }
2237
2238 private:
2239 EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
2240
2241 void generateCode(ScopeChainNode*) JSC_FAST_CALL;
2242 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2243
2244 OwnPtr<EvalCodeBlock> m_code;
2245 };
2246
2247 class FunctionBodyNode : public ScopeNode {
2248 public:
2249 static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
2250 static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
2251 ~FunctionBodyNode();
2252
2253 const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
2254 size_t parameterCount() const { return m_parameterCount; }
2255 UString paramString() const JSC_FAST_CALL;
2256 Identifier* copyParameters();
2257
2258 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2259
2260 SymbolTable& symbolTable() { return m_symbolTable; } // FIXME: Remove this
2261
2262 CodeBlock& byteCode(ScopeChainNode* scopeChain) JSC_FAST_CALL
2263 {
2264 ASSERT(scopeChain);
2265 if (!m_code)
2266 generateCode(scopeChain);
2267 return *m_code;
2268 }
2269
2270 CodeBlock& generatedByteCode() JSC_FAST_CALL
2271 {
2272 ASSERT(m_code);
2273 return *m_code;
2274 }
2275
2276 bool isGenerated() JSC_FAST_CALL
2277 {
2278 return m_code;
2279 }
2280
2281 void mark();
2282
2283 void finishParsing(const SourceCode&, ParameterNode*);
2284 void finishParsing(Identifier* parameters, size_t parameterCount);
2285
2286 UString toSourceString() const JSC_FAST_CALL { return UString("{") + source().toString() + UString("}"); }
2287
2288 // These objects are ref/deref'd a lot in the scope chain, so this is a faster ref/deref.
2289 // If the virtual machine changes so this doesn't happen as much we can change back.
2290 void ref()
2291 {
2292 if (++m_refCount == 1)
2293 ScopeNode::ref();
2294 }
2295 void deref()
2296 {
2297 ASSERT(m_refCount);
2298 if (!--m_refCount)
2299 ScopeNode::deref();
2300 }
2301
2302 protected:
2303 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
2304
2305 private:
2306 void generateCode(ScopeChainNode*) JSC_FAST_CALL;
2307
2308 Identifier* m_parameters;
2309 size_t m_parameterCount;
2310 SymbolTable m_symbolTable;
2311 OwnPtr<CodeBlock> m_code;
2312 unsigned m_refCount;
2313 };
2314
2315 class FuncExprNode : public ExpressionNode {
2316 public:
2317 FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) JSC_FAST_CALL
2318 : ExpressionNode(globalData)
2319 , m_ident(ident)
2320 , m_parameter(parameter)
2321 , m_body(body)
2322 {
2323 m_body->finishParsing(source, m_parameter.get());
2324 }
2325
2326 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2327 JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
2328 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2329 virtual Precedence precedence() const { return PrecMember; }
2330 virtual bool needsParensIfLeftmost() const { return true; }
2331
2332 FunctionBodyNode* body() { return m_body.get(); }
2333
2334 private:
2335 // Used for streamTo
2336 friend class PropertyNode;
2337 Identifier m_ident;
2338 RefPtr<ParameterNode> m_parameter;
2339 RefPtr<FunctionBodyNode> m_body;
2340 };
2341
2342 class FuncDeclNode : public StatementNode {
2343 public:
2344 FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) JSC_FAST_CALL
2345 : StatementNode(globalData)
2346 , m_ident(ident)
2347 , m_parameter(parameter)
2348 , m_body(body)
2349 {
2350 m_body->finishParsing(source, m_parameter.get());
2351 }
2352
2353 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2354
2355 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2356 JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
2357
2358 Identifier m_ident;
2359
2360 FunctionBodyNode* body() { return m_body.get(); }
2361
2362 private:
2363 RefPtr<ParameterNode> m_parameter;
2364 RefPtr<FunctionBodyNode> m_body;
2365 };
2366
2367 class CaseClauseNode : public Node {
2368 public:
2369 CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
2370 : Node(globalData)
2371 , m_expr(expr)
2372 {
2373 }
2374
2375 CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr, SourceElements* children) JSC_FAST_CALL
2376 : Node(globalData)
2377 , m_expr(expr)
2378 {
2379 if (children)
2380 children->releaseContentsIntoVector(m_children);
2381 }
2382
2383 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2384 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2385
2386 ExpressionNode* expr() const { return m_expr.get(); }
2387 StatementVector& children() { return m_children; }
2388
2389 private:
2390 RefPtr<ExpressionNode> m_expr;
2391 StatementVector m_children;
2392 };
2393
2394 class ClauseListNode : public Node {
2395 public:
2396 ClauseListNode(JSGlobalData* globalData, CaseClauseNode* clause) JSC_FAST_CALL
2397 : Node(globalData)
2398 , m_clause(clause)
2399 {
2400 }
2401
2402 ClauseListNode(JSGlobalData* globalData, ClauseListNode* clauseList, CaseClauseNode* clause) JSC_FAST_CALL
2403 : Node(globalData)
2404 , m_clause(clause)
2405 {
2406 clauseList->m_next = this;
2407 }
2408
2409 CaseClauseNode* getClause() const JSC_FAST_CALL { return m_clause.get(); }
2410 ClauseListNode* getNext() const JSC_FAST_CALL { return m_next.get(); }
2411 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2412 PassRefPtr<ClauseListNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
2413 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2414
2415 private:
2416 friend class CaseBlockNode;
2417 RefPtr<CaseClauseNode> m_clause;
2418 ListRefPtr<ClauseListNode> m_next;
2419 };
2420
2421 class CaseBlockNode : public Node {
2422 public:
2423 CaseBlockNode(JSGlobalData* globalData, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) JSC_FAST_CALL
2424 : Node(globalData)
2425 , m_list1(list1)
2426 , m_defaultClause(defaultClause)
2427 , m_list2(list2)
2428 {
2429 }
2430
2431 RegisterID* emitCodeForBlock(CodeGenerator&, RegisterID* input, RegisterID* dst = 0) JSC_FAST_CALL;
2432
2433 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2434 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2435
2436 private:
2437 SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
2438 RefPtr<ClauseListNode> m_list1;
2439 RefPtr<CaseClauseNode> m_defaultClause;
2440 RefPtr<ClauseListNode> m_list2;
2441 };
2442
2443 class SwitchNode : public StatementNode {
2444 public:
2445 SwitchNode(JSGlobalData* globalData, ExpressionNode* expr, CaseBlockNode* block) JSC_FAST_CALL
2446 : StatementNode(globalData)
2447 , m_expr(expr)
2448 , m_block(block)
2449 {
2450 }
2451
2452 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
2453
2454 virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
2455
2456 private:
2457 RefPtr<ExpressionNode> m_expr;
2458 RefPtr<CaseBlockNode> m_block;
2459 };
2460
2461 struct ElementList {
2462 ElementNode* head;
2463 ElementNode* tail;
2464 };
2465
2466 struct PropertyList {
2467 PropertyListNode* head;
2468 PropertyListNode* tail;
2469 };
2470
2471 struct ArgumentList {
2472 ArgumentListNode* head;
2473 ArgumentListNode* tail;
2474 };
2475
2476 struct ConstDeclList {
2477 ConstDeclNode* head;
2478 ConstDeclNode* tail;
2479 };
2480
2481 struct ParameterList {
2482 ParameterNode* head;
2483 ParameterNode* tail;
2484 };
2485
2486 struct ClauseList {
2487 ClauseListNode* head;
2488 ClauseListNode* tail;
2489 };
2490
2491} // namespace JSC
2492
2493#endif // NODES_H_
Note: See TracBrowser for help on using the repository browser.