| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library kernel.ast_to_binary; | 4 library kernel.ast_to_binary; |
| 5 | 5 |
| 6 import '../ast.dart'; | 6 import '../ast.dart'; |
| 7 import '../import_table.dart'; | 7 import '../import_table.dart'; |
| 8 import 'tag.dart'; | 8 import 'tag.dart'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:typed_data'; | 10 import 'dart:typed_data'; |
| 11 import 'dart:collection'; | 11 import 'dart:collection'; |
| 12 | 12 |
| 13 /// Writes to a binary file. | 13 /// Writes to a binary file. |
| 14 /// | 14 /// |
| 15 /// A [BinaryPrinter] can be used to write one file and must then be | 15 /// A [BinaryPrinter] can be used to write one file and must then be |
| 16 /// discarded. | 16 /// discarded. |
| 17 class BinaryPrinter extends Visitor { | 17 class BinaryPrinter extends Visitor { |
| 18 ImportTable _importTable; | 18 ImportTable _importTable; |
| 19 | 19 |
| 20 VariableIndexer _variableIndexer; | 20 VariableIndexer _variableIndexer; |
| 21 LabelIndexer _labelIndexer; | 21 LabelIndexer _labelIndexer; |
| 22 SwitchCaseIndexer _switchCaseIndexer; | 22 SwitchCaseIndexer _switchCaseIndexer; |
| 23 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer(); | 23 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer(); |
| 24 final GlobalIndexer _globalIndexer; | 24 final GlobalIndexer _globalIndexer; |
| 25 final StringIndexer _stringIndexer = new StringIndexer(); | 25 final StringIndexer _stringIndexer = new StringIndexer(); |
| 26 final StringIndexer _sourceUriIndexer = new StringIndexer(); | 26 final StringIndexer _sourceUriIndexer = new StringIndexer(); |
| 27 Map<DeferredImport, int> _deferredImportIndexer = <DeferredImport, int>{}; |
| 27 | 28 |
| 28 final BufferedSink _sink; | 29 final BufferedSink _sink; |
| 29 | 30 |
| 30 /// Create a printer that writes to the given [sink]. | 31 /// Create a printer that writes to the given [sink]. |
| 31 /// | 32 /// |
| 32 /// The BinaryPrinter will use its own buffer, so the [sink] does not need | 33 /// The BinaryPrinter will use its own buffer, so the [sink] does not need |
| 33 /// one. | 34 /// one. |
| 34 /// | 35 /// |
| 35 /// If multiple binaries are to be written based on the same IR, a shared | 36 /// If multiple binaries are to be written based on the same IR, a shared |
| 36 /// [globalIndexer] may be passed in to avoid rebuilding the same indices | 37 /// [globalIndexer] may be passed in to avoid rebuilding the same indices |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 } | 169 } |
| 169 | 170 |
| 170 void writeLibraryReference(Library node) { | 171 void writeLibraryReference(Library node) { |
| 171 int index = _importTable.getImportIndex(node); | 172 int index = _importTable.getImportIndex(node); |
| 172 if (index == -1) { | 173 if (index == -1) { |
| 173 throw 'Missing import for library: ${node.importUri}'; | 174 throw 'Missing import for library: ${node.importUri}'; |
| 174 } | 175 } |
| 175 writeUInt30(index); | 176 writeUInt30(index); |
| 176 } | 177 } |
| 177 | 178 |
| 179 void writeDeferredImportReference(DeferredImport node) { |
| 180 int index = _deferredImportIndexer[node]; |
| 181 if (index == null) { |
| 182 throw 'Reference to deferred import $node out of scope'; |
| 183 } |
| 184 writeUInt30(index); |
| 185 } |
| 186 |
| 178 void writeClassIndex(Class node) { | 187 void writeClassIndex(Class node) { |
| 179 writeUInt30(_globalIndexer[node]); | 188 writeUInt30(_globalIndexer[node]); |
| 180 } | 189 } |
| 181 | 190 |
| 182 void writeClassReference(Class node, {bool allowNull: false}) { | 191 void writeClassReference(Class node, {bool allowNull: false}) { |
| 183 if (node == null) { | 192 if (node == null) { |
| 184 if (allowNull) { | 193 if (allowNull) { |
| 185 writeByte(Tag.NullReference); | 194 writeByte(Tag.NullReference); |
| 186 } else { | 195 } else { |
| 187 throw 'Expected a class reference to be valid but was `null`.'; | 196 throw 'Expected a class reference to be valid but was `null`.'; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 271 |
| 263 bool insideExternalLibrary = false; | 272 bool insideExternalLibrary = false; |
| 264 | 273 |
| 265 visitLibrary(Library node) { | 274 visitLibrary(Library node) { |
| 266 insideExternalLibrary = node.isExternal; | 275 insideExternalLibrary = node.isExternal; |
| 267 writeByte(insideExternalLibrary ? 1 : 0); | 276 writeByte(insideExternalLibrary ? 1 : 0); |
| 268 writeStringReference(node.name ?? ''); | 277 writeStringReference(node.name ?? ''); |
| 269 writeStringReference('${node.importUri}'); | 278 writeStringReference('${node.importUri}'); |
| 270 // TODO(jensj): We save (almost) the same URI twice. | 279 // TODO(jensj): We save (almost) the same URI twice. |
| 271 writeUriReference(node.fileUri ?? ''); | 280 writeUriReference(node.fileUri ?? ''); |
| 281 writeDeferredImports(node); |
| 272 writeNodeList(node.classes); | 282 writeNodeList(node.classes); |
| 273 writeNodeList(node.fields); | 283 writeNodeList(node.fields); |
| 274 writeNodeList(node.procedures); | 284 writeNodeList(node.procedures); |
| 275 } | 285 } |
| 276 | 286 |
| 287 void writeDeferredImports(Library library) { |
| 288 _deferredImportIndexer = library.deferredImports.isEmpty |
| 289 ? const <DeferredImport, int>{} |
| 290 : <DeferredImport, int>{}; |
| 291 writeUInt30(library.deferredImports.length); |
| 292 for (int i = 0; i < library.deferredImports.length; ++i) { |
| 293 var importNode = library.deferredImports[i]; |
| 294 _deferredImportIndexer[importNode] = i; |
| 295 writeDeferredImport(importNode); |
| 296 } |
| 297 } |
| 298 |
| 299 void writeDeferredImport(DeferredImport node) { |
| 300 writeLibraryReference(node.importedLibrary); |
| 301 writeStringReference(node.name); |
| 302 } |
| 303 |
| 277 void writeAnnotation(Expression annotation) { | 304 void writeAnnotation(Expression annotation) { |
| 278 _variableIndexer ??= new VariableIndexer(); | 305 _variableIndexer ??= new VariableIndexer(); |
| 279 writeNode(annotation); | 306 writeNode(annotation); |
| 280 } | 307 } |
| 281 | 308 |
| 282 void writeAnnotationList(List<Expression> annotations) { | 309 void writeAnnotationList(List<Expression> annotations) { |
| 283 writeList(annotations, writeAnnotation); | 310 writeList(annotations, writeAnnotation); |
| 284 } | 311 } |
| 285 | 312 |
| 286 visitClass(Class node) { | 313 visitClass(Class node) { |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 writeNode(node.function); | 732 writeNode(node.function); |
| 706 } | 733 } |
| 707 | 734 |
| 708 visitLet(Let node) { | 735 visitLet(Let node) { |
| 709 writeByte(Tag.Let); | 736 writeByte(Tag.Let); |
| 710 writeVariableDeclaration(node.variable); | 737 writeVariableDeclaration(node.variable); |
| 711 writeNode(node.body); | 738 writeNode(node.body); |
| 712 --_variableIndexer.stackHeight; | 739 --_variableIndexer.stackHeight; |
| 713 } | 740 } |
| 714 | 741 |
| 742 visitLoadLibrary(LoadLibrary node) { |
| 743 writeByte(Tag.LoadLibrary); |
| 744 writeDeferredImportReference(node.import); |
| 745 } |
| 746 |
| 747 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { |
| 748 writeByte(Tag.CheckLibraryIsLoaded); |
| 749 writeDeferredImportReference(node.import); |
| 750 } |
| 751 |
| 715 writeStatementOrEmpty(Statement node) { | 752 writeStatementOrEmpty(Statement node) { |
| 716 if (node == null) { | 753 if (node == null) { |
| 717 writeByte(Tag.EmptyStatement); | 754 writeByte(Tag.EmptyStatement); |
| 718 } else { | 755 } else { |
| 719 writeNode(node); | 756 writeNode(node); |
| 720 } | 757 } |
| 721 } | 758 } |
| 722 | 759 |
| 723 visitInvalidStatement(InvalidStatement node) { | 760 visitInvalidStatement(InvalidStatement node) { |
| 724 writeByte(Tag.InvalidStatement); | 761 writeByte(Tag.InvalidStatement); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 visitName(Name node) { | 1128 visitName(Name node) { |
| 1092 put(node.name); | 1129 put(node.name); |
| 1093 } | 1130 } |
| 1094 | 1131 |
| 1095 visitLibrary(Library node) { | 1132 visitLibrary(Library node) { |
| 1096 putOptional(node.name); | 1133 putOptional(node.name); |
| 1097 put('${node.importUri}'); | 1134 put('${node.importUri}'); |
| 1098 node.visitChildren(this); | 1135 node.visitChildren(this); |
| 1099 } | 1136 } |
| 1100 | 1137 |
| 1138 visitDeferredImport(DeferredImport node) { |
| 1139 put(node.name); |
| 1140 } |
| 1141 |
| 1101 visitClass(Class node) { | 1142 visitClass(Class node) { |
| 1102 putOptional(node.name); | 1143 putOptional(node.name); |
| 1103 node.visitChildren(this); | 1144 node.visitChildren(this); |
| 1104 } | 1145 } |
| 1105 | 1146 |
| 1106 visitNamedExpression(NamedExpression node) { | 1147 visitNamedExpression(NamedExpression node) { |
| 1107 put(node.name); | 1148 put(node.name); |
| 1108 node.visitChildren(this); | 1149 node.visitChildren(this); |
| 1109 } | 1150 } |
| 1110 | 1151 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 void flush() { | 1282 void flush() { |
| 1242 _sink.add(_buffer.sublist(0, length)); | 1283 _sink.add(_buffer.sublist(0, length)); |
| 1243 _buffer = new Uint8List(SIZE); | 1284 _buffer = new Uint8List(SIZE); |
| 1244 length = 0; | 1285 length = 0; |
| 1245 } | 1286 } |
| 1246 | 1287 |
| 1247 void flushAndDestroy() { | 1288 void flushAndDestroy() { |
| 1248 _sink.add(_buffer.sublist(0, length)); | 1289 _sink.add(_buffer.sublist(0, length)); |
| 1249 } | 1290 } |
| 1250 } | 1291 } |
| OLD | NEW |