• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_PREPARSER_DATA_H_
29 #define V8_PREPARSER_DATA_H_
30 
31 #include "hashmap.h"
32 
33 namespace v8 {
34 namespace internal {
35 
36 // Generic and general data used by preparse data recorders and readers.
37 
38 class PreparseDataConstants : public AllStatic {
39  public:
40   // Layout and constants of the preparse data exchange format.
41   static const unsigned kMagicNumber = 0xBadDead;
42   static const unsigned kCurrentVersion = 6;
43 
44   static const int kMagicOffset = 0;
45   static const int kVersionOffset = 1;
46   static const int kHasErrorOffset = 2;
47   static const int kFunctionsSizeOffset = 3;
48   static const int kSymbolCountOffset = 4;
49   static const int kSizeOffset = 5;
50   static const int kHeaderSize = 6;
51 
52   // If encoding a message, the following positions are fixed.
53   static const int kMessageStartPos = 0;
54   static const int kMessageEndPos = 1;
55   static const int kMessageArgCountPos = 2;
56   static const int kMessageTextPos = 3;
57 
58   static const byte kNumberTerminator = 0x80u;
59 };
60 
61 
62 // ----------------------------------------------------------------------------
63 // ParserRecorder - Logging of preparser data.
64 
65 // Abstract interface for preparse data recorder.
66 class ParserRecorder {
67  public:
ParserRecorder()68   ParserRecorder() { }
~ParserRecorder()69   virtual ~ParserRecorder() { }
70 
71   // Logs the scope and some details of a function literal in the source.
72   virtual void LogFunction(int start,
73                            int end,
74                            int literals,
75                            int properties) = 0;
76 
77   // Logs a symbol creation of a literal or identifier.
LogAsciiSymbol(int start,Vector<const char> literal)78   virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
LogUC16Symbol(int start,Vector<const uc16> literal)79   virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
80 
81   // Logs an error message and marks the log as containing an error.
82   // Further logging will be ignored, and ExtractData will return a vector
83   // representing the error only.
84   virtual void LogMessage(int start,
85                           int end,
86                           const char* message,
87                           const char* argument_opt) = 0;
88 
89   virtual int function_position() = 0;
90 
91   virtual int symbol_position() = 0;
92 
93   virtual int symbol_ids() = 0;
94 
95   virtual Vector<unsigned> ExtractData() = 0;
96 
97   virtual void PauseRecording() = 0;
98 
99   virtual void ResumeRecording() = 0;
100 };
101 
102 
103 // ----------------------------------------------------------------------------
104 // FunctionLoggingParserRecorder - Record only function entries
105 
106 class FunctionLoggingParserRecorder : public ParserRecorder {
107  public:
108   FunctionLoggingParserRecorder();
~FunctionLoggingParserRecorder()109   virtual ~FunctionLoggingParserRecorder() {}
110 
LogFunction(int start,int end,int literals,int properties)111   virtual void LogFunction(int start, int end, int literals, int properties) {
112     function_store_.Add(start);
113     function_store_.Add(end);
114     function_store_.Add(literals);
115     function_store_.Add(properties);
116   }
117 
118   // Logs an error message and marks the log as containing an error.
119   // Further logging will be ignored, and ExtractData will return a vector
120   // representing the error only.
121   virtual void LogMessage(int start,
122                           int end,
123                           const char* message,
124                           const char* argument_opt);
125 
function_position()126   virtual int function_position() { return function_store_.size(); }
127 
128 
129   virtual Vector<unsigned> ExtractData() = 0;
130 
PauseRecording()131   virtual void PauseRecording() {
132     pause_count_++;
133     is_recording_ = false;
134   }
135 
ResumeRecording()136   virtual void ResumeRecording() {
137     ASSERT(pause_count_ > 0);
138     if (--pause_count_ == 0) is_recording_ = !has_error();
139   }
140 
141  protected:
has_error()142   bool has_error() {
143     return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]);
144   }
145 
is_recording()146   bool is_recording() {
147     return is_recording_;
148   }
149 
150   void WriteString(Vector<const char> str);
151 
152   Collector<unsigned> function_store_;
153   unsigned preamble_[PreparseDataConstants::kHeaderSize];
154   bool is_recording_;
155   int pause_count_;
156 
157 #ifdef DEBUG
158   int prev_start_;
159 #endif
160 };
161 
162 
163 // ----------------------------------------------------------------------------
164 // PartialParserRecorder - Record only function entries
165 
166 class PartialParserRecorder : public FunctionLoggingParserRecorder {
167  public:
PartialParserRecorder()168   PartialParserRecorder() : FunctionLoggingParserRecorder() { }
LogAsciiSymbol(int start,Vector<const char> literal)169   virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
LogUC16Symbol(int start,Vector<const uc16> literal)170   virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
~PartialParserRecorder()171   virtual ~PartialParserRecorder() { }
172   virtual Vector<unsigned> ExtractData();
symbol_position()173   virtual int symbol_position() { return 0; }
symbol_ids()174   virtual int symbol_ids() { return 0; }
175 };
176 
177 
178 // ----------------------------------------------------------------------------
179 // CompleteParserRecorder -  Record both function entries and symbols.
180 
181 class CompleteParserRecorder: public FunctionLoggingParserRecorder {
182  public:
183   CompleteParserRecorder();
~CompleteParserRecorder()184   virtual ~CompleteParserRecorder() { }
185 
LogAsciiSymbol(int start,Vector<const char> literal)186   virtual void LogAsciiSymbol(int start, Vector<const char> literal) {
187     if (!is_recording_) return;
188     int hash = vector_hash(literal);
189     LogSymbol(start, hash, true, Vector<const byte>::cast(literal));
190   }
191 
LogUC16Symbol(int start,Vector<const uc16> literal)192   virtual void LogUC16Symbol(int start, Vector<const uc16> literal) {
193     if (!is_recording_) return;
194     int hash = vector_hash(literal);
195     LogSymbol(start, hash, false, Vector<const byte>::cast(literal));
196   }
197 
198   virtual Vector<unsigned> ExtractData();
199 
symbol_position()200   virtual int symbol_position() { return symbol_store_.size(); }
symbol_ids()201   virtual int symbol_ids() { return symbol_id_; }
202 
203  private:
204   struct Key {
205     bool is_ascii;
206     Vector<const byte> literal_bytes;
207   };
208 
209   virtual void LogSymbol(int start,
210                          int hash,
211                          bool is_ascii,
212                          Vector<const byte> literal);
213 
214   template <typename Char>
vector_hash(Vector<const Char> string)215   static int vector_hash(Vector<const Char> string) {
216     int hash = 0;
217     for (int i = 0; i < string.length(); i++) {
218       int c = static_cast<int>(string[i]);
219       hash += c;
220       hash += (hash << 10);
221       hash ^= (hash >> 6);
222     }
223     return hash;
224   }
225 
vector_compare(void * a,void * b)226   static bool vector_compare(void* a, void* b) {
227     Key* string1 = reinterpret_cast<Key*>(a);
228     Key* string2 = reinterpret_cast<Key*>(b);
229     if (string1->is_ascii != string2->is_ascii) return false;
230     int length = string1->literal_bytes.length();
231     if (string2->literal_bytes.length() != length) return false;
232     return memcmp(string1->literal_bytes.start(),
233                   string2->literal_bytes.start(), length) == 0;
234   }
235 
236   // Write a non-negative number to the symbol store.
237   void WriteNumber(int number);
238 
239   Collector<byte> literal_chars_;
240   Collector<byte> symbol_store_;
241   Collector<Key> symbol_keys_;
242   HashMap symbol_table_;
243   int symbol_id_;
244 };
245 
246 
247 } }  // namespace v8::internal.
248 
249 #endif  // V8_PREPARSER_DATA_H_
250