1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_JSON_PARSER_H_ 6 #define V8_JSON_PARSER_H_ 7 8 #include "src/factory.h" 9 #include "src/objects.h" 10 11 namespace v8 { 12 namespace internal { 13 14 enum ParseElementResult { kElementFound, kElementNotFound, kNullHandle }; 15 16 class JsonParseInternalizer BASE_EMBEDDED { 17 public: 18 static MaybeHandle<Object> Internalize(Isolate* isolate, 19 Handle<Object> object, 20 Handle<Object> reviver); 21 22 private: JsonParseInternalizer(Isolate * isolate,Handle<JSReceiver> reviver)23 JsonParseInternalizer(Isolate* isolate, Handle<JSReceiver> reviver) 24 : isolate_(isolate), reviver_(reviver) {} 25 26 MaybeHandle<Object> InternalizeJsonProperty(Handle<JSReceiver> holder, 27 Handle<String> key); 28 29 bool RecurseAndApply(Handle<JSReceiver> holder, Handle<String> name); 30 31 Isolate* isolate_; 32 Handle<JSReceiver> reviver_; 33 }; 34 35 // A simple json parser. 36 template <bool seq_one_byte> 37 class JsonParser BASE_EMBEDDED { 38 public: Parse(Isolate * isolate,Handle<String> source,Handle<Object> reviver)39 MUST_USE_RESULT static MaybeHandle<Object> Parse(Isolate* isolate, 40 Handle<String> source, 41 Handle<Object> reviver) { 42 Handle<Object> result; 43 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, 44 JsonParser(isolate, source).ParseJson(), Object); 45 if (reviver->IsCallable()) { 46 return JsonParseInternalizer::Internalize(isolate, result, reviver); 47 } 48 return result; 49 } 50 51 static const int kEndOfString = -1; 52 53 private: 54 JsonParser(Isolate* isolate, Handle<String> source); 55 56 // Parse a string containing a single JSON value. 57 MaybeHandle<Object> ParseJson(); 58 59 INLINE(void Advance()); 60 61 // The JSON lexical grammar is specified in the ECMAScript 5 standard, 62 // section 15.12.1.1. The only allowed whitespace characters between tokens 63 // are tab, carriage-return, newline and space. 64 65 INLINE(void AdvanceSkipWhitespace()); 66 INLINE(void SkipWhitespace()); 67 INLINE(uc32 AdvanceGetChar()); 68 69 // Checks that current charater is c. 70 // If so, then consume c and skip whitespace. 71 INLINE(bool MatchSkipWhiteSpace(uc32 c)); 72 73 // A JSON string (production JSONString) is subset of valid JavaScript string 74 // literals. The string must only be double-quoted (not single-quoted), and 75 // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and 76 // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid. ParseJsonString()77 Handle<String> ParseJsonString() { 78 return ScanJsonString<false>(); 79 } 80 81 bool ParseJsonString(Handle<String> expected); 82 ParseJsonInternalizedString()83 Handle<String> ParseJsonInternalizedString() { 84 Handle<String> result = ScanJsonString<true>(); 85 if (result.is_null()) return result; 86 return factory()->InternalizeString(result); 87 } 88 89 template <bool is_internalized> 90 Handle<String> ScanJsonString(); 91 // Creates a new string and copies prefix[start..end] into the beginning 92 // of it. Then scans the rest of the string, adding characters after the 93 // prefix. Called by ScanJsonString when reaching a '\' or non-Latin1 char. 94 template <typename StringType, typename SinkChar> 95 Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end); 96 97 // A JSON number (production JSONNumber) is a subset of the valid JavaScript 98 // decimal number literals. 99 // It includes an optional minus sign, must have at least one 100 // digit before and after a decimal point, may not have prefixed zeros (unless 101 // the integer part is zero), and may include an exponent part (e.g., "e-10"). 102 // Hexadecimal and octal numbers are not allowed. 103 Handle<Object> ParseJsonNumber(); 104 105 // Parse a single JSON value from input (grammar production JSONValue). 106 // A JSON value is either a (double-quoted) string literal, a number literal, 107 // one of "true", "false", or "null", or an object or array literal. 108 Handle<Object> ParseJsonValue(); 109 110 // Parse a JSON object literal (grammar production JSONObject). 111 // An object literal is a squiggly-braced and comma separated sequence 112 // (possibly empty) of key/value pairs, where the key is a JSON string 113 // literal, the value is a JSON value, and the two are separated by a colon. 114 // A JSON array doesn't allow numbers and identifiers as keys, like a 115 // JavaScript array. 116 Handle<Object> ParseJsonObject(); 117 118 // Helper for ParseJsonObject. Parses the form "123": obj, which is recorded 119 // as an element, not a property. 120 ParseElementResult ParseElement(Handle<JSObject> json_object); 121 122 // Parses a JSON array literal (grammar production JSONArray). An array 123 // literal is a square-bracketed and comma separated sequence (possibly empty) 124 // of JSON values. 125 // A JSON array doesn't allow leaving out values from the sequence, nor does 126 // it allow a terminal comma, like a JavaScript array does. 127 Handle<Object> ParseJsonArray(); 128 129 130 // Mark that a parsing error has happened at the current token, and 131 // return a null handle. Primarily for readability. ReportUnexpectedCharacter()132 inline Handle<Object> ReportUnexpectedCharacter() { 133 return Handle<Object>::null(); 134 } 135 isolate()136 inline Isolate* isolate() { return isolate_; } factory()137 inline Factory* factory() { return factory_; } object_constructor()138 inline Handle<JSFunction> object_constructor() { return object_constructor_; } 139 140 static const int kInitialSpecialStringLength = 32; 141 static const int kPretenureTreshold = 100 * 1024; 142 143 private: zone()144 Zone* zone() { return &zone_; } 145 146 void CommitStateToJsonObject(Handle<JSObject> json_object, Handle<Map> map, 147 ZoneList<Handle<Object> >* properties); 148 149 Handle<String> source_; 150 int source_length_; 151 Handle<SeqOneByteString> seq_source_; 152 153 PretenureFlag pretenure_; 154 Isolate* isolate_; 155 Factory* factory_; 156 Zone zone_; 157 Handle<JSFunction> object_constructor_; 158 uc32 c0_; 159 int position_; 160 }; 161 162 } // namespace internal 163 } // namespace v8 164 165 #endif // V8_JSON_PARSER_H_ 166