Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: runtime/vm/json_parser.h

Issue 2572423004: Reapply "Save and restore feedback from JIT." (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef RUNTIME_VM_JSON_PARSER_H_
6 #define RUNTIME_VM_JSON_PARSER_H_
7
8 #include "vm/allocation.h"
9 #include "vm/zone.h"
10 #include "vm/growable_array.h"
11
12 namespace dart {
13
14 class ParsedJSONArray;
15
16 class ParsedJSONValue : public ZoneAllocated {
17 public:
18 virtual ~ParsedJSONValue() {}
19
20 virtual bool IsObject() const { return false; }
21 virtual bool IsArray() const { return false; }
22 virtual bool IsString() const { return false; }
23 virtual bool IsNumber() const { return false; }
24 virtual bool IsBoolean() const { return false; }
25 virtual bool IsError() const { return false; }
26 };
27
28 class ParsedJSONString : public ParsedJSONValue {
29 public:
30 explicit ParsedJSONString(const char* value) : value_(value) {}
31 bool Equals(const char* other) { return strcmp(value_, other) == 0; }
32 const char* value() { return value_; }
33 virtual bool IsString() const { return true; }
34
35 private:
36 const char* value_;
37 };
38
39 class ParsedJSONNumber : public ParsedJSONValue {
40 public:
41 explicit ParsedJSONNumber(int64_t value) : value_(value) {}
42
43 int64_t value() { return value_; }
44 virtual bool IsNumber() const { return true; }
45
46 private:
47 int64_t value_;
48 };
49
50 class ParsedJSONBoolean : public ParsedJSONValue {
51 public:
52 explicit ParsedJSONBoolean(bool value) : value_(value) {}
53
54 bool value() { return value_; }
55 virtual bool IsBoolean() const { return true; }
56
57 private:
58 bool value_;
59 };
60
61 class ParsedJSONNull : public ParsedJSONValue {
62 public:
63 virtual bool IsNull() const { return true; }
64 };
65
66 class ParsedJSONObject : public ParsedJSONValue {
67 public:
68 ParsedJSONObject(intptr_t length, ParsedJSONValue** keys_and_values)
69 : length_(length), keys_and_values_(keys_and_values) {}
70
71 ParsedJSONValue* At(const char* key) const {
72 for (intptr_t i = 0; i < length_; i += 2) {
73 ASSERT(keys_and_values_[i]->IsString());
74 ParsedJSONString* jskey =
75 static_cast<ParsedJSONString*>(keys_and_values_[i]);
76 if (jskey->Equals(key)) {
77 return keys_and_values_[i + 1];
78 }
79 }
80 return NULL;
81 }
82
83 virtual bool IsObject() const { return true; }
84
85 ParsedJSONNumber* NumberAt(const char* key) {
86 ParsedJSONValue* member = At(key);
87 if ((member == NULL) || !member->IsNumber()) {
88 return NULL;
89 }
90 return static_cast<ParsedJSONNumber*>(member);
91 }
92
93 ParsedJSONString* StringAt(const char* key) {
94 ParsedJSONValue* member = At(key);
95 if ((member == NULL) || !member->IsString()) {
96 return NULL;
97 }
98 return static_cast<ParsedJSONString*>(member);
99 }
100
101 ParsedJSONBoolean* BooleanAt(const char* key) {
102 ParsedJSONValue* member = At(key);
103 if ((member == NULL) || !member->IsBoolean()) {
104 return NULL;
105 }
106 return static_cast<ParsedJSONBoolean*>(member);
107 }
108
109 inline ParsedJSONArray* ArrayAt(const char* key);
110
111 private:
112 intptr_t length_;
113 ParsedJSONValue** keys_and_values_;
114 };
115
116 class ParsedJSONArray : public ParsedJSONValue {
117 public:
118 ParsedJSONArray(intptr_t length, ParsedJSONValue** elements)
119 : length_(length), elements_(elements) {}
120
121 ParsedJSONValue* At(intptr_t index) const {
122 ASSERT(index < length_);
123 return elements_[index];
124 }
125
126 intptr_t Length() const { return length_; }
127
128 virtual bool IsArray() const { return true; }
129
130 ParsedJSONObject* ObjectAt(intptr_t index) {
131 ParsedJSONValue* element = At(index);
132 if ((element == NULL) || !element->IsObject()) {
133 return NULL;
134 }
135 return static_cast<ParsedJSONObject*>(element);
136 }
137
138 ParsedJSONNumber* NumberAt(intptr_t index) {
139 ParsedJSONValue* element = At(index);
140 if ((element == NULL) || !element->IsNumber()) {
141 return NULL;
142 }
143 return static_cast<ParsedJSONNumber*>(element);
144 }
145
146 private:
147 intptr_t length_;
148 ParsedJSONValue** elements_;
149 };
150
151 class ParsedJSONError : public ParsedJSONValue {
152 public:
153 explicit ParsedJSONError(const char* message, intptr_t position)
154 : message_(message), position_(position) {}
155
156 virtual bool IsError() const { return true; }
157
158 const char* message() const { return message_; }
159 intptr_t position() const { return position_; }
160
161 private:
162 const char* message_;
163 intptr_t position_;
164 };
165
166 class JSONParser {
167 public:
168 JSONParser(const char* buffer, intptr_t length, Zone* zone)
169 : buffer_(buffer), position_(0), length_(length), zone_(zone) {}
170
171 ParsedJSONValue* ParseValue() {
172 ConsumeWhitespace();
173 if (Peek() == '\"') return ParseString();
174 if (IsDigitOrMinus(Peek())) return ParseNumber();
175 if (Peek() == '{') return ParseObject();
176 if (Peek() == '[') return ParseArray();
177 if (PeekAndConsume("true")) return new (zone_) ParsedJSONBoolean(true);
178 if (PeekAndConsume("false")) return new (zone_) ParsedJSONBoolean(false);
179 if (PeekAndConsume("null")) return new (zone_) ParsedJSONNull();
180 return Error("value expected");
181 }
182
183 private:
184 intptr_t Available() const { return length_ - position_; }
185 char Peek() const {
186 if (position_ < length_) return buffer_[position_];
187 return 0;
188 }
189 char Consume() {
190 ASSERT(position_ < length_);
191 return buffer_[position_++];
192 }
193 bool PeekAndConsume(const char* expected) {
194 intptr_t n = strlen(expected);
195 if (Available() < n) return false;
196 if (strncmp(&buffer_[position_], expected, n) != 0) return false;
197 position_ += n;
198 return true;
199 }
200 void ConsumeWhitespace() {
201 while ((Available() > 0) && (buffer_[position_] < ' '))
202 position_++;
203 }
204 bool IsDigit(char c) { return c >= '0' && c <= '9'; }
205 bool IsDigitOrMinus(char c) { return (c == '-') || (c >= '0' && c <= '9'); }
206
207 ParsedJSONValue* ParseString() {
208 ConsumeWhitespace();
209 if (Peek() != '\"') return Error("string expected");
210 Consume();
211 intptr_t start = position_;
212 for (;;) {
213 if (Available() == 0) return Error("unterminated string");
214 if (Consume() == '\"') break;
215 }
216 intptr_t end = position_ - 1;
217
218 char* cstr = zone_->Alloc<char>(end - start + 1);
219 intptr_t dst_pos = 0;
220 for (intptr_t src_pos = start; src_pos < end; src_pos++) {
221 if (buffer_[src_pos] == '\\') {
222 src_pos++;
223 }
224 cstr[dst_pos++] = buffer_[src_pos];
225 }
226 cstr[dst_pos] = '\0';
227
228 return new (zone_) ParsedJSONString(cstr);
229 }
230
231 ParsedJSONValue* ParseNumber() {
232 ConsumeWhitespace();
233 bool negate = false;
234 if (Peek() == '-') {
235 Consume();
236 negate = true;
237 }
238 if (!IsDigit(Peek())) return Error("number expected");
239 int64_t value = 0;
240 for (;;) {
241 if (!IsDigit(Peek())) break;
242 char c = Consume();
243 value *= 10;
244 value += (c - '0');
245 }
246 if (negate) {
247 value = -value;
248 }
249 return new (zone_) ParsedJSONNumber(value);
250 }
251
252 ParsedJSONValue* ParseObject() {
253 ConsumeWhitespace();
254 if (Peek() != '{') return Error("object expected");
255 Consume();
256 ConsumeWhitespace();
257 if (Peek() == '}') return new (zone_) ParsedJSONObject(0, NULL);
258 ZoneGrowableArray<ParsedJSONValue*>* keys_and_values =
259 new (zone_) ZoneGrowableArray<ParsedJSONValue*>(zone_, 6);
260 for (;;) {
261 ParsedJSONValue* key = ParseString();
262 if (key->IsError()) return key;
263 ConsumeWhitespace();
264 if (Consume() != ':') return Error(": expected");
265 ConsumeWhitespace();
266 ParsedJSONValue* value = ParseValue();
267 if (value->IsError()) return value;
268 ConsumeWhitespace();
269
270 keys_and_values->Add(key);
271 keys_and_values->Add(value);
272
273 char c = Consume();
274 if (c == '}') break;
275 if (c != ',') return Error(", expected (object)");
276 ConsumeWhitespace();
277 }
278
279 return new (zone_)
280 ParsedJSONObject(keys_and_values->length(), keys_and_values->data());
281 }
282
283 ParsedJSONValue* ParseArray() {
284 ConsumeWhitespace();
285 if (Peek() != '[') return Error("array expected");
286 Consume();
287 ConsumeWhitespace();
288 if (Peek() == ']') {
289 Consume();
290 return new (zone_) ParsedJSONArray(0, NULL);
291 }
292 ZoneGrowableArray<ParsedJSONValue*>* elements =
293 new (zone_) ZoneGrowableArray<ParsedJSONValue*>(zone_, 6);
294 for (;;) {
295 ParsedJSONValue* element = ParseValue();
296 if (element->IsError()) return element;
297 ConsumeWhitespace();
298
299 elements->Add(element);
300
301 char c = Consume();
302 if (c == ']') break;
303 if (c != ',') return Error(", expected (array)");
304 ConsumeWhitespace();
305 }
306
307 return new (zone_) ParsedJSONArray(elements->length(), elements->data());
308 }
309
310 private:
311 ParsedJSONError* Error(const char* message) {
312 return new (zone_) ParsedJSONError(message, position_);
313 }
314
315 const char* const buffer_;
316 intptr_t position_;
317 intptr_t length_;
318 Zone* zone_;
319 };
320
321 ParsedJSONArray* ParsedJSONObject::ArrayAt(const char* key) {
322 ParsedJSONValue* member = At(key);
323 if ((member == NULL) || !member->IsArray()) {
324 return NULL;
325 }
326 return static_cast<ParsedJSONArray*>(member);
327 }
328
329 } // namespace dart
330
331 #endif // RUNTIME_VM_JSON_PARSER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698