OLD | NEW |
---|---|
(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 #include <errno.h> | |
6 #include <fcntl.h> | |
7 #include <sys/stat.h> | |
8 #include <unistd.h> | |
9 #include <map> | |
10 #include <memory> | |
11 #include <vector> | |
12 | |
13 #include "vm/dil.h" | |
14 | |
15 #include "platform/signal_blocker.h" | |
16 | |
17 #if 0 | |
18 #define TRACE_READ_OFFSET() reader->DumpOffset(__PRETTY_FUNCTION__); | |
19 #define TRACE_WRITE_OFFSET() writer->DumpOffset(__PRETTY_FUNCTION__); | |
20 #else | |
21 #define TRACE_READ_OFFSET() | |
22 #define TRACE_WRITE_OFFSET() | |
23 #endif | |
24 | |
25 namespace dart { | |
26 | |
27 | |
28 class InputFile { | |
29 public: | |
30 explicit InputFile(const char* filename) | |
31 : filename_(filename), buffer_(NULL), size_(-1) {} | |
32 | |
33 ~InputFile() { delete[] buffer_; } | |
34 | |
35 bool ReadAll() { | |
36 size_ = FileSize(); | |
37 if (size_ > 0) { | |
38 // TODO(kustermann): We could consider simply mmap()ing the file, but | |
39 // that might not work so easily on windows. | |
40 int fd = TEMP_FAILURE_RETRY(open(filename_, O_RDONLY)); | |
rmacnak
2016/10/13 00:56:39
IO belongs in the embedder, not the VM.
Vyacheslav Egorov (Google)
2016/10/13 14:37:57
Deleted this code.
| |
41 if (fd < 0) return false; | |
42 buffer_ = new uint8_t[size_]; | |
43 int64_t offset = 0; | |
44 while (offset < size_) { | |
45 ssize_t bytes = TEMP_FAILURE_RETRY(read(fd, buffer_, size_ - offset)); | |
46 if (bytes < 0) FATAL("Error during reading dil file."); | |
47 offset += bytes; | |
48 } | |
49 TEMP_FAILURE_RETRY(close(fd)); | |
50 return true; | |
51 } | |
52 return false; | |
53 } | |
54 | |
55 uint8_t* buffer() { return buffer_; } | |
56 int64_t size() { return size_; } | |
57 | |
58 private: | |
59 int FileSize() { | |
60 struct stat file_stat; | |
61 if (stat(filename_, &file_stat) == 0) { | |
62 return file_stat.st_size; | |
63 } | |
64 return -1; | |
65 } | |
66 | |
67 const char* filename_; | |
68 uint8_t* buffer_; | |
69 int64_t size_; | |
70 }; | |
71 | |
72 | |
73 class OutputFile { | |
74 public: | |
75 explicit OutputFile(const char* filename) | |
76 : filename_(filename), fd_(-1), offset_(0) {} | |
77 | |
78 ~OutputFile() { | |
79 if (fd_ >= 0) { | |
80 Flush(); | |
81 TEMP_FAILURE_RETRY(close(fd_)); | |
82 } | |
83 } | |
84 | |
85 bool Open() { | |
86 fd_ = | |
87 TEMP_FAILURE_RETRY(open(filename_, O_CREAT | O_WRONLY | O_TRUNC, 0666)); | |
88 return fd_ >= 0; | |
89 } | |
90 | |
91 void WriteByte(uint8_t byte) { | |
92 if (offset_ >= kBufferSize) { | |
93 Flush(); | |
94 } | |
95 buffer_[offset_++] = byte; | |
96 } | |
97 | |
98 void WriteBytes(uint8_t* buffer, int count) { | |
99 while (count > 0) { | |
100 if (offset_ >= kBufferSize) { | |
101 Flush(); | |
102 } | |
103 int space = kBufferSize - offset_; | |
104 int to_write = space >= count ? count : space; | |
105 | |
106 memcpy(buffer_ + offset_, buffer, to_write); // NOLINT | |
107 buffer += to_write; | |
108 count -= to_write; | |
109 offset_ += to_write; | |
110 } | |
111 } | |
112 | |
113 void Flush() { | |
114 uint8_t* buffer = buffer_; | |
115 int remaining = offset_; | |
116 while (remaining > 0) { | |
117 int result = TEMP_FAILURE_RETRY(write(fd_, buffer, remaining)); | |
118 if (result <= 0) FATAL("Something went wrong when writing"); | |
119 remaining -= result; | |
120 buffer += result; | |
121 } | |
122 offset_ = 0; | |
123 } | |
124 | |
125 private: | |
126 static const int kBufferSize = 32 * 1024; | |
127 | |
128 const char* filename_; | |
129 int fd_; | |
130 uint8_t buffer_[kBufferSize]; | |
131 intptr_t offset_; | |
132 }; | |
133 | |
134 | |
135 namespace dil { | |
136 | |
137 | |
138 static const uint32_t kMagicProgramFile = 0x90ABCDEFu; | |
139 | |
140 | |
141 // Keep in sync with package:dynamo/lib/binary/tag.dart | |
142 enum Tag { | |
143 kNothing = 0, | |
144 kSomething = 1, | |
145 | |
146 kNormalClass = 2, | |
147 kMixinClass = 3, | |
148 | |
149 kField = 4, | |
150 kConstructor = 5, | |
151 kProcedure = 6, | |
152 | |
153 kInvalidInitializer = 7, | |
154 kFieldInitializer = 8, | |
155 kSuperInitializer = 9, | |
156 kRedirectingInitializer = 10, | |
157 kLocalInitializer = 11, | |
158 | |
159 kDirectPropertyGet = 15, | |
160 kDirectPropertySet = 16, | |
161 kDirectMethodInvocation = 17, | |
162 kConstStaticInvocation = 18, | |
163 kInvalidExpression = 19, | |
164 kVariableGet = 20, | |
165 kVariableSet = 21, | |
166 kPropertyGet = 22, | |
167 kPropertySet = 23, | |
168 kSuperPropertyGet = 24, | |
169 kSuperPropertySet = 25, | |
170 kStaticGet = 26, | |
171 kStaticSet = 27, | |
172 kMethodInvocation = 28, | |
173 kSuperMethodInvocation = 29, | |
174 kStaticInvocation = 30, | |
175 kConstructorInvocation = 31, | |
176 kConstConstructorInvocation = 32, | |
177 kNot = 33, | |
178 kLogicalExpression = 34, | |
179 kConditionalExpression = 35, | |
180 kStringConcatenation = 36, | |
181 kIsExpression = 37, | |
182 kAsExpression = 38, | |
183 kStringLiteral = 39, | |
184 kDoubleLiteral = 40, | |
185 kTrueLiteral = 41, | |
186 kFalseLiteral = 42, | |
187 kNullLiteral = 43, | |
188 kSymbolLiteral = 44, | |
189 kTypeLiteral = 45, | |
190 kThisExpression = 46, | |
191 kRethrow = 47, | |
192 kThrow = 48, | |
193 kListLiteral = 49, | |
194 kMapLiteral = 50, | |
195 kAwaitExpression = 51, | |
196 kFunctionExpression = 52, | |
197 kLet = 53, | |
198 kBlockExpression = 54, | |
199 | |
200 kPositiveIntLiteral = 55, | |
201 kNegativeIntLiteral = 56, | |
202 kBigIntLiteral = 57, | |
203 kConstListLiteral = 58, | |
204 kConstMapLiteral = 59, | |
205 | |
206 kInvalidStatement = 60, | |
207 kExpressionStatement = 61, | |
208 kBlock = 62, | |
209 kEmptyStatement = 63, | |
210 kAssertStatement = 64, | |
211 kLabeledStatement = 65, | |
212 kBreakStatement = 66, | |
213 kWhileStatement = 67, | |
214 kDoStatement = 68, | |
215 kForStatement = 69, | |
216 kForInStatement = 70, | |
217 kSwitchStatement = 71, | |
218 kContinueSwitchStatement = 72, | |
219 kIfStatement = 73, | |
220 kReturnStatement = 74, | |
221 kTryCatch = 75, | |
222 kTryFinally = 76, | |
223 kYieldStatement = 77, | |
224 kVariableDeclaration = 78, | |
225 kFunctionDeclaration = 79, | |
226 kAsyncForInStatement = 80, | |
227 | |
228 kInvalidType = 90, | |
229 kDynamicType = 91, | |
230 kVoidType = 92, | |
231 kInterfaceType = 93, | |
232 kFunctionType = 94, | |
233 kTypeParameterType = 95, | |
234 kSimpleInterfaceType = 96, | |
235 kSimpleFunctionType = 97, | |
236 | |
237 kNullReference = 99, | |
238 kNormalClassReference = 100, | |
239 kMixinClassReference = 101, | |
240 | |
241 kLibraryFieldReference = 102, | |
242 kClassFieldReference = 103, | |
243 kClassConstructorReference = 104, | |
244 kLibraryProcedureReference = 105, | |
245 kClassProcedureReference = 106, | |
246 | |
247 kSpecializedTagHighBit = 0x80, // 10000000 | |
248 kSpecializedTagMask = 0xF8, // 11111000 | |
249 kSpecializedPayloadMask = 0x7, // 00000111 | |
250 | |
251 kSpecializedVariableGet = 128, | |
252 kSpecializedVariableSet = 136, | |
253 kSpecialIntLiteral = 144, | |
254 }; | |
255 | |
256 | |
257 static const int SpecializedIntLiteralBias = 3; | |
258 | |
259 | |
260 template <typename T> | |
261 class BlockStack { | |
262 public: | |
263 BlockStack() : current_count_(0) {} | |
264 | |
265 void EnterScope() { | |
266 variable_count_.push_back(current_count_); | |
267 current_count_ = 0; | |
268 } | |
269 | |
270 void LeaveScope() { | |
271 variables_.resize(variables_.size() - current_count_); | |
272 current_count_ = variable_count_[variable_count_.size() - 1]; | |
273 variable_count_.pop_back(); | |
274 } | |
275 | |
276 T* Lookup(int index) { | |
277 ASSERT(static_cast<unsigned>(index) < variables_.size()); | |
278 return variables_[index]; | |
279 } | |
280 | |
281 void Push(T* v) { | |
282 variables_.push_back(v); | |
283 current_count_++; | |
284 } | |
285 | |
286 void Push(List<T>* decl) { | |
287 for (int i = 0; i < decl->length(); i++) { | |
288 variables_.push_back(decl[i]); | |
289 current_count_++; | |
290 } | |
291 } | |
292 | |
293 void Pop(T* decl) { | |
294 variables_.resize(variables_.size() - 1); | |
295 current_count_--; | |
296 } | |
297 | |
298 void Pop(List<T>* decl) { | |
299 variables_.resize(variables_.size() - decl->length()); | |
300 current_count_ -= decl->length(); | |
301 } | |
302 | |
303 private: | |
304 int current_count_; | |
305 std::vector<T*> variables_; | |
306 std::vector<int> variable_count_; | |
307 }; | |
308 | |
309 | |
310 template <typename T> | |
311 class BlockMap { | |
312 public: | |
313 BlockMap() : current_count_(0), stack_height_(0) {} | |
314 | |
315 void EnterScope() { | |
316 variable_count_.push_back(current_count_); | |
317 current_count_ = 0; | |
318 } | |
319 | |
320 void LeaveScope() { | |
321 stack_height_ -= current_count_; | |
322 current_count_ = variable_count_[variable_count_.size() - 1]; | |
323 variable_count_.pop_back(); | |
324 } | |
325 | |
326 int Lookup(T* object) { | |
327 ASSERT(variables_.find(object) != variables_.end()); | |
328 if (variables_.find(object) == variables_.end()) FATAL("lookup failure"); | |
329 return variables_[object]; | |
330 } | |
331 | |
332 void Push(T* v) { | |
333 int index = stack_height_++; | |
334 variables_[v] = index; | |
335 current_count_++; | |
336 } | |
337 | |
338 void Set(T* v, int index) { variables_[v] = index; } | |
339 | |
340 void Push(List<T>* decl) { | |
341 for (int i = 0; i < decl->length(); i++) { | |
342 Push(decl[i]); | |
343 } | |
344 } | |
345 | |
346 void Pop(T* v) { | |
347 current_count_--; | |
348 stack_height_--; | |
349 } | |
350 | |
351 private: | |
352 int current_count_; | |
353 int stack_height_; | |
354 std::map<T*, int> variables_; | |
355 std::vector<int> variable_count_; | |
356 }; | |
357 | |
358 | |
359 template <typename T> | |
360 class VariableScope { | |
361 public: | |
362 explicit VariableScope(T* builder) : builder_(builder) { | |
363 builder_->variables().EnterScope(); | |
364 } | |
365 ~VariableScope() { builder_->variables().LeaveScope(); } | |
366 | |
367 private: | |
368 T* builder_; | |
369 }; | |
370 | |
371 | |
372 template <typename T> | |
373 class TypeParameterScope { | |
374 public: | |
375 explicit TypeParameterScope(T* builder) : builder_(builder) { | |
376 builder_->type_parameters().EnterScope(); | |
377 } | |
378 ~TypeParameterScope() { builder_->type_parameters().LeaveScope(); } | |
379 | |
380 private: | |
381 T* builder_; | |
382 }; | |
383 | |
384 | |
385 template <typename T> | |
386 class SwitchCaseScope { | |
387 public: | |
388 explicit SwitchCaseScope(T* builder) : builder_(builder) { | |
389 builder_->switch_cases().EnterScope(); | |
390 } | |
391 ~SwitchCaseScope() { builder_->switch_cases().LeaveScope(); } | |
392 | |
393 private: | |
394 T* builder_; | |
395 }; | |
396 | |
397 | |
398 class ReaderHelper { | |
399 public: | |
400 ReaderHelper() : program_(NULL) {} | |
401 ~ReaderHelper() {} | |
402 | |
403 Program* program() { return program_; } | |
404 void set_program(Program* program) { program_ = program; } | |
405 | |
406 BlockStack<VariableDeclaration>& variables() { return scope_; } | |
407 BlockStack<TypeParameter>& type_parameters() { return type_parameters_; } | |
408 BlockStack<LabeledStatement>& lables() { return labels_; } | |
409 BlockStack<SwitchCase>& switch_cases() { return switch_cases_; } | |
410 | |
411 private: | |
412 Program* program_; | |
413 BlockStack<VariableDeclaration> scope_; | |
414 BlockStack<TypeParameter> type_parameters_; | |
415 BlockStack<LabeledStatement> labels_; | |
416 BlockStack<SwitchCase> switch_cases_; | |
417 }; | |
418 | |
419 | |
420 class Reader { | |
421 public: | |
422 Reader(const uint8_t* buffer, int64_t size) | |
423 : buffer_(buffer), size_(size), offset_(0) {} | |
424 | |
425 uint32_t ReadUInt32() { | |
426 ASSERT(offset_ + 4 <= size_); | |
427 | |
428 uint32_t value = (buffer_[offset_ + 0] << 24) | | |
429 (buffer_[offset_ + 1] << 16) | | |
430 (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0); | |
431 offset_ += 4; | |
432 return value; | |
433 } | |
434 | |
435 uint32_t ReadUInt() { | |
436 ASSERT(offset_ + 1 <= size_); | |
437 uint8_t byte0 = buffer_[offset_]; | |
438 if ((byte0 & 0x80) == 0) { | |
439 // 0... | |
440 offset_++; | |
441 return byte0; | |
442 } else if ((byte0 & 0xc0) == 0x80) { | |
443 // 10... | |
444 ASSERT(offset_ + 2 <= size_); | |
445 uint32_t value = ((byte0 & ~0x80) << 8) | (buffer_[offset_ + 1]); | |
446 offset_ += 2; | |
447 return value; | |
448 } else { | |
449 // 11... | |
450 ASSERT(offset_ + 4 <= size_); | |
451 uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) | | |
452 (buffer_[offset_ + 2] << 8) | | |
453 (buffer_[offset_ + 3] << 0); | |
454 offset_ += 4; | |
455 return value; | |
456 } | |
457 } | |
458 | |
459 intptr_t ReadListLength() { return ReadUInt(); } | |
460 | |
461 uint8_t ReadByte() { return buffer_[offset_++]; } | |
462 | |
463 bool ReadBool() { return (ReadByte() & 1) == 1; } | |
464 | |
465 word ReadFlags() { return ReadByte(); } | |
466 | |
467 Tag ReadTag(uint8_t* payload = NULL) { | |
468 uint8_t byte = ReadByte(); | |
469 bool has_payload = (byte & kSpecializedTagHighBit) != 0; | |
470 if (has_payload) { | |
471 if (payload != NULL) { | |
472 *payload = byte & kSpecializedPayloadMask; | |
473 } | |
474 return static_cast<Tag>(byte & kSpecializedTagMask); | |
475 } else { | |
476 return static_cast<Tag>(byte); | |
477 } | |
478 } | |
479 | |
480 const uint8_t* Consume(int count) { | |
481 ASSERT(offset_ + count <= size_); | |
482 const uint8_t* old = buffer_ + offset_; | |
483 offset_ += count; | |
484 return old; | |
485 } | |
486 | |
487 void EnsureEnd() { | |
488 if (offset_ != size_) { | |
489 FATAL2("Reading Dil file: Expected to be at EOF (offset: %ld, size: %ld)", | |
490 offset_, size_); | |
491 } | |
492 } | |
493 | |
494 void DumpOffset(const char* str) { | |
495 fprintf(stderr, "@%ld %s\n", offset_, str); | |
rmacnak
2016/10/13 00:56:39
OS::PrintErr("@%" Pd64 %s\n", ...)
Vyacheslav Egorov (Google)
2016/10/13 14:37:57
Done.
| |
496 } | |
497 | |
498 template <typename T, typename RT> | |
499 T* ReadOptional() { | |
500 Tag tag = ReadTag(); | |
501 if (tag == kNothing) { | |
502 return NULL; | |
503 } | |
504 ASSERT(tag == kSomething); | |
505 return RT::ReadFrom(this); | |
506 } | |
507 | |
508 template <typename T> | |
509 T* ReadOptional() { | |
510 return ReadOptional<T, T>(); | |
511 } | |
512 | |
513 ReaderHelper* helper() { return &builder_; } | |
514 | |
515 private: | |
516 const uint8_t* buffer_; | |
517 int64_t size_; | |
518 int64_t offset_; | |
519 ReaderHelper builder_; | |
520 }; | |
521 | |
522 | |
523 class WriterHelper { | |
524 public: | |
525 void SetProgram(Program* program) { | |
526 program_ = program; | |
527 for (int i = 0; i < program->libraries().length(); i++) { | |
528 Library* lib = program->libraries()[i]; | |
529 libraries_.Set(lib, i); | |
530 | |
531 for (int j = 0; j < lib->classes().length(); j++) { | |
532 Class* klass = lib->classes()[j]; | |
533 classes_.Set(klass, j); | |
534 | |
535 for (int k = 0; k < klass->fields().length(); k++) { | |
536 Field* field = klass->fields()[k]; | |
537 fields_.Set(field, k); | |
538 } | |
539 for (int k = 0; k < klass->constructors().length(); k++) { | |
540 Constructor* constructor = klass->constructors()[k]; | |
541 constructors_.Set(constructor, k); | |
542 } | |
543 for (int k = 0; k < klass->procedures().length(); k++) { | |
544 Procedure* procedure = klass->procedures()[k]; | |
545 procedures_.Set(procedure, k); | |
546 } | |
547 } | |
548 | |
549 for (int k = 0; k < lib->fields().length(); k++) { | |
550 Field* field = lib->fields()[k]; | |
551 fields_.Set(field, k); | |
552 } | |
553 | |
554 for (int k = 0; k < lib->procedures().length(); k++) { | |
555 Procedure* procedure = lib->procedures()[k]; | |
556 procedures_.Set(procedure, k); | |
557 } | |
558 } | |
559 } | |
560 | |
561 Program* program() { return program_; } | |
562 | |
563 BlockMap<String>& strings() { return strings_; } | |
564 BlockMap<Library>& libraries() { return libraries_; } | |
565 BlockMap<Class>& classes() { return classes_; } | |
566 BlockMap<Field>& fields() { return fields_; } | |
567 BlockMap<Procedure>& procedures() { return procedures_; } | |
568 BlockMap<Constructor>& constructors() { return constructors_; } | |
569 | |
570 BlockMap<VariableDeclaration>& variables() { return scope_; } | |
571 BlockMap<TypeParameter>& type_parameters() { return type_parameters_; } | |
572 BlockMap<LabeledStatement>& lables() { return labels_; } | |
573 BlockMap<SwitchCase>& switch_cases() { return switch_cases_; } | |
574 | |
575 private: | |
576 Program* program_; | |
577 | |
578 BlockMap<String> strings_; | |
579 BlockMap<Library> libraries_; | |
580 BlockMap<Class> classes_; | |
581 BlockMap<Field> fields_; | |
582 BlockMap<Procedure> procedures_; | |
583 BlockMap<Constructor> constructors_; | |
584 | |
585 BlockMap<VariableDeclaration> scope_; | |
586 BlockMap<TypeParameter> type_parameters_; | |
587 BlockMap<LabeledStatement> labels_; | |
588 BlockMap<SwitchCase> switch_cases_; | |
589 }; | |
590 | |
591 | |
592 class Writer { | |
593 public: | |
594 explicit Writer(OutputFile* file) : out_(file), offset_(0) {} | |
595 | |
596 void WriteUInt32(uint32_t value) { | |
597 uint8_t buffer[4] = { | |
598 static_cast<uint8_t>((value >> 24) & 0xff), | |
599 static_cast<uint8_t>((value >> 16) & 0xff), | |
600 static_cast<uint8_t>((value >> 8) & 0xff), | |
601 static_cast<uint8_t>((value >> 0) & 0xff), | |
602 }; | |
603 WriteBytes(buffer, 4); | |
604 } | |
605 | |
606 void WriteUInt(uint32_t value) { | |
607 if (value < 0x80) { | |
608 // 0... | |
609 WriteByte(static_cast<uint8_t>(value)); | |
610 } else if (value < 0x4000) { | |
611 // 10... | |
612 WriteByte(static_cast<uint8_t>(((value >> 8) & 0x3f) | 0x80)); | |
613 WriteByte(static_cast<uint8_t>(value & 0xff)); | |
614 } else { | |
615 // 11... | |
616 // Ensure the highest 2 bits is not used for anything (we use it to for | |
617 // encoding). | |
618 ASSERT(static_cast<uint8_t>((value >> 24) & 0xc0) == 0); | |
619 uint8_t buffer[4] = { | |
620 static_cast<uint8_t>(((value >> 24) & 0x7f) | 0xc0), | |
621 static_cast<uint8_t>((value >> 16) & 0xff), | |
622 static_cast<uint8_t>((value >> 8) & 0xff), | |
623 static_cast<uint8_t>((value >> 0) & 0xff), | |
624 }; | |
625 WriteBytes(buffer, 4); | |
626 } | |
627 } | |
628 | |
629 void WriteListLength(intptr_t value) { return WriteUInt(value); } | |
630 | |
631 void WriteByte(uint8_t value) { | |
632 out_->WriteByte(value); | |
633 offset_++; | |
634 } | |
635 | |
636 void WriteBool(bool value) { WriteByte(value ? 1 : 0); } | |
637 | |
638 void WriteFlags(uint8_t value) { WriteByte(value); } | |
639 | |
640 void WriteTag(Tag tag) { WriteByte(static_cast<uint8_t>(tag)); } | |
641 | |
642 void WriteTag(Tag tag, uint8_t payload) { | |
643 ASSERT((payload & ~kSpecializedPayloadMask) == 0); | |
644 WriteByte(kSpecializedTagHighBit | static_cast<uint8_t>(tag) | payload); | |
645 } | |
646 | |
647 void WriteBytes(uint8_t* bytes, int length) { | |
648 out_->WriteBytes(bytes, length); | |
649 offset_ += length; | |
650 } | |
651 | |
652 template <typename T> | |
653 void WriteOptional(T* object) { | |
654 if (object == NULL) { | |
655 WriteTag(kNothing); | |
656 } else { | |
657 WriteTag(kSomething); | |
658 object->WriteTo(this); | |
659 } | |
660 } | |
661 | |
662 template <typename T, typename WT> | |
663 void WriteOptionalStatic(T* object) { | |
664 if (object == NULL) { | |
665 WriteTag(kNothing); | |
666 } else { | |
667 WriteTag(kSomething); | |
668 WT::WriteTo(this, object); | |
669 } | |
670 } | |
671 | |
672 template <typename T> | |
673 void WriteOptionalStatic(T* object) { | |
674 return WriteOptionalStatic<T, T>(object); | |
675 } | |
676 | |
677 void DumpOffset(const char* str) { | |
678 fprintf(stderr, "@%ld %s\n", offset_, str); | |
rmacnak
2016/10/13 00:56:39
OS::PrintErr
Vyacheslav Egorov (Google)
2016/10/13 14:37:58
Done.
| |
679 } | |
680 | |
681 WriterHelper* helper() { return &helper_; } | |
682 | |
683 void Flush() { out_->Flush(); } | |
684 | |
685 private: | |
686 OutputFile* out_; | |
687 WriterHelper helper_; | |
688 int64_t offset_; | |
689 }; | |
690 | |
691 | |
692 template <typename T> | |
693 template <typename IT> | |
694 void List<T>::ReadFrom(Reader* reader, TreeNode* parent) { | |
695 TRACE_READ_OFFSET(); | |
696 ASSERT(parent != NULL); | |
697 int length = reader->ReadListLength(); | |
698 EnsureInitialized(length); | |
699 | |
700 for (int i = 0; i < length_; i++) { | |
701 IT* object = GetOrCreate<IT>(i, parent); | |
702 object->ReadFrom(reader); | |
703 } | |
704 } | |
705 | |
706 | |
707 template <typename T> | |
708 template <typename IT> | |
709 void List<T>::ReadFrom(Reader* reader) { | |
710 TRACE_READ_OFFSET(); | |
711 int length = reader->ReadListLength(); | |
712 EnsureInitialized(length); | |
713 | |
714 for (int i = 0; i < length_; i++) { | |
715 GetOrCreate<IT>(i)->ReadFrom(reader); | |
716 } | |
717 } | |
718 | |
719 | |
720 template <typename T> | |
721 template <typename IT> | |
722 void List<T>::ReadFromStatic(Reader* reader) { | |
723 TRACE_READ_OFFSET(); | |
724 int length = reader->ReadListLength(); | |
725 EnsureInitialized(length); | |
726 | |
727 for (int i = 0; i < length_; i++) { | |
728 ASSERT(array_[i] == NULL); | |
729 array_[i] = IT::ReadFrom(reader); | |
730 } | |
731 } | |
732 | |
733 | |
734 template <typename T> | |
735 void List<T>::WriteTo(Writer* writer) { | |
736 TRACE_WRITE_OFFSET(); | |
737 | |
738 // NOTE: We only support dense lists. | |
739 writer->WriteListLength(length_); | |
740 for (int i = 0; i < length_; i++) { | |
741 T* object = array_[i]; | |
742 ASSERT(object != NULL); | |
743 object->WriteTo(writer); | |
744 } | |
745 } | |
746 | |
747 | |
748 template <typename T> | |
749 template <typename IT> | |
750 void List<T>::WriteToStatic(Writer* writer) { | |
751 TRACE_WRITE_OFFSET(); | |
752 | |
753 // NOTE: We only support dense lists. | |
754 writer->WriteListLength(length_); | |
755 for (int i = 0; i < length_; i++) { | |
756 T* object = array_[i]; | |
757 ASSERT(object != NULL); | |
758 IT::WriteTo(writer, object); | |
759 } | |
760 } | |
761 | |
762 | |
763 void TypeParameterList::ReadFrom(Reader* reader) { | |
764 // It is possible for the bound of the first type parameter to refer to | |
765 // the second type parameter. This means we need to create [TypeParameter] | |
766 // objects before reading the bounds. | |
767 int length = reader->ReadListLength(); | |
768 EnsureInitialized(length); | |
769 | |
770 // Make all [TypeParameter]s available in scope. | |
771 for (int i = 0; i < length; i++) { | |
772 TypeParameter* parameter = (*this)[i] = new TypeParameter(); | |
773 reader->helper()->type_parameters().Push(parameter); | |
774 } | |
775 | |
776 // Read all [TypeParameter]s and their bounds. | |
777 for (int i = 0; i < length; i++) { | |
778 (*this)[i]->ReadFrom(reader); | |
779 } | |
780 } | |
781 | |
782 | |
783 void TypeParameterList::WriteTo(Writer* writer) { | |
784 writer->WriteListLength(length()); | |
785 | |
786 // Make all [TypeParameter]s available in scope. | |
787 for (int i = 0; i < length(); i++) { | |
788 TypeParameter* parameter = (*this)[i]; | |
789 writer->helper()->type_parameters().Push(parameter); | |
790 } | |
791 | |
792 // Write all [TypeParameter]s and their bounds. | |
793 for (int i = 0; i < length(); i++) { | |
794 TypeParameter* parameter = (*this)[i]; | |
795 parameter->WriteTo(writer); | |
796 } | |
797 } | |
798 | |
799 | |
800 template <typename A, typename B> | |
801 Tuple<A, B>* Tuple<A, B>::ReadFrom(Reader* reader) { | |
802 TRACE_READ_OFFSET(); | |
803 A* first = A::ReadFrom(reader); | |
804 B* second = B::ReadFrom(reader); | |
805 return new Tuple<A, B>(first, second); | |
806 } | |
807 | |
808 | |
809 template <typename A, typename B> | |
810 void Tuple<A, B>::WriteTo(Writer* writer) { | |
811 TRACE_WRITE_OFFSET(); | |
812 first_->WriteTo(writer); | |
813 second_->WriteTo(writer); | |
814 } | |
815 | |
816 | |
817 template <typename B, typename S> | |
818 class DowncastReader { | |
819 public: | |
820 static S* ReadFrom(Reader* reader) { | |
821 TRACE_READ_OFFSET(); | |
822 return S::Cast(B::ReadFrom(reader)); | |
823 } | |
824 }; | |
825 | |
826 | |
827 class StringImpl { | |
828 public: | |
829 static String* ReadFrom(Reader* reader) { | |
830 TRACE_READ_OFFSET(); | |
831 return String::ReadFromImpl(reader); | |
832 } | |
833 | |
834 static void WriteTo(Writer* writer, String* string) { | |
835 TRACE_WRITE_OFFSET(); | |
836 string->WriteToImpl(writer); | |
837 } | |
838 }; | |
839 | |
840 | |
841 class VariableDeclarationImpl { | |
842 public: | |
843 static VariableDeclaration* ReadFrom(Reader* reader) { | |
844 TRACE_READ_OFFSET(); | |
845 return VariableDeclaration::ReadFromImpl(reader); | |
846 } | |
847 | |
848 static void WriteTo(Writer* writer, VariableDeclaration* d) { | |
849 TRACE_WRITE_OFFSET(); | |
850 d->WriteToImpl(writer); | |
851 } | |
852 }; | |
853 | |
854 | |
855 String* String::ReadFrom(Reader* reader) { | |
856 TRACE_READ_OFFSET(); | |
857 return Reference::ReadStringFrom(reader); | |
858 } | |
859 | |
860 | |
861 String* String::ReadFromImpl(Reader* reader) { | |
862 TRACE_READ_OFFSET(); | |
863 uint32_t bytes = reader->ReadUInt(); | |
864 String* string = new String(reader->Consume(bytes), bytes); | |
865 return string; | |
866 } | |
867 | |
868 | |
869 void String::WriteTo(Writer* writer) { | |
870 TRACE_WRITE_OFFSET(); | |
871 Reference::WriteStringTo(writer, this); | |
872 } | |
873 | |
874 | |
875 void String::WriteToImpl(Writer* writer) { | |
876 TRACE_WRITE_OFFSET(); | |
877 writer->WriteUInt(size_); | |
878 writer->WriteBytes(buffer_, size_); | |
879 } | |
880 | |
881 | |
882 void StringTable::ReadFrom(Reader* reader) { | |
883 strings_.ReadFromStatic<StringImpl>(reader); | |
884 } | |
885 | |
886 | |
887 void StringTable::WriteTo(Writer* writer) { | |
888 strings_.WriteToStatic<StringImpl>(writer); | |
889 | |
890 // Build up the "String* -> index" table. | |
891 WriterHelper* helper = writer->helper(); | |
892 for (int i = 0; i < strings_.length(); i++) { | |
893 helper->strings().Push(strings_[i]); | |
894 } | |
895 } | |
896 | |
897 | |
898 void LineStartingTable::ReadFrom(Reader* reader, intptr_t length) { | |
899 size_ = length; | |
900 values_ = new intptr_t*[size_]; | |
901 for (intptr_t i = 0; i < size_; ++i) { | |
902 intptr_t line_count = reader->ReadUInt(); | |
903 intptr_t* line_starts = new intptr_t[line_count + 1]; | |
904 line_starts[0] = line_count; | |
905 intptr_t previous_line_start = 0; | |
906 for (intptr_t j = 0; j < line_count; ++j) { | |
907 intptr_t lineStart = reader->ReadUInt() + previous_line_start; | |
908 line_starts[j + 1] = lineStart; | |
909 previous_line_start = lineStart; | |
910 } | |
911 values_[i] = line_starts; | |
912 } | |
913 } | |
914 | |
915 | |
916 void LineStartingTable::WriteTo(Writer* writer) { | |
917 for (intptr_t i = 0; i < size_; ++i) { | |
918 intptr_t* line_starts = values_[i]; | |
919 intptr_t line_count = line_starts[0]; | |
920 writer->WriteUInt(line_count); | |
921 | |
922 intptr_t previous_line_start = 0; | |
923 for (intptr_t j = 0; j < line_count; ++j) { | |
924 intptr_t line_start = line_starts[j + 1]; | |
925 writer->WriteUInt(line_start - previous_line_start); | |
926 previous_line_start = line_start; | |
927 } | |
928 } | |
929 } | |
930 | |
931 | |
932 Library* Library::ReadFrom(Reader* reader) { | |
933 TRACE_READ_OFFSET(); | |
934 int flags = reader->ReadFlags(); | |
935 ASSERT(flags == 0); // external libraries not supported | |
936 name_ = Reference::ReadStringFrom(reader); | |
937 import_uri_ = Reference::ReadStringFrom(reader); | |
938 reader->ReadUInt(); // TODO(jensj): source_uri_index | |
939 | |
940 int num_classes = reader->ReadUInt(); | |
941 classes().EnsureInitialized(num_classes); | |
942 for (int i = 0; i < num_classes; i++) { | |
943 Tag tag = reader->ReadTag(); | |
944 if (tag == kNormalClass) { | |
945 NormalClass* klass = classes().GetOrCreate<NormalClass>(i, this); | |
946 klass->ReadFrom(reader); | |
947 } else { | |
948 ASSERT(tag == kMixinClass); | |
949 MixinClass* klass = classes().GetOrCreate<MixinClass>(i, this); | |
950 klass->ReadFrom(reader); | |
951 } | |
952 } | |
953 | |
954 fields().ReadFrom<Field>(reader, this); | |
955 procedures().ReadFrom<Procedure>(reader, this); | |
956 return this; | |
957 } | |
958 | |
959 | |
960 void Library::WriteTo(Writer* writer) { | |
961 TRACE_WRITE_OFFSET(); | |
962 name_->WriteTo(writer); | |
963 import_uri_->WriteTo(writer); | |
964 writer->WriteUInt(0); // TODO(jensj): source_uri_index | |
965 | |
966 writer->WriteUInt(classes_.length()); | |
967 for (int i = 0; i < classes_.length(); i++) { | |
968 Class* klass = classes_[i]; | |
969 if (klass->IsNormalClass()) { | |
970 writer->WriteTag(kNormalClass); | |
971 NormalClass::Cast(klass)->WriteTo(writer); | |
972 } else { | |
973 writer->WriteTag(kMixinClass); | |
974 MixinClass::Cast(klass)->WriteTo(writer); | |
975 } | |
976 } | |
977 fields().WriteTo(writer); | |
978 procedures().WriteTo(writer); | |
979 } | |
980 | |
981 | |
982 Class* Class::ReadFrom(Reader* reader) { | |
983 TRACE_READ_OFFSET(); | |
984 | |
985 is_abstract_ = reader->ReadBool(); | |
986 name_ = Reference::ReadStringFrom(reader); | |
987 reader->ReadUInt(); // TODO(jensj): source_uri_index | |
988 annotations_.ReadFromStatic<Expression>(reader); | |
989 | |
990 return this; | |
991 } | |
992 | |
993 | |
994 void Class::WriteTo(Writer* writer) { | |
995 TRACE_WRITE_OFFSET(); | |
996 writer->WriteBool(is_abstract_); | |
997 name_->WriteTo(writer); | |
998 writer->WriteUInt(0); // TODO(jensj): source_uri_index | |
999 annotations_.WriteTo(writer); | |
1000 } | |
1001 | |
1002 | |
1003 NormalClass* NormalClass::ReadFrom(Reader* reader) { | |
1004 TRACE_READ_OFFSET(); | |
1005 Class::ReadFrom(reader); | |
1006 TypeParameterScope<ReaderHelper> scope(reader->helper()); | |
1007 | |
1008 type_parameters_.ReadFrom(reader); | |
1009 DartType* type = reader->ReadOptional<DartType>(); | |
1010 | |
1011 super_class_ = InterfaceType::Cast(type); | |
1012 implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >( | |
1013 reader); | |
1014 fields_.ReadFrom<Field>(reader, this); | |
1015 constructors_.ReadFrom<Constructor>(reader, this); | |
1016 procedures_.ReadFrom<Procedure>(reader, this); | |
1017 | |
1018 return this; | |
1019 } | |
1020 | |
1021 | |
1022 void NormalClass::WriteTo(Writer* writer) { | |
1023 TRACE_WRITE_OFFSET(); | |
1024 Class::WriteTo(writer); | |
1025 TypeParameterScope<WriterHelper> scope(writer->helper()); | |
1026 | |
1027 type_parameters().WriteTo(writer); | |
1028 writer->WriteOptional<DartType>(super_class_); | |
1029 implemented_classes().WriteTo(writer); | |
1030 fields_.WriteTo(writer); | |
1031 constructors_.WriteTo(writer); | |
1032 procedures_.WriteTo(writer); | |
1033 } | |
1034 | |
1035 | |
1036 MixinClass* MixinClass::ReadFrom(Reader* reader) { | |
1037 TRACE_READ_OFFSET(); | |
1038 TypeParameterScope<ReaderHelper> scope(reader->helper()); | |
1039 | |
1040 Class::ReadFrom(reader); | |
1041 type_parameters_.ReadFrom(reader); | |
1042 first_ = InterfaceType::Cast(DartType::ReadFrom(reader)); | |
1043 second_ = InterfaceType::Cast(DartType::ReadFrom(reader)); | |
1044 implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >( | |
1045 reader); | |
1046 constructors_.ReadFrom<Constructor>(reader, this); | |
1047 return this; | |
1048 } | |
1049 | |
1050 | |
1051 void MixinClass::WriteTo(Writer* writer) { | |
1052 TRACE_WRITE_OFFSET(); | |
1053 TypeParameterScope<WriterHelper> scope(writer->helper()); | |
1054 | |
1055 Class::WriteTo(writer); | |
1056 type_parameters_.WriteTo(writer); | |
1057 first_->WriteTo(writer); | |
1058 second_->WriteTo(writer); | |
1059 implemented_classes_.WriteTo(writer); | |
1060 constructors_.WriteTo(writer); | |
1061 } | |
1062 | |
1063 | |
1064 Member* Reference::ReadMemberFrom(Reader* reader, bool allow_null) { | |
1065 TRACE_READ_OFFSET(); | |
1066 | |
1067 Program* program = reader->helper()->program(); | |
1068 Tag tag = reader->ReadTag(); | |
1069 switch (tag) { | |
1070 case kLibraryFieldReference: { | |
1071 int library_idx = reader->ReadUInt(); | |
1072 int field_idx = reader->ReadUInt(); | |
1073 Library* library = program->libraries().GetOrCreate<Library>(library_idx); | |
1074 return library->fields().GetOrCreate<Field>(field_idx, library); | |
1075 } | |
1076 case kLibraryProcedureReference: { | |
1077 int library_idx = reader->ReadUInt(); | |
1078 int procedure_idx = reader->ReadUInt(); | |
1079 Library* library = program->libraries().GetOrCreate<Library>(library_idx); | |
1080 return library->procedures().GetOrCreate<Procedure>(procedure_idx, | |
1081 library); | |
1082 } | |
1083 case kClassFieldReference: | |
1084 case kClassConstructorReference: | |
1085 case kClassProcedureReference: { | |
1086 Class* klass = Reference::ReadClassFrom(reader); | |
1087 if (tag == kClassFieldReference) { | |
1088 int field_idx = reader->ReadUInt(); | |
1089 return klass->fields().GetOrCreate<Field>(field_idx, klass); | |
1090 } else if (tag == kClassConstructorReference) { | |
1091 int constructor_idx = reader->ReadUInt(); | |
1092 return klass->constructors().GetOrCreate<Constructor>(constructor_idx, | |
1093 klass); | |
1094 } else { | |
1095 ASSERT(tag == kClassProcedureReference); | |
1096 int procedure_idx = reader->ReadUInt(); | |
1097 return klass->procedures().GetOrCreate<Procedure>(procedure_idx, klass); | |
1098 } | |
1099 } | |
1100 case kNullReference: | |
1101 if (allow_null) { | |
1102 return NULL; | |
1103 } else { | |
1104 FATAL("Expected a valid member reference, but got `null`"); | |
1105 } | |
1106 default: | |
1107 UNREACHABLE(); | |
1108 break; | |
1109 } | |
1110 | |
1111 UNREACHABLE(); | |
1112 return NULL; | |
1113 } | |
1114 | |
1115 | |
1116 void Reference::WriteMemberTo(Writer* writer, Member* member, bool allow_null) { | |
1117 TRACE_WRITE_OFFSET(); | |
1118 if (member == NULL) { | |
1119 if (allow_null) { | |
1120 writer->WriteTag(kNullReference); | |
1121 return; | |
1122 } else { | |
1123 FATAL("Expected a valid member reference but got `null`"); | |
1124 } | |
1125 } | |
1126 TreeNode* node = member->parent(); | |
1127 | |
1128 WriterHelper* helper = writer->helper(); | |
1129 | |
1130 if (node->IsLibrary()) { | |
1131 Library* library = Library::Cast(node); | |
1132 if (member->IsField()) { | |
1133 Field* field = Field::Cast(member); | |
1134 writer->WriteTag(kLibraryFieldReference); | |
1135 writer->WriteUInt(helper->libraries().Lookup(library)); | |
1136 writer->WriteUInt(helper->fields().Lookup(field)); | |
1137 } else { | |
1138 Procedure* procedure = Procedure::Cast(member); | |
1139 writer->WriteTag(kLibraryProcedureReference); | |
1140 writer->WriteUInt(helper->libraries().Lookup(library)); | |
1141 writer->WriteUInt(helper->procedures().Lookup(procedure)); | |
1142 } | |
1143 } else { | |
1144 Class* klass = Class::Cast(node); | |
1145 | |
1146 if (member->IsField()) { | |
1147 Field* field = Field::Cast(member); | |
1148 writer->WriteTag(kClassFieldReference); | |
1149 Reference::WriteClassTo(writer, klass); | |
1150 writer->WriteUInt(helper->fields().Lookup(field)); | |
1151 } else if (member->IsConstructor()) { | |
1152 Constructor* constructor = Constructor::Cast(member); | |
1153 writer->WriteTag(kClassConstructorReference); | |
1154 Reference::WriteClassTo(writer, klass); | |
1155 writer->WriteUInt(helper->constructors().Lookup(constructor)); | |
1156 } else { | |
1157 Procedure* procedure = Procedure::Cast(member); | |
1158 writer->WriteTag(kClassProcedureReference); | |
1159 Reference::WriteClassTo(writer, klass); | |
1160 writer->WriteUInt(helper->procedures().Lookup(procedure)); | |
1161 } | |
1162 } | |
1163 } | |
1164 | |
1165 | |
1166 Class* Reference::ReadClassFrom(Reader* reader, bool allow_null) { | |
1167 TRACE_READ_OFFSET(); | |
1168 Program* program = reader->helper()->program(); | |
1169 | |
1170 Tag klass_member_tag = reader->ReadTag(); | |
1171 if (klass_member_tag == kNullReference) { | |
1172 if (allow_null) { | |
1173 return NULL; | |
1174 } else { | |
1175 FATAL("Expected a valid class reference but got `null`."); | |
1176 } | |
1177 } | |
1178 int library_idx = reader->ReadUInt(); | |
1179 int class_idx = reader->ReadUInt(); | |
1180 | |
1181 Library* library = program->libraries().GetOrCreate<Library>(library_idx); | |
1182 Class* klass; | |
1183 if (klass_member_tag == kNormalClassReference) { | |
1184 klass = library->classes().GetOrCreate<NormalClass>(class_idx, library); | |
1185 } else { | |
1186 ASSERT(klass_member_tag == kMixinClassReference); | |
1187 klass = library->classes().GetOrCreate<MixinClass>(class_idx, library); | |
1188 } | |
1189 return klass; | |
1190 } | |
1191 | |
1192 | |
1193 void Reference::WriteClassTo(Writer* writer, Class* klass, bool allow_null) { | |
1194 TRACE_WRITE_OFFSET(); | |
1195 if (klass == NULL) { | |
1196 if (allow_null) { | |
1197 writer->WriteTag(kNullReference); | |
1198 return; | |
1199 } else { | |
1200 FATAL("Expected a valid class reference but got `null`."); | |
1201 } | |
1202 } | |
1203 if (klass->IsNormalClass()) { | |
1204 writer->WriteTag(kNormalClassReference); | |
1205 } else { | |
1206 ASSERT(klass->IsMixinClass()); | |
1207 writer->WriteTag(kMixinClassReference); | |
1208 } | |
1209 | |
1210 writer->WriteUInt(writer->helper()->libraries().Lookup(klass->parent())); | |
1211 writer->WriteUInt(writer->helper()->classes().Lookup(klass)); | |
1212 } | |
1213 | |
1214 | |
1215 String* Reference::ReadStringFrom(Reader* reader) { | |
1216 int index = reader->ReadUInt(); | |
1217 return reader->helper()->program()->string_table().strings()[index]; | |
1218 } | |
1219 | |
1220 | |
1221 void Reference::WriteStringTo(Writer* writer, String* string) { | |
1222 int index = writer->helper()->strings().Lookup(string); | |
1223 writer->WriteUInt(index); | |
1224 } | |
1225 | |
1226 | |
1227 Field* Field::ReadFrom(Reader* reader) { | |
1228 TRACE_READ_OFFSET(); | |
1229 Tag tag = reader->ReadTag(); | |
1230 ASSERT(tag == kField); | |
1231 | |
1232 // TODO(kustermann) Do we need a variable scope here? | |
1233 reader->ReadUInt(); // TODO(jensj): offset | |
1234 flags_ = reader->ReadFlags(); | |
1235 name_ = Name::ReadFrom(reader); | |
1236 reader->ReadUInt(); // TODO(jensj): source_uri_index | |
1237 annotations_.ReadFromStatic<Expression>(reader); | |
1238 type_ = DartType::ReadFrom(reader); | |
1239 inferred_value_ = reader->ReadOptional<InferredValue>(); | |
1240 initializer_ = reader->ReadOptional<Expression>(); | |
1241 return this; | |
1242 } | |
1243 | |
1244 | |
1245 void Field::WriteTo(Writer* writer) { | |
1246 TRACE_WRITE_OFFSET(); | |
1247 writer->WriteTag(kField); | |
1248 writer->WriteUInt(0); // TODO(jensj): offset | |
1249 writer->WriteFlags(flags_); | |
1250 name_->WriteTo(writer); | |
1251 writer->WriteUInt(0); // TODO(jensj): source_uri_index | |
1252 annotations_.WriteTo(writer); | |
1253 type_->WriteTo(writer); | |
1254 writer->WriteOptional<InferredValue>(inferred_value_); | |
1255 writer->WriteOptional<Expression>(initializer_); | |
1256 } | |
1257 | |
1258 | |
1259 Constructor* Constructor::ReadFrom(Reader* reader) { | |
1260 TRACE_READ_OFFSET(); | |
1261 Tag tag = reader->ReadTag(); | |
1262 ASSERT(tag == kConstructor); | |
1263 | |
1264 VariableScope<ReaderHelper> parameters(reader->helper()); | |
1265 flags_ = reader->ReadFlags(); | |
1266 name_ = Name::ReadFrom(reader); | |
1267 annotations_.ReadFromStatic<Expression>(reader); | |
1268 function_ = FunctionNode::ReadFrom(reader); | |
1269 initializers_.ReadFromStatic<Initializer>(reader); | |
1270 return this; | |
1271 } | |
1272 | |
1273 | |
1274 void Constructor::WriteTo(Writer* writer) { | |
1275 TRACE_WRITE_OFFSET(); | |
1276 writer->WriteTag(kConstructor); | |
1277 | |
1278 VariableScope<WriterHelper> parameters(writer->helper()); | |
1279 writer->WriteFlags(flags_); | |
1280 name_->WriteTo(writer); | |
1281 annotations_.WriteTo(writer); | |
1282 function_->WriteTo(writer); | |
1283 initializers_.WriteTo(writer); | |
1284 } | |
1285 | |
1286 | |
1287 Procedure* Procedure::ReadFrom(Reader* reader) { | |
1288 TRACE_READ_OFFSET(); | |
1289 Tag tag = reader->ReadTag(); | |
1290 ASSERT(tag == kProcedure); | |
1291 | |
1292 VariableScope<ReaderHelper> parameters(reader->helper()); | |
1293 kind_ = static_cast<ProcedureKind>(reader->ReadByte()); | |
1294 flags_ = reader->ReadFlags(); | |
1295 name_ = Name::ReadFrom(reader); | |
1296 reader->ReadUInt(); // TODO(jensj): source_uri_index | |
1297 annotations_.ReadFromStatic<Expression>(reader); | |
1298 function_ = reader->ReadOptional<FunctionNode>(); | |
1299 return this; | |
1300 } | |
1301 | |
1302 | |
1303 void Procedure::WriteTo(Writer* writer) { | |
1304 TRACE_WRITE_OFFSET(); | |
1305 writer->WriteTag(kProcedure); | |
1306 | |
1307 VariableScope<WriterHelper> parameters(writer->helper()); | |
1308 writer->WriteByte(kind_); | |
1309 writer->WriteFlags(flags_); | |
1310 name_->WriteTo(writer); | |
1311 writer->WriteUInt(0); // TODO(jensj): source_uri_index | |
1312 annotations_.WriteTo(writer); | |
1313 writer->WriteOptional<FunctionNode>(function_); | |
1314 } | |
1315 | |
1316 | |
1317 Initializer* Initializer::ReadFrom(Reader* reader) { | |
1318 TRACE_READ_OFFSET(); | |
1319 Tag tag = reader->ReadTag(); | |
1320 switch (tag) { | |
1321 case kInvalidInitializer: | |
1322 return InvalidInitializer::ReadFromImpl(reader); | |
1323 case kFieldInitializer: | |
1324 return FieldInitializer::ReadFromImpl(reader); | |
1325 case kSuperInitializer: | |
1326 return SuperInitializer::ReadFromImpl(reader); | |
1327 case kRedirectingInitializer: | |
1328 return RedirectingInitializer::ReadFromImpl(reader); | |
1329 case kLocalInitializer: | |
1330 return LocalInitializer::ReadFromImpl(reader); | |
1331 default: | |
1332 UNREACHABLE(); | |
1333 } | |
1334 return NULL; | |
1335 } | |
1336 | |
1337 | |
1338 InvalidInitializer* InvalidInitializer::ReadFromImpl(Reader* reader) { | |
1339 TRACE_READ_OFFSET(); | |
1340 return new InvalidInitializer(); | |
1341 } | |
1342 | |
1343 | |
1344 void InvalidInitializer::WriteTo(Writer* writer) { | |
1345 TRACE_WRITE_OFFSET(); | |
1346 writer->WriteTag(kInvalidInitializer); | |
1347 } | |
1348 | |
1349 | |
1350 FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) { | |
1351 TRACE_READ_OFFSET(); | |
1352 FieldInitializer* initializer = new FieldInitializer(); | |
1353 initializer->field_ = Field::Cast(Reference::ReadMemberFrom(reader)); | |
1354 initializer->value_ = Expression::ReadFrom(reader); | |
1355 return initializer; | |
1356 } | |
1357 | |
1358 | |
1359 void FieldInitializer::WriteTo(Writer* writer) { | |
1360 TRACE_WRITE_OFFSET(); | |
1361 writer->WriteTag(kFieldInitializer); | |
1362 Reference::WriteMemberTo(writer, field_); | |
1363 value_->WriteTo(writer); | |
1364 } | |
1365 | |
1366 | |
1367 SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) { | |
1368 TRACE_READ_OFFSET(); | |
1369 SuperInitializer* init = new SuperInitializer(); | |
1370 init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader)); | |
1371 init->arguments_ = Arguments::ReadFrom(reader); | |
1372 return init; | |
1373 } | |
1374 | |
1375 | |
1376 void SuperInitializer::WriteTo(Writer* writer) { | |
1377 TRACE_WRITE_OFFSET(); | |
1378 writer->WriteTag(kSuperInitializer); | |
1379 Reference::WriteMemberTo(writer, target_); | |
1380 arguments_->WriteTo(writer); | |
1381 } | |
1382 | |
1383 | |
1384 RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) { | |
1385 TRACE_READ_OFFSET(); | |
1386 RedirectingInitializer* init = new RedirectingInitializer(); | |
1387 init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader)); | |
1388 init->arguments_ = Arguments::ReadFrom(reader); | |
1389 return init; | |
1390 } | |
1391 | |
1392 | |
1393 void RedirectingInitializer::WriteTo(Writer* writer) { | |
1394 TRACE_WRITE_OFFSET(); | |
1395 writer->WriteTag(kRedirectingInitializer); | |
1396 Reference::WriteMemberTo(writer, target_); | |
1397 arguments_->WriteTo(writer); | |
1398 } | |
1399 | |
1400 | |
1401 LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) { | |
1402 TRACE_READ_OFFSET(); | |
1403 LocalInitializer* init = new LocalInitializer(); | |
1404 init->variable_ = VariableDeclaration::ReadFromImpl(reader); | |
1405 return init; | |
1406 } | |
1407 | |
1408 | |
1409 void LocalInitializer::WriteTo(Writer* writer) { | |
1410 TRACE_WRITE_OFFSET(); | |
1411 writer->WriteTag(kLocalInitializer); | |
1412 variable_->WriteToImpl(writer); | |
1413 } | |
1414 | |
1415 | |
1416 Expression* Expression::ReadFrom(Reader* reader) { | |
1417 TRACE_READ_OFFSET(); | |
1418 uint8_t payload = 0; | |
1419 Tag tag = reader->ReadTag(&payload); | |
1420 switch (tag) { | |
1421 case kInvalidExpression: | |
1422 return InvalidExpression::ReadFrom(reader); | |
1423 case kVariableGet: | |
1424 return VariableGet::ReadFrom(reader); | |
1425 case kSpecializedVariableGet: | |
1426 return VariableGet::ReadFrom(reader, payload); | |
1427 case kVariableSet: | |
1428 return VariableSet::ReadFrom(reader); | |
1429 case kSpecializedVariableSet: | |
1430 return VariableSet::ReadFrom(reader, payload); | |
1431 case kPropertyGet: | |
1432 return PropertyGet::ReadFrom(reader); | |
1433 case kPropertySet: | |
1434 return PropertySet::ReadFrom(reader); | |
1435 case kDirectPropertyGet: | |
1436 return DirectPropertyGet::ReadFrom(reader); | |
1437 case kDirectPropertySet: | |
1438 return DirectPropertySet::ReadFrom(reader); | |
1439 case kStaticGet: | |
1440 return StaticGet::ReadFrom(reader); | |
1441 case kStaticSet: | |
1442 return StaticSet::ReadFrom(reader); | |
1443 case kMethodInvocation: | |
1444 return MethodInvocation::ReadFrom(reader); | |
1445 case kDirectMethodInvocation: | |
1446 return DirectMethodInvocation::ReadFrom(reader); | |
1447 case kStaticInvocation: | |
1448 return StaticInvocation::ReadFrom(reader, false); | |
1449 case kConstStaticInvocation: | |
1450 return StaticInvocation::ReadFrom(reader, true); | |
1451 case kConstructorInvocation: | |
1452 return ConstructorInvocation::ReadFrom(reader, false); | |
1453 case kConstConstructorInvocation: | |
1454 return ConstructorInvocation::ReadFrom(reader, true); | |
1455 case kNot: | |
1456 return Not::ReadFrom(reader); | |
1457 case kLogicalExpression: | |
1458 return LogicalExpression::ReadFrom(reader); | |
1459 case kConditionalExpression: | |
1460 return ConditionalExpression::ReadFrom(reader); | |
1461 case kStringConcatenation: | |
1462 return StringConcatenation::ReadFrom(reader); | |
1463 case kIsExpression: | |
1464 return IsExpression::ReadFrom(reader); | |
1465 case kAsExpression: | |
1466 return AsExpression::ReadFrom(reader); | |
1467 case kSymbolLiteral: | |
1468 return SymbolLiteral::ReadFrom(reader); | |
1469 case kTypeLiteral: | |
1470 return TypeLiteral::ReadFrom(reader); | |
1471 case kThisExpression: | |
1472 return ThisExpression::ReadFrom(reader); | |
1473 case kRethrow: | |
1474 return Rethrow::ReadFrom(reader); | |
1475 case kThrow: | |
1476 return Throw::ReadFrom(reader); | |
1477 case kListLiteral: | |
1478 return ListLiteral::ReadFrom(reader, false); | |
1479 case kConstListLiteral: | |
1480 return ListLiteral::ReadFrom(reader, true); | |
1481 case kMapLiteral: | |
1482 return MapLiteral::ReadFrom(reader, false); | |
1483 case kConstMapLiteral: | |
1484 return MapLiteral::ReadFrom(reader, true); | |
1485 case kAwaitExpression: | |
1486 return AwaitExpression::ReadFrom(reader); | |
1487 case kFunctionExpression: | |
1488 return FunctionExpression::ReadFrom(reader); | |
1489 case kLet: | |
1490 return Let::ReadFrom(reader); | |
1491 case kBlockExpression: | |
1492 return BlockExpression::ReadFrom(reader); | |
1493 case kBigIntLiteral: | |
1494 return BigintLiteral::ReadFrom(reader); | |
1495 case kStringLiteral: | |
1496 return StringLiteral::ReadFrom(reader); | |
1497 case kSpecialIntLiteral: | |
1498 return IntLiteral::ReadFrom(reader, payload); | |
1499 case kNegativeIntLiteral: | |
1500 return IntLiteral::ReadFrom(reader, true); | |
1501 case kPositiveIntLiteral: | |
1502 return IntLiteral::ReadFrom(reader, false); | |
1503 case kDoubleLiteral: | |
1504 return DoubleLiteral::ReadFrom(reader); | |
1505 case kTrueLiteral: | |
1506 return BoolLiteral::ReadFrom(reader, true); | |
1507 case kFalseLiteral: | |
1508 return BoolLiteral::ReadFrom(reader, false); | |
1509 case kNullLiteral: | |
1510 return NullLiteral::ReadFrom(reader); | |
1511 default: | |
1512 UNREACHABLE(); | |
1513 } | |
1514 return NULL; | |
1515 } | |
1516 | |
1517 | |
1518 InvalidExpression* InvalidExpression::ReadFrom(Reader* reader) { | |
1519 TRACE_READ_OFFSET(); | |
1520 return new InvalidExpression(); | |
1521 } | |
1522 | |
1523 | |
1524 void InvalidExpression::WriteTo(Writer* writer) { | |
1525 TRACE_WRITE_OFFSET(); | |
1526 writer->WriteTag(kInvalidExpression); | |
1527 } | |
1528 | |
1529 | |
1530 VariableGet* VariableGet::ReadFrom(Reader* reader) { | |
1531 TRACE_READ_OFFSET(); | |
1532 VariableGet* get = new VariableGet(); | |
1533 get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt()); | |
1534 reader->ReadOptional<DartType>(); // Unused promoted type. | |
1535 return get; | |
1536 } | |
1537 | |
1538 | |
1539 VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) { | |
1540 TRACE_READ_OFFSET(); | |
1541 VariableGet* get = new VariableGet(); | |
1542 get->variable_ = reader->helper()->variables().Lookup(payload); | |
1543 return get; | |
1544 } | |
1545 | |
1546 | |
1547 void VariableGet::WriteTo(Writer* writer) { | |
1548 TRACE_WRITE_OFFSET(); | |
1549 int index = writer->helper()->variables().Lookup(variable_); | |
1550 if ((index & kSpecializedPayloadMask) == index) { | |
1551 writer->WriteTag(kSpecializedVariableGet, static_cast<uint8_t>(index)); | |
1552 } else { | |
1553 writer->WriteTag(kVariableGet); | |
1554 writer->WriteUInt(index); | |
1555 writer->WriteOptional<DartType>(NULL); | |
1556 } | |
1557 } | |
1558 | |
1559 | |
1560 VariableSet* VariableSet::ReadFrom(Reader* reader) { | |
1561 TRACE_READ_OFFSET(); | |
1562 VariableSet* set = new VariableSet(); | |
1563 set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt()); | |
1564 set->expression_ = Expression::ReadFrom(reader); | |
1565 return set; | |
1566 } | |
1567 | |
1568 | |
1569 VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) { | |
1570 TRACE_READ_OFFSET(); | |
1571 VariableSet* set = new VariableSet(); | |
1572 set->variable_ = reader->helper()->variables().Lookup(payload); | |
1573 set->expression_ = Expression::ReadFrom(reader); | |
1574 return set; | |
1575 } | |
1576 | |
1577 | |
1578 void VariableSet::WriteTo(Writer* writer) { | |
1579 TRACE_WRITE_OFFSET(); | |
1580 int index = writer->helper()->variables().Lookup(variable_); | |
1581 if ((index & kSpecializedPayloadMask) == index) { | |
1582 writer->WriteTag(kSpecializedVariableSet, static_cast<uint8_t>(index)); | |
1583 } else { | |
1584 writer->WriteTag(kVariableSet); | |
1585 writer->WriteUInt(index); | |
1586 } | |
1587 expression_->WriteTo(writer); | |
1588 } | |
1589 | |
1590 | |
1591 PropertyGet* PropertyGet::ReadFrom(Reader* reader) { | |
1592 TRACE_READ_OFFSET(); | |
1593 PropertyGet* get = new PropertyGet(); | |
1594 reader->ReadUInt(); // TODO(jensj): offset | |
1595 get->receiver_ = Expression::ReadFrom(reader); | |
1596 get->name_ = Name::ReadFrom(reader); | |
1597 get->interfaceTarget_ = Reference::ReadMemberFrom(reader, true); | |
1598 return get; | |
1599 } | |
1600 | |
1601 | |
1602 void PropertyGet::WriteTo(Writer* writer) { | |
1603 TRACE_WRITE_OFFSET(); | |
1604 writer->WriteTag(kPropertyGet); | |
1605 writer->WriteUInt(0); // TODO(jensj): offset | |
1606 receiver_->WriteTo(writer); | |
1607 name_->WriteTo(writer); | |
1608 Reference::WriteMemberTo(writer, interfaceTarget_, true); | |
1609 } | |
1610 | |
1611 | |
1612 PropertySet* PropertySet::ReadFrom(Reader* reader) { | |
1613 TRACE_READ_OFFSET(); | |
1614 PropertySet* set = new PropertySet(); | |
1615 reader->ReadUInt(); // TODO(jensj): offset | |
1616 set->receiver_ = Expression::ReadFrom(reader); | |
1617 set->name_ = Name::ReadFrom(reader); | |
1618 set->value_ = Expression::ReadFrom(reader); | |
1619 set->interfaceTarget_ = Reference::ReadMemberFrom(reader, true); | |
1620 return set; | |
1621 } | |
1622 | |
1623 | |
1624 void PropertySet::WriteTo(Writer* writer) { | |
1625 TRACE_WRITE_OFFSET(); | |
1626 writer->WriteTag(kPropertySet); | |
1627 writer->WriteUInt(0); // TODO(jensj): offset | |
1628 receiver_->WriteTo(writer); | |
1629 name_->WriteTo(writer); | |
1630 value_->WriteTo(writer); | |
1631 Reference::WriteMemberTo(writer, interfaceTarget_, true); | |
1632 } | |
1633 | |
1634 | |
1635 DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) { | |
1636 TRACE_READ_OFFSET(); | |
1637 DirectPropertyGet* get = new DirectPropertyGet(); | |
1638 get->receiver_ = Expression::ReadFrom(reader); | |
1639 get->target_ = Reference::ReadMemberFrom(reader); | |
1640 return get; | |
1641 } | |
1642 | |
1643 | |
1644 void DirectPropertyGet::WriteTo(Writer* writer) { | |
1645 TRACE_WRITE_OFFSET(); | |
1646 writer->WriteTag(kDirectPropertyGet); | |
1647 receiver_->WriteTo(writer); | |
1648 Reference::WriteMemberTo(writer, target_); | |
1649 } | |
1650 | |
1651 | |
1652 DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) { | |
1653 TRACE_READ_OFFSET(); | |
1654 DirectPropertySet* set = new DirectPropertySet(); | |
1655 set->receiver_ = Expression::ReadFrom(reader); | |
1656 set->target_ = Reference::ReadMemberFrom(reader); | |
1657 set->value_ = Expression::ReadFrom(reader); | |
1658 return set; | |
1659 } | |
1660 | |
1661 | |
1662 void DirectPropertySet::WriteTo(Writer* writer) { | |
1663 TRACE_WRITE_OFFSET(); | |
1664 writer->WriteTag(kDirectPropertySet); | |
1665 receiver_->WriteTo(writer); | |
1666 Reference::WriteMemberTo(writer, target_); | |
1667 value_->WriteTo(writer); | |
1668 } | |
1669 | |
1670 | |
1671 StaticGet* StaticGet::ReadFrom(Reader* reader) { | |
1672 TRACE_READ_OFFSET(); | |
1673 StaticGet* get = new StaticGet(); | |
1674 reader->ReadUInt(); // TODO(jensj): offset | |
1675 get->target_ = Reference::ReadMemberFrom(reader); | |
1676 return get; | |
1677 } | |
1678 | |
1679 | |
1680 void StaticGet::WriteTo(Writer* writer) { | |
1681 TRACE_WRITE_OFFSET(); | |
1682 writer->WriteTag(kStaticGet); | |
1683 writer->WriteUInt(0); // TODO(jensj): offset | |
1684 Reference::WriteMemberTo(writer, target_); | |
1685 } | |
1686 | |
1687 | |
1688 StaticSet* StaticSet::ReadFrom(Reader* reader) { | |
1689 TRACE_READ_OFFSET(); | |
1690 StaticSet* set = new StaticSet(); | |
1691 set->target_ = Reference::ReadMemberFrom(reader); | |
1692 set->expression_ = Expression::ReadFrom(reader); | |
1693 return set; | |
1694 } | |
1695 | |
1696 | |
1697 void StaticSet::WriteTo(Writer* writer) { | |
1698 TRACE_WRITE_OFFSET(); | |
1699 writer->WriteTag(kStaticSet); | |
1700 Reference::WriteMemberTo(writer, target_); | |
1701 expression_->WriteTo(writer); | |
1702 } | |
1703 | |
1704 | |
1705 Arguments* Arguments::ReadFrom(Reader* reader) { | |
1706 TRACE_READ_OFFSET(); | |
1707 Arguments* arguments = new Arguments(); | |
1708 arguments->types().ReadFromStatic<DartType>(reader); | |
1709 arguments->positional().ReadFromStatic<Expression>(reader); | |
1710 arguments->named().ReadFromStatic<NamedExpression>(reader); | |
1711 return arguments; | |
1712 } | |
1713 | |
1714 | |
1715 void Arguments::WriteTo(Writer* writer) { | |
1716 TRACE_WRITE_OFFSET(); | |
1717 types().WriteTo(writer); | |
1718 positional().WriteTo(writer); | |
1719 named().WriteTo(writer); | |
1720 } | |
1721 | |
1722 | |
1723 NamedExpression* NamedExpression::ReadFrom(Reader* reader) { | |
1724 TRACE_READ_OFFSET(); | |
1725 String* name = Reference::ReadStringFrom(reader); | |
1726 Expression* expression = Expression::ReadFrom(reader); | |
1727 return new NamedExpression(name, expression); | |
1728 } | |
1729 | |
1730 | |
1731 void NamedExpression::WriteTo(Writer* writer) { | |
1732 TRACE_WRITE_OFFSET(); | |
1733 name_->WriteTo(writer); | |
1734 expression_->WriteTo(writer); | |
1735 } | |
1736 | |
1737 | |
1738 MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) { | |
1739 TRACE_READ_OFFSET(); | |
1740 MethodInvocation* invocation = new MethodInvocation(); | |
1741 reader->ReadUInt(); // TODO(jensj): offset | |
1742 invocation->receiver_ = Expression::ReadFrom(reader); | |
1743 invocation->name_ = Name::ReadFrom(reader); | |
1744 invocation->arguments_ = Arguments::ReadFrom(reader); | |
1745 invocation->interfaceTarget_ = Reference::ReadMemberFrom(reader, true); | |
1746 return invocation; | |
1747 } | |
1748 | |
1749 | |
1750 void MethodInvocation::WriteTo(Writer* writer) { | |
1751 TRACE_WRITE_OFFSET(); | |
1752 writer->WriteTag(kMethodInvocation); | |
1753 writer->WriteUInt(0); // TODO(jensj): offset | |
1754 receiver_->WriteTo(writer); | |
1755 name_->WriteTo(writer); | |
1756 arguments_->WriteTo(writer); | |
1757 Reference::WriteMemberTo(writer, interfaceTarget_, true); | |
1758 } | |
1759 | |
1760 | |
1761 DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) { | |
1762 TRACE_READ_OFFSET(); | |
1763 DirectMethodInvocation* invocation = new DirectMethodInvocation(); | |
1764 invocation->receiver_ = Expression::ReadFrom(reader); | |
1765 invocation->target_ = Procedure::Cast(Reference::ReadMemberFrom(reader)); | |
1766 invocation->arguments_ = Arguments::ReadFrom(reader); | |
1767 return invocation; | |
1768 } | |
1769 | |
1770 | |
1771 void DirectMethodInvocation::WriteTo(Writer* writer) { | |
1772 TRACE_WRITE_OFFSET(); | |
1773 writer->WriteTag(kDirectMethodInvocation); | |
1774 receiver_->WriteTo(writer); | |
1775 Reference::WriteMemberTo(writer, target_); | |
1776 arguments_->WriteTo(writer); | |
1777 } | |
1778 | |
1779 | |
1780 StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) { | |
1781 TRACE_READ_OFFSET(); | |
1782 | |
1783 reader->ReadUInt(); // TODO(jensj): offset | |
1784 Member* member = Reference::ReadMemberFrom(reader); | |
1785 Arguments* args = Arguments::ReadFrom(reader); | |
1786 | |
1787 return new StaticInvocation(Procedure::Cast(member), args, is_const); | |
1788 } | |
1789 | |
1790 | |
1791 void StaticInvocation::WriteTo(Writer* writer) { | |
1792 TRACE_WRITE_OFFSET(); | |
1793 writer->WriteTag(is_const_ ? kConstStaticInvocation : kStaticInvocation); | |
1794 writer->WriteUInt(0); // TODO(jensj): offset | |
1795 Reference::WriteMemberTo(writer, procedure_); | |
1796 arguments_->WriteTo(writer); | |
1797 } | |
1798 | |
1799 | |
1800 ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader, | |
1801 bool is_const) { | |
1802 TRACE_READ_OFFSET(); | |
1803 ConstructorInvocation* invocation = new ConstructorInvocation(); | |
1804 invocation->is_const_ = is_const; | |
1805 reader->ReadUInt(); // TODO(jensj): offset | |
1806 invocation->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader)); | |
1807 invocation->arguments_ = Arguments::ReadFrom(reader); | |
1808 return invocation; | |
1809 } | |
1810 | |
1811 | |
1812 void ConstructorInvocation::WriteTo(Writer* writer) { | |
1813 TRACE_WRITE_OFFSET(); | |
1814 writer->WriteTag(is_const_ ? kConstConstructorInvocation | |
1815 : kConstructorInvocation); | |
1816 writer->WriteUInt(0); // TODO(jensj): offset | |
1817 Reference::WriteMemberTo(writer, target_); | |
1818 arguments_->WriteTo(writer); | |
1819 } | |
1820 | |
1821 | |
1822 Not* Not::ReadFrom(Reader* reader) { | |
1823 TRACE_READ_OFFSET(); | |
1824 Not* n = new Not(); | |
1825 n->expression_ = Expression::ReadFrom(reader); | |
1826 return n; | |
1827 } | |
1828 | |
1829 | |
1830 void Not::WriteTo(Writer* writer) { | |
1831 TRACE_WRITE_OFFSET(); | |
1832 writer->WriteTag(kNot); | |
1833 expression_->WriteTo(writer); | |
1834 } | |
1835 | |
1836 | |
1837 LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) { | |
1838 TRACE_READ_OFFSET(); | |
1839 LogicalExpression* expr = new LogicalExpression(); | |
1840 expr->left_ = Expression::ReadFrom(reader); | |
1841 expr->operator_ = static_cast<Operator>(reader->ReadByte()); | |
1842 expr->right_ = Expression::ReadFrom(reader); | |
1843 return expr; | |
1844 } | |
1845 | |
1846 | |
1847 void LogicalExpression::WriteTo(Writer* writer) { | |
1848 TRACE_WRITE_OFFSET(); | |
1849 writer->WriteTag(kLogicalExpression); | |
1850 left_->WriteTo(writer); | |
1851 writer->WriteByte(operator_); | |
1852 right_->WriteTo(writer); | |
1853 } | |
1854 | |
1855 | |
1856 ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) { | |
1857 TRACE_READ_OFFSET(); | |
1858 ConditionalExpression* expr = new ConditionalExpression(); | |
1859 expr->condition_ = Expression::ReadFrom(reader); | |
1860 expr->then_ = Expression::ReadFrom(reader); | |
1861 expr->otherwise_ = Expression::ReadFrom(reader); | |
1862 reader->ReadOptional<DartType>(); // Unused static type. | |
1863 return expr; | |
1864 } | |
1865 | |
1866 | |
1867 void ConditionalExpression::WriteTo(Writer* writer) { | |
1868 TRACE_WRITE_OFFSET(); | |
1869 writer->WriteTag(kConditionalExpression); | |
1870 condition_->WriteTo(writer); | |
1871 then_->WriteTo(writer); | |
1872 otherwise_->WriteTo(writer); | |
1873 writer->WriteOptional<DartType>(NULL); // Unused static type. | |
1874 } | |
1875 | |
1876 | |
1877 StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) { | |
1878 TRACE_READ_OFFSET(); | |
1879 StringConcatenation* concat = new StringConcatenation(); | |
1880 concat->expressions_.ReadFromStatic<Expression>(reader); | |
1881 return concat; | |
1882 } | |
1883 | |
1884 | |
1885 void StringConcatenation::WriteTo(Writer* writer) { | |
1886 TRACE_WRITE_OFFSET(); | |
1887 writer->WriteTag(kStringConcatenation); | |
1888 expressions_.WriteTo(writer); | |
1889 } | |
1890 | |
1891 | |
1892 IsExpression* IsExpression::ReadFrom(Reader* reader) { | |
1893 TRACE_READ_OFFSET(); | |
1894 IsExpression* expr = new IsExpression(); | |
1895 expr->operand_ = Expression::ReadFrom(reader); | |
1896 expr->type_ = DartType::ReadFrom(reader); | |
1897 return expr; | |
1898 } | |
1899 | |
1900 | |
1901 void IsExpression::WriteTo(Writer* writer) { | |
1902 TRACE_WRITE_OFFSET(); | |
1903 writer->WriteTag(kIsExpression); | |
1904 operand_->WriteTo(writer); | |
1905 type_->WriteTo(writer); | |
1906 } | |
1907 | |
1908 | |
1909 AsExpression* AsExpression::ReadFrom(Reader* reader) { | |
1910 TRACE_READ_OFFSET(); | |
1911 AsExpression* expr = new AsExpression(); | |
1912 expr->operand_ = Expression::ReadFrom(reader); | |
1913 expr->type_ = DartType::ReadFrom(reader); | |
1914 return expr; | |
1915 } | |
1916 | |
1917 | |
1918 void AsExpression::WriteTo(Writer* writer) { | |
1919 TRACE_WRITE_OFFSET(); | |
1920 writer->WriteTag(kAsExpression); | |
1921 operand_->WriteTo(writer); | |
1922 type_->WriteTo(writer); | |
1923 } | |
1924 | |
1925 | |
1926 StringLiteral* StringLiteral::ReadFrom(Reader* reader) { | |
1927 TRACE_READ_OFFSET(); | |
1928 return new StringLiteral(Reference::ReadStringFrom(reader)); | |
1929 } | |
1930 | |
1931 | |
1932 void StringLiteral::WriteTo(Writer* writer) { | |
1933 TRACE_WRITE_OFFSET(); | |
1934 writer->WriteTag(kStringLiteral); | |
1935 value_->WriteTo(writer); | |
1936 } | |
1937 | |
1938 | |
1939 BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) { | |
1940 TRACE_READ_OFFSET(); | |
1941 return new BigintLiteral(Reference::ReadStringFrom(reader)); | |
1942 } | |
1943 | |
1944 | |
1945 void BigintLiteral::WriteTo(Writer* writer) { | |
1946 TRACE_WRITE_OFFSET(); | |
1947 writer->WriteTag(kBigIntLiteral); | |
1948 value_->WriteTo(writer); | |
1949 } | |
1950 | |
1951 | |
1952 IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) { | |
1953 TRACE_READ_OFFSET(); | |
1954 IntLiteral* literal = new IntLiteral(); | |
1955 literal->value_ = is_negative ? -static_cast<int64_t>(reader->ReadUInt()) | |
1956 : reader->ReadUInt(); | |
1957 return literal; | |
1958 } | |
1959 | |
1960 | |
1961 IntLiteral* IntLiteral::ReadFrom(Reader* reader, uint8_t payload) { | |
1962 TRACE_READ_OFFSET(); | |
1963 IntLiteral* literal = new IntLiteral(); | |
1964 literal->value_ = static_cast<int32_t>(payload) - SpecializedIntLiteralBias; | |
1965 return literal; | |
1966 } | |
1967 | |
1968 | |
1969 void IntLiteral::WriteTo(Writer* writer) { | |
1970 TRACE_WRITE_OFFSET(); | |
1971 int64_t payload = value_ + SpecializedIntLiteralBias; | |
1972 if ((payload & kSpecializedPayloadMask) == payload) { | |
1973 writer->WriteTag(kSpecialIntLiteral, static_cast<uint8_t>(payload)); | |
1974 } else { | |
1975 writer->WriteTag(value_ < 0 ? kNegativeIntLiteral : kPositiveIntLiteral); | |
1976 writer->WriteUInt(static_cast<uint32_t>(value_ < 0 ? -value_ : value_)); | |
1977 } | |
1978 } | |
1979 | |
1980 | |
1981 DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) { | |
1982 TRACE_READ_OFFSET(); | |
1983 DoubleLiteral* literal = new DoubleLiteral(); | |
1984 literal->value_ = Reference::ReadStringFrom(reader); | |
1985 return literal; | |
1986 } | |
1987 | |
1988 | |
1989 void DoubleLiteral::WriteTo(Writer* writer) { | |
1990 TRACE_WRITE_OFFSET(); | |
1991 writer->WriteTag(kDoubleLiteral); | |
1992 value_->WriteTo(writer); | |
1993 } | |
1994 | |
1995 | |
1996 BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) { | |
1997 TRACE_READ_OFFSET(); | |
1998 BoolLiteral* lit = new BoolLiteral(); | |
1999 lit->value_ = value; | |
2000 return lit; | |
2001 } | |
2002 | |
2003 | |
2004 void BoolLiteral::WriteTo(Writer* writer) { | |
2005 TRACE_WRITE_OFFSET(); | |
2006 writer->WriteTag(value_ ? kTrueLiteral : kFalseLiteral); | |
2007 } | |
2008 | |
2009 | |
2010 NullLiteral* NullLiteral::ReadFrom(Reader* reader) { | |
2011 TRACE_READ_OFFSET(); | |
2012 return new NullLiteral(); | |
2013 } | |
2014 | |
2015 | |
2016 void NullLiteral::WriteTo(Writer* writer) { | |
2017 TRACE_WRITE_OFFSET(); | |
2018 writer->WriteTag(kNullLiteral); | |
2019 } | |
2020 | |
2021 | |
2022 SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) { | |
2023 TRACE_READ_OFFSET(); | |
2024 SymbolLiteral* lit = new SymbolLiteral(); | |
2025 lit->value_ = Reference::ReadStringFrom(reader); | |
2026 return lit; | |
2027 } | |
2028 | |
2029 | |
2030 void SymbolLiteral::WriteTo(Writer* writer) { | |
2031 TRACE_WRITE_OFFSET(); | |
2032 writer->WriteTag(kSymbolLiteral); | |
2033 value_->WriteTo(writer); | |
2034 } | |
2035 | |
2036 | |
2037 TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) { | |
2038 TRACE_READ_OFFSET(); | |
2039 TypeLiteral* literal = new TypeLiteral(); | |
2040 literal->type_ = DartType::ReadFrom(reader); | |
2041 return literal; | |
2042 } | |
2043 | |
2044 | |
2045 void TypeLiteral::WriteTo(Writer* writer) { | |
2046 TRACE_WRITE_OFFSET(); | |
2047 writer->WriteTag(kTypeLiteral); | |
2048 type_->WriteTo(writer); | |
2049 } | |
2050 | |
2051 | |
2052 ThisExpression* ThisExpression::ReadFrom(Reader* reader) { | |
2053 TRACE_READ_OFFSET(); | |
2054 return new ThisExpression(); | |
2055 } | |
2056 | |
2057 | |
2058 void ThisExpression::WriteTo(Writer* writer) { | |
2059 TRACE_WRITE_OFFSET(); | |
2060 writer->WriteTag(kThisExpression); | |
2061 } | |
2062 | |
2063 | |
2064 Rethrow* Rethrow::ReadFrom(Reader* reader) { | |
2065 TRACE_READ_OFFSET(); | |
2066 return new Rethrow(); | |
2067 } | |
2068 | |
2069 | |
2070 void Rethrow::WriteTo(Writer* writer) { | |
2071 TRACE_WRITE_OFFSET(); | |
2072 writer->WriteTag(kRethrow); | |
2073 } | |
2074 | |
2075 | |
2076 Throw* Throw::ReadFrom(Reader* reader) { | |
2077 TRACE_READ_OFFSET(); | |
2078 Throw* t = new Throw(); | |
2079 reader->ReadUInt(); // TODO(jensj): offset | |
2080 t->expression_ = Expression::ReadFrom(reader); | |
2081 return t; | |
2082 } | |
2083 | |
2084 | |
2085 void Throw::WriteTo(Writer* writer) { | |
2086 TRACE_WRITE_OFFSET(); | |
2087 writer->WriteTag(kThrow); | |
2088 writer->WriteUInt(0); // TODO(jensj): offset | |
2089 expression_->WriteTo(writer); | |
2090 } | |
2091 | |
2092 | |
2093 ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) { | |
2094 TRACE_READ_OFFSET(); | |
2095 ListLiteral* literal = new ListLiteral(); | |
2096 literal->is_const_ = is_const; | |
2097 literal->type_ = DartType::ReadFrom(reader); | |
2098 literal->expressions_.ReadFromStatic<Expression>(reader); | |
2099 return literal; | |
2100 } | |
2101 | |
2102 | |
2103 void ListLiteral::WriteTo(Writer* writer) { | |
2104 TRACE_WRITE_OFFSET(); | |
2105 writer->WriteTag(is_const_ ? kConstListLiteral : kListLiteral); | |
2106 type_->WriteTo(writer); | |
2107 expressions_.WriteTo(writer); | |
2108 } | |
2109 | |
2110 | |
2111 MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) { | |
2112 TRACE_READ_OFFSET(); | |
2113 MapLiteral* literal = new MapLiteral(); | |
2114 literal->is_const_ = is_const; | |
2115 literal->key_type_ = DartType::ReadFrom(reader); | |
2116 literal->value_type_ = DartType::ReadFrom(reader); | |
2117 literal->entries_.ReadFromStatic<MapEntry>(reader); | |
2118 return literal; | |
2119 } | |
2120 | |
2121 | |
2122 void MapLiteral::WriteTo(Writer* writer) { | |
2123 TRACE_WRITE_OFFSET(); | |
2124 writer->WriteTag(is_const_ ? kConstMapLiteral : kMapLiteral); | |
2125 key_type_->WriteTo(writer); | |
2126 value_type_->WriteTo(writer); | |
2127 entries_.WriteTo(writer); | |
2128 } | |
2129 | |
2130 | |
2131 MapEntry* MapEntry::ReadFrom(Reader* reader) { | |
2132 MapEntry* entry = new MapEntry(); | |
2133 entry->key_ = Expression::ReadFrom(reader); | |
2134 entry->value_ = Expression::ReadFrom(reader); | |
2135 return entry; | |
2136 } | |
2137 | |
2138 | |
2139 void MapEntry::WriteTo(Writer* writer) { | |
2140 TRACE_WRITE_OFFSET(); | |
2141 key_->WriteTo(writer); | |
2142 value_->WriteTo(writer); | |
2143 } | |
2144 | |
2145 | |
2146 AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) { | |
2147 TRACE_READ_OFFSET(); | |
2148 AwaitExpression* await = new AwaitExpression(); | |
2149 await->operand_ = Expression::ReadFrom(reader); | |
2150 return await; | |
2151 } | |
2152 | |
2153 | |
2154 void AwaitExpression::WriteTo(Writer* writer) { | |
2155 TRACE_WRITE_OFFSET(); | |
2156 writer->WriteTag(kAwaitExpression); | |
2157 operand_->WriteTo(writer); | |
2158 } | |
2159 | |
2160 | |
2161 FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) { | |
2162 TRACE_READ_OFFSET(); | |
2163 VariableScope<ReaderHelper> parameters(reader->helper()); | |
2164 FunctionExpression* expr = new FunctionExpression(); | |
2165 expr->function_ = FunctionNode::ReadFrom(reader); | |
2166 return expr; | |
2167 } | |
2168 | |
2169 | |
2170 void FunctionExpression::WriteTo(Writer* writer) { | |
2171 TRACE_WRITE_OFFSET(); | |
2172 VariableScope<WriterHelper> parameters(writer->helper()); | |
2173 writer->WriteTag(kFunctionExpression); | |
2174 function_->WriteTo(writer); | |
2175 } | |
2176 | |
2177 | |
2178 Let* Let::ReadFrom(Reader* reader) { | |
2179 TRACE_READ_OFFSET(); | |
2180 VariableScope<ReaderHelper> vars(reader->helper()); | |
2181 Let* let = new Let(); | |
2182 let->variable_ = VariableDeclaration::ReadFromImpl(reader); | |
2183 let->body_ = Expression::ReadFrom(reader); | |
2184 return let; | |
2185 } | |
2186 | |
2187 | |
2188 void Let::WriteTo(Writer* writer) { | |
2189 TRACE_WRITE_OFFSET(); | |
2190 VariableScope<WriterHelper> vars(writer->helper()); | |
2191 writer->WriteTag(kLet); | |
2192 variable_->WriteToImpl(writer); | |
2193 body_->WriteTo(writer); | |
2194 } | |
2195 | |
2196 | |
2197 BlockExpression* BlockExpression::ReadFrom(Reader* reader) { | |
2198 TRACE_READ_OFFSET(); | |
2199 BlockExpression* be = new BlockExpression(); | |
2200 be->body_ = Block::ReadFromImpl(reader); | |
2201 be->value_ = Expression::ReadFrom(reader); | |
2202 return be; | |
2203 } | |
2204 | |
2205 | |
2206 void BlockExpression::WriteTo(Writer* writer) { | |
2207 TRACE_WRITE_OFFSET(); | |
2208 writer->WriteTag(kBlockExpression); | |
2209 body_->WriteToImpl(writer); | |
2210 value_->WriteTo(writer); | |
2211 } | |
2212 | |
2213 | |
2214 Statement* Statement::ReadFrom(Reader* reader) { | |
2215 TRACE_READ_OFFSET(); | |
2216 Tag tag = reader->ReadTag(); | |
2217 switch (tag) { | |
2218 case kInvalidStatement: | |
2219 return InvalidStatement::ReadFrom(reader); | |
2220 case kExpressionStatement: | |
2221 return ExpressionStatement::ReadFrom(reader); | |
2222 case kBlock: | |
2223 return Block::ReadFromImpl(reader); | |
2224 case kEmptyStatement: | |
2225 return EmptyStatement::ReadFrom(reader); | |
2226 case kAssertStatement: | |
2227 return AssertStatement::ReadFrom(reader); | |
2228 case kLabeledStatement: | |
2229 return LabeledStatement::ReadFrom(reader); | |
2230 case kBreakStatement: | |
2231 return BreakStatement::ReadFrom(reader); | |
2232 case kWhileStatement: | |
2233 return WhileStatement::ReadFrom(reader); | |
2234 case kDoStatement: | |
2235 return DoStatement::ReadFrom(reader); | |
2236 case kForStatement: | |
2237 return ForStatement::ReadFrom(reader); | |
2238 case kForInStatement: | |
2239 return ForInStatement::ReadFrom(reader, false); | |
2240 case kAsyncForInStatement: | |
2241 return ForInStatement::ReadFrom(reader, true); | |
2242 case kSwitchStatement: | |
2243 return SwitchStatement::ReadFrom(reader); | |
2244 case kContinueSwitchStatement: | |
2245 return ContinueSwitchStatement::ReadFrom(reader); | |
2246 case kIfStatement: | |
2247 return IfStatement::ReadFrom(reader); | |
2248 case kReturnStatement: | |
2249 return ReturnStatement::ReadFrom(reader); | |
2250 case kTryCatch: | |
2251 return TryCatch::ReadFrom(reader); | |
2252 case kTryFinally: | |
2253 return TryFinally::ReadFrom(reader); | |
2254 case kYieldStatement: | |
2255 return YieldStatement::ReadFrom(reader); | |
2256 case kVariableDeclaration: | |
2257 return VariableDeclaration::ReadFromImpl(reader); | |
2258 case kFunctionDeclaration: | |
2259 return FunctionDeclaration::ReadFrom(reader); | |
2260 default: | |
2261 UNREACHABLE(); | |
2262 } | |
2263 return NULL; | |
2264 } | |
2265 | |
2266 | |
2267 InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) { | |
2268 TRACE_READ_OFFSET(); | |
2269 return new InvalidStatement(); | |
2270 } | |
2271 | |
2272 | |
2273 void InvalidStatement::WriteTo(Writer* writer) { | |
2274 TRACE_WRITE_OFFSET(); | |
2275 writer->WriteTag(kInvalidStatement); | |
2276 } | |
2277 | |
2278 | |
2279 ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) { | |
2280 TRACE_READ_OFFSET(); | |
2281 return new ExpressionStatement(Expression::ReadFrom(reader)); | |
2282 } | |
2283 | |
2284 | |
2285 void ExpressionStatement::WriteTo(Writer* writer) { | |
2286 TRACE_WRITE_OFFSET(); | |
2287 writer->WriteTag(kExpressionStatement); | |
2288 expression_->WriteTo(writer); | |
2289 } | |
2290 | |
2291 | |
2292 Block* Block::ReadFromImpl(Reader* reader) { | |
2293 TRACE_READ_OFFSET(); | |
2294 VariableScope<ReaderHelper> vars(reader->helper()); | |
2295 Block* block = new Block(); | |
2296 block->statements().ReadFromStatic<Statement>(reader); | |
2297 return block; | |
2298 } | |
2299 | |
2300 | |
2301 void Block::WriteTo(Writer* writer) { | |
2302 writer->WriteTag(kBlock); | |
2303 WriteToImpl(writer); | |
2304 } | |
2305 | |
2306 | |
2307 void Block::WriteToImpl(Writer* writer) { | |
2308 TRACE_WRITE_OFFSET(); | |
2309 VariableScope<WriterHelper> vars(writer->helper()); | |
2310 statements_.WriteTo(writer); | |
2311 } | |
2312 | |
2313 | |
2314 EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) { | |
2315 TRACE_READ_OFFSET(); | |
2316 return new EmptyStatement(); | |
2317 } | |
2318 | |
2319 | |
2320 void EmptyStatement::WriteTo(Writer* writer) { | |
2321 TRACE_WRITE_OFFSET(); | |
2322 writer->WriteTag(kEmptyStatement); | |
2323 } | |
2324 | |
2325 | |
2326 AssertStatement* AssertStatement::ReadFrom(Reader* reader) { | |
2327 TRACE_READ_OFFSET(); | |
2328 AssertStatement* stmt = new AssertStatement(); | |
2329 stmt->condition_ = Expression::ReadFrom(reader); | |
2330 stmt->message_ = reader->ReadOptional<Expression>(); | |
2331 return stmt; | |
2332 } | |
2333 | |
2334 | |
2335 void AssertStatement::WriteTo(Writer* writer) { | |
2336 TRACE_WRITE_OFFSET(); | |
2337 writer->WriteTag(kAssertStatement); | |
2338 condition_->WriteTo(writer); | |
2339 writer->WriteOptional<Expression>(message_); | |
2340 } | |
2341 | |
2342 | |
2343 LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) { | |
2344 TRACE_READ_OFFSET(); | |
2345 LabeledStatement* stmt = new LabeledStatement(); | |
2346 reader->helper()->lables().Push(stmt); | |
2347 stmt->body_ = Statement::ReadFrom(reader); | |
2348 reader->helper()->lables().Pop(stmt); | |
2349 return stmt; | |
2350 } | |
2351 | |
2352 | |
2353 void LabeledStatement::WriteTo(Writer* writer) { | |
2354 TRACE_WRITE_OFFSET(); | |
2355 writer->WriteTag(kLabeledStatement); | |
2356 writer->helper()->lables().Push(this); | |
2357 body_->WriteTo(writer); | |
2358 writer->helper()->lables().Pop(this); | |
2359 } | |
2360 | |
2361 | |
2362 BreakStatement* BreakStatement::ReadFrom(Reader* reader) { | |
2363 TRACE_READ_OFFSET(); | |
2364 BreakStatement* stmt = new BreakStatement(); | |
2365 stmt->target_ = reader->helper()->lables().Lookup(reader->ReadUInt()); | |
2366 return stmt; | |
2367 } | |
2368 | |
2369 | |
2370 void BreakStatement::WriteTo(Writer* writer) { | |
2371 TRACE_WRITE_OFFSET(); | |
2372 writer->WriteTag(kBreakStatement); | |
2373 writer->WriteUInt(writer->helper()->lables().Lookup(target_)); | |
2374 } | |
2375 | |
2376 | |
2377 WhileStatement* WhileStatement::ReadFrom(Reader* reader) { | |
2378 TRACE_READ_OFFSET(); | |
2379 WhileStatement* stmt = new WhileStatement(); | |
2380 stmt->condition_ = Expression::ReadFrom(reader); | |
2381 stmt->body_ = Statement::ReadFrom(reader); | |
2382 return stmt; | |
2383 } | |
2384 | |
2385 | |
2386 void WhileStatement::WriteTo(Writer* writer) { | |
2387 TRACE_WRITE_OFFSET(); | |
2388 writer->WriteTag(kWhileStatement); | |
2389 condition_->WriteTo(writer); | |
2390 body_->WriteTo(writer); | |
2391 } | |
2392 | |
2393 | |
2394 DoStatement* DoStatement::ReadFrom(Reader* reader) { | |
2395 TRACE_READ_OFFSET(); | |
2396 DoStatement* dostmt = new DoStatement(); | |
2397 dostmt->body_ = Statement::ReadFrom(reader); | |
2398 dostmt->condition_ = Expression::ReadFrom(reader); | |
2399 return dostmt; | |
2400 } | |
2401 | |
2402 | |
2403 void DoStatement::WriteTo(Writer* writer) { | |
2404 TRACE_WRITE_OFFSET(); | |
2405 writer->WriteTag(kDoStatement); | |
2406 body_->WriteTo(writer); | |
2407 condition_->WriteTo(writer); | |
2408 } | |
2409 | |
2410 | |
2411 ForStatement* ForStatement::ReadFrom(Reader* reader) { | |
2412 TRACE_READ_OFFSET(); | |
2413 VariableScope<ReaderHelper> vars(reader->helper()); | |
2414 ForStatement* forstmt = new ForStatement(); | |
2415 forstmt->variables_.ReadFromStatic<VariableDeclarationImpl>(reader); | |
2416 forstmt->condition_ = reader->ReadOptional<Expression>(); | |
2417 forstmt->updates_.ReadFromStatic<Expression>(reader); | |
2418 forstmt->body_ = Statement::ReadFrom(reader); | |
2419 return forstmt; | |
2420 } | |
2421 | |
2422 | |
2423 void ForStatement::WriteTo(Writer* writer) { | |
2424 TRACE_WRITE_OFFSET(); | |
2425 writer->WriteTag(kForStatement); | |
2426 VariableScope<WriterHelper> vars(writer->helper()); | |
2427 variables_.WriteToStatic<VariableDeclarationImpl>(writer); | |
2428 writer->WriteOptional<Expression>(condition_); | |
2429 updates_.WriteTo(writer); | |
2430 body_->WriteTo(writer); | |
2431 } | |
2432 | |
2433 | |
2434 ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) { | |
2435 TRACE_READ_OFFSET(); | |
2436 VariableScope<ReaderHelper> vars(reader->helper()); | |
2437 ForInStatement* forinstmt = new ForInStatement(); | |
2438 forinstmt->is_async_ = is_async; | |
2439 forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader); | |
2440 forinstmt->iterable_ = Expression::ReadFrom(reader); | |
2441 forinstmt->body_ = Statement::ReadFrom(reader); | |
2442 return forinstmt; | |
2443 } | |
2444 | |
2445 | |
2446 void ForInStatement::WriteTo(Writer* writer) { | |
2447 TRACE_WRITE_OFFSET(); | |
2448 writer->WriteTag(is_async_ ? kAsyncForInStatement : kForInStatement); | |
2449 VariableScope<WriterHelper> vars(writer->helper()); | |
2450 variable_->WriteToImpl(writer); | |
2451 iterable_->WriteTo(writer); | |
2452 body_->WriteTo(writer); | |
2453 } | |
2454 | |
2455 | |
2456 SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) { | |
2457 TRACE_READ_OFFSET(); | |
2458 SwitchCaseScope<ReaderHelper> scope(reader->helper()); | |
2459 SwitchStatement* stmt = new SwitchStatement(); | |
2460 stmt->condition_ = Expression::ReadFrom(reader); | |
2461 // We need to explicitly create empty [SwitchCase]s first in order to add them | |
2462 // to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch | |
2463 // case can refer to one defined later on. | |
2464 int count = reader->ReadUInt(); | |
2465 for (int i = 0; i < count; i++) { | |
2466 SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i); | |
2467 reader->helper()->switch_cases().Push(sc); | |
2468 } | |
2469 for (int i = 0; i < count; i++) { | |
2470 SwitchCase* sc = stmt->cases_[i]; | |
2471 sc->ReadFrom(reader); | |
2472 } | |
2473 return stmt; | |
2474 } | |
2475 | |
2476 | |
2477 void SwitchStatement::WriteTo(Writer* writer) { | |
2478 TRACE_WRITE_OFFSET(); | |
2479 SwitchCaseScope<WriterHelper> scope(writer->helper()); | |
2480 writer->WriteTag(kSwitchStatement); | |
2481 condition_->WriteTo(writer); | |
2482 for (int i = 0; i < cases_.length(); i++) { | |
2483 writer->helper()->switch_cases().Push(cases_[i]); | |
2484 } | |
2485 cases_.WriteTo(writer); | |
2486 } | |
2487 | |
2488 | |
2489 SwitchCase* SwitchCase::ReadFrom(Reader* reader) { | |
2490 TRACE_READ_OFFSET(); | |
2491 expressions_.ReadFromStatic<Expression>(reader); | |
2492 is_default_ = reader->ReadBool(); | |
2493 body_ = Statement::ReadFrom(reader); | |
2494 return this; | |
2495 } | |
2496 | |
2497 | |
2498 void SwitchCase::WriteTo(Writer* writer) { | |
2499 TRACE_WRITE_OFFSET(); | |
2500 expressions_.WriteTo(writer); | |
2501 writer->WriteBool(is_default_); | |
2502 body_->WriteTo(writer); | |
2503 } | |
2504 | |
2505 | |
2506 ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) { | |
2507 TRACE_READ_OFFSET(); | |
2508 ContinueSwitchStatement* stmt = new ContinueSwitchStatement(); | |
2509 stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt()); | |
2510 return stmt; | |
2511 } | |
2512 | |
2513 | |
2514 void ContinueSwitchStatement::WriteTo(Writer* writer) { | |
2515 TRACE_WRITE_OFFSET(); | |
2516 writer->WriteTag(kContinueSwitchStatement); | |
2517 writer->WriteUInt(writer->helper()->switch_cases().Lookup(target_)); | |
2518 } | |
2519 | |
2520 | |
2521 IfStatement* IfStatement::ReadFrom(Reader* reader) { | |
2522 TRACE_READ_OFFSET(); | |
2523 IfStatement* ifstmt = new IfStatement(); | |
2524 ifstmt->condition_ = Expression::ReadFrom(reader); | |
2525 ifstmt->then_ = Statement::ReadFrom(reader); | |
2526 ifstmt->otherwise_ = Statement::ReadFrom(reader); | |
2527 return ifstmt; | |
2528 } | |
2529 | |
2530 | |
2531 void IfStatement::WriteTo(Writer* writer) { | |
2532 TRACE_WRITE_OFFSET(); | |
2533 writer->WriteTag(kIfStatement); | |
2534 condition_->WriteTo(writer); | |
2535 then_->WriteTo(writer); | |
2536 otherwise_->WriteTo(writer); | |
2537 } | |
2538 | |
2539 | |
2540 ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) { | |
2541 TRACE_READ_OFFSET(); | |
2542 ReturnStatement* ret = new ReturnStatement(); | |
2543 ret->expression_ = reader->ReadOptional<Expression>(); | |
2544 return ret; | |
2545 } | |
2546 | |
2547 | |
2548 void ReturnStatement::WriteTo(Writer* writer) { | |
2549 TRACE_WRITE_OFFSET(); | |
2550 writer->WriteTag(kReturnStatement); | |
2551 writer->WriteOptional<Expression>(expression_); | |
2552 } | |
2553 | |
2554 | |
2555 TryCatch* TryCatch::ReadFrom(Reader* reader) { | |
2556 TRACE_READ_OFFSET(); | |
2557 TryCatch* tc = new TryCatch(); | |
2558 tc->body_ = Statement::ReadFrom(reader); | |
2559 tc->catches_.ReadFromStatic<Catch>(reader); | |
2560 return tc; | |
2561 } | |
2562 | |
2563 | |
2564 void TryCatch::WriteTo(Writer* writer) { | |
2565 TRACE_WRITE_OFFSET(); | |
2566 writer->WriteTag(kTryCatch); | |
2567 body_->WriteTo(writer); | |
2568 catches_.WriteTo(writer); | |
2569 } | |
2570 | |
2571 | |
2572 Catch* Catch::ReadFrom(Reader* reader) { | |
2573 TRACE_READ_OFFSET(); | |
2574 VariableScope<ReaderHelper> vars(reader->helper()); | |
2575 Catch* c = new Catch(); | |
2576 c->guard_ = DartType::ReadFrom(reader); | |
2577 c->exception_ = | |
2578 reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>(); | |
2579 c->stack_trace_ = | |
2580 reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>(); | |
2581 c->body_ = Statement::ReadFrom(reader); | |
2582 return c; | |
2583 } | |
2584 | |
2585 | |
2586 void Catch::WriteTo(Writer* writer) { | |
2587 TRACE_WRITE_OFFSET(); | |
2588 VariableScope<WriterHelper> vars(writer->helper()); | |
2589 guard_->WriteTo(writer); | |
2590 writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>( | |
2591 exception_); | |
2592 writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>( | |
2593 stack_trace_); | |
2594 body_->WriteTo(writer); | |
2595 } | |
2596 | |
2597 | |
2598 TryFinally* TryFinally::ReadFrom(Reader* reader) { | |
2599 TRACE_READ_OFFSET(); | |
2600 TryFinally* tf = new TryFinally(); | |
2601 tf->body_ = Statement::ReadFrom(reader); | |
2602 tf->finalizer_ = Statement::ReadFrom(reader); | |
2603 return tf; | |
2604 } | |
2605 | |
2606 | |
2607 void TryFinally::WriteTo(Writer* writer) { | |
2608 TRACE_WRITE_OFFSET(); | |
2609 writer->WriteTag(kTryFinally); | |
2610 body_->WriteTo(writer); | |
2611 finalizer_->WriteTo(writer); | |
2612 } | |
2613 | |
2614 | |
2615 YieldStatement* YieldStatement::ReadFrom(Reader* reader) { | |
2616 TRACE_READ_OFFSET(); | |
2617 YieldStatement* stmt = new YieldStatement(); | |
2618 stmt->flags_ = reader->ReadByte(); | |
2619 stmt->expression_ = Expression::ReadFrom(reader); | |
2620 return stmt; | |
2621 } | |
2622 | |
2623 | |
2624 void YieldStatement::WriteTo(Writer* writer) { | |
2625 TRACE_WRITE_OFFSET(); | |
2626 writer->WriteTag(kYieldStatement); | |
2627 writer->WriteByte(flags_); | |
2628 expression_->WriteTo(writer); | |
2629 } | |
2630 | |
2631 | |
2632 VariableDeclaration* VariableDeclaration::ReadFrom(Reader* reader) { | |
2633 TRACE_READ_OFFSET(); | |
2634 Tag tag = reader->ReadTag(); | |
2635 ASSERT(tag == kVariableDeclaration); | |
2636 return VariableDeclaration::ReadFromImpl(reader); | |
2637 } | |
2638 | |
2639 | |
2640 VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader) { | |
2641 TRACE_READ_OFFSET(); | |
2642 VariableDeclaration* decl = new VariableDeclaration(); | |
2643 decl->flags_ = reader->ReadFlags(); | |
2644 decl->name_ = Reference::ReadStringFrom(reader); | |
2645 decl->type_ = DartType::ReadFrom(reader); | |
2646 decl->inferred_value_ = reader->ReadOptional<InferredValue>(); | |
2647 decl->initializer_ = reader->ReadOptional<Expression>(); | |
2648 reader->helper()->variables().Push(decl); | |
2649 return decl; | |
2650 } | |
2651 | |
2652 | |
2653 void VariableDeclaration::WriteTo(Writer* writer) { | |
2654 TRACE_WRITE_OFFSET(); | |
2655 writer->WriteTag(kVariableDeclaration); | |
2656 WriteToImpl(writer); | |
2657 } | |
2658 | |
2659 | |
2660 void VariableDeclaration::WriteToImpl(Writer* writer) { | |
2661 TRACE_WRITE_OFFSET(); | |
2662 writer->WriteFlags(flags_); | |
2663 name_->WriteTo(writer); | |
2664 type_->WriteTo(writer); | |
2665 writer->WriteOptional<InferredValue>(inferred_value_); | |
2666 writer->WriteOptional<Expression>(initializer_); | |
2667 writer->helper()->variables().Push(this); | |
2668 } | |
2669 | |
2670 | |
2671 FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) { | |
2672 TRACE_READ_OFFSET(); | |
2673 FunctionDeclaration* decl = new FunctionDeclaration(); | |
2674 decl->variable_ = VariableDeclaration::ReadFromImpl(reader); | |
2675 VariableScope<ReaderHelper> parameters(reader->helper()); | |
2676 decl->function_ = FunctionNode::ReadFrom(reader); | |
2677 return decl; | |
2678 } | |
2679 | |
2680 | |
2681 void FunctionDeclaration::WriteTo(Writer* writer) { | |
2682 TRACE_WRITE_OFFSET(); | |
2683 writer->WriteTag(kFunctionDeclaration); | |
2684 variable_->WriteToImpl(writer); | |
2685 VariableScope<WriterHelper> parameters(writer->helper()); | |
2686 function_->WriteTo(writer); | |
2687 } | |
2688 | |
2689 | |
2690 Name* Name::ReadFrom(Reader* reader) { | |
2691 String* string = Reference::ReadStringFrom(reader); | |
2692 if (string->size() >= 1 && string->buffer()[0] == '_') { | |
2693 int lib_index = reader->ReadUInt(); | |
2694 Library* library = | |
2695 reader->helper()->program()->libraries().GetOrCreate<Library>( | |
2696 lib_index); | |
2697 return new Name(string, library); | |
2698 } else { | |
2699 return new Name(string, NULL); | |
2700 } | |
2701 } | |
2702 | |
2703 | |
2704 void Name::WriteTo(Writer* writer) { | |
2705 TRACE_WRITE_OFFSET(); | |
2706 string_->WriteTo(writer); | |
2707 Library* library = library_; | |
2708 bool is_private = library != NULL; | |
2709 if (is_private) { | |
2710 writer->WriteUInt(writer->helper()->libraries().Lookup(library_)); | |
2711 } | |
2712 } | |
2713 | |
2714 | |
2715 InferredValue* InferredValue::ReadFrom(Reader* reader) { | |
2716 InferredValue* type = new InferredValue(); | |
2717 type->klass_ = Reference::ReadClassFrom(reader, true); | |
2718 type->kind_ = static_cast<BaseClassKind>(reader->ReadByte()); | |
2719 type->value_bits_ = reader->ReadByte(); | |
2720 return type; | |
2721 } | |
2722 | |
2723 | |
2724 void InferredValue::WriteTo(Writer* writer) { | |
2725 Reference::WriteClassTo(writer, klass_, true); | |
2726 writer->WriteByte(static_cast<uint8_t>(kind_)); | |
2727 writer->WriteByte(value_bits_); | |
2728 } | |
2729 | |
2730 | |
2731 DartType* DartType::ReadFrom(Reader* reader) { | |
2732 TRACE_READ_OFFSET(); | |
2733 Tag tag = reader->ReadTag(); | |
2734 switch (tag) { | |
2735 case kInvalidType: | |
2736 return InvalidType::ReadFrom(reader); | |
2737 case kDynamicType: | |
2738 return DynamicType::ReadFrom(reader); | |
2739 case kVoidType: | |
2740 return VoidType::ReadFrom(reader); | |
2741 case kInterfaceType: | |
2742 return InterfaceType::ReadFrom(reader); | |
2743 case kSimpleInterfaceType: | |
2744 return InterfaceType::ReadFrom(reader, true); | |
2745 case kFunctionType: | |
2746 return FunctionType::ReadFrom(reader); | |
2747 case kSimpleFunctionType: | |
2748 return FunctionType::ReadFrom(reader, true); | |
2749 case kTypeParameterType: | |
2750 return TypeParameterType::ReadFrom(reader); | |
2751 default: | |
2752 UNREACHABLE(); | |
2753 } | |
2754 UNREACHABLE(); | |
2755 return NULL; | |
2756 } | |
2757 | |
2758 | |
2759 InvalidType* InvalidType::ReadFrom(Reader* reader) { | |
2760 TRACE_READ_OFFSET(); | |
2761 return new InvalidType(); | |
2762 } | |
2763 | |
2764 | |
2765 void InvalidType::WriteTo(Writer* writer) { | |
2766 TRACE_WRITE_OFFSET(); | |
2767 writer->WriteTag(kInvalidType); | |
2768 } | |
2769 | |
2770 | |
2771 DynamicType* DynamicType::ReadFrom(Reader* reader) { | |
2772 TRACE_READ_OFFSET(); | |
2773 return new DynamicType(); | |
2774 } | |
2775 | |
2776 | |
2777 void DynamicType::WriteTo(Writer* writer) { | |
2778 TRACE_WRITE_OFFSET(); | |
2779 writer->WriteTag(kDynamicType); | |
2780 } | |
2781 | |
2782 | |
2783 VoidType* VoidType::ReadFrom(Reader* reader) { | |
2784 TRACE_READ_OFFSET(); | |
2785 return new VoidType(); | |
2786 } | |
2787 | |
2788 | |
2789 void VoidType::WriteTo(Writer* writer) { | |
2790 TRACE_WRITE_OFFSET(); | |
2791 writer->WriteTag(kVoidType); | |
2792 } | |
2793 | |
2794 | |
2795 InterfaceType* InterfaceType::ReadFrom(Reader* reader) { | |
2796 TRACE_READ_OFFSET(); | |
2797 Class* klass = Reference::ReadClassFrom(reader); | |
2798 InterfaceType* type = new InterfaceType(klass); | |
2799 type->type_arguments().ReadFromStatic<DartType>(reader); | |
2800 return type; | |
2801 } | |
2802 | |
2803 | |
2804 InterfaceType* InterfaceType::ReadFrom(Reader* reader, | |
2805 bool _without_type_arguments_) { | |
2806 TRACE_READ_OFFSET(); | |
2807 Class* klass = Reference::ReadClassFrom(reader); | |
2808 InterfaceType* type = new InterfaceType(klass); | |
2809 ASSERT(_without_type_arguments_); | |
2810 return type; | |
2811 } | |
2812 | |
2813 | |
2814 void InterfaceType::WriteTo(Writer* writer) { | |
2815 TRACE_WRITE_OFFSET(); | |
2816 if (type_arguments_.length() == 0) { | |
2817 writer->WriteTag(kSimpleInterfaceType); | |
2818 Reference::WriteClassTo(writer, klass_); | |
2819 } else { | |
2820 writer->WriteTag(kInterfaceType); | |
2821 Reference::WriteClassTo(writer, klass_); | |
2822 type_arguments_.WriteTo(writer); | |
2823 } | |
2824 } | |
2825 | |
2826 | |
2827 FunctionType* FunctionType::ReadFrom(Reader* reader) { | |
2828 TRACE_READ_OFFSET(); | |
2829 FunctionType* type = new FunctionType(); | |
2830 TypeParameterScope<ReaderHelper> scope(reader->helper()); | |
2831 type->type_parameters().ReadFrom(reader); | |
2832 type->required_parameter_count_ = reader->ReadUInt(); | |
2833 type->positional_parameters().ReadFromStatic<DartType>(reader); | |
2834 type->named_parameters().ReadFromStatic<Tuple<String, DartType> >(reader); | |
2835 type->return_type_ = DartType::ReadFrom(reader); | |
2836 return type; | |
2837 } | |
2838 | |
2839 | |
2840 FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) { | |
2841 TRACE_READ_OFFSET(); | |
2842 FunctionType* type = new FunctionType(); | |
2843 ASSERT(_is_simple_); | |
2844 type->positional_parameters().ReadFromStatic<DartType>(reader); | |
2845 type->required_parameter_count_ = type->positional_parameters().length(); | |
2846 type->return_type_ = DartType::ReadFrom(reader); | |
2847 return type; | |
2848 } | |
2849 | |
2850 | |
2851 void FunctionType::WriteTo(Writer* writer) { | |
2852 TRACE_WRITE_OFFSET(); | |
2853 | |
2854 bool is_simple = | |
2855 positional_parameters_.length() == required_parameter_count_ && | |
2856 type_parameters_.length() == 0 && named_parameters_.length() == 0; | |
2857 if (is_simple) { | |
2858 writer->WriteTag(kSimpleFunctionType); | |
2859 positional_parameters_.WriteTo(writer); | |
2860 return_type_->WriteTo(writer); | |
2861 } else { | |
2862 TypeParameterScope<WriterHelper> scope(writer->helper()); | |
2863 writer->WriteTag(kFunctionType); | |
2864 type_parameters_.WriteTo(writer); | |
2865 writer->WriteUInt(required_parameter_count_); | |
2866 positional_parameters_.WriteTo(writer); | |
2867 named_parameters_.WriteTo(writer); | |
2868 return_type_->WriteTo(writer); | |
2869 } | |
2870 } | |
2871 | |
2872 | |
2873 TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) { | |
2874 TRACE_READ_OFFSET(); | |
2875 TypeParameterType* type = new TypeParameterType(); | |
2876 type->parameter_ = | |
2877 reader->helper()->type_parameters().Lookup(reader->ReadUInt()); | |
2878 return type; | |
2879 } | |
2880 | |
2881 | |
2882 void TypeParameterType::WriteTo(Writer* writer) { | |
2883 TRACE_WRITE_OFFSET(); | |
2884 writer->WriteTag(kTypeParameterType); | |
2885 writer->WriteUInt(writer->helper()->type_parameters().Lookup(parameter_)); | |
2886 } | |
2887 | |
2888 | |
2889 Program* Program::ReadFrom(Reader* reader) { | |
2890 TRACE_READ_OFFSET(); | |
2891 uint32_t magic = reader->ReadUInt32(); | |
2892 if (magic != kMagicProgramFile) FATAL("Invalid magic identifier"); | |
2893 | |
2894 Program* program = new Program(); | |
2895 reader->helper()->set_program(program); | |
2896 | |
2897 program->string_table_.ReadFrom(reader); | |
2898 StringTable dummy1; | |
2899 dummy1.ReadFrom(reader); // TODO(jensj): source_uri_table | |
2900 LineStartingTable dummy2; | |
2901 // TODO(jensj) line_starting_table | |
2902 dummy2.ReadFrom(reader, dummy1.strings_.length()); | |
2903 | |
2904 int libraries = reader->ReadUInt(); | |
2905 program->libraries().EnsureInitialized(libraries); | |
2906 for (int i = 0; i < libraries; i++) { | |
2907 program->libraries().GetOrCreate<Library>(i)->ReadFrom(reader); | |
2908 } | |
2909 | |
2910 program->main_method_ = Procedure::Cast(Reference::ReadMemberFrom(reader)); | |
2911 | |
2912 return program; | |
2913 } | |
2914 | |
2915 | |
2916 void Program::WriteTo(Writer* writer) { | |
2917 TRACE_WRITE_OFFSET(); | |
2918 | |
2919 writer->helper()->SetProgram(this); | |
2920 | |
2921 writer->WriteUInt32(kMagicProgramFile); | |
2922 | |
2923 // TODO(kustermann): We should really change the format so we don't need to | |
2924 // loop over the whole program to GC all strings and build the table. Let's | |
2925 // just do the table at the end! | |
2926 // | |
2927 // NOTE: Currently we don't GC strings and we require that all referenced | |
2928 // strings in nodes are present in [string_table_]. | |
2929 string_table_.WriteTo(writer); | |
2930 StringTable dummy1; | |
2931 dummy1.WriteTo(writer); // TODO(jensj): source_uri_table | |
2932 LineStartingTable dummy2; | |
2933 dummy2.WriteTo(writer); // TODO(jensj) line_starting_table | |
2934 | |
2935 libraries_.WriteTo(writer); | |
2936 Reference::WriteMemberTo(writer, main_method_); | |
2937 } | |
2938 | |
2939 | |
2940 FunctionNode* FunctionNode::ReadFrom(Reader* reader) { | |
2941 TRACE_READ_OFFSET(); | |
2942 TypeParameterScope<ReaderHelper> scope(reader->helper()); | |
2943 | |
2944 FunctionNode* function = new FunctionNode(); | |
2945 function->async_marker_ = | |
2946 static_cast<FunctionNode::AsyncMarker>(reader->ReadByte()); | |
2947 function->type_parameters().ReadFrom(reader); | |
2948 function->required_parameter_count_ = reader->ReadUInt(); | |
2949 function->positional_parameters().ReadFromStatic<VariableDeclarationImpl>( | |
2950 reader); | |
2951 function->named_parameters().ReadFromStatic<VariableDeclarationImpl>(reader); | |
2952 function->return_type_ = DartType::ReadFrom(reader); | |
2953 function->inferred_return_value_ = reader->ReadOptional<InferredValue>(); | |
2954 | |
2955 VariableScope<ReaderHelper> vars(reader->helper()); | |
2956 function->body_ = reader->ReadOptional<Statement>(); | |
2957 return function; | |
2958 } | |
2959 | |
2960 | |
2961 void FunctionNode::WriteTo(Writer* writer) { | |
2962 TRACE_WRITE_OFFSET(); | |
2963 TypeParameterScope<WriterHelper> scope(writer->helper()); | |
2964 | |
2965 writer->WriteByte(static_cast<uint8_t>(async_marker_)); | |
2966 type_parameters().WriteTo(writer); | |
2967 writer->WriteUInt(required_parameter_count()); | |
2968 positional_parameters().WriteToStatic<VariableDeclarationImpl>(writer); | |
2969 named_parameters().WriteToStatic<VariableDeclarationImpl>(writer); | |
2970 return_type_->WriteTo(writer); | |
2971 writer->WriteOptional<InferredValue>(inferred_return_value_); | |
2972 | |
2973 VariableScope<WriterHelper> vars(writer->helper()); | |
2974 writer->WriteOptional<Statement>(body_); | |
2975 } | |
2976 | |
2977 | |
2978 TypeParameter* TypeParameter::ReadFrom(Reader* reader) { | |
2979 TRACE_READ_OFFSET(); | |
2980 name_ = Reference::ReadStringFrom(reader); | |
2981 bound_ = DartType::ReadFrom(reader); | |
2982 return this; | |
2983 } | |
2984 | |
2985 | |
2986 void TypeParameter::WriteTo(Writer* writer) { | |
2987 TRACE_WRITE_OFFSET(); | |
2988 name_->WriteTo(writer); | |
2989 bound_->WriteTo(writer); | |
2990 } | |
2991 | |
2992 | |
2993 } // namespace dil | |
2994 | |
2995 dil::Program* ReadPrecompiledDil(const char* filename) { | |
2996 if (filename != NULL) { | |
2997 InputFile file(filename); | |
2998 if (file.ReadAll()) { | |
2999 dil::Reader reader(file.buffer(), file.size()); | |
3000 return dil::Program::ReadFrom(&reader); | |
3001 } | |
3002 } | |
3003 return NULL; | |
3004 } | |
3005 | |
3006 | |
3007 dil::Program* ReadPrecompiledDilFromBuffer(const uint8_t* buffer, | |
3008 intptr_t buffer_length) { | |
3009 dil::Reader reader(buffer, buffer_length); | |
3010 return dil::Program::ReadFrom(&reader); | |
3011 } | |
3012 | |
3013 | |
3014 bool WritePrecompiledDil(const char* filename, dil::Program* program) { | |
3015 ASSERT(filename != NULL); | |
3016 | |
3017 { | |
3018 OutputFile file(filename); | |
3019 if (!file.Open()) return false; | |
3020 | |
3021 dil::Writer writer(&file); | |
3022 program->WriteTo(&writer); | |
3023 return true; | |
3024 } | |
3025 return false; | |
3026 } | |
3027 | |
3028 | |
3029 } // namespace dart | |
OLD | NEW |