1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_PARSING_PENDING_COMPILATION_ERROR_HANDLER_H_ 6 #define V8_PARSING_PENDING_COMPILATION_ERROR_HANDLER_H_ 7 8 #include <forward_list> 9 10 #include "src/base/export-template.h" 11 #include "src/base/macros.h" 12 #include "src/common/globals.h" 13 #include "src/common/message-template.h" 14 #include "src/handles/handles.h" 15 16 namespace v8 { 17 namespace internal { 18 19 class AstRawString; 20 class AstValueFactory; 21 class Isolate; 22 class Script; 23 24 // Helper class for handling pending compilation errors consistently in various 25 // compilation phases. 26 class PendingCompilationErrorHandler { 27 public: 28 PendingCompilationErrorHandler() = default; 29 PendingCompilationErrorHandler(const PendingCompilationErrorHandler&) = 30 delete; 31 PendingCompilationErrorHandler& operator=( 32 const PendingCompilationErrorHandler&) = delete; 33 34 void ReportMessageAt(int start_position, int end_position, 35 MessageTemplate message, const char* arg = nullptr); 36 37 void ReportMessageAt(int start_position, int end_position, 38 MessageTemplate message, const AstRawString* arg); 39 40 void ReportMessageAt(int start_position, int end_position, 41 MessageTemplate message, const AstRawString* arg0, 42 const char* arg1); 43 44 void ReportWarningAt(int start_position, int end_position, 45 MessageTemplate message, const char* arg = nullptr); 46 stack_overflow()47 bool stack_overflow() const { return stack_overflow_; } 48 set_stack_overflow()49 void set_stack_overflow() { 50 has_pending_error_ = true; 51 stack_overflow_ = true; 52 } 53 has_pending_error()54 bool has_pending_error() const { return has_pending_error_; } has_pending_warnings()55 bool has_pending_warnings() const { return !warning_messages_.empty(); } 56 57 // Handle errors detected during parsing. 58 template <typename IsolateT> 59 EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 60 void PrepareErrors(IsolateT* isolate, AstValueFactory* ast_value_factory); 61 V8_EXPORT_PRIVATE void ReportErrors(Isolate* isolate, 62 Handle<Script> script) const; 63 64 // Handle warnings detected during compilation. 65 template <typename IsolateT> 66 void PrepareWarnings(IsolateT* isolate); 67 void ReportWarnings(Isolate* isolate, Handle<Script> script) const; 68 69 V8_EXPORT_PRIVATE Handle<String> FormatErrorMessageForTest(Isolate* isolate); 70 set_unidentifiable_error()71 void set_unidentifiable_error() { 72 has_pending_error_ = true; 73 unidentifiable_error_ = true; 74 } clear_unidentifiable_error()75 void clear_unidentifiable_error() { 76 has_pending_error_ = false; 77 unidentifiable_error_ = false; 78 } has_error_unidentifiable_by_preparser()79 bool has_error_unidentifiable_by_preparser() const { 80 return unidentifiable_error_; 81 } 82 83 private: 84 class MessageDetails { 85 public: 86 MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(MessageDetails); MessageDetails()87 MessageDetails() 88 : start_position_(-1), 89 end_position_(-1), 90 message_(MessageTemplate::kNone) {} MessageDetails(int start_position,int end_position,MessageTemplate message,const AstRawString * arg0)91 MessageDetails(int start_position, int end_position, 92 MessageTemplate message, const AstRawString* arg0) 93 : start_position_(start_position), 94 end_position_(end_position), 95 message_(message), 96 args_{MessageArgument{arg0}, MessageArgument{}} {} MessageDetails(int start_position,int end_position,MessageTemplate message,const AstRawString * arg0,const char * arg1)97 MessageDetails(int start_position, int end_position, 98 MessageTemplate message, const AstRawString* arg0, 99 const char* arg1) 100 : start_position_(start_position), 101 end_position_(end_position), 102 message_(message), 103 args_{MessageArgument{arg0}, MessageArgument{arg1}} { 104 DCHECK_NOT_NULL(arg0); 105 DCHECK_NOT_NULL(arg1); 106 } MessageDetails(int start_position,int end_position,MessageTemplate message,const char * arg0)107 MessageDetails(int start_position, int end_position, 108 MessageTemplate message, const char* arg0) 109 : start_position_(start_position), 110 end_position_(end_position), 111 message_(message), 112 args_{MessageArgument{arg0}, MessageArgument{}} {} 113 114 Handle<String> ArgString(Isolate* isolate, int index) const; ArgCount()115 int ArgCount() const { 116 int argc = 0; 117 for (int i = 0; i < kMaxArgumentCount; i++) { 118 if (args_[i].type == kNone) break; 119 argc++; 120 } 121 #ifdef DEBUG 122 for (int i = argc; i < kMaxArgumentCount; i++) { 123 DCHECK_EQ(args_[i].type, kNone); 124 } 125 #endif // DEBUG 126 return argc; 127 } 128 129 MessageLocation GetLocation(Handle<Script> script) const; message()130 MessageTemplate message() const { return message_; } 131 132 template <typename IsolateT> 133 void Prepare(IsolateT* isolate); 134 135 private: 136 enum Type { kNone, kAstRawString, kConstCharString, kMainThreadHandle }; 137 138 void SetString(Handle<String> string, Isolate* isolate); 139 void SetString(Handle<String> string, LocalIsolate* isolate); 140 141 int start_position_; 142 int end_position_; 143 144 MessageTemplate message_; 145 146 struct MessageArgument final { MessageArgumentfinal147 constexpr MessageArgument() : ast_string(nullptr), type(kNone) {} MessageArgumentfinal148 explicit constexpr MessageArgument(const AstRawString* s) 149 : ast_string(s), type(s == nullptr ? kNone : kAstRawString) {} MessageArgumentfinal150 explicit constexpr MessageArgument(const char* s) 151 : c_string(s), type(s == nullptr ? kNone : kConstCharString) {} 152 153 union { 154 const AstRawString* ast_string; 155 const char* c_string; 156 Handle<String> js_string; 157 }; 158 Type type; 159 }; 160 161 static constexpr int kMaxArgumentCount = 2; 162 MessageArgument args_[kMaxArgumentCount]; 163 }; 164 165 void ThrowPendingError(Isolate* isolate, Handle<Script> script) const; 166 167 bool has_pending_error_ = false; 168 bool stack_overflow_ = false; 169 bool unidentifiable_error_ = false; 170 171 MessageDetails error_details_; 172 173 std::forward_list<MessageDetails> warning_messages_; 174 }; 175 176 extern template void PendingCompilationErrorHandler::PrepareErrors( 177 Isolate* isolate, AstValueFactory* ast_value_factory); 178 extern template void PendingCompilationErrorHandler::PrepareErrors( 179 LocalIsolate* isolate, AstValueFactory* ast_value_factory); 180 extern template void PendingCompilationErrorHandler::PrepareWarnings( 181 Isolate* isolate); 182 extern template void PendingCompilationErrorHandler::PrepareWarnings( 183 LocalIsolate* isolate); 184 185 } // namespace internal 186 } // namespace v8 187 #endif // V8_PARSING_PENDING_COMPILATION_ERROR_HANDLER_H_ 188