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