@@ -6,6 +6,8 @@ library vm.metadata.bytecode;
66
77import 'package:kernel/ast.dart' ;
88import '../bytecode/constant_pool.dart' show ConstantPool;
9+ import '../bytecode/dbc.dart'
10+ show stableBytecodeFormatVersion, futureBytecodeFormatVersion;
911import '../bytecode/disassembler.dart' show BytecodeDisassembler;
1012import '../bytecode/exceptions.dart' show ExceptionsTable;
1113
@@ -14,6 +16,7 @@ import '../bytecode/exceptions.dart' show ExceptionsTable;
1416/// In kernel binary, bytecode metadata is encoded as following:
1517///
1618/// type BytecodeMetadata {
19+ /// UInt bytecodeFormatVersion
1720/// UInt flags (HasExceptionsTable, HasNullableFields, HasClosures)
1821///
1922/// ConstantPool constantPool
@@ -46,6 +49,7 @@ class BytecodeMetadata {
4649 static const hasNullableFieldsFlag = 1 << 1 ;
4750 static const hasClosuresFlag = 1 << 2 ;
4851
52+ final int version;
4953 final ConstantPool constantPool;
5054 final List <int > bytecodes;
5155 final ExceptionsTable exceptionsTable;
@@ -61,13 +65,16 @@ class BytecodeMetadata {
6165 (hasNullableFields ? hasNullableFieldsFlag : 0 ) |
6266 (hasClosures ? hasClosuresFlag : 0 );
6367
64- BytecodeMetadata (this .constantPool , this .bytecodes , this .exceptionsTable ,
65- this .nullableFields, this .closures);
68+ BytecodeMetadata (this .version , this .constantPool , this .bytecodes ,
69+ this .exceptionsTable, this . nullableFields, this .closures);
6670
6771 // TODO(alexmarkov): Consider printing constant pool before bytecode.
6872 @override
6973 String toString () => "\n "
70- "Bytecode {\n "
74+ "Bytecode"
75+ " (version: "
76+ "${version == stableBytecodeFormatVersion ? 'stable' : version == futureBytecodeFormatVersion ? 'future' : "v$version " }"
77+ ") {\n "
7178 "${new BytecodeDisassembler ().disassemble (bytecodes , exceptionsTable )}}\n "
7279 "$exceptionsTable "
7380 "${nullableFields .isEmpty ? '' : 'Nullable fields: ${nullableFields .map ((ref ) => ref .asField ).toList ()}\n ' }"
@@ -121,6 +128,7 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
121128
122129 @override
123130 void writeToBinary (BytecodeMetadata metadata, Node node, BinarySink sink) {
131+ sink.writeUInt30 (metadata.version);
124132 sink.writeUInt30 (metadata.flags);
125133 metadata.constantPool.writeToBinary (node, sink);
126134 sink.writeByteList (metadata.bytecodes);
@@ -140,6 +148,11 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
140148
141149 @override
142150 BytecodeMetadata readFromBinary (Node node, BinarySource source) {
151+ int version = source.readUInt ();
152+ if (version != stableBytecodeFormatVersion &&
153+ version != futureBytecodeFormatVersion) {
154+ throw 'Error: unexpected bytecode version $version ' ;
155+ }
143156 int flags = source.readUInt ();
144157 final ConstantPool constantPool =
145158 new ConstantPool .readFromBinary (node, source);
@@ -158,7 +171,7 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
158171 ? new List <ClosureBytecode >.generate (source.readUInt (),
159172 (_) => new ClosureBytecode .readFromBinary (source))
160173 : const < ClosureBytecode > [];
161- return new BytecodeMetadata (
162- constantPool, bytecodes, exceptionsTable, nullableFields, closures);
174+ return new BytecodeMetadata (version, constantPool, bytecodes,
175+ exceptionsTable, nullableFields, closures);
163176 }
164177}
0 commit comments