113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved.
213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Use of this source code is governed by a BSD-style license that can be
313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// found in the LICENSE file.
413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/json-parser.h"
613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/char-predicates-inl.h"
813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/conversions.h"
913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/debug/debug.h"
1013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/factory.h"
1113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/field-type.h"
1213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/messages.h"
1313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/objects-inl.h"
1413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/parsing/token.h"
1513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/property-descriptor.h"
1613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/transitions.h"
17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/unicode-cache.h"
1813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace v8 {
2013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace internal {
2113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2213e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMaybeHandle<Object> JsonParseInternalizer::Internalize(Isolate* isolate,
2313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                       Handle<Object> object,
2413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                       Handle<Object> reviver) {
2513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(reviver->IsCallable());
2613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  JsonParseInternalizer internalizer(isolate,
2713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                     Handle<JSReceiver>::cast(reviver));
2813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<JSObject> holder =
2913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate->factory()->NewJSObject(isolate->object_function());
3013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<String> name = isolate->factory()->empty_string();
3113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  JSObject::AddProperty(holder, name, object, NONE);
3213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return internalizer.InternalizeJsonProperty(holder, name);
3313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
3413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
3513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMaybeHandle<Object> JsonParseInternalizer::InternalizeJsonProperty(
3613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<JSReceiver> holder, Handle<String> name) {
3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  HandleScope outer_scope(isolate_);
3813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Object> value;
3913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(
4013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate_, value, Object::GetPropertyOrElement(holder, name), Object);
4113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (value->IsJSReceiver()) {
4213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
4313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Maybe<bool> is_array = Object::IsArray(object);
4413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (is_array.IsNothing()) return MaybeHandle<Object>();
4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (is_array.FromJust()) {
4613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<Object> length_object;
4713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSIGN_RETURN_ON_EXCEPTION(
4813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          isolate_, length_object,
4913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Object::GetLengthFromArrayLike(isolate_, object), Object);
5013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      double length = length_object->Number();
5113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      for (double i = 0; i < length; i++) {
5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        HandleScope inner_scope(isolate_);
5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Handle<Object> index = isolate_->factory()->NewNumber(i);
5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Handle<String> name = isolate_->factory()->NumberToString(index);
5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (!RecurseAndApply(object, name)) return MaybeHandle<Object>();
5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<FixedArray> contents;
5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSIGN_RETURN_ON_EXCEPTION(
6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          isolate_, contents,
6113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
6213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                  ENUMERABLE_STRINGS,
6313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                  GetKeysConversion::kConvertToString),
6413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          Object);
6513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      for (int i = 0; i < contents->length(); i++) {
6613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        HandleScope inner_scope(isolate_);
6713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Handle<String> name(String::cast(contents->get(i)), isolate_);
6813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (!RecurseAndApply(object, name)) return MaybeHandle<Object>();
6913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
7013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
7113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
7213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Object> argv[] = {name, value};
7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Object> result;
7413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(
7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate_, result, Execution::Call(isolate_, reviver_, holder, 2, argv),
7613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Object);
7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return outer_scope.CloseAndEscape(result);
7813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
7913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
8013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool JsonParseInternalizer::RecurseAndApply(Handle<JSReceiver> holder,
8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                            Handle<String> name) {
8213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Object> result;
8313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
8413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate_, result, InternalizeJsonProperty(holder, name), false);
8513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Maybe<bool> change_result = Nothing<bool>();
8613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (result->IsUndefined(isolate_)) {
8713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    change_result = JSReceiver::DeletePropertyOrElement(holder, name, SLOPPY);
8813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
8913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    PropertyDescriptor desc;
9013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    desc.set_value(result);
9113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    desc.set_configurable(true);
9213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    desc.set_enumerable(true);
9313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    desc.set_writable(true);
9413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    change_result = JSReceiver::DefineOwnProperty(isolate_, holder, name, &desc,
9513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                  Object::DONT_THROW);
9613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
9713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  MAYBE_RETURN(change_result, false);
9813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return true;
9913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
10013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
10113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
10213e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochJsonParser<seq_one_byte>::JsonParser(Isolate* isolate, Handle<String> source)
10313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    : source_(source),
10413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      source_length_(source->length()),
10513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate_(isolate),
10613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      factory_(isolate_->factory()),
107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      zone_(isolate_->allocator(), ZONE_NAME),
10813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      object_constructor_(isolate_->native_context()->object_function(),
10913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                          isolate_),
11013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      position_(-1) {
11113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  source_ = String::Flatten(source_);
11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED;
11313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
11413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Optimized fast case where we only have Latin1 characters.
11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (seq_one_byte) {
11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    seq_source_ = Handle<SeqOneByteString>::cast(source_);
11713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
11813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
12113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMaybeHandle<Object> JsonParser<seq_one_byte>::ParseJson() {
12213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Advance to the first character (possibly EOS)
12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Object> result = ParseJsonValue();
12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (result.is_null() || c0_ != kEndOfString) {
12613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Some exception (for example stack overflow) is already pending.
12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (isolate_->has_pending_exception()) return Handle<Object>::null();
12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Parse failed. Current character is the unexpected token.
13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Factory* factory = this->factory();
13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    MessageTemplate::Template message;
13213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<Object> arg1 = Handle<Smi>(Smi::FromInt(position_), isolate());
13313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<Object> arg2;
13413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    switch (c0_) {
13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case kEndOfString:
13713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        message = MessageTemplate::kJsonParseUnexpectedEOS;
13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        break;
13913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '-':
14013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '0':
14113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '1':
14213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '2':
14313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '3':
14413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '4':
14513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '5':
14613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '6':
14713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '7':
14813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '8':
14913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '9':
15013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        message = MessageTemplate::kJsonParseUnexpectedTokenNumber;
15113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        break;
15213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      case '"':
15313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        message = MessageTemplate::kJsonParseUnexpectedTokenString;
15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        break;
15513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      default:
15613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        message = MessageTemplate::kJsonParseUnexpectedToken;
15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        arg2 = arg1;
15813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        arg1 = factory->LookupSingleCharacterStringFromCode(c0_);
15913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        break;
16013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
16113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
16213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<Script> script(factory->NewScript(source_));
16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // We should sent compile error event because we compile JSON object in
16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // separated source file.
16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    isolate()->debug()->OnCompileError(script);
16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    MessageLocation location(script, position_, position_ + 1);
16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2);
16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return isolate()->template Throw<Object>(error, &location);
16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
17013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return result;
17113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
17213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
17313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMaybeHandle<Object> InternalizeJsonProperty(Handle<JSObject> holder,
17413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                            Handle<String> key);
17513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
17613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
17713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid JsonParser<seq_one_byte>::Advance() {
17813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  position_++;
17913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (position_ >= source_length_) {
18013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    c0_ = kEndOfString;
18113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else if (seq_one_byte) {
18213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    c0_ = seq_source_->SeqOneByteStringGet(position_);
18313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
18413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    c0_ = source_->Get(position_);
18513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
18613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
18713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
18813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
18913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid JsonParser<seq_one_byte>::AdvanceSkipWhitespace() {
19013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {
19113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
19213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r');
19313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
19413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
19513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid JsonParser<seq_one_byte>::SkipWhitespace() {
19713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r') {
19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
20113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
20213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
20313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochuc32 JsonParser<seq_one_byte>::AdvanceGetChar() {
20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Advance();
20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return c0_;
20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
20813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
20913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool JsonParser<seq_one_byte>::MatchSkipWhiteSpace(uc32 c) {
21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == c) {
21113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    AdvanceSkipWhitespace();
21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return true;
21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
21413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return false;
21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
21613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
21713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
21813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool JsonParser<seq_one_byte>::ParseJsonString(Handle<String> expected) {
21913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int length = expected->length();
22013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (source_->length() - position_ - 1 > length) {
22113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DisallowHeapAllocation no_gc;
22213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    String::FlatContent content = expected->GetFlatContent();
22313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (content.IsOneByte()) {
22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK_EQ('"', c0_);
22513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1;
22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      const uint8_t* expected_chars = content.ToOneByteVector().start();
22713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      for (int i = 0; i < length; i++) {
22813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        uint8_t c0 = input_chars[i];
22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (c0 != expected_chars[i] || c0 == '"' || c0 < 0x20 || c0 == '\\') {
23013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          return false;
23113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
23213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
23313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (input_chars[length] == '"') {
23413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        position_ = position_ + length + 1;
23513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        AdvanceSkipWhitespace();
23613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return true;
23713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
23813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
23913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return false;
24113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
24213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
24313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Parse any JSON value.
24413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
24513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochHandle<Object> JsonParser<seq_one_byte>::ParseJsonValue() {
24613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  StackLimitCheck stack_check(isolate_);
24713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (stack_check.HasOverflowed()) {
24813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    isolate_->StackOverflow();
24913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return Handle<Object>::null();
25013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
25113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
25213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (stack_check.InterruptRequested() &&
25313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      isolate_->stack_guard()->HandleInterrupts()->IsException(isolate_)) {
25413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return Handle<Object>::null();
25513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
25613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
25713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '"') return ParseJsonString();
25813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber();
25913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '{') return ParseJsonObject();
26013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '[') return ParseJsonArray();
26113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == 'f') {
26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' &&
26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') {
26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AdvanceSkipWhitespace();
26513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return factory()->false_value();
26613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return ReportUnexpectedCharacter();
26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
26913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == 't') {
27013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' &&
27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        AdvanceGetChar() == 'e') {
27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AdvanceSkipWhitespace();
27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return factory()->true_value();
27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return ReportUnexpectedCharacter();
27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == 'n') {
27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' &&
27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        AdvanceGetChar() == 'l') {
28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AdvanceSkipWhitespace();
28113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return factory()->null_value();
28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return ReportUnexpectedCharacter();
28413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
28513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return ReportUnexpectedCharacter();
28613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
28713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
28813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
28913e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochParseElementResult JsonParser<seq_one_byte>::ParseElement(
29013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<JSObject> json_object) {
29113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  uint32_t index = 0;
29213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Maybe an array index, try to parse it.
29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '0') {
29413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // With a leading zero, the string has to be "0" only to be an index.
29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
29613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
29813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      int d = c0_ - '0';
29913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (index > 429496729U - ((d + 3) >> 3)) break;
30013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      index = (index * 10) + d;
30113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();
30213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (IsDecimalDigit(c0_));
30313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
30413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
30513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '"') {
30613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Successfully parsed index, parse and store element.
30713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    AdvanceSkipWhitespace();
30813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
30913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ == ':') {
31013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AdvanceSkipWhitespace();
31113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<Object> value = ParseJsonValue();
31213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (!value.is_null()) {
31313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        JSObject::SetOwnElementIgnoreAttributes(json_object, index, value, NONE)
31413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            .Assert();
31513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return kElementFound;
31613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else {
31713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return kNullHandle;
31813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
31913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
32013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
32113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return kElementNotFound;
32213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
32313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
32413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Parse a JSON object. Position must be right at '{'.
32513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
32613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochHandle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
32713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  HandleScope scope(isolate());
32813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<JSObject> json_object =
32913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      factory()->NewJSObject(object_constructor(), pretenure_);
33013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Map> map(json_object->map());
33113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int descriptor = 0;
33213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ZoneList<Handle<Object> > properties(8, zone());
33313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ(c0_, '{');
33413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
33513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool transitioning = true;
33613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
33713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
33813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ != '}') {
33913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
34013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (c0_ != '"') return ReportUnexpectedCharacter();
34113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
34213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      int start_position = position_;
34313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();
34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
34513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (IsDecimalDigit(c0_)) {
34613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        ParseElementResult element_result = ParseElement(json_object);
34713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (element_result == kNullHandle) return Handle<Object>::null();
34813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (element_result == kElementFound) continue;
34913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
35013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Not an index, fallback to the slow path.
35113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
35213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      position_ = start_position;
35313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#ifdef DEBUG
35413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      c0_ = '"';
35513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif
35613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
35713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<String> key;
35813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<Object> value;
35913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
36013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Try to follow existing transitions as long as possible. Once we stop
36113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // transitioning, no transition can be found anymore.
36213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK(transitioning);
36313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // First check whether there is a single expected transition. If so, try
36413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // to parse it first.
36513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      bool follow_expected = false;
36613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<Map> target;
36713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (seq_one_byte) {
36813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        key = TransitionArray::ExpectedTransitionKey(map);
36913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        follow_expected = !key.is_null() && ParseJsonString(key);
37013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
37113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // If the expected transition hits, follow it.
37213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (follow_expected) {
37313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        target = TransitionArray::ExpectedTransitionTarget(map);
37413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else {
37513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        // If the expected transition failed, parse an internalized string and
37613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        // try to find a matching transition.
37713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        key = ParseJsonInternalizedString();
37813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (key.is_null()) return ReportUnexpectedCharacter();
37913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
38013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        target = TransitionArray::FindTransitionToField(map, key);
38113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        // If a transition was found, follow it and continue.
38213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        transitioning = !target.is_null();
38313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (c0_ != ':') return ReportUnexpectedCharacter();
38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AdvanceSkipWhitespace();
38713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      value = ParseJsonValue();
38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (value.is_null()) return ReportUnexpectedCharacter();
38913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
39013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (transitioning) {
39113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        PropertyDetails details =
39213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            target->instance_descriptors()->GetDetails(descriptor);
39313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Representation expected_representation = details.representation();
39413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
39513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (value->FitsRepresentation(expected_representation)) {
39613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (expected_representation.IsHeapObject() &&
39713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              !target->instance_descriptors()
39813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                   ->GetFieldType(descriptor)
39913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                   ->NowContains(value)) {
40013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            Handle<FieldType> value_type(
40113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                value->OptimalType(isolate(), expected_representation));
40213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            Map::GeneralizeFieldType(target, descriptor,
40313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                     expected_representation, value_type);
40413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          }
40513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          DCHECK(target->instance_descriptors()
40613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     ->GetFieldType(descriptor)
40713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     ->NowContains(value));
40813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          properties.Add(value, zone());
40913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          map = target;
41013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          descriptor++;
41113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          continue;
41213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        } else {
41313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          transitioning = false;
41413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
41713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK(!transitioning);
41813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
41913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Commit the intermediate state to the object and stop transitioning.
42013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CommitStateToJsonObject(json_object, map, &properties);
42113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
42213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key, value)
42313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          .Check();
42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (transitioning && MatchSkipWhiteSpace(','));
42513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
42613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // If we transitioned until the very end, transition the map now.
42713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (transitioning) {
42813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CommitStateToJsonObject(json_object, map, &properties);
42913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
43013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      while (MatchSkipWhiteSpace(',')) {
43113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        HandleScope local_scope(isolate());
43213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (c0_ != '"') return ReportUnexpectedCharacter();
43313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
43413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        int start_position = position_;
43513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Advance();
43613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
43713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (IsDecimalDigit(c0_)) {
43813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          ParseElementResult element_result = ParseElement(json_object);
43913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (element_result == kNullHandle) return Handle<Object>::null();
44013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (element_result == kElementFound) continue;
44113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
44213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        // Not an index, fallback to the slow path.
44313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
44413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        position_ = start_position;
44513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#ifdef DEBUG
44613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        c0_ = '"';
44713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif
44813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
44913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Handle<String> key;
45013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Handle<Object> value;
45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
45213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        key = ParseJsonInternalizedString();
45313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
45413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
45513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        AdvanceSkipWhitespace();
45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        value = ParseJsonValue();
45713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (value.is_null()) return ReportUnexpectedCharacter();
45813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
45913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key,
46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                          value)
46113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            .Check();
46213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
46313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
46413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
46513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ != '}') {
46613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return ReportUnexpectedCharacter();
46713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
46813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
46913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
47013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return scope.CloseAndEscape(json_object);
47113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
47313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
47413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid JsonParser<seq_one_byte>::CommitStateToJsonObject(
47513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<JSObject> json_object, Handle<Map> map,
47613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    ZoneList<Handle<Object> >* properties) {
47713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  JSObject::AllocateStorageForMap(json_object, map);
47813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(!json_object->map()->is_dictionary_map());
47913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
48013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DisallowHeapAllocation no_gc;
48113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
48213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int length = properties->length();
48313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (int i = 0; i < length; i++) {
48413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<Object> value = (*properties)[i];
48513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    json_object->WriteToField(i, *value);
48613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
48713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
48813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
48913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Parse a JSON array. Position must be right at '['.
49013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
49113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochHandle<Object> JsonParser<seq_one_byte>::ParseJsonArray() {
49213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  HandleScope scope(isolate());
49313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ZoneList<Handle<Object> > elements(4, zone());
49413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ(c0_, '[');
49513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
49613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
49713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ != ']') {
49813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
49913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Handle<Object> element = ParseJsonValue();
50013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (element.is_null()) return ReportUnexpectedCharacter();
50113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      elements.Add(element, zone());
50213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (MatchSkipWhiteSpace(','));
50313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ != ']') {
50413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return ReportUnexpectedCharacter();
50513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
50613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
50713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
50813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Allocate a fixed array with all the elements.
50913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<FixedArray> fast_elements =
51013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      factory()->NewFixedArray(elements.length(), pretenure_);
51113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (int i = 0, n = elements.length(); i < n; i++) {
51213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    fast_elements->set(i, *elements[i]);
51313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
51413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<Object> json_array = factory()->NewJSArrayWithElements(
51513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      fast_elements, FAST_ELEMENTS, pretenure_);
51613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return scope.CloseAndEscape(json_array);
51713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
51813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
51913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
52013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochHandle<Object> JsonParser<seq_one_byte>::ParseJsonNumber() {
52113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool negative = false;
52213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int beg_pos = position_;
52313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '-') {
52413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
52513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    negative = true;
52613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
52713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '0') {
52813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
52913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Prefix zero is only allowed if it's the only digit before
53013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // a decimal point or exponent.
53113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (IsDecimalDigit(c0_)) return ReportUnexpectedCharacter();
53213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
53313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int i = 0;
53413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int digits = 0;
53513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter();
53613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
53713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      i = i * 10 + c0_ - '0';
53813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      digits++;
53913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();
54013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (IsDecimalDigit(c0_));
54113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
54213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      SkipWhitespace();
54313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate());
54413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
54513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '.') {
54713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
54813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter();
54913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
55013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();
55113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (IsDecimalDigit(c0_));
55213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
55313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (AsciiAlphaToLower(c0_) == 'e') {
55413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Advance();
55513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ == '-' || c0_ == '+') Advance();
55613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter();
55713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
55813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();
55913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (IsDecimalDigit(c0_));
56013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
56113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int length = position_ - beg_pos;
56213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  double number;
56313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (seq_one_byte) {
56413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length);
56513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    number = StringToDouble(isolate()->unicode_cache(), chars,
56613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            NO_FLAGS,  // Hex, octal or trailing junk.
56713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            std::numeric_limits<double>::quiet_NaN());
56813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
56913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Vector<uint8_t> buffer = Vector<uint8_t>::New(length);
57013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
57113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Vector<const uint8_t> result =
57213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Vector<const uint8_t>(buffer.start(), length);
57313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    number = StringToDouble(isolate()->unicode_cache(), result,
57413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            NO_FLAGS,  // Hex, octal or trailing junk.
57513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            0.0);
57613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    buffer.Dispose();
57713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
57813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  SkipWhitespace();
57913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return factory()->NewNumber(number, pretenure_);
58013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
58113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
58213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <typename StringType>
58313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochinline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c);
58413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
58513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <>
58613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochinline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) {
58713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  seq_str->SeqTwoByteStringSet(i, c);
58813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
58913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
59013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <>
59113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochinline void SeqStringSet(Handle<SeqOneByteString> seq_str, int i, uc32 c) {
59213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  seq_str->SeqOneByteStringSet(i, c);
59313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
59413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
59513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <typename StringType>
59613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochinline Handle<StringType> NewRawString(Factory* factory, int length,
59713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                       PretenureFlag pretenure);
59813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
59913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <>
60013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochinline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length,
60113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                             PretenureFlag pretenure) {
60213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return factory->NewRawTwoByteString(length, pretenure).ToHandleChecked();
60313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
60413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
60513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <>
60613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochinline Handle<SeqOneByteString> NewRawString(Factory* factory, int length,
60713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                             PretenureFlag pretenure) {
60813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return factory->NewRawOneByteString(length, pretenure).ToHandleChecked();
60913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
61013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
61113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Scans the rest of a JSON string starting from position_ and writes
61213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// prefix[start..end] along with the scanned characters into a
61313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// sequential string of type StringType.
61413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
61513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <typename StringType, typename SinkChar>
61613e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochHandle<String> JsonParser<seq_one_byte>::SlowScanJsonString(
61713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<String> prefix, int start, int end) {
61813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int count = end - start;
61913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int max_length = count + source_length_ - position_;
62013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
62113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<StringType> seq_string =
62213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      NewRawString<StringType>(factory(), length, pretenure_);
62313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Copy prefix into seq_str.
62413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  SinkChar* dest = seq_string->GetChars();
62513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  String::WriteToFlat(*prefix, dest, start, end);
62613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
62713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while (c0_ != '"') {
62813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Check for control character (0x00-0x1f) or unterminated string (<0).
62913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ < 0x20) return Handle<String>::null();
63013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (count >= length) {
63113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // We need to create a longer sequential string for the result.
63213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return SlowScanJsonString<StringType, SinkChar>(seq_string, 0, count);
63313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
63413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ != '\\') {
63513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // If the sink can contain UC16 characters, or source_ contains only
63613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Latin1 characters, there's no need to test whether we can store the
63713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // character. Otherwise check whether the UC16 source character can fit
63813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // in the Latin1 sink.
63913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (sizeof(SinkChar) == kUC16Size || seq_one_byte ||
64013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          c0_ <= String::kMaxOneByteCharCode) {
64113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        SeqStringSet(seq_string, count++, c0_);
64213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Advance();
64313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else {
64413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        // StringType is SeqOneByteString and we just read a non-Latin1 char.
64513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, count);
64613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
64713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
64813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();  // Advance past the \.
64913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      switch (c0_) {
65013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case '"':
65113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case '\\':
65213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case '/':
65313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          SeqStringSet(seq_string, count++, c0_);
65413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          break;
65513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case 'b':
65613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          SeqStringSet(seq_string, count++, '\x08');
65713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          break;
65813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case 'f':
65913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          SeqStringSet(seq_string, count++, '\x0c');
66013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          break;
66113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case 'n':
66213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          SeqStringSet(seq_string, count++, '\x0a');
66313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          break;
66413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case 'r':
66513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          SeqStringSet(seq_string, count++, '\x0d');
66613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          break;
66713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case 't':
66813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          SeqStringSet(seq_string, count++, '\x09');
66913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          break;
67013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case 'u': {
67113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          uc32 value = 0;
67213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          for (int i = 0; i < 4; i++) {
67313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            Advance();
67413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            int digit = HexValue(c0_);
67513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            if (digit < 0) {
67613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              return Handle<String>::null();
67713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            }
67813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            value = value * 16 + digit;
67913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          }
68013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (sizeof(SinkChar) == kUC16Size ||
68113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              value <= String::kMaxOneByteCharCode) {
68213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            SeqStringSet(seq_string, count++, value);
68313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            break;
68413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          } else {
68513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            // StringType is SeqOneByteString and we just read a non-Latin1
68613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            // char.
68713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            position_ -= 6;  // Rewind position_ to \ in \uxxxx.
68813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            Advance();
68913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0,
69013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                              count);
69113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          }
69213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
69313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        default:
69413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          return Handle<String>::null();
69513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
69613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Advance();
69713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
69813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
69913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
70013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ('"', c0_);
70113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Advance past the last '"'.
70213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
70313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
70413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Shrink seq_string length to count and return.
70513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return SeqString::Truncate(seq_string, count);
70613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
70713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
70813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool seq_one_byte>
70913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <bool is_internalized>
71013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochHandle<String> JsonParser<seq_one_byte>::ScanJsonString() {
71113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ('"', c0_);
71213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Advance();
71313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (c0_ == '"') {
71413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    AdvanceSkipWhitespace();
71513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return factory()->empty_string();
71613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
71713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
71813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (seq_one_byte && is_internalized) {
71913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Fast path for existing internalized strings.  If the the string being
72013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // parsed is not a known internalized string, contains backslashes or
72113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // unexpectedly reaches the end of string, return with an empty handle.
72213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    uint32_t running_hash = isolate()->heap()->HashSeed();
72313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int position = position_;
72413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    uc32 c0 = c0_;
72513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    do {
72613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (c0 == '\\') {
72713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        c0_ = c0;
72813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        int beg_pos = position_;
72913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        position_ = position;
73013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos,
73113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                             position_);
73213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
73313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (c0 < 0x20) return Handle<String>::null();
73413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      running_hash = StringHasher::AddCharacterCore(running_hash,
73513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                    static_cast<uint16_t>(c0));
73613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      position++;
73713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (position >= source_length_) return Handle<String>::null();
73813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      c0 = seq_source_->SeqOneByteStringGet(position);
73913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } while (c0 != '"');
74013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int length = position - position_;
74113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    uint32_t hash = (length <= String::kMaxHashCalcLength)
74213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                        ? StringHasher::GetHashCore(running_hash)
74313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                        : static_cast<uint32_t>(length);
74413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Vector<const uint8_t> string_vector(seq_source_->GetChars() + position_,
74513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                        length);
74613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    StringTable* string_table = isolate()->heap()->string_table();
74713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    uint32_t capacity = string_table->Capacity();
74813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    uint32_t entry = StringTable::FirstProbe(hash, capacity);
74913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    uint32_t count = 1;
75013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Handle<String> result;
75113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    while (true) {
75213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Object* element = string_table->KeyAt(entry);
75313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (element->IsUndefined(isolate())) {
75413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        // Lookup failure.
75513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        result =
75613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            factory()->InternalizeOneByteString(seq_source_, position_, length);
75713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        break;
75813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
75913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (!element->IsTheHole(isolate()) &&
76013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          String::cast(element)->IsOneByteEqualTo(string_vector)) {
76113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        result = Handle<String>(String::cast(element), isolate());
76213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#ifdef DEBUG
76313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        uint32_t hash_field =
76413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            (hash << String::kHashShift) | String::kIsNotArrayIndexMask;
76513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        DCHECK_EQ(static_cast<int>(result->Hash()),
76613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                  static_cast<int>(hash_field >> String::kHashShift));
76713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif
76813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        break;
76913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
77013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      entry = StringTable::NextProbe(entry, count++, capacity);
77113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
77213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    position_ = position;
77313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Advance past the last '"'.
77413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    AdvanceSkipWhitespace();
77513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return result;
77613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
77713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
77813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int beg_pos = position_;
77913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Fast case for Latin1 only without escape characters.
78013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {
78113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Check for control character (0x00-0x1f) or unterminated string (<0).
78213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ < 0x20) return Handle<String>::null();
78313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (c0_ != '\\') {
78413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (seq_one_byte || c0_ <= String::kMaxOneByteCharCode) {
78513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Advance();
78613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else {
78713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return SlowScanJsonString<SeqTwoByteString, uc16>(source_, beg_pos,
78813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                          position_);
78913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
79013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
79113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos,
79213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                           position_);
79313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
79413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (c0_ != '"');
79513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int length = position_ - beg_pos;
79613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Handle<String> result =
79713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked();
79813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
79913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  String::WriteToFlat(*source_, dest, beg_pos, position_);
80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
80113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ('"', c0_);
80213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Advance past the last '"'.
80313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  AdvanceSkipWhitespace();
80413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return result;
80513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
80613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
80713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Explicit instantiation.
80813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate class JsonParser<true>;
80913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate class JsonParser<false>;
81013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
81113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}  // namespace internal
81213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}  // namespace v8
813