[vm] Support Dart metadata on libraries and library dependencies in Dart 2 mode
Fixes https://github.com/dart-lang/sdk/issues/33774
Change-Id: I0b34cdf2bee099076e29bec6cfb849b0b250f690
Reviewed-on: https://dart-review.googlesource.com/64245
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 9770a26..46dba1a 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -7283,26 +7283,34 @@
return metadata_values.raw();
}
-RawObject* StreamingFlowGraphBuilder::EvaluateMetadata(intptr_t kernel_offset) {
+RawObject* StreamingFlowGraphBuilder::EvaluateMetadata(
+ intptr_t kernel_offset,
+ bool is_annotations_offset) {
SetOffset(kernel_offset);
- const Tag tag = PeekTag();
ASSERT(active_class() != NULL);
- if (tag == kClass) {
- ClassHelper class_helper(this);
- class_helper.ReadUntilExcluding(ClassHelper::kAnnotations);
- } else if (tag == kProcedure) {
- ProcedureHelper procedure_helper(this);
- procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
- } else if (tag == kField) {
- FieldHelper field_helper(this);
- field_helper.ReadUntilExcluding(FieldHelper::kAnnotations);
- } else if (tag == kConstructor) {
- ConstructorHelper constructor_helper(this);
- constructor_helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
- } else {
- FATAL("No support for metadata on this type of kernel node\n");
+ // Library and LibraryDependency objects do not have a tag in kernel binary.
+ // Synthetic metadata fields corresponding to these objects keep kernel
+ // offset of annotations list instead of annotated object.
+ if (!is_annotations_offset) {
+ const Tag tag = PeekTag();
+
+ if (tag == kClass) {
+ ClassHelper class_helper(this);
+ class_helper.ReadUntilExcluding(ClassHelper::kAnnotations);
+ } else if (tag == kProcedure) {
+ ProcedureHelper procedure_helper(this);
+ procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
+ } else if (tag == kField) {
+ FieldHelper field_helper(this);
+ field_helper.ReadUntilExcluding(FieldHelper::kAnnotations);
+ } else if (tag == kConstructor) {
+ ConstructorHelper constructor_helper(this);
+ constructor_helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
+ } else {
+ FATAL("No support for metadata on this type of kernel node\n");
+ }
}
return BuildAnnotations();
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index cc258c8..c9babb5 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -275,7 +275,8 @@
Fragment BuildStatementAt(intptr_t kernel_offset);
RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
RawObject* BuildAnnotations();
- RawObject* EvaluateMetadata(intptr_t kernel_offset);
+ RawObject* EvaluateMetadata(intptr_t kernel_offset,
+ bool is_annotations_offset);
void CollectTokenPositionsFor(
intptr_t script_index,
intptr_t initial_script_index,
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 57f95cc..d22bad5 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2058,7 +2058,8 @@
return nsm;
}
-RawObject* EvaluateMetadata(const Field& metadata_field) {
+RawObject* EvaluateMetadata(const Field& metadata_field,
+ bool is_annotations_offset) {
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
Thread* thread = Thread::Current();
@@ -2076,7 +2077,7 @@
ExternalTypedData::Handle(Z, metadata_field.KernelData()),
metadata_field.KernelDataProgramOffset(), &active_class);
return streaming_flow_graph_builder.EvaluateMetadata(
- metadata_field.kernel_offset());
+ metadata_field.kernel_offset(), is_annotations_offset);
} else {
Thread* thread = Thread::Current();
Error& error = Error::Handle();
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 2fdace5..53d60ec 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -690,7 +690,8 @@
intptr_t catch_try_index_;
};
-RawObject* EvaluateMetadata(const Field& metadata_field);
+RawObject* EvaluateMetadata(const Field& metadata_field,
+ bool is_annotations_offset);
RawObject* BuildParameterDescriptor(const Function& function);
void CollectTokenPositionsFor(const Script& script);
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 99aa61f..8e6e3b39 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1304,7 +1304,10 @@
}
/* Falls through */
case kAnnotations: {
- helper_->SkipListOfExpressions();
+ annotation_count_ = helper_->ReadListLength();
+ for (intptr_t i = 0; i < annotation_count_; ++i) {
+ helper_->SkipExpression(); // read ith expression.
+ }
if (++next_read_ == field) return;
}
/* Falls through */
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index eb1564d..f18a9bb 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -729,7 +729,7 @@
};
explicit LibraryDependencyHelper(KernelReaderHelper* helper)
- : helper_(helper), next_read_(kFileOffset) {}
+ : annotation_count_(0), helper_(helper), next_read_(kFileOffset) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -740,6 +740,7 @@
uint8_t flags_;
StringIndex name_index_;
NameIndex target_library_canonical_name_;
+ intptr_t annotation_count_;
private:
KernelReaderHelper* helper_;
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 114ae9a..31148a0 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -762,6 +762,8 @@
Z, ScriptAt(library_helper.source_uri_index_, import_uri_index));
library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations);
+ intptr_t annotations_kernel_offset =
+ builder_.ReaderOffset() - correction_offset_;
intptr_t annotation_count = builder_.ReadListLength(); // read list length.
if (annotation_count > 0) {
EnsurePotentialExtensionLibraries();
@@ -772,10 +774,6 @@
}
library_helper.SetJustRead(LibraryHelper::kAnnotations);
- library_helper.ReadUntilExcluding(LibraryHelper::kDependencies);
- LoadLibraryImportsAndExports(&library);
- library_helper.SetJustRead(LibraryHelper::kDependencies);
-
// Setup toplevel class (which contains library fields/procedures).
Class& toplevel_class =
Class::Handle(Z, Class::New(library, Symbols::TopLevel(), script,
@@ -783,6 +781,10 @@
toplevel_class.set_is_cycle_free();
library.set_toplevel_class(toplevel_class);
+ library_helper.ReadUntilExcluding(LibraryHelper::kDependencies);
+ LoadLibraryImportsAndExports(&library, toplevel_class);
+ library_helper.SetJustRead(LibraryHelper::kDependencies);
+
const GrowableObjectArray& classes =
GrowableObjectArray::Handle(Z, I->object_store()->pending_classes());
@@ -851,6 +853,12 @@
LoadProcedure(library, toplevel_class, false, next_procedure_offset);
}
+ if (FLAG_enable_mirrors && annotation_count > 0) {
+ ASSERT(annotations_kernel_offset > 0);
+ library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource,
+ annotations_kernel_offset);
+ }
+
toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray()));
classes.Add(toplevel_class, Heap::kOld);
if (!library.Loaded()) library.SetLoaded();
@@ -858,7 +866,8 @@
return library.raw();
}
-void KernelLoader::LoadLibraryImportsAndExports(Library* library) {
+void KernelLoader::LoadLibraryImportsAndExports(Library* library,
+ const Class& toplevel_class) {
GrowableObjectArray& show_list = GrowableObjectArray::Handle(Z);
GrowableObjectArray& hide_list = GrowableObjectArray::Handle(Z);
Array& show_names = Array::Handle(Z);
@@ -869,6 +878,11 @@
const intptr_t deps_count = builder_.ReadListLength();
for (intptr_t dep = 0; dep < deps_count; ++dep) {
LibraryDependencyHelper dependency_helper(&builder_);
+
+ dependency_helper.ReadUntilExcluding(LibraryDependencyHelper::kAnnotations);
+ intptr_t annotations_kernel_offset =
+ builder_.ReaderOffset() - correction_offset_;
+
dependency_helper.ReadUntilExcluding(LibraryDependencyHelper::kCombinators);
// Ignore the dependency if the target library is invalid.
@@ -937,6 +951,11 @@
}
}
}
+ if (FLAG_enable_mirrors && dependency_helper.annotation_count_ > 0) {
+ ASSERT(annotations_kernel_offset > 0);
+ ns.AddMetadata(toplevel_class, TokenPosition::kNoSource,
+ annotations_kernel_offset);
+ }
}
}
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 954ef90..bc41510 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -249,7 +249,8 @@
const Function& function,
const AbstractType& field_type);
- void LoadLibraryImportsAndExports(Library* library);
+ void LoadLibraryImportsAndExports(Library* library,
+ const Class& toplevel_class);
Library& LookupLibraryOrNull(NameIndex library);
Library& LookupLibrary(NameIndex library);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index da966ec..cfdfcbc 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -10626,8 +10626,9 @@
}
void Library::AddLibraryMetadata(const Object& tl_owner,
- TokenPosition token_pos) const {
- AddMetadata(tl_owner, Symbols::TopLevel(), token_pos);
+ TokenPosition token_pos,
+ intptr_t kernel_offset) const {
+ AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset);
}
RawString* Library::MakeMetadataName(const Object& obj) const {
@@ -10695,7 +10696,8 @@
metadata = field.StaticValue();
if (field.StaticValue() == Object::empty_array().raw()) {
if (field.kernel_offset() > 0) {
- metadata = kernel::EvaluateMetadata(field);
+ metadata = kernel::EvaluateMetadata(
+ field, /* is_annotations_offset = */ obj.IsLibrary());
} else {
metadata = Parser::ParseMetadata(field);
}
@@ -12287,7 +12289,9 @@
StorePointer(&raw_ptr()->metadata_field_, value.raw());
}
-void Namespace::AddMetadata(const Object& owner, TokenPosition token_pos) {
+void Namespace::AddMetadata(const Object& owner,
+ TokenPosition token_pos,
+ intptr_t kernel_offset) {
ASSERT(Field::Handle(metadata_field()).IsNull());
Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(),
false, // is_final
@@ -12296,6 +12300,7 @@
field.set_is_reflectable(false);
field.SetFieldType(Object::dynamic_type());
field.SetStaticValue(Array::empty_array(), true);
+ field.set_kernel_offset(kernel_offset);
set_metadata_field(field);
}
@@ -12311,7 +12316,12 @@
Object& metadata = Object::Handle();
metadata = field.StaticValue();
if (field.StaticValue() == Object::empty_array().raw()) {
- metadata = Parser::ParseMetadata(field);
+ if (field.kernel_offset() > 0) {
+ metadata =
+ kernel::EvaluateMetadata(field, /* is_annotations_offset = */ true);
+ } else {
+ metadata = Parser::ParseMetadata(field);
+ }
if (metadata.IsArray()) {
ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw());
field.SetStaticValue(Array::Cast(metadata), true);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 5e2b6f3..ff768b4 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3849,7 +3849,8 @@
TokenPosition token_pos,
intptr_t kernel_offset = 0) const;
void AddLibraryMetadata(const Object& tl_owner,
- TokenPosition token_pos) const;
+ TokenPosition token_pos,
+ intptr_t kernel_offset = 0) const;
void AddTypeParameterMetadata(const TypeParameter& param,
TokenPosition token_pos) const;
void CloneMetadataFrom(const Library& from_library,
@@ -4065,7 +4066,9 @@
RawArray* show_names() const { return raw_ptr()->show_names_; }
RawArray* hide_names() const { return raw_ptr()->hide_names_; }
- void AddMetadata(const Object& owner, TokenPosition token_pos);
+ void AddMetadata(const Object& owner,
+ TokenPosition token_pos,
+ intptr_t kernel_offset = 0);
RawObject* GetMetadata() const;
static intptr_t InstanceSize() {
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index 6dffcc5..4257d48 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -116,7 +116,6 @@
mirrors/constructor_private_name_test: RuntimeError # Issue 33345 - Incorrect qualified symbol literal from kernel reader
mirrors/constructors_test: CompileTimeError # Issue 31402 (Invocation arguments)
mirrors/dart2js_mirrors_test: RuntimeError # 31916
-mirrors/deferred_mirrors_metadata_test: RuntimeError, CompileTimeError # Deferred loading kernel issue 28335.
mirrors/deferred_type_test: CompileTimeError, RuntimeError
mirrors/empty_test: Crash, RuntimeError
mirrors/enum_test: RuntimeError # Issue 31402 (Invocation arguments)
@@ -140,7 +139,6 @@
mirrors/library_imports_prefixed_show_hide_test: RuntimeError # Issue 33098
mirrors/library_imports_prefixed_test: RuntimeError # Issue 33098
mirrors/library_imports_shown_test: RuntimeError # Issue 33098
-mirrors/library_metadata_test: RuntimeError
mirrors/load_library_test: RuntimeError
mirrors/metadata_allowed_values_test/16: Skip # Flaky, crashes.
mirrors/metadata_scope_test/none: RuntimeError