Chromium Code Reviews| 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 |