Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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" |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 9 | #include "src/base/hashmap.h" |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 10 | #include "src/collector.h" |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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_ |