v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
json-parser.h
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_JSON_PARSER_H_
29 #define V8_JSON_PARSER_H_
30 
31 #include "v8.h"
32 
33 #include "char-predicates-inl.h"
34 #include "v8conversions.h"
35 #include "messages.h"
36 #include "spaces-inl.h"
37 #include "token.h"
38 
39 namespace v8 {
40 namespace internal {
41 
42 // A simple json parser.
43 template <bool seq_ascii>
44 class JsonParser BASE_EMBEDDED {
45  public:
46  static Handle<Object> Parse(Handle<String> source, Zone* zone) {
47  return JsonParser().ParseJson(source, zone);
48  }
49 
50  static const int kEndOfString = -1;
51 
52  private:
53  // Parse a string containing a single JSON value.
54  Handle<Object> ParseJson(Handle<String> source, Zone* zone);
55 
56  inline void Advance() {
57  position_++;
58  if (position_ >= source_length_) {
59  c0_ = kEndOfString;
60  } else if (seq_ascii) {
61  c0_ = seq_source_->SeqAsciiStringGet(position_);
62  } else {
63  c0_ = source_->Get(position_);
64  }
65  }
66 
67  // The JSON lexical grammar is specified in the ECMAScript 5 standard,
68  // section 15.12.1.1. The only allowed whitespace characters between tokens
69  // are tab, carriage-return, newline and space.
70 
71  inline void AdvanceSkipWhitespace() {
72  do {
73  Advance();
74  } while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r');
75  }
76 
77  inline void SkipWhitespace() {
78  while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r') {
79  Advance();
80  }
81  }
82 
83  inline uc32 AdvanceGetChar() {
84  Advance();
85  return c0_;
86  }
87 
88  // Checks that current charater is c.
89  // If so, then consume c and skip whitespace.
90  inline bool MatchSkipWhiteSpace(uc32 c) {
91  if (c0_ == c) {
92  AdvanceSkipWhitespace();
93  return true;
94  }
95  return false;
96  }
97 
98  // A JSON string (production JSONString) is subset of valid JavaScript string
99  // literals. The string must only be double-quoted (not single-quoted), and
100  // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and
101  // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid.
102  Handle<String> ParseJsonString() {
103  return ScanJsonString<false>();
104  }
105  Handle<String> ParseJsonSymbol() {
106  return ScanJsonString<true>();
107  }
108  template <bool is_symbol>
109  Handle<String> ScanJsonString();
110  // Creates a new string and copies prefix[start..end] into the beginning
111  // of it. Then scans the rest of the string, adding characters after the
112  // prefix. Called by ScanJsonString when reaching a '\' or non-ASCII char.
113  template <typename StringType, typename SinkChar>
114  Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end);
115 
116  // A JSON number (production JSONNumber) is a subset of the valid JavaScript
117  // decimal number literals.
118  // It includes an optional minus sign, must have at least one
119  // digit before and after a decimal point, may not have prefixed zeros (unless
120  // the integer part is zero), and may include an exponent part (e.g., "e-10").
121  // Hexadecimal and octal numbers are not allowed.
122  Handle<Object> ParseJsonNumber();
123 
124  // Parse a single JSON value from input (grammar production JSONValue).
125  // A JSON value is either a (double-quoted) string literal, a number literal,
126  // one of "true", "false", or "null", or an object or array literal.
127  Handle<Object> ParseJsonValue();
128 
129  // Parse a JSON object literal (grammar production JSONObject).
130  // An object literal is a squiggly-braced and comma separated sequence
131  // (possibly empty) of key/value pairs, where the key is a JSON string
132  // literal, the value is a JSON value, and the two are separated by a colon.
133  // A JSON array doesn't allow numbers and identifiers as keys, like a
134  // JavaScript array.
135  Handle<Object> ParseJsonObject();
136 
137  // Parses a JSON array literal (grammar production JSONArray). An array
138  // literal is a square-bracketed and comma separated sequence (possibly empty)
139  // of JSON values.
140  // A JSON array doesn't allow leaving out values from the sequence, nor does
141  // it allow a terminal comma, like a JavaScript array does.
142  Handle<Object> ParseJsonArray();
143 
144 
145  // Mark that a parsing error has happened at the current token, and
146  // return a null handle. Primarily for readability.
147  inline Handle<Object> ReportUnexpectedCharacter() {
148  return Handle<Object>::null();
149  }
150 
151  inline Isolate* isolate() { return isolate_; }
152  inline Factory* factory() { return factory_; }
153  inline Handle<JSFunction> object_constructor() { return object_constructor_; }
154  inline Zone* zone() const { return zone_; }
155 
156  static const int kInitialSpecialStringLength = 1024;
157 
158 
159  private:
160  Handle<String> source_;
161  int source_length_;
162  Handle<SeqAsciiString> seq_source_;
163 
164  Isolate* isolate_;
165  Factory* factory_;
166  Handle<JSFunction> object_constructor_;
167  uc32 c0_;
168  int position_;
169  Zone* zone_;
170 };
171 
172 template <bool seq_ascii>
173 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
174  Zone* zone) {
175  isolate_ = source->map()->GetHeap()->isolate();
176  factory_ = isolate_->factory();
177  object_constructor_ =
178  Handle<JSFunction>(isolate()->native_context()->object_function());
179  zone_ = zone;
180  FlattenString(source);
181  source_ = source;
182  source_length_ = source_->length();
183 
184  // Optimized fast case where we only have ASCII characters.
185  if (seq_ascii) {
186  seq_source_ = Handle<SeqAsciiString>::cast(source_);
187  }
188 
189  // Set initial position right before the string.
190  position_ = -1;
191  // Advance to the first character (possibly EOS)
192  AdvanceSkipWhitespace();
193  Handle<Object> result = ParseJsonValue();
194  if (result.is_null() || c0_ != kEndOfString) {
195  // Parse failed. Current character is the unexpected token.
196 
197  const char* message;
198  Factory* factory = this->factory();
199  Handle<JSArray> array;
200 
201  switch (c0_) {
202  case kEndOfString:
203  message = "unexpected_eos";
204  array = factory->NewJSArray(0);
205  break;
206  case '-':
207  case '0':
208  case '1':
209  case '2':
210  case '3':
211  case '4':
212  case '5':
213  case '6':
214  case '7':
215  case '8':
216  case '9':
217  message = "unexpected_token_number";
218  array = factory->NewJSArray(0);
219  break;
220  case '"':
221  message = "unexpected_token_string";
222  array = factory->NewJSArray(0);
223  break;
224  default:
225  message = "unexpected_token";
226  Handle<Object> name = LookupSingleCharacterStringFromCode(c0_);
227  Handle<FixedArray> element = factory->NewFixedArray(1);
228  element->set(0, *name);
229  array = factory->NewJSArrayWithElements(element);
230  break;
231  }
232 
233  MessageLocation location(factory->NewScript(source),
234  position_,
235  position_ + 1);
236  Handle<Object> result = factory->NewSyntaxError(message, array);
237  isolate()->Throw(*result, &location);
238  return Handle<Object>::null();
239  }
240  return result;
241 }
242 
243 
244 // Parse any JSON value.
245 template <bool seq_ascii>
246 Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() {
247  if (c0_ == '"') return ParseJsonString();
248  if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber();
249  if (c0_ == '{') return ParseJsonObject();
250  if (c0_ == '[') return ParseJsonArray();
251  if (c0_ == 'f') {
252  if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
253  AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
254  AdvanceSkipWhitespace();
255  return factory()->false_value();
256  }
257  return ReportUnexpectedCharacter();
258  }
259  if (c0_ == 't') {
260  if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
261  AdvanceGetChar() == 'e') {
262  AdvanceSkipWhitespace();
263  return factory()->true_value();
264  }
265  return ReportUnexpectedCharacter();
266  }
267  if (c0_ == 'n') {
268  if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
269  AdvanceGetChar() == 'l') {
270  AdvanceSkipWhitespace();
271  return factory()->null_value();
272  }
273  return ReportUnexpectedCharacter();
274  }
275  return ReportUnexpectedCharacter();
276 }
277 
278 
279 // Parse a JSON object. Position must be right at '{'.
280 template <bool seq_ascii>
281 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
282  Handle<Object> prototype;
283  Handle<JSObject> json_object =
284  factory()->NewJSObject(object_constructor());
285  ASSERT_EQ(c0_, '{');
286 
287  AdvanceSkipWhitespace();
288  if (c0_ != '}') {
289  do {
290  if (c0_ != '"') return ReportUnexpectedCharacter();
291 
292  int start_position = position_;
293  Advance();
294 
295  uint32_t index = 0;
296  while (c0_ >= '0' && c0_ <= '9') {
297  int d = c0_ - '0';
298  if (index > 429496729U - ((d > 5) ? 1 : 0)) break;
299  index = (index * 10) + d;
300  Advance();
301  }
302 
303  if (position_ != start_position + 1 && c0_ == '"') {
304  AdvanceSkipWhitespace();
305 
306  if (c0_ != ':') return ReportUnexpectedCharacter();
307  AdvanceSkipWhitespace();
308  Handle<Object> value = ParseJsonValue();
309  if (value.is_null()) return ReportUnexpectedCharacter();
310 
311  JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
312  } else {
313  position_ = start_position;
314 #ifdef DEBUG
315  c0_ = '"';
316 #endif
317 
318  Handle<String> key = ParseJsonSymbol();
319  if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
320 
321  AdvanceSkipWhitespace();
322  Handle<Object> value = ParseJsonValue();
323  if (value.is_null()) return ReportUnexpectedCharacter();
324 
325  if (key->Equals(isolate()->heap()->Proto_symbol())) {
326  prototype = value;
327  } else {
328  if (JSObject::TryTransitionToField(json_object, key)) {
329  int index = json_object->LastAddedFieldIndex();
330  json_object->FastPropertyAtPut(index, *value);
331  } else {
333  json_object, key, value, NONE);
334  }
335  }
336  }
337  } while (MatchSkipWhiteSpace(','));
338  if (c0_ != '}') {
339  return ReportUnexpectedCharacter();
340  }
341  if (!prototype.is_null()) SetPrototype(json_object, prototype);
342  }
343  AdvanceSkipWhitespace();
344  return json_object;
345 }
346 
347 // Parse a JSON array. Position must be right at '['.
348 template <bool seq_ascii>
349 Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
350  ZoneScope zone_scope(zone(), DELETE_ON_EXIT);
351  ZoneList<Handle<Object> > elements(4, zone());
352  ASSERT_EQ(c0_, '[');
353 
354  AdvanceSkipWhitespace();
355  if (c0_ != ']') {
356  do {
357  Handle<Object> element = ParseJsonValue();
358  if (element.is_null()) return ReportUnexpectedCharacter();
359  elements.Add(element, zone());
360  } while (MatchSkipWhiteSpace(','));
361  if (c0_ != ']') {
362  return ReportUnexpectedCharacter();
363  }
364  }
365  AdvanceSkipWhitespace();
366  // Allocate a fixed array with all the elements.
367  Handle<FixedArray> fast_elements =
368  factory()->NewFixedArray(elements.length());
369  for (int i = 0, n = elements.length(); i < n; i++) {
370  fast_elements->set(i, *elements[i]);
371  }
372  return factory()->NewJSArrayWithElements(fast_elements);
373 }
374 
375 
376 template <bool seq_ascii>
377 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
378  bool negative = false;
379  int beg_pos = position_;
380  if (c0_ == '-') {
381  Advance();
382  negative = true;
383  }
384  if (c0_ == '0') {
385  Advance();
386  // Prefix zero is only allowed if it's the only digit before
387  // a decimal point or exponent.
388  if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter();
389  } else {
390  int i = 0;
391  int digits = 0;
392  if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter();
393  do {
394  i = i * 10 + c0_ - '0';
395  digits++;
396  Advance();
397  } while (c0_ >= '0' && c0_ <= '9');
398  if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
399  SkipWhitespace();
400  return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate());
401  }
402  }
403  if (c0_ == '.') {
404  Advance();
405  if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
406  do {
407  Advance();
408  } while (c0_ >= '0' && c0_ <= '9');
409  }
410  if (AsciiAlphaToLower(c0_) == 'e') {
411  Advance();
412  if (c0_ == '-' || c0_ == '+') Advance();
413  if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
414  do {
415  Advance();
416  } while (c0_ >= '0' && c0_ <= '9');
417  }
418  int length = position_ - beg_pos;
419  double number;
420  if (seq_ascii) {
421  Vector<const char> chars(seq_source_->GetChars() + beg_pos, length);
422  number = StringToDouble(isolate()->unicode_cache(),
423  chars,
424  NO_FLAGS, // Hex, octal or trailing junk.
425  OS::nan_value());
426  } else {
427  Vector<char> buffer = Vector<char>::New(length);
428  String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
429  Vector<const char> result =
430  Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
431  length);
432  number = StringToDouble(isolate()->unicode_cache(),
433  result,
434  NO_FLAGS, // Hex, octal or trailing junk.
435  0.0);
436  buffer.Dispose();
437  }
438  SkipWhitespace();
439  return factory()->NewNumber(number);
440 }
441 
442 
443 template <typename StringType>
444 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c);
445 
446 template <>
447 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) {
448  seq_str->SeqTwoByteStringSet(i, c);
449 }
450 
451 template <>
452 inline void SeqStringSet(Handle<SeqAsciiString> seq_str, int i, uc32 c) {
453  seq_str->SeqAsciiStringSet(i, c);
454 }
455 
456 template <typename StringType>
457 inline Handle<StringType> NewRawString(Factory* factory, int length);
458 
459 template <>
460 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length) {
461  return factory->NewRawTwoByteString(length, NOT_TENURED);
462 }
463 
464 template <>
465 inline Handle<SeqAsciiString> NewRawString(Factory* factory, int length) {
466  return factory->NewRawAsciiString(length, NOT_TENURED);
467 }
468 
469 
470 // Scans the rest of a JSON string starting from position_ and writes
471 // prefix[start..end] along with the scanned characters into a
472 // sequential string of type StringType.
473 template <bool seq_ascii>
474 template <typename StringType, typename SinkChar>
475 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
476  Handle<String> prefix, int start, int end) {
477  int count = end - start;
478  int max_length = count + source_length_ - position_;
479  int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
480  Handle<StringType> seq_str = NewRawString<StringType>(factory(), length);
481  // Copy prefix into seq_str.
482  SinkChar* dest = seq_str->GetChars();
483  String::WriteToFlat(*prefix, dest, start, end);
484 
485  while (c0_ != '"') {
486  // Check for control character (0x00-0x1f) or unterminated string (<0).
487  if (c0_ < 0x20) return Handle<String>::null();
488  if (count >= length) {
489  // We need to create a longer sequential string for the result.
490  return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count);
491  }
492  if (c0_ != '\\') {
493  // If the sink can contain UC16 characters, or source_ contains only
494  // ASCII characters, there's no need to test whether we can store the
495  // character. Otherwise check whether the UC16 source character can fit
496  // in the ASCII sink.
497  if (sizeof(SinkChar) == kUC16Size ||
498  seq_ascii ||
499  c0_ <= kMaxAsciiCharCode) {
500  SeqStringSet(seq_str, count++, c0_);
501  Advance();
502  } else {
503  // StringType is SeqAsciiString and we just read a non-ASCII char.
504  return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count);
505  }
506  } else {
507  Advance(); // Advance past the \.
508  switch (c0_) {
509  case '"':
510  case '\\':
511  case '/':
512  SeqStringSet(seq_str, count++, c0_);
513  break;
514  case 'b':
515  SeqStringSet(seq_str, count++, '\x08');
516  break;
517  case 'f':
518  SeqStringSet(seq_str, count++, '\x0c');
519  break;
520  case 'n':
521  SeqStringSet(seq_str, count++, '\x0a');
522  break;
523  case 'r':
524  SeqStringSet(seq_str, count++, '\x0d');
525  break;
526  case 't':
527  SeqStringSet(seq_str, count++, '\x09');
528  break;
529  case 'u': {
530  uc32 value = 0;
531  for (int i = 0; i < 4; i++) {
532  Advance();
533  int digit = HexValue(c0_);
534  if (digit < 0) {
535  return Handle<String>::null();
536  }
537  value = value * 16 + digit;
538  }
539  if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) {
540  SeqStringSet(seq_str, count++, value);
541  break;
542  } else {
543  // StringType is SeqAsciiString and we just read a non-ASCII char.
544  position_ -= 6; // Rewind position_ to \ in \uxxxx.
545  Advance();
546  return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str,
547  0,
548  count);
549  }
550  }
551  default:
552  return Handle<String>::null();
553  }
554  Advance();
555  }
556  }
557  // Shrink seq_string length to count.
558  if (isolate()->heap()->InNewSpace(*seq_str)) {
559  isolate()->heap()->new_space()->
560  template ShrinkStringAtAllocationBoundary<StringType>(
561  *seq_str, count);
562  } else {
563  int string_size = StringType::SizeFor(count);
564  int allocated_string_size = StringType::SizeFor(length);
565  int delta = allocated_string_size - string_size;
566  Address start_filler_object = seq_str->address() + string_size;
567  seq_str->set_length(count);
568  isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
569  }
570  ASSERT_EQ('"', c0_);
571  // Advance past the last '"'.
572  AdvanceSkipWhitespace();
573  return seq_str;
574 }
575 
576 
577 template <bool seq_ascii>
578 template <bool is_symbol>
579 Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
580  ASSERT_EQ('"', c0_);
581  Advance();
582  if (c0_ == '"') {
583  AdvanceSkipWhitespace();
584  return Handle<String>(isolate()->heap()->empty_string());
585  }
586 
587  if (seq_ascii && is_symbol) {
588  // Fast path for existing symbols. If the the string being parsed is not
589  // a known symbol, contains backslashes or unexpectedly reaches the end of
590  // string, return with an empty handle.
591  uint32_t running_hash = isolate()->heap()->HashSeed();
592  int position = position_;
593  uc32 c0 = c0_;
594  do {
595  if (c0 == '\\') {
596  c0_ = c0;
597  int beg_pos = position_;
598  position_ = position;
599  return SlowScanJsonString<SeqAsciiString, char>(source_,
600  beg_pos,
601  position_);
602  }
603  if (c0 < 0x20) return Handle<String>::null();
604  running_hash = StringHasher::AddCharacterCore(running_hash, c0);
605  position++;
606  if (position >= source_length_) return Handle<String>::null();
607  c0 = seq_source_->SeqAsciiStringGet(position);
608  } while (c0 != '"');
609  int length = position - position_;
610  uint32_t hash = (length <= String::kMaxHashCalcLength)
611  ? StringHasher::GetHashCore(running_hash) : length;
612  Vector<const char> string_vector(
613  seq_source_->GetChars() + position_, length);
614  SymbolTable* symbol_table = isolate()->heap()->symbol_table();
615  uint32_t capacity = symbol_table->Capacity();
616  uint32_t entry = SymbolTable::FirstProbe(hash, capacity);
617  uint32_t count = 1;
618  while (true) {
619  Object* element = symbol_table->KeyAt(entry);
620  if (element == isolate()->heap()->raw_unchecked_undefined_value()) {
621  // Lookup failure.
622  break;
623  }
624  if (element != isolate()->heap()->raw_unchecked_the_hole_value() &&
625  String::cast(element)->IsAsciiEqualTo(string_vector)) {
626  // Lookup success, update the current position.
627  position_ = position;
628  // Advance past the last '"'.
629  AdvanceSkipWhitespace();
630  return Handle<String>(String::cast(element));
631  }
632  entry = SymbolTable::NextProbe(entry, count++, capacity);
633  }
634  }
635 
636  int beg_pos = position_;
637  // Fast case for ASCII only without escape characters.
638  do {
639  // Check for control character (0x00-0x1f) or unterminated string (<0).
640  if (c0_ < 0x20) return Handle<String>::null();
641  if (c0_ != '\\') {
642  if (seq_ascii || c0_ <= kMaxAsciiCharCode) {
643  Advance();
644  } else {
645  return SlowScanJsonString<SeqTwoByteString, uc16>(source_,
646  beg_pos,
647  position_);
648  }
649  } else {
650  return SlowScanJsonString<SeqAsciiString, char>(source_,
651  beg_pos,
652  position_);
653  }
654  } while (c0_ != '"');
655  int length = position_ - beg_pos;
656  Handle<String> result;
657  if (seq_ascii && is_symbol) {
658  result = factory()->LookupAsciiSymbol(seq_source_,
659  beg_pos,
660  length);
661  } else {
662  result = factory()->NewRawAsciiString(length);
663  char* dest = SeqAsciiString::cast(*result)->GetChars();
664  String::WriteToFlat(*source_, dest, beg_pos, position_);
665  }
666  ASSERT_EQ('"', c0_);
667  // Advance past the last '"'.
668  AdvanceSkipWhitespace();
669  return result;
670 }
671 
672 } } // namespace v8::internal
673 
674 #endif // V8_JSON_PARSER_H_
byte * Address
Definition: globals.h:157
void FlattenString(Handle< String > string)
Definition: handles.cc:211
static String * cast(Object *obj)
static Smi * FromInt(int value)
Definition: objects-inl.h:981
Handle< SeqAsciiString > NewRawAsciiString(int length, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:225
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
static const int kMaxHashCalcLength
Definition: objects.h:7390
int AsciiAlphaToLower(uc32 c)
int32_t uc32
Definition: globals.h:260
static bool TryTransitionToField(Handle< JSObject > object, Handle< String > key)
Definition: objects-inl.h:1432
static Handle< Object > SetOwnElement(Handle< JSObject > object, uint32_t index, Handle< Object > value, StrictModeFlag strict_mode)
Definition: objects.cc:9874
double StringToDouble(UnicodeCache *unicode_cache, const char *str, int flags, double empty_string_val)
Definition: conversions.cc:41
static Handle< Object > Parse(Handle< String > source, Zone *zone)
Definition: json-parser.h:46
Handle< SeqTwoByteString > NewRawTwoByteString(int length, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:234
Handle< Object > LookupSingleCharacterStringFromCode(uint32_t index)
Definition: handles.cc:318
static SeqAsciiString * cast(Object *obj)
int HexValue(uc32 c)
Definition: scanner.h:66
static Handle< Object > SetLocalPropertyIgnoreAttributes(Handle< JSObject > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes)
Definition: objects.cc:2952
Definition: v8.h:105
static Vector< T > New(int length)
Definition: utils.h:370
#define BASE_EMBEDDED
Definition: allocation.h:68
static void WriteToFlat(String *source, sinkchar *sink, int from, int to)
Definition: objects.cc:6891
static double nan_value()
static Handle< T > null()
Definition: handles.h:86
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
Handle< StringType > NewRawString(Factory *factory, int length)
Definition: json-parser.h:460
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage message
Definition: flags.cc:495
static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size)
Definition: objects.h:2927
Handle< Object > SetPrototype(Handle< JSFunction > function, Handle< Object > prototype)
Definition: handles.cc:221
static uint32_t FirstProbe(uint32_t hash, uint32_t size)
Definition: objects.h:2923
void SeqStringSet(Handle< StringType > seq_str, int i, uc32 c)
const uc32 kMaxAsciiCharCode
Definition: globals.h:263
const int kUC16Size
Definition: globals.h:262