Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_LEXER_EXPERIMENTAL_SCANNER_H | 28 #ifndef V8_LEXER_EXPERIMENTAL_SCANNER_H |
| 29 #define V8_LEXER_EXPERIMENTAL_SCANNER_H | 29 #define V8_LEXER_EXPERIMENTAL_SCANNER_H |
| 30 | 30 |
| 31 #include <set> | |
| 32 | |
| 31 #include "compiler.h" | 33 #include "compiler.h" |
| 32 #include "isolate.h" | 34 #include "isolate.h" |
| 33 #include "scanner.h" // UnicodeCache. | 35 #include "scanner.h" // UnicodeCache. |
| 34 #include "token.h" | 36 #include "token.h" |
| 35 #include "utils.h" | 37 #include "utils.h" |
| 36 #include "v8stdint.h" | 38 #include "v8stdint.h" |
| 37 | 39 |
| 38 namespace v8 { | 40 namespace v8 { |
| 39 namespace internal { | 41 namespace internal { |
| 40 | 42 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 52 return beg_pos >= 0 && end_pos >= beg_pos; | 54 return beg_pos >= 0 && end_pos >= beg_pos; |
| 53 } | 55 } |
| 54 | 56 |
| 55 static Location invalid() { return Location(-1, -1); } | 57 static Location invalid() { return Location(-1, -1); } |
| 56 | 58 |
| 57 int beg_pos; | 59 int beg_pos; |
| 58 int end_pos; | 60 int end_pos; |
| 59 }; | 61 }; |
| 60 | 62 |
| 61 explicit ScannerBase(Isolate* isolate) | 63 explicit ScannerBase(Isolate* isolate) |
| 62 : unicode_cache_(isolate->unicode_cache()), | 64 : isolate_(isolate), |
| 65 unicode_cache_(isolate->unicode_cache()), | |
| 63 has_line_terminator_before_next_(true), | 66 has_line_terminator_before_next_(true), |
| 64 harmony_numeric_literals_(false), | 67 harmony_numeric_literals_(false), |
| 65 harmony_modules_(false), | 68 harmony_modules_(false), |
| 66 harmony_scoping_(false) { | 69 harmony_scoping_(false) { |
| 70 if (!scanners_) { | |
| 71 scanners_ = new std::set<ScannerBase*>(); | |
| 72 isolate->heap()->AddGCEpilogueCallback(&ScannerBase::UpdateBuffersAfterGC, | |
| 73 kGCTypeAll, false); | |
| 74 } | |
| 75 scanners_->insert(this); | |
| 67 } | 76 } |
| 68 | 77 |
| 69 virtual ~ScannerBase() { } | 78 virtual ~ScannerBase() { |
| 79 scanners_->erase(this); | |
| 80 if (scanners_->empty()) { | |
| 81 isolate_->heap()->RemoveGCEpilogueCallback( | |
| 82 &ScannerBase::UpdateBuffersAfterGC); | |
| 83 delete scanners_; | |
| 84 scanners_ = NULL; | |
| 85 } | |
| 86 } | |
| 70 | 87 |
| 71 // Returns the next token and advances input. | 88 // Returns the next token and advances input. |
| 72 Token::Value Next() { | 89 Token::Value Next() { |
| 73 has_line_terminator_before_next_ = false; | 90 has_line_terminator_before_next_ = false; |
| 74 current_ = next_; | 91 current_ = next_; |
| 75 Scan(); // Virtual! Will fill in next_. | 92 Scan(); // Virtual! Will fill in next_. |
| 76 return current_.token; | 93 return current_.token; |
| 77 } | 94 } |
| 78 | 95 |
| 79 // Returns the current token again. | 96 // Returns the current token again. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 | 192 |
| 176 protected: | 193 protected: |
| 177 struct TokenDesc { | 194 struct TokenDesc { |
| 178 Token::Value token; | 195 Token::Value token; |
| 179 int beg_pos; | 196 int beg_pos; |
| 180 int end_pos; | 197 int end_pos; |
| 181 }; | 198 }; |
| 182 | 199 |
| 183 virtual void Scan() = 0; | 200 virtual void Scan() = 0; |
| 184 virtual uc32 ScanHexNumber(int length) = 0; | 201 virtual uc32 ScanHexNumber(int length) = 0; |
| 202 virtual void SetBufferBasedOnHandle() = 0; | |
| 203 | |
| 204 static void UpdateBuffersAfterGC(v8::Isolate*, GCType, GCCallbackFlags); | |
| 205 | |
| 185 | 206 |
| 186 bool ValidIdentifierPart() { | 207 bool ValidIdentifierPart() { |
| 187 return unicode_cache_->IsIdentifierPart(ScanHexNumber(4)); | 208 return unicode_cache_->IsIdentifierPart(ScanHexNumber(4)); |
| 188 } | 209 } |
| 189 | 210 |
| 190 bool ValidIdentifierStart() { | 211 bool ValidIdentifierStart() { |
| 191 return unicode_cache_->IsIdentifierStart(ScanHexNumber(4)); | 212 return unicode_cache_->IsIdentifierStart(ScanHexNumber(4)); |
| 192 } | 213 } |
| 193 | 214 |
| 215 Isolate* isolate_; | |
| 194 UnicodeCache* unicode_cache_; | 216 UnicodeCache* unicode_cache_; |
| 195 | 217 |
| 196 bool has_line_terminator_before_next_; | 218 bool has_line_terminator_before_next_; |
| 197 | 219 |
| 198 TokenDesc current_; // desc for current token (as returned by Next()) | 220 TokenDesc current_; // desc for current token (as returned by Next()) |
| 199 TokenDesc next_; // desc for next token (one token look-ahead) | 221 TokenDesc next_; // desc for next token (one token look-ahead) |
| 200 | 222 |
| 201 bool harmony_numeric_literals_; | 223 bool harmony_numeric_literals_; |
| 202 bool harmony_modules_; | 224 bool harmony_modules_; |
| 203 bool harmony_scoping_; | 225 bool harmony_scoping_; |
| 226 | |
| 227 private: | |
| 228 static std::set<ScannerBase*>* scanners_; | |
| 204 }; | 229 }; |
| 205 | 230 |
| 206 | 231 |
| 207 template<typename YYCTYPE> | 232 template<typename YYCTYPE> |
| 208 class ExperimentalScanner : public ScannerBase { | 233 class ExperimentalScanner : public ScannerBase { |
| 209 public: | 234 public: |
| 210 explicit ExperimentalScanner( | 235 explicit ExperimentalScanner( |
| 211 YYCTYPE* source, | 236 Handle<String> source, |
| 212 YYCTYPE* source_end, | 237 Isolate* isolate) |
| 213 Isolate* isolate); | 238 : ScannerBase(isolate), |
| 239 source_handle_(source), | |
| 240 buffer_(NULL), | |
| 241 buffer_end_(NULL), | |
| 242 start_(NULL), | |
| 243 cursor_(NULL), | |
| 244 marker_(NULL) { | |
| 245 ASSERT(source->IsFlat()); | |
|
ulan
2013/11/26 13:41:35
You can use FlattenString() instead of assert.
| |
| 246 SetBufferBasedOnHandle(); | |
| 247 Scan(); | |
| 248 } | |
| 214 | 249 |
| 215 virtual ~ExperimentalScanner(); | 250 virtual ~ExperimentalScanner() { } |
| 216 | 251 |
| 217 virtual void Scan(); | 252 virtual void Scan(); |
| 218 virtual uc32 ScanHexNumber(int length); | 253 virtual uc32 ScanHexNumber(int length); |
| 219 | 254 |
| 255 virtual void SetBufferBasedOnHandle() { | |
| 256 // We get a raw pointer from the Handle, but we also update it every time | |
| 257 // there is a GC, so it is safe. | |
| 258 DisallowHeapAllocation no_gc; | |
| 259 const YYCTYPE* new_buffer = GetNewBufferBasedOnHandle(); | |
| 260 if (new_buffer != buffer_) { | |
| 261 int start_offset = start_ - buffer_; | |
| 262 int cursor_offset = cursor_ - buffer_; | |
| 263 int marker_offset = marker_ - buffer_; | |
| 264 buffer_ = new_buffer; | |
| 265 buffer_end_ = buffer_ + source_handle_->length(); | |
| 266 start_ = buffer_ + start_offset; | |
| 267 cursor_ = buffer_ + cursor_offset; | |
| 268 marker_ = buffer_ + marker_offset; | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 const YYCTYPE* GetNewBufferBasedOnHandle() const; | |
| 273 | |
| 220 private: | 274 private: |
| 275 Handle<String> source_handle_; | |
| 221 YYCTYPE yych; | 276 YYCTYPE yych; |
|
dcarney
2013/11/26 13:38:54
yych should be unused now
| |
| 222 YYCTYPE* buffer_; | 277 const YYCTYPE* buffer_; |
| 223 YYCTYPE* buffer_end_; | 278 const YYCTYPE* buffer_end_; |
| 224 YYCTYPE* start_; | 279 const YYCTYPE* start_; |
| 225 YYCTYPE* cursor_; | 280 const YYCTYPE* cursor_; |
| 226 YYCTYPE* marker_; | 281 const YYCTYPE* marker_; |
| 227 }; | 282 }; |
| 228 | 283 |
| 229 | 284 |
| 230 template<typename YYCTYPE> | 285 template<> |
|
dcarney
2013/11/26 13:38:54
do these need to be here?
| |
| 231 ExperimentalScanner<YYCTYPE>::ExperimentalScanner( | 286 void ExperimentalScanner<uint8_t>::Scan(); |
| 232 YYCTYPE* source, | 287 |
| 233 YYCTYPE* source_end, | 288 template<> |
| 234 Isolate* isolate) | 289 void ExperimentalScanner<uint16_t>::Scan(); |
| 235 : ScannerBase(isolate), | 290 |
| 236 buffer_(source), | 291 template<> |
| 237 buffer_end_(source_end), | 292 void ExperimentalScanner<int8_t>::Scan(); |
| 238 start_(source), | |
| 239 cursor_(source), | |
| 240 marker_(source) { | |
| 241 Scan(); | |
| 242 } | |
| 243 | 293 |
| 244 | 294 |
| 245 template<typename YYCTYPE> | 295 template<typename YYCTYPE> |
| 246 ExperimentalScanner<YYCTYPE>::~ExperimentalScanner() { | |
| 247 delete[] buffer_; | |
| 248 } | |
| 249 | |
| 250 | |
| 251 template<typename YYCTYPE> | |
| 252 uc32 ExperimentalScanner<YYCTYPE>::ScanHexNumber(int length) { | 296 uc32 ExperimentalScanner<YYCTYPE>::ScanHexNumber(int length) { |
| 253 // We have seen \uXXXX, let's see what it is. | 297 // We have seen \uXXXX, let's see what it is. |
| 254 // FIXME: we never end up in here if only a subset of the 4 chars are valid | 298 // FIXME: we never end up in here if only a subset of the 4 chars are valid |
| 255 // hex digits -> handle the case where they're not. | 299 // hex digits -> handle the case where they're not. |
| 256 uc32 x = 0; | 300 uc32 x = 0; |
| 257 for (YYCTYPE* s = cursor_ - length; s != cursor_; ++s) { | 301 for (const YYCTYPE* s = cursor_ - length; s != cursor_; ++s) { |
| 258 int d = HexValue(*s); | 302 int d = HexValue(*s); |
| 259 if (d < 0) { | 303 if (d < 0) { |
| 260 return -1; | 304 return -1; |
| 261 } | 305 } |
| 262 x = x * 16 + d; | 306 x = x * 16 + d; |
| 263 } | 307 } |
| 264 return x; | 308 return x; |
| 265 } | 309 } |
| 266 | 310 |
| 267 | 311 |
| 268 } } | 312 } } |
| 269 | 313 |
| 270 #endif // V8_LEXER_EXPERIMENTAL_SCANNER_H | 314 #endif // V8_LEXER_EXPERIMENTAL_SCANNER_H |
| OLD | NEW |