| 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 | |
| 33 #include "compiler.h" | 31 #include "compiler.h" |
| 34 #include "isolate.h" | 32 #include "isolate.h" |
| 35 #include "scanner.h" // UnicodeCache. | 33 #include "scanner.h" // UnicodeCache. |
| 36 #include "token.h" | 34 #include "token.h" |
| 37 #include "utils.h" | 35 #include "utils.h" |
| 38 #include "v8stdint.h" | 36 #include "v8stdint.h" |
| 39 #include "char-predicates-inl.h" | 37 #include "char-predicates-inl.h" |
| 40 | 38 |
| 41 namespace v8 { | 39 namespace v8 { |
| 42 namespace internal { | 40 namespace internal { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 63 | 61 |
| 64 explicit ScannerBase(Isolate* isolate) | 62 explicit ScannerBase(Isolate* isolate) |
| 65 : isolate_(isolate), | 63 : isolate_(isolate), |
| 66 unicode_cache_(isolate->unicode_cache()), | 64 unicode_cache_(isolate->unicode_cache()), |
| 67 has_line_terminator_before_next_(true), | 65 has_line_terminator_before_next_(true), |
| 68 current_literal_(&literals_[0]), | 66 current_literal_(&literals_[0]), |
| 69 next_literal_(&literals_[1]), | 67 next_literal_(&literals_[1]), |
| 70 harmony_numeric_literals_(false), | 68 harmony_numeric_literals_(false), |
| 71 harmony_modules_(false), | 69 harmony_modules_(false), |
| 72 harmony_scoping_(false) { | 70 harmony_scoping_(false) { |
| 73 if (!scanners_) { | 71 isolate->AddScanner(this); |
| 74 scanners_ = new std::set<ScannerBase*>(); | |
| 75 isolate->heap()->AddGCEpilogueCallback(&ScannerBase::UpdateBuffersAfterGC, | |
| 76 kGCTypeAll, false); | |
| 77 } | |
| 78 scanners_->insert(this); | |
| 79 } | 72 } |
| 80 | 73 |
| 81 virtual ~ScannerBase() { | 74 virtual ~ScannerBase() { |
| 82 scanners_->erase(this); | 75 isolate_->RemoveScanner(this); |
| 83 if (scanners_->empty()) { | |
| 84 isolate_->heap()->RemoveGCEpilogueCallback( | |
| 85 &ScannerBase::UpdateBuffersAfterGC); | |
| 86 delete scanners_; | |
| 87 scanners_ = NULL; | |
| 88 } | |
| 89 } | 76 } |
| 90 | 77 |
| 91 // Has to be called after creating the scanner and setting the flags. | 78 // Has to be called after creating the scanner and setting the flags. |
| 92 virtual void Init() = 0; | 79 virtual void Init() = 0; |
| 93 | 80 |
| 94 // Seek forward to the given position. This operation works for simple cases | 81 // Seek forward to the given position. This operation works for simple cases |
| 95 // such as seeking forward until simple delimiter tokens, which is what it is | 82 // such as seeking forward until simple delimiter tokens, which is what it is |
| 96 // used for. After this call, we will have the token at the given position as | 83 // used for. After this call, we will have the token at the given position as |
| 97 // the "next" token. The "current" token will be invalid. FIXME: for utf-8, | 84 // the "next" token. The "current" token will be invalid. FIXME: for utf-8, |
| 98 // we need to decide if pos is counted in characters or in bytes. | 85 // we need to decide if pos is counted in characters or in bytes. |
| 99 virtual void SeekForward(int pos) = 0; | 86 virtual void SeekForward(int pos) = 0; |
| 100 virtual void SetEnd(int pos) = 0; | 87 virtual void SetEnd(int pos) = 0; |
| 101 | 88 |
| 102 // Scans the input as a regular expression pattern, previous character(s) must | 89 // Scans the input as a regular expression pattern, previous character(s) must |
| 103 // be /(=). Returns true if a pattern is scanned. FIXME: this won't work for | 90 // be /(=). Returns true if a pattern is scanned. FIXME: this won't work for |
| 104 // utf-8 newlines. | 91 // utf-8 newlines. |
| 105 virtual bool ScanRegExpPattern(bool seen_equal) = 0; | 92 virtual bool ScanRegExpPattern(bool seen_equal) = 0; |
| 106 // Returns true if regexp flags are scanned (always since flags can | 93 // Returns true if regexp flags are scanned (always since flags can |
| 107 // be empty). | 94 // be empty). |
| 108 virtual bool ScanRegExpFlags() = 0; | 95 virtual bool ScanRegExpFlags() = 0; |
| 109 | 96 |
| 110 // Returns the location of the last seen octal literal. | 97 // Returns the location of the last seen octal literal. |
| 111 virtual Location octal_position() const = 0; | 98 virtual Location octal_position() const = 0; |
| 112 virtual void clear_octal_position() = 0; | 99 virtual void clear_octal_position() = 0; |
| 113 | 100 |
| 101 // Sets the raw string pointer based on the string handle. Needs to be called |
| 102 // right after GC. |
| 103 virtual void UpdateBufferBasedOnHandle() = 0; |
| 104 |
| 114 // Returns the next token and advances input. | 105 // Returns the next token and advances input. |
| 115 Token::Value Next() { | 106 Token::Value Next() { |
| 116 has_line_terminator_before_next_ = false; | 107 has_line_terminator_before_next_ = false; |
| 117 current_ = next_; | 108 current_ = next_; |
| 118 std::swap(current_literal_, next_literal_); | 109 std::swap(current_literal_, next_literal_); |
| 119 Scan(); // Virtual! Will fill in next_. | 110 Scan(); // Virtual! Will fill in next_. |
| 120 return current_.token; | 111 return current_.token; |
| 121 } | 112 } |
| 122 | 113 |
| 123 // Returns the current token again. | 114 // Returns the current token again. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 bool is_ascii; | 244 bool is_ascii; |
| 254 int length; | 245 int length; |
| 255 Vector<const char> ascii_string; | 246 Vector<const char> ascii_string; |
| 256 Vector<const uc16> utf16_string; | 247 Vector<const uc16> utf16_string; |
| 257 LiteralBuffer buffer; | 248 LiteralBuffer buffer; |
| 258 LiteralDesc() : beg_pos(-1), is_ascii(false), length(0) { } | 249 LiteralDesc() : beg_pos(-1), is_ascii(false), length(0) { } |
| 259 bool Valid(int pos) { return beg_pos == pos; } | 250 bool Valid(int pos) { return beg_pos == pos; } |
| 260 }; | 251 }; |
| 261 | 252 |
| 262 virtual void Scan() = 0; | 253 virtual void Scan() = 0; |
| 263 virtual void SetBufferBasedOnHandle() = 0; | |
| 264 | |
| 265 static void UpdateBuffersAfterGC(v8::Isolate*, GCType, GCCallbackFlags); | |
| 266 virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal) = 0; | 254 virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal) = 0; |
| 267 | 255 |
| 268 Isolate* isolate_; | 256 Isolate* isolate_; |
| 269 UnicodeCache* unicode_cache_; | 257 UnicodeCache* unicode_cache_; |
| 270 | 258 |
| 271 bool has_line_terminator_before_next_; | 259 bool has_line_terminator_before_next_; |
| 272 | 260 |
| 273 TokenDesc current_; // desc for current token (as returned by Next()) | 261 TokenDesc current_; // desc for current token (as returned by Next()) |
| 274 TokenDesc next_; // desc for next token (one token look-ahead) | 262 TokenDesc next_; // desc for next token (one token look-ahead) |
| 275 | 263 |
| 276 LiteralDesc* current_literal_; | 264 LiteralDesc* current_literal_; |
| 277 LiteralDesc* next_literal_; | 265 LiteralDesc* next_literal_; |
| 278 LiteralDesc literals_[2]; | 266 LiteralDesc literals_[2]; |
| 279 | 267 |
| 280 bool harmony_numeric_literals_; | 268 bool harmony_numeric_literals_; |
| 281 bool harmony_modules_; | 269 bool harmony_modules_; |
| 282 bool harmony_scoping_; | 270 bool harmony_scoping_; |
| 283 | |
| 284 private: | |
| 285 static std::set<ScannerBase*>* scanners_; | |
| 286 }; | 271 }; |
| 287 | 272 |
| 288 | 273 |
| 289 template<typename Char> | 274 template<typename Char> |
| 290 class ExperimentalScanner : public ScannerBase { | 275 class ExperimentalScanner : public ScannerBase { |
| 291 public: | 276 public: |
| 292 explicit ExperimentalScanner( | 277 explicit ExperimentalScanner( |
| 293 Handle<String> source, | 278 Handle<String> source, |
| 294 Isolate* isolate) | 279 Isolate* isolate) |
| 295 : ScannerBase(isolate), | 280 : ScannerBase(isolate), |
| 296 source_handle_(source), | 281 source_handle_(source), |
| 297 buffer_(NULL), | 282 buffer_(NULL), |
| 298 buffer_end_(NULL), | 283 buffer_end_(NULL), |
| 299 start_(NULL), | 284 start_(NULL), |
| 300 cursor_(NULL), | 285 cursor_(NULL), |
| 301 marker_(NULL), | 286 marker_(NULL), |
| 302 last_octal_end_(NULL) { | 287 last_octal_end_(NULL) { |
| 303 ASSERT(source->IsFlat()); | 288 ASSERT(source->IsFlat()); |
| 304 SetBufferBasedOnHandle(); | 289 UpdateBufferBasedOnHandle(); |
| 305 current_.beg_pos = current_.end_pos = next_.beg_pos = next_.end_pos = 0; | 290 current_.beg_pos = current_.end_pos = next_.beg_pos = next_.end_pos = 0; |
| 306 } | 291 } |
| 307 | 292 |
| 308 virtual void Init() { | 293 virtual void Init() { |
| 309 Scan(); | 294 Scan(); |
| 310 } | 295 } |
| 311 | 296 |
| 312 virtual ~ExperimentalScanner() { } | 297 virtual ~ExperimentalScanner() { } |
| 313 | 298 |
| 314 virtual void SeekForward(int pos); | 299 virtual void SeekForward(int pos); |
| 315 virtual void SetEnd(int pos); | 300 virtual void SetEnd(int pos); |
| 316 virtual bool ScanRegExpPattern(bool seen_equal); | 301 virtual bool ScanRegExpPattern(bool seen_equal); |
| 317 virtual bool ScanRegExpFlags(); | 302 virtual bool ScanRegExpFlags(); |
| 318 virtual Location octal_position() const; | 303 virtual Location octal_position() const; |
| 319 virtual void clear_octal_position() { | 304 virtual void clear_octal_position() { |
| 320 last_octal_end_ = NULL; | 305 last_octal_end_ = NULL; |
| 321 } | 306 } |
| 322 | 307 |
| 323 protected: | 308 virtual void UpdateBufferBasedOnHandle() { |
| 324 virtual void Scan(); | |
| 325 | |
| 326 virtual void SetBufferBasedOnHandle() { | |
| 327 // We get a raw pointer from the Handle, but we also update it every time | 309 // We get a raw pointer from the Handle, but we also update it every time |
| 328 // there is a GC, so it is safe. | 310 // there is a GC, so it is safe. |
| 329 DisallowHeapAllocation no_gc; | 311 DisallowHeapAllocation no_gc; |
| 330 const Char* new_buffer = GetNewBufferBasedOnHandle(); | 312 const Char* new_buffer = GetNewBufferBasedOnHandle(); |
| 331 if (new_buffer != buffer_) { | 313 if (new_buffer != buffer_) { |
| 332 int start_offset = start_ - buffer_; | 314 int start_offset = start_ - buffer_; |
| 333 int cursor_offset = cursor_ - buffer_; | 315 int cursor_offset = cursor_ - buffer_; |
| 334 int marker_offset = marker_ - buffer_; | 316 int marker_offset = marker_ - buffer_; |
| 335 buffer_ = new_buffer; | 317 buffer_ = new_buffer; |
| 336 buffer_end_ = buffer_ + source_handle_->length(); | 318 buffer_end_ = buffer_ + source_handle_->length(); |
| 337 start_ = buffer_ + start_offset; | 319 start_ = buffer_ + start_offset; |
| 338 cursor_ = buffer_ + cursor_offset; | 320 cursor_ = buffer_ + cursor_offset; |
| 339 marker_ = buffer_ + marker_offset; | 321 marker_ = buffer_ + marker_offset; |
| 340 } | 322 } |
| 341 } | 323 } |
| 342 | 324 |
| 325 protected: |
| 326 virtual void Scan(); |
| 327 |
| 343 const Char* GetNewBufferBasedOnHandle() const; | 328 const Char* GetNewBufferBasedOnHandle() const; |
| 344 | 329 |
| 345 virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal); | 330 virtual bool FillLiteral(const TokenDesc& token, LiteralDesc* literal); |
| 346 | 331 |
| 347 private: | 332 private: |
| 348 bool ValidIdentifierPart() { | 333 bool ValidIdentifierPart() { |
| 349 return unicode_cache_->IsIdentifierPart(ScanHexNumber(4)); | 334 return unicode_cache_->IsIdentifierPart(ScanHexNumber(4)); |
| 350 } | 335 } |
| 351 | 336 |
| 352 bool ValidIdentifierStart() { | 337 bool ValidIdentifierStart() { |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 // character. | 596 // character. |
| 612 const Char* temp_cursor = last_octal_end_ - 1; | 597 const Char* temp_cursor = last_octal_end_ - 1; |
| 613 while (temp_cursor >= buffer_ && *temp_cursor >= '0' && *temp_cursor <= '7') | 598 while (temp_cursor >= buffer_ && *temp_cursor >= '0' && *temp_cursor <= '7') |
| 614 --temp_cursor; | 599 --temp_cursor; |
| 615 return Location(temp_cursor - buffer_ + 1, last_octal_end_ - buffer_); | 600 return Location(temp_cursor - buffer_ + 1, last_octal_end_ - buffer_); |
| 616 } | 601 } |
| 617 | 602 |
| 618 } } | 603 } } |
| 619 | 604 |
| 620 #endif // V8_LEXER_EXPERIMENTAL_SCANNER_H | 605 #endif // V8_LEXER_EXPERIMENTAL_SCANNER_H |
| OLD | NEW |