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

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

Issue 6993057: Version 3.4.2 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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') | src/mark-compact.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 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 if (c0_ != '"') return ReportUnexpectedCharacter();
144 return ReportUnexpectedToken(); 171 Handle<String> key = ParseJsonSymbol();
145 } 172 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
146 Handle<String> key = GetString(true); 173 AdvanceSkipWhitespace();
147 if (Next() != Token::COLON) {
148 return ReportUnexpectedToken();
149 }
150
151 Handle<Object> value = ParseJsonValue(); 174 Handle<Object> value = ParseJsonValue();
152 if (value.is_null()) return Handle<Object>::null(); 175 if (value.is_null()) return ReportUnexpectedCharacter();
153 176
154 uint32_t index; 177 uint32_t index;
155 if (key->AsArrayIndex(&index)) { 178 if (key->AsArrayIndex(&index)) {
156 SetOwnElement(json_object, index, value, kNonStrictMode); 179 SetOwnElement(json_object, index, value, kNonStrictMode);
157 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { 180 } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
158 SetPrototype(json_object, value); 181 SetPrototype(json_object, value);
159 } else { 182 } else {
160 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); 183 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
161 } 184 }
162 } while (Next() == Token::COMMA); 185 } while (MatchSkipWhiteSpace(','));
163 if (current_.token != Token::RBRACE) { 186 if (c0_ != '}') {
164 return ReportUnexpectedToken(); 187 return ReportUnexpectedCharacter();
165 } 188 }
166 } 189 }
190 AdvanceSkipWhitespace();
167 return json_object; 191 return json_object;
168 } 192 }
169 193
170 // Parse a JSON array. Scanner must be right after '[' token. 194 // Parse a JSON array. Position must be right at '['.
171 Handle<Object> JsonParser::ParseJsonArray() { 195 Handle<Object> JsonParser::ParseJsonArray() {
172 ZoneScope zone_scope(isolate(), DELETE_ON_EXIT); 196 ZoneScope zone_scope(isolate(), DELETE_ON_EXIT);
173 ZoneList<Handle<Object> > elements(4); 197 ZoneList<Handle<Object> > elements(4);
198 ASSERT_EQ(c0_, '[');
174 199
175 Token::Value token = Peek(); 200 AdvanceSkipWhitespace();
176 if (token == Token::RBRACK) { 201 if (c0_ != ']') {
177 Next();
178 } else {
179 do { 202 do {
180 Handle<Object> element = ParseJsonValue(); 203 Handle<Object> element = ParseJsonValue();
181 if (element.is_null()) return Handle<Object>::null(); 204 if (element.is_null()) return ReportUnexpectedCharacter();
182 elements.Add(element); 205 elements.Add(element);
183 token = Next(); 206 } while (MatchSkipWhiteSpace(','));
184 } while (token == Token::COMMA); 207 if (c0_ != ']') {
185 if (token != Token::RBRACK) { 208 return ReportUnexpectedCharacter();
186 return ReportUnexpectedToken();
187 } 209 }
188 } 210 }
189 211 AdvanceSkipWhitespace();
190 // Allocate a fixed array with all the elements. 212 // Allocate a fixed array with all the elements.
191 Handle<FixedArray> fast_elements = 213 Handle<FixedArray> fast_elements =
192 isolate()->factory()->NewFixedArray(elements.length()); 214 isolate()->factory()->NewFixedArray(elements.length());
193
194 for (int i = 0, n = elements.length(); i < n; i++) { 215 for (int i = 0, n = elements.length(); i < n; i++) {
195 fast_elements->set(i, *elements[i]); 216 fast_elements->set(i, *elements[i]);
196 } 217 }
197
198 return isolate()->factory()->NewJSArrayWithElements(fast_elements); 218 return isolate()->factory()->NewJSArrayWithElements(fast_elements);
199 } 219 }
200 220
201 221
202 Token::Value JsonParser::Next() { 222 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; 223 bool negative = false;
305 224 beg_pos_ = position_;
306 if (c0_ == '-') { 225 if (c0_ == '-') {
307 Advance(); 226 Advance();
308 negative = true; 227 negative = true;
309 } 228 }
310 if (c0_ == '0') { 229 if (c0_ == '0') {
311 Advance(); 230 Advance();
312 // Prefix zero is only allowed if it's the only digit before 231 // Prefix zero is only allowed if it's the only digit before
313 // a decimal point or exponent. 232 // a decimal point or exponent.
314 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; 233 if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter();
315 } else { 234 } else {
316 int i = 0; 235 int i = 0;
317 int digits = 0; 236 int digits = 0;
318 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; 237 if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter();
319 do { 238 do {
320 i = i * 10 + c0_ - '0'; 239 i = i * 10 + c0_ - '0';
321 digits++; 240 digits++;
322 Advance(); 241 Advance();
323 } while (c0_ >= '0' && c0_ <= '9'); 242 } while (c0_ >= '0' && c0_ <= '9');
324 if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { 243 if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
325 number_ = (negative ? -i : i); 244 number_ = (negative ? -i : i);
326 return Token::NUMBER; 245 SkipWhitespace();
246 return isolate()->factory()->NewNumber(number_);
327 } 247 }
328 } 248 }
329 if (c0_ == '.') { 249 if (c0_ == '.') {
330 Advance(); 250 Advance();
331 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 251 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
332 do { 252 do {
333 Advance(); 253 Advance();
334 } while (c0_ >= '0' && c0_ <= '9'); 254 } while (c0_ >= '0' && c0_ <= '9');
335 } 255 }
336 if (AsciiAlphaToLower(c0_) == 'e') { 256 if (AsciiAlphaToLower(c0_) == 'e') {
337 Advance(); 257 Advance();
338 if (c0_ == '-' || c0_ == '+') Advance(); 258 if (c0_ == '-' || c0_ == '+') Advance();
339 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 259 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
340 do { 260 do {
341 Advance(); 261 Advance();
342 } while (c0_ >= '0' && c0_ <= '9'); 262 } while (c0_ >= '0' && c0_ <= '9');
343 } 263 }
264 int length = position_ - beg_pos_;
344 if (is_sequential_ascii_) { 265 if (is_sequential_ascii_) {
345 Vector<const char> chars(seq_source_->GetChars() + next_.beg_pos, 266 Vector<const char> chars(seq_source_->GetChars() + beg_pos_, length);
346 position_ - next_.beg_pos);
347 number_ = StringToDouble(isolate()->unicode_cache(), 267 number_ = StringToDouble(isolate()->unicode_cache(),
348 chars, 268 chars,
349 NO_FLAGS, // Hex, octal or trailing junk. 269 NO_FLAGS, // Hex, octal or trailing junk.
350 OS::nan_value()); 270 OS::nan_value());
351 } else { 271 } else {
352 Vector<char> buffer = Vector<char>::New(position_ - next_.beg_pos); 272 Vector<char> buffer = Vector<char>::New(length);
353 String::WriteToFlat(*source_, buffer.start(), next_.beg_pos, position_); 273 String::WriteToFlat(*source_, buffer.start(), beg_pos_, position_);
354 Vector<const char> result = 274 Vector<const char> result =
355 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), 275 Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
356 position_ - next_.beg_pos); 276 length);
357 number_ = StringToDouble(isolate()->unicode_cache(), 277 number_ = StringToDouble(isolate()->unicode_cache(),
358 result, 278 result,
359 NO_FLAGS, // Hex, octal or trailing junk. 279 NO_FLAGS, // Hex, octal or trailing junk.
360 0.0); 280 0.0);
361 buffer.Dispose(); 281 buffer.Dispose();
362 } 282 }
363 return Token::NUMBER; 283 SkipWhitespace();
284 return isolate()->factory()->NewNumber(number_);
364 } 285 }
365 286
366 Token::Value JsonParser::SlowScanJsonString() { 287 Handle<String> JsonParser::SlowScanJsonString() {
367 // The currently scanned ascii characters. 288 // The currently scanned ascii characters.
368 Handle<String> ascii(isolate()->factory()->NewSubString(source_, 289 Handle<String> ascii(isolate()->factory()->NewSubString(source_,
369 next_.beg_pos + 1, 290 beg_pos_,
370 position_)); 291 position_));
371 Handle<String> two_byte = 292 Handle<String> two_byte =
372 isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize, 293 isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize,
373 NOT_TENURED); 294 NOT_TENURED);
374 Handle<SeqTwoByteString> seq_two_byte = 295 Handle<SeqTwoByteString> seq_two_byte =
375 Handle<SeqTwoByteString>::cast(two_byte); 296 Handle<SeqTwoByteString>::cast(two_byte);
376 297
377 int allocation_count = 1; 298 int allocation_count = 1;
378 int count = 0; 299 int count = 0;
379 300
380 while (c0_ != '"') { 301 while (c0_ != '"') {
381 // Create new seq string 302 // Create new seq string
382 if (count >= kInitialSpecialStringSize * allocation_count) { 303 if (count >= kInitialSpecialStringSize * allocation_count) {
383 allocation_count = allocation_count * 2; 304 allocation_count = allocation_count * 2;
384 int new_size = allocation_count * kInitialSpecialStringSize; 305 int new_size = allocation_count * kInitialSpecialStringSize;
385 Handle<String> new_two_byte = 306 Handle<String> new_two_byte =
386 isolate()->factory()->NewRawTwoByteString(new_size, 307 isolate()->factory()->NewRawTwoByteString(new_size,
387 NOT_TENURED); 308 NOT_TENURED);
388 uc16* char_start = 309 uc16* char_start =
389 Handle<SeqTwoByteString>::cast(new_two_byte)->GetChars(); 310 Handle<SeqTwoByteString>::cast(new_two_byte)->GetChars();
390 String::WriteToFlat(*seq_two_byte, char_start, 0, count); 311 String::WriteToFlat(*seq_two_byte, char_start, 0, count);
391 seq_two_byte = Handle<SeqTwoByteString>::cast(new_two_byte); 312 seq_two_byte = Handle<SeqTwoByteString>::cast(new_two_byte);
392 } 313 }
393 314
394 // Check for control character (0x00-0x1f) or unterminated string (<0). 315 // Check for control character (0x00-0x1f) or unterminated string (<0).
395 if (c0_ < 0x20) return Token::ILLEGAL; 316 if (c0_ < 0x20) return Handle<String>::null();
396 if (c0_ != '\\') { 317 if (c0_ != '\\') {
397 seq_two_byte->SeqTwoByteStringSet(count++, c0_); 318 seq_two_byte->SeqTwoByteStringSet(count++, c0_);
398 Advance(); 319 Advance();
399 } else { 320 } else {
400 Advance(); 321 Advance();
401 switch (c0_) { 322 switch (c0_) {
402 case '"': 323 case '"':
403 case '\\': 324 case '\\':
404 case '/': 325 case '/':
405 seq_two_byte->SeqTwoByteStringSet(count++, c0_); 326 seq_two_byte->SeqTwoByteStringSet(count++, c0_);
(...skipping 12 matching lines...) Expand all
418 break; 339 break;
419 case 't': 340 case 't':
420 seq_two_byte->SeqTwoByteStringSet(count++, '\x09'); 341 seq_two_byte->SeqTwoByteStringSet(count++, '\x09');
421 break; 342 break;
422 case 'u': { 343 case 'u': {
423 uc32 value = 0; 344 uc32 value = 0;
424 for (int i = 0; i < 4; i++) { 345 for (int i = 0; i < 4; i++) {
425 Advance(); 346 Advance();
426 int digit = HexValue(c0_); 347 int digit = HexValue(c0_);
427 if (digit < 0) { 348 if (digit < 0) {
428 return Token::ILLEGAL; 349 return Handle<String>::null();
429 } 350 }
430 value = value * 16 + digit; 351 value = value * 16 + digit;
431 } 352 }
432 seq_two_byte->SeqTwoByteStringSet(count++, value); 353 seq_two_byte->SeqTwoByteStringSet(count++, value);
433 break; 354 break;
434 } 355 }
435 default: 356 default:
436 return Token::ILLEGAL; 357 return Handle<String>::null();
437 } 358 }
438 Advance(); 359 Advance();
439 } 360 }
440 } 361 }
441 // Advance past the last '"'. 362 // Advance past the last '"'.
442 ASSERT_EQ('"', c0_); 363 ASSERT_EQ('"', c0_);
443 Advance(); 364 AdvanceSkipWhitespace();
444 365
445 // Shrink the the string to our length. 366 // Shrink the the string to our length.
446 if (isolate()->heap()->InNewSpace(*seq_two_byte)) { 367 if (isolate()->heap()->InNewSpace(*seq_two_byte)) {
447 isolate()->heap()->new_space()-> 368 isolate()->heap()->new_space()->
448 ShrinkStringAtAllocationBoundary<SeqTwoByteString>(*seq_two_byte, 369 ShrinkStringAtAllocationBoundary<SeqTwoByteString>(*seq_two_byte,
449 count); 370 count);
450 } else { 371 } else {
451 int string_size = SeqTwoByteString::SizeFor(count); 372 int string_size = SeqTwoByteString::SizeFor(count);
452 int allocated_string_size = 373 int allocated_string_size =
453 SeqTwoByteString::SizeFor(kInitialSpecialStringSize * allocation_count); 374 SeqTwoByteString::SizeFor(kInitialSpecialStringSize * allocation_count);
454 int delta = allocated_string_size - string_size; 375 int delta = allocated_string_size - string_size;
455 Address start_filler_object = seq_two_byte->address() + string_size; 376 Address start_filler_object = seq_two_byte->address() + string_size;
456 seq_two_byte->set_length(count); 377 seq_two_byte->set_length(count);
457 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta); 378 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
458 } 379 }
459 string_val_ = isolate()->factory()->NewConsString(ascii, seq_two_byte); 380 return isolate()->factory()->NewConsString(ascii, seq_two_byte);
460 return Token::STRING;
461 } 381 }
462 382
463 383
464 Token::Value JsonParser::ScanJsonString() { 384 template <bool is_symbol>
385 Handle<String> JsonParser::ScanJsonString() {
465 ASSERT_EQ('"', c0_); 386 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(); 387 Advance();
388 beg_pos_ = position_;
470 // Fast case for ascii only without escape characters. 389 // Fast case for ascii only without escape characters.
471 while (c0_ != '"') { 390 while (c0_ != '"') {
472 // Check for control character (0x00-0x1f) or unterminated string (<0). 391 // Check for control character (0x00-0x1f) or unterminated string (<0).
473 if (c0_ < 0x20) return Token::ILLEGAL; 392 if (c0_ < 0x20) return Handle<String>::null();
474 if (c0_ != '\\' && c0_ < kMaxAsciiCharCode) { 393 if (c0_ != '\\' && c0_ < kMaxAsciiCharCode) {
475 Advance(); 394 Advance();
476 } else { 395 } else {
477 return SlowScanJsonString(); 396 return SlowScanJsonString();
478 } 397 }
479 } 398 }
480 ASSERT_EQ('"', c0_); 399 ASSERT_EQ('"', c0_);
400 end_pos_ = position_;
481 // Advance past the last '"'. 401 // Advance past the last '"'.
482 Advance(); 402 AdvanceSkipWhitespace();
483 return Token::STRING; 403 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_, 404 return isolate()->factory()->LookupAsciiSymbol(seq_source_,
505 current_.beg_pos + 1, 405 beg_pos_,
506 length); 406 end_pos_ - beg_pos_);
407 } else {
408 return isolate()->factory()->NewSubString(source_, beg_pos_, end_pos_);
507 } 409 }
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 } 410 }
512 411
513 } } // namespace v8::internal 412 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/json-parser.h ('k') | src/mark-compact.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698