OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |