Home | History | Annotate | Download | only in src
      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/json-parser.h"
      6 
      7 #include "src/char-predicates-inl.h"
      8 #include "src/conversions.h"
      9 #include "src/debug/debug.h"
     10 #include "src/factory.h"
     11 #include "src/field-type.h"
     12 #include "src/messages.h"
     13 #include "src/objects-inl.h"
     14 #include "src/parsing/scanner.h"
     15 #include "src/parsing/token.h"
     16 #include "src/property-descriptor.h"
     17 #include "src/transitions.h"
     18 
     19 namespace v8 {
     20 namespace internal {
     21 
     22 MaybeHandle<Object> JsonParseInternalizer::Internalize(Isolate* isolate,
     23                                                        Handle<Object> object,
     24                                                        Handle<Object> reviver) {
     25   DCHECK(reviver->IsCallable());
     26   JsonParseInternalizer internalizer(isolate,
     27                                      Handle<JSReceiver>::cast(reviver));
     28   Handle<JSObject> holder =
     29       isolate->factory()->NewJSObject(isolate->object_function());
     30   Handle<String> name = isolate->factory()->empty_string();
     31   JSObject::AddProperty(holder, name, object, NONE);
     32   return internalizer.InternalizeJsonProperty(holder, name);
     33 }
     34 
     35 MaybeHandle<Object> JsonParseInternalizer::InternalizeJsonProperty(
     36     Handle<JSReceiver> holder, Handle<String> name) {
     37   HandleScope outer_scope(isolate_);
     38   Handle<Object> value;
     39   ASSIGN_RETURN_ON_EXCEPTION(
     40       isolate_, value, Object::GetPropertyOrElement(holder, name), Object);
     41   if (value->IsJSReceiver()) {
     42     Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
     43     Maybe<bool> is_array = Object::IsArray(object);
     44     if (is_array.IsNothing()) return MaybeHandle<Object>();
     45     if (is_array.FromJust()) {
     46       Handle<Object> length_object;
     47       ASSIGN_RETURN_ON_EXCEPTION(
     48           isolate_, length_object,
     49           Object::GetLengthFromArrayLike(isolate_, object), Object);
     50       double length = length_object->Number();
     51       for (double i = 0; i < length; i++) {
     52         HandleScope inner_scope(isolate_);
     53         Handle<Object> index = isolate_->factory()->NewNumber(i);
     54         Handle<String> name = isolate_->factory()->NumberToString(index);
     55         if (!RecurseAndApply(object, name)) return MaybeHandle<Object>();
     56       }
     57     } else {
     58       Handle<FixedArray> contents;
     59       ASSIGN_RETURN_ON_EXCEPTION(
     60           isolate_, contents,
     61           KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
     62                                   ENUMERABLE_STRINGS,
     63                                   GetKeysConversion::kConvertToString),
     64           Object);
     65       for (int i = 0; i < contents->length(); i++) {
     66         HandleScope inner_scope(isolate_);
     67         Handle<String> name(String::cast(contents->get(i)), isolate_);
     68         if (!RecurseAndApply(object, name)) return MaybeHandle<Object>();
     69       }
     70     }
     71   }
     72   Handle<Object> argv[] = {name, value};
     73   Handle<Object> result;
     74   ASSIGN_RETURN_ON_EXCEPTION(
     75       isolate_, result, Execution::Call(isolate_, reviver_, holder, 2, argv),
     76       Object);
     77   return outer_scope.CloseAndEscape(result);
     78 }
     79 
     80 bool JsonParseInternalizer::RecurseAndApply(Handle<JSReceiver> holder,
     81                                             Handle<String> name) {
     82   Handle<Object> result;
     83   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     84       isolate_, result, InternalizeJsonProperty(holder, name), false);
     85   Maybe<bool> change_result = Nothing<bool>();
     86   if (result->IsUndefined(isolate_)) {
     87     change_result = JSReceiver::DeletePropertyOrElement(holder, name, SLOPPY);
     88   } else {
     89     PropertyDescriptor desc;
     90     desc.set_value(result);
     91     desc.set_configurable(true);
     92     desc.set_enumerable(true);
     93     desc.set_writable(true);
     94     change_result = JSReceiver::DefineOwnProperty(isolate_, holder, name, &desc,
     95                                                   Object::DONT_THROW);
     96   }
     97   MAYBE_RETURN(change_result, false);
     98   return true;
     99 }
    100 
    101 template <bool seq_one_byte>
    102 JsonParser<seq_one_byte>::JsonParser(Isolate* isolate, Handle<String> source)
    103     : source_(source),
    104       source_length_(source->length()),
    105       isolate_(isolate),
    106       factory_(isolate_->factory()),
    107       zone_(isolate_->allocator()),
    108       object_constructor_(isolate_->native_context()->object_function(),
    109                           isolate_),
    110       position_(-1) {
    111   source_ = String::Flatten(source_);
    112   pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED;
    113 
    114   // Optimized fast case where we only have Latin1 characters.
    115   if (seq_one_byte) {
    116     seq_source_ = Handle<SeqOneByteString>::cast(source_);
    117   }
    118 }
    119 
    120 template <bool seq_one_byte>
    121 MaybeHandle<Object> JsonParser<seq_one_byte>::ParseJson() {
    122   // Advance to the first character (possibly EOS)
    123   AdvanceSkipWhitespace();
    124   Handle<Object> result = ParseJsonValue();
    125   if (result.is_null() || c0_ != kEndOfString) {
    126     // Some exception (for example stack overflow) is already pending.
    127     if (isolate_->has_pending_exception()) return Handle<Object>::null();
    128 
    129     // Parse failed. Current character is the unexpected token.
    130     Factory* factory = this->factory();
    131     MessageTemplate::Template message;
    132     Handle<Object> arg1 = Handle<Smi>(Smi::FromInt(position_), isolate());
    133     Handle<Object> arg2;
    134 
    135     switch (c0_) {
    136       case kEndOfString:
    137         message = MessageTemplate::kJsonParseUnexpectedEOS;
    138         break;
    139       case '-':
    140       case '0':
    141       case '1':
    142       case '2':
    143       case '3':
    144       case '4':
    145       case '5':
    146       case '6':
    147       case '7':
    148       case '8':
    149       case '9':
    150         message = MessageTemplate::kJsonParseUnexpectedTokenNumber;
    151         break;
    152       case '"':
    153         message = MessageTemplate::kJsonParseUnexpectedTokenString;
    154         break;
    155       default:
    156         message = MessageTemplate::kJsonParseUnexpectedToken;
    157         arg2 = arg1;
    158         arg1 = factory->LookupSingleCharacterStringFromCode(c0_);
    159         break;
    160     }
    161 
    162     Handle<Script> script(factory->NewScript(source_));
    163     // We should sent compile error event because we compile JSON object in
    164     // separated source file.
    165     isolate()->debug()->OnCompileError(script);
    166     MessageLocation location(script, position_, position_ + 1);
    167     Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2);
    168     return isolate()->template Throw<Object>(error, &location);
    169   }
    170   return result;
    171 }
    172 
    173 MaybeHandle<Object> InternalizeJsonProperty(Handle<JSObject> holder,
    174                                             Handle<String> key);
    175 
    176 template <bool seq_one_byte>
    177 void JsonParser<seq_one_byte>::Advance() {
    178   position_++;
    179   if (position_ >= source_length_) {
    180     c0_ = kEndOfString;
    181   } else if (seq_one_byte) {
    182     c0_ = seq_source_->SeqOneByteStringGet(position_);
    183   } else {
    184     c0_ = source_->Get(position_);
    185   }
    186 }
    187 
    188 template <bool seq_one_byte>
    189 void JsonParser<seq_one_byte>::AdvanceSkipWhitespace() {
    190   do {
    191     Advance();
    192   } while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r');
    193 }
    194 
    195 template <bool seq_one_byte>
    196 void JsonParser<seq_one_byte>::SkipWhitespace() {
    197   while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r') {
    198     Advance();
    199   }
    200 }
    201 
    202 template <bool seq_one_byte>
    203 uc32 JsonParser<seq_one_byte>::AdvanceGetChar() {
    204   Advance();
    205   return c0_;
    206 }
    207 
    208 template <bool seq_one_byte>
    209 bool JsonParser<seq_one_byte>::MatchSkipWhiteSpace(uc32 c) {
    210   if (c0_ == c) {
    211     AdvanceSkipWhitespace();
    212     return true;
    213   }
    214   return false;
    215 }
    216 
    217 template <bool seq_one_byte>
    218 bool JsonParser<seq_one_byte>::ParseJsonString(Handle<String> expected) {
    219   int length = expected->length();
    220   if (source_->length() - position_ - 1 > length) {
    221     DisallowHeapAllocation no_gc;
    222     String::FlatContent content = expected->GetFlatContent();
    223     if (content.IsOneByte()) {
    224       DCHECK_EQ('"', c0_);
    225       const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1;
    226       const uint8_t* expected_chars = content.ToOneByteVector().start();
    227       for (int i = 0; i < length; i++) {
    228         uint8_t c0 = input_chars[i];
    229         if (c0 != expected_chars[i] || c0 == '"' || c0 < 0x20 || c0 == '\\') {
    230           return false;
    231         }
    232       }
    233       if (input_chars[length] == '"') {
    234         position_ = position_ + length + 1;
    235         AdvanceSkipWhitespace();
    236         return true;
    237       }
    238     }
    239   }
    240   return false;
    241 }
    242 
    243 // Parse any JSON value.
    244 template <bool seq_one_byte>
    245 Handle<Object> JsonParser<seq_one_byte>::ParseJsonValue() {
    246   StackLimitCheck stack_check(isolate_);
    247   if (stack_check.HasOverflowed()) {
    248     isolate_->StackOverflow();
    249     return Handle<Object>::null();
    250   }
    251 
    252   if (stack_check.InterruptRequested() &&
    253       isolate_->stack_guard()->HandleInterrupts()->IsException(isolate_)) {
    254     return Handle<Object>::null();
    255   }
    256 
    257   if (c0_ == '"') return ParseJsonString();
    258   if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber();
    259   if (c0_ == '{') return ParseJsonObject();
    260   if (c0_ == '[') return ParseJsonArray();
    261   if (c0_ == 'f') {
    262     if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
    263         AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
    264       AdvanceSkipWhitespace();
    265       return factory()->false_value();
    266     }
    267     return ReportUnexpectedCharacter();
    268   }
    269   if (c0_ == 't') {
    270     if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
    271         AdvanceGetChar() == 'e') {
    272       AdvanceSkipWhitespace();
    273       return factory()->true_value();
    274     }
    275     return ReportUnexpectedCharacter();
    276   }
    277   if (c0_ == 'n') {
    278     if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
    279         AdvanceGetChar() == 'l') {
    280       AdvanceSkipWhitespace();
    281       return factory()->null_value();
    282     }
    283     return ReportUnexpectedCharacter();
    284   }
    285   return ReportUnexpectedCharacter();
    286 }
    287 
    288 template <bool seq_one_byte>
    289 ParseElementResult JsonParser<seq_one_byte>::ParseElement(
    290     Handle<JSObject> json_object) {
    291   uint32_t index = 0;
    292   // Maybe an array index, try to parse it.
    293   if (c0_ == '0') {
    294     // With a leading zero, the string has to be "0" only to be an index.
    295     Advance();
    296   } else {
    297     do {
    298       int d = c0_ - '0';
    299       if (index > 429496729U - ((d + 3) >> 3)) break;
    300       index = (index * 10) + d;
    301       Advance();
    302     } while (IsDecimalDigit(c0_));
    303   }
    304 
    305   if (c0_ == '"') {
    306     // Successfully parsed index, parse and store element.
    307     AdvanceSkipWhitespace();
    308 
    309     if (c0_ == ':') {
    310       AdvanceSkipWhitespace();
    311       Handle<Object> value = ParseJsonValue();
    312       if (!value.is_null()) {
    313         JSObject::SetOwnElementIgnoreAttributes(json_object, index, value, NONE)
    314             .Assert();
    315         return kElementFound;
    316       } else {
    317         return kNullHandle;
    318       }
    319     }
    320   }
    321   return kElementNotFound;
    322 }
    323 
    324 // Parse a JSON object. Position must be right at '{'.
    325 template <bool seq_one_byte>
    326 Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
    327   HandleScope scope(isolate());
    328   Handle<JSObject> json_object =
    329       factory()->NewJSObject(object_constructor(), pretenure_);
    330   Handle<Map> map(json_object->map());
    331   int descriptor = 0;
    332   ZoneList<Handle<Object> > properties(8, zone());
    333   DCHECK_EQ(c0_, '{');
    334 
    335   bool transitioning = true;
    336 
    337   AdvanceSkipWhitespace();
    338   if (c0_ != '}') {
    339     do {
    340       if (c0_ != '"') return ReportUnexpectedCharacter();
    341 
    342       int start_position = position_;
    343       Advance();
    344 
    345       if (IsDecimalDigit(c0_)) {
    346         ParseElementResult element_result = ParseElement(json_object);
    347         if (element_result == kNullHandle) return Handle<Object>::null();
    348         if (element_result == kElementFound) continue;
    349       }
    350       // Not an index, fallback to the slow path.
    351 
    352       position_ = start_position;
    353 #ifdef DEBUG
    354       c0_ = '"';
    355 #endif
    356 
    357       Handle<String> key;
    358       Handle<Object> value;
    359 
    360       // Try to follow existing transitions as long as possible. Once we stop
    361       // transitioning, no transition can be found anymore.
    362       DCHECK(transitioning);
    363       // First check whether there is a single expected transition. If so, try
    364       // to parse it first.
    365       bool follow_expected = false;
    366       Handle<Map> target;
    367       if (seq_one_byte) {
    368         key = TransitionArray::ExpectedTransitionKey(map);
    369         follow_expected = !key.is_null() && ParseJsonString(key);
    370       }
    371       // If the expected transition hits, follow it.
    372       if (follow_expected) {
    373         target = TransitionArray::ExpectedTransitionTarget(map);
    374       } else {
    375         // If the expected transition failed, parse an internalized string and
    376         // try to find a matching transition.
    377         key = ParseJsonInternalizedString();
    378         if (key.is_null()) return ReportUnexpectedCharacter();
    379 
    380         target = TransitionArray::FindTransitionToField(map, key);
    381         // If a transition was found, follow it and continue.
    382         transitioning = !target.is_null();
    383       }
    384       if (c0_ != ':') return ReportUnexpectedCharacter();
    385 
    386       AdvanceSkipWhitespace();
    387       value = ParseJsonValue();
    388       if (value.is_null()) return ReportUnexpectedCharacter();
    389 
    390       if (transitioning) {
    391         PropertyDetails details =
    392             target->instance_descriptors()->GetDetails(descriptor);
    393         Representation expected_representation = details.representation();
    394 
    395         if (value->FitsRepresentation(expected_representation)) {
    396           if (expected_representation.IsHeapObject() &&
    397               !target->instance_descriptors()
    398                    ->GetFieldType(descriptor)
    399                    ->NowContains(value)) {
    400             Handle<FieldType> value_type(
    401                 value->OptimalType(isolate(), expected_representation));
    402             Map::GeneralizeFieldType(target, descriptor,
    403                                      expected_representation, value_type);
    404           }
    405           DCHECK(target->instance_descriptors()
    406                      ->GetFieldType(descriptor)
    407                      ->NowContains(value));
    408           properties.Add(value, zone());
    409           map = target;
    410           descriptor++;
    411           continue;
    412         } else {
    413           transitioning = false;
    414         }
    415       }
    416 
    417       DCHECK(!transitioning);
    418 
    419       // Commit the intermediate state to the object and stop transitioning.
    420       CommitStateToJsonObject(json_object, map, &properties);
    421 
    422       JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key, value)
    423           .Check();
    424     } while (transitioning && MatchSkipWhiteSpace(','));
    425 
    426     // If we transitioned until the very end, transition the map now.
    427     if (transitioning) {
    428       CommitStateToJsonObject(json_object, map, &properties);
    429     } else {
    430       while (MatchSkipWhiteSpace(',')) {
    431         HandleScope local_scope(isolate());
    432         if (c0_ != '"') return ReportUnexpectedCharacter();
    433 
    434         int start_position = position_;
    435         Advance();
    436 
    437         if (IsDecimalDigit(c0_)) {
    438           ParseElementResult element_result = ParseElement(json_object);
    439           if (element_result == kNullHandle) return Handle<Object>::null();
    440           if (element_result == kElementFound) continue;
    441         }
    442         // Not an index, fallback to the slow path.
    443 
    444         position_ = start_position;
    445 #ifdef DEBUG
    446         c0_ = '"';
    447 #endif
    448 
    449         Handle<String> key;
    450         Handle<Object> value;
    451 
    452         key = ParseJsonInternalizedString();
    453         if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
    454 
    455         AdvanceSkipWhitespace();
    456         value = ParseJsonValue();
    457         if (value.is_null()) return ReportUnexpectedCharacter();
    458 
    459         JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key,
    460                                                           value)
    461             .Check();
    462       }
    463     }
    464 
    465     if (c0_ != '}') {
    466       return ReportUnexpectedCharacter();
    467     }
    468   }
    469   AdvanceSkipWhitespace();
    470   return scope.CloseAndEscape(json_object);
    471 }
    472 
    473 template <bool seq_one_byte>
    474 void JsonParser<seq_one_byte>::CommitStateToJsonObject(
    475     Handle<JSObject> json_object, Handle<Map> map,
    476     ZoneList<Handle<Object> >* properties) {
    477   JSObject::AllocateStorageForMap(json_object, map);
    478   DCHECK(!json_object->map()->is_dictionary_map());
    479 
    480   DisallowHeapAllocation no_gc;
    481 
    482   int length = properties->length();
    483   for (int i = 0; i < length; i++) {
    484     Handle<Object> value = (*properties)[i];
    485     json_object->WriteToField(i, *value);
    486   }
    487 }
    488 
    489 // Parse a JSON array. Position must be right at '['.
    490 template <bool seq_one_byte>
    491 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() {
    492   HandleScope scope(isolate());
    493   ZoneList<Handle<Object> > elements(4, zone());
    494   DCHECK_EQ(c0_, '[');
    495 
    496   AdvanceSkipWhitespace();
    497   if (c0_ != ']') {
    498     do {
    499       Handle<Object> element = ParseJsonValue();
    500       if (element.is_null()) return ReportUnexpectedCharacter();
    501       elements.Add(element, zone());
    502     } while (MatchSkipWhiteSpace(','));
    503     if (c0_ != ']') {
    504       return ReportUnexpectedCharacter();
    505     }
    506   }
    507   AdvanceSkipWhitespace();
    508   // Allocate a fixed array with all the elements.
    509   Handle<FixedArray> fast_elements =
    510       factory()->NewFixedArray(elements.length(), pretenure_);
    511   for (int i = 0, n = elements.length(); i < n; i++) {
    512     fast_elements->set(i, *elements[i]);
    513   }
    514   Handle<Object> json_array = factory()->NewJSArrayWithElements(
    515       fast_elements, FAST_ELEMENTS, pretenure_);
    516   return scope.CloseAndEscape(json_array);
    517 }
    518 
    519 template <bool seq_one_byte>
    520 Handle<Object> JsonParser<seq_one_byte>::ParseJsonNumber() {
    521   bool negative = false;
    522   int beg_pos = position_;
    523   if (c0_ == '-') {
    524     Advance();
    525     negative = true;
    526   }
    527   if (c0_ == '0') {
    528     Advance();
    529     // Prefix zero is only allowed if it's the only digit before
    530     // a decimal point or exponent.
    531     if (IsDecimalDigit(c0_)) return ReportUnexpectedCharacter();
    532   } else {
    533     int i = 0;
    534     int digits = 0;
    535     if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter();
    536     do {
    537       i = i * 10 + c0_ - '0';
    538       digits++;
    539       Advance();
    540     } while (IsDecimalDigit(c0_));
    541     if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
    542       SkipWhitespace();
    543       return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate());
    544     }
    545   }
    546   if (c0_ == '.') {
    547     Advance();
    548     if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter();
    549     do {
    550       Advance();
    551     } while (IsDecimalDigit(c0_));
    552   }
    553   if (AsciiAlphaToLower(c0_) == 'e') {
    554     Advance();
    555     if (c0_ == '-' || c0_ == '+') Advance();
    556     if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter();
    557     do {
    558       Advance();
    559     } while (IsDecimalDigit(c0_));
    560   }
    561   int length = position_ - beg_pos;
    562   double number;
    563   if (seq_one_byte) {
    564     Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length);
    565     number = StringToDouble(isolate()->unicode_cache(), chars,
    566                             NO_FLAGS,  // Hex, octal or trailing junk.
    567                             std::numeric_limits<double>::quiet_NaN());
    568   } else {
    569     Vector<uint8_t> buffer = Vector<uint8_t>::New(length);
    570     String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
    571     Vector<const uint8_t> result =
    572         Vector<const uint8_t>(buffer.start(), length);
    573     number = StringToDouble(isolate()->unicode_cache(), result,
    574                             NO_FLAGS,  // Hex, octal or trailing junk.
    575                             0.0);
    576     buffer.Dispose();
    577   }
    578   SkipWhitespace();
    579   return factory()->NewNumber(number, pretenure_);
    580 }
    581 
    582 template <typename StringType>
    583 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c);
    584 
    585 template <>
    586 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) {
    587   seq_str->SeqTwoByteStringSet(i, c);
    588 }
    589 
    590 template <>
    591 inline void SeqStringSet(Handle<SeqOneByteString> seq_str, int i, uc32 c) {
    592   seq_str->SeqOneByteStringSet(i, c);
    593 }
    594 
    595 template <typename StringType>
    596 inline Handle<StringType> NewRawString(Factory* factory, int length,
    597                                        PretenureFlag pretenure);
    598 
    599 template <>
    600 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length,
    601                                              PretenureFlag pretenure) {
    602   return factory->NewRawTwoByteString(length, pretenure).ToHandleChecked();
    603 }
    604 
    605 template <>
    606 inline Handle<SeqOneByteString> NewRawString(Factory* factory, int length,
    607                                              PretenureFlag pretenure) {
    608   return factory->NewRawOneByteString(length, pretenure).ToHandleChecked();
    609 }
    610 
    611 // Scans the rest of a JSON string starting from position_ and writes
    612 // prefix[start..end] along with the scanned characters into a
    613 // sequential string of type StringType.
    614 template <bool seq_one_byte>
    615 template <typename StringType, typename SinkChar>
    616 Handle<String> JsonParser<seq_one_byte>::SlowScanJsonString(
    617     Handle<String> prefix, int start, int end) {
    618   int count = end - start;
    619   int max_length = count + source_length_ - position_;
    620   int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
    621   Handle<StringType> seq_string =
    622       NewRawString<StringType>(factory(), length, pretenure_);
    623   // Copy prefix into seq_str.
    624   SinkChar* dest = seq_string->GetChars();
    625   String::WriteToFlat(*prefix, dest, start, end);
    626 
    627   while (c0_ != '"') {
    628     // Check for control character (0x00-0x1f) or unterminated string (<0).
    629     if (c0_ < 0x20) return Handle<String>::null();
    630     if (count >= length) {
    631       // We need to create a longer sequential string for the result.
    632       return SlowScanJsonString<StringType, SinkChar>(seq_string, 0, count);
    633     }
    634     if (c0_ != '\\') {
    635       // If the sink can contain UC16 characters, or source_ contains only
    636       // Latin1 characters, there's no need to test whether we can store the
    637       // character. Otherwise check whether the UC16 source character can fit
    638       // in the Latin1 sink.
    639       if (sizeof(SinkChar) == kUC16Size || seq_one_byte ||
    640           c0_ <= String::kMaxOneByteCharCode) {
    641         SeqStringSet(seq_string, count++, c0_);
    642         Advance();
    643       } else {
    644         // StringType is SeqOneByteString and we just read a non-Latin1 char.
    645         return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, count);
    646       }
    647     } else {
    648       Advance();  // Advance past the \.
    649       switch (c0_) {
    650         case '"':
    651         case '\\':
    652         case '/':
    653           SeqStringSet(seq_string, count++, c0_);
    654           break;
    655         case 'b':
    656           SeqStringSet(seq_string, count++, '\x08');
    657           break;
    658         case 'f':
    659           SeqStringSet(seq_string, count++, '\x0c');
    660           break;
    661         case 'n':
    662           SeqStringSet(seq_string, count++, '\x0a');
    663           break;
    664         case 'r':
    665           SeqStringSet(seq_string, count++, '\x0d');
    666           break;
    667         case 't':
    668           SeqStringSet(seq_string, count++, '\x09');
    669           break;
    670         case 'u': {
    671           uc32 value = 0;
    672           for (int i = 0; i < 4; i++) {
    673             Advance();
    674             int digit = HexValue(c0_);
    675             if (digit < 0) {
    676               return Handle<String>::null();
    677             }
    678             value = value * 16 + digit;
    679           }
    680           if (sizeof(SinkChar) == kUC16Size ||
    681               value <= String::kMaxOneByteCharCode) {
    682             SeqStringSet(seq_string, count++, value);
    683             break;
    684           } else {
    685             // StringType is SeqOneByteString and we just read a non-Latin1
    686             // char.
    687             position_ -= 6;  // Rewind position_ to \ in \uxxxx.
    688             Advance();
    689             return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0,
    690                                                               count);
    691           }
    692         }
    693         default:
    694           return Handle<String>::null();
    695       }
    696       Advance();
    697     }
    698   }
    699 
    700   DCHECK_EQ('"', c0_);
    701   // Advance past the last '"'.
    702   AdvanceSkipWhitespace();
    703 
    704   // Shrink seq_string length to count and return.
    705   return SeqString::Truncate(seq_string, count);
    706 }
    707 
    708 template <bool seq_one_byte>
    709 template <bool is_internalized>
    710 Handle<String> JsonParser<seq_one_byte>::ScanJsonString() {
    711   DCHECK_EQ('"', c0_);
    712   Advance();
    713   if (c0_ == '"') {
    714     AdvanceSkipWhitespace();
    715     return factory()->empty_string();
    716   }
    717 
    718   if (seq_one_byte && is_internalized) {
    719     // Fast path for existing internalized strings.  If the the string being
    720     // parsed is not a known internalized string, contains backslashes or
    721     // unexpectedly reaches the end of string, return with an empty handle.
    722     uint32_t running_hash = isolate()->heap()->HashSeed();
    723     int position = position_;
    724     uc32 c0 = c0_;
    725     do {
    726       if (c0 == '\\') {
    727         c0_ = c0;
    728         int beg_pos = position_;
    729         position_ = position;
    730         return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos,
    731                                                              position_);
    732       }
    733       if (c0 < 0x20) return Handle<String>::null();
    734       running_hash = StringHasher::AddCharacterCore(running_hash,
    735                                                     static_cast<uint16_t>(c0));
    736       position++;
    737       if (position >= source_length_) return Handle<String>::null();
    738       c0 = seq_source_->SeqOneByteStringGet(position);
    739     } while (c0 != '"');
    740     int length = position - position_;
    741     uint32_t hash = (length <= String::kMaxHashCalcLength)
    742                         ? StringHasher::GetHashCore(running_hash)
    743                         : static_cast<uint32_t>(length);
    744     Vector<const uint8_t> string_vector(seq_source_->GetChars() + position_,
    745                                         length);
    746     StringTable* string_table = isolate()->heap()->string_table();
    747     uint32_t capacity = string_table->Capacity();
    748     uint32_t entry = StringTable::FirstProbe(hash, capacity);
    749     uint32_t count = 1;
    750     Handle<String> result;
    751     while (true) {
    752       Object* element = string_table->KeyAt(entry);
    753       if (element->IsUndefined(isolate())) {
    754         // Lookup failure.
    755         result =
    756             factory()->InternalizeOneByteString(seq_source_, position_, length);
    757         break;
    758       }
    759       if (!element->IsTheHole(isolate()) &&
    760           String::cast(element)->IsOneByteEqualTo(string_vector)) {
    761         result = Handle<String>(String::cast(element), isolate());
    762 #ifdef DEBUG
    763         uint32_t hash_field =
    764             (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
    765         DCHECK_EQ(static_cast<int>(result->Hash()),
    766                   static_cast<int>(hash_field >> String::kHashShift));
    767 #endif
    768         break;
    769       }
    770       entry = StringTable::NextProbe(entry, count++, capacity);
    771     }
    772     position_ = position;
    773     // Advance past the last '"'.
    774     AdvanceSkipWhitespace();
    775     return result;
    776   }
    777 
    778   int beg_pos = position_;
    779   // Fast case for Latin1 only without escape characters.
    780   do {
    781     // Check for control character (0x00-0x1f) or unterminated string (<0).
    782     if (c0_ < 0x20) return Handle<String>::null();
    783     if (c0_ != '\\') {
    784       if (seq_one_byte || c0_ <= String::kMaxOneByteCharCode) {
    785         Advance();
    786       } else {
    787         return SlowScanJsonString<SeqTwoByteString, uc16>(source_, beg_pos,
    788                                                           position_);
    789       }
    790     } else {
    791       return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos,
    792                                                            position_);
    793     }
    794   } while (c0_ != '"');
    795   int length = position_ - beg_pos;
    796   Handle<String> result =
    797       factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked();
    798   uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
    799   String::WriteToFlat(*source_, dest, beg_pos, position_);
    800 
    801   DCHECK_EQ('"', c0_);
    802   // Advance past the last '"'.
    803   AdvanceSkipWhitespace();
    804   return result;
    805 }
    806 
    807 // Explicit instantiation.
    808 template class JsonParser<true>;
    809 template class JsonParser<false>;
    810 
    811 }  // namespace internal
    812 }  // namespace v8
    813