// Copyright 2011 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_PARSING_PREPARSE_DATA_H_ #define V8_PARSING_PREPARSE_DATA_H_ #include "src/allocation.h" #include "src/base/hashmap.h" #include "src/collector.h" #include "src/messages.h" #include "src/parsing/preparse-data-format.h" namespace v8 { namespace internal { class ScriptData { public: ScriptData(const byte* data, int length); ~ScriptData() { if (owns_data_) DeleteArray(data_); } const byte* data() const { return data_; } int length() const { return length_; } bool rejected() const { return rejected_; } void Reject() { rejected_ = true; } void AcquireDataOwnership() { DCHECK(!owns_data_); owns_data_ = true; } void ReleaseDataOwnership() { DCHECK(owns_data_); owns_data_ = false; } private: bool owns_data_ : 1; bool rejected_ : 1; const byte* data_; int length_; DISALLOW_COPY_AND_ASSIGN(ScriptData); }; // Abstract interface for preparse data recorder. class ParserRecorder { public: ParserRecorder() { } virtual ~ParserRecorder() { } // Logs the scope and some details of a function literal in the source. virtual void LogFunction(int start, int end, int literals, int properties, LanguageMode language_mode, bool uses_super_property, bool calls_eval) = 0; // Logs an error message and marks the log as containing an error. // Further logging will be ignored, and ExtractData will return a vector // representing the error only. virtual void LogMessage(int start, int end, MessageTemplate::Template message, const char* argument_opt, ParseErrorType error_type) = 0; private: DISALLOW_COPY_AND_ASSIGN(ParserRecorder); }; class SingletonLogger : public ParserRecorder { public: SingletonLogger() : has_error_(false), start_(-1), end_(-1), error_type_(kSyntaxError) {} virtual ~SingletonLogger() {} void Reset() { has_error_ = false; } virtual void LogFunction(int start, int end, int literals, int properties, LanguageMode language_mode, bool uses_super_property, bool calls_eval) { DCHECK(!has_error_); start_ = start; end_ = end; literals_ = literals; properties_ = properties; language_mode_ = language_mode; uses_super_property_ = uses_super_property; calls_eval_ = calls_eval; } // Logs an error message and marks the log as containing an error. // Further logging will be ignored, and ExtractData will return a vector // representing the error only. virtual void LogMessage(int start, int end, MessageTemplate::Template message, const char* argument_opt, ParseErrorType error_type) { if (has_error_) return; has_error_ = true; start_ = start; end_ = end; message_ = message; argument_opt_ = argument_opt; error_type_ = error_type; } bool has_error() const { return has_error_; } int start() const { return start_; } int end() const { return end_; } int literals() const { DCHECK(!has_error_); return literals_; } int properties() const { DCHECK(!has_error_); return properties_; } LanguageMode language_mode() const { DCHECK(!has_error_); return language_mode_; } bool uses_super_property() const { DCHECK(!has_error_); return uses_super_property_; } bool calls_eval() const { DCHECK(!has_error_); return calls_eval_; } ParseErrorType error_type() const { DCHECK(has_error_); return error_type_; } MessageTemplate::Template message() { DCHECK(has_error_); return message_; } const char* argument_opt() const { DCHECK(has_error_); return argument_opt_; } private: bool has_error_; int start_; int end_; // For function entries. int literals_; int properties_; LanguageMode language_mode_; bool uses_super_property_; bool calls_eval_; // For error messages. MessageTemplate::Template message_; const char* argument_opt_; ParseErrorType error_type_; }; class CompleteParserRecorder : public ParserRecorder { public: struct Key { bool is_one_byte; Vector literal_bytes; }; CompleteParserRecorder(); virtual ~CompleteParserRecorder() {} virtual void LogFunction(int start, int end, int literals, int properties, LanguageMode language_mode, bool uses_super_property, bool calls_eval) { function_store_.Add(start); function_store_.Add(end); function_store_.Add(literals); function_store_.Add(properties); function_store_.Add(language_mode); function_store_.Add(uses_super_property); function_store_.Add(calls_eval); } // Logs an error message and marks the log as containing an error. // Further logging will be ignored, and ExtractData will return a vector // representing the error only. virtual void LogMessage(int start, int end, MessageTemplate::Template message, const char* argument_opt, ParseErrorType error_type); ScriptData* GetScriptData(); bool HasError() { return static_cast(preamble_[PreparseDataConstants::kHasErrorOffset]); } Vector ErrorMessageData() { DCHECK(HasError()); return function_store_.ToVector(); } private: void WriteString(Vector str); Collector function_store_; unsigned preamble_[PreparseDataConstants::kHeaderSize]; #ifdef DEBUG int prev_start_; #endif }; } // namespace internal } // namespace v8. #endif // V8_PARSING_PREPARSE_DATA_H_