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