1 // -*- c-basic-offset: 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.
31 #include "CompileState.h"
32 #include "operations.h"
33 #include "SymbolTable.h"
35 #include "bytecode/opargs.h"
36 #include <wtf/ListRefPtr.h>
37 #include <wtf/Vector.h>
42 class PropertyNameNode
;
43 class PropertyListNode
;
45 class SourceElementsNode
;
49 class FunctionBodyNode
;
53 class FuncDeclVisitor
;
56 struct CompileReference
;
60 virtual ~NodeVisitor() {}
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
);
89 virtual NodeType
type() const { return UnknownNodeType
; }
91 UString
toString() const;
93 // This updates line numbers to the pretty-printed version, and
95 UString
reindent(int baseLine
= 0) const;
97 virtual void streamTo(SourceStream
&) const = 0;
98 int lineNo() const { return m_line
; }
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*/) {}
132 static void recurseVisitLink(NodeVisitor
* visitor
, RefPtr
<T
>& link
)
137 T
* newLink
= static_cast<T
*>(visitor
->visit(link
.get()));
143 static void recurseVisitLink(NodeVisitor
* visitor
, ListRefPtr
<T
>& link
)
148 T
* newLink
= static_cast<T
*>(visitor
->visit(link
.get()));
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
);
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
{
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
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
{
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
*);
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
{
224 virtual NodeType
type() const { return NullNodeType
; }
225 virtual OpValue
generateEvalCode(CompileState
* comp
);
226 virtual void streamTo(SourceStream
&) const;
229 class BooleanNode
: public Node
{
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;
241 class NumberNode
: public Node
{
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;
254 class StringNode
: public Node
{
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;
267 class RegExpNode
: public Node
{
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;
275 UString pattern
, flags
;
278 class ThisNode
: public Node
{
281 virtual OpValue
generateEvalCode(CompileState
* comp
);
282 virtual void streamTo(SourceStream
&) const;
285 class VarAccessNode
: public LocationNode
{
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
);
317 class GroupNode
: public Node
{
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
);
330 class ElementNode
: public Node
{
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
);
342 friend class ArrayNode
;
343 ListRefPtr
<ElementNode
> next
;
348 class ArrayNode
: public Node
{
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
);
359 RefPtr
<ElementNode
> element
;
364 class PropertyNameNode
: public Node
{
366 PropertyNameNode(const Identifier
&s
) : str(s
) { }
367 virtual void streamTo(SourceStream
&) const;
369 friend class ObjectLiteralNode
;
373 class PropertyNode
: public Node
{
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
);
382 friend class ObjectLiteralNode
;
383 RefPtr
<PropertyNameNode
> name
;
388 class PropertyListNode
: public Node
{
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
);
400 friend class ObjectLiteralNode
;
401 RefPtr
<PropertyNode
> node
;
402 ListRefPtr
<PropertyListNode
> next
;
405 class ObjectLiteralNode
: public Node
{
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
);
413 RefPtr
<PropertyListNode
> list
;
416 class BracketAccessorNode
: public LocationNode
{
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
);
439 class DotAccessorNode
: public LocationNode
{
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
);
462 class ArgumentListNode
: public Node
{
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
);
475 friend class ArgumentsNode
;
476 ListRefPtr
<ArgumentListNode
> next
;
480 class ArgumentsNode
: public Node
{
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
);
491 RefPtr
<ArgumentListNode
> list
;
494 class NewExprNode
: public Node
{
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
);
504 RefPtr
<ArgumentsNode
> args
;
507 class FunctionCallValueNode
: public Node
{
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
);
516 RefPtr
<ArgumentsNode
> args
;
519 class FunctionCallReferenceNode
: public Node
{
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
);
528 RefPtr
<ArgumentsNode
> args
;
531 class PostfixNode
: public Node
{
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
);
543 class DeleteReferenceNode
: public Node
{
545 DeleteReferenceNode(LocationNode
*l
) : loc(l
) {}
547 void streamTo(SourceStream
&) const;
548 void recurseVisit(NodeVisitor
* visitor
);
549 virtual OpValue
generateEvalCode(CompileState
* comp
);
551 RefPtr
<LocationNode
> loc
;
554 class DeleteValueNode
: public Node
{
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
);
566 class VoidNode
: public Node
{
568 VoidNode(Node
*e
) : expr(e
) {}
570 virtual OpValue
generateEvalCode(CompileState
* comp
);
571 virtual void streamTo(SourceStream
&) const;
572 virtual void recurseVisit(NodeVisitor
*visitor
);
577 class TypeOfVarNode
: public Node
{
579 TypeOfVarNode(VarAccessNode
*l
) : loc(l
) {}
581 virtual OpValue
generateEvalCode(CompileState
* comp
);
582 void streamTo(SourceStream
&) const;
583 void recurseVisit(NodeVisitor
* visitor
);
585 RefPtr
<VarAccessNode
> loc
;
588 class TypeOfValueNode
: public Node
{
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
);
599 class PrefixNode
: public Node
{
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
);
611 class UnaryPlusNode
: public Node
{
613 UnaryPlusNode(Node
*e
) : expr(e
) {}
615 virtual OpValue
generateEvalCode(CompileState
* comp
);
616 virtual void streamTo(SourceStream
&) const;
617 virtual void recurseVisit(NodeVisitor
*visitor
);
622 class NegateNode
: public Node
{
624 NegateNode(Node
*e
) : expr(e
) {}
626 virtual OpValue
generateEvalCode(CompileState
* comp
);
627 virtual void streamTo(SourceStream
&) const;
628 virtual void recurseVisit(NodeVisitor
*visitor
);
633 class BitwiseNotNode
: public Node
{
635 BitwiseNotNode(Node
*e
) : expr(e
) {}
637 virtual OpValue
generateEvalCode(CompileState
* comp
);
638 virtual void streamTo(SourceStream
&) const;
639 virtual void recurseVisit(NodeVisitor
*visitor
);
644 class LogicalNotNode
: public Node
{
646 LogicalNotNode(Node
*e
) : expr(e
) {}
648 virtual OpValue
generateEvalCode(CompileState
* comp
);
649 virtual void streamTo(SourceStream
&) const;
650 virtual void recurseVisit(NodeVisitor
*visitor
);
655 class BinaryOperatorNode
: public Node
{
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
);
670 * expr1 && expr2, expr1 || expr2
672 class BinaryLogicalNode
: public Node
{
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
);
687 * The ternary operator, "logical ? expr1 : expr2"
689 class ConditionalNode
: public Node
{
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
);
698 RefPtr
<Node
> logical
;
703 class AssignNode
: public Node
{
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
);
714 RefPtr
<Node
> m_right
;
717 class CommaNode
: public Node
{
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
);
729 class AssignExprNode
: public Node
{
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(); }
742 class VarDeclNode
: public Node
{
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
*);
754 friend class VarStatementNode
;
755 friend class VarDeclListNode
;
758 RefPtr
<AssignExprNode
> init
;
761 class VarDeclListNode
: public Node
{
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
);
774 friend class ForNode
;
775 friend class VarStatementNode
;
776 ListRefPtr
<VarDeclListNode
> next
;
777 RefPtr
<VarDeclNode
> var
;
780 class VarStatementNode
: public StatementNode
{
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
*);
788 RefPtr
<VarDeclListNode
> next
;
791 class BlockNode
: public StatementNode
{
793 BlockNode(SourceElementsNode
*s
);
795 virtual void streamTo(SourceStream
&) const;
796 virtual void recurseVisit(NodeVisitor
*visitor
);
797 virtual void generateExecCode(CompileState
*);
799 RefPtr
<SourceElementsNode
> source
;
802 class EmptyStatementNode
: public StatementNode
{
804 EmptyStatementNode() { } // debug
806 virtual void streamTo(SourceStream
&) const;
807 virtual void generateExecCode(CompileState
*);
810 class ExprStatementNode
: public StatementNode
{
812 ExprStatementNode(Node
*e
) : expr(e
) { }
814 virtual void streamTo(SourceStream
&) const;
815 virtual void recurseVisit(NodeVisitor
*visitor
);
816 virtual void generateExecCode(CompileState
*);
821 class IfNode
: public StatementNode
{
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
*);
831 RefPtr
<StatementNode
> statement1
;
832 RefPtr
<StatementNode
> statement2
;
835 class DoWhileNode
: public StatementNode
{
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; }
844 RefPtr
<StatementNode
> statement
;
848 class WhileNode
: public StatementNode
{
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; }
858 RefPtr
<StatementNode
> statement
;
861 class ForNode
: public StatementNode
{
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; }
876 RefPtr
<StatementNode
> statement
;
879 class ForInNode
: public StatementNode
{
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; }
890 RefPtr
<AssignExprNode
> init
;
893 RefPtr
<VarDeclNode
> varDecl
;
894 RefPtr
<StatementNode
> statement
;
897 class ContinueNode
: public StatementNode
{
899 ContinueNode() : target(0) { }
900 ContinueNode(const Identifier
&i
) : ident(i
), target(0) { }
902 virtual void generateExecCode(CompileState
*);
903 virtual void streamTo(SourceStream
&) const;
909 class BreakNode
: public StatementNode
{
911 BreakNode() : target(0) { }
912 BreakNode(const Identifier
&i
) : ident(i
), target(0) { }
914 virtual void generateExecCode(CompileState
*);
915 virtual void streamTo(SourceStream
&) const;
921 class ReturnNode
: public StatementNode
{
923 ReturnNode(Node
*v
) : value(v
) {}
925 virtual void generateExecCode(CompileState
*);
926 virtual void streamTo(SourceStream
&) const;
927 virtual void recurseVisit(NodeVisitor
*visitor
);
932 class WithNode
: public StatementNode
{
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
);
941 RefPtr
<StatementNode
> statement
;
944 class LabelNode
: public StatementNode
{
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
; }
954 RefPtr
<StatementNode
> statement
;
957 class ThrowNode
: public StatementNode
{
959 ThrowNode(Node
*e
) : expr(e
) {}
961 virtual void generateExecCode(CompileState
*);
962 virtual void streamTo(SourceStream
&) const;
963 virtual void recurseVisit(NodeVisitor
*visitor
);
968 class TryNode
: public StatementNode
{
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
);
978 RefPtr
<StatementNode
> tryBlock
;
979 Identifier exceptionIdent
;
980 RefPtr
<StatementNode
> catchBlock
;
981 RefPtr
<StatementNode
> finallyBlock
;
984 class ParameterNode
: public Node
{
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
);
999 friend class FuncDeclNode
;
1000 friend class FuncExprNode
;
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
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
1021 inherited by ProgramNode
1023 class FunctionBodyNode
: public BlockNode
{
1026 SymbolInfo(int _attr
, FuncDeclNode
* _funcDecl
) : funcDecl(_funcDecl
), attr(_attr
) {}
1028 FuncDeclNode
* funcDecl
;
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
; }
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
;
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
{
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; }
1120 // Used for streamTo
1121 friend class PropertyNode
;
1123 RefPtr
<ParameterNode
> param
;
1124 RefPtr
<FunctionBodyNode
> body
;
1127 class FuncDeclNode
: public StatementNode
{
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
*);
1144 RefPtr
<ParameterNode
> param
;
1145 RefPtr
<FunctionBodyNode
> body
;
1148 // A linked list of source element nodes
1149 class SourceElementsNode
: public StatementNode
{
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
);
1161 friend class BlockNode
;
1162 friend class CaseClauseNode
;
1163 RefPtr
<StatementNode
> node
;
1164 ListRefPtr
<SourceElementsNode
> next
;
1167 class CaseClauseNode
: public Node
{
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
);
1176 friend class SwitchNode
;
1178 RefPtr
<SourceElementsNode
> source
;
1181 class ClauseListNode
: public Node
{
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
);
1195 friend class SwitchNode
;
1196 friend class CaseBlockNode
;
1197 RefPtr
<CaseClauseNode
> clause
;
1198 ListRefPtr
<ClauseListNode
> next
;
1201 class CaseBlockNode
: public Node
{
1203 CaseBlockNode(ClauseListNode
*l1
, CaseClauseNode
*d
, ClauseListNode
*l2
);
1205 virtual void streamTo(SourceStream
&) const;
1206 virtual void recurseVisit(NodeVisitor
*visitor
);
1208 friend class SwitchNode
;
1209 RefPtr
<ClauseListNode
> list1
;
1210 RefPtr
<CaseClauseNode
> def
;
1211 RefPtr
<ClauseListNode
> list2
;
1214 class SwitchNode
: public StatementNode
{
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
);
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
{
1231 ProgramNode(SourceElementsNode
*s
);
1232 virtual void streamTo(SourceStream
&) const;
1235 class PackageNameNode
: public Node
{
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
);
1248 PackageObject
* resolvePackage(ExecState
* exec
,
1249 JSObject
* baseObject
, Package
* basePackage
);
1250 RefPtr
<PackageNameNode
> names
;
1254 class ImportStatement
: public StatementNode
{
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
);
1264 virtual void processVarDecl (ExecState
* state
);
1265 RefPtr
<PackageNameNode
> name
;
1273 // kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on;