diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index 9dc8a27a12b..422d6a3076e 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md @@ -139,7 +139,7 @@ type CanonicalName { type ComponentFile { UInt32 magic = 0x90ABCDEF; - UInt32 formatVersion = 26; + UInt32 formatVersion = 27; List problemsAsJson; // Described in problems.md. Library[] libraries; UriSource sourceMap; diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index f1996a98674..751f36f588d 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -820,6 +820,15 @@ class BinaryBuilder { int flags = readByte(); bool isExternal = (flags & Library.ExternalFlag) != 0; _isReadingLibraryImplementation = !isExternal; + + // TODO(jensj): Eventually, language version should always be set. + int languageVersionMajor = readUInt(); + int languageVersionMinor = readUInt(); + if (languageVersionMajor == 0 || languageVersionMinor == 0) { + languageVersionMajor = null; + languageVersionMinor = null; + } + var canonicalName = readCanonicalNameReference(); Reference reference = canonicalName.getReference(); Library library = reference.node; @@ -842,6 +851,8 @@ class BinaryBuilder { if (shouldWriteData) { library.flags = flags; + library.languageVersionMajor = languageVersionMajor; + library.languageVersionMinor = languageVersionMinor; library.name = name; library.fileUri = fileUri; library.problemsAsJson = problemsAsJson; diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 35337eaf70f..c4ad1b56967 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -912,6 +912,11 @@ class BinaryPrinter implements Visitor, BinarySink { insideExternalLibrary = node.isExternal; libraryOffsets.add(getBufferOffset()); writeByte(node.flags); + + // TODO(jensj): Eventually, language version should always be set. + writeUInt30(node.languageVersionMajor ?? 0); + writeUInt30(node.languageVersionMinor ?? 0); + writeNonNullCanonicalNameReference(getCanonicalNameOfLibrary(node)); writeStringReference(node.name ?? ''); writeUriReference(node.fileUri); diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index 8e52b703f8f..3996b560df0 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart @@ -150,7 +150,7 @@ class Tag { /// Internal version of kernel binary format. /// Bump it when making incompatible changes in kernel binaries. /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md. - static const int BinaryFormatVersion = 25; + static const int BinaryFormatVersion = 27; } abstract class ConstantTag { diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index cfd267b1eab..44d60dbe92e 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc @@ -1305,11 +1305,21 @@ void LibraryHelper::ReadUntilExcluding(Field field) { // Ordered with fall-through. switch (next_read_) { + // Note that this (up to canonical name) needs to be kept in sync with + // "library_canonical_name" (currently in "kernel_loader.h"). case kFlags: { flags_ = helper_->ReadFlags(); if (++next_read_ == field) return; FALL_THROUGH; } + case kLanguageVersion: { + if (binary_version_ >= 27) { + helper_->ReadUInt(); // Read major language version. + helper_->ReadUInt(); // Read minor language version. + } + if (++next_read_ == field) return; + FALL_THROUGH; + } case kCanonicalName: canonical_name_ = helper_->ReadCanonicalNameReference(); // read canonical_name. diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h index 957851780df..e10c794eee6 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.h +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h @@ -715,6 +715,7 @@ class LibraryHelper { public: enum Field { kFlags, + kLanguageVersion /* from binary version 27 */, kCanonicalName, kName, kSourceUriIndex, @@ -739,8 +740,8 @@ class LibraryHelper { kSynthetic = 1 << 1, }; - explicit LibraryHelper(KernelReaderHelper* helper) - : helper_(helper), next_read_(kFlags) {} + explicit LibraryHelper(KernelReaderHelper* helper, uint32_t binary_version) + : helper_(helper), binary_version_(binary_version), next_read_(kFlags) {} void ReadUntilIncluding(Field field) { ReadUntilExcluding(static_cast(static_cast(field) + 1)); @@ -761,6 +762,7 @@ class LibraryHelper { private: KernelReaderHelper* helper_; + uint32_t binary_version_; intptr_t next_read_; DISALLOW_COPY_AND_ASSIGN(LibraryHelper); diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index 00c119f5a7b..5e57905c4db 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h @@ -20,7 +20,7 @@ static const uint32_t kMagicProgramFile = 0x90ABCDEFu; // Both version numbers are inclusive. static const uint32_t kMinSupportedKernelFormatVersion = 18; -static const uint32_t kMaxSupportedKernelFormatVersion = 26; +static const uint32_t kMaxSupportedKernelFormatVersion = 27; // Keep in sync with package:kernel/lib/binary/tag.dart #define KERNEL_TAG_LIST(V) \ diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index 440f437fd9b..661a2e163f8 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -655,7 +655,7 @@ void KernelLoader::LoadNativeExtensionLibraries() { } else { helper_.SetOffset(library.kernel_offset()); - LibraryHelper library_helper(&helper_); + LibraryHelper library_helper(&helper_, kernel_binary_version_); library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations); const intptr_t annotation_count = helper_.ReadListLength(); @@ -925,7 +925,7 @@ void KernelLoader::walk_incremental_kernel(BitVector* modified_libs, for (intptr_t i = 0; i < length; i++) { intptr_t kernel_offset = library_offset(i); helper_.SetOffset(kernel_offset); - LibraryHelper library_helper(&helper_); + LibraryHelper library_helper(&helper_, kernel_binary_version_); library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName); lib = LookupLibraryOrNull(library_helper.canonical_name_); if (!lib.IsNull() && !lib.is_dart_scheme()) { @@ -994,7 +994,7 @@ RawLibrary* KernelLoader::LoadLibrary(intptr_t index) { // offset. helper_.SetOffset(library_kernel_offset_); - LibraryHelper library_helper(&helper_); + LibraryHelper library_helper(&helper_, kernel_binary_version_); library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName); if (!FLAG_precompiled_mode && !I->should_load_vmservice()) { StringIndex lib_name_index = diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h index 59a9ea96cb5..6f3dea74e10 100644 --- a/runtime/vm/kernel_loader.h +++ b/runtime/vm/kernel_loader.h @@ -288,7 +288,12 @@ class KernelLoader : public ValueObject { reader.set_offset(library_offset(index)); // Start reading library. + // Note that this needs to be keep in sync with LibraryHelper. reader.ReadFlags(); + if (program_->binary_version() >= 27) { + reader.ReadUInt(); // Read major language version. + reader.ReadUInt(); // Read minor language version. + } return reader.ReadCanonicalNameReference(); }