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 |