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

Side by Side Diff: runtime/vm/dil_binary.cc

Issue 2411823003: VM support for running Kernel binaries. (Closed)
Patch Set: Address initial review comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698