| 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 // TODO: We can do the indexing on-the-fly, but for now just keep it simple. | |
| 21 VariableIndexer _variableIndexer; | 20 VariableIndexer _variableIndexer; |
| 22 LabelIndexer _labelIndexer; | 21 LabelIndexer _labelIndexer; |
| 23 SwitchCaseIndexer _switchCaseIndexer; | 22 SwitchCaseIndexer _switchCaseIndexer; |
| 24 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer(); | 23 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer(); |
| 25 final GlobalIndexer _globalIndexer; | 24 final GlobalIndexer _globalIndexer; |
| 26 final StringIndexer _stringIndexer = new StringIndexer(); | 25 final StringIndexer _stringIndexer = new StringIndexer(); |
| 27 final StringIndexer _sourceUriIndexer = new StringIndexer(); | 26 final StringIndexer _sourceUriIndexer = new StringIndexer(); |
| 28 | 27 |
| 29 final BufferedSink _sink; | 28 final BufferedSink _sink; |
| 30 | 29 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 writeStringReference('${node.importUri}'); | 266 writeStringReference('${node.importUri}'); |
| 268 // TODO(jensj): We save (almost) the same URI twice. | 267 // TODO(jensj): We save (almost) the same URI twice. |
| 269 writeUriReference(node.fileUri ?? ''); | 268 writeUriReference(node.fileUri ?? ''); |
| 270 writeNodeList(node.classes); | 269 writeNodeList(node.classes); |
| 271 writeNodeList(node.fields); | 270 writeNodeList(node.fields); |
| 272 writeNodeList(node.procedures); | 271 writeNodeList(node.procedures); |
| 273 } | 272 } |
| 274 | 273 |
| 275 void writeAnnotation(Expression annotation) { | 274 void writeAnnotation(Expression annotation) { |
| 276 _variableIndexer ??= new VariableIndexer(); | 275 _variableIndexer ??= new VariableIndexer(); |
| 277 _variableIndexer.build(annotation); | |
| 278 writeNode(annotation); | 276 writeNode(annotation); |
| 279 } | 277 } |
| 280 | 278 |
| 281 void writeAnnotationList(List<Expression> annotations) { | 279 void writeAnnotationList(List<Expression> annotations) { |
| 282 writeList(annotations, writeAnnotation); | 280 writeList(annotations, writeAnnotation); |
| 283 } | 281 } |
| 284 | 282 |
| 285 visitClass(Class node) { | 283 visitClass(Class node) { |
| 286 int flags = node.isAbstract ? 1 : 0; | 284 int flags = node.isAbstract ? 1 : 0; |
| 287 if (node.level == ClassLevel.Type) { | 285 if (node.level == ClassLevel.Type) { |
| 288 flags |= 0x2; | 286 flags |= 0x2; |
| 289 } | 287 } |
| 290 if (node.isMixinApplication) { | 288 if (node.isMixinApplication) { |
| 291 writeByte(Tag.MixinClass); | 289 writeByte(Tag.MixinClass); |
| 292 writeByte(flags); | 290 writeByte(flags); |
| 293 writeStringReference(node.name ?? ''); | 291 writeStringReference(node.name ?? ''); |
| 294 writeUriReference(node.fileUri ?? ''); | 292 writeUriReference(node.fileUri ?? ''); |
| 295 writeAnnotationList(node.annotations); | 293 writeAnnotationList(node.annotations); |
| 296 _typeParameterIndexer.push(node.typeParameters); | 294 _typeParameterIndexer.enter(node.typeParameters); |
| 297 writeNodeList(node.typeParameters); | 295 writeNodeList(node.typeParameters); |
| 298 writeNode(node.supertype); | 296 writeNode(node.supertype); |
| 299 writeNode(node.mixedInType); | 297 writeNode(node.mixedInType); |
| 300 writeNodeList(node.implementedTypes); | 298 writeNodeList(node.implementedTypes); |
| 301 writeNodeList(node.constructors); | 299 writeNodeList(node.constructors); |
| 302 _typeParameterIndexer.pop(node.typeParameters); | 300 _typeParameterIndexer.exit(node.typeParameters); |
| 303 } else { | 301 } else { |
| 304 writeByte(Tag.NormalClass); | 302 writeByte(Tag.NormalClass); |
| 305 writeByte(flags); | 303 writeByte(flags); |
| 306 writeStringReference(node.name ?? ''); | 304 writeStringReference(node.name ?? ''); |
| 307 writeUriReference(node.fileUri ?? ''); | 305 writeUriReference(node.fileUri ?? ''); |
| 308 writeAnnotationList(node.annotations); | 306 writeAnnotationList(node.annotations); |
| 309 _typeParameterIndexer.push(node.typeParameters); | 307 _typeParameterIndexer.enter(node.typeParameters); |
| 310 writeNodeList(node.typeParameters); | 308 writeNodeList(node.typeParameters); |
| 311 writeOptionalNode(node.supertype); | 309 writeOptionalNode(node.supertype); |
| 312 writeNodeList(node.implementedTypes); | 310 writeNodeList(node.implementedTypes); |
| 313 writeNodeList(node.fields); | 311 writeNodeList(node.fields); |
| 314 writeNodeList(node.constructors); | 312 writeNodeList(node.constructors); |
| 315 writeNodeList(node.procedures); | 313 writeNodeList(node.procedures); |
| 316 _typeParameterIndexer.pop(node.typeParameters); | 314 _typeParameterIndexer.exit(node.typeParameters); |
| 317 } | 315 } |
| 318 } | 316 } |
| 319 | 317 |
| 320 static final Name _emptyName = new Name(''); | 318 static final Name _emptyName = new Name(''); |
| 321 | 319 |
| 322 visitConstructor(Constructor node) { | 320 visitConstructor(Constructor node) { |
| 323 _variableIndexer = new VariableIndexer()..build(node); | 321 _variableIndexer = new VariableIndexer(); |
| 324 writeByte(Tag.Constructor); | 322 writeByte(Tag.Constructor); |
| 325 writeByte(node.flags); | 323 writeByte(node.flags); |
| 326 writeName(node.name ?? _emptyName); | 324 writeName(node.name ?? _emptyName); |
| 327 writeAnnotationList(node.annotations); | 325 writeAnnotationList(node.annotations); |
| 328 assert(node.function.typeParameters.isEmpty); | 326 assert(node.function.typeParameters.isEmpty); |
| 329 writeNode(node.function); | 327 writeNode(node.function); |
| 328 // Parameters are in scope in the initializers. |
| 329 _variableIndexer.restoreScope(node.function.positionalParameters.length + |
| 330 node.function.namedParameters.length); |
| 330 writeNodeList(node.initializers); | 331 writeNodeList(node.initializers); |
| 332 _variableIndexer = null; |
| 331 } | 333 } |
| 332 | 334 |
| 333 visitProcedure(Procedure node) { | 335 visitProcedure(Procedure node) { |
| 334 _variableIndexer = new VariableIndexer()..build(node); | 336 _variableIndexer = new VariableIndexer(); |
| 335 writeByte(Tag.Procedure); | 337 writeByte(Tag.Procedure); |
| 336 writeByte(node.kind.index); | 338 writeByte(node.kind.index); |
| 337 writeByte(node.flags); | 339 writeByte(node.flags); |
| 338 writeName(node.name ?? ''); | 340 writeName(node.name ?? ''); |
| 339 writeUriReference(node.fileUri ?? ''); | 341 writeUriReference(node.fileUri ?? ''); |
| 340 writeAnnotationList(node.annotations); | 342 writeAnnotationList(node.annotations); |
| 341 writeOptionalNode(node.function); | 343 writeOptionalNode(node.function); |
| 344 _variableIndexer = null; |
| 342 } | 345 } |
| 343 | 346 |
| 344 visitField(Field node) { | 347 visitField(Field node) { |
| 345 _variableIndexer = new VariableIndexer()..build(node); | 348 _variableIndexer = new VariableIndexer(); |
| 346 writeByte(Tag.Field); | 349 writeByte(Tag.Field); |
| 347 writeOffset(node); | 350 writeOffset(node); |
| 348 writeByte(node.flags); | 351 writeByte(node.flags); |
| 349 writeName(node.name ?? ''); | 352 writeName(node.name ?? ''); |
| 350 writeUriReference(node.fileUri ?? ''); | 353 writeUriReference(node.fileUri ?? ''); |
| 351 writeAnnotationList(node.annotations); | 354 writeAnnotationList(node.annotations); |
| 352 writeNode(node.type); | 355 writeNode(node.type); |
| 353 writeOptionalInferredValue(node.inferredValue); | 356 writeOptionalInferredValue(node.inferredValue); |
| 354 writeOptionalNode(node.initializer); | 357 writeOptionalNode(node.initializer); |
| 358 _variableIndexer = null; |
| 355 } | 359 } |
| 356 | 360 |
| 357 visitInvalidInitializer(InvalidInitializer node) { | 361 visitInvalidInitializer(InvalidInitializer node) { |
| 358 writeByte(Tag.InvalidInitializer); | 362 writeByte(Tag.InvalidInitializer); |
| 359 } | 363 } |
| 360 | 364 |
| 361 visitFieldInitializer(FieldInitializer node) { | 365 visitFieldInitializer(FieldInitializer node) { |
| 362 writeByte(Tag.FieldInitializer); | 366 writeByte(Tag.FieldInitializer); |
| 363 writeMemberReference(node.field); | 367 writeMemberReference(node.field); |
| 364 writeNode(node.value); | 368 writeNode(node.value); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 376 writeNode(node.arguments); | 380 writeNode(node.arguments); |
| 377 } | 381 } |
| 378 | 382 |
| 379 visitLocalInitializer(LocalInitializer node) { | 383 visitLocalInitializer(LocalInitializer node) { |
| 380 writeByte(Tag.LocalInitializer); | 384 writeByte(Tag.LocalInitializer); |
| 381 writeVariableDeclaration(node.variable); | 385 writeVariableDeclaration(node.variable); |
| 382 } | 386 } |
| 383 | 387 |
| 384 visitFunctionNode(FunctionNode node) { | 388 visitFunctionNode(FunctionNode node) { |
| 385 assert(_variableIndexer != null); | 389 assert(_variableIndexer != null); |
| 390 _variableIndexer.pushScope(); |
| 386 var oldLabels = _labelIndexer; | 391 var oldLabels = _labelIndexer; |
| 387 _labelIndexer = new LabelIndexer()..build(node); | 392 _labelIndexer = new LabelIndexer(); |
| 388 var oldCases = _switchCaseIndexer; | 393 var oldCases = _switchCaseIndexer; |
| 389 _switchCaseIndexer = new SwitchCaseIndexer()..build(node); | 394 _switchCaseIndexer = new SwitchCaseIndexer(); |
| 390 // Note: FunctionNode has no tag. | 395 // Note: FunctionNode has no tag. |
| 391 _typeParameterIndexer.push(node.typeParameters); | 396 _typeParameterIndexer.enter(node.typeParameters); |
| 392 writeByte(node.asyncMarker.index); | 397 writeByte(node.asyncMarker.index); |
| 393 writeNodeList(node.typeParameters); | 398 writeNodeList(node.typeParameters); |
| 394 writeUInt30(node.requiredParameterCount); | 399 writeUInt30(node.requiredParameterCount); |
| 395 writeVariableDeclarationList(node.positionalParameters); | 400 writeVariableDeclarationList(node.positionalParameters); |
| 396 writeVariableDeclarationList(node.namedParameters); | 401 writeVariableDeclarationList(node.namedParameters); |
| 397 writeNode(node.returnType); | 402 writeNode(node.returnType); |
| 398 writeOptionalInferredValue(node.inferredReturnValue); | 403 writeOptionalInferredValue(node.inferredReturnValue); |
| 399 writeOptionalNode(node.body); | 404 writeOptionalNode(node.body); |
| 400 _labelIndexer = oldLabels; | 405 _labelIndexer = oldLabels; |
| 401 _switchCaseIndexer = oldCases; | 406 _switchCaseIndexer = oldCases; |
| 402 _typeParameterIndexer.pop(node.typeParameters); | 407 _typeParameterIndexer.exit(node.typeParameters); |
| 408 _variableIndexer.popScope(); |
| 403 } | 409 } |
| 404 | 410 |
| 405 visitInvalidExpression(InvalidExpression node) { | 411 visitInvalidExpression(InvalidExpression node) { |
| 406 writeByte(Tag.InvalidExpression); | 412 writeByte(Tag.InvalidExpression); |
| 407 } | 413 } |
| 408 | 414 |
| 409 visitVariableGet(VariableGet node) { | 415 visitVariableGet(VariableGet node) { |
| 410 assert(_variableIndexer != null); | 416 assert(_variableIndexer != null); |
| 411 int index = _variableIndexer[node.variable]; | 417 int index = _variableIndexer[node.variable]; |
| 412 assert(index != null); | 418 assert(index != null); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 | 682 |
| 677 visitFunctionExpression(FunctionExpression node) { | 683 visitFunctionExpression(FunctionExpression node) { |
| 678 writeByte(Tag.FunctionExpression); | 684 writeByte(Tag.FunctionExpression); |
| 679 writeNode(node.function); | 685 writeNode(node.function); |
| 680 } | 686 } |
| 681 | 687 |
| 682 visitLet(Let node) { | 688 visitLet(Let node) { |
| 683 writeByte(Tag.Let); | 689 writeByte(Tag.Let); |
| 684 writeVariableDeclaration(node.variable); | 690 writeVariableDeclaration(node.variable); |
| 685 writeNode(node.body); | 691 writeNode(node.body); |
| 692 --_variableIndexer.stackHeight; |
| 686 } | 693 } |
| 687 | 694 |
| 688 writeStatementOrEmpty(Statement node) { | 695 writeStatementOrEmpty(Statement node) { |
| 689 if (node == null) { | 696 if (node == null) { |
| 690 writeByte(Tag.EmptyStatement); | 697 writeByte(Tag.EmptyStatement); |
| 691 } else { | 698 } else { |
| 692 writeNode(node); | 699 writeNode(node); |
| 693 } | 700 } |
| 694 } | 701 } |
| 695 | 702 |
| 696 visitInvalidStatement(InvalidStatement node) { | 703 visitInvalidStatement(InvalidStatement node) { |
| 697 writeByte(Tag.InvalidStatement); | 704 writeByte(Tag.InvalidStatement); |
| 698 } | 705 } |
| 699 | 706 |
| 700 visitExpressionStatement(ExpressionStatement node) { | 707 visitExpressionStatement(ExpressionStatement node) { |
| 701 writeByte(Tag.ExpressionStatement); | 708 writeByte(Tag.ExpressionStatement); |
| 702 writeNode(node.expression); | 709 writeNode(node.expression); |
| 703 } | 710 } |
| 704 | 711 |
| 705 visitBlock(Block node) { | 712 visitBlock(Block node) { |
| 713 _variableIndexer.pushScope(); |
| 706 writeByte(Tag.Block); | 714 writeByte(Tag.Block); |
| 707 writeNodeList(node.statements); | 715 writeNodeList(node.statements); |
| 716 _variableIndexer.popScope(); |
| 708 } | 717 } |
| 709 | 718 |
| 710 visitEmptyStatement(EmptyStatement node) { | 719 visitEmptyStatement(EmptyStatement node) { |
| 711 writeByte(Tag.EmptyStatement); | 720 writeByte(Tag.EmptyStatement); |
| 712 } | 721 } |
| 713 | 722 |
| 714 visitAssertStatement(AssertStatement node) { | 723 visitAssertStatement(AssertStatement node) { |
| 715 writeByte(Tag.AssertStatement); | 724 writeByte(Tag.AssertStatement); |
| 716 writeNode(node.condition); | 725 writeNode(node.condition); |
| 717 writeOptionalNode(node.message); | 726 writeOptionalNode(node.message); |
| 718 } | 727 } |
| 719 | 728 |
| 720 visitLabeledStatement(LabeledStatement node) { | 729 visitLabeledStatement(LabeledStatement node) { |
| 730 _labelIndexer.enter(node); |
| 721 writeByte(Tag.LabeledStatement); | 731 writeByte(Tag.LabeledStatement); |
| 722 writeNode(node.body); | 732 writeNode(node.body); |
| 733 _labelIndexer.exit(); |
| 723 } | 734 } |
| 724 | 735 |
| 725 visitBreakStatement(BreakStatement node) { | 736 visitBreakStatement(BreakStatement node) { |
| 726 writeByte(Tag.BreakStatement); | 737 writeByte(Tag.BreakStatement); |
| 727 writeUInt30(_labelIndexer[node.target]); | 738 writeUInt30(_labelIndexer[node.target]); |
| 728 } | 739 } |
| 729 | 740 |
| 730 visitWhileStatement(WhileStatement node) { | 741 visitWhileStatement(WhileStatement node) { |
| 731 writeByte(Tag.WhileStatement); | 742 writeByte(Tag.WhileStatement); |
| 732 writeNode(node.condition); | 743 writeNode(node.condition); |
| 733 writeNode(node.body); | 744 writeNode(node.body); |
| 734 } | 745 } |
| 735 | 746 |
| 736 visitDoStatement(DoStatement node) { | 747 visitDoStatement(DoStatement node) { |
| 737 writeByte(Tag.DoStatement); | 748 writeByte(Tag.DoStatement); |
| 738 writeNode(node.body); | 749 writeNode(node.body); |
| 739 writeNode(node.condition); | 750 writeNode(node.condition); |
| 740 } | 751 } |
| 741 | 752 |
| 742 visitForStatement(ForStatement node) { | 753 visitForStatement(ForStatement node) { |
| 754 _variableIndexer.pushScope(); |
| 743 writeByte(Tag.ForStatement); | 755 writeByte(Tag.ForStatement); |
| 744 writeVariableDeclarationList(node.variables); | 756 writeVariableDeclarationList(node.variables); |
| 745 writeOptionalNode(node.condition); | 757 writeOptionalNode(node.condition); |
| 746 writeNodeList(node.updates); | 758 writeNodeList(node.updates); |
| 747 writeNode(node.body); | 759 writeNode(node.body); |
| 760 _variableIndexer.popScope(); |
| 748 } | 761 } |
| 749 | 762 |
| 750 visitForInStatement(ForInStatement node) { | 763 visitForInStatement(ForInStatement node) { |
| 764 _variableIndexer.pushScope(); |
| 751 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); | 765 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); |
| 752 writeVariableDeclaration(node.variable); | 766 writeVariableDeclaration(node.variable); |
| 753 writeNode(node.iterable); | 767 writeNode(node.iterable); |
| 754 writeNode(node.body); | 768 writeNode(node.body); |
| 769 _variableIndexer.popScope(); |
| 755 } | 770 } |
| 756 | 771 |
| 757 visitSwitchStatement(SwitchStatement node) { | 772 visitSwitchStatement(SwitchStatement node) { |
| 773 _switchCaseIndexer.enter(node); |
| 758 writeByte(Tag.SwitchStatement); | 774 writeByte(Tag.SwitchStatement); |
| 759 writeNode(node.expression); | 775 writeNode(node.expression); |
| 760 writeNodeList(node.cases); | 776 writeNodeList(node.cases); |
| 777 _switchCaseIndexer.exit(node); |
| 761 } | 778 } |
| 762 | 779 |
| 763 visitSwitchCase(SwitchCase node) { | 780 visitSwitchCase(SwitchCase node) { |
| 764 // Note: there is no tag on SwitchCase. | 781 // Note: there is no tag on SwitchCase. |
| 765 writeNodeList(node.expressions); | 782 writeNodeList(node.expressions); |
| 766 writeByte(node.isDefault ? 1 : 0); | 783 writeByte(node.isDefault ? 1 : 0); |
| 767 writeNode(node.body); | 784 writeNode(node.body); |
| 768 } | 785 } |
| 769 | 786 |
| 770 visitContinueSwitchStatement(ContinueSwitchStatement node) { | 787 visitContinueSwitchStatement(ContinueSwitchStatement node) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 785 } | 802 } |
| 786 | 803 |
| 787 visitTryCatch(TryCatch node) { | 804 visitTryCatch(TryCatch node) { |
| 788 writeByte(Tag.TryCatch); | 805 writeByte(Tag.TryCatch); |
| 789 writeNode(node.body); | 806 writeNode(node.body); |
| 790 writeNodeList(node.catches); | 807 writeNodeList(node.catches); |
| 791 } | 808 } |
| 792 | 809 |
| 793 visitCatch(Catch node) { | 810 visitCatch(Catch node) { |
| 794 // Note: there is no tag on Catch. | 811 // Note: there is no tag on Catch. |
| 812 _variableIndexer.pushScope(); |
| 795 writeNode(node.guard); | 813 writeNode(node.guard); |
| 796 writeOptionalVariableDeclaration(node.exception); | 814 writeOptionalVariableDeclaration(node.exception); |
| 797 writeOptionalVariableDeclaration(node.stackTrace); | 815 writeOptionalVariableDeclaration(node.stackTrace); |
| 798 writeNode(node.body); | 816 writeNode(node.body); |
| 817 _variableIndexer.popScope(); |
| 799 } | 818 } |
| 800 | 819 |
| 801 visitTryFinally(TryFinally node) { | 820 visitTryFinally(TryFinally node) { |
| 802 writeByte(Tag.TryFinally); | 821 writeByte(Tag.TryFinally); |
| 803 writeNode(node.body); | 822 writeNode(node.body); |
| 804 writeNode(node.finalizer); | 823 writeNode(node.finalizer); |
| 805 } | 824 } |
| 806 | 825 |
| 807 visitYieldStatement(YieldStatement node) { | 826 visitYieldStatement(YieldStatement node) { |
| 808 writeByte(Tag.YieldStatement); | 827 writeByte(Tag.YieldStatement); |
| 809 writeByte(node.flags); | 828 writeByte(node.flags); |
| 810 writeNode(node.expression); | 829 writeNode(node.expression); |
| 811 } | 830 } |
| 812 | 831 |
| 813 visitVariableDeclaration(VariableDeclaration node) { | 832 visitVariableDeclaration(VariableDeclaration node) { |
| 814 writeByte(Tag.VariableDeclaration); | 833 writeByte(Tag.VariableDeclaration); |
| 815 writeVariableDeclaration(node); | 834 writeVariableDeclaration(node); |
| 816 } | 835 } |
| 817 | 836 |
| 818 void writeVariableDeclaration(VariableDeclaration node) { | 837 void writeVariableDeclaration(VariableDeclaration node) { |
| 819 writeByte(node.flags); | 838 writeByte(node.flags); |
| 820 writeStringReference(node.name ?? ''); | 839 writeStringReference(node.name ?? ''); |
| 821 writeNode(node.type); | 840 writeNode(node.type); |
| 822 writeOptionalInferredValue(node.inferredValue); | 841 writeOptionalInferredValue(node.inferredValue); |
| 823 writeOptionalNode(node.initializer); | 842 writeOptionalNode(node.initializer); |
| 843 // Declare the variable after its initializer. It is not in scope in its |
| 844 // own initializer. |
| 845 _variableIndexer.declare(node); |
| 824 } | 846 } |
| 825 | 847 |
| 826 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { | 848 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { |
| 827 writeList(nodes, writeVariableDeclaration); | 849 writeList(nodes, writeVariableDeclaration); |
| 828 } | 850 } |
| 829 | 851 |
| 830 void writeOptionalVariableDeclaration(VariableDeclaration node) { | 852 void writeOptionalVariableDeclaration(VariableDeclaration node) { |
| 831 if (node == null) { | 853 if (node == null) { |
| 832 writeByte(Tag.Nothing); | 854 writeByte(Tag.Nothing); |
| 833 } else { | 855 } else { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 | 904 |
| 883 visitFunctionType(FunctionType node) { | 905 visitFunctionType(FunctionType node) { |
| 884 if (node.requiredParameterCount == node.positionalParameters.length && | 906 if (node.requiredParameterCount == node.positionalParameters.length && |
| 885 node.typeParameters.isEmpty && | 907 node.typeParameters.isEmpty && |
| 886 node.namedParameters.isEmpty) { | 908 node.namedParameters.isEmpty) { |
| 887 writeByte(Tag.SimpleFunctionType); | 909 writeByte(Tag.SimpleFunctionType); |
| 888 writeNodeList(node.positionalParameters); | 910 writeNodeList(node.positionalParameters); |
| 889 writeNode(node.returnType); | 911 writeNode(node.returnType); |
| 890 } else { | 912 } else { |
| 891 writeByte(Tag.FunctionType); | 913 writeByte(Tag.FunctionType); |
| 892 _typeParameterIndexer.push(node.typeParameters); | 914 _typeParameterIndexer.enter(node.typeParameters); |
| 893 writeNodeList(node.typeParameters); | 915 writeNodeList(node.typeParameters); |
| 894 writeUInt30(node.requiredParameterCount); | 916 writeUInt30(node.requiredParameterCount); |
| 895 writeNodeList(node.positionalParameters); | 917 writeNodeList(node.positionalParameters); |
| 896 writeList(node.namedParameters.keys.toList(), (String name) { | 918 writeList(node.namedParameters.keys.toList(), (String name) { |
| 897 writeStringReference(name); | 919 writeStringReference(name); |
| 898 writeNode(node.namedParameters[name]); | 920 writeNode(node.namedParameters[name]); |
| 899 }); | 921 }); |
| 900 writeNode(node.returnType); | 922 writeNode(node.returnType); |
| 901 _typeParameterIndexer.pop(node.typeParameters); | 923 _typeParameterIndexer.exit(node.typeParameters); |
| 902 } | 924 } |
| 903 } | 925 } |
| 904 | 926 |
| 905 visitTypeParameterType(TypeParameterType node) { | 927 visitTypeParameterType(TypeParameterType node) { |
| 906 writeByte(Tag.TypeParameterType); | 928 writeByte(Tag.TypeParameterType); |
| 907 writeUInt30(_typeParameterIndexer[node.parameter]); | 929 writeUInt30(_typeParameterIndexer[node.parameter]); |
| 908 } | 930 } |
| 909 | 931 |
| 910 visitTypeParameter(TypeParameter node) { | 932 visitTypeParameter(TypeParameter node) { |
| 911 writeStringReference(node.name ?? ''); | 933 writeStringReference(node.name ?? ''); |
| 912 writeNode(node.bound); | 934 writeNode(node.bound); |
| 913 } | 935 } |
| 914 | 936 |
| 915 defaultNode(Node node) { | 937 defaultNode(Node node) { |
| 916 throw 'Unsupported node: $node'; | 938 throw 'Unsupported node: $node'; |
| 917 } | 939 } |
| 918 } | 940 } |
| 919 | 941 |
| 920 class VariableIndexer extends RecursiveVisitor { | 942 class VariableIndexer { |
| 921 final Map<VariableDeclaration, int> index = <VariableDeclaration, int>{}; | 943 final Map<VariableDeclaration, int> index = <VariableDeclaration, int>{}; |
| 944 final List<int> scopes = <int>[]; |
| 922 int stackHeight = 0; | 945 int stackHeight = 0; |
| 923 | 946 |
| 924 void build(TreeNode node) => node.accept(this); | 947 void declare(VariableDeclaration node) { |
| 925 | 948 index[node] = stackHeight++; |
| 926 visitConstructor(Constructor node) { | |
| 927 node.function.accept(this); | |
| 928 // Keep parameters in scope when traversing initializers. | |
| 929 stackHeight = node.function.positionalParameters.length + | |
| 930 node.function.namedParameters.length; | |
| 931 for (var init in node.initializers) { | |
| 932 init.accept(this); | |
| 933 } | |
| 934 stackHeight = 0; | |
| 935 } | 949 } |
| 936 | 950 |
| 937 visitFunctionNode(FunctionNode node) { | 951 void pushScope() { |
| 938 int frame = stackHeight; | 952 scopes.add(stackHeight); |
| 939 node.visitChildren(this); | |
| 940 stackHeight = frame; | |
| 941 } | 953 } |
| 942 | 954 |
| 943 visitBlock(Block node) { | 955 void popScope() { |
| 944 int frame = stackHeight; | 956 stackHeight = scopes.removeLast(); |
| 945 node.visitChildren(this); | |
| 946 stackHeight = frame; | |
| 947 } | 957 } |
| 948 | 958 |
| 949 visitLet(Let node) { | 959 void restoreScope(int numberOfVariables) { |
| 950 int frame = stackHeight; | 960 stackHeight += numberOfVariables; |
| 951 node.visitChildren(this); | |
| 952 stackHeight = frame; | |
| 953 } | 961 } |
| 954 | 962 |
| 955 visitForInStatement(ForInStatement node) { | 963 int operator [](VariableDeclaration node) { |
| 956 int frame = stackHeight; | 964 return index[node]; |
| 957 node.visitChildren(this); | |
| 958 stackHeight = frame; | |
| 959 } | 965 } |
| 960 | |
| 961 visitForStatement(ForStatement node) { | |
| 962 int frame = stackHeight; | |
| 963 node.visitChildren(this); | |
| 964 stackHeight = frame; | |
| 965 } | |
| 966 | |
| 967 visitCatch(Catch node) { | |
| 968 int frame = stackHeight; | |
| 969 node.visitChildren(this); | |
| 970 stackHeight = frame; | |
| 971 } | |
| 972 | |
| 973 visitVariableDeclaration(VariableDeclaration node) { | |
| 974 node.visitChildren(this); | |
| 975 assert(!index.containsKey(node)); | |
| 976 index[node] = stackHeight; | |
| 977 ++stackHeight; | |
| 978 } | |
| 979 | |
| 980 int operator [](VariableDeclaration node) => index[node]; | |
| 981 } | 966 } |
| 982 | 967 |
| 983 class LabelIndexer extends RecursiveVisitor { | 968 class LabelIndexer { |
| 984 final Map<LabeledStatement, int> index = <LabeledStatement, int>{}; | 969 final Map<LabeledStatement, int> index = <LabeledStatement, int>{}; |
| 985 int stackHeight = 0; | 970 int stackHeight = 0; |
| 986 | 971 |
| 987 void build(FunctionNode node) => node.visitChildren(this); | 972 void enter(LabeledStatement node) { |
| 988 | 973 index[node] = stackHeight++; |
| 989 visitFunctionNode(FunctionNode node) { | |
| 990 // Inhibit traversal into nested functions. | |
| 991 // The client must create a separate label indexer for the | |
| 992 // nested function. | |
| 993 } | 974 } |
| 994 | 975 |
| 995 visitLabeledStatement(LabeledStatement node) { | 976 void exit() { |
| 996 index[node] = stackHeight; | |
| 997 ++stackHeight; | |
| 998 node.visitChildren(this); | |
| 999 --stackHeight; | 977 --stackHeight; |
| 1000 } | 978 } |
| 1001 | 979 |
| 1002 int operator [](LabeledStatement node) => index[node]; | 980 int operator [](LabeledStatement node) => index[node]; |
| 1003 } | 981 } |
| 1004 | 982 |
| 1005 class SwitchCaseIndexer extends RecursiveVisitor { | 983 class SwitchCaseIndexer { |
| 1006 final Map<SwitchCase, int> index = <SwitchCase, int>{}; | 984 final Map<SwitchCase, int> index = <SwitchCase, int>{}; |
| 1007 int stackHeight = 0; | 985 int stackHeight = 0; |
| 1008 | 986 |
| 1009 void build(FunctionNode node) => node.visitChildren(this); | 987 void enter(SwitchStatement node) { |
| 1010 | 988 for (var caseNode in node.cases) { |
| 1011 visitFunctionNode(FunctionNode node) { | 989 index[caseNode] = stackHeight++; |
| 1012 // Inhibit traversal into nested functions. | 990 } |
| 1013 // The client must create a separate case indexer for the | |
| 1014 // nested function. | |
| 1015 } | 991 } |
| 1016 | 992 |
| 1017 visitSwitchStatement(SwitchStatement node) { | 993 void exit(SwitchStatement node) { |
| 1018 int oldHeight = stackHeight; | 994 stackHeight -= node.cases.length; |
| 1019 for (var caseNode in node.cases) { | |
| 1020 index[caseNode] = stackHeight; | |
| 1021 ++stackHeight; | |
| 1022 } | |
| 1023 node.visitChildren(this); | |
| 1024 stackHeight = oldHeight; | |
| 1025 } | 995 } |
| 1026 | 996 |
| 1027 int operator [](SwitchCase node) => index[node]; | 997 int operator [](SwitchCase node) => index[node]; |
| 1028 } | 998 } |
| 1029 | 999 |
| 1030 /// The type parameter indexer works differently from the other indexers because | |
| 1031 /// type parameters can be bound inside DartTypes, which can be shared by the | |
| 1032 /// in-memory representation (but not the binary form) and the index depends on | |
| 1033 /// the use site. | |
| 1034 class TypeParameterIndexer { | 1000 class TypeParameterIndexer { |
| 1035 final Map<TypeParameter, int> index = <TypeParameter, int>{}; | 1001 final Map<TypeParameter, int> index = <TypeParameter, int>{}; |
| 1036 int stackHeight = 0; | 1002 int stackHeight = 0; |
| 1037 | 1003 |
| 1038 void push(List<TypeParameter> typeParameters) { | 1004 void enter(List<TypeParameter> typeParameters) { |
| 1039 for (var parameter in typeParameters) { | 1005 for (var parameter in typeParameters) { |
| 1040 index[parameter] = stackHeight; | 1006 index[parameter] = stackHeight; |
| 1041 ++stackHeight; | 1007 ++stackHeight; |
| 1042 } | 1008 } |
| 1043 } | 1009 } |
| 1044 | 1010 |
| 1045 void pop(List<TypeParameter> typeParameters) { | 1011 void exit(List<TypeParameter> typeParameters) { |
| 1046 stackHeight -= typeParameters.length; | 1012 stackHeight -= typeParameters.length; |
| 1047 } | 1013 } |
| 1048 | 1014 |
| 1049 int operator [](TypeParameter parameter) => index[parameter]; | 1015 int operator [](TypeParameter parameter) => index[parameter]; |
| 1050 } | 1016 } |
| 1051 | 1017 |
| 1052 class StringTableEntry implements Comparable<StringTableEntry> { | 1018 class StringTableEntry implements Comparable<StringTableEntry> { |
| 1053 final String value; | 1019 final String value; |
| 1054 int frequency = 0; | 1020 int frequency = 0; |
| 1055 | 1021 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 void flush() { | 1215 void flush() { |
| 1250 _sink.add(_buffer.sublist(0, length)); | 1216 _sink.add(_buffer.sublist(0, length)); |
| 1251 _buffer = new Uint8List(SIZE); | 1217 _buffer = new Uint8List(SIZE); |
| 1252 length = 0; | 1218 length = 0; |
| 1253 } | 1219 } |
| 1254 | 1220 |
| 1255 void flushAndDestroy() { | 1221 void flushAndDestroy() { |
| 1256 _sink.add(_buffer.sublist(0, length)); | 1222 _sink.add(_buffer.sublist(0, length)); |
| 1257 } | 1223 } |
| 1258 } | 1224 } |
| OLD | NEW |