fix logic
[personal-kdelibs.git] / kjs / nodes.h
blob8813e0e8fc1e725341ecbefb71abed6013f01924
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)
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.
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.
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.
26 #ifndef NODES_H_
27 #define NODES_H_
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>
40 namespace 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;
52 class VarDeclVisitor;
53 class FuncDeclVisitor;
55 class CompileState;
56 struct CompileReference;
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.
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
69 virtual Node* visit(Node* node);
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
86 Node();
87 virtual ~Node();
89 virtual NodeType type() const { return UnknownNodeType; }
91 UString toString() const;
93 // This updates line numbers to the pretty-printed version, and
94 // returns it out.
95 UString reindent(int baseLine = 0) const;
97 virtual void streamTo(SourceStream&) const = 0;
98 int lineNo() const { return m_line; }
100 void ref();
101 void deref();
102 unsigned refcount();
103 static void clearNewNodes();
105 virtual Node *nodeInsideAllParens();
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 introducesNewStaticScope () const { return false; }
115 virtual bool isIterationStatement() const { return false; }
117 virtual void breakCycle() { }
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*);
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
129 virtual void recurseVisit(NodeVisitor * /*visitor*/) {}
131 template<typename T>
132 static void recurseVisitLink(NodeVisitor* visitor, RefPtr<T>& link)
134 if (!link)
135 return;
137 T* newLink = static_cast<T*>(visitor->visit(link.get()));
138 if (newLink)
139 link = newLink;
142 template<typename T>
143 static void recurseVisitLink(NodeVisitor* visitor, ListRefPtr<T>& link)
145 if (!link)
146 return;
148 T* newLink = static_cast<T*>(visitor->visit(link.get()));
149 if (newLink)
150 link = newLink;
154 JSValue* throwError(ExecState*, ErrorType, const UString& msg);
155 JSValue* throwError(ExecState*, ErrorType, const UString& msg, const Identifier&);
156 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&);
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;
167 // disallow assignment
168 Node& operator=(const Node&);
169 Node(const Node &other);
172 class LocationNode : public Node {
173 public:
174 virtual bool isLocation() const { return true; }
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;
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;
186 // Writes to a bound reference.
187 virtual void generateRefWrite (CompileState*,
188 CompileReference* ref, OpValue& valToStore) = 0;
190 // The location nodes also handle deletes themselves. Note that this is called
191 // w/o generateRefBegin
192 virtual OpValue generateRefDelete(CompileState*) = 0;
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;
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*);
207 void generateDebugInfoIfNeeded(CompileState* comp);
209 virtual void generateExecCode(CompileState*);
210 private:
211 void generateDebugInfo(CompileState* comp);
212 mutable int m_lastLine;
215 inline void StatementNode::generateDebugInfoIfNeeded(CompileState* comp)
217 if (comp->compileType() == Debug)
218 generateDebugInfo(comp);
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;
229 class BooleanNode : public Node {
230 public:
231 BooleanNode(bool v) : val(v) {}
232 bool value() const { return val; }
234 virtual NodeType type() const { return BooleanNodeType; }
235 virtual OpValue generateEvalCode(CompileState* comp);
236 virtual void streamTo(SourceStream&) const;
237 private:
238 bool val;
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; }
247 virtual NodeType type() const { return NumberNodeType; }
248 virtual OpValue generateEvalCode(CompileState* comp);
249 virtual void streamTo(SourceStream&) const;
250 private:
251 double val;
254 class StringNode : public Node {
255 public:
256 StringNode(const UString *v) : val(*v) { }
257 UString value() const { return val; }
258 void setValue(const UString& v) { val = v; }
260 virtual NodeType type() const { return StringNodeType; }
261 virtual OpValue generateEvalCode(CompileState* comp);
262 virtual void streamTo(SourceStream&) const;
263 private:
264 UString val;
267 class RegExpNode : public Node {
268 public:
269 RegExpNode(const UString &p, const UString &f)
270 : pattern(p), flags(f) { }
271 virtual NodeType type() const { return RegExpNodeType; }
272 virtual OpValue generateEvalCode(CompileState* comp);
273 virtual void streamTo(SourceStream&) const;
274 private:
275 UString pattern, flags;
278 class ThisNode : public Node {
279 public:
280 ThisNode() {}
281 virtual OpValue generateEvalCode(CompileState* comp);
282 virtual void streamTo(SourceStream&) const;
285 class VarAccessNode : public LocationNode {
286 public:
287 VarAccessNode(const Identifier& s) : ident(s) {}
289 virtual bool isVarAccessNode() const { return true; }
290 virtual void streamTo(SourceStream&) const;
291 virtual OpValue generateEvalCode(CompileState* comp);
293 virtual CompileReference* generateRefBind(CompileState*);
294 virtual CompileReference* generateRefRead(CompileState*, OpValue* out);
295 virtual void generateRefWrite (CompileState*,
296 CompileReference* ref, OpValue& valToStore);
297 virtual OpValue generateRefDelete(CompileState*);
298 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut);
300 // This one never fails..
301 OpValue valueForTypeOf(CompileState* comp);
303 // Returns the ID this variable should be accessed as, or
304 // missingSymbolMarker(), along with the variable's classification
305 enum Classification {
306 Local, // local variable accessed by register #
307 NonLocal, // one scope above, unless local injected
308 Dynamic, // need to do a full lookup
309 Global // in the global object, if anywhere.
312 size_t classifyVariable(CompileState*, Classification& classify);
313 protected:
314 Identifier ident;
317 class GroupNode : public Node {
318 public:
319 GroupNode(Node *g) : group(g) { }
320 virtual NodeType type() const { return GroupNodeType; }
322 virtual OpValue generateEvalCode(CompileState* comp);
323 virtual Node *nodeInsideAllParens();
324 virtual void streamTo(SourceStream&) const;
325 virtual void recurseVisit(NodeVisitor *visitor);
326 private:
327 RefPtr<Node> group;
330 class ElementNode : public Node {
331 public:
332 // list pointer is tail of a circular list, cracked in the ArrayNode ctor
333 ElementNode(int e, Node *n) : next(this), elision(e), node(n) { Parser::noteNodeCycle(this); }
334 ElementNode(ElementNode *l, int e, Node *n)
335 : next(l->next), elision(e), node(n) { l->next = this; }
337 virtual void streamTo(SourceStream&) const;
338 PassRefPtr<ElementNode> releaseNext() { return next.release(); }
339 virtual void breakCycle();
340 virtual void recurseVisit(NodeVisitor *visitor);
341 private:
342 friend class ArrayNode;
343 ListRefPtr<ElementNode> next;
344 int elision;
345 RefPtr<Node> node;
348 class ArrayNode : public Node {
349 public:
350 ArrayNode(int e) : elision(e), opt(true) { }
351 ArrayNode(ElementNode *ele)
352 : element(ele->next.release()), elision(0), opt(false) { Parser::removeNodeCycle(element.get()); }
353 ArrayNode(int eli, ElementNode *ele)
354 : element(ele->next.release()), elision(eli), opt(true) { Parser::removeNodeCycle(element.get()); }
355 virtual OpValue generateEvalCode(CompileState* comp);
356 virtual void streamTo(SourceStream&) const;
357 virtual void recurseVisit(NodeVisitor *visitor);
358 private:
359 RefPtr<ElementNode> element;
360 int elision;
361 bool opt;
364 class PropertyNameNode : public Node {
365 public:
366 PropertyNameNode(const Identifier &s) : str(s) { }
367 virtual void streamTo(SourceStream&) const;
368 private:
369 friend class ObjectLiteralNode;
370 Identifier str;
373 class PropertyNode : public Node {
374 public:
375 enum Type { Constant, Getter, Setter };
376 PropertyNode(PropertyNameNode *n, Node *a, Type t)
377 : name(n), assign(a), type(t) { }
378 virtual void streamTo(SourceStream&) const;
379 friend class PropertyListNode;
380 virtual void recurseVisit(NodeVisitor *visitor);
381 private:
382 friend class ObjectLiteralNode;
383 RefPtr<PropertyNameNode> name;
384 RefPtr<Node> assign;
385 Type type;
388 class PropertyListNode : public Node {
389 public:
390 // list pointer is tail of a circular list, cracked in the ObjectLiteralNode ctor
391 PropertyListNode(PropertyNode *n)
392 : node(n), next(this) { Parser::noteNodeCycle(this); }
393 PropertyListNode(PropertyNode *n, PropertyListNode *l)
394 : node(n), next(l->next) { l->next = this; }
395 virtual void streamTo(SourceStream&) const;
396 PassRefPtr<PropertyListNode> releaseNext() { return next.release(); }
397 virtual void breakCycle();
398 virtual void recurseVisit(NodeVisitor *visitor);
399 private:
400 friend class ObjectLiteralNode;
401 RefPtr<PropertyNode> node;
402 ListRefPtr<PropertyListNode> next;
405 class ObjectLiteralNode : public Node {
406 public:
407 ObjectLiteralNode() { }
408 ObjectLiteralNode(PropertyListNode *l) : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
409 virtual OpValue generateEvalCode(CompileState* comp);
410 virtual void streamTo(SourceStream&) const;
411 virtual void recurseVisit(NodeVisitor *visitor);
412 private:
413 RefPtr<PropertyListNode> list;
416 class BracketAccessorNode : public LocationNode {
417 public:
418 BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
419 virtual void streamTo(SourceStream&) const;
421 virtual OpValue generateEvalCode(CompileState* comp);
423 virtual CompileReference* generateRefBind(CompileState*);
424 virtual CompileReference* generateRefRead(CompileState*, OpValue* out);
425 virtual void generateRefWrite (CompileState*,
426 CompileReference* ref, OpValue& valToStore);
427 virtual OpValue generateRefDelete(CompileState*);
428 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut);
430 Node *base() { return expr1.get(); }
431 Node *subscript() { return expr2.get(); }
433 virtual void recurseVisit(NodeVisitor *visitor);
434 protected:
435 RefPtr<Node> expr1;
436 RefPtr<Node> expr2;
439 class DotAccessorNode : public LocationNode {
440 public:
441 DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { }
442 virtual void streamTo(SourceStream&) const;
444 virtual OpValue generateEvalCode(CompileState* comp);
446 virtual CompileReference* generateRefBind(CompileState*);
447 virtual CompileReference* generateRefRead(CompileState*, OpValue* out);
448 virtual void generateRefWrite (CompileState*,
449 CompileReference* ref, OpValue& valToStore);
450 virtual OpValue generateRefDelete(CompileState*);
451 virtual void generateRefFunc(CompileState* comp, OpValue* funOut, OpValue* thisOut);
453 Node *base() const { return expr.get(); }
454 const Identifier& identifier() const { return ident; }
456 virtual void recurseVisit(NodeVisitor *visitor);
457 protected:
458 RefPtr<Node> expr;
459 Identifier ident;
462 class ArgumentListNode : public Node {
463 public:
464 // list pointer is tail of a circular list, cracked in the ArgumentsNode ctor
465 ArgumentListNode(Node *e) : next(this), expr(e) { Parser::noteNodeCycle(this); }
466 ArgumentListNode(ArgumentListNode *l, Node *e)
467 : next(l->next), expr(e) { l->next = this; }
469 virtual void streamTo(SourceStream&) const;
470 PassRefPtr<ArgumentListNode> releaseNext() { return next.release(); }
471 virtual void breakCycle();
473 virtual void recurseVisit(NodeVisitor *visitor);
474 private:
475 friend class ArgumentsNode;
476 ListRefPtr<ArgumentListNode> next;
477 RefPtr<Node> expr;
480 class ArgumentsNode : public Node {
481 public:
482 ArgumentsNode() { }
483 ArgumentsNode(ArgumentListNode *l)
484 : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
486 void generateEvalArguments(CompileState* comp);
487 virtual void streamTo(SourceStream&) const;
489 virtual void recurseVisit(NodeVisitor *visitor);
490 private:
491 RefPtr<ArgumentListNode> list;
494 class NewExprNode : public Node {
495 public:
496 NewExprNode(Node *e) : expr(e) {}
497 NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
499 virtual OpValue generateEvalCode(CompileState* comp);
500 virtual void streamTo(SourceStream&) const;
501 virtual void recurseVisit(NodeVisitor *visitor);
502 private:
503 RefPtr<Node> expr;
504 RefPtr<ArgumentsNode> args;
507 class FunctionCallValueNode : public Node {
508 public:
509 FunctionCallValueNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
511 virtual OpValue generateEvalCode(CompileState* comp);
512 virtual void streamTo(SourceStream&) const;
513 virtual void recurseVisit(NodeVisitor *visitor);
514 private:
515 RefPtr<Node> expr;
516 RefPtr<ArgumentsNode> args;
519 class FunctionCallReferenceNode : public Node {
520 public:
521 FunctionCallReferenceNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
523 virtual OpValue generateEvalCode(CompileState* comp);
524 virtual void streamTo(SourceStream&) const;
525 virtual void recurseVisit(NodeVisitor *visitor);
526 private:
527 RefPtr<Node> expr;
528 RefPtr<ArgumentsNode> args;
531 class PostfixNode : public Node {
532 public:
533 PostfixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
535 void streamTo(SourceStream&) const;
536 void recurseVisit(NodeVisitor * visitor);
537 virtual OpValue generateEvalCode(CompileState* comp);
538 protected:
539 RefPtr<Node> m_loc;
540 Operator m_oper;
543 class DeleteReferenceNode : public Node {
544 public:
545 DeleteReferenceNode(LocationNode *l) : loc(l) {}
547 void streamTo(SourceStream&) const;
548 void recurseVisit(NodeVisitor * visitor);
549 virtual OpValue generateEvalCode(CompileState* comp);
550 private:
551 RefPtr<LocationNode> loc;
554 class DeleteValueNode : public Node {
555 public:
556 DeleteValueNode(Node *e) : m_expr(e) {}
558 virtual void streamTo(SourceStream&) const;
559 virtual void recurseVisit(NodeVisitor *visitor);
560 virtual OpValue generateEvalCode(CompileState* comp);
561 private:
562 RefPtr<Node> m_expr;
566 class VoidNode : public Node {
567 public:
568 VoidNode(Node *e) : expr(e) {}
570 virtual OpValue generateEvalCode(CompileState* comp);
571 virtual void streamTo(SourceStream&) const;
572 virtual void recurseVisit(NodeVisitor *visitor);
573 private:
574 RefPtr<Node> expr;
577 class TypeOfVarNode : public Node {
578 public:
579 TypeOfVarNode(VarAccessNode *l) : loc(l) {}
581 virtual OpValue generateEvalCode(CompileState* comp);
582 void streamTo(SourceStream&) const;
583 void recurseVisit(NodeVisitor * visitor);
584 private:
585 RefPtr<VarAccessNode> loc;
588 class TypeOfValueNode : public Node {
589 public:
590 TypeOfValueNode(Node *e) : m_expr(e) {}
592 virtual OpValue generateEvalCode(CompileState* comp);
593 virtual void streamTo(SourceStream&) const;
594 virtual void recurseVisit(NodeVisitor *visitor);
595 private:
596 RefPtr<Node> m_expr;
599 class PrefixNode : public Node {
600 public:
601 PrefixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
603 virtual OpValue generateEvalCode(CompileState* comp);
604 void streamTo(SourceStream&) const;
605 void recurseVisit(NodeVisitor * visitor);
606 protected:
607 RefPtr<Node> m_loc;
608 Operator m_oper;
611 class UnaryPlusNode : public Node {
612 public:
613 UnaryPlusNode(Node *e) : expr(e) {}
615 virtual OpValue generateEvalCode(CompileState* comp);
616 virtual void streamTo(SourceStream&) const;
617 virtual void recurseVisit(NodeVisitor *visitor);
618 private:
619 RefPtr<Node> expr;
622 class NegateNode : public Node {
623 public:
624 NegateNode(Node *e) : expr(e) {}
626 virtual OpValue generateEvalCode(CompileState* comp);
627 virtual void streamTo(SourceStream&) const;
628 virtual void recurseVisit(NodeVisitor *visitor);
629 private:
630 RefPtr<Node> expr;
633 class BitwiseNotNode : public Node {
634 public:
635 BitwiseNotNode(Node *e) : expr(e) {}
637 virtual OpValue generateEvalCode(CompileState* comp);
638 virtual void streamTo(SourceStream&) const;
639 virtual void recurseVisit(NodeVisitor *visitor);
640 private:
641 RefPtr<Node> expr;
644 class LogicalNotNode : public Node {
645 public:
646 LogicalNotNode(Node *e) : expr(e) {}
648 virtual OpValue generateEvalCode(CompileState* comp);
649 virtual void streamTo(SourceStream&) const;
650 virtual void recurseVisit(NodeVisitor *visitor);
651 private:
652 RefPtr<Node> expr;
655 class BinaryOperatorNode : public Node {
656 public:
657 BinaryOperatorNode(Node* e1, Node* e2, Operator op)
658 : expr1(e1), expr2(e2), oper(op) {}
660 virtual OpValue generateEvalCode(CompileState* comp);
661 virtual void streamTo(SourceStream&) const;
662 virtual void recurseVisit(NodeVisitor* visitor);
663 private:
664 RefPtr<Node> expr1;
665 RefPtr<Node> expr2;
666 Operator oper;
670 * expr1 && expr2, expr1 || expr2
672 class BinaryLogicalNode : public Node {
673 public:
674 BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
675 expr1(e1), expr2(e2), oper(o) {}
677 virtual OpValue generateEvalCode(CompileState* comp);
678 virtual void streamTo(SourceStream&) const;
679 virtual void recurseVisit(NodeVisitor *visitor);
680 private:
681 RefPtr<Node> expr1;
682 RefPtr<Node> expr2;
683 Operator oper;
687 * The ternary operator, "logical ? expr1 : expr2"
689 class ConditionalNode : public Node {
690 public:
691 ConditionalNode(Node *l, Node *e1, Node *e2) :
692 logical(l), expr1(e1), expr2(e2) {}
694 virtual OpValue generateEvalCode(CompileState* comp);
695 virtual void streamTo(SourceStream&) const;
696 virtual void recurseVisit(NodeVisitor *visitor);
697 private:
698 RefPtr<Node> logical;
699 RefPtr<Node> expr1;
700 RefPtr<Node> expr2;
703 class AssignNode : public Node {
704 public:
705 AssignNode(Node* loc, Operator oper, Node *right)
706 : m_loc(loc), m_oper(oper), m_right(right) {}
708 void streamTo(SourceStream&) const;
709 virtual OpValue generateEvalCode(CompileState* comp);
710 void recurseVisit(NodeVisitor * visitor);
711 protected:
712 RefPtr<Node> m_loc;
713 Operator m_oper;
714 RefPtr<Node> m_right;
717 class CommaNode : public Node {
718 public:
719 CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
721 virtual void streamTo(SourceStream&) const;
722 virtual void recurseVisit(NodeVisitor *visitor);
723 virtual OpValue generateEvalCode(CompileState* comp);
724 private:
725 RefPtr<Node> expr1;
726 RefPtr<Node> expr2;
729 class AssignExprNode : public Node {
730 public:
731 AssignExprNode(Node *e) : expr(e) {}
733 virtual void streamTo(SourceStream&) const;
734 virtual void recurseVisit(NodeVisitor *visitor);
735 virtual OpValue generateEvalCode(CompileState* comp);
737 Node* getExpr() { return expr.get(); }
738 private:
739 RefPtr<Node> expr;
742 class VarDeclNode : public Node {
743 public:
744 enum Type { Variable, Constant };
745 VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
747 void generateCode(CompileState* comp);
749 virtual void streamTo(SourceStream&) const;
750 virtual void recurseVisit(NodeVisitor *visitor);
752 virtual void processVarDecl(ExecState*);
753 private:
754 friend class VarStatementNode;
755 friend class VarDeclListNode;
756 Type varType;
757 Identifier ident;
758 RefPtr<AssignExprNode> init;
761 class VarDeclListNode : public Node {
762 public:
763 // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
764 VarDeclListNode(VarDeclNode *v) : next(this), var(v) { Parser::noteNodeCycle(this); }
765 VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
766 : next(l->next), var(v) { l->next = this; }
768 virtual OpValue generateEvalCode(CompileState* comp);
769 virtual void streamTo(SourceStream&) const;
770 PassRefPtr<VarDeclListNode> releaseNext() { return next.release(); }
771 virtual void breakCycle();
772 virtual void recurseVisit(NodeVisitor *visitor);
773 private:
774 friend class ForNode;
775 friend class VarStatementNode;
776 ListRefPtr<VarDeclListNode> next;
777 RefPtr<VarDeclNode> var;
780 class VarStatementNode : public StatementNode {
781 public:
782 VarStatementNode(VarDeclListNode *l) : next(l->next.release()) { Parser::removeNodeCycle(next.get()); }
784 virtual void streamTo(SourceStream&) const;
785 virtual void recurseVisit(NodeVisitor *visitor);
786 virtual void generateExecCode(CompileState*);
787 private:
788 RefPtr<VarDeclListNode> next;
791 class BlockNode : public StatementNode {
792 public:
793 BlockNode(SourceElementsNode *s);
795 virtual void streamTo(SourceStream&) const;
796 virtual void recurseVisit(NodeVisitor *visitor);
797 virtual void generateExecCode(CompileState*);
798 protected:
799 RefPtr<SourceElementsNode> source;
802 class EmptyStatementNode : public StatementNode {
803 public:
804 EmptyStatementNode() { } // debug
806 virtual void streamTo(SourceStream&) const;
807 virtual void generateExecCode(CompileState*);
810 class ExprStatementNode : public StatementNode {
811 public:
812 ExprStatementNode(Node *e) : expr(e) { }
814 virtual void streamTo(SourceStream&) const;
815 virtual void recurseVisit(NodeVisitor *visitor);
816 virtual void generateExecCode(CompileState*);
817 private:
818 RefPtr<Node> expr;
821 class IfNode : public StatementNode {
822 public:
823 IfNode(Node *e, StatementNode *s1, StatementNode *s2)
824 : expr(e), statement1(s1), statement2(s2) {}
826 virtual void streamTo(SourceStream&) const;
827 virtual void recurseVisit(NodeVisitor *visitor);
828 virtual void generateExecCode(CompileState*);
829 private:
830 RefPtr<Node> expr;
831 RefPtr<StatementNode> statement1;
832 RefPtr<StatementNode> statement2;
835 class DoWhileNode : public StatementNode {
836 public:
837 DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
839 virtual void streamTo(SourceStream&) const;
840 virtual void recurseVisit(NodeVisitor *visitor);
841 virtual void generateExecCode(CompileState*);
842 virtual bool isIterationStatement() const { return true; }
843 private:
844 RefPtr<StatementNode> statement;
845 RefPtr<Node> expr;
848 class WhileNode : public StatementNode {
849 public:
850 WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
852 virtual void streamTo(SourceStream&) const;
853 virtual void recurseVisit(NodeVisitor *visitor);
854 virtual void generateExecCode(CompileState*);
855 virtual bool isIterationStatement() const { return true; }
856 private:
857 RefPtr<Node> expr;
858 RefPtr<StatementNode> statement;
861 class ForNode : public StatementNode {
862 public:
863 ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
864 expr1(e1), expr2(e2), expr3(e3), statement(s) {}
865 ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
866 expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s) { Parser::removeNodeCycle(expr1.get()); }
868 virtual void generateExecCode(CompileState*);
869 virtual void streamTo(SourceStream&) const;
870 virtual void recurseVisit(NodeVisitor *visitor);
871 virtual bool isIterationStatement() const { return true; }
872 private:
873 RefPtr<Node> expr1;
874 RefPtr<Node> expr2;
875 RefPtr<Node> expr3;
876 RefPtr<StatementNode> statement;
879 class ForInNode : public StatementNode {
880 public:
881 ForInNode(Node *l, Node *e, StatementNode *s);
882 ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
884 virtual void generateExecCode(CompileState*);
885 virtual void streamTo(SourceStream&) const;
886 virtual void recurseVisit(NodeVisitor *visitor);
887 virtual bool isIterationStatement() const { return true; }
888 private:
889 Identifier ident;
890 RefPtr<AssignExprNode> init;
891 RefPtr<Node> lexpr;
892 RefPtr<Node> expr;
893 RefPtr<VarDeclNode> varDecl;
894 RefPtr<StatementNode> statement;
897 class ContinueNode : public StatementNode {
898 public:
899 ContinueNode() : target(0) { }
900 ContinueNode(const Identifier &i) : ident(i), target(0) { }
902 virtual void generateExecCode(CompileState*);
903 virtual void streamTo(SourceStream&) const;
904 private:
905 Identifier ident;
906 const Node* target;
909 class BreakNode : public StatementNode {
910 public:
911 BreakNode() : target(0) { }
912 BreakNode(const Identifier &i) : ident(i), target(0) { }
914 virtual void generateExecCode(CompileState*);
915 virtual void streamTo(SourceStream&) const;
916 private:
917 Identifier ident;
918 const Node* target;
921 class ReturnNode : public StatementNode {
922 public:
923 ReturnNode(Node *v) : value(v) {}
925 virtual void generateExecCode(CompileState*);
926 virtual void streamTo(SourceStream&) const;
927 virtual void recurseVisit(NodeVisitor *visitor);
928 private:
929 RefPtr<Node> value;
932 class WithNode : public StatementNode {
933 public:
934 WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
936 virtual void generateExecCode(CompileState*);
937 virtual void streamTo(SourceStream&) const;
938 virtual void recurseVisit(NodeVisitor *visitor);
939 private:
940 RefPtr<Node> expr;
941 RefPtr<StatementNode> statement;
944 class LabelNode : public StatementNode {
945 public:
946 LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
948 virtual void streamTo(SourceStream&) const;
949 virtual void recurseVisit(NodeVisitor *visitor);
950 virtual void generateExecCode(CompileState*);
951 virtual NodeType type() const { return LabelNodeType; }
952 private:
953 Identifier label;
954 RefPtr<StatementNode> statement;
957 class ThrowNode : public StatementNode {
958 public:
959 ThrowNode(Node *e) : expr(e) {}
961 virtual void generateExecCode(CompileState*);
962 virtual void streamTo(SourceStream&) const;
963 virtual void recurseVisit(NodeVisitor *visitor);
964 private:
965 RefPtr<Node> expr;
968 class TryNode : public StatementNode {
969 public:
970 TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f)
971 : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
972 virtual NodeType type() const { return TryNodeType; }
974 virtual void generateExecCode(CompileState*);
975 virtual void streamTo(SourceStream&) const;
976 virtual void recurseVisit(NodeVisitor *visitor);
977 private:
978 RefPtr<StatementNode> tryBlock;
979 Identifier exceptionIdent;
980 RefPtr<StatementNode> catchBlock;
981 RefPtr<StatementNode> finallyBlock;
984 class ParameterNode : public Node {
985 public:
986 // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
987 ParameterNode(const Identifier &i) : id(i), next(this) { Parser::noteNodeCycle(this); }
988 ParameterNode(ParameterNode *next, const Identifier &i)
989 : id(i), next(next->next) { next->next = this; }
991 const Identifier& ident() const { return id; }
992 ParameterNode *nextParam() const { return next.get(); }
993 virtual void streamTo(SourceStream&) const;
994 PassRefPtr<ParameterNode> releaseNext() { return next.release(); }
995 virtual void breakCycle();
997 virtual void recurseVisit(NodeVisitor *visitor);
998 private:
999 friend class FuncDeclNode;
1000 friend class FuncExprNode;
1001 Identifier id;
1002 ListRefPtr<ParameterNode> next;
1005 // Flags about function bodies we care about for codegen
1006 enum FunctionBodyFlags {
1007 // note: neither of the two below is set for things created via
1008 // top-level, eval, or function ctor
1009 FuncFl_Decl = 1,
1010 FuncFl_Expr = 2,
1011 FuncFl_HasEvalOp = 4
1015 This AST node corresponds to the function body or top-level code in the AST, but is used to
1016 keep track of much of the information relevant to the whole function,
1017 such as parameter names and symbol tables. This is because there are both function
1018 declarations and expressions, so there is no natural single place to put this stuff
1019 above the body
1021 inherited by ProgramNode
1023 class FunctionBodyNode : public BlockNode {
1024 public:
1025 struct SymbolInfo {
1026 SymbolInfo(int _attr, FuncDeclNode* _funcDecl) : funcDecl(_funcDecl), attr(_attr) {}
1027 SymbolInfo() {}
1028 FuncDeclNode* funcDecl;
1029 int attr;
1031 FunctionBodyNode(SourceElementsNode *);
1032 int sourceId() { return m_sourceId; }
1033 const UString& sourceURL() { return m_sourceURL; }
1035 bool isCompiled() const { return m_compType != NotCompiled; }
1036 void compileIfNeeded(CodeType ctype, CompileType compType);
1037 void compile(CodeType ctype, CompileType compType);
1038 CompileType compileState() const { return m_compType; }
1040 virtual void generateExecCode(CompileState*);
1042 // Reserves a register for private use, making sure that id is in the right spot..
1043 void reserveSlot(size_t id, bool shouldMark);
1045 // Symbol table functions
1046 SymbolTable& symbolTable() { return m_symbolTable; }
1047 size_t lookupSymbolID(const Identifier& id) const { return m_symbolTable.get(id.ustring().rep()); }
1049 int numLocalsAndRegisters() const { return m_symbolList.size(); }
1050 SymbolInfo* getLocalInfo() { return m_symbolList.data(); }
1052 size_t numFunctionLocals() const { return m_functionLocals.size(); }
1053 size_t* getFunctionLocalInfo() { return m_functionLocals.data(); }
1055 // Parameter stuff. We only collect the names during the parsing/
1056 // while FunctionImp is responsible for managing the IDs.
1057 void addParam(const Identifier& ident);
1058 size_t numParams() const { return m_paramList.size(); }
1059 const Identifier& paramName(size_t pos) const { return m_paramList[pos]; }
1061 void addVarDecl(const Identifier& ident, int attr, ExecState* exec);
1062 void addFunDecl(const Identifier& ident, int attr, FuncDeclNode* funcDecl);
1064 // Adds a new symbol, killing any previous ID.
1065 void addSymbolOverwriteID(size_t id, const Identifier& ident, int attr);
1067 // Runs the code, compiling if needed. This should only be used for non-function ExecStates
1068 Completion execute(ExecState *exec);
1070 bool tearOffAtEnd() const { return m_tearOffAtEnd; }
1072 const CodeBlock& code() const { return m_compiledCode; }
1073 CodeBlock& code() { return m_compiledCode; }
1075 // Collection of FuncFl_* flags describing information collected about this function
1076 // during the parsing.
1077 unsigned flags() const { return m_flags; }
1079 private:
1080 size_t addSymbol(const Identifier& ident, int attr, FuncDeclNode* funcDecl = 0);
1081 UString m_sourceURL;
1082 int m_sourceId : 31;
1083 bool m_tearOffAtEnd : 1;
1084 CompileType m_compType;
1086 // Flags
1087 unsigned m_flags;
1089 // This maps id -> attributes and function decl info
1090 WTF::Vector<SymbolInfo> m_symbolList;
1092 // This contains the list of locals which contains function declarations
1093 WTF::Vector<size_t> m_functionLocals;
1095 // This maps name -> id
1096 SymbolTable m_symbolTable;
1098 // The list of parameter names
1099 WTF::Vector<Identifier> m_paramList;
1101 CodeBlock m_compiledCode;
1104 inline void FunctionBodyNode::compileIfNeeded(CodeType ctype, CompileType compType) {
1105 if (m_compType != compType)
1106 compile(ctype, compType);
1109 class FuncExprNode : public Node {
1110 public:
1111 FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = 0)
1112 : ident(i), param(p ? p->next.release() : PassRefPtr<ParameterNode>(0)), body(b) { if (p) { Parser::removeNodeCycle(param.get()); } addParams(); }
1114 virtual OpValue generateEvalCode(CompileState* comp);
1115 virtual void streamTo(SourceStream&) const;
1116 virtual void recurseVisit(NodeVisitor *visitor);
1117 virtual bool introducesNewStaticScope() const { return true; }
1118 private:
1119 void addParams();
1120 // Used for streamTo
1121 friend class PropertyNode;
1122 Identifier ident;
1123 RefPtr<ParameterNode> param;
1124 RefPtr<FunctionBodyNode> body;
1127 class FuncDeclNode : public StatementNode {
1128 public:
1129 FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
1130 : ident(i), body(b) { addParams(); }
1131 FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
1132 : ident(i), param(p->next.release()), body(b) { Parser::removeNodeCycle(param.get()); addParams(); }
1134 virtual void generateExecCode(CompileState*);
1135 virtual void streamTo(SourceStream&) const;
1136 virtual void recurseVisit(NodeVisitor *visitor);
1137 virtual bool introducesNewStaticScope() const { return true; }
1139 virtual void processFuncDecl(ExecState*);
1140 FunctionImp* makeFunctionObject(ExecState*);
1141 private:
1142 void addParams();
1143 Identifier ident;
1144 RefPtr<ParameterNode> param;
1145 RefPtr<FunctionBodyNode> body;
1148 // A linked list of source element nodes
1149 class SourceElementsNode : public StatementNode {
1150 public:
1151 // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1152 SourceElementsNode(StatementNode*);
1153 SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
1155 virtual void generateExecCode(CompileState*);
1156 virtual void streamTo(SourceStream&) const;
1157 PassRefPtr<SourceElementsNode> releaseNext() { return next.release(); }
1158 virtual void breakCycle();
1159 virtual void recurseVisit(NodeVisitor *visitor);
1160 private:
1161 friend class BlockNode;
1162 friend class CaseClauseNode;
1163 RefPtr<StatementNode> node;
1164 ListRefPtr<SourceElementsNode> next;
1167 class CaseClauseNode : public Node {
1168 public:
1169 CaseClauseNode(Node *e) : expr(e) { }
1170 CaseClauseNode(Node *e, SourceElementsNode *s)
1171 : expr(e), source(s->next.release()) { Parser::removeNodeCycle(source.get()); }
1173 virtual void streamTo(SourceStream&) const;
1174 virtual void recurseVisit(NodeVisitor *visitor);
1175 private:
1176 friend class SwitchNode;
1177 RefPtr<Node> expr;
1178 RefPtr<SourceElementsNode> source;
1181 class ClauseListNode : public Node {
1182 public:
1183 // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
1184 ClauseListNode(CaseClauseNode *c) : clause(c), next(this) { Parser::noteNodeCycle(this); }
1185 ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
1186 : clause(c), next(n->next) { n->next = this; }
1188 CaseClauseNode *getClause() const { return clause.get(); }
1189 ClauseListNode *getNext() const { return next.get(); }
1190 virtual void streamTo(SourceStream&) const;
1191 PassRefPtr<ClauseListNode> releaseNext() { return next.release(); }
1192 virtual void breakCycle();
1193 virtual void recurseVisit(NodeVisitor *visitor);
1194 private:
1195 friend class SwitchNode;
1196 friend class CaseBlockNode;
1197 RefPtr<CaseClauseNode> clause;
1198 ListRefPtr<ClauseListNode> next;
1201 class CaseBlockNode : public Node {
1202 public:
1203 CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
1205 virtual void streamTo(SourceStream&) const;
1206 virtual void recurseVisit(NodeVisitor *visitor);
1207 private:
1208 friend class SwitchNode;
1209 RefPtr<ClauseListNode> list1;
1210 RefPtr<CaseClauseNode> def;
1211 RefPtr<ClauseListNode> list2;
1214 class SwitchNode : public StatementNode {
1215 public:
1216 SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
1218 virtual void streamTo(SourceStream&) const;
1219 virtual void recurseVisit(NodeVisitor *visitor);
1220 virtual void generateExecCode(CompileState* comp);
1221 private:
1222 RefPtr<Node> expr;
1223 RefPtr<CaseBlockNode> block;
1226 // important: these are also built when compiling things via the Function constructor
1227 // (see FunctionObjectImp::construct() and Parser::parseFunctionBody, so the existance
1228 // of this class rather than the bare FunctionBodyNode does not care much information.
1229 class ProgramNode : public FunctionBodyNode {
1230 public:
1231 ProgramNode(SourceElementsNode *s);
1232 virtual void streamTo(SourceStream&) const;
1235 class PackageNameNode : public Node {
1236 public:
1237 PackageNameNode(const Identifier &i) : names(0), id(i) { }
1238 PackageNameNode(PackageNameNode *n,
1239 const Identifier &i) : names(n), id(i) { }
1241 virtual void streamTo(SourceStream&) const;
1242 virtual void recurseVisit(NodeVisitor *visitor);
1244 Completion loadSymbol(ExecState* exec, bool wildcard);
1245 PackageObject* resolvePackage(ExecState* exec);
1247 private:
1248 PackageObject* resolvePackage(ExecState* exec,
1249 JSObject* baseObject, Package* basePackage);
1250 RefPtr<PackageNameNode> names;
1251 Identifier id;
1254 class ImportStatement : public StatementNode {
1255 public:
1256 ImportStatement(PackageNameNode *n) : name(n), wld(false) {}
1257 void enableWildcard() { wld = true; }
1258 void setAlias(const Identifier &a) { al = a; }
1260 virtual void generateExecCode(CompileState*);
1261 virtual void streamTo(SourceStream&) const;
1262 virtual void recurseVisit(NodeVisitor *visitor);
1263 private:
1264 virtual void processVarDecl (ExecState* state);
1265 RefPtr<PackageNameNode> name;
1266 Identifier al;
1267 bool wld;
1270 } // namespace
1272 #endif
1273 // kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on;