1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Redistribution and use in source and binary forms, with or without 3257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// modification, are permitted provided that the following conditions are 4257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// met: 5257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// 6257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// * Redistributions of source code must retain the above copyright 7257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// notice, this list of conditions and the following disclaimer. 8257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// * Redistributions in binary form must reproduce the above 9257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// copyright notice, this list of conditions and the following 10257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// disclaimer in the documentation and/or other materials provided 11257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// with the distribution. 12257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// contributors may be used to endorse or promote products derived 14257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// from this software without specific prior written permission. 15257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// 16257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 28257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifndef V8_JSON_PARSER_H_ 29257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#define V8_JSON_PARSER_H_ 30257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "v8.h" 323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "char-predicates-inl.h" 343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "v8conversions.h" 353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "messages.h" 363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "spaces-inl.h" 37257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "token.h" 38257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 39257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochnamespace v8 { 40257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochnamespace internal { 41257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// A simple json parser. 433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 44257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass JsonParser BASE_EMBEDDED { 45257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 46257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static Handle<Object> Parse(Handle<String> source) { 47257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return JsonParser().ParseJson(source); 48257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kEndOfString = -1; 51257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 52257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Parse a string containing a single JSON value. 54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> ParseJson(Handle<String> source); 55257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 56257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch inline void Advance() { 573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_++; 58257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (position_ >= source_length_) { 59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch c0_ = kEndOfString; 603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (seq_ascii) { 61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch c0_ = seq_source_->SeqAsciiStringGet(position_); 62257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 63257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch c0_ = source_->Get(position_); 64257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The JSON lexical grammar is specified in the ECMAScript 5 standard, 683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // section 15.12.1.1. The only allowed whitespace characters between tokens 693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // are tab, carriage-return, newline and space. 70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline void AdvanceSkipWhitespace() { 723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' '); 753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 76257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline void SkipWhitespace() { 783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' ') { 793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline uc32 AdvanceGetChar() { 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return c0_; 863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Checks that current charater is c. 893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If so, then consume c and skip whitespace. 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline bool MatchSkipWhiteSpace(uc32 c) { 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ == c) { 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // A JSON string (production JSONString) is subset of valid JavaScript string 99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // literals. The string must only be double-quoted (not single-quoted), and 100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid. 1023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> ParseJsonString() { 1033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ScanJsonString<false>(); 1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> ParseJsonSymbol() { 1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ScanJsonString<true>(); 1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch template <bool is_symbol> 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> ScanJsonString(); 1103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Creates a new string and copies prefix[start..end] into the beginning 1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // of it. Then scans the rest of the string, adding characters after the 1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // prefix. Called by ScanJsonString when reaching a '\' or non-ASCII char. 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch template <typename StringType, typename SinkChar> 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end); 115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // A JSON number (production JSONNumber) is a subset of the valid JavaScript 117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // decimal number literals. 118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // It includes an optional minus sign, must have at least one 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // digit before and after a decimal point, may not have prefixed zeros (unless 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the integer part is zero), and may include an exponent part (e.g., "e-10"). 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Hexadecimal and octal numbers are not allowed. 1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> ParseJsonNumber(); 123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Parse a single JSON value from input (grammar production JSONValue). 125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // A JSON value is either a (double-quoted) string literal, a number literal, 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // one of "true", "false", or "null", or an object or array literal. 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> ParseJsonValue(); 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Parse a JSON object literal (grammar production JSONObject). 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // An object literal is a squiggly-braced and comma separated sequence 131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // (possibly empty) of key/value pairs, where the key is a JSON string 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // literal, the value is a JSON value, and the two are separated by a colon. 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // A JSON array doesn't allow numbers and identifiers as keys, like a 134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // JavaScript array. 135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> ParseJsonObject(); 136257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Parses a JSON array literal (grammar production JSONArray). An array 138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // literal is a square-bracketed and comma separated sequence (possibly empty) 139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // of JSON values. 140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // A JSON array doesn't allow leaving out values from the sequence, nor does 141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // it allow a terminal comma, like a JavaScript array does. 142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> ParseJsonArray(); 143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Mark that a parsing error has happened at the current token, and 146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // return a null handle. Primarily for readability. 1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline Handle<Object> ReportUnexpectedCharacter() { 1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Handle<Object>::null(); 1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch inline Isolate* isolate() { return isolate_; } 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kInitialSpecialStringLength = 1024; 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<String> source_; 158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int source_length_; 159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<SeqAsciiString> seq_source_; 160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate* isolate_; 162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uc32 c0_; 163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int position_; 1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source) { 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_ = source->map()->GetHeap()->isolate(); 16969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FlattenString(source); 17069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch source_ = source; 1713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch source_length_ = source_->length(); 172257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Optimized fast case where we only have ASCII characters. 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (seq_ascii) { 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch seq_source_ = Handle<SeqAsciiString>::cast(source_); 1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set initial position right before the string. 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_ = -1; 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Advance to the first character (possibly EOS) 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> result = ParseJsonValue(); 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (result.is_null() || c0_ != kEndOfString) { 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Parse failed. Current character is the unexpected token. 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* message; 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Factory* factory = isolate()->factory(); 1883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<JSArray> array; 1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (c0_) { 1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case kEndOfString: 1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch message = "unexpected_eos"; 1933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch array = factory->NewJSArray(0); 1943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '-': 1963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '0': 1973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '1': 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '2': 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '3': 2003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '4': 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '5': 2023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '6': 2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '7': 2043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '8': 2053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '9': 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch message = "unexpected_token_number"; 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch array = factory->NewJSArray(0); 2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '"': 2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch message = "unexpected_token_string"; 2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch array = factory->NewJSArray(0); 2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch message = "unexpected_token"; 2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> name = LookupSingleCharacterStringFromCode(c0_); 2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<FixedArray> element = factory->NewFixedArray(1); 2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch element->set(0, *name); 2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch array = factory->NewJSArrayWithElements(element); 2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MessageLocation location(factory->NewScript(source), 2233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_, 2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_ + 1); 2253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> result = factory->NewSyntaxError(message, array); 2263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->Throw(*result, &location); 2273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Handle<Object>::null(); 2283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return result; 2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 2313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Parse any JSON value. 2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 2353fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Object> JsonParser<seq_ascii>::ParseJsonValue() { 2363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (c0_) { 2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '"': 2383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ParseJsonString(); 2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '-': 2403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '0': 2413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '1': 2423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '2': 2433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '3': 2443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '4': 2453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '5': 2463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '6': 2473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '7': 2483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '8': 2493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '9': 2503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ParseJsonNumber(); 2513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'f': 2523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && 2533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { 2543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 2553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->factory()->false_value(); 2563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 2573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportUnexpectedCharacter(); 2583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 't': 2603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && 2613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceGetChar() == 'e') { 2623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 2633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->factory()->true_value(); 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportUnexpectedCharacter(); 2663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'n': 2683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && 2693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceGetChar() == 'l') { 2703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->factory()->null_value(); 2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportUnexpectedCharacter(); 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '{': 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ParseJsonObject(); 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '[': 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ParseJsonArray(); 2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportUnexpectedCharacter(); 2813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 2833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Parse a JSON object. Position must be right at '{'. 2863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 2873fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Object> JsonParser<seq_ascii>::ParseJsonObject() { 2883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<JSFunction> object_constructor( 2893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->global_context()->object_function()); 2903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<JSObject> json_object = 2913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->factory()->NewJSObject(object_constructor); 2923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ(c0_, '{'); 2933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 2953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != '}') { 2963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 2973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != '"') return ReportUnexpectedCharacter(); 2983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> key = ParseJsonSymbol(); 2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); 3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 3013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> value = ParseJsonValue(); 3023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (value.is_null()) return ReportUnexpectedCharacter(); 3033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t index; 3053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (key->AsArrayIndex(&index)) { 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::SetOwnElement(json_object, index, value, kNonStrictMode); 3073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (key->Equals(isolate()->heap()->Proto_symbol())) { 3083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SetPrototype(json_object, value); 3093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::SetLocalPropertyIgnoreAttributes( 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch json_object, key, value, NONE); 3123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (MatchSkipWhiteSpace(',')); 3143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != '}') { 3153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportUnexpectedCharacter(); 3163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 3193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return json_object; 3203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 3213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Parse a JSON array. Position must be right at '['. 3233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Object> JsonParser<seq_ascii>::ParseJsonArray() { 3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneScope zone_scope(isolate(), DELETE_ON_EXIT); 3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneList<Handle<Object> > elements(4); 3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ(c0_, '['); 3283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 3303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != ']') { 3313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 3323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> element = ParseJsonValue(); 3333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (element.is_null()) return ReportUnexpectedCharacter(); 3343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch elements.Add(element); 3353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (MatchSkipWhiteSpace(',')); 3363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != ']') { 3373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return ReportUnexpectedCharacter(); 3383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 3413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Allocate a fixed array with all the elements. 3423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<FixedArray> fast_elements = 3433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->factory()->NewFixedArray(elements.length()); 3443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0, n = elements.length(); i < n; i++) { 3453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fast_elements->set(i, *elements[i]); 3463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->factory()->NewJSArrayWithElements(fast_elements); 3483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 3493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 3523fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { 3533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool negative = false; 3543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int beg_pos = position_; 3553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ == '-') { 3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch negative = true; 3583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ == '0') { 3603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Prefix zero is only allowed if it's the only digit before 3623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // a decimal point or exponent. 3633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter(); 3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 3653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int i = 0; 3663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int digits = 0; 3673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter(); 3683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 3693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch i = i * 10 + c0_ - '0'; 3703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch digits++; 3713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (c0_ >= '0' && c0_ <= '9'); 3733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { 3743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SkipWhitespace(); 3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Handle<Smi>(Smi::FromInt((negative ? -i : i)), isolate()); 3763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ == '.') { 3793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); 3813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 3823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (c0_ >= '0' && c0_ <= '9'); 3843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (AsciiAlphaToLower(c0_) == 'e') { 3863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ == '-' || c0_ == '+') Advance(); 3883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); 3893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 3903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 3913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (c0_ >= '0' && c0_ <= '9'); 3923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int length = position_ - beg_pos; 3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch double number; 3953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (seq_ascii) { 3963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Vector<const char> chars(seq_source_->GetChars() + beg_pos, length); 3973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number = StringToDouble(isolate()->unicode_cache(), 3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch chars, 3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NO_FLAGS, // Hex, octal or trailing junk. 4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OS::nan_value()); 4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 4023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Vector<char> buffer = Vector<char>::New(length); 4033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch String::WriteToFlat(*source_, buffer.start(), beg_pos, position_); 4043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Vector<const char> result = 4053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Vector<const char>(reinterpret_cast<const char*>(buffer.start()), 4063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch length); 4073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number = StringToDouble(isolate()->unicode_cache(), 4083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result, 4093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NO_FLAGS, // Hex, octal or trailing junk. 4103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0.0); 4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer.Dispose(); 4123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SkipWhitespace(); 4143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->factory()->NewNumber(number); 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <typename StringType> 4193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochinline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); 4203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <> 4223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochinline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { 4233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch seq_str->SeqTwoByteStringSet(i, c); 4243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <> 4273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochinline void SeqStringSet(Handle<SeqAsciiString> seq_str, int i, uc32 c) { 4283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch seq_str->SeqAsciiStringSet(i, c); 4293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <typename StringType> 4323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochinline Handle<StringType> NewRawString(Factory* factory, int length); 4333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <> 4353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochinline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length) { 4363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return factory->NewRawTwoByteString(length, NOT_TENURED); 4373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <> 4403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochinline Handle<SeqAsciiString> NewRawString(Factory* factory, int length) { 4413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return factory->NewRawAsciiString(length, NOT_TENURED); 4423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Scans the rest of a JSON string starting from position_ and writes 4463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// prefix[start..end] along with the scanned characters into a 4473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// sequential string of type StringType. 4483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 4493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <typename StringType, typename SinkChar> 4503fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<String> JsonParser<seq_ascii>::SlowScanJsonString( 4513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> prefix, int start, int end) { 4523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int count = end - start; 4533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int max_length = count + source_length_ - position_; 4543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); 4553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<StringType> seq_str = NewRawString<StringType>(isolate()->factory(), 4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch length); 4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Copy prefix into seq_str. 4583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SinkChar* dest = seq_str->GetChars(); 4593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch String::WriteToFlat(*prefix, dest, start, end); 4603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (c0_ != '"') { 4623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check for control character (0x00-0x1f) or unterminated string (<0). 4633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ < 0x20) return Handle<String>::null(); 4643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (count >= length) { 4653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We need to create a longer sequential string for the result. 4663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); 4673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != '\\') { 4693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the sink can contain UC16 characters, or source_ contains only 4703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // ASCII characters, there's no need to test whether we can store the 4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // character. Otherwise check whether the UC16 source character can fit 4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // in the ASCII sink. 4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (sizeof(SinkChar) == kUC16Size || 4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch seq_ascii || 4753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch c0_ <= kMaxAsciiCharCode) { 4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, c0_); 4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // StringType is SeqAsciiString and we just read a non-ASCII char. 4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count); 4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); // Advance past the \. 4843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (c0_) { 4853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '"': 4863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '\\': 4873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case '/': 4883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, c0_); 4893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 4903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'b': 4913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, '\x08'); 4923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'f': 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, '\x0c'); 4953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'n': 4973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, '\x0a'); 4983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 4993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'r': 5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, '\x0d'); 5013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 5023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 't': 5033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, '\x09'); 5043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 5053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 'u': { 5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uc32 value = 0; 5073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < 4; i++) { 5083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 5093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int digit = HexValue(c0_); 5103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (digit < 0) { 5113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Handle<String>::null(); 5123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch value = value * 16 + digit; 5143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) { 5163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SeqStringSet(seq_str, count++, value); 5173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 5183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // StringType is SeqAsciiString and we just read a non-ASCII char. 5203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_ -= 6; // Rewind position_ to \ in \uxxxx. 5213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 5223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch count); 5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 5283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Handle<String>::null(); 5293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 5313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Shrink seq_string length to count. 5343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (isolate()->heap()->InNewSpace(*seq_str)) { 5353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->heap()->new_space()-> 5363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch template ShrinkStringAtAllocationBoundary<StringType>( 5373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *seq_str, count); 5383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int string_size = StringType::SizeFor(count); 5403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int allocated_string_size = StringType::SizeFor(length); 5413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int delta = allocated_string_size - string_size; 5423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Address start_filler_object = seq_str->address() + string_size; 5433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch seq_str->set_length(count); 5443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta); 5453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ('"', c0_); 5473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Advance past the last '"'. 5483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 5493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return seq_str; 5503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool seq_ascii> 5543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <bool is_symbol> 5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochHandle<String> JsonParser<seq_ascii>::ScanJsonString() { 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ('"', c0_); 5573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 5583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ == '"') { 5593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 5603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Handle<String>(isolate()->heap()->empty_string()); 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int beg_pos = position_; 5633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Fast case for ASCII only without escape characters. 5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check for control character (0x00-0x1f) or unterminated string (<0). 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ < 0x20) return Handle<String>::null(); 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (c0_ != '\\') { 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (seq_ascii || c0_ <= kMaxAsciiCharCode) { 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Advance(); 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return SlowScanJsonString<SeqTwoByteString, uc16>(source_, 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch beg_pos, 5733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_); 5743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return SlowScanJsonString<SeqAsciiString, char>(source_, 5773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch beg_pos, 5783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch position_); 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (c0_ != '"'); 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int length = position_ - beg_pos; 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> result; 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (seq_ascii && is_symbol) { 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result = isolate()->factory()->LookupAsciiSymbol(seq_source_, 5853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch beg_pos, 5863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch length); 5873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result = isolate()->factory()->NewRawAsciiString(length); 5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char* dest = SeqAsciiString::cast(*result)->GetChars(); 5903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch String::WriteToFlat(*source_, dest, beg_pos, position_); 5913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ('"', c0_); 5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Advance past the last '"'. 5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceSkipWhitespace(); 5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return result; 5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} } // namespace v8::internal 599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif // V8_JSON_PARSER_H_ 601