[vm,dyn_modules] Support reading pragmas from bytecode

TEST=vm/cc/*

Change-Id: I561e23ebc758faea70c2eb72c08dc13b8326aee8
Cq-Include-Trybots: luci.dart.try:vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439061
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
diff --git a/runtime/vm/bytecode_reader.cc b/runtime/vm/bytecode_reader.cc
index 7ece101..c98067f 100644
--- a/runtime/vm/bytecode_reader.cc
+++ b/runtime/vm/bytecode_reader.cc
@@ -1554,6 +1554,24 @@
   return type_arguments.Canonicalize(thread_);
 }
 
+void BytecodeReaderHelper::ReadAnnotations(const Class& cls,
+                                           const Object& declaration,
+                                           bool has_pragma) {
+  const intptr_t annotations_offset =
+      reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset();
+  ASSERT(annotations_offset > 0);
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (FLAG_enable_mirrors || has_pragma) {
+    AlternativeReadingScope alt(&reader_, annotations_offset);
+    const auto& metadata = Object::Handle(Z, ReadObject());
+    ASSERT(metadata.IsArray());
+    const auto& library = Library::Handle(Z, cls.library());
+    library.AddMetadata(declaration, metadata);
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+}
+
 void BytecodeReaderHelper::ReadMembers(const Class& cls, bool discard_fields) {
   ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
   ASSERT(cls.is_type_finalized());
@@ -1726,7 +1744,7 @@
     }
 
     if ((flags & kHasAnnotationsFlag) != 0) {
-      reader_.ReadUInt();  // Skip annotations offset.
+      ReadAnnotations(cls, field, has_pragma);
     }
 
     if (field.is_static()) {
@@ -2003,7 +2021,7 @@
     }
 
     if ((flags & kHasAnnotationsFlag) != 0) {
-      reader_.ReadUInt();  // Skip annotations offset.
+      ReadAnnotations(cls, function, has_pragma);
     }
 
     functions_->SetAt(function_index_++, function);
@@ -2122,7 +2140,7 @@
   }
 
   if ((flags & kHasAnnotationsFlag) != 0) {
-    reader_.ReadUInt();  // Skip annotations offset.
+    ReadAnnotations(cls, cls, has_pragma);
   }
 
   const intptr_t members_offset = reader_.ReadUInt();
diff --git a/runtime/vm/bytecode_reader.h b/runtime/vm/bytecode_reader.h
index 4c5ea23..12a669e 100644
--- a/runtime/vm/bytecode_reader.h
+++ b/runtime/vm/bytecode_reader.h
@@ -349,6 +349,9 @@
   TypedDataPtr ReadLineStartsData(intptr_t line_starts_offset);
   ScriptPtr ReadSourceFile(const String& uri, intptr_t offset);
   TypeArgumentsPtr ReadTypeArguments();
+  void ReadAnnotations(const Class& cls,
+                       const Object& declaration,
+                       bool has_pragma);
   void SetupFieldAccessorFunction(const Class& klass,
                                   const Function& function,
                                   const AbstractType& field_type);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6955148..62d4541 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -14363,6 +14363,11 @@
 
 void Library::AddMetadata(const Object& declaration,
                           intptr_t kernel_offset) const {
+  AddMetadata(declaration, Smi::Handle(Smi::New(kernel_offset)));
+}
+
+void Library::AddMetadata(const Object& declaration,
+                          const Object& metadata_value) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
 #else
@@ -14370,7 +14375,7 @@
   ASSERT(thread->isolate_group()->program_lock()->IsCurrentThreadWriter());
 
   MetadataMap map(metadata());
-  map.UpdateOrInsert(declaration, Smi::Handle(Smi::New(kernel_offset)));
+  map.UpdateOrInsert(declaration, metadata_value);
   set_metadata(map.Release());
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index fb8f4f0..02d9794 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5235,6 +5235,8 @@
   void AddExport(const Namespace& ns) const;
 
   void AddMetadata(const Object& declaration, intptr_t kernel_offset) const;
+  void AddMetadata(const Object& declaration,
+                   const Object& metadata_value) const;
   ObjectPtr GetMetadata(const Object& declaration) const;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)