Chromium Code Reviews| Index: runtime/vm/kernel_binary_flowgraph.cc |
| diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc |
| index 873182c146aae5cfd9cf840ac04f5b75492877b3..f65488af1f70c6ffd51ae79d14dfed33d0f5beee 100644 |
| --- a/runtime/vm/kernel_binary_flowgraph.cc |
| +++ b/runtime/vm/kernel_binary_flowgraph.cc |
| @@ -9,14 +9,17 @@ |
| namespace dart { |
| namespace kernel { |
| -Fragment StreamingFlowGraphBuilder::BuildAt(int64_t kernel_offset) { |
| +#define Z (flow_graph_builder_->zone_) |
| +#define H (flow_graph_builder_->translation_helper_) |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildAt(intptr_t kernel_offset) { |
| reader_->set_offset(kernel_offset); |
| uint8_t payload = 0; |
| Tag tag = reader_->ReadTag(&payload); |
| switch (tag) { |
| - // case kInvalidExpression: |
| - // return InvalidExpression::ReadFrom(reader_); |
| + case kInvalidExpression: |
| + return BuildInvalidExpression(); |
| // case kVariableGet: |
| // return VariableGet::ReadFrom(reader_); |
| // case kSpecializedVariableGet: |
| @@ -65,8 +68,8 @@ Fragment StreamingFlowGraphBuilder::BuildAt(int64_t kernel_offset) { |
| // return SymbolLiteral::ReadFrom(reader_); |
| // case kTypeLiteral: |
| // return TypeLiteral::ReadFrom(reader_); |
| - // case kThisExpression: |
| - // return ThisExpression::ReadFrom(reader_); |
| + case kThisExpression: |
| + return BuildThisExpression(); |
| case kRethrow: |
| return BuildRethrow(); |
| // case kThrow: |
| @@ -87,22 +90,22 @@ Fragment StreamingFlowGraphBuilder::BuildAt(int64_t kernel_offset) { |
| // 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 kStringLiteral: |
| + return BuildStringLiteral(); |
| + case kSpecialIntLiteral: |
| + return BuildIntLiteral(payload); |
| + case kNegativeIntLiteral: |
| + return BuildIntLiteral(true); |
| + case kPositiveIntLiteral: |
| + return BuildIntLiteral(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_); |
| + case kTrueLiteral: |
| + return BuildBoolLiteral(true); |
| + case kFalseLiteral: |
| + return BuildBoolLiteral(false); |
| + case kNullLiteral: |
| + return BuildNullLiteral(); |
| default: |
| UNREACHABLE(); |
| } |
| @@ -110,6 +113,40 @@ Fragment StreamingFlowGraphBuilder::BuildAt(int64_t kernel_offset) { |
| return Fragment(); |
| } |
| +intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) { |
| + if (string_table_offsets_ != NULL && string_table_entries_read_ > index) { |
| + return string_table_offsets_[index]; |
| + } |
| + if (string_table_offsets_ == NULL) { |
| + reader_->set_offset(4); // Skip kMagicProgramFile - now at string table. |
| + string_table_size_ = ReadListLength(); |
| + string_table_offsets_ = new intptr_t[string_table_size_]; |
| + string_table_offsets_[0] = reader_->offset(); |
| + string_table_entries_read_ = 1; |
| + } |
| + |
| + ASSERT(string_table_size_ > index); |
| + --string_table_entries_read_; |
| + reader_->set_offset(string_table_offsets_[string_table_entries_read_]); |
| + for (; string_table_entries_read_ < index; ++string_table_entries_read_) { |
| + string_table_offsets_[string_table_entries_read_] = reader_->offset(); |
| + uint32_t bytes = ReadUInt(); |
| + reader_->set_offset(reader_->offset() + bytes); |
| + } |
| + string_table_offsets_[string_table_entries_read_] = reader_->offset(); |
| + ++string_table_entries_read_; |
| + |
| + return string_table_offsets_[index]; |
| +} |
| + |
| +uint32_t StreamingFlowGraphBuilder::ReadUInt() { |
| + return reader_->ReadUInt(); |
| +} |
| + |
| +intptr_t StreamingFlowGraphBuilder::ReadListLength() { |
| + return reader_->ReadListLength(); |
| +} |
| + |
| TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) { |
| return reader_->ReadPosition(record); |
| } |
| @@ -118,6 +155,10 @@ CatchBlock* StreamingFlowGraphBuilder::catch_block() { |
| return flow_graph_builder_->catch_block_; |
| } |
| +ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() { |
| + return flow_graph_builder_->scopes_; |
| +} |
| + |
| Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) { |
| return flow_graph_builder_->DebugStepCheck(position); |
| } |
| @@ -135,6 +176,29 @@ Fragment StreamingFlowGraphBuilder::RethrowException(TokenPosition position, |
| return flow_graph_builder_->RethrowException(position, catch_try_index); |
| } |
| +Fragment StreamingFlowGraphBuilder::ThrowNoSuchMethodError() { |
| + return flow_graph_builder_->ThrowNoSuchMethodError(); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::Constant(const Object& value) { |
| + return flow_graph_builder_->Constant(value); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::IntConstant(int64_t value) { |
| + return flow_graph_builder_->IntConstant(value); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() { |
| + // The frontend will take care of emitting normal errors (like |
| + // [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special |
| + // situations (e.g. an invalid annotation). |
| + return ThrowNoSuchMethodError(); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildThisExpression() { |
| + return LoadLocal(scopes()->this_variable); |
| +} |
| + |
| Fragment StreamingFlowGraphBuilder::BuildRethrow() { |
| TokenPosition position = ReadPosition(); |
| Fragment instructions = DebugStepCheck(position); |
| @@ -147,6 +211,36 @@ Fragment StreamingFlowGraphBuilder::BuildRethrow() { |
| return instructions; |
| } |
| +Fragment StreamingFlowGraphBuilder::BuildStringLiteral() { |
| + int str_index = ReadUInt(); |
| + intptr_t savedOffset = reader_->offset(); |
|
Kevin Millikin (Google)
2017/03/31 12:05:41
Maybe it would be convenient to have a helper to r
|
| + |
| + reader_->set_offset(GetStringTableOffset(str_index)); |
| + uint32_t bytes = ReadUInt(); |
| + const uint8_t* data = &reader_->buffer()[reader_->offset()]; |
| + |
| + reader_->set_offset(savedOffset); |
| + return Constant(H.DartSymbol(data, bytes)); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload) { |
| + int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias; |
| + return IntConstant(value); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative) { |
| + int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt()) : ReadUInt(); |
| + return IntConstant(value); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value) { |
| + return Constant(Bool::Get(value)); |
| +} |
| + |
| +Fragment StreamingFlowGraphBuilder::BuildNullLiteral() { |
| + return Constant(Instance::ZoneHandle(Z, Instance::null())); |
| +} |
| + |
| } // namespace kernel |
| } // namespace dart |