blob: bb5707b61dfe5f234ed5ff6232e84cc133d7b9fd [file] [log] [blame]
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08001// 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
33namespace v8 {
34namespace internal {
35
36// Generic and general data used by preparse data recorders and readers.
37
38class PreparseDataConstants : public AllStatic {
39 public:
40 // Layout and constants of the preparse data exchange format.
41 static const unsigned kMagicNumber = 0xBadDead;
Ben Murdochb8e0da22011-05-16 14:20:40 +010042 static const unsigned kCurrentVersion = 6;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080043
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.
66class ParserRecorder {
67 public:
68 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.
Steve Block9fac8402011-05-12 15:51:54 +010078 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
79 virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080080
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
106class FunctionLoggingParserRecorder : public ParserRecorder {
107 public:
108 FunctionLoggingParserRecorder();
109 virtual ~FunctionLoggingParserRecorder() {}
110
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
126 virtual int function_position() { return function_store_.size(); }
127
128
129 virtual Vector<unsigned> ExtractData() = 0;
130
131 virtual void PauseRecording() {
132 pause_count_++;
133 is_recording_ = false;
134 }
135
136 virtual void ResumeRecording() {
137 ASSERT(pause_count_ > 0);
138 if (--pause_count_ == 0) is_recording_ = !has_error();
139 }
140
141 protected:
142 bool has_error() {
143 return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]);
144 }
145
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
166class PartialParserRecorder : public FunctionLoggingParserRecorder {
167 public:
168 PartialParserRecorder() : FunctionLoggingParserRecorder() { }
Steve Block9fac8402011-05-12 15:51:54 +0100169 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
170 virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800171 virtual ~PartialParserRecorder() { }
172 virtual Vector<unsigned> ExtractData();
173 virtual int symbol_position() { return 0; }
174 virtual int symbol_ids() { return 0; }
175};
176
177
178// ----------------------------------------------------------------------------
179// CompleteParserRecorder - Record both function entries and symbols.
180
181class CompleteParserRecorder: public FunctionLoggingParserRecorder {
182 public:
183 CompleteParserRecorder();
184 virtual ~CompleteParserRecorder() { }
185
Steve Block9fac8402011-05-12 15:51:54 +0100186 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
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 }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800197
198 virtual Vector<unsigned> ExtractData();
199
200 virtual int symbol_position() { return symbol_store_.size(); }
201 virtual int symbol_ids() { return symbol_id_; }
202
203 private:
Steve Block9fac8402011-05-12 15:51:54 +0100204 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>
215 static int vector_hash(Vector<const Char> string) {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800216 int hash = 0;
217 for (int i = 0; i < string.length(); i++) {
Steve Block9fac8402011-05-12 15:51:54 +0100218 int c = static_cast<int>(string[i]);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800219 hash += c;
220 hash += (hash << 10);
221 hash ^= (hash >> 6);
222 }
223 return hash;
224 }
225
226 static bool vector_compare(void* a, void* b) {
Steve Block9fac8402011-05-12 15:51:54 +0100227 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;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800234 }
235
236 // Write a non-negative number to the symbol store.
237 void WriteNumber(int number);
238
Steve Block9fac8402011-05-12 15:51:54 +0100239 Collector<byte> literal_chars_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800240 Collector<byte> symbol_store_;
Steve Block9fac8402011-05-12 15:51:54 +0100241 Collector<Key> symbol_keys_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800242 HashMap symbol_table_;
243 int symbol_id_;
244};
245
246
247} } // namespace v8::internal.
248
249#endif // V8_PREPARSER_DATA_H_