File indexing completed on 2024-05-12 15:43:28

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
0004  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
0005  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
0006  *  Copyright (C) 2007, 2008 Maksim Orlovich (maksim@kde.org)
0007  *
0008  *  This library is free software; you can redistribute it and/or
0009  *  modify it under the terms of the GNU Library General Public
0010  *  License as published by the Free Software Foundation; either
0011  *  version 2 of the License, or (at your option) any later version.
0012  *
0013  *  This library is distributed in the hope that it will be useful,
0014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  *  Library General Public License for more details.
0017  *
0018  *  You should have received a copy of the GNU Library General Public License
0019  *  along with this library; see the file COPYING.LIB.  If not, write to
0020  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  *  Boston, MA 02110-1301, USA.
0022  *
0023  */
0024 
0025 #ifndef NODES_H_
0026 #define NODES_H_
0027 
0028 #include "Parser.h"
0029 #include "internal.h"
0030 #include "CompileState.h"
0031 #include "operations.h"
0032 #include "SymbolTable.h"
0033 #include "opcodes.h"
0034 #include "bytecode/opargs.h"
0035 #include <wtf/ListRefPtr.h>
0036 #include <wtf/Vector.h>
0037 
0038 namespace KJS
0039 {
0040 class ProgramNode;
0041 class PropertyNameNode;
0042 class PropertyListNode;
0043 class RegExp;
0044 class SourceElementsNode;
0045 class SourceStream;
0046 class PackageObject;
0047 class FuncDeclNode;
0048 class FunctionBodyNode;
0049 class Node;
0050 
0051 class VarDeclVisitor;
0052 class FuncDeclVisitor;
0053 
0054 class CompileState;
0055 struct CompileReference;
0056 
0057 class NodeVisitor
0058 {
0059 public:
0060     virtual ~NodeVisitor() {}
0061     /**
0062      This method should be overridden by subclasses to process nodes, and
0063      perhaps return pointers for replacement nodes. If the node should not be
0064      changed, return 0. Otherwise, return the replacement node.
0065 
0066      The default implementation asks the node to visit its kids, and do
0067      replacements on them if needed, but does not change anything for this node
0068     */
0069     virtual Node *visit(Node *node);
0070 };
0071 
0072 class Node
0073 {
0074 public:
0075     enum NodeType {
0076         UnknownNodeType,
0077         NullNodeType,
0078         BooleanNodeType,
0079         NumberNodeType,
0080         StringNodeType,
0081         RegExpNodeType,
0082         TryNodeType,
0083         GroupNodeType,
0084         LabelNodeType
0085     };
0086 
0087     Node();
0088     virtual ~Node();
0089 
0090     virtual NodeType type() const
0091     {
0092         return UnknownNodeType;
0093     }
0094 
0095     UString toString() const;
0096 
0097     // This updates line numbers to the pretty-printed version, and
0098     // returns it out.
0099     UString reindent(int baseLine = 0) const;
0100 
0101     virtual void streamTo(SourceStream &) const = 0;
0102     int lineNo() const
0103     {
0104         return m_line;
0105     }
0106 
0107     void ref();
0108     void deref();
0109     unsigned refcount();
0110     static void clearNewNodes();
0111 
0112     virtual Node *nodeInsideAllParens();
0113 
0114     virtual bool isLocation() const
0115     {
0116         return false;
0117     }
0118     virtual bool isVarAccessNode() const
0119     {
0120         return false;
0121     }
0122     bool isNumber() const
0123     {
0124         return type() == NumberNodeType;
0125     }
0126     bool isString() const
0127     {
0128         return type() == StringNodeType;
0129     }
0130     bool isGroupNode() const
0131     {
0132         return type() == GroupNodeType;
0133     }
0134     bool isTryNode() const
0135     {
0136         return type() == TryNodeType;
0137     }
0138     bool isLabelNode() const
0139     {
0140         return type() == LabelNodeType;
0141     }
0142     virtual bool scanForDeclarations() const
0143     {
0144         return true;
0145     }
0146     virtual bool isIterationStatement()      const
0147     {
0148         return false;
0149     }
0150 
0151     virtual void breakCycle() { }
0152 
0153     // Processes all function and variable declarations below this node,
0154     // adding them to symbol table or the current object depending on the
0155     // execution context..
0156     void processDecls(ExecState *);
0157 
0158     /*
0159       Implementations of this method should call visitor->visit on all the
0160       children nodes, and if they return value is non-0, update the link to the child.
0161       The recurseVisitLink helper takes care of this
0162     */
0163     virtual void recurseVisit(NodeVisitor * /*visitor*/) {}
0164 
0165     template<typename T>
0166     static void recurseVisitLink(NodeVisitor *visitor, RefPtr<T> &link)
0167     {
0168         if (!link) {
0169             return;
0170         }
0171 
0172         T *newLink = static_cast<T *>(visitor->visit(link.get()));
0173         if (newLink) {
0174             link = newLink;
0175         }
0176     }
0177 
0178     template<typename T>
0179     static void recurseVisitLink(NodeVisitor *visitor, ListRefPtr<T> &link)
0180     {
0181         if (!link) {
0182             return;
0183         }
0184 
0185         T *newLink = static_cast<T *>(visitor->visit(link.get()));
0186         if (newLink) {
0187             link = newLink;
0188         }
0189     }
0190 
0191     JSValue *throwError(ExecState *, ErrorType, const UString &msg);
0192     JSValue *throwError(ExecState *, ErrorType, const UString &msg, const Identifier &);
0193     JSValue *throwUndefinedVariableError(ExecState *, const Identifier &);
0194 
0195     virtual OpValue generateEvalCode(CompileState *comp);
0196 protected:
0197     mutable int m_line;
0198 private:
0199     virtual void processVarDecl(ExecState *state);
0200     virtual void processFuncDecl(ExecState *state);
0201     friend class VarDeclVisitor;
0202     friend class FuncDeclVisitor;
0203 
0204     // disallow assignment
0205     Node &operator=(const Node &);
0206     Node(const Node &other);
0207 };
0208 
0209 class LocationNode : public Node
0210 {
0211 public:
0212     bool isLocation() const override
0213     {
0214         return true;
0215     }
0216 
0217     // For assignments, we need to conceptually evaluate the LHS to a reference before looking at the RHS
0218     // generateRefBind corresponds to that action. It never issues an error. The returned
0219     // reference should be passed to generateRefWrite when needed
0220     virtual CompileReference *generateRefBind(CompileState *) = 0;
0221 
0222     // When we are doing a read-modify-write style op, or just plain read, we want to do a read
0223     // right after the binding. This does that, and returns a reference for use of follow up
0224     // writes.
0225     virtual CompileReference *generateRefRead(CompileState *, OpValue *out) = 0;
0226 
0227     // Writes to a bound reference.
0228     virtual void generateRefWrite(CompileState *,
0229                                   CompileReference *ref, OpValue &valToStore) = 0;
0230 
0231     // The location nodes also handle deletes themselves. Note that this is called
0232     // w/o generateRefBegin
0233     virtual OpValue generateRefDelete(CompileState *) = 0;
0234 
0235     // For function calls, we also do a specialized lookup, getting both the value and the
0236     // scope/this, also making sure it's not an activation.
0237     virtual void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) = 0;
0238 };
0239 
0240 class StatementNode : public Node
0241 {
0242 public:
0243     StatementNode();
0244     void setLoc(int line0, int line1) const;
0245     int firstLine() const
0246     {
0247         return lineNo();
0248     }
0249     int lastLine() const
0250     {
0251         return m_lastLine;
0252     }
0253     void hitStatement(ExecState *);
0254 
0255     void generateDebugInfoIfNeeded(CompileState *comp);
0256 
0257     virtual void generateExecCode(CompileState *);
0258 private:
0259     void generateDebugInfo(CompileState *comp);
0260     mutable int m_lastLine;
0261 };
0262 
0263 inline void StatementNode::generateDebugInfoIfNeeded(CompileState *comp)
0264 {
0265     if (comp->compileType() == Debug) {
0266         generateDebugInfo(comp);
0267     }
0268 }
0269 
0270 class NullNode : public Node
0271 {
0272 public:
0273     NullNode() {}
0274     NodeType type() const override
0275     {
0276         return NullNodeType;
0277     }
0278     OpValue generateEvalCode(CompileState *comp) override;
0279     void streamTo(SourceStream &) const override;
0280 };
0281 
0282 class BooleanNode : public Node
0283 {
0284 public:
0285     BooleanNode(bool v) : val(v) {}
0286     bool value() const
0287     {
0288         return val;
0289     }
0290 
0291     NodeType type() const override
0292     {
0293         return BooleanNodeType;
0294     }
0295     OpValue generateEvalCode(CompileState *comp) override;
0296     void streamTo(SourceStream &) const override;
0297 private:
0298     bool val;
0299 };
0300 
0301 class NumberNode : public Node
0302 {
0303 public:
0304     NumberNode(double v) : val(v) {}
0305     double value() const
0306     {
0307         return val;
0308     }
0309     void setValue(double v)
0310     {
0311         val = v;
0312     }
0313 
0314     NodeType type() const override
0315     {
0316         return NumberNodeType;
0317     }
0318     OpValue generateEvalCode(CompileState *comp) override;
0319     void streamTo(SourceStream &) const override;
0320 private:
0321     double val;
0322 };
0323 
0324 class StringNode : public Node
0325 {
0326 public:
0327     StringNode(const UString *v) : val(*v), interned(nullptr) { }
0328     ~StringNode() override; // in nodes2bytecode.cpp
0329     UString value() const
0330     {
0331         return val;
0332     }
0333     void setValue(const UString &v)
0334     {
0335         val = v;
0336     }
0337 
0338     NodeType type() const override
0339     {
0340         return StringNodeType;
0341     }
0342     OpValue generateEvalCode(CompileState *comp) override;
0343     void streamTo(SourceStream &) const override;
0344 private:
0345     UString val;
0346     StringImp *interned;
0347 };
0348 
0349 class RegExpNode : public Node
0350 {
0351 public:
0352     RegExpNode(const UString &p, const UString &f)
0353         : pattern(p), flags(f) { }
0354     NodeType type() const override
0355     {
0356         return RegExpNodeType;
0357     }
0358     OpValue generateEvalCode(CompileState *comp) override;
0359     void streamTo(SourceStream &) const override;
0360 private:
0361     UString pattern, flags;
0362 };
0363 
0364 class ThisNode : public Node
0365 {
0366 public:
0367     ThisNode() {}
0368     OpValue generateEvalCode(CompileState *comp) override;
0369     void streamTo(SourceStream &) const override;
0370 };
0371 
0372 class VarAccessNode : public LocationNode
0373 {
0374 public:
0375     VarAccessNode(const Identifier &s) : ident(s) {}
0376 
0377     bool isVarAccessNode() const override
0378     {
0379         return true;
0380     }
0381     void streamTo(SourceStream &) const override;
0382     OpValue generateEvalCode(CompileState *comp) override;
0383 
0384     CompileReference *generateRefBind(CompileState *) override;
0385     CompileReference *generateRefRead(CompileState *, OpValue *out) override;
0386     void generateRefWrite(CompileState *,
0387                                   CompileReference *ref, OpValue &valToStore) override;
0388     OpValue generateRefDelete(CompileState *) override;
0389     void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) override;
0390 
0391     // This one never fails..
0392     OpValue valueForTypeOf(CompileState *comp);
0393 
0394     // Returns the ID this variable should be accessed as, or
0395     // missingSymbolMarker(), along with the variable's classification
0396     enum Classification {
0397         Local,      // local variable accessed by register #
0398         NonLocal,    // one scope above, unless local injected
0399         Dynamic,    // need to do a full lookup
0400         Global      // in the global object, if anywhere.
0401     };
0402 
0403     size_t classifyVariable(CompileState *, Classification &classify);
0404 protected:
0405     Identifier ident;
0406 };
0407 
0408 class GroupNode : public Node
0409 {
0410 public:
0411     GroupNode(Node *g) : group(g) { }
0412     NodeType type() const override
0413     {
0414         return GroupNodeType;
0415     }
0416 
0417     OpValue generateEvalCode(CompileState *comp) override;
0418     Node *nodeInsideAllParens() override;
0419     void streamTo(SourceStream &) const override;
0420     void recurseVisit(NodeVisitor *visitor) override;
0421 private:
0422     RefPtr<Node> group;
0423 };
0424 
0425 class ElementNode : public Node
0426 {
0427 public:
0428     // list pointer is tail of a circular list, cracked in the ArrayNode ctor
0429     ElementNode(int e, Node *n) : next(this), elision(e), node(n)
0430     {
0431         Parser::noteNodeCycle(this);
0432     }
0433     ElementNode(ElementNode *l, int e, Node *n)
0434         : next(l->next), elision(e), node(n)
0435     {
0436         l->next = this;
0437     }
0438 
0439     void streamTo(SourceStream &) const override;
0440     PassRefPtr<ElementNode> releaseNext()
0441     {
0442         return next.release();
0443     }
0444     void breakCycle() override;
0445     void recurseVisit(NodeVisitor *visitor) override;
0446 private:
0447     friend class ArrayNode;
0448     ListRefPtr<ElementNode> next;
0449     int elision;
0450     RefPtr<Node> node;
0451 };
0452 
0453 class ArrayNode : public Node
0454 {
0455 public:
0456     ArrayNode(int e) : elision(e), opt(true) { }
0457     ArrayNode(ElementNode *ele)
0458         : element(ele->next.release()), elision(0), opt(false)
0459     {
0460         Parser::removeNodeCycle(element.get());
0461     }
0462     ArrayNode(int eli, ElementNode *ele)
0463         : element(ele->next.release()), elision(eli), opt(true)
0464     {
0465         Parser::removeNodeCycle(element.get());
0466     }
0467     OpValue generateEvalCode(CompileState *comp) override;
0468     void streamTo(SourceStream &) const override;
0469     void recurseVisit(NodeVisitor *visitor) override;
0470     bool scanForDeclarations() const override
0471     {
0472         return false;
0473     }
0474 private:
0475     RefPtr<ElementNode> element;
0476     int elision;
0477     bool opt;
0478 };
0479 
0480 class PropertyNameNode : public Node
0481 {
0482 public:
0483     PropertyNameNode(const Identifier &s) : str(s) { }
0484     void streamTo(SourceStream &) const override;
0485 private:
0486     friend class ObjectLiteralNode;
0487     Identifier str;
0488 };
0489 
0490 class PropertyNode : public Node
0491 {
0492 public:
0493     enum Type { Constant, Getter, Setter };
0494     PropertyNode(PropertyNameNode *n, Node *a, Type t)
0495         : name(n), assign(a), type(t) { }
0496     void streamTo(SourceStream &) const override;
0497     friend class PropertyListNode;
0498     void recurseVisit(NodeVisitor *visitor) override;
0499 private:
0500     friend class ObjectLiteralNode;
0501     RefPtr<PropertyNameNode> name;
0502     RefPtr<Node> assign;
0503     Type type;
0504 };
0505 
0506 class PropertyListNode : public Node
0507 {
0508 public:
0509     // list pointer is tail of a circular list, cracked in the ObjectLiteralNode ctor
0510     PropertyListNode(PropertyNode *n)
0511         : node(n), next(this)
0512     {
0513         Parser::noteNodeCycle(this);
0514     }
0515     PropertyListNode(PropertyNode *n, PropertyListNode *l)
0516         : node(n), next(l->next)
0517     {
0518         l->next = this;
0519     }
0520     void streamTo(SourceStream &) const override;
0521     PassRefPtr<PropertyListNode> releaseNext()
0522     {
0523         return next.release();
0524     }
0525     void breakCycle() override;
0526     void recurseVisit(NodeVisitor *visitor) override;
0527 private:
0528     friend class ObjectLiteralNode;
0529     RefPtr<PropertyNode> node;
0530     ListRefPtr<PropertyListNode> next;
0531 };
0532 
0533 class ObjectLiteralNode : public Node
0534 {
0535 public:
0536     ObjectLiteralNode() { }
0537     ObjectLiteralNode(PropertyListNode *l) : list(l->next.release())
0538     {
0539         Parser::removeNodeCycle(list.get());
0540     }
0541     OpValue generateEvalCode(CompileState *comp) override;
0542     void streamTo(SourceStream &) const override;
0543     void recurseVisit(NodeVisitor *visitor) override;
0544     bool scanForDeclarations() const override
0545     {
0546         return false;
0547     }
0548 private:
0549     RefPtr<PropertyListNode> list;
0550 };
0551 
0552 class BracketAccessorNode : public LocationNode
0553 {
0554 public:
0555     BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
0556     void streamTo(SourceStream &) const override;
0557 
0558     OpValue generateEvalCode(CompileState *comp) override;
0559 
0560     CompileReference *generateRefBind(CompileState *) override;
0561     CompileReference *generateRefRead(CompileState *, OpValue *out) override;
0562     void generateRefWrite(CompileState *,
0563                                   CompileReference *ref, OpValue &valToStore) override;
0564     OpValue generateRefDelete(CompileState *) override;
0565     void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) override;
0566 
0567     Node *base()
0568     {
0569         return expr1.get();
0570     }
0571     Node *subscript()
0572     {
0573         return expr2.get();
0574     }
0575 
0576     void recurseVisit(NodeVisitor *visitor) override;
0577 protected:
0578     RefPtr<Node> expr1;
0579     RefPtr<Node> expr2;
0580 };
0581 
0582 class DotAccessorNode : public LocationNode
0583 {
0584 public:
0585     DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { }
0586     void streamTo(SourceStream &) const override;
0587 
0588     OpValue generateEvalCode(CompileState *comp) override;
0589 
0590     CompileReference *generateRefBind(CompileState *) override;
0591     CompileReference *generateRefRead(CompileState *, OpValue *out) override;
0592     void generateRefWrite(CompileState *,
0593                                   CompileReference *ref, OpValue &valToStore) override;
0594     OpValue generateRefDelete(CompileState *) override;
0595     void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) override;
0596 
0597     Node *base() const
0598     {
0599         return expr.get();
0600     }
0601     const Identifier &identifier() const
0602     {
0603         return ident;
0604     }
0605 
0606     void recurseVisit(NodeVisitor *visitor) override;
0607 protected:
0608     RefPtr<Node> expr;
0609     Identifier ident;
0610 };
0611 
0612 class ArgumentListNode : public Node
0613 {
0614 public:
0615     // list pointer is tail of a circular list, cracked in the ArgumentsNode ctor
0616     ArgumentListNode(Node *e) : next(this), expr(e)
0617     {
0618         Parser::noteNodeCycle(this);
0619     }
0620     ArgumentListNode(ArgumentListNode *l, Node *e)
0621         : next(l->next), expr(e)
0622     {
0623         l->next = this;
0624     }
0625 
0626     void streamTo(SourceStream &) const override;
0627     PassRefPtr<ArgumentListNode> releaseNext()
0628     {
0629         return next.release();
0630     }
0631     void breakCycle() override;
0632 
0633     void recurseVisit(NodeVisitor *visitor) override;
0634 private:
0635     friend class ArgumentsNode;
0636     ListRefPtr<ArgumentListNode> next;
0637     RefPtr<Node> expr;
0638 };
0639 
0640 class ArgumentsNode : public Node
0641 {
0642 public:
0643     ArgumentsNode() { }
0644     ArgumentsNode(ArgumentListNode *l)
0645         : list(l->next.release())
0646     {
0647         Parser::removeNodeCycle(list.get());
0648     }
0649 
0650     void generateEvalArguments(CompileState *comp);
0651     void streamTo(SourceStream &) const override;
0652 
0653     void recurseVisit(NodeVisitor *visitor) override;
0654 private:
0655     RefPtr<ArgumentListNode> list;
0656 };
0657 
0658 class NewExprNode : public Node
0659 {
0660 public:
0661     NewExprNode(Node *e) : expr(e) {}
0662     NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
0663 
0664     OpValue generateEvalCode(CompileState *comp) override;
0665     void streamTo(SourceStream &) const override;
0666     void recurseVisit(NodeVisitor *visitor) override;
0667 private:
0668     RefPtr<Node> expr;
0669     RefPtr<ArgumentsNode> args;
0670 };
0671 
0672 class FunctionCallValueNode : public Node
0673 {
0674 public:
0675     FunctionCallValueNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
0676 
0677     OpValue generateEvalCode(CompileState *comp) override;
0678     void streamTo(SourceStream &) const override;
0679     void recurseVisit(NodeVisitor *visitor) override;
0680 private:
0681     RefPtr<Node> expr;
0682     RefPtr<ArgumentsNode> args;
0683 };
0684 
0685 class FunctionCallReferenceNode : public Node
0686 {
0687 public:
0688     FunctionCallReferenceNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
0689 
0690     OpValue generateEvalCode(CompileState *comp) override;
0691     void streamTo(SourceStream &) const override;
0692     void recurseVisit(NodeVisitor *visitor) override;
0693 private:
0694     RefPtr<Node> expr;
0695     RefPtr<ArgumentsNode> args;
0696 };
0697 
0698 class PostfixNode : public Node
0699 {
0700 public:
0701     PostfixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
0702 
0703     void streamTo(SourceStream &) const override;
0704     void recurseVisit(NodeVisitor *visitor) override;
0705     OpValue generateEvalCode(CompileState *comp) override;
0706 protected:
0707     RefPtr<Node> m_loc;
0708     Operator m_oper;
0709 };
0710 
0711 class DeleteReferenceNode : public Node
0712 {
0713 public:
0714     DeleteReferenceNode(LocationNode *l) : loc(l) {}
0715 
0716     void streamTo(SourceStream &) const override;
0717     void recurseVisit(NodeVisitor *visitor) override;
0718     OpValue generateEvalCode(CompileState *comp) override;
0719 private:
0720     RefPtr<LocationNode> loc;
0721 };
0722 
0723 class DeleteValueNode : public Node
0724 {
0725 public:
0726     DeleteValueNode(Node *e) : m_expr(e) {}
0727 
0728     void streamTo(SourceStream &) const override;
0729     void recurseVisit(NodeVisitor *visitor) override;
0730     OpValue generateEvalCode(CompileState *comp) override;
0731 private:
0732     RefPtr<Node> m_expr;
0733 };
0734 
0735 class VoidNode : public Node
0736 {
0737 public:
0738     VoidNode(Node *e) : expr(e) {}
0739 
0740     OpValue generateEvalCode(CompileState *comp) override;
0741     void streamTo(SourceStream &) const override;
0742     void recurseVisit(NodeVisitor *visitor) override;
0743 private:
0744     RefPtr<Node> expr;
0745 };
0746 
0747 class TypeOfVarNode : public Node
0748 {
0749 public:
0750     TypeOfVarNode(VarAccessNode *l) : loc(l) {}
0751 
0752     OpValue generateEvalCode(CompileState *comp) override;
0753     void streamTo(SourceStream &) const override;
0754     void recurseVisit(NodeVisitor *visitor) override;
0755 private:
0756     RefPtr<VarAccessNode> loc;
0757 };
0758 
0759 class TypeOfValueNode : public Node
0760 {
0761 public:
0762     TypeOfValueNode(Node *e) : m_expr(e) {}
0763 
0764     OpValue generateEvalCode(CompileState *comp) override;
0765     void streamTo(SourceStream &) const override;
0766     void recurseVisit(NodeVisitor *visitor) override;
0767 private:
0768     RefPtr<Node> m_expr;
0769 };
0770 
0771 class PrefixNode : public Node
0772 {
0773 public:
0774     PrefixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
0775 
0776     OpValue generateEvalCode(CompileState *comp) override;
0777     void streamTo(SourceStream &) const override;
0778     void recurseVisit(NodeVisitor *visitor) override;
0779 protected:
0780     RefPtr<Node> m_loc;
0781     Operator m_oper;
0782 };
0783 
0784 class UnaryPlusNode : public Node
0785 {
0786 public:
0787     UnaryPlusNode(Node *e) : expr(e) {}
0788 
0789     OpValue generateEvalCode(CompileState *comp) override;
0790     void streamTo(SourceStream &) const override;
0791     void recurseVisit(NodeVisitor *visitor) override;
0792 private:
0793     RefPtr<Node> expr;
0794 };
0795 
0796 class NegateNode : public Node
0797 {
0798 public:
0799     NegateNode(Node *e) : expr(e) {}
0800 
0801     OpValue generateEvalCode(CompileState *comp) override;
0802     void streamTo(SourceStream &) const override;
0803     void recurseVisit(NodeVisitor *visitor) override;
0804 private:
0805     RefPtr<Node> expr;
0806 };
0807 
0808 class BitwiseNotNode : public Node
0809 {
0810 public:
0811     BitwiseNotNode(Node *e) : expr(e) {}
0812 
0813     OpValue generateEvalCode(CompileState *comp) override;
0814     void streamTo(SourceStream &) const override;
0815     void recurseVisit(NodeVisitor *visitor) override;
0816 private:
0817     RefPtr<Node> expr;
0818 };
0819 
0820 class LogicalNotNode : public Node
0821 {
0822 public:
0823     LogicalNotNode(Node *e) : expr(e) {}
0824 
0825     OpValue generateEvalCode(CompileState *comp) override;
0826     void streamTo(SourceStream &) const override;
0827     void recurseVisit(NodeVisitor *visitor) override;
0828 private:
0829     RefPtr<Node> expr;
0830 };
0831 
0832 class BinaryOperatorNode : public Node
0833 {
0834 public:
0835     BinaryOperatorNode(Node *e1, Node *e2, Operator op)
0836         : expr1(e1), expr2(e2), oper(op) {}
0837 
0838     OpValue generateEvalCode(CompileState *comp) override;
0839     void streamTo(SourceStream &) const override;
0840     void recurseVisit(NodeVisitor *visitor) override;
0841 private:
0842     RefPtr<Node> expr1;
0843     RefPtr<Node> expr2;
0844     Operator oper;
0845 };
0846 
0847 /**
0848  * expr1 && expr2, expr1 || expr2
0849  */
0850 class BinaryLogicalNode : public Node
0851 {
0852 public:
0853     BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
0854         expr1(e1), expr2(e2), oper(o) {}
0855 
0856     OpValue generateEvalCode(CompileState *comp) override;
0857     void streamTo(SourceStream &) const override;
0858     void recurseVisit(NodeVisitor *visitor) override;
0859 private:
0860     RefPtr<Node> expr1;
0861     RefPtr<Node> expr2;
0862     Operator oper;
0863 };
0864 
0865 /**
0866  * The ternary operator, "logical ? expr1 : expr2"
0867  */
0868 class ConditionalNode : public Node
0869 {
0870 public:
0871     ConditionalNode(Node *l, Node *e1, Node *e2) :
0872         logical(l), expr1(e1), expr2(e2) {}
0873 
0874     OpValue generateEvalCode(CompileState *comp) override;
0875     void streamTo(SourceStream &) const override;
0876     void recurseVisit(NodeVisitor *visitor) override;
0877 private:
0878     RefPtr<Node> logical;
0879     RefPtr<Node> expr1;
0880     RefPtr<Node> expr2;
0881 };
0882 
0883 class AssignNode : public Node
0884 {
0885 public:
0886     AssignNode(Node *loc, Operator oper, Node *right)
0887         : m_loc(loc), m_oper(oper), m_right(right) {}
0888 
0889     void streamTo(SourceStream &) const override;
0890     OpValue generateEvalCode(CompileState *comp) override;
0891     void recurseVisit(NodeVisitor *visitor) override;
0892 protected:
0893     RefPtr<Node> m_loc;
0894     Operator m_oper;
0895     RefPtr<Node> m_right;
0896 };
0897 
0898 class CommaNode : public Node
0899 {
0900 public:
0901     CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
0902 
0903     void streamTo(SourceStream &) const override;
0904     void recurseVisit(NodeVisitor *visitor) override;
0905     OpValue generateEvalCode(CompileState *comp) override;
0906 private:
0907     RefPtr<Node> expr1;
0908     RefPtr<Node> expr2;
0909 };
0910 
0911 class AssignExprNode : public Node
0912 {
0913 public:
0914     AssignExprNode(Node *e) : expr(e) {}
0915 
0916     void streamTo(SourceStream &) const override;
0917     void recurseVisit(NodeVisitor *visitor) override;
0918     OpValue generateEvalCode(CompileState *comp) override;
0919 
0920     Node *getExpr()
0921     {
0922         return expr.get();
0923     }
0924 private:
0925     RefPtr<Node> expr;
0926 };
0927 
0928 class VarDeclNode : public Node
0929 {
0930 public:
0931     enum Type { Variable, Constant };
0932     VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
0933 
0934     void generateCode(CompileState *comp);
0935 
0936     void streamTo(SourceStream &) const override;
0937     void recurseVisit(NodeVisitor *visitor) override;
0938 
0939     void processVarDecl(ExecState *) override;
0940 private:
0941     friend class VarStatementNode;
0942     friend class VarDeclListNode;
0943     Type varType;
0944     Identifier ident;
0945     RefPtr<AssignExprNode> init;
0946 };
0947 
0948 class VarDeclListNode : public Node
0949 {
0950 public:
0951     // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
0952     VarDeclListNode(VarDeclNode *v) : next(this), var(v)
0953     {
0954         Parser::noteNodeCycle(this);
0955     }
0956     VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
0957         : next(l->next), var(v)
0958     {
0959         l->next = this;
0960     }
0961 
0962     OpValue generateEvalCode(CompileState *comp) override;
0963     void streamTo(SourceStream &) const override;
0964     PassRefPtr<VarDeclListNode> releaseNext()
0965     {
0966         return next.release();
0967     }
0968     void breakCycle() override;
0969     void recurseVisit(NodeVisitor *visitor) override;
0970 private:
0971     friend class ForNode;
0972     friend class VarStatementNode;
0973     ListRefPtr<VarDeclListNode> next;
0974     RefPtr<VarDeclNode> var;
0975 };
0976 
0977 class VarStatementNode : public StatementNode
0978 {
0979 public:
0980     VarStatementNode(VarDeclListNode *l) : next(l->next.release())
0981     {
0982         Parser::removeNodeCycle(next.get());
0983     }
0984 
0985     void streamTo(SourceStream &) const override;
0986     void recurseVisit(NodeVisitor *visitor) override;
0987     void generateExecCode(CompileState *) override;
0988 private:
0989     RefPtr<VarDeclListNode> next;
0990 };
0991 
0992 class BlockNode : public StatementNode
0993 {
0994 public:
0995     BlockNode(SourceElementsNode *s);
0996 
0997     void streamTo(SourceStream &) const override;
0998     void recurseVisit(NodeVisitor *visitor) override;
0999     void generateExecCode(CompileState *) override;
1000 protected:
1001     RefPtr<SourceElementsNode> source;
1002 };
1003 
1004 class EmptyStatementNode : public StatementNode
1005 {
1006 public:
1007     EmptyStatementNode() { } // debug
1008 
1009     void streamTo(SourceStream &) const override;
1010     void generateExecCode(CompileState *) override;
1011 };
1012 
1013 class ExprStatementNode : public StatementNode
1014 {
1015 public:
1016     ExprStatementNode(Node *e) : expr(e) { }
1017 
1018     void streamTo(SourceStream &) const override;
1019     void recurseVisit(NodeVisitor *visitor) override;
1020     void generateExecCode(CompileState *) override;
1021 private:
1022     RefPtr<Node> expr;
1023 };
1024 
1025 class IfNode : public StatementNode
1026 {
1027 public:
1028     IfNode(Node *e, StatementNode *s1, StatementNode *s2)
1029         : expr(e), statement1(s1), statement2(s2) {}
1030 
1031     void streamTo(SourceStream &) const override;
1032     void recurseVisit(NodeVisitor *visitor) override;
1033     void generateExecCode(CompileState *) override;
1034 private:
1035     RefPtr<Node> expr;
1036     RefPtr<StatementNode> statement1;
1037     RefPtr<StatementNode> statement2;
1038 };
1039 
1040 class DoWhileNode : public StatementNode
1041 {
1042 public:
1043     DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
1044 
1045     void streamTo(SourceStream &) const override;
1046     void recurseVisit(NodeVisitor *visitor) override;
1047     void generateExecCode(CompileState *) override;
1048     bool isIterationStatement() const override
1049     {
1050         return true;
1051     }
1052 private:
1053     RefPtr<StatementNode> statement;
1054     RefPtr<Node> expr;
1055 };
1056 
1057 class WhileNode : public StatementNode
1058 {
1059 public:
1060     WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
1061 
1062     void streamTo(SourceStream &) const override;
1063     void recurseVisit(NodeVisitor *visitor) override;
1064     void generateExecCode(CompileState *) override;
1065     bool isIterationStatement() const override
1066     {
1067         return true;
1068     }
1069 private:
1070     RefPtr<Node> expr;
1071     RefPtr<StatementNode> statement;
1072 };
1073 
1074 class ForNode : public StatementNode
1075 {
1076 public:
1077     ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
1078         expr1(e1), expr2(e2), expr3(e3), statement(s) {}
1079     ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
1080         expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s)
1081     {
1082         Parser::removeNodeCycle(expr1.get());
1083     }
1084 
1085     void generateExecCode(CompileState *) override;
1086     void streamTo(SourceStream &) const override;
1087     void recurseVisit(NodeVisitor *visitor) override;
1088     bool isIterationStatement() const override
1089     {
1090         return true;
1091     }
1092 private:
1093     RefPtr<Node> expr1;
1094     RefPtr<Node> expr2;
1095     RefPtr<Node> expr3;
1096     RefPtr<StatementNode> statement;
1097 };
1098 
1099 class ForInNode : public StatementNode
1100 {
1101 public:
1102     ForInNode(Node *l, Node *e, StatementNode *s);
1103     ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
1104 
1105     void generateExecCode(CompileState *) override;
1106     void streamTo(SourceStream &) const override;
1107     void recurseVisit(NodeVisitor *visitor) override;
1108     bool isIterationStatement() const override
1109     {
1110         return true;
1111     }
1112 private:
1113     Identifier ident;
1114     RefPtr<AssignExprNode> init;
1115     RefPtr<Node> lexpr;
1116     RefPtr<Node> expr;
1117     RefPtr<VarDeclNode> varDecl;
1118     RefPtr<StatementNode> statement;
1119 };
1120 
1121 class ContinueNode : public StatementNode
1122 {
1123 public:
1124     ContinueNode() : target(nullptr) { }
1125     ContinueNode(const Identifier &i) : ident(i), target(nullptr) { }
1126 
1127     void generateExecCode(CompileState *) override;
1128     void streamTo(SourceStream &) const override;
1129 private:
1130     Identifier  ident;
1131     const Node *target;
1132 };
1133 
1134 class BreakNode : public StatementNode
1135 {
1136 public:
1137     BreakNode() : target(nullptr) { }
1138     BreakNode(const Identifier &i) : ident(i), target(nullptr) { }
1139 
1140     void generateExecCode(CompileState *) override;
1141     void streamTo(SourceStream &) const override;
1142 private:
1143     Identifier ident;
1144     const Node *target;
1145 };
1146 
1147 class ReturnNode : public StatementNode
1148 {
1149 public:
1150     ReturnNode(Node *v) : value(v) {}
1151 
1152     void generateExecCode(CompileState *) override;
1153     void streamTo(SourceStream &) const override;
1154     void recurseVisit(NodeVisitor *visitor) override;
1155 private:
1156     RefPtr<Node> value;
1157 };
1158 
1159 class WithNode : public StatementNode
1160 {
1161 public:
1162     WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
1163 
1164     void generateExecCode(CompileState *) override;
1165     void streamTo(SourceStream &) const override;
1166     void recurseVisit(NodeVisitor *visitor) override;
1167 private:
1168     RefPtr<Node> expr;
1169     RefPtr<StatementNode> statement;
1170 };
1171 
1172 class LabelNode : public StatementNode
1173 {
1174 public:
1175     LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
1176 
1177     void streamTo(SourceStream &) const override;
1178     void recurseVisit(NodeVisitor *visitor) override;
1179     void generateExecCode(CompileState *) override;
1180     NodeType type() const override
1181     {
1182         return LabelNodeType;
1183     }
1184 private:
1185     Identifier label;
1186     RefPtr<StatementNode> statement;
1187 };
1188 
1189 class ThrowNode : public StatementNode
1190 {
1191 public:
1192     ThrowNode(Node *e) : expr(e) {}
1193 
1194     void generateExecCode(CompileState *) override;
1195     void streamTo(SourceStream &) const override;
1196     void recurseVisit(NodeVisitor *visitor) override;
1197 private:
1198     RefPtr<Node> expr;
1199 };
1200 
1201 class TryNode : public StatementNode
1202 {
1203 public:
1204     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f)
1205         : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
1206     NodeType type() const override
1207     {
1208         return TryNodeType;
1209     }
1210 
1211     void generateExecCode(CompileState *) override;
1212     void streamTo(SourceStream &) const override;
1213     void recurseVisit(NodeVisitor *visitor) override;
1214 private:
1215     RefPtr<StatementNode> tryBlock;
1216     Identifier exceptionIdent;
1217     RefPtr<StatementNode> catchBlock;
1218     RefPtr<StatementNode> finallyBlock;
1219 };
1220 
1221 class ParameterNode : public Node
1222 {
1223 public:
1224     // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
1225     ParameterNode(const Identifier &i) : id(i), next(this)
1226     {
1227         Parser::noteNodeCycle(this);
1228     }
1229     ParameterNode(ParameterNode *next, const Identifier &i)
1230         : id(i), next(next->next)
1231     {
1232         next->next = this;
1233     }
1234 
1235     const Identifier &ident() const
1236     {
1237         return id;
1238     }
1239     ParameterNode *nextParam() const
1240     {
1241         return next.get();
1242     }
1243     void streamTo(SourceStream &) const override;
1244     PassRefPtr<ParameterNode> releaseNext()
1245     {
1246         return next.release();
1247     }
1248     void breakCycle() override;
1249 
1250     void recurseVisit(NodeVisitor *visitor) override;
1251 private:
1252     friend class FuncDeclNode;
1253     friend class FuncExprNode;
1254     Identifier id;
1255     ListRefPtr<ParameterNode> next;
1256 };
1257 
1258 // Flags about function bodies we care about for codegen
1259 enum FunctionBodyFlags {
1260     // note: neither of the two below is set for things created via
1261     // top-level, eval, or function ctor
1262     FuncFl_Decl      = 1,
1263     FuncFl_Expr      = 2,
1264     FuncFl_HasEvalOp = 4
1265 };
1266 
1267 /**
1268  This AST node corresponds to the function body or top-level code in the AST, but is used to
1269  keep track of much of the information relevant to the whole function,
1270  such as parameter names and symbol tables. This is because there are both function
1271  declarations and expressions, so there is no natural single place to put this stuff
1272  above the body
1273 
1274  inherited by ProgramNode
1275 */
1276 class FunctionBodyNode : public BlockNode
1277 {
1278 public:
1279     struct SymbolInfo {
1280         SymbolInfo(int _attr, FuncDeclNode *_funcDecl) : funcDecl(_funcDecl), attr(_attr) {}
1281         SymbolInfo() {}
1282         FuncDeclNode *funcDecl;
1283         int           attr;
1284     };
1285     FunctionBodyNode(SourceElementsNode *);
1286     int sourceId()
1287     {
1288         return m_sourceId;
1289     }
1290     const UString &sourceURL()
1291     {
1292         return m_sourceURL;
1293     }
1294 
1295     bool isCompiled() const
1296     {
1297         return m_compType != NotCompiled;
1298     }
1299     void compileIfNeeded(CodeType ctype, CompileType compType);
1300     void compile(CodeType ctype, CompileType compType);
1301     CompileType compileState() const
1302     {
1303         return m_compType;
1304     }
1305 
1306     void generateExecCode(CompileState *) override;
1307 
1308     // Reserves a register for private use, making sure that id is in the right spot..
1309     void reserveSlot(size_t id, bool shouldMark);
1310 
1311     // Symbol table functions
1312     SymbolTable &symbolTable()
1313     {
1314         return m_symbolTable;
1315     }
1316     size_t lookupSymbolID(const Identifier &id) const
1317     {
1318         return m_symbolTable.get(id.ustring().rep());
1319     }
1320 
1321     int  numLocalsAndRegisters() const
1322     {
1323         return m_symbolList.size();
1324     }
1325     SymbolInfo *getLocalInfo()
1326     {
1327         return m_symbolList.data();
1328     }
1329 
1330     size_t  numFunctionLocals() const
1331     {
1332         return m_functionLocals.size();
1333     }
1334     size_t *getFunctionLocalInfo()
1335     {
1336         return m_functionLocals.data();
1337     }
1338 
1339     // Parameter stuff. We only collect the names during the parsing/
1340     // while FunctionImp is responsible for managing the IDs.
1341     void addParam(const Identifier &ident);
1342     size_t numParams() const
1343     {
1344         return m_paramList.size();
1345     }
1346     const Identifier &paramName(size_t pos) const
1347     {
1348         return m_paramList[pos];
1349     }
1350 
1351     void addVarDecl(const Identifier &ident, int attr, ExecState *exec);
1352     void addFunDecl(const Identifier &ident, int attr, FuncDeclNode *funcDecl);
1353 
1354     // Adds a new symbol, killing any previous ID.
1355     void addSymbolOverwriteID(size_t id, const Identifier &ident, int attr);
1356 
1357     // Runs the code, compiling if needed. This should only be used for non-function ExecStates
1358     Completion execute(ExecState *exec);
1359 
1360     bool tearOffAtEnd() const
1361     {
1362         return m_tearOffAtEnd;
1363     }
1364 
1365     const CodeBlock &code() const
1366     {
1367         return m_compiledCode;
1368     }
1369     CodeBlock &code()
1370     {
1371         return m_compiledCode;
1372     }
1373 
1374     // Collection of FuncFl_* flags describing information collected about this function
1375     // during the parsing.
1376     unsigned flags() const
1377     {
1378         return m_flags;
1379     }
1380 
1381 private:
1382     size_t addSymbol(const Identifier &ident, int attr, FuncDeclNode *funcDecl = nullptr);
1383     UString m_sourceURL;
1384     int m_sourceId : 31;
1385     bool m_tearOffAtEnd : 1;
1386     CompileType m_compType;
1387 
1388     // Flags
1389     unsigned m_flags;
1390 
1391     // This maps id -> attributes and function decl info
1392     WTF::Vector<SymbolInfo> m_symbolList;
1393 
1394     // This contains the list of locals which contains function declarations
1395     WTF::Vector<size_t> m_functionLocals;
1396 
1397     // This maps name -> id
1398     SymbolTable m_symbolTable;
1399 
1400     // The list of parameter names
1401     WTF::Vector<Identifier> m_paramList;
1402 
1403     CodeBlock m_compiledCode;
1404 };
1405 
1406 inline void FunctionBodyNode::compileIfNeeded(CodeType ctype, CompileType compType)
1407 {
1408     if (m_compType != compType) {
1409         compile(ctype, compType);
1410     }
1411 }
1412 
1413 class FuncExprNode : public Node
1414 {
1415 public:
1416     FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = nullptr)
1417         : ident(i), param(p ? p->next.release() : PassRefPtr<ParameterNode>(nullptr)), body(b)
1418     {
1419         if (p) {
1420             Parser::removeNodeCycle(param.get());
1421         } addParams();
1422     }
1423 
1424     OpValue generateEvalCode(CompileState *comp) override;
1425     void streamTo(SourceStream &) const override;
1426     void recurseVisit(NodeVisitor *visitor) override;
1427     bool scanForDeclarations() const override
1428     {
1429         return false;
1430     }
1431 private:
1432     void addParams();
1433     // Used for streamTo
1434     friend class PropertyNode;
1435     Identifier ident;
1436     RefPtr<ParameterNode> param;
1437     RefPtr<FunctionBodyNode> body;
1438 };
1439 
1440 class FuncDeclNode : public StatementNode
1441 {
1442 public:
1443     FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
1444         : ident(i), body(b)
1445     {
1446         addParams();
1447     }
1448     FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
1449         : ident(i), param(p->next.release()), body(b)
1450     {
1451         Parser::removeNodeCycle(param.get());
1452         addParams();
1453     }
1454 
1455     void generateExecCode(CompileState *) override;
1456     void streamTo(SourceStream &) const override;
1457     void recurseVisit(NodeVisitor *visitor) override;
1458     bool scanForDeclarations() const override
1459     {
1460         return false;
1461     }
1462 
1463     void processFuncDecl(ExecState *) override;
1464     FunctionImp *makeFunctionObject(ExecState *);
1465 private:
1466     void addParams();
1467     Identifier ident;
1468     RefPtr<ParameterNode> param;
1469     RefPtr<FunctionBodyNode> body;
1470 };
1471 
1472 // A linked list of source element nodes
1473 class SourceElementsNode : public StatementNode
1474 {
1475 public:
1476     // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1477     SourceElementsNode(StatementNode *);
1478     SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
1479 
1480     void generateExecCode(CompileState *) override;
1481     void streamTo(SourceStream &) const override;
1482     PassRefPtr<SourceElementsNode> releaseNext()
1483     {
1484         return next.release();
1485     }
1486     void breakCycle() override;
1487     void recurseVisit(NodeVisitor *visitor) override;
1488 private:
1489     friend class BlockNode;
1490     friend class CaseClauseNode;
1491     RefPtr<StatementNode> node;
1492     ListRefPtr<SourceElementsNode> next;
1493 };
1494 
1495 class CaseClauseNode : public Node
1496 {
1497 public:
1498     CaseClauseNode(Node *e) : expr(e) { }
1499     CaseClauseNode(Node *e, SourceElementsNode *s)
1500         : expr(e), source(s->next.release())
1501     {
1502         Parser::removeNodeCycle(source.get());
1503     }
1504 
1505     void streamTo(SourceStream &) const override;
1506     void recurseVisit(NodeVisitor *visitor) override;
1507 private:
1508     friend class SwitchNode;
1509     RefPtr<Node> expr;
1510     RefPtr<SourceElementsNode> source;
1511 };
1512 
1513 class ClauseListNode : public Node
1514 {
1515 public:
1516     // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
1517     ClauseListNode(CaseClauseNode *c) : clause(c), next(this)
1518     {
1519         Parser::noteNodeCycle(this);
1520     }
1521     ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
1522         : clause(c), next(n->next)
1523     {
1524         n->next = this;
1525     }
1526 
1527     CaseClauseNode *getClause() const
1528     {
1529         return clause.get();
1530     }
1531     ClauseListNode *getNext() const
1532     {
1533         return next.get();
1534     }
1535     void streamTo(SourceStream &) const override;
1536     PassRefPtr<ClauseListNode> releaseNext()
1537     {
1538         return next.release();
1539     }
1540     void breakCycle() override;
1541     void recurseVisit(NodeVisitor *visitor) override;
1542 private:
1543     friend class SwitchNode;
1544     friend class CaseBlockNode;
1545     RefPtr<CaseClauseNode> clause;
1546     ListRefPtr<ClauseListNode> next;
1547 };
1548 
1549 class CaseBlockNode : public Node
1550 {
1551 public:
1552     CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
1553 
1554     void streamTo(SourceStream &) const override;
1555     void recurseVisit(NodeVisitor *visitor) override;
1556 private:
1557     friend class SwitchNode;
1558     RefPtr<ClauseListNode> list1;
1559     RefPtr<CaseClauseNode> def;
1560     RefPtr<ClauseListNode> list2;
1561 };
1562 
1563 class SwitchNode : public StatementNode
1564 {
1565 public:
1566     SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
1567 
1568     void streamTo(SourceStream &) const override;
1569     void recurseVisit(NodeVisitor *visitor) override;
1570     void generateExecCode(CompileState *comp) override;
1571 private:
1572     RefPtr<Node> expr;
1573     RefPtr<CaseBlockNode> block;
1574 };
1575 
1576 // important: these are also built when compiling things via the Function constructor
1577 // (see FunctionObjectImp::construct() and Parser::parseFunctionBody, so the existence
1578 // of this class rather than the bare FunctionBodyNode does not care much information.
1579 class ProgramNode : public FunctionBodyNode
1580 {
1581 public:
1582     ProgramNode(SourceElementsNode *s);
1583     void streamTo(SourceStream &) const override;
1584 };
1585 
1586 class PackageNameNode : public Node
1587 {
1588 public:
1589     PackageNameNode(const Identifier &i) : names(nullptr), id(i) { }
1590     PackageNameNode(PackageNameNode *n,
1591                     const Identifier &i) : names(n), id(i) { }
1592 
1593     void streamTo(SourceStream &) const override;
1594     void recurseVisit(NodeVisitor *visitor) override;
1595 
1596     Completion loadSymbol(ExecState *exec, bool wildcard);
1597     PackageObject *resolvePackage(ExecState *exec);
1598 
1599 private:
1600     PackageObject *resolvePackage(ExecState *exec,
1601                                   JSObject *baseObject, Package *basePackage);
1602     RefPtr<PackageNameNode> names;
1603     Identifier id;
1604 };
1605 
1606 class ImportStatement : public StatementNode
1607 {
1608 public:
1609     ImportStatement(PackageNameNode *n) : name(n), wld(false) {}
1610     void enableWildcard()
1611     {
1612         wld = true;
1613     }
1614     void setAlias(const Identifier &a)
1615     {
1616         al = a;
1617     }
1618 
1619     void generateExecCode(CompileState *) override;
1620     void streamTo(SourceStream &) const override;
1621     void recurseVisit(NodeVisitor *visitor) override;
1622 private:
1623     void processVarDecl(ExecState *state) override;
1624     RefPtr<PackageNameNode> name;
1625     Identifier al;
1626     bool wld;
1627 };
1628 
1629 } // namespace
1630 
1631 #endif