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'; |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 } | 386 } |
387 | 387 |
388 visitRedirectingInitializer(RedirectingInitializer node) { | 388 visitRedirectingInitializer(RedirectingInitializer node) { |
389 writeByte(Tag.RedirectingInitializer); | 389 writeByte(Tag.RedirectingInitializer); |
390 writeReference(node.targetReference); | 390 writeReference(node.targetReference); |
391 writeNode(node.arguments); | 391 writeNode(node.arguments); |
392 } | 392 } |
393 | 393 |
394 visitLocalInitializer(LocalInitializer node) { | 394 visitLocalInitializer(LocalInitializer node) { |
395 writeByte(Tag.LocalInitializer); | 395 writeByte(Tag.LocalInitializer); |
396 writeVariableDeclaration(node.variable); | 396 writeVariableDeclaration(node.variable, false); |
397 } | 397 } |
398 | 398 |
399 visitFunctionNode(FunctionNode node) { | 399 visitFunctionNode(FunctionNode node) { |
400 assert(_variableIndexer != null); | 400 assert(_variableIndexer != null); |
401 _variableIndexer.pushScope(); | 401 _variableIndexer.pushScope(); |
402 var oldLabels = _labelIndexer; | 402 var oldLabels = _labelIndexer; |
403 _labelIndexer = new LabelIndexer(); | 403 _labelIndexer = new LabelIndexer(); |
404 var oldCases = _switchCaseIndexer; | 404 var oldCases = _switchCaseIndexer; |
405 _switchCaseIndexer = new SwitchCaseIndexer(); | 405 _switchCaseIndexer = new SwitchCaseIndexer(); |
406 // Note: FunctionNode has no tag. | 406 // Note: FunctionNode has no tag. |
(...skipping 19 matching lines...) Expand all Loading... | |
426 } | 426 } |
427 | 427 |
428 visitVariableGet(VariableGet node) { | 428 visitVariableGet(VariableGet node) { |
429 assert(_variableIndexer != null); | 429 assert(_variableIndexer != null); |
430 int index = _variableIndexer[node.variable]; | 430 int index = _variableIndexer[node.variable]; |
431 assert(index != null); | 431 assert(index != null); |
432 if (index & Tag.SpecializedPayloadMask == index && | 432 if (index & Tag.SpecializedPayloadMask == index && |
433 node.promotedType == null) { | 433 node.promotedType == null) { |
434 writeByte(Tag.SpecializedVariableGet + index); | 434 writeByte(Tag.SpecializedVariableGet + index); |
435 writeOffset(node.fileOffset); | 435 writeOffset(node.fileOffset); |
436 writeUInt30(node.variable.tempOffset); | |
436 } else { | 437 } else { |
437 writeByte(Tag.VariableGet); | 438 writeByte(Tag.VariableGet); |
438 writeOffset(node.fileOffset); | 439 writeOffset(node.fileOffset); |
440 writeUInt30(node.variable.tempOffset); | |
439 writeUInt30(_variableIndexer[node.variable]); | 441 writeUInt30(_variableIndexer[node.variable]); |
440 writeOptionalNode(node.promotedType); | 442 writeOptionalNode(node.promotedType); |
441 } | 443 } |
442 } | 444 } |
443 | 445 |
444 visitVariableSet(VariableSet node) { | 446 visitVariableSet(VariableSet node) { |
445 assert(_variableIndexer != null); | 447 assert(_variableIndexer != null); |
446 int index = _variableIndexer[node.variable]; | 448 int index = _variableIndexer[node.variable]; |
447 if (index & Tag.SpecializedPayloadMask == index) { | 449 if (index & Tag.SpecializedPayloadMask == index) { |
448 writeByte(Tag.SpecializedVariableSet + index); | 450 writeByte(Tag.SpecializedVariableSet + index); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
706 writeNode(node.operand); | 708 writeNode(node.operand); |
707 } | 709 } |
708 | 710 |
709 visitFunctionExpression(FunctionExpression node) { | 711 visitFunctionExpression(FunctionExpression node) { |
710 writeByte(Tag.FunctionExpression); | 712 writeByte(Tag.FunctionExpression); |
711 writeNode(node.function); | 713 writeNode(node.function); |
712 } | 714 } |
713 | 715 |
714 visitLet(Let node) { | 716 visitLet(Let node) { |
715 writeByte(Tag.Let); | 717 writeByte(Tag.Let); |
716 writeVariableDeclaration(node.variable); | 718 writeVariableDeclaration(node.variable, false); |
717 writeNode(node.body); | 719 writeNode(node.body); |
718 --_variableIndexer.stackHeight; | 720 --_variableIndexer.stackHeight; |
719 } | 721 } |
720 | 722 |
721 visitLoadLibrary(LoadLibrary node) { | 723 visitLoadLibrary(LoadLibrary node) { |
722 writeByte(Tag.LoadLibrary); | 724 writeByte(Tag.LoadLibrary); |
723 writeDeferredImportReference(node.import); | 725 writeDeferredImportReference(node.import); |
724 } | 726 } |
725 | 727 |
726 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { | 728 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
817 writeOptionalNode(node.condition); | 819 writeOptionalNode(node.condition); |
818 writeNodeList(node.updates); | 820 writeNodeList(node.updates); |
819 writeNode(node.body); | 821 writeNode(node.body); |
820 _variableIndexer.popScope(); | 822 _variableIndexer.popScope(); |
821 } | 823 } |
822 | 824 |
823 visitForInStatement(ForInStatement node) { | 825 visitForInStatement(ForInStatement node) { |
824 _variableIndexer.pushScope(); | 826 _variableIndexer.pushScope(); |
825 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); | 827 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); |
826 writeOffset(node.fileOffset); | 828 writeOffset(node.fileOffset); |
827 writeVariableDeclaration(node.variable); | 829 writeVariableDeclaration(node.variable, false); |
828 writeNode(node.iterable); | 830 writeNode(node.iterable); |
829 writeNode(node.body); | 831 writeNode(node.body); |
830 _variableIndexer.popScope(); | 832 _variableIndexer.popScope(); |
831 } | 833 } |
832 | 834 |
833 visitSwitchStatement(SwitchStatement node) { | 835 visitSwitchStatement(SwitchStatement node) { |
834 _switchCaseIndexer.enter(node); | 836 _switchCaseIndexer.enter(node); |
835 writeByte(Tag.SwitchStatement); | 837 writeByte(Tag.SwitchStatement); |
836 writeNode(node.expression); | 838 writeNode(node.expression); |
837 writeNodeList(node.cases); | 839 writeNodeList(node.cases); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
888 | 890 |
889 visitYieldStatement(YieldStatement node) { | 891 visitYieldStatement(YieldStatement node) { |
890 writeByte(Tag.YieldStatement); | 892 writeByte(Tag.YieldStatement); |
891 writeOffset(node.fileOffset); | 893 writeOffset(node.fileOffset); |
892 writeByte(node.flags); | 894 writeByte(node.flags); |
893 writeNode(node.expression); | 895 writeNode(node.expression); |
894 } | 896 } |
895 | 897 |
896 visitVariableDeclaration(VariableDeclaration node) { | 898 visitVariableDeclaration(VariableDeclaration node) { |
897 writeByte(Tag.VariableDeclaration); | 899 writeByte(Tag.VariableDeclaration); |
898 writeVariableDeclaration(node); | 900 writeVariableDeclaration(node, true); |
899 } | 901 } |
900 | 902 |
901 void writeVariableDeclaration(VariableDeclaration node) { | 903 void writeVariableDeclaration(VariableDeclaration node, |
904 [bool hasTag = false]) { | |
905 int length = _sink.flushedLength + _sink.length - (hasTag ? 1 : 0); | |
Kevin Millikin (Google)
2017/04/05 08:59:57
It seems better to move writing of the tag here so
| |
906 node.tempOffset = length; | |
902 writeOffset(node.fileOffset); | 907 writeOffset(node.fileOffset); |
903 writeOffset(node.fileEqualsOffset); | 908 writeOffset(node.fileEqualsOffset); |
904 writeByte(node.flags); | 909 writeByte(node.flags); |
905 writeStringReference(node.name ?? ''); | 910 writeStringReference(node.name ?? ''); |
906 writeNode(node.type); | 911 writeNode(node.type); |
907 writeOptionalNode(node.initializer); | 912 writeOptionalNode(node.initializer); |
908 // Declare the variable after its initializer. It is not in scope in its | 913 // Declare the variable after its initializer. It is not in scope in its |
909 // own initializer. | 914 // own initializer. |
910 _variableIndexer.declare(node); | 915 _variableIndexer.declare(node); |
911 } | 916 } |
912 | 917 |
913 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { | 918 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { |
914 writeList(nodes, writeVariableDeclaration); | 919 writeList(nodes, writeVariableDeclaration); |
915 } | 920 } |
916 | 921 |
917 void writeOptionalVariableDeclaration(VariableDeclaration node) { | 922 void writeOptionalVariableDeclaration(VariableDeclaration node) { |
918 if (node == null) { | 923 if (node == null) { |
919 writeByte(Tag.Nothing); | 924 writeByte(Tag.Nothing); |
920 } else { | 925 } else { |
921 writeByte(Tag.Something); | 926 writeByte(Tag.Something); |
922 writeVariableDeclaration(node); | 927 writeVariableDeclaration(node, false); |
923 } | 928 } |
924 } | 929 } |
925 | 930 |
926 visitFunctionDeclaration(FunctionDeclaration node) { | 931 visitFunctionDeclaration(FunctionDeclaration node) { |
927 writeByte(Tag.FunctionDeclaration); | 932 writeByte(Tag.FunctionDeclaration); |
928 writeOffset(node.fileOffset); | 933 writeOffset(node.fileOffset); |
929 writeVariableDeclaration(node.variable); | 934 writeVariableDeclaration(node.variable, false); |
930 writeNode(node.function); | 935 writeNode(node.function); |
931 } | 936 } |
932 | 937 |
933 visitBottomType(BottomType node) { | 938 visitBottomType(BottomType node) { |
934 writeByte(Tag.BottomType); | 939 writeByte(Tag.BottomType); |
935 } | 940 } |
936 | 941 |
937 visitInvalidType(InvalidType node) { | 942 visitInvalidType(InvalidType node) { |
938 writeByte(Tag.InvalidType); | 943 writeByte(Tag.InvalidType); |
939 } | 944 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1245 } | 1250 } |
1246 } | 1251 } |
1247 | 1252 |
1248 /// Puts a buffer in front of a [Sink<List<int>>]. | 1253 /// Puts a buffer in front of a [Sink<List<int>>]. |
1249 class BufferedSink { | 1254 class BufferedSink { |
1250 static const int SIZE = 100000; | 1255 static const int SIZE = 100000; |
1251 static const int SMALL = 10000; | 1256 static const int SMALL = 10000; |
1252 final Sink<List<int>> _sink; | 1257 final Sink<List<int>> _sink; |
1253 Uint8List _buffer = new Uint8List(SIZE); | 1258 Uint8List _buffer = new Uint8List(SIZE); |
1254 int length = 0; | 1259 int length = 0; |
1260 int flushedLength = 0; | |
1255 | 1261 |
1256 BufferedSink(this._sink); | 1262 BufferedSink(this._sink); |
1257 | 1263 |
1258 void addByte(int byte) { | 1264 void addByte(int byte) { |
1259 _buffer[length++] = byte; | 1265 _buffer[length++] = byte; |
1260 if (length == SIZE) { | 1266 if (length == SIZE) { |
1261 _sink.add(_buffer); | 1267 _sink.add(_buffer); |
1262 _buffer = new Uint8List(SIZE); | 1268 _buffer = new Uint8List(SIZE); |
1263 length = 0; | 1269 length = 0; |
1270 flushedLength += SIZE; | |
1264 } | 1271 } |
1265 } | 1272 } |
1266 | 1273 |
1267 void addBytes(List<int> bytes) { | 1274 void addBytes(List<int> bytes) { |
1268 // Avoid copying a large buffer into the another large buffer. Also, if | 1275 // Avoid copying a large buffer into the another large buffer. Also, if |
1269 // the bytes buffer is too large to fit in our own buffer, just emit both. | 1276 // the bytes buffer is too large to fit in our own buffer, just emit both. |
1270 if (length + bytes.length < SIZE && | 1277 if (length + bytes.length < SIZE && |
1271 (bytes.length < SMALL || length < SMALL)) { | 1278 (bytes.length < SMALL || length < SMALL)) { |
1272 if (length == 0) { | 1279 if (length == 0) { |
1273 _sink.add(bytes); | 1280 _sink.add(bytes); |
1281 flushedLength += bytes.length; | |
1274 } else { | 1282 } else { |
1275 _buffer.setRange(length, length + bytes.length, bytes); | 1283 _buffer.setRange(length, length + bytes.length, bytes); |
1276 length += bytes.length; | 1284 length += bytes.length; |
1277 } | 1285 } |
1278 } else if (bytes.length < SMALL) { | 1286 } else if (bytes.length < SMALL) { |
1279 // Flush as much as we can in the current buffer. | 1287 // Flush as much as we can in the current buffer. |
1280 _buffer.setRange(length, SIZE, bytes); | 1288 _buffer.setRange(length, SIZE, bytes); |
1281 _sink.add(_buffer); | 1289 _sink.add(_buffer); |
1282 // Copy over the remainder into a new buffer. It is guaranteed to fit | 1290 // Copy over the remainder into a new buffer. It is guaranteed to fit |
1283 // because the input byte array is small. | 1291 // because the input byte array is small. |
1284 int alreadyEmitted = SIZE - length; | 1292 int alreadyEmitted = SIZE - length; |
1285 int remainder = bytes.length - alreadyEmitted; | 1293 int remainder = bytes.length - alreadyEmitted; |
1286 _buffer = new Uint8List(SIZE); | 1294 _buffer = new Uint8List(SIZE); |
1287 _buffer.setRange(0, remainder, bytes, alreadyEmitted); | 1295 _buffer.setRange(0, remainder, bytes, alreadyEmitted); |
1288 length = remainder; | 1296 length = remainder; |
1297 flushedLength += SIZE; | |
1289 } else { | 1298 } else { |
1290 _sink.add(_buffer.sublist(0, length)); | 1299 _sink.add(_buffer.sublist(0, length)); |
1291 _sink.add(bytes); | 1300 _sink.add(bytes); |
1292 _buffer = new Uint8List(SIZE); | 1301 _buffer = new Uint8List(SIZE); |
1302 flushedLength += length; | |
1303 flushedLength += bytes.length; | |
1293 length = 0; | 1304 length = 0; |
1294 } | 1305 } |
1295 } | 1306 } |
1296 | 1307 |
1297 void flush() { | 1308 void flush() { |
1298 _sink.add(_buffer.sublist(0, length)); | 1309 _sink.add(_buffer.sublist(0, length)); |
1299 _buffer = new Uint8List(SIZE); | 1310 _buffer = new Uint8List(SIZE); |
1311 flushedLength += length; | |
1300 length = 0; | 1312 length = 0; |
1301 } | 1313 } |
1302 | 1314 |
1303 void flushAndDestroy() { | 1315 void flushAndDestroy() { |
1304 _sink.add(_buffer.sublist(0, length)); | 1316 _sink.add(_buffer.sublist(0, length)); |
1305 } | 1317 } |
1306 } | 1318 } |
OLD | NEW |