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

Side by Side Diff: src/json-parser.cc

Issue 7020018: Remove scanner abstraction layer from JSON parsing. The change in api.cc is t... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 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 | « src/json-parser.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 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 if (source_->IsSeqAsciiString()) { 46 if (source_->IsSeqAsciiString()) {
47 is_sequential_ascii_ = true; 47 is_sequential_ascii_ = true;
48 seq_source_ = Handle<SeqAsciiString>::cast(source_); 48 seq_source_ = Handle<SeqAsciiString>::cast(source_);
49 } else { 49 } else {
50 is_sequential_ascii_ = false; 50 is_sequential_ascii_ = false;
51 } 51 }
52 52
53 // Set initial position right before the string. 53 // Set initial position right before the string.
54 position_ = -1; 54 position_ = -1;
55 // Advance to the first character (posibly EOS) 55 // Advance to the first character (posibly EOS)
56 Advance(); 56 AdvanceSkipWhitespace();
57 Next();
58 Handle<Object> result = ParseJsonValue(); 57 Handle<Object> result = ParseJsonValue();
59 if (result.is_null() || Next() != Token::EOS) { 58 if (result.is_null() || c0_ != kEndOfString) {
60 // Parse failed. Scanner's current token is the unexpected token. 59 // Parse failed. Current character is the unexpected token.
61 Token::Value token = current_.token;
62 60
63 const char* message; 61 const char* message;
64 const char* name_opt = NULL; 62 Factory* factory = isolate()->factory();
63 Handle<JSArray> array;
65 64
66 switch (token) { 65 switch (c0_) {
67 case Token::EOS: 66 case kEndOfString:
68 message = "unexpected_eos"; 67 message = "unexpected_eos";
68 array = factory->NewJSArray(0);
69 break; 69 break;
70 case Token::NUMBER: 70 case '-':
71 case '0':
72 case '1':
73 case '2':
74 case '3':
75 case '4':
76 case '5':
77 case '6':
78 case '7':
79 case '8':
80 case '9':
71 message = "unexpected_token_number"; 81 message = "unexpected_token_number";
82 array = factory->NewJSArray(0);
72 break; 83 break;
73 case Token::STRING: 84 case '"':
74 message = "unexpected_token_string"; 85 message = "unexpected_token_string";
75 break; 86 array = factory->NewJSArray(0);
76 case Token::IDENTIFIER:
77 case Token::FUTURE_RESERVED_WORD:
78 message = "unexpected_token_identifier";
79 break; 87 break;
80 default: 88 default:
81 message = "unexpected_token"; 89 message = "unexpected_token";
82 name_opt = Token::String(token); 90 Handle<Object> name = LookupSingleCharacterStringFromCode(c0_);
83 ASSERT(name_opt != NULL); 91 Handle<FixedArray> element = factory->NewFixedArray(1);
92 element->set(0, *name);
93 array = factory->NewJSArrayWithElements(element);
84 break; 94 break;
85 } 95 }
86 96
87 Factory* factory = isolate()->factory();
88 MessageLocation location(factory->NewScript(source), 97 MessageLocation location(factory->NewScript(source),
89 current_.beg_pos, 98 position_,
90 current_.end_pos); 99 position_ + 1);
91 Handle<JSArray> array;
92 if (name_opt == NULL) {
93 array = factory->NewJSArray(0);
94 } else {
95 Handle<String> name = factory->NewStringFromUtf8(CStrVector(name_opt));
96 Handle<FixedArray> element = factory->NewFixedArray(1);
97 element->set(0, *name);
98 array = factory->NewJSArrayWithElements(element);
99 }
100 Handle<Object> result = factory->NewSyntaxError(message, array); 100 Handle<Object> result = factory->NewSyntaxError(message, array);
101 isolate()->Throw(*result, &location); 101 isolate()->Throw(*result, &location);
102 return Handle<Object>::null(); 102 return Handle<Object>::null();
103 } 103 }
104 return result; 104 return result;
105 } 105 }
106 106
107 107
108 // Parse any JSON value. 108 // Parse any JSON value.
109 Handle<Object> JsonParser::ParseJsonValue() { 109 Handle<Object> JsonParser::ParseJsonValue() {
110 Token::Value token = Next(); 110 switch (c0_) {
111 switch (token) { 111 case '"':
112 case Token::STRING: 112 return ParseJsonString();
113 return GetString(false); 113 case '-':
114 case Token::NUMBER: 114 case '0':
115 return isolate()->factory()->NewNumber(number_); 115 case '1':
116 case Token::FALSE_LITERAL: 116 case '2':
117 return isolate()->factory()->false_value(); 117 case '3':
118 case Token::TRUE_LITERAL: 118 case '4':
119 return isolate()->factory()->true_value(); 119 case '5':
120 case Token::NULL_LITERAL: 120 case '6':
121 return isolate()->factory()->null_value(); 121 case '7':
122 case Token::LBRACE: 122 case '8':
123 case '9':
124 return ParseJsonNumber();
125 case 'f':
126 if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
127 AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
128 AdvanceSkipWhitespace();
129 return isolate()->factory()->false_value();
130 } else {
131 return ReportUnexpectedCharacter();
132 }
133 case 't':
134 if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
135 AdvanceGetChar() == 'e') {
136 AdvanceSkipWhitespace();
137 return isolate()->factory()->true_value();
138 } else {
139 return ReportUnexpectedCharacter();
140 }
141 case 'n':
142 if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
143 AdvanceGetChar() == 'l') {
144 AdvanceSkipWhitespace();
145 return isolate()->factory()->null_value();
146 } else {
147 return ReportUnexpectedCharacter();
148 }
149 case '{':
123 return ParseJsonObject(); 150 return ParseJsonObject();
124 case Token::LBRACK: 151 case '[':
125 return ParseJsonArray(); 152 return ParseJsonArray();
126 default: 153 default:
127 return ReportUnexpectedToken(); 154 return ReportUnexpectedCharacter();
128 } 155 }
129 } 156 }
130 157
131 158
132 // Parse a JSON object. Scanner must be right after '{' token. 159 // Parse a JSON object. Position must be right at '{'.
133 Handle<Object> JsonParser::ParseJsonObject() { 160 Handle<Object> JsonParser::ParseJsonObject() {
134 Handle<JSFunction> object_constructor( 161 Handle<JSFunction> object_constructor(
135 isolate()->global_context()->object_function()); 162 isolate()->global_context()->object_function());
136 Handle<JSObject> json_object = 163 Handle<JSObject> json_object =
137 isolate()->factory()->NewJSObject(object_constructor); 164 isolate()->factory()->NewJSObject(object_constructor);
165 ASSERT_EQ(c0_, '{');
138 166
139 if (Peek() == Token::RBRACE) { 167 AdvanceSkipWhitespace();
140 Next(); 168 if (c0_ != '}') {
141 } else {
142 do { 169 do {
143 if (Next() != Token::STRING) { 170 Handle<String> key = ParseJsonSymbol();
144 return ReportUnexpectedToken(); 171 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
145 } 172 AdvanceSkipWhitespace();
146 Handle<String> key = GetString(true);
147 if (Next() != Token::COLON) {
148 return ReportUnexpectedToken();
149 }
150
151 Handle<Object> value = ParseJsonValue(); 173 Handle<Object> value = ParseJsonValue();
152 if (value.is_null()) return Handle<Object>::null(); 174 if (value.is_null()) return ReportUnexpectedCharacter();
153 175
154 uint32_t index; 176 uint32_t index;
155 if (key->AsArrayIndex(&index)) { 177 if (key->AsArrayIndex(&index)) {
156 SetOwnElement(json_object, index, value, kNonStrictMode); 178 SetOwnElement(json_object, index, value, kNonStrictMode);
157 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { 179 } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
158 SetPrototype(json_object, value); 180 SetPrototype(json_object, value);
159 } else { 181 } else {
160 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); 182 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
161 } 183 }
162 } while (Next() == Token::COMMA); 184 } while (MatchSkipWhiteSpace(','));
163 if (current_.token != Token::RBRACE) { 185 if (c0_ != '}') {
164 return ReportUnexpectedToken(); 186 return ReportUnexpectedCharacter();
165 } 187 }
166 } 188 }
189 AdvanceSkipWhitespace();
167 return json_object; 190 return json_object;
168 } 191 }
169 192
170 // Parse a JSON array. Scanner must be right after '[' token. 193 // Parse a JSON array. Position must be right at '['.
171 Handle<Object> JsonParser::ParseJsonArray() { 194 Handle<Object> JsonParser::ParseJsonArray() {
172 ZoneScope zone_scope(isolate(), DELETE_ON_EXIT); 195 ZoneScope zone_scope(isolate(), DELETE_ON_EXIT);
173 ZoneList<Handle<Object> > elements(4); 196 ZoneList<Handle<Object> > elements(4);
197 ASSERT_EQ(c0_, '[');
174 198
175 Token::Value token = Peek(); 199 AdvanceSkipWhitespace();
176 if (token == Token::RBRACK) { 200 if (c0_ != ']') {
177 Next();
178 } else {
179 do { 201 do {
180 Handle<Object> element = ParseJsonValue(); 202 Handle<Object> element = ParseJsonValue();
181 if (element.is_null()) return Handle<Object>::null(); 203 if (element.is_null()) return ReportUnexpectedCharacter();
182 elements.Add(element); 204 elements.Add(element);
183 token = Next(); 205 } while (MatchSkipWhiteSpace(','));
184 } while (token == Token::COMMA); 206 if (c0_ != ']') {
185 if (token != Token::RBRACK) { 207 return ReportUnexpectedCharacter();
186 return ReportUnexpectedToken();
187 } 208 }
188 } 209 }
189 210 AdvanceSkipWhitespace();
190 // Allocate a fixed array with all the elements. 211 // Allocate a fixed array with all the elements.
191 Handle<FixedArray> fast_elements = 212 Handle<FixedArray> fast_elements =
192 isolate()->factory()->NewFixedArray(elements.length()); 213 isolate()->factory()->NewFixedArray(elements.length());
193
194 for (int i = 0, n = elements.length(); i < n; i++) { 214 for (int i = 0, n = elements.length(); i < n; i++) {
195 fast_elements->set(i, *elements[i]); 215 fast_elements->set(i, *elements[i]);
196 } 216 }
197
198 return isolate()->factory()->NewJSArrayWithElements(fast_elements); 217 return isolate()->factory()->NewJSArrayWithElements(fast_elements);
199 } 218 }
200 219
201 220
202 Token::Value JsonParser::Next() { 221 Handle<Object> JsonParser::ParseJsonNumber() {
203 current_ = next_;
204 ScanJson();
205 return current_.token;
206 }
207
208 void JsonParser::ScanJson() {
209 if (source_->IsSeqAsciiString()) {
210 is_sequential_ascii_ = true;
211 } else {
212 is_sequential_ascii_ = false;
213 }
214
215 Token::Value token;
216 do {
217 // Remember the position of the next token
218 next_.beg_pos = position_;
219 switch (c0_) {
220 case '\t':
221 case '\r':
222 case '\n':
223 case ' ':
224 Advance();
225 token = Token::WHITESPACE;
226 break;
227 case '{':
228 Advance();
229 token = Token::LBRACE;
230 break;
231 case '}':
232 Advance();
233 token = Token::RBRACE;
234 break;
235 case '[':
236 Advance();
237 token = Token::LBRACK;
238 break;
239 case ']':
240 Advance();
241 token = Token::RBRACK;
242 break;
243 case ':':
244 Advance();
245 token = Token::COLON;
246 break;
247 case ',':
248 Advance();
249 token = Token::COMMA;
250 break;
251 case '"':
252 token = ScanJsonString();
253 break;
254 case '-':
255 case '0':
256 case '1':
257 case '2':
258 case '3':
259 case '4':
260 case '5':
261 case '6':
262 case '7':
263 case '8':
264 case '9':
265 token = ScanJsonNumber();
266 break;
267 case 't':
268 token = ScanJsonIdentifier("true", Token::TRUE_LITERAL);
269 break;
270 case 'f':
271 token = ScanJsonIdentifier("false", Token::FALSE_LITERAL);
272 break;
273 case 'n':
274 token = ScanJsonIdentifier("null", Token::NULL_LITERAL);
275 break;
276 default:
277 if (c0_ < 0) {
278 Advance();
279 token = Token::EOS;
280 } else {
281 Advance();
282 token = Token::ILLEGAL;
283 }
284 }
285 } while (token == Token::WHITESPACE);
286
287 next_.end_pos = position_;
288 next_.token = token;
289 }
290
291
292 Token::Value JsonParser::ScanJsonIdentifier(const char* text,
293 Token::Value token) {
294 while (*text != '\0') {
295 if (c0_ != *text) return Token::ILLEGAL;
296 Advance();
297 text++;
298 }
299 return token;
300 }
301
302
303 Token::Value JsonParser::ScanJsonNumber() {
304 bool negative = false; 222 bool negative = false;
305 223 beg_pos_ = position_;
306 if (c0_ == '-') { 224 if (c0_ == '-') {
307 Advance(); 225 Advance();
308 negative = true; 226 negative = true;
309 } 227 }
310 if (c0_ == '0') { 228 if (c0_ == '0') {
311 Advance(); 229 Advance();
312 // Prefix zero is only allowed if it's the only digit before 230 // Prefix zero is only allowed if it's the only digit before
313 // a decimal point or exponent. 231 // a decimal point or exponent.
314 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; 232 if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter();
315 } else { 233 } else {
316 int i = 0; 234 int i = 0;
317 int digits = 0; 235 int digits = 0;
318 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; 236 if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter();
319 do { 237 do {
320 i = i * 10 + c0_ - '0'; 238 i = i * 10 + c0_ - '0';
321 digits++; 239 digits++;
322 Advance(); 240 Advance();
323 } while (c0_ >= '0' && c0_ <= '9'); 241 } while (c0_ >= '0' && c0_ <= '9');
324 if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { 242 if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
325 number_ = (negative ? -i : i); 243 number_ = (negative ? -i : i);
326 return Token::NUMBER; 244 SkipWhitespace();
245 return isolate()->factory()->NewNumber(number_);
327 } 246 }
328 } 247 }
329 if (c0_ == '.') { 248 if (c0_ == '.') {
330 Advance(); 249 Advance();
331 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 250 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
332 do { 251 do {
333 Advance(); 252 Advance();
334 } while (c0_ >= '0' && c0_ <= '9'); 253 } while (c0_ >= '0' && c0_ <= '9');
335 } 254 }
336 if (AsciiAlphaToLower(c0_) == 'e') { 255 if (AsciiAlphaToLower(c0_) == 'e') {
337 Advance(); 256 Advance();
338 if (c0_ == '-' || c0_ == '+') Advance(); 257 if (c0_ == '-' || c0_ == '+') Advance();
339 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 258 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
340 do { 259 do {
341 Advance(); 260 Advance();
342 } while (c0_ >= '0' && c0_ <= '9'); 261 } while (c0_ >= '0' && c0_ <= '9');
343 } 262 }
263 int length = position_ - beg_pos_;
344 if (is_sequential_ascii_) { 264 if (is_sequential_ascii_) {
345 Vector<const char> chars(seq_source_->GetChars() + next_.beg_pos, 265 Vector<const char> chars(seq_source_->GetChars() + beg_pos_, length);
346 position_ - next_.beg_pos);
347 number_ = StringToDouble(isolate()->unicode_cache(), 266 number_ = StringToDouble(isolate()->unicode_cache(),
348 chars, 267 chars,
349 NO_FLAGS, // Hex, octal or trailing junk. 268 NO_FLAGS, // Hex, octal or trailing junk.
350 OS::nan_value()); 269 OS::nan_value());
351 } else { 270 } else {
352 Vector<char> buffer = Vector<char>::New(position_ - next_.beg_pos); 271 Vector<char> buffer = Vector<char>::New(length);
353 String::WriteToFlat(*source_, buffer.start(), next_.beg_pos, position_); 272 String::WriteToFlat(*source_, buffer.start(), beg_pos_, position_);
354 Vector<const char> result = 273 Vector<const char> result =
355 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), 274 Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
356 position_ - next_.beg_pos); 275 length);
357 number_ = StringToDouble(isolate()->unicode_cache(), 276 number_ = StringToDouble(isolate()->unicode_cache(),
358 result, 277 result,
359 NO_FLAGS, // Hex, octal or trailing junk. 278 NO_FLAGS, // Hex, octal or trailing junk.
360 0.0); 279 0.0);
361 buffer.Dispose(); 280 buffer.Dispose();
362 } 281 }
363 return Token::NUMBER; 282 SkipWhitespace();
283 return isolate()->factory()->NewNumber(number_);
364 } 284 }
365 285
366 Token::Value JsonParser::SlowScanJsonString() { 286 Handle<Object> JsonParser::SlowScanJsonString() {
367 // The currently scanned ascii characters. 287 // The currently scanned ascii characters.
368 Handle<String> ascii(isolate()->factory()->NewSubString(source_, 288 Handle<String> ascii(isolate()->factory()->NewSubString(source_,
369 next_.beg_pos + 1, 289 beg_pos_,
370 position_)); 290 position_));
371 Handle<String> two_byte = 291 Handle<String> two_byte =
372 isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize, 292 isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize,
373 NOT_TENURED); 293 NOT_TENURED);
374 Handle<SeqTwoByteString> seq_two_byte = 294 Handle<SeqTwoByteString> seq_two_byte =
375 Handle<SeqTwoByteString>::cast(two_byte); 295 Handle<SeqTwoByteString>::cast(two_byte);
376 296
377 int allocation_count = 1; 297 int allocation_count = 1;
378 int count = 0; 298 int count = 0;
379 299
380 while (c0_ != '"') { 300 while (c0_ != '"') {
381 // Create new seq string 301 // Create new seq string
382 if (count >= kInitialSpecialStringSize * allocation_count) { 302 if (count >= kInitialSpecialStringSize * allocation_count) {
383 allocation_count = allocation_count * 2; 303 allocation_count = allocation_count * 2;
384 int new_size = allocation_count * kInitialSpecialStringSize; 304 int new_size = allocation_count * kInitialSpecialStringSize;
385 Handle<String> new_two_byte = 305 Handle<String> new_two_byte =
386 isolate()->factory()->NewRawTwoByteString(new_size, 306 isolate()->factory()->NewRawTwoByteString(new_size,
387 NOT_TENURED); 307 NOT_TENURED);
388 uc16* char_start = 308 uc16* char_start =
389 Handle<SeqTwoByteString>::cast(new_two_byte)->GetChars(); 309 Handle<SeqTwoByteString>::cast(new_two_byte)->GetChars();
390 String::WriteToFlat(*seq_two_byte, char_start, 0, count); 310 String::WriteToFlat(*seq_two_byte, char_start, 0, count);
391 seq_two_byte = Handle<SeqTwoByteString>::cast(new_two_byte); 311 seq_two_byte = Handle<SeqTwoByteString>::cast(new_two_byte);
392 } 312 }
393 313
394 // Check for control character (0x00-0x1f) or unterminated string (<0). 314 // Check for control character (0x00-0x1f) or unterminated string (<0).
395 if (c0_ < 0x20) return Token::ILLEGAL; 315 if (c0_ < 0x20) return ReportUnexpectedCharacter();
396 if (c0_ != '\\') { 316 if (c0_ != '\\') {
397 seq_two_byte->SeqTwoByteStringSet(count++, c0_); 317 seq_two_byte->SeqTwoByteStringSet(count++, c0_);
398 Advance(); 318 Advance();
399 } else { 319 } else {
400 Advance(); 320 Advance();
401 switch (c0_) { 321 switch (c0_) {
402 case '"': 322 case '"':
403 case '\\': 323 case '\\':
404 case '/': 324 case '/':
405 seq_two_byte->SeqTwoByteStringSet(count++, c0_); 325 seq_two_byte->SeqTwoByteStringSet(count++, c0_);
(...skipping 12 matching lines...) Expand all
418 break; 338 break;
419 case 't': 339 case 't':
420 seq_two_byte->SeqTwoByteStringSet(count++, '\x09'); 340 seq_two_byte->SeqTwoByteStringSet(count++, '\x09');
421 break; 341 break;
422 case 'u': { 342 case 'u': {
423 uc32 value = 0; 343 uc32 value = 0;
424 for (int i = 0; i < 4; i++) { 344 for (int i = 0; i < 4; i++) {
425 Advance(); 345 Advance();
426 int digit = HexValue(c0_); 346 int digit = HexValue(c0_);
427 if (digit < 0) { 347 if (digit < 0) {
428 return Token::ILLEGAL; 348 return ReportUnexpectedCharacter();
429 } 349 }
430 value = value * 16 + digit; 350 value = value * 16 + digit;
431 } 351 }
432 seq_two_byte->SeqTwoByteStringSet(count++, value); 352 seq_two_byte->SeqTwoByteStringSet(count++, value);
433 break; 353 break;
434 } 354 }
435 default: 355 default:
436 return Token::ILLEGAL; 356 return ReportUnexpectedCharacter();
437 } 357 }
438 Advance(); 358 Advance();
439 } 359 }
440 } 360 }
441 // Advance past the last '"'. 361 // Advance past the last '"'.
442 ASSERT_EQ('"', c0_); 362 ASSERT_EQ('"', c0_);
443 Advance(); 363 AdvanceSkipWhitespace();
444 364
445 // Shrink the the string to our length. 365 // Shrink the the string to our length.
446 if (isolate()->heap()->InNewSpace(*seq_two_byte)) { 366 if (isolate()->heap()->InNewSpace(*seq_two_byte)) {
447 isolate()->heap()->new_space()-> 367 isolate()->heap()->new_space()->
448 ShrinkStringAtAllocationBoundary<SeqTwoByteString>(*seq_two_byte, 368 ShrinkStringAtAllocationBoundary<SeqTwoByteString>(*seq_two_byte,
449 count); 369 count);
450 } else { 370 } else {
451 int string_size = SeqTwoByteString::SizeFor(count); 371 int string_size = SeqTwoByteString::SizeFor(count);
452 int allocated_string_size = 372 int allocated_string_size =
453 SeqTwoByteString::SizeFor(kInitialSpecialStringSize * allocation_count); 373 SeqTwoByteString::SizeFor(kInitialSpecialStringSize * allocation_count);
454 int delta = allocated_string_size - string_size; 374 int delta = allocated_string_size - string_size;
455 Address start_filler_object = seq_two_byte->address() + string_size; 375 Address start_filler_object = seq_two_byte->address() + string_size;
456 seq_two_byte->set_length(count); 376 seq_two_byte->set_length(count);
457 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta); 377 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
458 } 378 }
459 string_val_ = isolate()->factory()->NewConsString(ascii, seq_two_byte); 379 return isolate()->factory()->NewConsString(ascii, seq_two_byte);
460 return Token::STRING;
461 } 380 }
462 381
463 382
464 Token::Value JsonParser::ScanJsonString() { 383 template <bool is_symbol>
384 Handle<Object> JsonParser::ScanJsonString() {
465 ASSERT_EQ('"', c0_); 385 ASSERT_EQ('"', c0_);
466 // Set string_val to null. If string_val is not set we assume an
467 // ascii string begining at next_.beg_pos + 1 to next_.end_pos - 1.
468 string_val_ = Handle<String>::null();
469 Advance(); 386 Advance();
387 beg_pos_ = position_;
470 // Fast case for ascii only without escape characters. 388 // Fast case for ascii only without escape characters.
471 while (c0_ != '"') { 389 while (c0_ != '"') {
472 // Check for control character (0x00-0x1f) or unterminated string (<0). 390 // Check for control character (0x00-0x1f) or unterminated string (<0).
473 if (c0_ < 0x20) return Token::ILLEGAL; 391 if (c0_ < 0x20) return ReportUnexpectedCharacter();
474 if (c0_ != '\\' && c0_ < kMaxAsciiCharCode) { 392 if (c0_ != '\\' && c0_ < kMaxAsciiCharCode) {
475 Advance(); 393 Advance();
476 } else { 394 } else {
477 return SlowScanJsonString(); 395 return SlowScanJsonString();
478 } 396 }
479 } 397 }
480 ASSERT_EQ('"', c0_); 398 ASSERT_EQ('"', c0_);
399 end_pos_ = position_;
481 // Advance past the last '"'. 400 // Advance past the last '"'.
482 Advance(); 401 AdvanceSkipWhitespace();
483 return Token::STRING; 402 if (is_sequential_ascii_ && is_symbol) {
484 }
485
486 Handle<String> JsonParser::GetString() {
487 return GetString(false);
488 }
489
490 Handle<String> JsonParser::GetSymbol() {
491 Handle<String> result = GetString(true);
492 if (result->IsSymbol()) return result;
493 return isolate()->factory()->LookupSymbol(result);
494 }
495
496 Handle<String> JsonParser::GetString(bool hint_symbol) {
497 // We have a non ascii string, return that.
498 if (!string_val_.is_null()) return string_val_;
499
500 if (is_sequential_ascii_ && hint_symbol) {
501 Handle<SeqAsciiString> seq = Handle<SeqAsciiString>::cast(source_);
502 // The current token includes the '"' in both ends.
503 int length = current_.end_pos - current_.beg_pos - 2;
504 return isolate()->factory()->LookupAsciiSymbol(seq_source_, 403 return isolate()->factory()->LookupAsciiSymbol(seq_source_,
505 current_.beg_pos + 1, 404 beg_pos_,
506 length); 405 end_pos_ - beg_pos_);
406 } else {
407 return isolate()->factory()->NewSubString(source_, beg_pos_, end_pos_);
507 } 408 }
508 // The current token includes the '"' in both ends.
509 return isolate()->factory()->NewSubString(
510 source_, current_.beg_pos + 1, current_.end_pos - 1);
511 } 409 }
512 410
513 } } // namespace v8::internal 411 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/json-parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698