b2b00e8909
Utilize the offsets added in previous CLs. While this doesn't by it self give anything that resembles a good debugging experience, it should now be possible to set *some* breakpoints and actually break on them. Because of the way observatory works (and because of an unfinished Script::GenerateLineNumberArray (for kernel)) the formatting of the code you try to load up and 'debug' has to be quite specific (e.g. no indentation at all), and even then it mostly doesn't work. This is step #3 in introducing these things, next step(s) will be fixing stuff like the above. R=kmillikin@google.com Review-Url: https://codereview.chromium.org/2628693004 .
1897 lines
53 KiB
C++
1897 lines
53 KiB
C++
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
#include "platform/globals.h"
|
|
#include "vm/flags.h"
|
|
#include "vm/kernel.h"
|
|
#include "vm/os.h"
|
|
|
|
#if defined(DEBUG)
|
|
#define TRACE_READ_OFFSET() \
|
|
do { \
|
|
if (FLAG_trace_kernel_binary) reader->DumpOffset(DART_PRETTY_FUNCTION); \
|
|
} while (0)
|
|
#else
|
|
#define TRACE_READ_OFFSET()
|
|
#endif
|
|
|
|
namespace dart {
|
|
|
|
|
|
namespace kernel {
|
|
|
|
|
|
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
|
|
|
|
|
|
// Keep in sync with package:dynamo/lib/binary/tag.dart
|
|
enum Tag {
|
|
kNothing = 0,
|
|
kSomething = 1,
|
|
|
|
kNormalClass = 2,
|
|
kMixinClass = 3,
|
|
|
|
kField = 4,
|
|
kConstructor = 5,
|
|
kProcedure = 6,
|
|
|
|
kInvalidInitializer = 7,
|
|
kFieldInitializer = 8,
|
|
kSuperInitializer = 9,
|
|
kRedirectingInitializer = 10,
|
|
kLocalInitializer = 11,
|
|
|
|
kDirectPropertyGet = 15,
|
|
kDirectPropertySet = 16,
|
|
kDirectMethodInvocation = 17,
|
|
kConstStaticInvocation = 18,
|
|
kInvalidExpression = 19,
|
|
kVariableGet = 20,
|
|
kVariableSet = 21,
|
|
kPropertyGet = 22,
|
|
kPropertySet = 23,
|
|
kSuperPropertyGet = 24,
|
|
kSuperPropertySet = 25,
|
|
kStaticGet = 26,
|
|
kStaticSet = 27,
|
|
kMethodInvocation = 28,
|
|
kSuperMethodInvocation = 29,
|
|
kStaticInvocation = 30,
|
|
kConstructorInvocation = 31,
|
|
kConstConstructorInvocation = 32,
|
|
kNot = 33,
|
|
kLogicalExpression = 34,
|
|
kConditionalExpression = 35,
|
|
kStringConcatenation = 36,
|
|
kIsExpression = 37,
|
|
kAsExpression = 38,
|
|
kStringLiteral = 39,
|
|
kDoubleLiteral = 40,
|
|
kTrueLiteral = 41,
|
|
kFalseLiteral = 42,
|
|
kNullLiteral = 43,
|
|
kSymbolLiteral = 44,
|
|
kTypeLiteral = 45,
|
|
kThisExpression = 46,
|
|
kRethrow = 47,
|
|
kThrow = 48,
|
|
kListLiteral = 49,
|
|
kMapLiteral = 50,
|
|
kAwaitExpression = 51,
|
|
kFunctionExpression = 52,
|
|
kLet = 53,
|
|
|
|
kPositiveIntLiteral = 55,
|
|
kNegativeIntLiteral = 56,
|
|
kBigIntLiteral = 57,
|
|
kConstListLiteral = 58,
|
|
kConstMapLiteral = 59,
|
|
|
|
kInvalidStatement = 60,
|
|
kExpressionStatement = 61,
|
|
kBlock = 62,
|
|
kEmptyStatement = 63,
|
|
kAssertStatement = 64,
|
|
kLabeledStatement = 65,
|
|
kBreakStatement = 66,
|
|
kWhileStatement = 67,
|
|
kDoStatement = 68,
|
|
kForStatement = 69,
|
|
kForInStatement = 70,
|
|
kSwitchStatement = 71,
|
|
kContinueSwitchStatement = 72,
|
|
kIfStatement = 73,
|
|
kReturnStatement = 74,
|
|
kTryCatch = 75,
|
|
kTryFinally = 76,
|
|
kYieldStatement = 77,
|
|
kVariableDeclaration = 78,
|
|
kFunctionDeclaration = 79,
|
|
kAsyncForInStatement = 80,
|
|
|
|
kInvalidType = 90,
|
|
kDynamicType = 91,
|
|
kVoidType = 92,
|
|
kInterfaceType = 93,
|
|
kFunctionType = 94,
|
|
kTypeParameterType = 95,
|
|
kSimpleInterfaceType = 96,
|
|
kSimpleFunctionType = 97,
|
|
|
|
kNullReference = 99,
|
|
kNormalClassReference = 100,
|
|
kMixinClassReference = 101,
|
|
|
|
kLibraryFieldReference = 102,
|
|
kClassFieldReference = 103,
|
|
kClassConstructorReference = 104,
|
|
kLibraryProcedureReference = 105,
|
|
kClassProcedureReference = 106,
|
|
|
|
kSpecializedTagHighBit = 0x80, // 10000000
|
|
kSpecializedTagMask = 0xF8, // 11111000
|
|
kSpecializedPayloadMask = 0x7, // 00000111
|
|
|
|
kSpecializedVariableGet = 128,
|
|
kSpecializedVariableSet = 136,
|
|
kSpecialIntLiteral = 144,
|
|
};
|
|
|
|
|
|
static const int SpecializedIntLiteralBias = 3;
|
|
|
|
|
|
template <typename T>
|
|
class BlockStack {
|
|
public:
|
|
BlockStack() : current_count_(0) {}
|
|
|
|
void EnterScope() {
|
|
variable_count_.push_back(current_count_);
|
|
current_count_ = 0;
|
|
}
|
|
|
|
void LeaveScope() {
|
|
variables_.resize(variables_.size() - current_count_);
|
|
current_count_ = variable_count_[variable_count_.size() - 1];
|
|
variable_count_.pop_back();
|
|
}
|
|
|
|
T* Lookup(int index) {
|
|
ASSERT(static_cast<unsigned>(index) < variables_.size());
|
|
return variables_[index];
|
|
}
|
|
|
|
void Push(T* v) {
|
|
variables_.push_back(v);
|
|
current_count_++;
|
|
}
|
|
|
|
void Push(List<T>* decl) {
|
|
for (int i = 0; i < decl->length(); i++) {
|
|
variables_.push_back(decl[i]);
|
|
current_count_++;
|
|
}
|
|
}
|
|
|
|
void Pop(T* decl) {
|
|
variables_.resize(variables_.size() - 1);
|
|
current_count_--;
|
|
}
|
|
|
|
void Pop(List<T>* decl) {
|
|
variables_.resize(variables_.size() - decl->length());
|
|
current_count_ -= decl->length();
|
|
}
|
|
|
|
private:
|
|
int current_count_;
|
|
std::vector<T*> variables_;
|
|
std::vector<int> variable_count_;
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
class BlockMap {
|
|
public:
|
|
BlockMap() : current_count_(0), stack_height_(0) {}
|
|
|
|
void EnterScope() {
|
|
variable_count_.push_back(current_count_);
|
|
current_count_ = 0;
|
|
}
|
|
|
|
void LeaveScope() {
|
|
stack_height_ -= current_count_;
|
|
current_count_ = variable_count_[variable_count_.size() - 1];
|
|
variable_count_.pop_back();
|
|
}
|
|
|
|
int Lookup(T* object) {
|
|
ASSERT(variables_.find(object) != variables_.end());
|
|
if (variables_.find(object) == variables_.end()) FATAL("lookup failure");
|
|
return variables_[object];
|
|
}
|
|
|
|
void Push(T* v) {
|
|
int index = stack_height_++;
|
|
variables_[v] = index;
|
|
current_count_++;
|
|
}
|
|
|
|
void Set(T* v, int index) { variables_[v] = index; }
|
|
|
|
void Push(List<T>* decl) {
|
|
for (int i = 0; i < decl->length(); i++) {
|
|
Push(decl[i]);
|
|
}
|
|
}
|
|
|
|
void Pop(T* v) {
|
|
current_count_--;
|
|
stack_height_--;
|
|
}
|
|
|
|
private:
|
|
int current_count_;
|
|
int stack_height_;
|
|
std::map<T*, int> variables_;
|
|
std::vector<int> variable_count_;
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
class VariableScope {
|
|
public:
|
|
explicit VariableScope(T* builder) : builder_(builder) {
|
|
builder_->variables().EnterScope();
|
|
}
|
|
~VariableScope() { builder_->variables().LeaveScope(); }
|
|
|
|
private:
|
|
T* builder_;
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
class TypeParameterScope {
|
|
public:
|
|
explicit TypeParameterScope(T* builder) : builder_(builder) {
|
|
builder_->type_parameters().EnterScope();
|
|
}
|
|
~TypeParameterScope() { builder_->type_parameters().LeaveScope(); }
|
|
|
|
private:
|
|
T* builder_;
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
class SwitchCaseScope {
|
|
public:
|
|
explicit SwitchCaseScope(T* builder) : builder_(builder) {
|
|
builder_->switch_cases().EnterScope();
|
|
}
|
|
~SwitchCaseScope() { builder_->switch_cases().LeaveScope(); }
|
|
|
|
private:
|
|
T* builder_;
|
|
};
|
|
|
|
|
|
// Unlike other scopes, labels from enclosing functions are not visible in
|
|
// nested functions. The LabelScope class is used to hide outer labels.
|
|
template <typename Builder, typename Block>
|
|
class LabelScope {
|
|
public:
|
|
explicit LabelScope(Builder* builder) : builder_(builder) {
|
|
outer_block_ = builder_->labels();
|
|
builder_->set_labels(&block_);
|
|
}
|
|
~LabelScope() { builder_->set_labels(outer_block_); }
|
|
|
|
private:
|
|
Builder* builder_;
|
|
Block block_;
|
|
Block* outer_block_;
|
|
};
|
|
|
|
class ReaderHelper {
|
|
public:
|
|
ReaderHelper() : program_(NULL), labels_(NULL) {}
|
|
|
|
Program* program() { return program_; }
|
|
void set_program(Program* program) { program_ = program; }
|
|
|
|
BlockStack<VariableDeclaration>& variables() { return scope_; }
|
|
BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
|
|
BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }
|
|
|
|
BlockStack<LabeledStatement>* labels() { return labels_; }
|
|
void set_labels(BlockStack<LabeledStatement>* labels) { labels_ = labels; }
|
|
|
|
private:
|
|
Program* program_;
|
|
BlockStack<VariableDeclaration> scope_;
|
|
BlockStack<TypeParameter> type_parameters_;
|
|
BlockStack<SwitchCase> switch_cases_;
|
|
BlockStack<LabeledStatement>* labels_;
|
|
};
|
|
|
|
|
|
class Reader {
|
|
public:
|
|
Reader(const uint8_t* buffer, int64_t size)
|
|
: buffer_(buffer), size_(size), offset_(0) {}
|
|
|
|
uint32_t ReadUInt32() {
|
|
ASSERT(offset_ + 4 <= size_);
|
|
|
|
uint32_t value = (buffer_[offset_ + 0] << 24) |
|
|
(buffer_[offset_ + 1] << 16) |
|
|
(buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0);
|
|
offset_ += 4;
|
|
return value;
|
|
}
|
|
|
|
uint32_t ReadUInt() {
|
|
ASSERT(offset_ + 1 <= size_);
|
|
uint8_t byte0 = buffer_[offset_];
|
|
if ((byte0 & 0x80) == 0) {
|
|
// 0...
|
|
offset_++;
|
|
return byte0;
|
|
} else if ((byte0 & 0xc0) == 0x80) {
|
|
// 10...
|
|
ASSERT(offset_ + 2 <= size_);
|
|
uint32_t value = ((byte0 & ~0x80) << 8) | (buffer_[offset_ + 1]);
|
|
offset_ += 2;
|
|
return value;
|
|
} else {
|
|
// 11...
|
|
ASSERT(offset_ + 4 <= size_);
|
|
uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) |
|
|
(buffer_[offset_ + 2] << 8) |
|
|
(buffer_[offset_ + 3] << 0);
|
|
offset_ += 4;
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read and return a TokenPosition from this reader.
|
|
*/
|
|
TokenPosition ReadPosition() {
|
|
// Position is saved as unsigned,
|
|
// but actually ranges from -1 and up (thus the -1)
|
|
intptr_t value = ReadUInt() - 1;
|
|
TokenPosition result = TokenPosition(value);
|
|
max_position_ = Utils::Maximum(max_position_, result);
|
|
if (min_position_.IsNoSource()) {
|
|
min_position_ = result;
|
|
} else if (result.IsReal()) {
|
|
min_position_ = Utils::Minimum(min_position_, result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
intptr_t ReadListLength() { return ReadUInt(); }
|
|
|
|
uint8_t ReadByte() { return buffer_[offset_++]; }
|
|
|
|
bool ReadBool() { return (ReadByte() & 1) == 1; }
|
|
|
|
word ReadFlags() { return ReadByte(); }
|
|
|
|
Tag ReadTag(uint8_t* payload = NULL) {
|
|
uint8_t byte = ReadByte();
|
|
bool has_payload = (byte & kSpecializedTagHighBit) != 0;
|
|
if (has_payload) {
|
|
if (payload != NULL) {
|
|
*payload = byte & kSpecializedPayloadMask;
|
|
}
|
|
return static_cast<Tag>(byte & kSpecializedTagMask);
|
|
} else {
|
|
return static_cast<Tag>(byte);
|
|
}
|
|
}
|
|
|
|
const uint8_t* Consume(int count) {
|
|
ASSERT(offset_ + count <= size_);
|
|
const uint8_t* old = buffer_ + offset_;
|
|
offset_ += count;
|
|
return old;
|
|
}
|
|
|
|
void EnsureEnd() {
|
|
if (offset_ != size_) {
|
|
FATAL2(
|
|
"Reading Kernel file: Expected to be at EOF "
|
|
"(offset: %" Pd64 ", size: %" Pd64 ")",
|
|
offset_, size_);
|
|
}
|
|
}
|
|
|
|
void DumpOffset(const char* str) {
|
|
OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
|
|
}
|
|
|
|
// The largest position read yet (since last reset).
|
|
// This is automatically updated when calling ReadPosition,
|
|
// but can be overwritten (e.g. via the PositionScope class).
|
|
TokenPosition max_position() { return max_position_; }
|
|
// The smallest position read yet (since last reset).
|
|
// This is automatically updated when calling ReadPosition,
|
|
// but can be overwritten (e.g. via the PositionScope class).
|
|
TokenPosition min_position() { return min_position_; }
|
|
// The current script id for what we are currently processing.
|
|
// Note though that this is only a convenience helper and has to be set
|
|
// manually.
|
|
intptr_t current_script_id() { return current_script_id_; }
|
|
void set_current_script_id(intptr_t script_id) {
|
|
current_script_id_ = script_id;
|
|
}
|
|
|
|
template <typename T, typename RT>
|
|
T* ReadOptional() {
|
|
Tag tag = ReadTag();
|
|
if (tag == kNothing) {
|
|
return NULL;
|
|
}
|
|
ASSERT(tag == kSomething);
|
|
return RT::ReadFrom(this);
|
|
}
|
|
|
|
template <typename T>
|
|
T* ReadOptional() {
|
|
return ReadOptional<T, T>();
|
|
}
|
|
|
|
ReaderHelper* helper() { return &builder_; }
|
|
|
|
private:
|
|
const uint8_t* buffer_;
|
|
int64_t size_;
|
|
int64_t offset_;
|
|
ReaderHelper builder_;
|
|
TokenPosition max_position_;
|
|
TokenPosition min_position_;
|
|
intptr_t current_script_id_;
|
|
|
|
friend class PositionScope;
|
|
};
|
|
|
|
|
|
// A helper class that resets the readers min and max positions both upon
|
|
// initialization and upon destruction, i.e. when created the min an max
|
|
// positions will be reset to "noSource", when destructing the min and max will
|
|
// be reset to have they value they would have had, if they hadn't been reset in
|
|
// the first place.
|
|
class PositionScope {
|
|
public:
|
|
explicit PositionScope(Reader* reader)
|
|
: reader_(reader),
|
|
min_(reader->min_position_),
|
|
max_(reader->max_position_) {
|
|
reader->min_position_ = reader->max_position_ = TokenPosition::kNoSource;
|
|
}
|
|
|
|
~PositionScope() {
|
|
if (reader_->min_position_.IsNoSource()) {
|
|
reader_->min_position_ = min_;
|
|
} else if (min_.IsReal()) {
|
|
reader_->min_position_ = Utils::Minimum(reader_->min_position_, min_);
|
|
}
|
|
reader_->max_position_ = Utils::Maximum(reader_->max_position_, max_);
|
|
}
|
|
|
|
private:
|
|
Reader* reader_;
|
|
TokenPosition min_;
|
|
TokenPosition max_;
|
|
};
|
|
|
|
template <typename T>
|
|
template <typename IT>
|
|
void List<T>::ReadFrom(Reader* reader, TreeNode* parent) {
|
|
TRACE_READ_OFFSET();
|
|
ASSERT(parent != NULL);
|
|
int length = reader->ReadListLength();
|
|
EnsureInitialized(length);
|
|
|
|
for (int i = 0; i < length_; i++) {
|
|
IT* object = GetOrCreate<IT>(i, parent);
|
|
object->ReadFrom(reader);
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
template <typename IT>
|
|
void List<T>::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
int length = reader->ReadListLength();
|
|
EnsureInitialized(length);
|
|
|
|
for (int i = 0; i < length_; i++) {
|
|
GetOrCreate<IT>(i)->ReadFrom(reader);
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
template <typename IT>
|
|
void List<T>::ReadFromStatic(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
int length = reader->ReadListLength();
|
|
EnsureInitialized(length);
|
|
|
|
for (int i = 0; i < length_; i++) {
|
|
ASSERT(array_[i] == NULL);
|
|
array_[i] = IT::ReadFrom(reader);
|
|
}
|
|
}
|
|
|
|
void TypeParameterList::ReadFrom(Reader* reader) {
|
|
// It is possible for the bound of the first type parameter to refer to
|
|
// the second type parameter. This means we need to create [TypeParameter]
|
|
// objects before reading the bounds.
|
|
int length = reader->ReadListLength();
|
|
EnsureInitialized(length);
|
|
|
|
// Make all [TypeParameter]s available in scope.
|
|
for (int i = 0; i < length; i++) {
|
|
TypeParameter* parameter = (*this)[i] = new TypeParameter();
|
|
reader->helper()->type_parameters().Push(parameter);
|
|
}
|
|
|
|
// Read all [TypeParameter]s and their bounds.
|
|
for (int i = 0; i < length; i++) {
|
|
(*this)[i]->ReadFrom(reader);
|
|
}
|
|
}
|
|
|
|
|
|
template <typename A, typename B>
|
|
Tuple<A, B>* Tuple<A, B>::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
A* first = A::ReadFrom(reader);
|
|
B* second = B::ReadFrom(reader);
|
|
return new Tuple<A, B>(first, second);
|
|
}
|
|
|
|
|
|
template <typename B, typename S>
|
|
class DowncastReader {
|
|
public:
|
|
static S* ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return S::Cast(B::ReadFrom(reader));
|
|
}
|
|
};
|
|
|
|
|
|
class StringImpl {
|
|
public:
|
|
static String* ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return String::ReadFromImpl(reader);
|
|
}
|
|
};
|
|
|
|
|
|
class VariableDeclarationImpl {
|
|
public:
|
|
static VariableDeclaration* ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return VariableDeclaration::ReadFromImpl(reader);
|
|
}
|
|
};
|
|
|
|
|
|
String* String::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return Reference::ReadStringFrom(reader);
|
|
}
|
|
|
|
|
|
String* String::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
uint32_t bytes = reader->ReadUInt();
|
|
String* string = new String(reader->Consume(bytes), bytes);
|
|
return string;
|
|
}
|
|
|
|
void StringTable::ReadFrom(Reader* reader) {
|
|
strings_.ReadFromStatic<StringImpl>(reader);
|
|
}
|
|
|
|
|
|
void SourceTable::ReadFrom(Reader* reader) {
|
|
size_ = reader->helper()->program()->source_uri_table().strings().length();
|
|
source_code_ = new String*[size_];
|
|
line_starts_ = new intptr_t*[size_];
|
|
line_count_ = new intptr_t[size_];
|
|
for (intptr_t i = 0; i < size_; ++i) {
|
|
source_code_[i] = StringImpl::ReadFrom(reader);
|
|
intptr_t line_count = reader->ReadUInt();
|
|
intptr_t* line_starts = new intptr_t[line_count];
|
|
line_count_[i] = line_count;
|
|
intptr_t previous_line_start = 0;
|
|
for (intptr_t j = 0; j < line_count; ++j) {
|
|
intptr_t line_start = reader->ReadUInt() + previous_line_start;
|
|
line_starts[j] = line_start;
|
|
previous_line_start = line_start;
|
|
}
|
|
line_starts_[i] = line_starts;
|
|
}
|
|
}
|
|
|
|
|
|
Library* Library::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
int flags = reader->ReadFlags();
|
|
ASSERT(flags == 0); // external libraries not supported
|
|
name_ = Reference::ReadStringFrom(reader);
|
|
import_uri_ = Reference::ReadStringFrom(reader);
|
|
source_uri_index_ = reader->ReadUInt();
|
|
reader->set_current_script_id(source_uri_index_);
|
|
|
|
int num_classes = reader->ReadUInt();
|
|
classes().EnsureInitialized(num_classes);
|
|
for (int i = 0; i < num_classes; i++) {
|
|
Tag tag = reader->ReadTag();
|
|
if (tag == kNormalClass) {
|
|
NormalClass* klass = classes().GetOrCreate<NormalClass>(i, this);
|
|
klass->ReadFrom(reader);
|
|
} else {
|
|
ASSERT(tag == kMixinClass);
|
|
MixinClass* klass = classes().GetOrCreate<MixinClass>(i, this);
|
|
klass->ReadFrom(reader);
|
|
}
|
|
}
|
|
|
|
fields().ReadFrom<Field>(reader, this);
|
|
procedures().ReadFrom<Procedure>(reader, this);
|
|
return this;
|
|
}
|
|
|
|
|
|
Class* Class::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
|
|
position_ = reader->ReadPosition();
|
|
is_abstract_ = reader->ReadBool();
|
|
name_ = Reference::ReadStringFrom(reader);
|
|
source_uri_index_ = reader->ReadUInt();
|
|
reader->set_current_script_id(source_uri_index_);
|
|
annotations_.ReadFromStatic<Expression>(reader);
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
NormalClass* NormalClass::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Class::ReadFrom(reader);
|
|
TypeParameterScope<ReaderHelper> scope(reader->helper());
|
|
|
|
type_parameters_.ReadFrom(reader);
|
|
DartType* type = reader->ReadOptional<DartType>();
|
|
|
|
super_class_ = InterfaceType::Cast(type);
|
|
implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
|
|
reader);
|
|
fields_.ReadFrom<Field>(reader, this);
|
|
constructors_.ReadFrom<Constructor>(reader, this);
|
|
procedures_.ReadFrom<Procedure>(reader, this);
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
MixinClass* MixinClass::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
TypeParameterScope<ReaderHelper> scope(reader->helper());
|
|
|
|
Class::ReadFrom(reader);
|
|
type_parameters_.ReadFrom(reader);
|
|
first_ = InterfaceType::Cast(DartType::ReadFrom(reader));
|
|
second_ = InterfaceType::Cast(DartType::ReadFrom(reader));
|
|
implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
|
|
reader);
|
|
constructors_.ReadFrom<Constructor>(reader, this);
|
|
return this;
|
|
}
|
|
|
|
|
|
Member* Reference::ReadMemberFrom(Reader* reader, bool allow_null) {
|
|
TRACE_READ_OFFSET();
|
|
|
|
Program* program = reader->helper()->program();
|
|
Tag tag = reader->ReadTag();
|
|
switch (tag) {
|
|
case kLibraryFieldReference: {
|
|
int library_idx = reader->ReadUInt();
|
|
int field_idx = reader->ReadUInt();
|
|
Library* library = program->libraries().GetOrCreate<Library>(library_idx);
|
|
return library->fields().GetOrCreate<Field>(field_idx, library);
|
|
}
|
|
case kLibraryProcedureReference: {
|
|
int library_idx = reader->ReadUInt();
|
|
int procedure_idx = reader->ReadUInt();
|
|
Library* library = program->libraries().GetOrCreate<Library>(library_idx);
|
|
return library->procedures().GetOrCreate<Procedure>(procedure_idx,
|
|
library);
|
|
}
|
|
case kClassFieldReference:
|
|
case kClassConstructorReference:
|
|
case kClassProcedureReference: {
|
|
Class* klass = Reference::ReadClassFrom(reader);
|
|
if (tag == kClassFieldReference) {
|
|
int field_idx = reader->ReadUInt();
|
|
return klass->fields().GetOrCreate<Field>(field_idx, klass);
|
|
} else if (tag == kClassConstructorReference) {
|
|
int constructor_idx = reader->ReadUInt();
|
|
return klass->constructors().GetOrCreate<Constructor>(constructor_idx,
|
|
klass);
|
|
} else {
|
|
ASSERT(tag == kClassProcedureReference);
|
|
int procedure_idx = reader->ReadUInt();
|
|
return klass->procedures().GetOrCreate<Procedure>(procedure_idx, klass);
|
|
}
|
|
}
|
|
case kNullReference:
|
|
if (allow_null) {
|
|
return NULL;
|
|
} else {
|
|
FATAL("Expected a valid member reference, but got `null`");
|
|
}
|
|
default:
|
|
UNREACHABLE();
|
|
break;
|
|
}
|
|
|
|
UNREACHABLE();
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Class* Reference::ReadClassFrom(Reader* reader, bool allow_null) {
|
|
TRACE_READ_OFFSET();
|
|
Program* program = reader->helper()->program();
|
|
|
|
Tag klass_member_tag = reader->ReadTag();
|
|
if (klass_member_tag == kNullReference) {
|
|
if (allow_null) {
|
|
return NULL;
|
|
} else {
|
|
FATAL("Expected a valid class reference but got `null`.");
|
|
}
|
|
}
|
|
int library_idx = reader->ReadUInt();
|
|
int class_idx = reader->ReadUInt();
|
|
|
|
Library* library = program->libraries().GetOrCreate<Library>(library_idx);
|
|
Class* klass;
|
|
if (klass_member_tag == kNormalClassReference) {
|
|
klass = library->classes().GetOrCreate<NormalClass>(class_idx, library);
|
|
} else {
|
|
ASSERT(klass_member_tag == kMixinClassReference);
|
|
klass = library->classes().GetOrCreate<MixinClass>(class_idx, library);
|
|
}
|
|
return klass;
|
|
}
|
|
|
|
|
|
String* Reference::ReadStringFrom(Reader* reader) {
|
|
int index = reader->ReadUInt();
|
|
return reader->helper()->program()->string_table().strings()[index];
|
|
}
|
|
|
|
|
|
Field* Field::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
ASSERT(tag == kField);
|
|
|
|
position_ = reader->ReadPosition();
|
|
end_position_ = reader->ReadPosition();
|
|
flags_ = reader->ReadFlags();
|
|
name_ = Name::ReadFrom(reader);
|
|
source_uri_index_ = reader->ReadUInt();
|
|
reader->set_current_script_id(source_uri_index_);
|
|
annotations_.ReadFromStatic<Expression>(reader);
|
|
type_ = DartType::ReadFrom(reader);
|
|
inferred_value_ = reader->ReadOptional<InferredValue>();
|
|
initializer_ = reader->ReadOptional<Expression>();
|
|
return this;
|
|
}
|
|
|
|
|
|
Constructor* Constructor::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
ASSERT(tag == kConstructor);
|
|
|
|
VariableScope<ReaderHelper> parameters(reader->helper());
|
|
position_ = reader->ReadPosition();
|
|
end_position_ = reader->ReadPosition();
|
|
flags_ = reader->ReadFlags();
|
|
name_ = Name::ReadFrom(reader);
|
|
annotations_.ReadFromStatic<Expression>(reader);
|
|
function_ = FunctionNode::ReadFrom(reader);
|
|
initializers_.ReadFromStatic<Initializer>(reader);
|
|
return this;
|
|
}
|
|
|
|
|
|
Procedure* Procedure::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
ASSERT(tag == kProcedure);
|
|
|
|
VariableScope<ReaderHelper> parameters(reader->helper());
|
|
position_ = reader->ReadPosition();
|
|
end_position_ = reader->ReadPosition();
|
|
kind_ = static_cast<ProcedureKind>(reader->ReadByte());
|
|
flags_ = reader->ReadFlags();
|
|
name_ = Name::ReadFrom(reader);
|
|
source_uri_index_ = reader->ReadUInt();
|
|
reader->set_current_script_id(source_uri_index_);
|
|
annotations_.ReadFromStatic<Expression>(reader);
|
|
function_ = reader->ReadOptional<FunctionNode>();
|
|
return this;
|
|
}
|
|
|
|
|
|
Initializer* Initializer::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
switch (tag) {
|
|
case kInvalidInitializer:
|
|
return InvalidInitializer::ReadFromImpl(reader);
|
|
case kFieldInitializer:
|
|
return FieldInitializer::ReadFromImpl(reader);
|
|
case kSuperInitializer:
|
|
return SuperInitializer::ReadFromImpl(reader);
|
|
case kRedirectingInitializer:
|
|
return RedirectingInitializer::ReadFromImpl(reader);
|
|
case kLocalInitializer:
|
|
return LocalInitializer::ReadFromImpl(reader);
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
InvalidInitializer* InvalidInitializer::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new InvalidInitializer();
|
|
}
|
|
|
|
|
|
FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
FieldInitializer* initializer = new FieldInitializer();
|
|
initializer->field_ = Field::Cast(Reference::ReadMemberFrom(reader));
|
|
initializer->value_ = Expression::ReadFrom(reader);
|
|
return initializer;
|
|
}
|
|
|
|
|
|
SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
SuperInitializer* init = new SuperInitializer();
|
|
init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
|
|
init->arguments_ = Arguments::ReadFrom(reader);
|
|
return init;
|
|
}
|
|
|
|
|
|
RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
RedirectingInitializer* init = new RedirectingInitializer();
|
|
init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
|
|
init->arguments_ = Arguments::ReadFrom(reader);
|
|
return init;
|
|
}
|
|
|
|
|
|
LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
LocalInitializer* init = new LocalInitializer();
|
|
init->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
|
return init;
|
|
}
|
|
|
|
|
|
Expression* Expression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
uint8_t payload = 0;
|
|
Tag tag = reader->ReadTag(&payload);
|
|
switch (tag) {
|
|
case kInvalidExpression:
|
|
return InvalidExpression::ReadFrom(reader);
|
|
case kVariableGet:
|
|
return VariableGet::ReadFrom(reader);
|
|
case kSpecializedVariableGet:
|
|
return VariableGet::ReadFrom(reader, payload);
|
|
case kVariableSet:
|
|
return VariableSet::ReadFrom(reader);
|
|
case kSpecializedVariableSet:
|
|
return VariableSet::ReadFrom(reader, payload);
|
|
case kPropertyGet:
|
|
return PropertyGet::ReadFrom(reader);
|
|
case kPropertySet:
|
|
return PropertySet::ReadFrom(reader);
|
|
case kDirectPropertyGet:
|
|
return DirectPropertyGet::ReadFrom(reader);
|
|
case kDirectPropertySet:
|
|
return DirectPropertySet::ReadFrom(reader);
|
|
case kStaticGet:
|
|
return StaticGet::ReadFrom(reader);
|
|
case kStaticSet:
|
|
return StaticSet::ReadFrom(reader);
|
|
case kMethodInvocation:
|
|
return MethodInvocation::ReadFrom(reader);
|
|
case kDirectMethodInvocation:
|
|
return DirectMethodInvocation::ReadFrom(reader);
|
|
case kStaticInvocation:
|
|
return StaticInvocation::ReadFrom(reader, false);
|
|
case kConstStaticInvocation:
|
|
return StaticInvocation::ReadFrom(reader, true);
|
|
case kConstructorInvocation:
|
|
return ConstructorInvocation::ReadFrom(reader, false);
|
|
case kConstConstructorInvocation:
|
|
return ConstructorInvocation::ReadFrom(reader, true);
|
|
case kNot:
|
|
return Not::ReadFrom(reader);
|
|
case kLogicalExpression:
|
|
return LogicalExpression::ReadFrom(reader);
|
|
case kConditionalExpression:
|
|
return ConditionalExpression::ReadFrom(reader);
|
|
case kStringConcatenation:
|
|
return StringConcatenation::ReadFrom(reader);
|
|
case kIsExpression:
|
|
return IsExpression::ReadFrom(reader);
|
|
case kAsExpression:
|
|
return AsExpression::ReadFrom(reader);
|
|
case kSymbolLiteral:
|
|
return SymbolLiteral::ReadFrom(reader);
|
|
case kTypeLiteral:
|
|
return TypeLiteral::ReadFrom(reader);
|
|
case kThisExpression:
|
|
return ThisExpression::ReadFrom(reader);
|
|
case kRethrow:
|
|
return Rethrow::ReadFrom(reader);
|
|
case kThrow:
|
|
return Throw::ReadFrom(reader);
|
|
case kListLiteral:
|
|
return ListLiteral::ReadFrom(reader, false);
|
|
case kConstListLiteral:
|
|
return ListLiteral::ReadFrom(reader, true);
|
|
case kMapLiteral:
|
|
return MapLiteral::ReadFrom(reader, false);
|
|
case kConstMapLiteral:
|
|
return MapLiteral::ReadFrom(reader, true);
|
|
case kAwaitExpression:
|
|
return AwaitExpression::ReadFrom(reader);
|
|
case kFunctionExpression:
|
|
return FunctionExpression::ReadFrom(reader);
|
|
case kLet:
|
|
return Let::ReadFrom(reader);
|
|
case kBigIntLiteral:
|
|
return BigintLiteral::ReadFrom(reader);
|
|
case kStringLiteral:
|
|
return StringLiteral::ReadFrom(reader);
|
|
case kSpecialIntLiteral:
|
|
return IntLiteral::ReadFrom(reader, payload);
|
|
case kNegativeIntLiteral:
|
|
return IntLiteral::ReadFrom(reader, true);
|
|
case kPositiveIntLiteral:
|
|
return IntLiteral::ReadFrom(reader, false);
|
|
case kDoubleLiteral:
|
|
return DoubleLiteral::ReadFrom(reader);
|
|
case kTrueLiteral:
|
|
return BoolLiteral::ReadFrom(reader, true);
|
|
case kFalseLiteral:
|
|
return BoolLiteral::ReadFrom(reader, false);
|
|
case kNullLiteral:
|
|
return NullLiteral::ReadFrom(reader);
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
InvalidExpression* InvalidExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new InvalidExpression();
|
|
}
|
|
|
|
|
|
VariableGet* VariableGet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
VariableGet* get = new VariableGet();
|
|
get->position_ = reader->ReadPosition();
|
|
get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
|
|
reader->ReadOptional<DartType>(); // Unused promoted type.
|
|
return get;
|
|
}
|
|
|
|
|
|
VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) {
|
|
TRACE_READ_OFFSET();
|
|
VariableGet* get = new VariableGet();
|
|
get->position_ = reader->ReadPosition();
|
|
get->variable_ = reader->helper()->variables().Lookup(payload);
|
|
return get;
|
|
}
|
|
|
|
|
|
VariableSet* VariableSet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
VariableSet* set = new VariableSet();
|
|
set->position_ = reader->ReadPosition();
|
|
set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
|
|
set->expression_ = Expression::ReadFrom(reader);
|
|
return set;
|
|
}
|
|
|
|
|
|
VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) {
|
|
TRACE_READ_OFFSET();
|
|
VariableSet* set = new VariableSet();
|
|
set->variable_ = reader->helper()->variables().Lookup(payload);
|
|
set->position_ = reader->ReadPosition();
|
|
set->expression_ = Expression::ReadFrom(reader);
|
|
return set;
|
|
}
|
|
|
|
|
|
PropertyGet* PropertyGet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
PropertyGet* get = new PropertyGet();
|
|
get->position_ = reader->ReadPosition();
|
|
get->receiver_ = Expression::ReadFrom(reader);
|
|
get->name_ = Name::ReadFrom(reader);
|
|
get->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
|
|
return get;
|
|
}
|
|
|
|
|
|
PropertySet* PropertySet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
PropertySet* set = new PropertySet();
|
|
set->position_ = reader->ReadPosition();
|
|
set->receiver_ = Expression::ReadFrom(reader);
|
|
set->name_ = Name::ReadFrom(reader);
|
|
set->value_ = Expression::ReadFrom(reader);
|
|
set->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
|
|
return set;
|
|
}
|
|
|
|
|
|
DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
DirectPropertyGet* get = new DirectPropertyGet();
|
|
get->receiver_ = Expression::ReadFrom(reader);
|
|
get->target_ = Reference::ReadMemberFrom(reader);
|
|
return get;
|
|
}
|
|
|
|
|
|
DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
DirectPropertySet* set = new DirectPropertySet();
|
|
set->receiver_ = Expression::ReadFrom(reader);
|
|
set->target_ = Reference::ReadMemberFrom(reader);
|
|
set->value_ = Expression::ReadFrom(reader);
|
|
return set;
|
|
}
|
|
|
|
|
|
StaticGet* StaticGet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
StaticGet* get = new StaticGet();
|
|
get->position_ = reader->ReadPosition();
|
|
get->target_ = Reference::ReadMemberFrom(reader);
|
|
return get;
|
|
}
|
|
|
|
|
|
StaticSet* StaticSet::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
StaticSet* set = new StaticSet();
|
|
set->target_ = Reference::ReadMemberFrom(reader);
|
|
set->expression_ = Expression::ReadFrom(reader);
|
|
return set;
|
|
}
|
|
|
|
|
|
Arguments* Arguments::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Arguments* arguments = new Arguments();
|
|
arguments->types().ReadFromStatic<DartType>(reader);
|
|
arguments->positional().ReadFromStatic<Expression>(reader);
|
|
arguments->named().ReadFromStatic<NamedExpression>(reader);
|
|
return arguments;
|
|
}
|
|
|
|
|
|
NamedExpression* NamedExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
String* name = Reference::ReadStringFrom(reader);
|
|
Expression* expression = Expression::ReadFrom(reader);
|
|
return new NamedExpression(name, expression);
|
|
}
|
|
|
|
|
|
MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
MethodInvocation* invocation = new MethodInvocation();
|
|
invocation->position_ = reader->ReadPosition();
|
|
invocation->receiver_ = Expression::ReadFrom(reader);
|
|
invocation->name_ = Name::ReadFrom(reader);
|
|
invocation->arguments_ = Arguments::ReadFrom(reader);
|
|
invocation->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
|
|
return invocation;
|
|
}
|
|
|
|
|
|
DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
DirectMethodInvocation* invocation = new DirectMethodInvocation();
|
|
invocation->receiver_ = Expression::ReadFrom(reader);
|
|
invocation->target_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
|
|
invocation->arguments_ = Arguments::ReadFrom(reader);
|
|
return invocation;
|
|
}
|
|
|
|
|
|
StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) {
|
|
TRACE_READ_OFFSET();
|
|
StaticInvocation* invocation = new StaticInvocation();
|
|
invocation->is_const_ = is_const;
|
|
invocation->position_ = reader->ReadPosition();
|
|
invocation->procedure_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
|
|
invocation->arguments_ = Arguments::ReadFrom(reader);
|
|
return invocation;
|
|
}
|
|
|
|
|
|
ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader,
|
|
bool is_const) {
|
|
TRACE_READ_OFFSET();
|
|
ConstructorInvocation* invocation = new ConstructorInvocation();
|
|
invocation->is_const_ = is_const;
|
|
invocation->position_ = reader->ReadPosition();
|
|
invocation->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
|
|
invocation->arguments_ = Arguments::ReadFrom(reader);
|
|
return invocation;
|
|
}
|
|
|
|
|
|
Not* Not::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Not* n = new Not();
|
|
n->expression_ = Expression::ReadFrom(reader);
|
|
return n;
|
|
}
|
|
|
|
|
|
LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
LogicalExpression* expr = new LogicalExpression();
|
|
expr->left_ = Expression::ReadFrom(reader);
|
|
expr->operator_ = static_cast<Operator>(reader->ReadByte());
|
|
expr->right_ = Expression::ReadFrom(reader);
|
|
return expr;
|
|
}
|
|
|
|
|
|
ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
ConditionalExpression* expr = new ConditionalExpression();
|
|
expr->condition_ = Expression::ReadFrom(reader);
|
|
expr->then_ = Expression::ReadFrom(reader);
|
|
expr->otherwise_ = Expression::ReadFrom(reader);
|
|
reader->ReadOptional<DartType>(); // Unused static type.
|
|
return expr;
|
|
}
|
|
|
|
|
|
StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
StringConcatenation* concat = new StringConcatenation();
|
|
concat->position_ = reader->ReadPosition();
|
|
concat->expressions_.ReadFromStatic<Expression>(reader);
|
|
return concat;
|
|
}
|
|
|
|
|
|
IsExpression* IsExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
IsExpression* expr = new IsExpression();
|
|
expr->position_ = reader->ReadPosition();
|
|
expr->operand_ = Expression::ReadFrom(reader);
|
|
expr->type_ = DartType::ReadFrom(reader);
|
|
return expr;
|
|
}
|
|
|
|
|
|
AsExpression* AsExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
AsExpression* expr = new AsExpression();
|
|
expr->operand_ = Expression::ReadFrom(reader);
|
|
expr->type_ = DartType::ReadFrom(reader);
|
|
return expr;
|
|
}
|
|
|
|
|
|
StringLiteral* StringLiteral::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new StringLiteral(Reference::ReadStringFrom(reader));
|
|
}
|
|
|
|
|
|
BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new BigintLiteral(Reference::ReadStringFrom(reader));
|
|
}
|
|
|
|
|
|
IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) {
|
|
TRACE_READ_OFFSET();
|
|
IntLiteral* literal = new IntLiteral();
|
|
literal->value_ = is_negative ? -static_cast<int64_t>(reader->ReadUInt())
|
|
: reader->ReadUInt();
|
|
return literal;
|
|
}
|
|
|
|
|
|
IntLiteral* IntLiteral::ReadFrom(Reader* reader, uint8_t payload) {
|
|
TRACE_READ_OFFSET();
|
|
IntLiteral* literal = new IntLiteral();
|
|
literal->value_ = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
|
|
return literal;
|
|
}
|
|
|
|
|
|
DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
DoubleLiteral* literal = new DoubleLiteral();
|
|
literal->value_ = Reference::ReadStringFrom(reader);
|
|
return literal;
|
|
}
|
|
|
|
|
|
BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) {
|
|
TRACE_READ_OFFSET();
|
|
BoolLiteral* lit = new BoolLiteral();
|
|
lit->value_ = value;
|
|
return lit;
|
|
}
|
|
|
|
|
|
NullLiteral* NullLiteral::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new NullLiteral();
|
|
}
|
|
|
|
|
|
SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
SymbolLiteral* lit = new SymbolLiteral();
|
|
lit->value_ = Reference::ReadStringFrom(reader);
|
|
return lit;
|
|
}
|
|
|
|
|
|
TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
TypeLiteral* literal = new TypeLiteral();
|
|
literal->type_ = DartType::ReadFrom(reader);
|
|
return literal;
|
|
}
|
|
|
|
|
|
ThisExpression* ThisExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new ThisExpression();
|
|
}
|
|
|
|
|
|
Rethrow* Rethrow::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new Rethrow();
|
|
}
|
|
|
|
|
|
Throw* Throw::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Throw* t = new Throw();
|
|
t->position_ = reader->ReadPosition();
|
|
t->expression_ = Expression::ReadFrom(reader);
|
|
return t;
|
|
}
|
|
|
|
|
|
ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) {
|
|
TRACE_READ_OFFSET();
|
|
ListLiteral* literal = new ListLiteral();
|
|
literal->is_const_ = is_const;
|
|
literal->type_ = DartType::ReadFrom(reader);
|
|
literal->expressions_.ReadFromStatic<Expression>(reader);
|
|
return literal;
|
|
}
|
|
|
|
|
|
MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) {
|
|
TRACE_READ_OFFSET();
|
|
MapLiteral* literal = new MapLiteral();
|
|
literal->is_const_ = is_const;
|
|
literal->position_ = reader->ReadPosition();
|
|
literal->key_type_ = DartType::ReadFrom(reader);
|
|
literal->value_type_ = DartType::ReadFrom(reader);
|
|
literal->entries_.ReadFromStatic<MapEntry>(reader);
|
|
return literal;
|
|
}
|
|
|
|
|
|
MapEntry* MapEntry::ReadFrom(Reader* reader) {
|
|
MapEntry* entry = new MapEntry();
|
|
entry->key_ = Expression::ReadFrom(reader);
|
|
entry->value_ = Expression::ReadFrom(reader);
|
|
return entry;
|
|
}
|
|
|
|
|
|
AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
AwaitExpression* await = new AwaitExpression();
|
|
await->operand_ = Expression::ReadFrom(reader);
|
|
return await;
|
|
}
|
|
|
|
|
|
FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
VariableScope<ReaderHelper> parameters(reader->helper());
|
|
FunctionExpression* expr = new FunctionExpression();
|
|
expr->function_ = FunctionNode::ReadFrom(reader);
|
|
return expr;
|
|
}
|
|
|
|
|
|
Let* Let::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
VariableScope<ReaderHelper> vars(reader->helper());
|
|
PositionScope scope(reader);
|
|
|
|
Let* let = new Let();
|
|
let->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
|
let->body_ = Expression::ReadFrom(reader);
|
|
let->position_ = reader->min_position();
|
|
let->end_position_ = reader->max_position();
|
|
|
|
return let;
|
|
}
|
|
|
|
|
|
Statement* Statement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
switch (tag) {
|
|
case kInvalidStatement:
|
|
return InvalidStatement::ReadFrom(reader);
|
|
case kExpressionStatement:
|
|
return ExpressionStatement::ReadFrom(reader);
|
|
case kBlock:
|
|
return Block::ReadFromImpl(reader);
|
|
case kEmptyStatement:
|
|
return EmptyStatement::ReadFrom(reader);
|
|
case kAssertStatement:
|
|
return AssertStatement::ReadFrom(reader);
|
|
case kLabeledStatement:
|
|
return LabeledStatement::ReadFrom(reader);
|
|
case kBreakStatement:
|
|
return BreakStatement::ReadFrom(reader);
|
|
case kWhileStatement:
|
|
return WhileStatement::ReadFrom(reader);
|
|
case kDoStatement:
|
|
return DoStatement::ReadFrom(reader);
|
|
case kForStatement:
|
|
return ForStatement::ReadFrom(reader);
|
|
case kForInStatement:
|
|
return ForInStatement::ReadFrom(reader, false);
|
|
case kAsyncForInStatement:
|
|
return ForInStatement::ReadFrom(reader, true);
|
|
case kSwitchStatement:
|
|
return SwitchStatement::ReadFrom(reader);
|
|
case kContinueSwitchStatement:
|
|
return ContinueSwitchStatement::ReadFrom(reader);
|
|
case kIfStatement:
|
|
return IfStatement::ReadFrom(reader);
|
|
case kReturnStatement:
|
|
return ReturnStatement::ReadFrom(reader);
|
|
case kTryCatch:
|
|
return TryCatch::ReadFrom(reader);
|
|
case kTryFinally:
|
|
return TryFinally::ReadFrom(reader);
|
|
case kYieldStatement:
|
|
return YieldStatement::ReadFrom(reader);
|
|
case kVariableDeclaration:
|
|
return VariableDeclaration::ReadFromImpl(reader);
|
|
case kFunctionDeclaration:
|
|
return FunctionDeclaration::ReadFrom(reader);
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new InvalidStatement();
|
|
}
|
|
|
|
|
|
ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new ExpressionStatement(Expression::ReadFrom(reader));
|
|
}
|
|
|
|
|
|
Block* Block::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
PositionScope scope(reader);
|
|
|
|
VariableScope<ReaderHelper> vars(reader->helper());
|
|
Block* block = new Block();
|
|
block->statements().ReadFromStatic<Statement>(reader);
|
|
block->position_ = reader->min_position();
|
|
block->end_position_ = reader->max_position();
|
|
|
|
return block;
|
|
}
|
|
|
|
|
|
EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new EmptyStatement();
|
|
}
|
|
|
|
|
|
AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
AssertStatement* stmt = new AssertStatement();
|
|
stmt->condition_ = Expression::ReadFrom(reader);
|
|
stmt->message_ = reader->ReadOptional<Expression>();
|
|
return stmt;
|
|
}
|
|
|
|
|
|
LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
LabeledStatement* stmt = new LabeledStatement();
|
|
reader->helper()->labels()->Push(stmt);
|
|
stmt->body_ = Statement::ReadFrom(reader);
|
|
reader->helper()->labels()->Pop(stmt);
|
|
return stmt;
|
|
}
|
|
|
|
|
|
BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
BreakStatement* stmt = new BreakStatement();
|
|
stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt());
|
|
return stmt;
|
|
}
|
|
|
|
|
|
WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
WhileStatement* stmt = new WhileStatement();
|
|
stmt->condition_ = Expression::ReadFrom(reader);
|
|
stmt->body_ = Statement::ReadFrom(reader);
|
|
return stmt;
|
|
}
|
|
|
|
|
|
DoStatement* DoStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
DoStatement* dostmt = new DoStatement();
|
|
dostmt->body_ = Statement::ReadFrom(reader);
|
|
dostmt->condition_ = Expression::ReadFrom(reader);
|
|
return dostmt;
|
|
}
|
|
|
|
|
|
ForStatement* ForStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
VariableScope<ReaderHelper> vars(reader->helper());
|
|
PositionScope scope(reader);
|
|
|
|
ForStatement* forstmt = new ForStatement();
|
|
forstmt->variables_.ReadFromStatic<VariableDeclarationImpl>(reader);
|
|
forstmt->condition_ = reader->ReadOptional<Expression>();
|
|
forstmt->updates_.ReadFromStatic<Expression>(reader);
|
|
forstmt->body_ = Statement::ReadFrom(reader);
|
|
forstmt->end_position_ = reader->max_position();
|
|
forstmt->position_ = reader->min_position();
|
|
|
|
return forstmt;
|
|
}
|
|
|
|
|
|
ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) {
|
|
TRACE_READ_OFFSET();
|
|
VariableScope<ReaderHelper> vars(reader->helper());
|
|
PositionScope scope(reader);
|
|
|
|
ForInStatement* forinstmt = new ForInStatement();
|
|
forinstmt->is_async_ = is_async;
|
|
forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
|
forinstmt->iterable_ = Expression::ReadFrom(reader);
|
|
forinstmt->body_ = Statement::ReadFrom(reader);
|
|
forinstmt->end_position_ = reader->max_position();
|
|
forinstmt->position_ = reader->min_position();
|
|
|
|
return forinstmt;
|
|
}
|
|
|
|
|
|
SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
SwitchCaseScope<ReaderHelper> scope(reader->helper());
|
|
SwitchStatement* stmt = new SwitchStatement();
|
|
stmt->condition_ = Expression::ReadFrom(reader);
|
|
// We need to explicitly create empty [SwitchCase]s first in order to add them
|
|
// to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch
|
|
// case can refer to one defined later on.
|
|
int count = reader->ReadUInt();
|
|
for (int i = 0; i < count; i++) {
|
|
SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
|
|
reader->helper()->switch_cases().Push(sc);
|
|
}
|
|
for (int i = 0; i < count; i++) {
|
|
SwitchCase* sc = stmt->cases_[i];
|
|
sc->ReadFrom(reader);
|
|
}
|
|
return stmt;
|
|
}
|
|
|
|
|
|
SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
expressions_.ReadFromStatic<Expression>(reader);
|
|
is_default_ = reader->ReadBool();
|
|
body_ = Statement::ReadFrom(reader);
|
|
return this;
|
|
}
|
|
|
|
|
|
ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
|
|
stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt());
|
|
return stmt;
|
|
}
|
|
|
|
|
|
IfStatement* IfStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
IfStatement* ifstmt = new IfStatement();
|
|
ifstmt->condition_ = Expression::ReadFrom(reader);
|
|
ifstmt->then_ = Statement::ReadFrom(reader);
|
|
ifstmt->otherwise_ = Statement::ReadFrom(reader);
|
|
return ifstmt;
|
|
}
|
|
|
|
|
|
ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
ReturnStatement* ret = new ReturnStatement();
|
|
ret->position_ = reader->ReadPosition();
|
|
ret->expression_ = reader->ReadOptional<Expression>();
|
|
return ret;
|
|
}
|
|
|
|
|
|
TryCatch* TryCatch::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
PositionScope scope(reader);
|
|
|
|
TryCatch* tc = new TryCatch();
|
|
tc->body_ = Statement::ReadFrom(reader);
|
|
tc->catches_.ReadFromStatic<Catch>(reader);
|
|
tc->position_ = reader->min_position();
|
|
|
|
return tc;
|
|
}
|
|
|
|
|
|
Catch* Catch::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
VariableScope<ReaderHelper> vars(reader->helper());
|
|
PositionScope scope(reader);
|
|
|
|
Catch* c = new Catch();
|
|
c->guard_ = DartType::ReadFrom(reader);
|
|
c->exception_ =
|
|
reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
|
|
c->stack_trace_ =
|
|
reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
|
|
c->body_ = Statement::ReadFrom(reader);
|
|
c->end_position_ = reader->max_position();
|
|
c->position_ = reader->min_position();
|
|
|
|
return c;
|
|
}
|
|
|
|
|
|
TryFinally* TryFinally::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
TryFinally* tf = new TryFinally();
|
|
tf->body_ = Statement::ReadFrom(reader);
|
|
tf->finalizer_ = Statement::ReadFrom(reader);
|
|
return tf;
|
|
}
|
|
|
|
|
|
YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
YieldStatement* stmt = new YieldStatement();
|
|
stmt->position_ = reader->ReadPosition();
|
|
stmt->flags_ = reader->ReadByte();
|
|
stmt->expression_ = Expression::ReadFrom(reader);
|
|
return stmt;
|
|
}
|
|
|
|
|
|
VariableDeclaration* VariableDeclaration::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
ASSERT(tag == kVariableDeclaration);
|
|
return VariableDeclaration::ReadFromImpl(reader);
|
|
}
|
|
|
|
|
|
VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
PositionScope scope(reader);
|
|
|
|
VariableDeclaration* decl = new VariableDeclaration();
|
|
decl->position_ = reader->ReadPosition();
|
|
decl->flags_ = reader->ReadFlags();
|
|
decl->name_ = Reference::ReadStringFrom(reader);
|
|
decl->type_ = DartType::ReadFrom(reader);
|
|
decl->inferred_value_ = reader->ReadOptional<InferredValue>();
|
|
decl->initializer_ = reader->ReadOptional<Expression>();
|
|
|
|
// Go to next token position so it ends *after* the last potentially
|
|
// debuggable position in the initializer.
|
|
TokenPosition position = reader->max_position();
|
|
if (position.IsReal()) position.Next();
|
|
decl->end_position_ = position;
|
|
reader->helper()->variables().Push(decl);
|
|
|
|
return decl;
|
|
}
|
|
|
|
|
|
FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
FunctionDeclaration* decl = new FunctionDeclaration();
|
|
decl->position_ = reader->ReadPosition();
|
|
decl->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
|
VariableScope<ReaderHelper> parameters(reader->helper());
|
|
decl->function_ = FunctionNode::ReadFrom(reader);
|
|
return decl;
|
|
}
|
|
|
|
|
|
Name* Name::ReadFrom(Reader* reader) {
|
|
String* string = Reference::ReadStringFrom(reader);
|
|
if (string->size() >= 1 && string->buffer()[0] == '_') {
|
|
int lib_index = reader->ReadUInt();
|
|
Library* library =
|
|
reader->helper()->program()->libraries().GetOrCreate<Library>(
|
|
lib_index);
|
|
return new Name(string, library);
|
|
} else {
|
|
return new Name(string, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
InferredValue* InferredValue::ReadFrom(Reader* reader) {
|
|
InferredValue* type = new InferredValue();
|
|
type->klass_ = Reference::ReadClassFrom(reader, true);
|
|
type->kind_ = static_cast<BaseClassKind>(reader->ReadByte());
|
|
type->value_bits_ = reader->ReadByte();
|
|
return type;
|
|
}
|
|
|
|
|
|
DartType* DartType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Tag tag = reader->ReadTag();
|
|
switch (tag) {
|
|
case kInvalidType:
|
|
return InvalidType::ReadFrom(reader);
|
|
case kDynamicType:
|
|
return DynamicType::ReadFrom(reader);
|
|
case kVoidType:
|
|
return VoidType::ReadFrom(reader);
|
|
case kInterfaceType:
|
|
return InterfaceType::ReadFrom(reader);
|
|
case kSimpleInterfaceType:
|
|
return InterfaceType::ReadFrom(reader, true);
|
|
case kFunctionType:
|
|
return FunctionType::ReadFrom(reader);
|
|
case kSimpleFunctionType:
|
|
return FunctionType::ReadFrom(reader, true);
|
|
case kTypeParameterType:
|
|
return TypeParameterType::ReadFrom(reader);
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
UNREACHABLE();
|
|
return NULL;
|
|
}
|
|
|
|
|
|
InvalidType* InvalidType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new InvalidType();
|
|
}
|
|
|
|
|
|
DynamicType* DynamicType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new DynamicType();
|
|
}
|
|
|
|
|
|
VoidType* VoidType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
return new VoidType();
|
|
}
|
|
|
|
|
|
InterfaceType* InterfaceType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
Class* klass = Reference::ReadClassFrom(reader);
|
|
InterfaceType* type = new InterfaceType(klass);
|
|
type->type_arguments().ReadFromStatic<DartType>(reader);
|
|
return type;
|
|
}
|
|
|
|
|
|
InterfaceType* InterfaceType::ReadFrom(Reader* reader,
|
|
bool _without_type_arguments_) {
|
|
TRACE_READ_OFFSET();
|
|
Class* klass = Reference::ReadClassFrom(reader);
|
|
InterfaceType* type = new InterfaceType(klass);
|
|
ASSERT(_without_type_arguments_);
|
|
return type;
|
|
}
|
|
|
|
|
|
FunctionType* FunctionType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
FunctionType* type = new FunctionType();
|
|
TypeParameterScope<ReaderHelper> scope(reader->helper());
|
|
type->type_parameters().ReadFrom(reader);
|
|
type->required_parameter_count_ = reader->ReadUInt();
|
|
type->positional_parameters().ReadFromStatic<DartType>(reader);
|
|
type->named_parameters().ReadFromStatic<Tuple<String, DartType> >(reader);
|
|
type->return_type_ = DartType::ReadFrom(reader);
|
|
return type;
|
|
}
|
|
|
|
|
|
FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) {
|
|
TRACE_READ_OFFSET();
|
|
FunctionType* type = new FunctionType();
|
|
ASSERT(_is_simple_);
|
|
type->positional_parameters().ReadFromStatic<DartType>(reader);
|
|
type->required_parameter_count_ = type->positional_parameters().length();
|
|
type->return_type_ = DartType::ReadFrom(reader);
|
|
return type;
|
|
}
|
|
|
|
|
|
TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
TypeParameterType* type = new TypeParameterType();
|
|
type->parameter_ =
|
|
reader->helper()->type_parameters().Lookup(reader->ReadUInt());
|
|
return type;
|
|
}
|
|
|
|
|
|
Program* Program::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
uint32_t magic = reader->ReadUInt32();
|
|
if (magic != kMagicProgramFile) FATAL("Invalid magic identifier");
|
|
|
|
Program* program = new Program();
|
|
reader->helper()->set_program(program);
|
|
|
|
program->string_table_.ReadFrom(reader);
|
|
program->source_uri_table_.ReadFrom(reader);
|
|
program->source_table_.ReadFrom(reader);
|
|
|
|
int libraries = reader->ReadUInt();
|
|
program->libraries().EnsureInitialized(libraries);
|
|
for (int i = 0; i < libraries; i++) {
|
|
program->libraries().GetOrCreate<Library>(i)->ReadFrom(reader);
|
|
}
|
|
|
|
program->main_method_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
|
|
|
|
return program;
|
|
}
|
|
|
|
|
|
FunctionNode* FunctionNode::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
TypeParameterScope<ReaderHelper> scope(reader->helper());
|
|
|
|
FunctionNode* function = new FunctionNode();
|
|
function->position_ = reader->ReadPosition();
|
|
function->end_position_ = reader->ReadPosition();
|
|
function->async_marker_ =
|
|
static_cast<FunctionNode::AsyncMarker>(reader->ReadByte());
|
|
function->debuggable_ = reader->ReadByte() == 1 ? true : false;
|
|
function->type_parameters().ReadFrom(reader);
|
|
function->required_parameter_count_ = reader->ReadUInt();
|
|
function->positional_parameters().ReadFromStatic<VariableDeclarationImpl>(
|
|
reader);
|
|
function->named_parameters().ReadFromStatic<VariableDeclarationImpl>(reader);
|
|
function->return_type_ = DartType::ReadFrom(reader);
|
|
function->inferred_return_value_ = reader->ReadOptional<InferredValue>();
|
|
|
|
LabelScope<ReaderHelper, BlockStack<LabeledStatement> > labels(
|
|
reader->helper());
|
|
VariableScope<ReaderHelper> vars(reader->helper());
|
|
function->body_ = reader->ReadOptional<Statement>();
|
|
return function;
|
|
}
|
|
|
|
|
|
TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
|
|
TRACE_READ_OFFSET();
|
|
name_ = Reference::ReadStringFrom(reader);
|
|
bound_ = DartType::ReadFrom(reader);
|
|
return this;
|
|
}
|
|
|
|
|
|
} // namespace kernel
|
|
|
|
|
|
kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
|
|
intptr_t buffer_length) {
|
|
kernel::Reader reader(buffer, buffer_length);
|
|
return kernel::Program::ReadFrom(&reader);
|
|
}
|
|
|
|
|
|
} // namespace dart
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|