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

Side by Side Diff: src/scanner.h

Issue 12257005: Improve JSON stringifier's escape check. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: reduce impact on the scanner. Created 7 years, 10 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 | « src/preparser.cc ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 165
166 DISALLOW_COPY_AND_ASSIGN(UnicodeCache); 166 DISALLOW_COPY_AND_ASSIGN(UnicodeCache);
167 }; 167 };
168 168
169 169
170 // ---------------------------------------------------------------------------- 170 // ----------------------------------------------------------------------------
171 // LiteralBuffer - Collector of chars of literals. 171 // LiteralBuffer - Collector of chars of literals.
172 172
173 class LiteralBuffer { 173 class LiteralBuffer {
174 public: 174 public:
175 LiteralBuffer() : is_ascii_(true), position_(0), backing_store_() { } 175 // "Printable" ASCII is in the range 0x20 .. 0x7e.
176 enum CharacterRange { PRINTABLE_ASCII, ASCII, TWO_BYTE };
177
178 LiteralBuffer() : character_range_(PRINTABLE_ASCII),
179 position_(0),
180 backing_store_() { }
176 181
177 ~LiteralBuffer() { 182 ~LiteralBuffer() {
178 if (backing_store_.length() > 0) { 183 if (backing_store_.length() > 0) {
179 backing_store_.Dispose(); 184 backing_store_.Dispose();
180 } 185 }
181 } 186 }
182 187
183 INLINE(void AddChar(uint32_t code_unit)) { 188 INLINE(void AddChar(uint32_t code_unit)) {
184 if (position_ >= backing_store_.length()) ExpandBuffer(); 189 if (position_ >= backing_store_.length()) ExpandBuffer();
185 if (is_ascii_) { 190 switch (character_range_) {
186 if (code_unit <= unibrow::Latin1::kMaxChar) { 191 case PRINTABLE_ASCII:
187 backing_store_[position_] = static_cast<byte>(code_unit); 192 if (code_unit >= 0x20 && code_unit < 0x7f) break;
188 position_ += kOneByteSize; 193 character_range_ = ASCII;
194 case ASCII:
195 if (code_unit <= unibrow::Latin1::kMaxChar) break;
196 ConvertToUtf16();
197 case TWO_BYTE:
198 ASSERT(code_unit < 0x10000u);
199 *reinterpret_cast<uc16*>(&backing_store_[position_]) = code_unit;
200 position_ += kUC16Size;
189 return; 201 return;
190 }
191 ConvertToUtf16();
192 } 202 }
193 ASSERT(code_unit < 0x10000u); 203 ASSERT(character_range_ <= ASCII);
194 *reinterpret_cast<uc16*>(&backing_store_[position_]) = code_unit; 204 backing_store_[position_] = static_cast<byte>(code_unit);
195 position_ += kUC16Size; 205 position_ += kOneByteSize;
196 } 206 }
197 207
198 bool is_ascii() { return is_ascii_; } 208 inline bool is_ascii() { return character_range_ <= ASCII; }
209 bool is_printable_ascii() { return character_range_ == PRINTABLE_ASCII; }
199 210
200 Vector<const uc16> utf16_literal() { 211 Vector<const uc16> utf16_literal() {
201 ASSERT(!is_ascii_); 212 ASSERT(character_range_ == TWO_BYTE);
202 ASSERT((position_ & 0x1) == 0); 213 ASSERT((position_ & 0x1) == 0);
203 return Vector<const uc16>( 214 return Vector<const uc16>(
204 reinterpret_cast<const uc16*>(backing_store_.start()), 215 reinterpret_cast<const uc16*>(backing_store_.start()),
205 position_ >> 1); 216 position_ >> 1);
206 } 217 }
207 218
208 Vector<const char> ascii_literal() { 219 Vector<const char> ascii_literal() {
209 ASSERT(is_ascii_); 220 ASSERT(is_ascii());
210 return Vector<const char>( 221 return Vector<const char>(
211 reinterpret_cast<const char*>(backing_store_.start()), 222 reinterpret_cast<const char*>(backing_store_.start()),
212 position_); 223 position_);
213 } 224 }
214 225
215 int length() { 226 int length() {
216 return is_ascii_ ? position_ : (position_ >> 1); 227 return is_ascii() ? position_ : (position_ >> 1);
217 } 228 }
218 229
219 void Reset() { 230 void Reset() {
220 position_ = 0; 231 position_ = 0;
221 is_ascii_ = true; 232 character_range_ = PRINTABLE_ASCII;
222 } 233 }
223 234
224 private: 235 private:
225 static const int kInitialCapacity = 16; 236 static const int kInitialCapacity = 16;
226 static const int kGrowthFactory = 4; 237 static const int kGrowthFactory = 4;
227 static const int kMinConversionSlack = 256; 238 static const int kMinConversionSlack = 256;
228 static const int kMaxGrowth = 1 * MB; 239 static const int kMaxGrowth = 1 * MB;
229 inline int NewCapacity(int min_capacity) { 240 inline int NewCapacity(int min_capacity) {
230 int capacity = Max(min_capacity, backing_store_.length()); 241 int capacity = Max(min_capacity, backing_store_.length());
231 int new_capacity = Min(capacity * kGrowthFactory, capacity + kMaxGrowth); 242 int new_capacity = Min(capacity * kGrowthFactory, capacity + kMaxGrowth);
232 return new_capacity; 243 return new_capacity;
233 } 244 }
234 245
235 void ExpandBuffer() { 246 void ExpandBuffer() {
236 Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity)); 247 Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity));
237 memcpy(new_store.start(), backing_store_.start(), position_); 248 memcpy(new_store.start(), backing_store_.start(), position_);
238 backing_store_.Dispose(); 249 backing_store_.Dispose();
239 backing_store_ = new_store; 250 backing_store_ = new_store;
240 } 251 }
241 252
242 void ConvertToUtf16() { 253 void ConvertToUtf16() {
243 ASSERT(is_ascii_); 254 ASSERT(character_range_ == ASCII);
244 Vector<byte> new_store; 255 Vector<byte> new_store;
245 int new_content_size = position_ * kUC16Size; 256 int new_content_size = position_ * kUC16Size;
246 if (new_content_size >= backing_store_.length()) { 257 if (new_content_size >= backing_store_.length()) {
247 // Ensure room for all currently read code units as UC16 as well 258 // Ensure room for all currently read code units as UC16 as well
248 // as the code unit about to be stored. 259 // as the code unit about to be stored.
249 new_store = Vector<byte>::New(NewCapacity(new_content_size)); 260 new_store = Vector<byte>::New(NewCapacity(new_content_size));
250 } else { 261 } else {
251 new_store = backing_store_; 262 new_store = backing_store_;
252 } 263 }
253 uint8_t* src = backing_store_.start(); 264 uint8_t* src = backing_store_.start();
254 uc16* dst = reinterpret_cast<uc16*>(new_store.start()); 265 uc16* dst = reinterpret_cast<uc16*>(new_store.start());
255 for (int i = position_ - 1; i >= 0; i--) { 266 for (int i = position_ - 1; i >= 0; i--) {
256 dst[i] = src[i]; 267 dst[i] = src[i];
257 } 268 }
258 if (new_store.start() != backing_store_.start()) { 269 if (new_store.start() != backing_store_.start()) {
259 backing_store_.Dispose(); 270 backing_store_.Dispose();
260 backing_store_ = new_store; 271 backing_store_ = new_store;
261 } 272 }
262 position_ = new_content_size; 273 position_ = new_content_size;
263 is_ascii_ = false; 274 character_range_ = TWO_BYTE;
264 } 275 }
265 276
266 bool is_ascii_; 277 CharacterRange character_range_;
267 int position_; 278 int position_;
268 Vector<byte> backing_store_; 279 Vector<byte> backing_store_;
269 280
270 DISALLOW_COPY_AND_ASSIGN(LiteralBuffer); 281 DISALLOW_COPY_AND_ASSIGN(LiteralBuffer);
271 }; 282 };
272 283
273 284
274 // ---------------------------------------------------------------------------- 285 // ----------------------------------------------------------------------------
275 // JavaScript Scanner. 286 // JavaScript Scanner.
276 287
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 return current_.literal_chars->ascii_literal(); 348 return current_.literal_chars->ascii_literal();
338 } 349 }
339 Vector<const uc16> literal_utf16_string() { 350 Vector<const uc16> literal_utf16_string() {
340 ASSERT_NOT_NULL(current_.literal_chars); 351 ASSERT_NOT_NULL(current_.literal_chars);
341 return current_.literal_chars->utf16_literal(); 352 return current_.literal_chars->utf16_literal();
342 } 353 }
343 bool is_literal_ascii() { 354 bool is_literal_ascii() {
344 ASSERT_NOT_NULL(current_.literal_chars); 355 ASSERT_NOT_NULL(current_.literal_chars);
345 return current_.literal_chars->is_ascii(); 356 return current_.literal_chars->is_ascii();
346 } 357 }
358 bool is_literal_printable_ascii() {
359 ASSERT_NOT_NULL(current_.literal_chars);
360 return current_.literal_chars->is_printable_ascii();
361 }
347 int literal_length() const { 362 int literal_length() const {
348 ASSERT_NOT_NULL(current_.literal_chars); 363 ASSERT_NOT_NULL(current_.literal_chars);
349 return current_.literal_chars->length(); 364 return current_.literal_chars->length();
350 } 365 }
351 366
352 bool literal_contains_escapes() const { 367 bool literal_contains_escapes() const {
353 Location location = current_.location; 368 Location location = current_.location;
354 int source_length = (location.end_pos - location.beg_pos); 369 int source_length = (location.end_pos - location.beg_pos);
355 if (current_.token == Token::STRING) { 370 if (current_.token == Token::STRING) {
356 // Subtract delimiters. 371 // Subtract delimiters.
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 bool has_multiline_comment_before_next_; 576 bool has_multiline_comment_before_next_;
562 // Whether we scan 'let' as a keyword for harmony block-scoped let bindings. 577 // Whether we scan 'let' as a keyword for harmony block-scoped let bindings.
563 bool harmony_scoping_; 578 bool harmony_scoping_;
564 // Whether we scan 'module', 'import', 'export' as keywords. 579 // Whether we scan 'module', 'import', 'export' as keywords.
565 bool harmony_modules_; 580 bool harmony_modules_;
566 }; 581 };
567 582
568 } } // namespace v8::internal 583 } } // namespace v8::internal
569 584
570 #endif // V8_SCANNER_H_ 585 #endif // V8_SCANNER_H_
OLDNEW
« no previous file with comments | « src/preparser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698