1 // Copyright 2011 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_PREPARSE_DATA_H_ 6 #define V8_PARSING_PREPARSE_DATA_H_ 7 8 #include "src/allocation.h" 9 #include "src/hashmap.h" 10 #include "src/messages.h" 11 #include "src/parsing/preparse-data-format.h" 12 13 namespace v8 { 14 namespace internal { 15 16 class ScriptData { 17 public: 18 ScriptData(const byte* data, int length); 19 ~ScriptData() { 20 if (owns_data_) DeleteArray(data_); 21 } 22 23 const byte* data() const { return data_; } 24 int length() const { return length_; } 25 bool rejected() const { return rejected_; } 26 27 void Reject() { rejected_ = true; } 28 29 void AcquireDataOwnership() { 30 DCHECK(!owns_data_); 31 owns_data_ = true; 32 } 33 34 void ReleaseDataOwnership() { 35 DCHECK(owns_data_); 36 owns_data_ = false; 37 } 38 39 private: 40 bool owns_data_ : 1; 41 bool rejected_ : 1; 42 const byte* data_; 43 int length_; 44 45 DISALLOW_COPY_AND_ASSIGN(ScriptData); 46 }; 47 48 // Abstract interface for preparse data recorder. 49 class ParserRecorder { 50 public: 51 ParserRecorder() { } 52 virtual ~ParserRecorder() { } 53 54 // Logs the scope and some details of a function literal in the source. 55 virtual void LogFunction(int start, int end, int literals, int properties, 56 LanguageMode language_mode, bool uses_super_property, 57 bool calls_eval) = 0; 58 59 // Logs an error message and marks the log as containing an error. 60 // Further logging will be ignored, and ExtractData will return a vector 61 // representing the error only. 62 virtual void LogMessage(int start, int end, MessageTemplate::Template message, 63 const char* argument_opt, 64 ParseErrorType error_type) = 0; 65 66 private: 67 DISALLOW_COPY_AND_ASSIGN(ParserRecorder); 68 }; 69 70 71 class SingletonLogger : public ParserRecorder { 72 public: 73 SingletonLogger() 74 : has_error_(false), start_(-1), end_(-1), error_type_(kSyntaxError) {} 75 virtual ~SingletonLogger() {} 76 77 void Reset() { has_error_ = false; } 78 79 virtual void LogFunction(int start, int end, int literals, int properties, 80 LanguageMode language_mode, bool uses_super_property, 81 bool calls_eval) { 82 DCHECK(!has_error_); 83 start_ = start; 84 end_ = end; 85 literals_ = literals; 86 properties_ = properties; 87 language_mode_ = language_mode; 88 uses_super_property_ = uses_super_property; 89 calls_eval_ = calls_eval; 90 } 91 92 // Logs an error message and marks the log as containing an error. 93 // Further logging will be ignored, and ExtractData will return a vector 94 // representing the error only. 95 virtual void LogMessage(int start, int end, MessageTemplate::Template message, 96 const char* argument_opt, ParseErrorType error_type) { 97 if (has_error_) return; 98 has_error_ = true; 99 start_ = start; 100 end_ = end; 101 message_ = message; 102 argument_opt_ = argument_opt; 103 error_type_ = error_type; 104 } 105 106 bool has_error() const { return has_error_; } 107 108 int start() const { return start_; } 109 int end() const { return end_; } 110 int literals() const { 111 DCHECK(!has_error_); 112 return literals_; 113 } 114 int properties() const { 115 DCHECK(!has_error_); 116 return properties_; 117 } 118 LanguageMode language_mode() const { 119 DCHECK(!has_error_); 120 return language_mode_; 121 } 122 bool uses_super_property() const { 123 DCHECK(!has_error_); 124 return uses_super_property_; 125 } 126 bool calls_eval() const { 127 DCHECK(!has_error_); 128 return calls_eval_; 129 } 130 ParseErrorType error_type() const { 131 DCHECK(has_error_); 132 return error_type_; 133 } 134 MessageTemplate::Template message() { 135 DCHECK(has_error_); 136 return message_; 137 } 138 const char* argument_opt() const { 139 DCHECK(has_error_); 140 return argument_opt_; 141 } 142 143 private: 144 bool has_error_; 145 int start_; 146 int end_; 147 // For function entries. 148 int literals_; 149 int properties_; 150 LanguageMode language_mode_; 151 bool uses_super_property_; 152 bool calls_eval_; 153 // For error messages. 154 MessageTemplate::Template message_; 155 const char* argument_opt_; 156 ParseErrorType error_type_; 157 }; 158 159 160 class CompleteParserRecorder : public ParserRecorder { 161 public: 162 struct Key { 163 bool is_one_byte; 164 Vector<const byte> literal_bytes; 165 }; 166 167 CompleteParserRecorder(); 168 virtual ~CompleteParserRecorder() {} 169 170 virtual void LogFunction(int start, int end, int literals, int properties, 171 LanguageMode language_mode, bool uses_super_property, 172 bool calls_eval) { 173 function_store_.Add(start); 174 function_store_.Add(end); 175 function_store_.Add(literals); 176 function_store_.Add(properties); 177 function_store_.Add(language_mode); 178 function_store_.Add(uses_super_property); 179 function_store_.Add(calls_eval); 180 } 181 182 // Logs an error message and marks the log as containing an error. 183 // Further logging will be ignored, and ExtractData will return a vector 184 // representing the error only. 185 virtual void LogMessage(int start, int end, MessageTemplate::Template message, 186 const char* argument_opt, ParseErrorType error_type); 187 ScriptData* GetScriptData(); 188 189 bool HasError() { 190 return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]); 191 } 192 Vector<unsigned> ErrorMessageData() { 193 DCHECK(HasError()); 194 return function_store_.ToVector(); 195 } 196 197 private: 198 void WriteString(Vector<const char> str); 199 200 Collector<unsigned> function_store_; 201 unsigned preamble_[PreparseDataConstants::kHeaderSize]; 202 203 #ifdef DEBUG 204 int prev_start_; 205 #endif 206 }; 207 208 209 } // namespace internal 210 } // namespace v8. 211 212 #endif // V8_PARSING_PREPARSE_DATA_H_ 213