Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: src/lexer/experimental-scanner.h

Issue 91833002: Experimental scanner: keeping track of octal numbers octal escapes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/lexer/lexer-shell.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 int beg_pos; 60 int beg_pos;
61 int end_pos; 61 int end_pos;
62 }; 62 };
63 63
64 explicit ScannerBase(Isolate* isolate) 64 explicit ScannerBase(Isolate* isolate)
65 : isolate_(isolate), 65 : isolate_(isolate),
66 unicode_cache_(isolate->unicode_cache()), 66 unicode_cache_(isolate->unicode_cache()),
67 has_line_terminator_before_next_(true), 67 has_line_terminator_before_next_(true),
68 current_literal_(&literals_[0]), 68 current_literal_(&literals_[0]),
69 next_literal_(&literals_[1]), 69 next_literal_(&literals_[1]),
70 octal_pos_(Location::invalid()),
71 harmony_numeric_literals_(false), 70 harmony_numeric_literals_(false),
72 harmony_modules_(false), 71 harmony_modules_(false),
73 harmony_scoping_(false) { 72 harmony_scoping_(false) {
74 if (!scanners_) { 73 if (!scanners_) {
75 scanners_ = new std::set<ScannerBase*>(); 74 scanners_ = new std::set<ScannerBase*>();
76 isolate->heap()->AddGCEpilogueCallback(&ScannerBase::UpdateBuffersAfterGC, 75 isolate->heap()->AddGCEpilogueCallback(&ScannerBase::UpdateBuffersAfterGC,
77 kGCTypeAll, false); 76 kGCTypeAll, false);
78 } 77 }
79 scanners_->insert(this); 78 scanners_->insert(this);
80 } 79 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 return next_literal_->is_ascii; 209 return next_literal_->is_ascii;
211 } 210 }
212 211
213 bool is_next_contextual_keyword(Vector<const char> keyword) { 212 bool is_next_contextual_keyword(Vector<const char> keyword) {
214 if (!is_next_literal_ascii()) return false; 213 if (!is_next_literal_ascii()) return false;
215 Vector<const char> literal = next_literal_ascii_string(); 214 Vector<const char> literal = next_literal_ascii_string();
216 return literal.length() == keyword.length() && 215 return literal.length() == keyword.length() &&
217 (memcmp(literal.start(), keyword.start(), literal.length()) == 0); 216 (memcmp(literal.start(), keyword.start(), literal.length()) == 0);
218 } 217 }
219 218
220 // Returns the location of the last seen octal literal.
221 Location octal_position() const { return octal_pos_; }
222 void clear_octal_position() { octal_pos_ = Location::invalid(); }
223
224 // Seek forward to the given position. This operation works for simple cases 219 // Seek forward to the given position. This operation works for simple cases
225 // such as seeking forward until simple delimiter tokens, which is what it is 220 // such as seeking forward until simple delimiter tokens, which is what it is
226 // used for. After this call, we will have the token at the given position as 221 // used for. After this call, we will have the token at the given position as
227 // the "next" token. The "current" token will be invalid. FIXME: for utf-8, 222 // the "next" token. The "current" token will be invalid. FIXME: for utf-8,
228 // we need to decide if pos is counted in characters or in bytes. 223 // we need to decide if pos is counted in characters or in bytes.
229 virtual void SeekForward(int pos) = 0; 224 virtual void SeekForward(int pos) = 0;
230 virtual void SetEnd(int pos) = 0; 225 virtual void SetEnd(int pos) = 0;
231 226
232 // Scans the input as a regular expression pattern, previous character(s) must 227 // Scans the input as a regular expression pattern, previous character(s) must
233 // be /(=). Returns true if a pattern is scanned. FIXME: this won't work for 228 // be /(=). Returns true if a pattern is scanned. FIXME: this won't work for
234 // utf-8 newlines. 229 // utf-8 newlines.
235 virtual bool ScanRegExpPattern(bool seen_equal) = 0; 230 virtual bool ScanRegExpPattern(bool seen_equal) = 0;
236 // Returns true if regexp flags are scanned (always since flags can 231 // Returns true if regexp flags are scanned (always since flags can
237 // be empty). 232 // be empty).
238 virtual bool ScanRegExpFlags() = 0; 233 virtual bool ScanRegExpFlags() = 0;
239 234
235 // Returns the location of the last seen octal literal.
236 virtual Location octal_position() const = 0;
237 virtual void clear_octal_position() = 0;
238
240 protected: 239 protected:
241 struct TokenDesc { 240 struct TokenDesc {
242 Token::Value token; 241 Token::Value token;
243 int beg_pos; 242 int beg_pos;
244 int end_pos; 243 int end_pos;
245 bool has_escapes; 244 bool has_escapes;
246 }; 245 };
247 246
248 struct LiteralDesc { 247 struct LiteralDesc {
249 int beg_pos; 248 int beg_pos;
(...skipping 16 matching lines...) Expand all
266 265
267 bool has_line_terminator_before_next_; 266 bool has_line_terminator_before_next_;
268 267
269 TokenDesc current_; // desc for current token (as returned by Next()) 268 TokenDesc current_; // desc for current token (as returned by Next())
270 TokenDesc next_; // desc for next token (one token look-ahead) 269 TokenDesc next_; // desc for next token (one token look-ahead)
271 270
272 LiteralDesc* current_literal_; 271 LiteralDesc* current_literal_;
273 LiteralDesc* next_literal_; 272 LiteralDesc* next_literal_;
274 LiteralDesc literals_[2]; 273 LiteralDesc literals_[2];
275 274
276 Location octal_pos_;
277
278 bool harmony_numeric_literals_; 275 bool harmony_numeric_literals_;
279 bool harmony_modules_; 276 bool harmony_modules_;
280 bool harmony_scoping_; 277 bool harmony_scoping_;
281 278
282 private: 279 private:
283 static std::set<ScannerBase*>* scanners_; 280 static std::set<ScannerBase*>* scanners_;
284 }; 281 };
285 282
286 283
287 template<typename Char> 284 template<typename Char>
288 class ExperimentalScanner : public ScannerBase { 285 class ExperimentalScanner : public ScannerBase {
289 public: 286 public:
290 explicit ExperimentalScanner( 287 explicit ExperimentalScanner(
291 Handle<String> source, 288 Handle<String> source,
292 Isolate* isolate) 289 Isolate* isolate)
293 : ScannerBase(isolate), 290 : ScannerBase(isolate),
294 source_handle_(source), 291 source_handle_(source),
295 buffer_(NULL), 292 buffer_(NULL),
296 buffer_end_(NULL), 293 buffer_end_(NULL),
297 start_(NULL), 294 start_(NULL),
298 cursor_(NULL), 295 cursor_(NULL),
299 marker_(NULL) { 296 marker_(NULL),
297 last_octal_end_(NULL) {
300 ASSERT(source->IsFlat()); 298 ASSERT(source->IsFlat());
301 SetBufferBasedOnHandle(); 299 SetBufferBasedOnHandle();
302 Scan(); 300 Scan();
303 } 301 }
304 302
305 virtual ~ExperimentalScanner() { } 303 virtual ~ExperimentalScanner() { }
306 304
307 protected:
308 virtual void Scan();
309 virtual void SeekForward(int pos); 305 virtual void SeekForward(int pos);
310 virtual void SetEnd(int pos); 306 virtual void SetEnd(int pos);
311 virtual bool ScanRegExpPattern(bool seen_equal); 307 virtual bool ScanRegExpPattern(bool seen_equal);
312 virtual bool ScanRegExpFlags(); 308 virtual bool ScanRegExpFlags();
309 virtual Location octal_position() const;
310 virtual void clear_octal_position() {
311 last_octal_end_ = NULL;
312 }
313
314 protected:
315 virtual void Scan();
313 316
314 virtual void SetBufferBasedOnHandle() { 317 virtual void SetBufferBasedOnHandle() {
315 // We get a raw pointer from the Handle, but we also update it every time 318 // We get a raw pointer from the Handle, but we also update it every time
316 // there is a GC, so it is safe. 319 // there is a GC, so it is safe.
317 DisallowHeapAllocation no_gc; 320 DisallowHeapAllocation no_gc;
318 const Char* new_buffer = GetNewBufferBasedOnHandle(); 321 const Char* new_buffer = GetNewBufferBasedOnHandle();
319 if (new_buffer != buffer_) { 322 if (new_buffer != buffer_) {
320 int start_offset = start_ - buffer_; 323 int start_offset = start_ - buffer_;
321 int cursor_offset = cursor_ - buffer_; 324 int cursor_offset = cursor_ - buffer_;
322 int marker_offset = marker_ - buffer_; 325 int marker_offset = marker_ - buffer_;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 const Char* ScanEscape(const Char* start, 359 const Char* ScanEscape(const Char* start,
357 const Char* end, 360 const Char* end,
358 LiteralBuffer* literal); 361 LiteralBuffer* literal);
359 362
360 Handle<String> source_handle_; 363 Handle<String> source_handle_;
361 const Char* buffer_; 364 const Char* buffer_;
362 const Char* buffer_end_; 365 const Char* buffer_end_;
363 const Char* start_; 366 const Char* start_;
364 const Char* cursor_; 367 const Char* cursor_;
365 const Char* marker_; 368 const Char* marker_;
369
370 // Where we have seen the last octal number or an octal escape inside a
371 // string. Used by octal_position().
372 const Char* last_octal_end_;
366 }; 373 };
367 374
368 375
369 template<typename Char> 376 template<typename Char>
370 void ExperimentalScanner<Char>::SeekForward(int pos) { 377 void ExperimentalScanner<Char>::SeekForward(int pos) {
371 cursor_ = buffer_ + pos; 378 cursor_ = buffer_ + pos;
372 start_ = cursor_; 379 start_ = cursor_;
373 marker_ = cursor_; 380 marker_ = cursor_;
374 has_line_terminator_before_next_ = false; 381 has_line_terminator_before_next_ = false;
375 Scan(); // Fills in next_. 382 Scan(); // Fills in next_.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 const Char* start, const Char* end, uc32* result) { 488 const Char* start, const Char* end, uc32* result) {
482 uc32 x = *result - '0'; 489 uc32 x = *result - '0';
483 const Char* cursor; 490 const Char* cursor;
484 for (cursor = start; cursor < end; cursor++) { 491 for (cursor = start; cursor < end; cursor++) {
485 int d = *cursor - '0'; 492 int d = *cursor - '0';
486 if (d < 0 || d > 7) break; 493 if (d < 0 || d > 7) break;
487 int nx = x * 8 + d; 494 int nx = x * 8 + d;
488 if (nx >= 256) break; 495 if (nx >= 256) break;
489 x = nx; 496 x = nx;
490 } 497 }
491 // Anything except '\0' is an octal escape sequence, illegal in strict mode.
492 // Remember the position of octal escape sequences so that an error
493 // can be reported later (in strict mode).
494 // We don't report the error immediately, because the octal escape can
495 // occur before the "use strict" directive.
496 if (*result != '0' || cursor > start) {
497 octal_pos_ = Location(start - 1 - buffer_, cursor - 1 - buffer_);
498 }
499 *result = x; 498 *result = x;
500 return cursor; 499 return cursor;
501 } 500 }
502 501
503 502
504 template<typename Char> 503 template<typename Char>
505 bool ExperimentalScanner<Char>::ScanLiteralUnicodeEscape() { 504 bool ExperimentalScanner<Char>::ScanLiteralUnicodeEscape() {
506 ASSERT(cursor_ < buffer_end_); 505 ASSERT(cursor_ < buffer_end_);
507 Char primary_char = *(cursor_); 506 Char primary_char = *(cursor_);
508 ASSERT(primary_char == '\\'); 507 ASSERT(primary_char == '\\');
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 cursor = ScanOctalEscape(cursor, end, &c); break; 585 cursor = ScanOctalEscape(cursor, end, &c); break;
587 } 586 }
588 587
589 // According to ECMA-262, section 7.8.4, characters not covered by the 588 // According to ECMA-262, section 7.8.4, characters not covered by the
590 // above cases should be illegal, but they are commonly handled as 589 // above cases should be illegal, but they are commonly handled as
591 // non-escaped characters by JS VMs. 590 // non-escaped characters by JS VMs.
592 literal->AddChar(c); 591 literal->AddChar(c);
593 return cursor; 592 return cursor;
594 } 593 }
595 594
595 template<typename Char>
596 ScannerBase::Location ExperimentalScanner<Char>::octal_position() const {
597 if (!last_octal_end_)
598 return Location::invalid();
599 // The last octal might be an octal escape or an octal number. Whichever it
600 // is, we'll find the start by just scanning back until we hit a non-octal
601 // character.
602 const Char* temp_cursor = last_octal_end_ - 1;
603 while (temp_cursor >= buffer_ && *temp_cursor >= '0' && *temp_cursor <= '7')
604 --temp_cursor;
605 return Location(temp_cursor - buffer_ + 1, last_octal_end_ - buffer_);
606 }
596 607
597 } } 608 } }
598 609
599 #endif // V8_LEXER_EXPERIMENTAL_SCANNER_H 610 #endif // V8_LEXER_EXPERIMENTAL_SCANNER_H
OLDNEW
« no previous file with comments | « no previous file | src/lexer/lexer-shell.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698