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

Side by Side Diff: runtime/vm/scanner.cc

Issue 316253003: Scanner cleanups: use isolates to allocate handles and zone objects (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 months 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 | « runtime/vm/scanner.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/scanner.h" 5 #include "vm/scanner.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/dart.h" 8 #include "vm/dart.h"
9 #include "vm/flags.h" 9 #include "vm/flags.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/symbols.h" 12 #include "vm/symbols.h"
13 #include "vm/thread.h" 13 #include "vm/thread.h"
14 #include "vm/token.h" 14 #include "vm/token.h"
15 #include "vm/unicode.h" 15 #include "vm/unicode.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 DEFINE_FLAG(bool, print_tokens, false, "Print scanned tokens."); 19 DEFINE_FLAG(bool, print_tokens, false, "Print scanned tokens.");
20 20
21 21
22 // Quick access to the locally defined isolate() method.
23 #define I (isolate())
24
25
26 class ScanContext : public ZoneAllocated {
27 public:
28 explicit ScanContext(Scanner* scanner)
29 : next_(scanner->saved_context_),
30 string_delimiter_(scanner->string_delimiter_),
31 string_is_multiline_(scanner->string_is_multiline_),
32 brace_level_(scanner->brace_level_) {}
33
34 void CopyTo(Scanner* scanner) {
35 scanner->string_delimiter_ = string_delimiter_;
36 scanner->string_is_multiline_ = string_is_multiline_;
37 scanner->brace_level_ = brace_level_;
38 }
39
40 ScanContext* next() const { return next_; }
41
42 private:
hausner 2014/06/05 21:58:54 IMO it does not really make much sense to make thi
srdjan 2014/06/05 22:03:51 Discussed offline, leaving it as it is.
43 ScanContext* next_;
44 const char string_delimiter_;
45 const bool string_is_multiline_;
46 const int brace_level_;
47 };
48
49
22 Scanner::KeywordTable Scanner::keywords_[Token::kNumKeywords]; 50 Scanner::KeywordTable Scanner::keywords_[Token::kNumKeywords];
23 int Scanner::keywords_char_offset_[Scanner::kNumLowercaseChars]; 51 int Scanner::keywords_char_offset_[Scanner::kNumLowercaseChars];
24 52
25 53
26 void Scanner::Reset() { 54 void Scanner::Reset() {
27 // Non-changing newline properties. 55 // Non-changing newline properties.
28 newline_token_.kind = Token::kNEWLINE; 56 newline_token_.kind = Token::kNEWLINE;
29 newline_token_.literal = NULL; 57 newline_token_.literal = NULL;
30 // We don't preserve the column information. 58 // We don't preserve the column information.
31 newline_token_.position.column = 0; 59 newline_token_.position.column = 0;
32 60
33 // Non-changing empty string token properties. 61 // Non-changing empty string token properties.
34 empty_string_token_.kind = Token::kSTRING; 62 empty_string_token_.kind = Token::kSTRING;
35 empty_string_token_.literal = &Symbols::Empty(); 63 empty_string_token_.literal = &Symbols::Empty();
36 empty_string_token_.position.column = 0; 64 empty_string_token_.position.column = 0;
37 65
38 lookahead_pos_ = -1; 66 lookahead_pos_ = -1;
39 token_start_ = 0; 67 token_start_ = 0;
40 c0_ = '\0'; 68 c0_ = '\0';
41 newline_seen_ = false; 69 newline_seen_ = false;
42 prev_token_line_ = 1; 70 prev_token_line_ = 1;
43 while (saved_context_ != NULL) { 71 saved_context_ = NULL;
44 ScanContext* ctx = saved_context_;
45 saved_context_ = ctx->next;
46 delete ctx;
47 }
48 string_delimiter_ = '\0'; 72 string_delimiter_ = '\0';
49 string_is_multiline_ = false; 73 string_is_multiline_ = false;
50 brace_level_ = 0; 74 brace_level_ = 0;
51 c0_pos_.line = 1; 75 c0_pos_.line = 1;
52 c0_pos_.column = 0; 76 c0_pos_.column = 0;
53 ReadChar(); 77 ReadChar();
54 } 78 }
55 79
56 80
57 Scanner::Scanner(const String& src, const String& private_key) 81 Scanner::Scanner(const String& src, const String& private_key)
58 : source_(src), 82 : source_(src),
59 source_length_(src.Length()), 83 source_length_(src.Length()),
60 saved_context_(NULL), 84 saved_context_(NULL),
61 private_key_(String::ZoneHandle(private_key.raw())), 85 private_key_(String::ZoneHandle(private_key.raw())),
62 char_at_func_(src.CharAtFunc()), 86 char_at_func_(src.CharAtFunc()),
63 isolate_(Isolate::Current()) { 87 isolate_(Isolate::Current()) {
64 Reset(); 88 Reset();
65 } 89 }
66 90
67 91
68 Scanner::~Scanner() { 92 Scanner::~Scanner() {}
69 while (saved_context_ != NULL) {
70 ScanContext* ctx = saved_context_;
71 saved_context_ = ctx->next;
72 delete ctx;
73 }
74 }
75 93
76 94
77 void Scanner::ErrorMsg(const char* msg) { 95 void Scanner::ErrorMsg(const char* msg) {
78 current_token_.kind = Token::kERROR; 96 current_token_.kind = Token::kERROR;
79 current_token_.literal = &String::ZoneHandle(Symbols::New(msg)); 97 current_token_.literal = &String::ZoneHandle(I, Symbols::New(msg));
80 current_token_.position = c0_pos_; 98 current_token_.position = c0_pos_;
81 token_start_ = lookahead_pos_; 99 token_start_ = lookahead_pos_;
82 current_token_.offset = lookahead_pos_; 100 current_token_.offset = lookahead_pos_;
83 } 101 }
84 102
85 103
86 void Scanner::PushContext() { 104 void Scanner::PushContext() {
87 ScanContext* ctx = new ScanContext; 105 ScanContext* ctx = new(I) ScanContext(this);
88 ctx->next = saved_context_;
89 saved_context_ = ctx; 106 saved_context_ = ctx;
90 ctx->string_delimiter = string_delimiter_;
91 ctx->string_is_multiline = string_is_multiline_;
92 ctx->brace_level = brace_level_;
93 string_delimiter_ = '\0'; 107 string_delimiter_ = '\0';
94 string_is_multiline_ = false; 108 string_is_multiline_ = false;
95 brace_level_ = 1; // Account for the opening ${ token. 109 brace_level_ = 1; // Account for the opening ${ token.
96 } 110 }
97 111
98 112
99 void Scanner::PopContext() { 113 void Scanner::PopContext() {
100 ASSERT(saved_context_ != NULL); 114 ASSERT(saved_context_ != NULL);
101 ASSERT(brace_level_ == 0); 115 ASSERT(brace_level_ == 0);
102 ASSERT(string_delimiter_ == '\0'); 116 ASSERT(string_delimiter_ == '\0');
103 ScanContext* ctx = saved_context_; 117 ScanContext* ctx = saved_context_;
104 saved_context_ = ctx->next; 118 ctx->CopyTo(this);
105 string_delimiter_ = ctx->string_delimiter; 119 saved_context_ = ctx->next();
106 ASSERT(string_delimiter_ != '\0'); 120 ASSERT(string_delimiter_ != '\0');
107 string_is_multiline_ = ctx->string_is_multiline;
108 brace_level_ = ctx->brace_level;
109 delete ctx;
110 } 121 }
111 122
112 123
113 void Scanner::BeginStringLiteral(const char delimiter) { 124 void Scanner::BeginStringLiteral(const char delimiter) {
114 string_delimiter_ = delimiter; 125 string_delimiter_ = delimiter;
115 } 126 }
116 127
117 128
118 void Scanner::EndStringLiteral() { 129 void Scanner::EndStringLiteral() {
119 string_delimiter_ = '\0'; 130 string_delimiter_ = '\0';
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 return; 322 return;
312 } 323 }
313 } 324 }
314 i++; 325 i++;
315 } 326 }
316 } 327 }
317 328
318 // We did not read a keyword. 329 // We did not read a keyword.
319 current_token_.kind = Token::kIDENT; 330 current_token_.kind = Token::kIDENT;
320 String& literal = 331 String& literal =
321 String::ZoneHandle(Symbols::New(source_, ident_pos, ident_length)); 332 String::ZoneHandle(I, Symbols::New(source_, ident_pos, ident_length));
322 if (ident_char0 == Library::kPrivateIdentifierStart) { 333 if (ident_char0 == Library::kPrivateIdentifierStart) {
323 // Private identifiers are mangled on a per library basis. 334 // Private identifiers are mangled on a per library basis.
324 literal = String::Concat(literal, private_key_); 335 literal = String::Concat(literal, private_key_);
325 literal = Symbols::New(literal); 336 literal = Symbols::New(literal);
326 } 337 }
327 current_token_.literal = &literal; 338 current_token_.literal = &literal;
328 } 339 }
329 340
330 341
331 // Parse integer or double number literal of format: 342 // Parse integer or double number literal of format:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 ErrorMsg("missing exponent digits"); 380 ErrorMsg("missing exponent digits");
370 return; 381 return;
371 } 382 }
372 while (IsDecimalDigit(c0_)) { 383 while (IsDecimalDigit(c0_)) {
373 ReadChar(); 384 ReadChar();
374 } 385 }
375 } 386 }
376 } 387 }
377 if (current_token_.kind != Token::kILLEGAL) { 388 if (current_token_.kind != Token::kILLEGAL) {
378 intptr_t len = lookahead_pos_ - token_start_; 389 intptr_t len = lookahead_pos_ - token_start_;
379 String& str = String::ZoneHandle( 390 String& str = String::ZoneHandle(I,
380 String::SubString(source_, token_start_, len, Heap::kOld)); 391 String::SubString(source_, token_start_, len, Heap::kOld));
381 str = Symbols::New(str); 392 str = Symbols::New(str);
382 current_token_.literal = &str; 393 current_token_.literal = &str;
383 } 394 }
384 } 395 }
385 396
386 397
387 void Scanner::SkipLine() { 398 void Scanner::SkipLine() {
388 while (c0_ != '\n' && c0_ != '\0') { 399 while (c0_ != '\n' && c0_ != '\0') {
389 ReadChar(); 400 ReadChar();
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 return; 535 return;
525 } 536 }
526 escape_char = c0_; 537 escape_char = c0_;
527 break; 538 break;
528 } 539 }
529 string_chars.Add(escape_char); 540 string_chars.Add(escape_char);
530 } else if (c0_ == '$' && !is_raw) { 541 } else if (c0_ == '$' && !is_raw) {
531 // Scanned a string piece. 542 // Scanned a string piece.
532 ASSERT(string_chars.data() != NULL); 543 ASSERT(string_chars.data() != NULL);
533 // Strings are canonicalized: Allocate a symbol. 544 // Strings are canonicalized: Allocate a symbol.
534 current_token_.literal = &String::ZoneHandle( 545 current_token_.literal = &String::ZoneHandle(I,
535 Symbols::FromUTF32(string_chars.data(), string_chars.length())); 546 Symbols::FromUTF32(string_chars.data(), string_chars.length()));
536 // Preserve error tokens. 547 // Preserve error tokens.
537 if (current_token_.kind != Token::kERROR) { 548 if (current_token_.kind != Token::kERROR) {
538 current_token_.kind = Token::kSTRING; 549 current_token_.kind = Token::kSTRING;
539 } 550 }
540 return; 551 return;
541 } else if (c0_ == string_delimiter_) { 552 } else if (c0_ == string_delimiter_) {
542 // Check if we are at the end of the string literal. 553 // Check if we are at the end of the string literal.
543 if (!string_is_multiline_ || 554 if (!string_is_multiline_ ||
544 ((LookaheadChar(1) == string_delimiter_) && 555 ((LookaheadChar(1) == string_delimiter_) &&
545 (LookaheadChar(2) == string_delimiter_))) { 556 (LookaheadChar(2) == string_delimiter_))) {
546 if (string_is_multiline_) { 557 if (string_is_multiline_) {
547 ReadChar(); // Skip two string delimiters. 558 ReadChar(); // Skip two string delimiters.
548 ReadChar(); 559 ReadChar();
549 } 560 }
550 // Preserve error tokens. 561 // Preserve error tokens.
551 if (current_token_.kind == Token::kERROR) { 562 if (current_token_.kind == Token::kERROR) {
552 ReadChar(); 563 ReadChar();
553 } else { 564 } else {
554 Recognize(Token::kSTRING); 565 Recognize(Token::kSTRING);
555 ASSERT(string_chars.data() != NULL); 566 ASSERT(string_chars.data() != NULL);
556 // Strings are canonicalized: Allocate a symbol. 567 // Strings are canonicalized: Allocate a symbol.
557 current_token_.literal = &String::ZoneHandle( 568 current_token_.literal = &String::ZoneHandle(I,
558 Symbols::FromUTF32(string_chars.data(), string_chars.length())); 569 Symbols::FromUTF32(string_chars.data(), string_chars.length()));
559 } 570 }
560 EndStringLiteral(); 571 EndStringLiteral();
561 return; 572 return;
562 } else { 573 } else {
563 string_chars.Add(string_delimiter_); 574 string_chars.Add(string_delimiter_);
564 } 575 }
565 } else { 576 } else {
566 // Test for a two part utf16 sequence, and decode to a code point 577 // Test for a two part utf16 sequence, and decode to a code point
567 // if we find one. 578 // if we find one.
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 (current_token_.kind == Token::kINTERPOL_START))) { 923 (current_token_.kind == Token::kINTERPOL_START))) {
913 index++; // Advance the index to account for tokens added in ScanAll. 924 index++; // Advance the index to account for tokens added in ScanAll.
914 } 925 }
915 index++; 926 index++;
916 prev_token_line_ = current_token_.position.line; 927 prev_token_line_ = current_token_.position.line;
917 } while ((token_index >= index) && (current_token_.kind != Token::kEOS)); 928 } while ((token_index >= index) && (current_token_.kind != Token::kEOS));
918 } 929 }
919 930
920 931
921 const Scanner::GrowableTokenStream& Scanner::GetStream() { 932 const Scanner::GrowableTokenStream& Scanner::GetStream() {
922 GrowableTokenStream* ts = new GrowableTokenStream(128); 933 GrowableTokenStream* ts = new(I) GrowableTokenStream(128);
923 ScanAll(ts); 934 ScanAll(ts);
924 if (FLAG_print_tokens) { 935 if (FLAG_print_tokens) {
925 Scanner::PrintTokens(*ts); 936 Scanner::PrintTokens(*ts);
926 } 937 }
927 return *ts; 938 return *ts;
928 } 939 }
929 940
930 941
931 void Scanner::PrintTokens(const GrowableTokenStream& ts) { 942 void Scanner::PrintTokens(const GrowableTokenStream& ts) {
932 int currentLine = -1; 943 int currentLine = -1;
(...skipping 22 matching lines...) Expand all
955 keywords_[i].keyword_symbol = &Symbols::Keyword(token); 966 keywords_[i].keyword_symbol = &Symbols::Keyword(token);
956 967
957 int ch = keywords_[i].keyword_chars[0] - 'a'; 968 int ch = keywords_[i].keyword_chars[0] - 'a';
958 if (keywords_char_offset_[ch] == Token::kNumKeywords) { 969 if (keywords_char_offset_[ch] == Token::kNumKeywords) {
959 keywords_char_offset_[ch] = i; 970 keywords_char_offset_[ch] = i;
960 } 971 }
961 } 972 }
962 } 973 }
963 974
964 } // namespace dart 975 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scanner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698