140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// Redistribution and use in source and binary forms, with or without 340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// modification, are permitted provided that the following conditions are 440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// met: 540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// 640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// * Redistributions of source code must retain the above copyright 740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// notice, this list of conditions and the following disclaimer. 840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// * Redistributions in binary form must reproduce the above 940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// copyright notice, this list of conditions and the following 1040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// disclaimer in the documentation and/or other materials provided 1140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// with the distribution. 1240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// * Neither the name of Google Inc. nor the names of its 1340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// contributors may be used to endorse or promote products derived 1440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// from this software without specific prior written permission. 1540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// 1640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 2840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#ifndef V8_JSON_PARSER_H_ 2940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#define V8_JSON_PARSER_H_ 3040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 31e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org#include "v8.h" 32e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 33e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org#include "char-predicates-inl.h" 34ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org#include "v8conversions.h" 35e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org#include "messages.h" 36e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org#include "spaces-inl.h" 3740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#include "token.h" 3840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 3940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgnamespace v8 { 4040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgnamespace internal { 4140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 4240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// A simple json parser. 43e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 4440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgclass JsonParser BASE_EMBEDDED { 4540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org public: 461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org static Handle<Object> Parse(Handle<String> source) { 471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return JsonParser(source).ParseJson(); 4840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 4940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 5040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static const int kEndOfString = -1; 5140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 5240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org private: 531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org explicit JsonParser(Handle<String> source) 541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org : source_(source), 551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org source_length_(source->length()), 561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org isolate_(source->map()->GetHeap()->isolate()), 571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org factory_(isolate_->factory()), 581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org zone_(isolate_), 591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org object_constructor_(isolate_->native_context()->object_function(), 601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org isolate_), 611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org position_(-1) { 621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org FlattenString(source_); 631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED; 641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Optimized fast case where we only have ASCII characters. 661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org if (seq_ascii) { 671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org seq_source_ = Handle<SeqOneByteString>::cast(source_); 681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 7140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Parse a string containing a single JSON value. 721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> ParseJson(); 7340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 7440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org inline void Advance() { 75d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com position_++; 763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (position_ >= source_length_) { 7740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org c0_ = kEndOfString; 78e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } else if (seq_ascii) { 79fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org c0_ = seq_source_->SeqOneByteStringGet(position_); 8040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } else { 8140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org c0_ = source_->Get(position_); 8240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 8340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 8440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 85d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // The JSON lexical grammar is specified in the ECMAScript 5 standard, 86d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // section 15.12.1.1. The only allowed whitespace characters between tokens 87d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // are tab, carriage-return, newline and space. 88d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 89d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com inline void AdvanceSkipWhitespace() { 90d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com do { 91d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Advance(); 9233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r'); 93d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 9440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 95d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com inline void SkipWhitespace() { 9633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org while (c0_ == ' ' || c0_ == '\t' || c0_ == '\n' || c0_ == '\r') { 97d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Advance(); 98d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 99d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 10040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 101d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com inline uc32 AdvanceGetChar() { 102d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Advance(); 103d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return c0_; 104d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 105d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 106d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // Checks that current charater is c. 107d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // If so, then consume c and skip whitespace. 108d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com inline bool MatchSkipWhiteSpace(uc32 c) { 109d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com if (c0_ == c) { 110d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com AdvanceSkipWhitespace(); 111d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return true; 112d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 113d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return false; 114d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 11540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 11640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // A JSON string (production JSONString) is subset of valid JavaScript string 11740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // literals. The string must only be double-quoted (not single-quoted), and 11840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and 11940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid. 120d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Handle<String> ParseJsonString() { 121d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return ScanJsonString<false>(); 122d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 123e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 124e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool ParseJsonString(Handle<String> expected) { 125e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int length = expected->length(); 126e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (source_->length() - position_ - 1 > length) { 12779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 128e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org String::FlatContent content = expected->GetFlatContent(); 129e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (content.IsAscii()) { 130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT_EQ('"', c0_); 131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1; 132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const uint8_t* expected_chars = content.ToOneByteVector().start(); 133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (int i = 0; i < length; i++) { 134e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint8_t c0 = input_chars[i]; 135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (c0 != expected_chars[i] || 136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org c0 == '"' || c0 < 0x20 || c0 == '\\') { 137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return false; 138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (input_chars[length] == '"') { 141e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org position_ = position_ + length + 1; 142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org AdvanceSkipWhitespace(); 143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 147e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return false; 148e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> ParseJsonInternalizedString() { 151d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return ScanJsonString<true>(); 152d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org template <bool is_internalized> 155d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Handle<String> ScanJsonString(); 1563cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Creates a new string and copies prefix[start..end] into the beginning 1573cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // of it. Then scans the rest of the string, adding characters after the 1583cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // prefix. Called by ScanJsonString when reaching a '\' or non-ASCII char. 1593cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org template <typename StringType, typename SinkChar> 1603cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end); 16140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 16240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // A JSON number (production JSONNumber) is a subset of the valid JavaScript 16340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // decimal number literals. 16440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // It includes an optional minus sign, must have at least one 16540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // digit before and after a decimal point, may not have prefixed zeros (unless 16640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // the integer part is zero), and may include an exponent part (e.g., "e-10"). 16740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Hexadecimal and octal numbers are not allowed. 168d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Handle<Object> ParseJsonNumber(); 16940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 17040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Parse a single JSON value from input (grammar production JSONValue). 17140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // A JSON value is either a (double-quoted) string literal, a number literal, 17240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // one of "true", "false", or "null", or an object or array literal. 17340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<Object> ParseJsonValue(); 17440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 17540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Parse a JSON object literal (grammar production JSONObject). 17640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // An object literal is a squiggly-braced and comma separated sequence 17740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // (possibly empty) of key/value pairs, where the key is a JSON string 17840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // literal, the value is a JSON value, and the two are separated by a colon. 1792efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // A JSON array doesn't allow numbers and identifiers as keys, like a 18040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // JavaScript array. 18140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<Object> ParseJsonObject(); 18240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 18340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Parses a JSON array literal (grammar production JSONArray). An array 18440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // literal is a square-bracketed and comma separated sequence (possibly empty) 18540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // of JSON values. 18640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // A JSON array doesn't allow leaving out values from the sequence, nor does 18740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // it allow a terminal comma, like a JavaScript array does. 18840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<Object> ParseJsonArray(); 18940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 19040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 19140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Mark that a parsing error has happened at the current token, and 19240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // return a null handle. Primarily for readability. 193d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com inline Handle<Object> ReportUnexpectedCharacter() { 194d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return Handle<Object>::null(); 195d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com } 196d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 197d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com inline Isolate* isolate() { return isolate_; } 19889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org inline Factory* factory() { return factory_; } 19989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org inline Handle<JSFunction> object_constructor() { return object_constructor_; } 20040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 2013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org static const int kInitialSpecialStringLength = 1024; 20272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org static const int kPretenureTreshold = 100 * 1024; 20340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 20440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 20540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org private: 2061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Zone* zone() { return &zone_; } 2071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 20840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Handle<String> source_; 20940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org int source_length_; 210fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Handle<SeqOneByteString> seq_source_; 21140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 21272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org PretenureFlag pretenure_; 21340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Isolate* isolate_; 21489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Factory* factory_; 2151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Zone zone_; 21689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Handle<JSFunction> object_constructor_; 21740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org uc32 c0_; 21840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org int position_; 21940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org}; 22040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 221e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 2221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgHandle<Object> JsonParser<seq_ascii>::ParseJson() { 2232efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Advance to the first character (possibly EOS) 224e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org AdvanceSkipWhitespace(); 225e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<Object> result = ParseJsonValue(); 226e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (result.is_null() || c0_ != kEndOfString) { 22772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Some exception (for example stack overflow) is already pending. 22872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (isolate_->has_pending_exception()) return Handle<Object>::null(); 229e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 23072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Parse failed. Current character is the unexpected token. 231e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org const char* message; 23289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Factory* factory = this->factory(); 233e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<JSArray> array; 234e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 235e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org switch (c0_) { 236e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case kEndOfString: 237e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org message = "unexpected_eos"; 238e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org array = factory->NewJSArray(0); 239e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 240e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '-': 241e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '0': 242e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '1': 243e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '2': 244e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '3': 245e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '4': 246e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '5': 247e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '6': 248e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '7': 249e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '8': 250e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '9': 251e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org message = "unexpected_token_number"; 252e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org array = factory->NewJSArray(0); 253e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 254e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '"': 255e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org message = "unexpected_token_string"; 256e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org array = factory->NewJSArray(0); 257e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 258e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org default: 259e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org message = "unexpected_token"; 26009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> name = 26109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org LookupSingleCharacterStringFromCode(isolate_, c0_); 262e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<FixedArray> element = factory->NewFixedArray(1); 263e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org element->set(0, *name); 264e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org array = factory->NewJSArrayWithElements(element); 265e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 266e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 267e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 2681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org MessageLocation location(factory->NewScript(source_), 269e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org position_, 270e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org position_ + 1); 271e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<Object> result = factory->NewSyntaxError(message, array); 272e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org isolate()->Throw(*result, &location); 273e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return Handle<Object>::null(); 274e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 275e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return result; 276e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 277e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 278e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 279e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// Parse any JSON value. 280e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 281e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgHandle<Object> JsonParser<seq_ascii>::ParseJsonValue() { 28272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org StackLimitCheck stack_check(isolate_); 28372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (stack_check.HasOverflowed()) { 28472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org isolate_->StackOverflow(); 28572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return Handle<Object>::null(); 28672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } 28772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 28889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0_ == '"') return ParseJsonString(); 28989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber(); 29089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0_ == '{') return ParseJsonObject(); 29189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0_ == '[') return ParseJsonArray(); 29289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0_ == 'f') { 29389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && 29489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { 29589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org AdvanceSkipWhitespace(); 29689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return factory()->false_value(); 29789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 29889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return ReportUnexpectedCharacter(); 29989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 30089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0_ == 't') { 30189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && 30289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org AdvanceGetChar() == 'e') { 30389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org AdvanceSkipWhitespace(); 30489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return factory()->true_value(); 30589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 30689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return ReportUnexpectedCharacter(); 30789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 30889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0_ == 'n') { 30989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && 31089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org AdvanceGetChar() == 'l') { 31189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org AdvanceSkipWhitespace(); 31289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return factory()->null_value(); 31389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org } 31489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return ReportUnexpectedCharacter(); 315e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 31689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return ReportUnexpectedCharacter(); 317e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 318e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 319e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 320e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// Parse a JSON object. Position must be right at '{'. 321e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 322e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgHandle<Object> JsonParser<seq_ascii>::ParseJsonObject() { 323f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org HandleScope scope(isolate()); 324e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<JSObject> json_object = 32572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org factory()->NewJSObject(object_constructor(), pretenure_); 326e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<Map> map(json_object->map()); 327e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ZoneList<Handle<Object> > properties(8, zone()); 328e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ASSERT_EQ(c0_, '{'); 329e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 330e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool transitioning = true; 331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 332e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org AdvanceSkipWhitespace(); 333e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != '}') { 334e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org do { 335e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != '"') return ReportUnexpectedCharacter(); 336e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 33789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org int start_position = position_; 33889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Advance(); 33989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 34089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org uint32_t index = 0; 34172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (c0_ >= '0' && c0_ <= '9') { 34272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Maybe an array index, try to parse it. 34372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (c0_ == '0') { 34472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // With a leading zero, the string has to be "0" only to be an index. 34572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org Advance(); 34672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } else { 34772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org do { 34872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org int d = c0_ - '0'; 34972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (index > 429496729U - ((d > 5) ? 1 : 0)) break; 35072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org index = (index * 10) + d; 35172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org Advance(); 35272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } while (c0_ >= '0' && c0_ <= '9'); 35372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } 35489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 35572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (c0_ == '"') { 35672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Successfully parsed index, parse and store element. 35772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org AdvanceSkipWhitespace(); 35889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 35972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (c0_ != ':') return ReportUnexpectedCharacter(); 36072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org AdvanceSkipWhitespace(); 36172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org Handle<Object> value = ParseJsonValue(); 36272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (value.is_null()) return ReportUnexpectedCharacter(); 36389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 36472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org JSObject::SetOwnElement(json_object, index, value, kNonStrictMode); 36572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org continue; 36672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } 36772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Not an index, fallback to the slow path. 36872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } 36972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 37072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org position_ = start_position; 37189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#ifdef DEBUG 37272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org c0_ = '"'; 37389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org#endif 37489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 375e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<String> key; 376e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<Object> value; 377e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 378e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Try to follow existing transitions as long as possible. Once we stop 379e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // transitioning, no transition can be found anymore. 380e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (transitioning) { 381e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // First check whether there is a single expected transition. If so, try 382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // to parse it first. 383e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool follow_expected = false; 38457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Map> target; 385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (seq_ascii) { 386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org key = JSObject::ExpectedTransitionKey(map); 387e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org follow_expected = !key.is_null() && ParseJsonString(key); 388e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 389e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If the expected transition hits, follow it. 390e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (follow_expected) { 39157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org target = JSObject::ExpectedTransitionTarget(map); 392e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 393e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If the expected transition failed, parse an internalized string and 394e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // try to find a matching transition. 395e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org key = ParseJsonInternalizedString(); 396e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (key.is_null()) return ReportUnexpectedCharacter(); 397e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 39857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org target = JSObject::FindTransitionToField(map, key); 399e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If a transition was found, follow it and continue. 40057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org transitioning = !target.is_null(); 401e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 402e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (c0_ != ':') return ReportUnexpectedCharacter(); 40389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 404e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org AdvanceSkipWhitespace(); 405e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org value = ParseJsonValue(); 406e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (value.is_null()) return ReportUnexpectedCharacter(); 40789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 408f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (transitioning) { 40957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int descriptor = map->NumberOfOwnDescriptors(); 41057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org PropertyDetails details = 41157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org target->instance_descriptors()->GetDetails(descriptor); 41257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Representation expected_representation = details.representation(); 41357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 41457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (value->FitsRepresentation(expected_representation)) { 41557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // If the target representation is double and the value is already 41657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // double, use the existing box. 41757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields && 41857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org value->IsSmi() && 41957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org expected_representation.IsDouble()) { 42057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org value = factory()->NewHeapNumber( 42157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Smi>::cast(value)->value()); 42257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 42357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org properties.Add(value, zone()); 42457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org map = target; 42557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org continue; 42657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 42757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org transitioning = false; 428f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 42957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 43057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 43157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Commit the intermediate state to the object and stop transitioning. 43257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org JSObject::AllocateStorageForMap(json_object, map); 43357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int length = properties.length(); 43457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org for (int i = 0; i < length; i++) { 43557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> value = properties[i]; 43657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org json_object->FastPropertyAtPut(i, *value); 437f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 43872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org } else { 439e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org key = ParseJsonInternalizedString(); 440e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); 441e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 442e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org AdvanceSkipWhitespace(); 443e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org value = ParseJsonValue(); 444e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (value.is_null()) return ReportUnexpectedCharacter(); 445e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 446e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 447e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org JSObject::SetLocalPropertyIgnoreAttributes( 448e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org json_object, key, value, NONE); 449e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } while (MatchSkipWhiteSpace(',')); 450e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != '}') { 451e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return ReportUnexpectedCharacter(); 452e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 453e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 454e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If we transitioned until the very end, transition the map now. 455e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (transitioning) { 45657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org JSObject::AllocateStorageForMap(json_object, map); 457e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int length = properties.length(); 458e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (int i = 0; i < length; i++) { 459f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Handle<Object> value = properties[i]; 460f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org json_object->FastPropertyAtPut(i, *value); 461e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 462e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 463e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 464e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org AdvanceSkipWhitespace(); 465f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return scope.CloseAndEscape(json_object); 466e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 467e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 468e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org// Parse a JSON array. Position must be right at '['. 469e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 470e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgHandle<Object> JsonParser<seq_ascii>::ParseJsonArray() { 471f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org HandleScope scope(isolate()); 4727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org ZoneList<Handle<Object> > elements(4, zone()); 473e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ASSERT_EQ(c0_, '['); 474e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 475e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org AdvanceSkipWhitespace(); 476e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != ']') { 477e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org do { 478e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<Object> element = ParseJsonValue(); 479e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (element.is_null()) return ReportUnexpectedCharacter(); 4807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org elements.Add(element, zone()); 481e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } while (MatchSkipWhiteSpace(',')); 482e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != ']') { 483e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return ReportUnexpectedCharacter(); 484e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 485e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 486e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org AdvanceSkipWhitespace(); 487e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // Allocate a fixed array with all the elements. 488e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Handle<FixedArray> fast_elements = 48972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org factory()->NewFixedArray(elements.length(), pretenure_); 490e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org for (int i = 0, n = elements.length(); i < n; i++) { 491e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org fast_elements->set(i, *elements[i]); 492e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 493f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Handle<Object> json_array = factory()->NewJSArrayWithElements( 49472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org fast_elements, FAST_ELEMENTS, pretenure_); 495f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return scope.CloseAndEscape(json_array); 496e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 497e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 498e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 499e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 500e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgHandle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { 501e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org bool negative = false; 50204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org int beg_pos = position_; 503e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ == '-') { 504e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 505e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org negative = true; 506e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 507e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ == '0') { 508e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 509e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // Prefix zero is only allowed if it's the only digit before 510e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // a decimal point or exponent. 511e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter(); 512e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } else { 513e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org int i = 0; 514e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org int digits = 0; 515e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter(); 516e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org do { 517e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org i = i * 10 + c0_ - '0'; 518e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org digits++; 519e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 520e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } while (c0_ >= '0' && c0_ <= '9'); 521e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { 522e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org SkipWhitespace(); 52304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate()); 524e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 525e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 526e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ == '.') { 527e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 528e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); 529e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org do { 530e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 531e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } while (c0_ >= '0' && c0_ <= '9'); 532e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 533e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (AsciiAlphaToLower(c0_) == 'e') { 534e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 535e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ == '-' || c0_ == '+') Advance(); 536e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); 537e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org do { 538e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 539e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } while (c0_ >= '0' && c0_ <= '9'); 540e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 54104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org int length = position_ - beg_pos; 54204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org double number; 543e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (seq_ascii) { 54459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length); 54504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org number = StringToDouble(isolate()->unicode_cache(), 54659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const char>::cast(chars), 547e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org NO_FLAGS, // Hex, octal or trailing junk. 548e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org OS::nan_value()); 549e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } else { 55059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<uint8_t> buffer = Vector<uint8_t>::New(length); 55104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org String::WriteToFlat(*source_, buffer.start(), beg_pos, position_); 55259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const uint8_t> result = 55359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const uint8_t>(buffer.start(), length); 55404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org number = StringToDouble(isolate()->unicode_cache(), 55559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // TODO(dcarney): Convert StringToDouble to uint_t. 55659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const char>::cast(result), 55759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org NO_FLAGS, // Hex, octal or trailing junk. 55859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 0.0); 559e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org buffer.Dispose(); 560e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 561e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org SkipWhitespace(); 56272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return factory()->NewNumber(number, pretenure_); 563e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 564e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 5653cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5663cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <typename StringType> 5673cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orginline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); 5683cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5693cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <> 5703cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orginline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { 5713cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org seq_str->SeqTwoByteStringSet(i, c); 5723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5743cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <> 575fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orginline void SeqStringSet(Handle<SeqOneByteString> seq_str, int i, uc32 c) { 576fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org seq_str->SeqOneByteStringSet(i, c); 5773cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <typename StringType> 58072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orginline Handle<StringType> NewRawString(Factory* factory, 58172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org int length, 58272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org PretenureFlag pretenure); 5833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <> 58572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orginline Handle<SeqTwoByteString> NewRawString(Factory* factory, 58672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org int length, 58772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org PretenureFlag pretenure) { 58872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return factory->NewRawTwoByteString(length, pretenure); 5893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <> 592fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orginline Handle<SeqOneByteString> NewRawString(Factory* factory, 59372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org int length, 59472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org PretenureFlag pretenure) { 595fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return factory->NewRawOneByteString(length, pretenure); 5963cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org} 5973cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5983cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 5993cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org// Scans the rest of a JSON string starting from position_ and writes 6003cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org// prefix[start..end] along with the scanned characters into a 6013cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org// sequential string of type StringType. 602e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 6033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgtemplate <typename StringType, typename SinkChar> 6043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.orgHandle<String> JsonParser<seq_ascii>::SlowScanJsonString( 6053cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Handle<String> prefix, int start, int end) { 6063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int count = end - start; 6073cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int max_length = count + source_length_ - position_; 6083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); 609f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Handle<StringType> seq_string = 61072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org NewRawString<StringType>(factory(), length, pretenure_); 6113cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Copy prefix into seq_str. 612f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SinkChar* dest = seq_string->GetChars(); 6133cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org String::WriteToFlat(*prefix, dest, start, end); 614e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 615e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org while (c0_ != '"') { 6167c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org // Check for control character (0x00-0x1f) or unterminated string (<0). 6177c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org if (c0_ < 0x20) return Handle<String>::null(); 6183cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (count >= length) { 6193cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // We need to create a longer sequential string for the result. 620f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return SlowScanJsonString<StringType, SinkChar>(seq_string, 0, count); 621e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 622e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ != '\\') { 6233cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // If the sink can contain UC16 characters, or source_ contains only 6243cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // ASCII characters, there's no need to test whether we can store the 6253cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // character. Otherwise check whether the UC16 source character can fit 6263cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // in the ASCII sink. 6273cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (sizeof(SinkChar) == kUC16Size || 6283cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org seq_ascii || 62959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org c0_ <= String::kMaxOneByteCharCode) { 630f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, c0_); 6313cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Advance(); 6323cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 633fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // StringType is SeqOneByteString and we just read a non-ASCII char. 634f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, count); 6353cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 636e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } else { 6373cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Advance(); // Advance past the \. 638e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org switch (c0_) { 639e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '"': 640e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '\\': 641e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case '/': 642f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, c0_); 643e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 644e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case 'b': 645f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, '\x08'); 646e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 647e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case 'f': 648f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, '\x0c'); 649e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 650e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case 'n': 651f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, '\x0a'); 652e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 653e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case 'r': 654f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, '\x0d'); 655e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 656e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case 't': 657f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, '\x09'); 658e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org break; 659e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org case 'u': { 660e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org uc32 value = 0; 661e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org for (int i = 0; i < 4; i++) { 662e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 663e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org int digit = HexValue(c0_); 664e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (digit < 0) { 665e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return Handle<String>::null(); 666e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 667e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org value = value * 16 + digit; 668e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 66959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (sizeof(SinkChar) == kUC16Size || 67059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org value <= String::kMaxOneByteCharCode) { 671f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org SeqStringSet(seq_string, count++, value); 6723cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org break; 6733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 674fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // StringType is SeqOneByteString and we just read a non-ASCII char. 6753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org position_ -= 6; // Rewind position_ to \ in \uxxxx. 6763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Advance(); 677f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 6783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 0, 6793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org count); 6803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 681e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 682e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org default: 683e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org return Handle<String>::null(); 684e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 685e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 686e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 687e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 688f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 6893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org ASSERT_EQ('"', c0_); 6903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Advance past the last '"'. 6913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org AdvanceSkipWhitespace(); 692f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 693f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Shrink seq_string length to count and return. 694f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return SeqString::Truncate(seq_string, count); 695e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 696e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 6973cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org 698e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgtemplate <bool seq_ascii> 6994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgtemplate <bool is_internalized> 700e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.orgHandle<String> JsonParser<seq_ascii>::ScanJsonString() { 701e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ASSERT_EQ('"', c0_); 702e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org Advance(); 7033cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (c0_ == '"') { 7043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org AdvanceSkipWhitespace(); 705e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org return factory()->empty_string(); 7063cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 70733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 7084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (seq_ascii && is_internalized) { 7094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Fast path for existing internalized strings. If the the string being 7104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // parsed is not a known internalized string, contains backslashes or 7114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // unexpectedly reaches the end of string, return with an empty handle. 71233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org uint32_t running_hash = isolate()->heap()->HashSeed(); 71333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int position = position_; 71433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org uc32 c0 = c0_; 71533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org do { 71633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (c0 == '\\') { 71789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org c0_ = c0; 71889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org int beg_pos = position_; 71989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org position_ = position; 72059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, 721f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org beg_pos, 722f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org position_); 72333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 72489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org if (c0 < 0x20) return Handle<String>::null(); 725a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (static_cast<uint32_t>(c0) > 726a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org unibrow::Utf16::kMaxNonSurrogateCharCode) { 727a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org running_hash = 728a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org StringHasher::AddCharacterCore(running_hash, 729a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org unibrow::Utf16::LeadSurrogate(c0)); 730a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org running_hash = 731a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org StringHasher::AddCharacterCore(running_hash, 732a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org unibrow::Utf16::TrailSurrogate(c0)); 733a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 734a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org running_hash = StringHasher::AddCharacterCore(running_hash, c0); 735a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 73633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org position++; 73733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (position >= source_length_) return Handle<String>::null(); 738fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org c0 = seq_source_->SeqOneByteStringGet(position); 73933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } while (c0 != '"'); 74033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int length = position - position_; 74133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org uint32_t hash = (length <= String::kMaxHashCalcLength) 74233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ? StringHasher::GetHashCore(running_hash) : length; 74359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Vector<const uint8_t> string_vector( 74433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org seq_source_->GetChars() + position_, length); 7454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org StringTable* string_table = isolate()->heap()->string_table(); 7464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org uint32_t capacity = string_table->Capacity(); 7474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org uint32_t entry = StringTable::FirstProbe(hash, capacity); 74833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org uint32_t count = 1; 749e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<String> result; 75033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org while (true) { 7514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Object* element = string_table->KeyAt(entry); 75272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (element == isolate()->heap()->undefined_value()) { 75333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Lookup failure. 754e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = factory()->InternalizeOneByteString( 755e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org seq_source_, position_, length); 75633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org break; 75733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 75872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org if (element != isolate()->heap()->the_hole_value() && 75959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org String::cast(element)->IsOneByteEqualTo(string_vector)) { 760e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org result = Handle<String>(String::cast(element), isolate()); 761e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef DEBUG 762e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t hash_field = 763e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (hash << String::kHashShift) | String::kIsNotArrayIndexMask; 764e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT_EQ(static_cast<int>(result->Hash()), 765e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static_cast<int>(hash_field >> String::kHashShift)); 766e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif 767e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org break; 76833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 7694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org entry = StringTable::NextProbe(entry, count++, capacity); 77033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 771e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org position_ = position; 772e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Advance past the last '"'. 773e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org AdvanceSkipWhitespace(); 774e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return result; 77533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 77633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 77704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org int beg_pos = position_; 7783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org // Fast case for ASCII only without escape characters. 7793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org do { 780e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // Check for control character (0x00-0x1f) or unterminated string (<0). 781e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org if (c0_ < 0x20) return Handle<String>::null(); 7823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org if (c0_ != '\\') { 78359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if (seq_ascii || c0_ <= String::kMaxOneByteCharCode) { 7843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Advance(); 7853cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } else { 7863cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return SlowScanJsonString<SeqTwoByteString, uc16>(source_, 7873cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org beg_pos, 7883cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org position_); 7893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } 790e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } else { 79159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, 79259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org beg_pos, 79359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org position_); 794e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org } 7953cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org } while (c0_ != '"'); 7963cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org int length = position_ - beg_pos; 797e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Handle<String> result = factory()->NewRawOneByteString(length, pretenure_); 798e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint8_t* dest = SeqOneByteString::cast(*result)->GetChars(); 799e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org String::WriteToFlat(*source_, dest, beg_pos, position_); 800e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 801e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org ASSERT_EQ('"', c0_); 802e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // Advance past the last '"'. 803e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org AdvanceSkipWhitespace(); 8043cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org return result; 805e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org} 806e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org 80740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} } // namespace v8::internal 80840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 80940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#endif // V8_JSON_PARSER_H_ 810