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 ¶mName(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