1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
6 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
7 * Copyright (C) 2007, 2008 Maksim Orlovich (maksim@kde.org)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 *
24 */
25
26#ifndef NODES_H_
27#define NODES_H_
28
29#include "Parser.h"
30#include "internal.h"
31#include "CompileState.h"
32#include "operations.h"
33#include "SymbolTable.h"
34#include "opcodes.h"
35#include "bytecode/opargs.h"
36#include <wtf/ListRefPtr.h>
37#include <wtf/Vector.h>
38
39
40namespace KJS {
41 class ProgramNode;
42 class PropertyNameNode;
43 class PropertyListNode;
44 class RegExp;
45 class SourceElementsNode;
46 class SourceStream;
47 class PackageObject;
48 class FuncDeclNode;
49 class FunctionBodyNode;
50 class Node;
51
52 class VarDeclVisitor;
53 class FuncDeclVisitor;
54
55 class CompileState;
56 struct CompileReference;
57
58 class NodeVisitor {
59 public:
60 virtual ~NodeVisitor() {}
61 /**
62 This method should be overridden by subclasses to process nodes, and
63 perhaps return pointers for replacement nodes. If the node should not be
64 changed, return 0. Otherwise, return the replacement node.
65
66 The default implementation asks the node to visit its kids, and do
67 replacements on them if needed, but does not change anything for this node
68 */
69 virtual Node* visit(Node* node);
70 };
71
72 class Node {
73 public:
74 enum NodeType {
75 UnknownNodeType,
76 NullNodeType,
77 BooleanNodeType,
78 NumberNodeType,
79 StringNodeType,
80 RegExpNodeType,
81 TryNodeType,
82 GroupNodeType,
83 LabelNodeType
84 };
85
86 Node();
87 virtual ~Node();
88
89 virtual NodeType type() const { return UnknownNodeType; }
90
91 UString toString() const;
92
93 // This updates line numbers to the pretty-printed version, and
94 // returns it out.
95 UString reindent(int baseLine = 0) const;
96
97 virtual void streamTo(SourceStream&) const = 0;
98 int lineNo() const { return m_line; }
99
100 void ref();
101 void deref();
102 unsigned refcount();
103 static void clearNewNodes();
104
105 virtual Node *nodeInsideAllParens();
106
107 virtual bool isLocation() const { return false; }
108 virtual bool isVarAccessNode() const { return false; }
109 bool isNumber() const { return type() == NumberNodeType; }
110 bool isString() const { return type() == StringNodeType; }
111 bool isGroupNode() const { return type() == GroupNodeType; }
112 bool isTryNode() const { return type() == TryNodeType; }
113 bool isLabelNode() const { return type() == LabelNodeType; }
114 virtual bool scanForDeclarations () const { return true; }
115 virtual bool isIterationStatement() const { return false; }
116
117 virtual void breakCycle() { }
118
119 // Processes all function and variable declarations below this node,
120 // adding them to symbol table or the current object depending on the
121 // execution context..
122 void processDecls(ExecState*);
123
124 /*
125 Implementations of this method should call visitor->visit on all the
126 children nodes, and if they return value is non-0, update the link to the child.
127 The recurseVisitLink helper takes care of this
128 */
129 virtual void recurseVisit(NodeVisitor * /*visitor*/) {}
130
131 template<typename T>
132 static void recurseVisitLink(NodeVisitor* visitor, RefPtr<T>& link)
133 {
134 if (!link)
135 return;
136
137 T* newLink = static_cast<T*>(visitor->visit(link.get()));
138 if (newLink)
139 link = newLink;
140 }
141
142 template<typename T>
143 static void recurseVisitLink(NodeVisitor* visitor, ListRefPtr<T>& link)
144 {
145 if (!link)
146 return;
147
148 T* newLink = static_cast<T*>(visitor->visit(link.get()));
149 if (newLink)
150 link = newLink;
151 }
152
153
154 JSValue* throwError(ExecState*, ErrorType, const UString& msg);
155 JSValue* throwError(ExecState*, ErrorType, const UString& msg, const Identifier&);
156 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&);
157
158 virtual OpValue generateEvalCode(CompileState* comp);
159 protected:
160 mutable int m_line;
161 private:
162 virtual void processVarDecl (ExecState* state);
163 virtual void processFuncDecl(ExecState* state);
164 friend class VarDeclVisitor;
165 friend class FuncDeclVisitor;
166
167 // disallow assignment
168 Node& operator=(const Node&);
169 Node(const Node &other);
170 };
171
172 class LocationNode : public Node {
173 public:
174 virtual bool isLocation() const { return true; }
175
176 // For assignments, we need to conceptually evaluate the LHS to a reference before looking at the RHS
177 // generateRefBind corresponds to that action. It never issues an error. The returned
178 // reference should be passed to generateRefWrite when needed
179 virtual CompileReference* generateRefBind(CompileState*) = 0;
180
181 // When we are doing a read-modify-write style op, or just plain read, we want to do a read
182 // right after the binding. This does that, and returns a reference for use of follow up
183 // writes.
184 virtual CompileReference* generateRefRead(CompileState*, OpValue* out) = 0;
185
186 // Writes to a bound reference.
187 virtual void generateRefWrite (CompileState*,
188 CompileReference* ref, OpValue& valToStore) = 0;
189
190 // The location nodes also handle deletes themselves. Note that this is called
191 // w/o generateRefBegin
192 virtual OpValue generateRefDelete(CompileState*) = 0;
193
194 // For function calls, we also do a specialized lookup, getting both the valie and the
195 // scope/this, also making sure it's not an activation.
196 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut) = 0;
197 };
198
199 class StatementNode : public Node {
200 public:
201 StatementNode();
202 void setLoc(int line0, int line1) const;
203 int firstLine() const { return lineNo(); }
204 int lastLine() const { return m_lastLine; }
205 void hitStatement(ExecState*);
206
207 void generateDebugInfoIfNeeded(CompileState* comp);
208
209 virtual void generateExecCode(CompileState*);
210 private:
211 void generateDebugInfo(CompileState* comp);
212 mutable int m_lastLine;
213 };
214
215 inline void StatementNode::generateDebugInfoIfNeeded(CompileState* comp)
216 {
217 if (comp->compileType() == Debug)
218 generateDebugInfo(comp);
219 }
220
221 class NullNode : public Node {
222 public:
223 NullNode() {}
224 virtual NodeType type() const { return NullNodeType; }
225 virtual OpValue generateEvalCode(CompileState* comp);
226 virtual void streamTo(SourceStream&) const;
227 };
228
229 class BooleanNode : public Node {
230 public:
231 BooleanNode(bool v) : val(v) {}
232 bool value() const { return val; }
233
234 virtual NodeType type() const { return BooleanNodeType; }
235 virtual OpValue generateEvalCode(CompileState* comp);
236 virtual void streamTo(SourceStream&) const;
237 private:
238 bool val;
239 };
240
241 class NumberNode : public Node {
242 public:
243 NumberNode(double v) : val(v) {}
244 double value() const { return val; }
245 void setValue(double v) { val = v; }
246
247 virtual NodeType type() const { return NumberNodeType; }
248 virtual OpValue generateEvalCode(CompileState* comp);
249 virtual void streamTo(SourceStream&) const;
250 private:
251 double val;
252 };
253
254 class StringNode : public Node {
255 public:
256 StringNode(const UString *v) : val(*v), interned(0) { }
257 ~StringNode(); // in nodes2bytecode.cpp
258 UString value() const { return val; }
259 void setValue(const UString& v) { val = v; }
260
261 virtual NodeType type() const { return StringNodeType; }
262 virtual OpValue generateEvalCode(CompileState* comp);
263 virtual void streamTo(SourceStream&) const;
264 private:
265 UString val;
266 StringImp* interned;
267 };
268
269 class RegExpNode : public Node {
270 public:
271 RegExpNode(const UString &p, const UString &f)
272 : pattern(p), flags(f) { }
273 virtual NodeType type() const { return RegExpNodeType; }
274 virtual OpValue generateEvalCode(CompileState* comp);
275 virtual void streamTo(SourceStream&) const;
276 private:
277 UString pattern, flags;
278 };
279
280 class ThisNode : public Node {
281 public:
282 ThisNode() {}
283 virtual OpValue generateEvalCode(CompileState* comp);
284 virtual void streamTo(SourceStream&) const;
285 };
286
287 class VarAccessNode : public LocationNode {
288 public:
289 VarAccessNode(const Identifier& s) : ident(s) {}
290
291 virtual bool isVarAccessNode() const { return true; }
292 virtual void streamTo(SourceStream&) const;
293 virtual OpValue generateEvalCode(CompileState* comp);
294
295 virtual CompileReference* generateRefBind(CompileState*);
296 virtual CompileReference* generateRefRead(CompileState*, OpValue* out);
297 virtual void generateRefWrite (CompileState*,
298 CompileReference* ref, OpValue& valToStore);
299 virtual OpValue generateRefDelete(CompileState*);
300 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut);
301
302 // This one never fails..
303 OpValue valueForTypeOf(CompileState* comp);
304
305 // Returns the ID this variable should be accessed as, or
306 // missingSymbolMarker(), along with the variable's classification
307 enum Classification {
308 Local, // local variable accessed by register #
309 NonLocal, // one scope above, unless local injected
310 Dynamic, // need to do a full lookup
311 Global // in the global object, if anywhere.
312 };
313
314 size_t classifyVariable(CompileState*, Classification& classify);
315 protected:
316 Identifier ident;
317 };
318
319 class GroupNode : public Node {
320 public:
321 GroupNode(Node *g) : group(g) { }
322 virtual NodeType type() const { return GroupNodeType; }
323
324 virtual OpValue generateEvalCode(CompileState* comp);
325 virtual Node *nodeInsideAllParens();
326 virtual void streamTo(SourceStream&) const;
327 virtual void recurseVisit(NodeVisitor *visitor);
328 private:
329 RefPtr<Node> group;
330 };
331
332 class ElementNode : public Node {
333 public:
334 // list pointer is tail of a circular list, cracked in the ArrayNode ctor
335 ElementNode(int e, Node *n) : next(this), elision(e), node(n) { Parser::noteNodeCycle(this); }
336 ElementNode(ElementNode *l, int e, Node *n)
337 : next(l->next), elision(e), node(n) { l->next = this; }
338
339 virtual void streamTo(SourceStream&) const;
340 PassRefPtr<ElementNode> releaseNext() { return next.release(); }
341 virtual void breakCycle();
342 virtual void recurseVisit(NodeVisitor *visitor);
343 private:
344 friend class ArrayNode;
345 ListRefPtr<ElementNode> next;
346 int elision;
347 RefPtr<Node> node;
348 };
349
350 class ArrayNode : public Node {
351 public:
352 ArrayNode(int e) : elision(e), opt(true) { }
353 ArrayNode(ElementNode *ele)
354 : element(ele->next.release()), elision(0), opt(false) { Parser::removeNodeCycle(element.get()); }
355 ArrayNode(int eli, ElementNode *ele)
356 : element(ele->next.release()), elision(eli), opt(true) { Parser::removeNodeCycle(element.get()); }
357 virtual OpValue generateEvalCode(CompileState* comp);
358 virtual void streamTo(SourceStream&) const;
359 virtual void recurseVisit(NodeVisitor *visitor);
360 virtual bool scanForDeclarations() const { return false; }
361 private:
362 RefPtr<ElementNode> element;
363 int elision;
364 bool opt;
365 };
366
367 class PropertyNameNode : public Node {
368 public:
369 PropertyNameNode(const Identifier &s) : str(s) { }
370 virtual void streamTo(SourceStream&) const;
371 private:
372 friend class ObjectLiteralNode;
373 Identifier str;
374 };
375
376 class PropertyNode : public Node {
377 public:
378 enum Type { Constant, Getter, Setter };
379 PropertyNode(PropertyNameNode *n, Node *a, Type t)
380 : name(n), assign(a), type(t) { }
381 virtual void streamTo(SourceStream&) const;
382 friend class PropertyListNode;
383 virtual void recurseVisit(NodeVisitor *visitor);
384 private:
385 friend class ObjectLiteralNode;
386 RefPtr<PropertyNameNode> name;
387 RefPtr<Node> assign;
388 Type type;
389 };
390
391 class PropertyListNode : public Node {
392 public:
393 // list pointer is tail of a circular list, cracked in the ObjectLiteralNode ctor
394 PropertyListNode(PropertyNode *n)
395 : node(n), next(this) { Parser::noteNodeCycle(this); }
396 PropertyListNode(PropertyNode *n, PropertyListNode *l)
397 : node(n), next(l->next) { l->next = this; }
398 virtual void streamTo(SourceStream&) const;
399 PassRefPtr<PropertyListNode> releaseNext() { return next.release(); }
400 virtual void breakCycle();
401 virtual void recurseVisit(NodeVisitor *visitor);
402 private:
403 friend class ObjectLiteralNode;
404 RefPtr<PropertyNode> node;
405 ListRefPtr<PropertyListNode> next;
406 };
407
408 class ObjectLiteralNode : public Node {
409 public:
410 ObjectLiteralNode() { }
411 ObjectLiteralNode(PropertyListNode *l) : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
412 virtual OpValue generateEvalCode(CompileState* comp);
413 virtual void streamTo(SourceStream&) const;
414 virtual void recurseVisit(NodeVisitor *visitor);
415 virtual bool scanForDeclarations() const { return false; }
416 private:
417 RefPtr<PropertyListNode> list;
418 };
419
420 class BracketAccessorNode : public LocationNode {
421 public:
422 BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
423 virtual void streamTo(SourceStream&) const;
424
425 virtual OpValue generateEvalCode(CompileState* comp);
426
427 virtual CompileReference* generateRefBind(CompileState*);
428 virtual CompileReference* generateRefRead(CompileState*, OpValue* out);
429 virtual void generateRefWrite (CompileState*,
430 CompileReference* ref, OpValue& valToStore);
431 virtual OpValue generateRefDelete(CompileState*);
432 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut);
433
434 Node *base() { return expr1.get(); }
435 Node *subscript() { return expr2.get(); }
436
437 virtual void recurseVisit(NodeVisitor *visitor);
438 protected:
439 RefPtr<Node> expr1;
440 RefPtr<Node> expr2;
441 };
442
443 class DotAccessorNode : public LocationNode {
444 public:
445 DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { }
446 virtual void streamTo(SourceStream&) const;
447
448 virtual OpValue generateEvalCode(CompileState* comp);
449
450 virtual CompileReference* generateRefBind(CompileState*);
451 virtual CompileReference* generateRefRead(CompileState*, OpValue* out);
452 virtual void generateRefWrite (CompileState*,
453 CompileReference* ref, OpValue& valToStore);
454 virtual OpValue generateRefDelete(CompileState*);
455 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut);
456
457 Node *base() const { return expr.get(); }
458 const Identifier& identifier() const { return ident; }
459
460 virtual void recurseVisit(NodeVisitor *visitor);
461 protected:
462 RefPtr<Node> expr;
463 Identifier ident;
464 };
465
466 class ArgumentListNode : public Node {
467 public:
468 // list pointer is tail of a circular list, cracked in the ArgumentsNode ctor
469 ArgumentListNode(Node *e) : next(this), expr(e) { Parser::noteNodeCycle(this); }
470 ArgumentListNode(ArgumentListNode *l, Node *e)
471 : next(l->next), expr(e) { l->next = this; }
472
473 virtual void streamTo(SourceStream&) const;
474 PassRefPtr<ArgumentListNode> releaseNext() { return next.release(); }
475 virtual void breakCycle();
476
477 virtual void recurseVisit(NodeVisitor *visitor);
478 private:
479 friend class ArgumentsNode;
480 ListRefPtr<ArgumentListNode> next;
481 RefPtr<Node> expr;
482 };
483
484 class ArgumentsNode : public Node {
485 public:
486 ArgumentsNode() { }
487 ArgumentsNode(ArgumentListNode *l)
488 : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
489
490 void generateEvalArguments(CompileState* comp);
491 virtual void streamTo(SourceStream&) const;
492
493 virtual void recurseVisit(NodeVisitor *visitor);
494 private:
495 RefPtr<ArgumentListNode> list;
496 };
497
498 class NewExprNode : public Node {
499 public:
500 NewExprNode(Node *e) : expr(e) {}
501 NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
502
503 virtual OpValue generateEvalCode(CompileState* comp);
504 virtual void streamTo(SourceStream&) const;
505 virtual void recurseVisit(NodeVisitor *visitor);
506 private:
507 RefPtr<Node> expr;
508 RefPtr<ArgumentsNode> args;
509 };
510
511 class FunctionCallValueNode : public Node {
512 public:
513 FunctionCallValueNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
514
515 virtual OpValue generateEvalCode(CompileState* comp);
516 virtual void streamTo(SourceStream&) const;
517 virtual void recurseVisit(NodeVisitor *visitor);
518 private:
519 RefPtr<Node> expr;
520 RefPtr<ArgumentsNode> args;
521 };
522
523 class FunctionCallReferenceNode : public Node {
524 public:
525 FunctionCallReferenceNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
526
527 virtual OpValue generateEvalCode(CompileState* comp);
528 virtual void streamTo(SourceStream&) const;
529 virtual void recurseVisit(NodeVisitor *visitor);
530 private:
531 RefPtr<Node> expr;
532 RefPtr<ArgumentsNode> args;
533 };
534
535 class PostfixNode : public Node {
536 public:
537 PostfixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
538
539 void streamTo(SourceStream&) const;
540 void recurseVisit(NodeVisitor * visitor);
541 virtual OpValue generateEvalCode(CompileState* comp);
542 protected:
543 RefPtr<Node> m_loc;
544 Operator m_oper;
545 };
546
547 class DeleteReferenceNode : public Node {
548 public:
549 DeleteReferenceNode(LocationNode *l) : loc(l) {}
550
551 void streamTo(SourceStream&) const;
552 void recurseVisit(NodeVisitor * visitor);
553 virtual OpValue generateEvalCode(CompileState* comp);
554 private:
555 RefPtr<LocationNode> loc;
556 };
557
558 class DeleteValueNode : public Node {
559 public:
560 DeleteValueNode(Node *e) : m_expr(e) {}
561
562 virtual void streamTo(SourceStream&) const;
563 virtual void recurseVisit(NodeVisitor *visitor);
564 virtual OpValue generateEvalCode(CompileState* comp);
565 private:
566 RefPtr<Node> m_expr;
567 };
568
569
570 class VoidNode : public Node {
571 public:
572 VoidNode(Node *e) : expr(e) {}
573
574 virtual OpValue generateEvalCode(CompileState* comp);
575 virtual void streamTo(SourceStream&) const;
576 virtual void recurseVisit(NodeVisitor *visitor);
577 private:
578 RefPtr<Node> expr;
579 };
580
581 class TypeOfVarNode : public Node {
582 public:
583 TypeOfVarNode(VarAccessNode *l) : loc(l) {}
584
585 virtual OpValue generateEvalCode(CompileState* comp);
586 void streamTo(SourceStream&) const;
587 void recurseVisit(NodeVisitor * visitor);
588 private:
589 RefPtr<VarAccessNode> loc;
590 };
591
592 class TypeOfValueNode : public Node {
593 public:
594 TypeOfValueNode(Node *e) : m_expr(e) {}
595
596 virtual OpValue generateEvalCode(CompileState* comp);
597 virtual void streamTo(SourceStream&) const;
598 virtual void recurseVisit(NodeVisitor *visitor);
599 private:
600 RefPtr<Node> m_expr;
601 };
602
603 class PrefixNode : public Node {
604 public:
605 PrefixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
606
607 virtual OpValue generateEvalCode(CompileState* comp);
608 void streamTo(SourceStream&) const;
609 void recurseVisit(NodeVisitor * visitor);
610 protected:
611 RefPtr<Node> m_loc;
612 Operator m_oper;
613 };
614
615 class UnaryPlusNode : public Node {
616 public:
617 UnaryPlusNode(Node *e) : expr(e) {}
618
619 virtual OpValue generateEvalCode(CompileState* comp);
620 virtual void streamTo(SourceStream&) const;
621 virtual void recurseVisit(NodeVisitor *visitor);
622 private:
623 RefPtr<Node> expr;
624 };
625
626 class NegateNode : public Node {
627 public:
628 NegateNode(Node *e) : expr(e) {}
629
630 virtual OpValue generateEvalCode(CompileState* comp);
631 virtual void streamTo(SourceStream&) const;
632 virtual void recurseVisit(NodeVisitor *visitor);
633 private:
634 RefPtr<Node> expr;
635 };
636
637 class BitwiseNotNode : public Node {
638 public:
639 BitwiseNotNode(Node *e) : expr(e) {}
640
641 virtual OpValue generateEvalCode(CompileState* comp);
642 virtual void streamTo(SourceStream&) const;
643 virtual void recurseVisit(NodeVisitor *visitor);
644 private:
645 RefPtr<Node> expr;
646 };
647
648 class LogicalNotNode : public Node {
649 public:
650 LogicalNotNode(Node *e) : expr(e) {}
651
652 virtual OpValue generateEvalCode(CompileState* comp);
653 virtual void streamTo(SourceStream&) const;
654 virtual void recurseVisit(NodeVisitor *visitor);
655 private:
656 RefPtr<Node> expr;
657 };
658
659 class BinaryOperatorNode : public Node {
660 public:
661 BinaryOperatorNode(Node* e1, Node* e2, Operator op)
662 : expr1(e1), expr2(e2), oper(op) {}
663
664 virtual OpValue generateEvalCode(CompileState* comp);
665 virtual void streamTo(SourceStream&) const;
666 virtual void recurseVisit(NodeVisitor* visitor);
667 private:
668 RefPtr<Node> expr1;
669 RefPtr<Node> expr2;
670 Operator oper;
671 };
672
673 /**
674 * expr1 && expr2, expr1 || expr2
675 */
676 class BinaryLogicalNode : public Node {
677 public:
678 BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
679 expr1(e1), expr2(e2), oper(o) {}
680
681 virtual OpValue generateEvalCode(CompileState* comp);
682 virtual void streamTo(SourceStream&) const;
683 virtual void recurseVisit(NodeVisitor *visitor);
684 private:
685 RefPtr<Node> expr1;
686 RefPtr<Node> expr2;
687 Operator oper;
688 };
689
690 /**
691 * The ternary operator, "logical ? expr1 : expr2"
692 */
693 class ConditionalNode : public Node {
694 public:
695 ConditionalNode(Node *l, Node *e1, Node *e2) :
696 logical(l), expr1(e1), expr2(e2) {}
697
698 virtual OpValue generateEvalCode(CompileState* comp);
699 virtual void streamTo(SourceStream&) const;
700 virtual void recurseVisit(NodeVisitor *visitor);
701 private:
702 RefPtr<Node> logical;
703 RefPtr<Node> expr1;
704 RefPtr<Node> expr2;
705 };
706
707 class AssignNode : public Node {
708 public:
709 AssignNode(Node* loc, Operator oper, Node *right)
710 : m_loc(loc), m_oper(oper), m_right(right) {}
711
712 void streamTo(SourceStream&) const;
713 virtual OpValue generateEvalCode(CompileState* comp);
714 void recurseVisit(NodeVisitor * visitor);
715 protected:
716 RefPtr<Node> m_loc;
717 Operator m_oper;
718 RefPtr<Node> m_right;
719 };
720
721 class CommaNode : public Node {
722 public:
723 CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
724
725 virtual void streamTo(SourceStream&) const;
726 virtual void recurseVisit(NodeVisitor *visitor);
727 virtual OpValue generateEvalCode(CompileState* comp);
728 private:
729 RefPtr<Node> expr1;
730 RefPtr<Node> expr2;
731 };
732
733 class AssignExprNode : public Node {
734 public:
735 AssignExprNode(Node *e) : expr(e) {}
736
737 virtual void streamTo(SourceStream&) const;
738 virtual void recurseVisit(NodeVisitor *visitor);
739 virtual OpValue generateEvalCode(CompileState* comp);
740
741 Node* getExpr() { return expr.get(); }
742 private:
743 RefPtr<Node> expr;
744 };
745
746 class VarDeclNode : public Node {
747 public:
748 enum Type { Variable, Constant };
749 VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
750
751 void generateCode(CompileState* comp);
752
753 virtual void streamTo(SourceStream&) const;
754 virtual void recurseVisit(NodeVisitor *visitor);
755
756 virtual void processVarDecl(ExecState*);
757 private:
758 friend class VarStatementNode;
759 friend class VarDeclListNode;
760 Type varType;
761 Identifier ident;
762 RefPtr<AssignExprNode> init;
763 };
764
765 class VarDeclListNode : public Node {
766 public:
767 // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
768 VarDeclListNode(VarDeclNode *v) : next(this), var(v) { Parser::noteNodeCycle(this); }
769 VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
770 : next(l->next), var(v) { l->next = this; }
771
772 virtual OpValue generateEvalCode(CompileState* comp);
773 virtual void streamTo(SourceStream&) const;
774 PassRefPtr<VarDeclListNode> releaseNext() { return next.release(); }
775 virtual void breakCycle();
776 virtual void recurseVisit(NodeVisitor *visitor);
777 private:
778 friend class ForNode;
779 friend class VarStatementNode;
780 ListRefPtr<VarDeclListNode> next;
781 RefPtr<VarDeclNode> var;
782 };
783
784 class VarStatementNode : public StatementNode {
785 public:
786 VarStatementNode(VarDeclListNode *l) : next(l->next.release()) { Parser::removeNodeCycle(next.get()); }
787
788 virtual void streamTo(SourceStream&) const;
789 virtual void recurseVisit(NodeVisitor *visitor);
790 virtual void generateExecCode(CompileState*);
791 private:
792 RefPtr<VarDeclListNode> next;
793 };
794
795 class BlockNode : public StatementNode {
796 public:
797 BlockNode(SourceElementsNode *s);
798
799 virtual void streamTo(SourceStream&) const;
800 virtual void recurseVisit(NodeVisitor *visitor);
801 virtual void generateExecCode(CompileState*);
802 protected:
803 RefPtr<SourceElementsNode> source;
804 };
805
806 class EmptyStatementNode : public StatementNode {
807 public:
808 EmptyStatementNode() { } // debug
809
810 virtual void streamTo(SourceStream&) const;
811 virtual void generateExecCode(CompileState*);
812 };
813
814 class ExprStatementNode : public StatementNode {
815 public:
816 ExprStatementNode(Node *e) : expr(e) { }
817
818 virtual void streamTo(SourceStream&) const;
819 virtual void recurseVisit(NodeVisitor *visitor);
820 virtual void generateExecCode(CompileState*);
821 private:
822 RefPtr<Node> expr;
823 };
824
825 class IfNode : public StatementNode {
826 public:
827 IfNode(Node *e, StatementNode *s1, StatementNode *s2)
828 : expr(e), statement1(s1), statement2(s2) {}
829
830 virtual void streamTo(SourceStream&) const;
831 virtual void recurseVisit(NodeVisitor *visitor);
832 virtual void generateExecCode(CompileState*);
833 private:
834 RefPtr<Node> expr;
835 RefPtr<StatementNode> statement1;
836 RefPtr<StatementNode> statement2;
837 };
838
839 class DoWhileNode : public StatementNode {
840 public:
841 DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
842
843 virtual void streamTo(SourceStream&) const;
844 virtual void recurseVisit(NodeVisitor *visitor);
845 virtual void generateExecCode(CompileState*);
846 virtual bool isIterationStatement() const { return true; }
847 private:
848 RefPtr<StatementNode> statement;
849 RefPtr<Node> expr;
850 };
851
852 class WhileNode : public StatementNode {
853 public:
854 WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
855
856 virtual void streamTo(SourceStream&) const;
857 virtual void recurseVisit(NodeVisitor *visitor);
858 virtual void generateExecCode(CompileState*);
859 virtual bool isIterationStatement() const { return true; }
860 private:
861 RefPtr<Node> expr;
862 RefPtr<StatementNode> statement;
863 };
864
865 class ForNode : public StatementNode {
866 public:
867 ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
868 expr1(e1), expr2(e2), expr3(e3), statement(s) {}
869 ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
870 expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s) { Parser::removeNodeCycle(expr1.get()); }
871
872 virtual void generateExecCode(CompileState*);
873 virtual void streamTo(SourceStream&) const;
874 virtual void recurseVisit(NodeVisitor *visitor);
875 virtual bool isIterationStatement() const { return true; }
876 private:
877 RefPtr<Node> expr1;
878 RefPtr<Node> expr2;
879 RefPtr<Node> expr3;
880 RefPtr<StatementNode> statement;
881 };
882
883 class ForInNode : public StatementNode {
884 public:
885 ForInNode(Node *l, Node *e, StatementNode *s);
886 ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
887
888 virtual void generateExecCode(CompileState*);
889 virtual void streamTo(SourceStream&) const;
890 virtual void recurseVisit(NodeVisitor *visitor);
891 virtual bool isIterationStatement() const { return true; }
892 private:
893 Identifier ident;
894 RefPtr<AssignExprNode> init;
895 RefPtr<Node> lexpr;
896 RefPtr<Node> expr;
897 RefPtr<VarDeclNode> varDecl;
898 RefPtr<StatementNode> statement;
899 };
900
901 class ContinueNode : public StatementNode {
902 public:
903 ContinueNode() : target(0) { }
904 ContinueNode(const Identifier &i) : ident(i), target(0) { }
905
906 virtual void generateExecCode(CompileState*);
907 virtual void streamTo(SourceStream&) const;
908 private:
909 Identifier ident;
910 const Node* target;
911 };
912
913 class BreakNode : public StatementNode {
914 public:
915 BreakNode() : target(0) { }
916 BreakNode(const Identifier &i) : ident(i), target(0) { }
917
918 virtual void generateExecCode(CompileState*);
919 virtual void streamTo(SourceStream&) const;
920 private:
921 Identifier ident;
922 const Node* target;
923 };
924
925 class ReturnNode : public StatementNode {
926 public:
927 ReturnNode(Node *v) : value(v) {}
928
929 virtual void generateExecCode(CompileState*);
930 virtual void streamTo(SourceStream&) const;
931 virtual void recurseVisit(NodeVisitor *visitor);
932 private:
933 RefPtr<Node> value;
934 };
935
936 class WithNode : public StatementNode {
937 public:
938 WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
939
940 virtual void generateExecCode(CompileState*);
941 virtual void streamTo(SourceStream&) const;
942 virtual void recurseVisit(NodeVisitor *visitor);
943 private:
944 RefPtr<Node> expr;
945 RefPtr<StatementNode> statement;
946 };
947
948 class LabelNode : public StatementNode {
949 public:
950 LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
951
952 virtual void streamTo(SourceStream&) const;
953 virtual void recurseVisit(NodeVisitor *visitor);
954 virtual void generateExecCode(CompileState*);
955 virtual NodeType type() const { return LabelNodeType; }
956 private:
957 Identifier label;
958 RefPtr<StatementNode> statement;
959 };
960
961 class ThrowNode : public StatementNode {
962 public:
963 ThrowNode(Node *e) : expr(e) {}
964
965 virtual void generateExecCode(CompileState*);
966 virtual void streamTo(SourceStream&) const;
967 virtual void recurseVisit(NodeVisitor *visitor);
968 private:
969 RefPtr<Node> expr;
970 };
971
972 class TryNode : public StatementNode {
973 public:
974 TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f)
975 : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
976 virtual NodeType type() const { return TryNodeType; }
977
978 virtual void generateExecCode(CompileState*);
979 virtual void streamTo(SourceStream&) const;
980 virtual void recurseVisit(NodeVisitor *visitor);
981 private:
982 RefPtr<StatementNode> tryBlock;
983 Identifier exceptionIdent;
984 RefPtr<StatementNode> catchBlock;
985 RefPtr<StatementNode> finallyBlock;
986 };
987
988 class ParameterNode : public Node {
989 public:
990 // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
991 ParameterNode(const Identifier &i) : id(i), next(this) { Parser::noteNodeCycle(this); }
992 ParameterNode(ParameterNode *next, const Identifier &i)
993 : id(i), next(next->next) { next->next = this; }
994
995 const Identifier& ident() const { return id; }
996 ParameterNode *nextParam() const { return next.get(); }
997 virtual void streamTo(SourceStream&) const;
998 PassRefPtr<ParameterNode> releaseNext() { return next.release(); }
999 virtual void breakCycle();
1000
1001 virtual void recurseVisit(NodeVisitor *visitor);
1002 private:
1003 friend class FuncDeclNode;
1004 friend class FuncExprNode;
1005 Identifier id;
1006 ListRefPtr<ParameterNode> next;
1007 };
1008
1009 // Flags about function bodies we care about for codegen
1010 enum FunctionBodyFlags {
1011 // note: neither of the two below is set for things created via
1012 // top-level, eval, or function ctor
1013 FuncFl_Decl = 1,
1014 FuncFl_Expr = 2,
1015 FuncFl_HasEvalOp = 4
1016 };
1017
1018 /**
1019 This AST node corresponds to the function body or top-level code in the AST, but is used to
1020 keep track of much of the information relevant to the whole function,
1021 such as parameter names and symbol tables. This is because there are both function
1022 declarations and expressions, so there is no natural single place to put this stuff
1023 above the body
1024
1025 inherited by ProgramNode
1026 */
1027 class FunctionBodyNode : public BlockNode {
1028 public:
1029 struct SymbolInfo {
1030 SymbolInfo(int _attr, FuncDeclNode* _funcDecl) : funcDecl(_funcDecl), attr(_attr) {}
1031 SymbolInfo() {}
1032 FuncDeclNode* funcDecl;
1033 int attr;
1034 };
1035 FunctionBodyNode(SourceElementsNode *);
1036 int sourceId() { return m_sourceId; }
1037 const UString& sourceURL() { return m_sourceURL; }
1038
1039 bool isCompiled() const { return m_compType != NotCompiled; }
1040 void compileIfNeeded(CodeType ctype, CompileType compType);
1041 void compile(CodeType ctype, CompileType compType);
1042 CompileType compileState() const { return m_compType; }
1043
1044 virtual void generateExecCode(CompileState*);
1045
1046 // Reserves a register for private use, making sure that id is in the right spot..
1047 void reserveSlot(size_t id, bool shouldMark);
1048
1049 // Symbol table functions
1050 SymbolTable& symbolTable() { return m_symbolTable; }
1051 size_t lookupSymbolID(const Identifier& id) const { return m_symbolTable.get(id.ustring().rep()); }
1052
1053 int numLocalsAndRegisters() const { return m_symbolList.size(); }
1054 SymbolInfo* getLocalInfo() { return m_symbolList.data(); }
1055
1056 size_t numFunctionLocals() const { return m_functionLocals.size(); }
1057 size_t* getFunctionLocalInfo() { return m_functionLocals.data(); }
1058
1059 // Parameter stuff. We only collect the names during the parsing/
1060 // while FunctionImp is responsible for managing the IDs.
1061 void addParam(const Identifier& ident);
1062 size_t numParams() const { return m_paramList.size(); }
1063 const Identifier& paramName(size_t pos) const { return m_paramList[pos]; }
1064
1065 void addVarDecl(const Identifier& ident, int attr, ExecState* exec);
1066 void addFunDecl(const Identifier& ident, int attr, FuncDeclNode* funcDecl);
1067
1068 // Adds a new symbol, killing any previous ID.
1069 void addSymbolOverwriteID(size_t id, const Identifier& ident, int attr);
1070
1071 // Runs the code, compiling if needed. This should only be used for non-function ExecStates
1072 Completion execute(ExecState *exec);
1073
1074 bool tearOffAtEnd() const { return m_tearOffAtEnd; }
1075
1076 const CodeBlock& code() const { return m_compiledCode; }
1077 CodeBlock& code() { return m_compiledCode; }
1078
1079 // Collection of FuncFl_* flags describing information collected about this function
1080 // during the parsing.
1081 unsigned flags() const { return m_flags; }
1082
1083 private:
1084 size_t addSymbol(const Identifier& ident, int attr, FuncDeclNode* funcDecl = 0);
1085 UString m_sourceURL;
1086 int m_sourceId : 31;
1087 bool m_tearOffAtEnd : 1;
1088 CompileType m_compType;
1089
1090 // Flags
1091 unsigned m_flags;
1092
1093 // This maps id -> attributes and function decl info
1094 WTF::Vector<SymbolInfo> m_symbolList;
1095
1096 // This contains the list of locals which contains function declarations
1097 WTF::Vector<size_t> m_functionLocals;
1098
1099 // This maps name -> id
1100 SymbolTable m_symbolTable;
1101
1102 // The list of parameter names
1103 WTF::Vector<Identifier> m_paramList;
1104
1105 CodeBlock m_compiledCode;
1106 };
1107
1108 inline void FunctionBodyNode::compileIfNeeded(CodeType ctype, CompileType compType) {
1109 if (m_compType != compType)
1110 compile(ctype, compType);
1111 }
1112
1113 class FuncExprNode : public Node {
1114 public:
1115 FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = 0)
1116 : ident(i), param(p ? p->next.release() : PassRefPtr<ParameterNode>(0)), body(b) { if (p) { Parser::removeNodeCycle(param.get()); } addParams(); }
1117
1118 virtual OpValue generateEvalCode(CompileState* comp);
1119 virtual void streamTo(SourceStream&) const;
1120 virtual void recurseVisit(NodeVisitor *visitor);
1121 virtual bool scanForDeclarations() const { return false; }
1122 private:
1123 void addParams();
1124 // Used for streamTo
1125 friend class PropertyNode;
1126 Identifier ident;
1127 RefPtr<ParameterNode> param;
1128 RefPtr<FunctionBodyNode> body;
1129 };
1130
1131 class FuncDeclNode : public StatementNode {
1132 public:
1133 FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
1134 : ident(i), body(b) { addParams(); }
1135 FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
1136 : ident(i), param(p->next.release()), body(b) { Parser::removeNodeCycle(param.get()); addParams(); }
1137
1138 virtual void generateExecCode(CompileState*);
1139 virtual void streamTo(SourceStream&) const;
1140 virtual void recurseVisit(NodeVisitor *visitor);
1141 virtual bool scanForDeclarations() const { return false; }
1142
1143 virtual void processFuncDecl(ExecState*);
1144 FunctionImp* makeFunctionObject(ExecState*);
1145 private:
1146 void addParams();
1147 Identifier ident;
1148 RefPtr<ParameterNode> param;
1149 RefPtr<FunctionBodyNode> body;
1150 };
1151
1152 // A linked list of source element nodes
1153 class SourceElementsNode : public StatementNode {
1154 public:
1155 // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1156 SourceElementsNode(StatementNode*);
1157 SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
1158
1159 virtual void generateExecCode(CompileState*);
1160 virtual void streamTo(SourceStream&) const;
1161 PassRefPtr<SourceElementsNode> releaseNext() { return next.release(); }
1162 virtual void breakCycle();
1163 virtual void recurseVisit(NodeVisitor *visitor);
1164 private:
1165 friend class BlockNode;
1166 friend class CaseClauseNode;
1167 RefPtr<StatementNode> node;
1168 ListRefPtr<SourceElementsNode> next;
1169 };
1170
1171 class CaseClauseNode : public Node {
1172 public:
1173 CaseClauseNode(Node *e) : expr(e) { }
1174 CaseClauseNode(Node *e, SourceElementsNode *s)
1175 : expr(e), source(s->next.release()) { Parser::removeNodeCycle(source.get()); }
1176
1177 virtual void streamTo(SourceStream&) const;
1178 virtual void recurseVisit(NodeVisitor *visitor);
1179 private:
1180 friend class SwitchNode;
1181 RefPtr<Node> expr;
1182 RefPtr<SourceElementsNode> source;
1183 };
1184
1185 class ClauseListNode : public Node {
1186 public:
1187 // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
1188 ClauseListNode(CaseClauseNode *c) : clause(c), next(this) { Parser::noteNodeCycle(this); }
1189 ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
1190 : clause(c), next(n->next) { n->next = this; }
1191
1192 CaseClauseNode *getClause() const { return clause.get(); }
1193 ClauseListNode *getNext() const { return next.get(); }
1194 virtual void streamTo(SourceStream&) const;
1195 PassRefPtr<ClauseListNode> releaseNext() { return next.release(); }
1196 virtual void breakCycle();
1197 virtual void recurseVisit(NodeVisitor *visitor);
1198 private:
1199 friend class SwitchNode;
1200 friend class CaseBlockNode;
1201 RefPtr<CaseClauseNode> clause;
1202 ListRefPtr<ClauseListNode> next;
1203 };
1204
1205 class CaseBlockNode : public Node {
1206 public:
1207 CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
1208
1209 virtual void streamTo(SourceStream&) const;
1210 virtual void recurseVisit(NodeVisitor *visitor);
1211 private:
1212 friend class SwitchNode;
1213 RefPtr<ClauseListNode> list1;
1214 RefPtr<CaseClauseNode> def;
1215 RefPtr<ClauseListNode> list2;
1216 };
1217
1218 class SwitchNode : public StatementNode {
1219 public:
1220 SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
1221
1222 virtual void streamTo(SourceStream&) const;
1223 virtual void recurseVisit(NodeVisitor *visitor);
1224 virtual void generateExecCode(CompileState* comp);
1225 private:
1226 RefPtr<Node> expr;
1227 RefPtr<CaseBlockNode> block;
1228 };
1229
1230 // important: these are also built when compiling things via the Function constructor
1231 // (see FunctionObjectImp::construct() and Parser::parseFunctionBody, so the existence
1232 // of this class rather than the bare FunctionBodyNode does not care much information.
1233 class ProgramNode : public FunctionBodyNode {
1234 public:
1235 ProgramNode(SourceElementsNode *s);
1236 virtual void streamTo(SourceStream&) const;
1237 };
1238
1239 class PackageNameNode : public Node {
1240 public:
1241 PackageNameNode(const Identifier &i) : names(0), id(i) { }
1242 PackageNameNode(PackageNameNode *n,
1243 const Identifier &i) : names(n), id(i) { }
1244
1245 virtual void streamTo(SourceStream&) const;
1246 virtual void recurseVisit(NodeVisitor *visitor);
1247
1248 Completion loadSymbol(ExecState* exec, bool wildcard);
1249 PackageObject* resolvePackage(ExecState* exec);
1250
1251 private:
1252 PackageObject* resolvePackage(ExecState* exec,
1253 JSObject* baseObject, Package* basePackage);
1254 RefPtr<PackageNameNode> names;
1255 Identifier id;
1256 };
1257
1258 class ImportStatement : public StatementNode {
1259 public:
1260 ImportStatement(PackageNameNode *n) : name(n), wld(false) {}
1261 void enableWildcard() { wld = true; }
1262 void setAlias(const Identifier &a) { al = a; }
1263
1264 virtual void generateExecCode(CompileState*);
1265 virtual void streamTo(SourceStream&) const;
1266 virtual void recurseVisit(NodeVisitor *visitor);
1267 private:
1268 virtual void processVarDecl (ExecState* state);
1269 RefPtr<PackageNameNode> name;
1270 Identifier al;
1271 bool wld;
1272 };
1273
1274} // namespace
1275
1276#endif
1277// kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on;
1278