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: 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. 78 virtual void LogAsciiSymbol(int start, Vector<const char> 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(); 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 166 class PartialParserRecorder : public FunctionLoggingParserRecorder { 167 public: 168 PartialParserRecorder() : FunctionLoggingParserRecorder() { } 169 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { } 170 virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { } 171 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 181 class CompleteParserRecorder: public FunctionLoggingParserRecorder { 182 public: 183 CompleteParserRecorder(); 184 virtual ~CompleteParserRecorder() { } 185 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 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 200 virtual int symbol_position() { return symbol_store_.size(); } 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> 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 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