OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_AST_AST_H_ | 5 #ifndef V8_AST_AST_H_ |
6 #define V8_AST_AST_H_ | 6 #define V8_AST_AST_H_ |
7 | 7 |
8 #include "src/ast/ast-value-factory.h" | 8 #include "src/ast/ast-value-factory.h" |
9 #include "src/ast/modules.h" | 9 #include "src/ast/modules.h" |
10 #include "src/ast/variables.h" | 10 #include "src/ast/variables.h" |
(...skipping 2868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 | 2879 |
2880 | 2880 |
2881 // ---------------------------------------------------------------------------- | 2881 // ---------------------------------------------------------------------------- |
2882 // Basic visitor | 2882 // Basic visitor |
2883 // Sub-class should parametrize AstVisitor with itself, e.g.: | 2883 // Sub-class should parametrize AstVisitor with itself, e.g.: |
2884 // class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... } | 2884 // class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... } |
2885 | 2885 |
2886 template <class Subclass> | 2886 template <class Subclass> |
2887 class AstVisitor BASE_EMBEDDED { | 2887 class AstVisitor BASE_EMBEDDED { |
2888 public: | 2888 public: |
2889 void Visit(AstNode* node) { This()->Visit(node); } | 2889 void Visit(AstNode* node) { impl()->Visit(node); } |
2890 | 2890 |
2891 void VisitDeclarations(ZoneList<Declaration*>* declarations) { | 2891 void VisitDeclarations(ZoneList<Declaration*>* declarations) { |
2892 for (int i = 0; i < declarations->length(); i++) { | 2892 for (int i = 0; i < declarations->length(); i++) { |
2893 Visit(declarations->at(i)); | 2893 Visit(declarations->at(i)); |
2894 } | 2894 } |
2895 } | 2895 } |
2896 | 2896 |
2897 void VisitStatements(ZoneList<Statement*>* statements) { | 2897 void VisitStatements(ZoneList<Statement*>* statements) { |
2898 for (int i = 0; i < statements->length(); i++) { | 2898 for (int i = 0; i < statements->length(); i++) { |
2899 Statement* stmt = statements->at(i); | 2899 Statement* stmt = statements->at(i); |
2900 Visit(stmt); | 2900 Visit(stmt); |
2901 if (stmt->IsJump()) break; | 2901 if (stmt->IsJump()) break; |
2902 } | 2902 } |
2903 } | 2903 } |
2904 | 2904 |
2905 void VisitExpressions(ZoneList<Expression*>* expressions) { | 2905 void VisitExpressions(ZoneList<Expression*>* expressions) { |
2906 for (int i = 0; i < expressions->length(); i++) { | 2906 for (int i = 0; i < expressions->length(); i++) { |
2907 // The variable statement visiting code may pass NULL expressions | 2907 // The variable statement visiting code may pass NULL expressions |
2908 // to this code. Maybe this should be handled by introducing an | 2908 // to this code. Maybe this should be handled by introducing an |
2909 // undefined expression or literal? Revisit this code if this | 2909 // undefined expression or literal? Revisit this code if this |
2910 // changes | 2910 // changes |
2911 Expression* expression = expressions->at(i); | 2911 Expression* expression = expressions->at(i); |
2912 if (expression != NULL) Visit(expression); | 2912 if (expression != NULL) Visit(expression); |
2913 } | 2913 } |
2914 } | 2914 } |
2915 | 2915 |
2916 private: | 2916 protected: |
2917 Subclass* This() { return static_cast<Subclass*>(this); } | 2917 Subclass* impl() { return static_cast<Subclass*>(this); } |
2918 }; | 2918 }; |
2919 | 2919 |
2920 #define GENERATE_VISIT_CASE(NodeType) \ | 2920 #define GENERATE_VISIT_CASE(NodeType) \ |
2921 case AstNode::k##NodeType: \ | 2921 case AstNode::k##NodeType: \ |
2922 return Visit##NodeType(static_cast<NodeType*>(node)); | 2922 return Visit##NodeType(static_cast<NodeType*>(node)); |
2923 | 2923 |
2924 #define GENERATE_AST_VISITOR_SWITCH() \ | 2924 #define GENERATE_AST_VISITOR_SWITCH() \ |
2925 switch (node->node_type()) { \ | 2925 switch (node->node_type()) { \ |
2926 AST_NODE_LIST(GENERATE_VISIT_CASE) \ | 2926 AST_NODE_LIST(GENERATE_VISIT_CASE) \ |
2927 case AstNode::kModule: \ | 2927 case AstNode::kModule: \ |
2928 UNREACHABLE(); \ | 2928 UNREACHABLE(); \ |
2929 } | 2929 } |
2930 | 2930 |
2931 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \ | 2931 #define DEFINE_AST_VISITOR_STACKOVERFLOW_MEMBERS() \ |
2932 public: \ | 2932 public: \ |
2933 void Visit(AstNode* node) { \ | |
2934 if (CheckStackOverflow()) return; \ | |
2935 GENERATE_AST_VISITOR_SWITCH() \ | |
2936 } \ | |
2937 \ | |
2938 void SetStackOverflow() { stack_overflow_ = true; } \ | 2933 void SetStackOverflow() { stack_overflow_ = true; } \ |
2939 void ClearStackOverflow() { stack_overflow_ = false; } \ | 2934 void ClearStackOverflow() { stack_overflow_ = false; } \ |
2940 bool HasStackOverflow() const { return stack_overflow_; } \ | 2935 bool HasStackOverflow() const { return stack_overflow_; } \ |
2941 \ | 2936 \ |
2942 bool CheckStackOverflow() { \ | 2937 bool CheckStackOverflow() { \ |
2943 if (stack_overflow_) return true; \ | 2938 if (stack_overflow_) return true; \ |
2944 if (GetCurrentStackPosition() < stack_limit_) { \ | 2939 if (GetCurrentStackPosition() < stack_limit_) { \ |
2945 stack_overflow_ = true; \ | 2940 stack_overflow_ = true; \ |
2946 return true; \ | 2941 return true; \ |
2947 } \ | 2942 } \ |
2948 return false; \ | 2943 return false; \ |
2949 } \ | 2944 } \ |
2950 \ | 2945 \ |
2951 private: \ | 2946 private: \ |
2952 void InitializeAstVisitor(Isolate* isolate) { \ | 2947 void InitializeAstVisitor(Isolate* isolate) { \ |
2953 stack_limit_ = isolate->stack_guard()->real_climit(); \ | 2948 stack_limit_ = isolate->stack_guard()->real_climit(); \ |
2954 stack_overflow_ = false; \ | 2949 stack_overflow_ = false; \ |
2955 } \ | 2950 } \ |
2956 \ | 2951 \ |
2957 void InitializeAstVisitor(uintptr_t stack_limit) { \ | 2952 void InitializeAstVisitor(uintptr_t stack_limit) { \ |
2958 stack_limit_ = stack_limit; \ | 2953 stack_limit_ = stack_limit; \ |
2959 stack_overflow_ = false; \ | 2954 stack_overflow_ = false; \ |
2960 } \ | 2955 } \ |
2961 \ | 2956 \ |
2962 uintptr_t stack_limit_; \ | 2957 uintptr_t stack_limit_; \ |
2963 bool stack_overflow_ | 2958 bool stack_overflow_ |
2964 | 2959 |
2965 #define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW() \ | 2960 #define DEFINE_AST_VISITOR_DISPATCH() \ |
2966 public: \ | 2961 public: \ |
2967 void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \ | 2962 void Visit(AstNode* node) { \ |
2968 \ | 2963 if (CheckStackOverflow()) return; \ |
2969 private: | 2964 GENERATE_AST_VISITOR_SWITCH() \ |
| 2965 } |
| 2966 |
| 2967 #define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW() \ |
| 2968 public: \ |
| 2969 void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } |
| 2970 |
| 2971 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \ |
| 2972 public: \ |
| 2973 DEFINE_AST_VISITOR_DISPATCH() \ |
| 2974 DEFINE_AST_VISITOR_STACKOVERFLOW_MEMBERS() |
2970 | 2975 |
2971 #define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \ | 2976 #define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \ |
2972 public: \ | 2977 public: \ |
2973 AstNode* Rewrite(AstNode* node) { \ | 2978 AstNode* Rewrite(AstNode* node) { \ |
2974 DCHECK_NULL(replacement_); \ | 2979 DCHECK_NULL(replacement_); \ |
2975 DCHECK_NOT_NULL(node); \ | 2980 DCHECK_NOT_NULL(node); \ |
2976 Visit(node); \ | 2981 Visit(node); \ |
2977 if (HasStackOverflow()) return node; \ | 2982 if (HasStackOverflow()) return node; \ |
2978 if (replacement_ == nullptr) return node; \ | 2983 if (replacement_ == nullptr) return node; \ |
2979 AstNode* result = replacement_; \ | 2984 AstNode* result = replacement_; \ |
2980 replacement_ = nullptr; \ | 2985 replacement_ = nullptr; \ |
2981 return result; \ | 2986 return result; \ |
2982 } \ | 2987 } \ |
2983 \ | 2988 \ |
2984 private: \ | 2989 private: \ |
2985 void InitializeAstRewriter(Isolate* isolate) { \ | 2990 void InitializeAstRewriter(Isolate* isolate) { \ |
2986 InitializeAstVisitor(isolate); \ | 2991 InitializeAstVisitor(isolate); \ |
2987 replacement_ = nullptr; \ | 2992 replacement_ = nullptr; \ |
2988 } \ | 2993 } \ |
2989 \ | 2994 \ |
2990 void InitializeAstRewriter(uintptr_t stack_limit) { \ | 2995 void InitializeAstRewriter(uintptr_t stack_limit) { \ |
2991 InitializeAstVisitor(stack_limit); \ | 2996 InitializeAstVisitor(stack_limit); \ |
2992 replacement_ = nullptr; \ | 2997 replacement_ = nullptr; \ |
2993 } \ | 2998 } \ |
2994 \ | 2999 \ |
2995 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \ | 3000 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \ |
2996 \ | 3001 \ |
2997 protected: \ | 3002 protected: \ |
2998 AstNode* replacement_ | 3003 AstNode* replacement_ |
| 3004 |
2999 // Generic macro for rewriting things; `GET` is the expression to be | 3005 // Generic macro for rewriting things; `GET` is the expression to be |
3000 // rewritten; `SET` is a command that should do the rewriting, i.e. | 3006 // rewritten; `SET` is a command that should do the rewriting, i.e. |
3001 // something sensible with the variable called `replacement`. | 3007 // something sensible with the variable called `replacement`. |
3002 #define AST_REWRITE(Type, GET, SET) \ | 3008 #define AST_REWRITE(Type, GET, SET) \ |
3003 do { \ | 3009 do { \ |
3004 DCHECK(!HasStackOverflow()); \ | 3010 DCHECK(!HasStackOverflow()); \ |
3005 DCHECK_NULL(replacement_); \ | 3011 DCHECK_NULL(replacement_); \ |
3006 Visit(GET); \ | 3012 Visit(GET); \ |
3007 if (HasStackOverflow()) return; \ | 3013 if (HasStackOverflow()) return; \ |
3008 if (replacement_ == nullptr) break; \ | 3014 if (replacement_ == nullptr) break; \ |
(...skipping 16 matching lines...) Expand all Loading... |
3025 // `at` and `Set`. | 3031 // `at` and `Set`. |
3026 #define AST_REWRITE_LIST_ELEMENT(Type, list, index) \ | 3032 #define AST_REWRITE_LIST_ELEMENT(Type, list, index) \ |
3027 do { \ | 3033 do { \ |
3028 auto _list = (list); \ | 3034 auto _list = (list); \ |
3029 auto _index = (index); \ | 3035 auto _index = (index); \ |
3030 AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \ | 3036 AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \ |
3031 } while (false) | 3037 } while (false) |
3032 | 3038 |
3033 | 3039 |
3034 // ---------------------------------------------------------------------------- | 3040 // ---------------------------------------------------------------------------- |
3035 // Traversing visitor | |
3036 // - fully traverses the entire AST. | |
3037 | |
3038 // This AstVistor is not final, and provides the AstVisitor methods as virtual | |
3039 // methods so they can be specialized by subclasses. | |
3040 class AstTraversalVisitor : public AstVisitor<AstTraversalVisitor> { | |
3041 public: | |
3042 explicit AstTraversalVisitor(Isolate* isolate); | |
3043 explicit AstTraversalVisitor(uintptr_t stack_limit); | |
3044 virtual ~AstTraversalVisitor() {} | |
3045 | |
3046 // Iteration left-to-right. | |
3047 void VisitDeclarations(ZoneList<Declaration*>* declarations); | |
3048 void VisitStatements(ZoneList<Statement*>* statements); | |
3049 | |
3050 // Individual nodes | |
3051 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | |
3052 AST_NODE_LIST(DECLARE_VISIT) | |
3053 #undef DECLARE_VISIT | |
3054 | |
3055 protected: | |
3056 int depth() { return depth_; } | |
3057 | |
3058 private: | |
3059 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | |
3060 | |
3061 int depth_; | |
3062 | |
3063 DISALLOW_COPY_AND_ASSIGN(AstTraversalVisitor); | |
3064 }; | |
3065 | |
3066 // ---------------------------------------------------------------------------- | |
3067 // AstNode factory | 3041 // AstNode factory |
3068 | 3042 |
3069 class AstNodeFactory final BASE_EMBEDDED { | 3043 class AstNodeFactory final BASE_EMBEDDED { |
3070 public: | 3044 public: |
3071 explicit AstNodeFactory(AstValueFactory* ast_value_factory) | 3045 explicit AstNodeFactory(AstValueFactory* ast_value_factory) |
3072 : local_zone_(ast_value_factory->zone()), | 3046 : local_zone_(ast_value_factory->zone()), |
3073 parser_zone_(ast_value_factory->zone()), | 3047 parser_zone_(ast_value_factory->zone()), |
3074 ast_value_factory_(ast_value_factory) {} | 3048 ast_value_factory_(ast_value_factory) {} |
3075 | 3049 |
3076 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } | 3050 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3543 : NULL; \ | 3517 : NULL; \ |
3544 } | 3518 } |
3545 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) | 3519 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) |
3546 #undef DECLARE_NODE_FUNCTIONS | 3520 #undef DECLARE_NODE_FUNCTIONS |
3547 | 3521 |
3548 | 3522 |
3549 } // namespace internal | 3523 } // namespace internal |
3550 } // namespace v8 | 3524 } // namespace v8 |
3551 | 3525 |
3552 #endif // V8_AST_AST_H_ | 3526 #endif // V8_AST_AST_H_ |
OLD | NEW |