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