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

Unified Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 2794473002: Stream StaticGet (Closed)
Patch Set: Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_to_il.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/kernel_binary_flowgraph.cc
diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc
index de0c1f36c8b5a23e938bb8b2679e4c8379a5215f..3fdd7a26aba7510267d8ee8b9e0e6a81561bb2f8 100644
--- a/runtime/vm/kernel_binary_flowgraph.cc
+++ b/runtime/vm/kernel_binary_flowgraph.cc
@@ -38,6 +38,9 @@ Instance& StreamingConstantEvaluator::EvaluateExpression() {
uint8_t payload = 0;
Tag tag = builder_->ReadTag(&payload);
switch (tag) {
+ case kStaticGet:
+ EvaluateStaticGet();
+ break;
case kSymbolLiteral:
EvaluateSymbolLiteral();
break;
@@ -55,6 +58,41 @@ Instance& StreamingConstantEvaluator::EvaluateExpression() {
return dart::Instance::ZoneHandle(Z, result_.raw());
}
+void StreamingConstantEvaluator::EvaluateStaticGet() {
+ builder_->ReadPosition();
+ int canonical_name_index = builder_->ReadUInt();
+ CanonicalName* target = builder_->GetCanonicalName(canonical_name_index);
+
+ if (target->IsField()) {
+ const dart::Field& field =
+ dart::Field::Handle(Z, H.LookupFieldByKernelField(target));
+ if (field.StaticValue() == Object::sentinel().raw() ||
+ field.StaticValue() == Object::transition_sentinel().raw()) {
+ field.EvaluateInitializer();
+ result_ = field.StaticValue();
+ result_ = H.Canonicalize(result_);
+ field.SetStaticValue(result_, true);
+ } else {
+ result_ = field.StaticValue();
+ }
+ } else if (target->IsProcedure()) {
+ const Function& function =
+ Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
+
+ if (target->IsMethod()) {
+ Function& closure_function =
+ Function::ZoneHandle(Z, function.ImplicitClosureFunction());
+ closure_function.set_kernel_function(function.kernel_function());
+ result_ = closure_function.ImplicitStaticClosure();
+ result_ = H.Canonicalize(result_);
+ } else if (target->IsGetter()) {
+ UNIMPLEMENTED();
+ } else {
+ UNIMPLEMENTED();
+ }
+ }
+}
+
void StreamingConstantEvaluator::EvaluateSymbolLiteral() {
int str_index = builder_->ReadUInt();
const dart::String& symbol_value = builder_->DartSymbol(str_index);
@@ -192,8 +230,8 @@ Fragment StreamingFlowGraphBuilder::BuildAt(intptr_t kernel_offset) {
// return DirectPropertyGet::ReadFrom(reader_);
// case kDirectPropertySet:
// return DirectPropertySet::ReadFrom(reader_);
- // case kStaticGet:
- // return StaticGet::ReadFrom(reader_);
+ case kStaticGet:
+ return BuildStaticGet();
// case kStaticSet:
// return StaticSet::ReadFrom(reader_);
// case kMethodInvocation:
@@ -273,6 +311,8 @@ intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) {
if (string_table_offsets_ != NULL && string_table_entries_read_ > index) {
return string_table_offsets_[index];
}
+
+ intptr_t saved_offset = ReaderOffset();
if (string_table_offsets_ == NULL) {
reader_->set_offset(4); // Skip kMagicProgramFile - now at string table.
string_table_size_ = ReadListLength();
@@ -292,9 +332,84 @@ intptr_t StreamingFlowGraphBuilder::GetStringTableOffset(intptr_t index) {
string_table_offsets_[string_table_entries_read_] = ReaderOffset();
++string_table_entries_read_;
+ SetOffset(saved_offset);
return string_table_offsets_[index];
}
+CanonicalName* StreamingFlowGraphBuilder::GetCanonicalName(intptr_t index) {
+ if (index == 0) return NULL;
+ --index;
+
+ if (canonical_names_ != NULL && canonical_names_entries_read_ > index) {
+ return canonical_names_[index];
+ }
+
+ intptr_t saved_offset = ReaderOffset();
+ if (canonical_names_ == NULL) {
+ // Find offset from where to read canonical names table.
+
+ // First skip the string table:
+ // Get first string to make sure we have the table size, get last string and
+ // read it to get past the string table.
+ // Note that this will also cache all string positions.
+ GetStringTableOffset(0);
+ SetOffset(GetStringTableOffset(string_table_size_ - 1));
+ uint32_t bytes = ReadUInt();
+ SkipBytes(bytes);
+
+ // Another string table (source URIs)
+ intptr_t list_length = ReadListLength();
+ for (intptr_t i = 0; i < list_length; ++i) {
+ uint32_t bytes = ReadUInt();
+ SkipBytes(bytes);
+ }
+
+ // Source code table
+ for (intptr_t i = 0; i < list_length; ++i) {
+ // Source code
+ intptr_t bytes = ReadUInt();
+ SkipBytes(bytes);
+
+ // Line starts table
+ intptr_t line_count = ReadUInt();
+ for (intptr_t j = 0; j < line_count; ++j) {
+ ReadUInt();
+ }
+ }
+
+ // Now at canonical names table.
+ canonical_names_size_ = ReadUInt();
+ canonical_names_ = new CanonicalName*[canonical_names_size_];
+ canonical_names_next_offset_ = ReaderOffset();
+ }
+
+ SetOffset(canonical_names_next_offset_);
+ for (; canonical_names_entries_read_ <= index;
+ ++canonical_names_entries_read_) {
+ intptr_t biased_parent_index = ReadUInt();
+ CanonicalName* parent;
+ if (biased_parent_index != 0) {
+ parent = canonical_names_[biased_parent_index - 1];
+ } else {
+ if (canonical_names_entries_read_ == 0) {
+ parent = CanonicalName::NewRoot();
+ } else {
+ parent = canonical_names_[0]->parent();
+ }
+ }
+ ASSERT(parent != NULL);
+ intptr_t name_index = ReadUInt();
+ String* name = KernelString(name_index);
+ CanonicalName* canonical_name = parent->AddChild(name);
+ canonical_names_[canonical_names_entries_read_] = canonical_name;
+ }
+
+ canonical_names_next_offset_ = ReaderOffset();
+
+ SetOffset(saved_offset);
+ return canonical_names_[index];
+}
+
intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
return reader_->offset();
}
@@ -357,6 +472,17 @@ dart::String& StreamingFlowGraphBuilder::DartString(intptr_t str_index) {
return H.DartString(data, bytes);
}
+String* StreamingFlowGraphBuilder::KernelString(intptr_t str_index) {
+ intptr_t savedOffset = ReaderOffset();
+
+ SetOffset(GetStringTableOffset(str_index));
+ uint32_t bytes = ReadUInt();
+ const uint8_t* data = &reader_->buffer()[ReaderOffset()];
+
+ SetOffset(savedOffset);
+ return new String(data, bytes);
+}
+
Fragment StreamingFlowGraphBuilder::DebugStepCheck(TokenPosition position) {
return flow_graph_builder_->DebugStepCheck(position);
}
@@ -386,6 +512,16 @@ Fragment StreamingFlowGraphBuilder::IntConstant(int64_t value) {
return flow_graph_builder_->IntConstant(value);
}
+Fragment StreamingFlowGraphBuilder::LoadStaticField() {
+ return flow_graph_builder_->LoadStaticField();
+}
+
+Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
+ const Function& target,
+ intptr_t argument_count) {
+ return flow_graph_builder_->StaticCall(position, target, argument_count);
+}
+
Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() {
// The frontend will take care of emitting normal errors (like
// [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special
@@ -393,6 +529,47 @@ Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() {
return ThrowNoSuchMethodError();
}
+Fragment StreamingFlowGraphBuilder::BuildStaticGet() {
+ intptr_t saved_offset = ReaderOffset() - 1; // Include the tag.
+ TokenPosition position = ReadPosition();
+ int canonical_name_index = ReadUInt();
+ CanonicalName* target = GetCanonicalName(canonical_name_index);
+
+ if (target->IsField()) {
+ const dart::Field& field =
+ dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
+ if (field.is_const()) {
+ SetOffset(saved_offset); // EvaluateExpression needs the tag.
+ return Constant(constant_evaluator_.EvaluateExpression());
+ } else {
+ const dart::Class& owner = dart::Class::Handle(Z, field.Owner());
+ const dart::String& getter_name = H.DartGetterName(target);
+ const Function& getter =
+ Function::ZoneHandle(Z, owner.LookupStaticFunction(getter_name));
+ if (getter.IsNull() || !field.has_initializer()) {
+ Fragment instructions = Constant(field);
+ return instructions + LoadStaticField();
+ } else {
+ return StaticCall(position, getter, 0);
+ }
+ }
+ } else {
+ const Function& function =
+ Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
+
+ if (target->IsGetter()) {
+ return StaticCall(position, function, 0);
+ } else if (target->IsMethod()) {
+ SetOffset(saved_offset); // EvaluateExpression needs the tag.
+ return Constant(constant_evaluator_.EvaluateExpression());
+ } else {
+ UNIMPLEMENTED();
+ }
+ }
+
+ return Fragment();
+}
+
Fragment StreamingFlowGraphBuilder::BuildSymbolLiteral() {
SkipBytes(-1); // EvaluateExpression needs the tag.
return Constant(constant_evaluator_.EvaluateExpression());
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_to_il.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698