Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: lib/binary/ast_to_binary.dart

Issue 2507723002: Remove unnecessary indexing passes from serialization. (Closed)
Patch Set: Add copyright Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/serialize_bench.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | test/serialize_bench.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698