| 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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 int abstactFlag = isAbstract ? 1 : 0; | 340 int abstactFlag = isAbstract ? 1 : 0; |
| 341 int levelFlags = (level.index - 1) << 1; | 341 int levelFlags = (level.index - 1) << 1; |
| 342 return abstactFlag | levelFlags; | 342 return abstactFlag | levelFlags; |
| 343 } | 343 } |
| 344 | 344 |
| 345 visitClass(Class node) { | 345 visitClass(Class node) { |
| 346 int flags = _encodeClassFlags(node.isAbstract, node.level); | 346 int flags = _encodeClassFlags(node.isAbstract, node.level); |
| 347 if (node.canonicalName == null) { | 347 if (node.canonicalName == null) { |
| 348 throw 'Missing canonical name for $node'; | 348 throw 'Missing canonical name for $node'; |
| 349 } | 349 } |
| 350 node.binaryOffset = _sink.flushedLength + _sink.length; |
| 350 writeByte(Tag.Class); | 351 writeByte(Tag.Class); |
| 351 writeCanonicalNameReference(getCanonicalNameOfClass(node)); | 352 writeCanonicalNameReference(getCanonicalNameOfClass(node)); |
| 352 writeOffset(node.fileOffset); | 353 writeOffset(node.fileOffset); |
| 353 writeByte(flags); | 354 writeByte(flags); |
| 354 writeStringReference(node.name ?? ''); | 355 writeStringReference(node.name ?? ''); |
| 355 writeUriReference(node.fileUri ?? ''); | 356 writeUriReference(node.fileUri ?? ''); |
| 356 writeAnnotationList(node.annotations); | 357 writeAnnotationList(node.annotations); |
| 357 _typeParameterIndexer.enter(node.typeParameters); | 358 _typeParameterIndexer.enter(node.typeParameters); |
| 358 writeNodeList(node.typeParameters); | 359 writeNodeList(node.typeParameters); |
| 359 writeOptionalNode(node.supertype); | 360 writeOptionalNode(node.supertype); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 370 visitConstructor(Constructor node) { | 371 visitConstructor(Constructor node) { |
| 371 if (node.canonicalName == null) { | 372 if (node.canonicalName == null) { |
| 372 throw 'Missing canonical name for $node'; | 373 throw 'Missing canonical name for $node'; |
| 373 } | 374 } |
| 374 _variableIndexer = new VariableIndexer(); | 375 _variableIndexer = new VariableIndexer(); |
| 375 writeByte(Tag.Constructor); | 376 writeByte(Tag.Constructor); |
| 376 writeCanonicalNameReference(getCanonicalNameOfMember(node)); | 377 writeCanonicalNameReference(getCanonicalNameOfMember(node)); |
| 377 writeOffset(node.fileOffset); | 378 writeOffset(node.fileOffset); |
| 378 writeOffset(node.fileEndOffset); | 379 writeOffset(node.fileEndOffset); |
| 379 writeByte(node.flags); | 380 writeByte(node.flags); |
| 381 assert(node.parent is Class); |
| 382 Class parent = node.parent; |
| 383 writeUInt30(parent.binaryOffset); |
| 380 writeName(node.name ?? _emptyName); | 384 writeName(node.name ?? _emptyName); |
| 381 writeAnnotationList(node.annotations); | 385 writeAnnotationList(node.annotations); |
| 382 assert(node.function.typeParameters.isEmpty); | 386 assert(node.function.typeParameters.isEmpty); |
| 383 writeNode(node.function); | 387 writeNode(node.function); |
| 384 // Parameters are in scope in the initializers. | 388 // Parameters are in scope in the initializers. |
| 385 _variableIndexer.restoreScope(node.function.positionalParameters.length + | 389 _variableIndexer.restoreScope(node.function.positionalParameters.length + |
| 386 node.function.namedParameters.length); | 390 node.function.namedParameters.length); |
| 387 writeNodeList(node.initializers); | 391 writeNodeList(node.initializers); |
| 388 _variableIndexer = null; | 392 _variableIndexer = null; |
| 389 } | 393 } |
| 390 | 394 |
| 391 visitProcedure(Procedure node) { | 395 visitProcedure(Procedure node) { |
| 392 if (node.canonicalName == null) { | 396 if (node.canonicalName == null) { |
| 393 throw 'Missing canonical name for $node'; | 397 throw 'Missing canonical name for $node'; |
| 394 } | 398 } |
| 395 _variableIndexer = new VariableIndexer(); | 399 _variableIndexer = new VariableIndexer(); |
| 396 writeByte(Tag.Procedure); | 400 writeByte(Tag.Procedure); |
| 397 writeCanonicalNameReference(getCanonicalNameOfMember(node)); | 401 writeCanonicalNameReference(getCanonicalNameOfMember(node)); |
| 398 writeOffset(node.fileOffset); | 402 writeOffset(node.fileOffset); |
| 399 writeOffset(node.fileEndOffset); | 403 writeOffset(node.fileEndOffset); |
| 400 writeByte(node.kind.index); | 404 writeByte(node.kind.index); |
| 401 writeByte(node.flags); | 405 writeByte(node.flags); |
| 406 if (node.parent is Class) { |
| 407 Class parent = node.parent; |
| 408 writeUInt30(parent.binaryOffset); |
| 409 } else { |
| 410 writeUInt30(0); // 0 is a valid offset, but not for a class. |
| 411 } |
| 402 writeName(node.name ?? ''); | 412 writeName(node.name ?? ''); |
| 403 writeUriReference(node.fileUri ?? ''); | 413 writeUriReference(node.fileUri ?? ''); |
| 404 writeAnnotationList(node.annotations); | 414 writeAnnotationList(node.annotations); |
| 405 writeOptionalNode(node.function); | 415 writeOptionalNode(node.function); |
| 406 _variableIndexer = null; | 416 _variableIndexer = null; |
| 407 } | 417 } |
| 408 | 418 |
| 409 visitField(Field node) { | 419 visitField(Field node) { |
| 410 if (node.canonicalName == null) { | 420 if (node.canonicalName == null) { |
| 411 throw 'Missing canonical name for $node'; | 421 throw 'Missing canonical name for $node'; |
| 412 } | 422 } |
| 413 _variableIndexer = new VariableIndexer(); | 423 _variableIndexer = new VariableIndexer(); |
| 414 writeByte(Tag.Field); | 424 writeByte(Tag.Field); |
| 415 writeCanonicalNameReference(getCanonicalNameOfMember(node)); | 425 writeCanonicalNameReference(getCanonicalNameOfMember(node)); |
| 416 writeOffset(node.fileOffset); | 426 writeOffset(node.fileOffset); |
| 417 writeOffset(node.fileEndOffset); | 427 writeOffset(node.fileEndOffset); |
| 418 writeByte(node.flags); | 428 writeByte(node.flags); |
| 429 if (node.parent is Class) { |
| 430 Class parent = node.parent; |
| 431 writeUInt30(parent.binaryOffset); |
| 432 } else { |
| 433 writeUInt30(0); // 0 is a valid offset, but not for a class. |
| 434 } |
| 419 writeName(node.name); | 435 writeName(node.name); |
| 420 writeUriReference(node.fileUri ?? ''); | 436 writeUriReference(node.fileUri ?? ''); |
| 421 writeAnnotationList(node.annotations); | 437 writeAnnotationList(node.annotations); |
| 422 writeNode(node.type); | 438 writeNode(node.type); |
| 423 writeOptionalNode(node.initializer); | 439 writeOptionalNode(node.initializer); |
| 424 _variableIndexer = null; | 440 _variableIndexer = null; |
| 425 } | 441 } |
| 426 | 442 |
| 427 visitInvalidInitializer(InvalidInitializer node) { | 443 visitInvalidInitializer(InvalidInitializer node) { |
| 428 writeByte(Tag.InvalidInitializer); | 444 writeByte(Tag.InvalidInitializer); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 441 } | 457 } |
| 442 | 458 |
| 443 visitRedirectingInitializer(RedirectingInitializer node) { | 459 visitRedirectingInitializer(RedirectingInitializer node) { |
| 444 writeByte(Tag.RedirectingInitializer); | 460 writeByte(Tag.RedirectingInitializer); |
| 445 writeReference(node.targetReference); | 461 writeReference(node.targetReference); |
| 446 writeNode(node.arguments); | 462 writeNode(node.arguments); |
| 447 } | 463 } |
| 448 | 464 |
| 449 visitLocalInitializer(LocalInitializer node) { | 465 visitLocalInitializer(LocalInitializer node) { |
| 450 writeByte(Tag.LocalInitializer); | 466 writeByte(Tag.LocalInitializer); |
| 451 writeVariableDeclaration(node.variable, false); | 467 writeVariableDeclaration(node.variable); |
| 452 } | 468 } |
| 453 | 469 |
| 454 visitFunctionNode(FunctionNode node) { | 470 visitFunctionNode(FunctionNode node) { |
| 471 writeByte(Tag.FunctionNode); |
| 455 assert(_variableIndexer != null); | 472 assert(_variableIndexer != null); |
| 456 _variableIndexer.pushScope(); | 473 _variableIndexer.pushScope(); |
| 457 var oldLabels = _labelIndexer; | 474 var oldLabels = _labelIndexer; |
| 458 _labelIndexer = new LabelIndexer(); | 475 _labelIndexer = new LabelIndexer(); |
| 459 var oldCases = _switchCaseIndexer; | 476 var oldCases = _switchCaseIndexer; |
| 460 _switchCaseIndexer = new SwitchCaseIndexer(); | 477 _switchCaseIndexer = new SwitchCaseIndexer(); |
| 461 // Note: FunctionNode has no tag. | 478 // Note: FunctionNode has no tag. |
| 462 _typeParameterIndexer.enter(node.typeParameters); | 479 _typeParameterIndexer.enter(node.typeParameters); |
| 463 writeOffset(node.fileOffset); | 480 writeOffset(node.fileOffset); |
| 464 writeOffset(node.fileEndOffset); | 481 writeOffset(node.fileEndOffset); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 481 } | 498 } |
| 482 | 499 |
| 483 visitVariableGet(VariableGet node) { | 500 visitVariableGet(VariableGet node) { |
| 484 assert(_variableIndexer != null); | 501 assert(_variableIndexer != null); |
| 485 int index = _variableIndexer[node.variable]; | 502 int index = _variableIndexer[node.variable]; |
| 486 assert(index != null); | 503 assert(index != null); |
| 487 if (index & Tag.SpecializedPayloadMask == index && | 504 if (index & Tag.SpecializedPayloadMask == index && |
| 488 node.promotedType == null) { | 505 node.promotedType == null) { |
| 489 writeByte(Tag.SpecializedVariableGet + index); | 506 writeByte(Tag.SpecializedVariableGet + index); |
| 490 writeOffset(node.fileOffset); | 507 writeOffset(node.fileOffset); |
| 491 writeUInt30(node.variable.binaryOffset); | 508 writeUInt30(node.variable.binaryOffsetNoTag); |
| 492 } else { | 509 } else { |
| 493 writeByte(Tag.VariableGet); | 510 writeByte(Tag.VariableGet); |
| 494 writeOffset(node.fileOffset); | 511 writeOffset(node.fileOffset); |
| 495 writeUInt30(node.variable.binaryOffset); | 512 writeUInt30(node.variable.binaryOffsetNoTag); |
| 496 writeUInt30(_variableIndexer[node.variable]); | 513 writeUInt30(_variableIndexer[node.variable]); |
| 497 writeOptionalNode(node.promotedType); | 514 writeOptionalNode(node.promotedType); |
| 498 } | 515 } |
| 499 } | 516 } |
| 500 | 517 |
| 501 visitVariableSet(VariableSet node) { | 518 visitVariableSet(VariableSet node) { |
| 502 assert(_variableIndexer != null); | 519 assert(_variableIndexer != null); |
| 503 int index = _variableIndexer[node.variable]; | 520 int index = _variableIndexer[node.variable]; |
| 504 if (index & Tag.SpecializedPayloadMask == index) { | 521 if (index & Tag.SpecializedPayloadMask == index) { |
| 505 writeByte(Tag.SpecializedVariableSet + index); | 522 writeByte(Tag.SpecializedVariableSet + index); |
| 506 writeOffset(node.fileOffset); | 523 writeOffset(node.fileOffset); |
| 507 writeUInt30(node.variable.binaryOffset); | 524 writeUInt30(node.variable.binaryOffsetNoTag); |
| 508 writeNode(node.value); | 525 writeNode(node.value); |
| 509 } else { | 526 } else { |
| 510 writeByte(Tag.VariableSet); | 527 writeByte(Tag.VariableSet); |
| 511 writeOffset(node.fileOffset); | 528 writeOffset(node.fileOffset); |
| 512 writeUInt30(node.variable.binaryOffset); | 529 writeUInt30(node.variable.binaryOffsetNoTag); |
| 513 writeUInt30(_variableIndexer[node.variable]); | 530 writeUInt30(_variableIndexer[node.variable]); |
| 514 writeNode(node.value); | 531 writeNode(node.value); |
| 515 } | 532 } |
| 516 } | 533 } |
| 517 | 534 |
| 518 visitPropertyGet(PropertyGet node) { | 535 visitPropertyGet(PropertyGet node) { |
| 519 writeByte(Tag.PropertyGet); | 536 writeByte(Tag.PropertyGet); |
| 520 writeOffset(node.fileOffset); | 537 writeOffset(node.fileOffset); |
| 521 writeNode(node.receiver); | 538 writeNode(node.receiver); |
| 522 writeName(node.name); | 539 writeName(node.name); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 writeNode(node.operand); | 783 writeNode(node.operand); |
| 767 } | 784 } |
| 768 | 785 |
| 769 visitFunctionExpression(FunctionExpression node) { | 786 visitFunctionExpression(FunctionExpression node) { |
| 770 writeByte(Tag.FunctionExpression); | 787 writeByte(Tag.FunctionExpression); |
| 771 writeNode(node.function); | 788 writeNode(node.function); |
| 772 } | 789 } |
| 773 | 790 |
| 774 visitLet(Let node) { | 791 visitLet(Let node) { |
| 775 writeByte(Tag.Let); | 792 writeByte(Tag.Let); |
| 776 writeVariableDeclaration(node.variable, false); | 793 writeVariableDeclaration(node.variable); |
| 777 writeNode(node.body); | 794 writeNode(node.body); |
| 778 --_variableIndexer.stackHeight; | 795 --_variableIndexer.stackHeight; |
| 779 } | 796 } |
| 780 | 797 |
| 781 visitLoadLibrary(LoadLibrary node) { | 798 visitLoadLibrary(LoadLibrary node) { |
| 782 writeByte(Tag.LoadLibrary); | 799 writeByte(Tag.LoadLibrary); |
| 783 writeLibraryDependencyReference(node.import); | 800 writeLibraryDependencyReference(node.import); |
| 784 } | 801 } |
| 785 | 802 |
| 786 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { | 803 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 writeOptionalNode(node.condition); | 901 writeOptionalNode(node.condition); |
| 885 writeNodeList(node.updates); | 902 writeNodeList(node.updates); |
| 886 writeNode(node.body); | 903 writeNode(node.body); |
| 887 _variableIndexer.popScope(); | 904 _variableIndexer.popScope(); |
| 888 } | 905 } |
| 889 | 906 |
| 890 visitForInStatement(ForInStatement node) { | 907 visitForInStatement(ForInStatement node) { |
| 891 _variableIndexer.pushScope(); | 908 _variableIndexer.pushScope(); |
| 892 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); | 909 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); |
| 893 writeOffset(node.fileOffset); | 910 writeOffset(node.fileOffset); |
| 894 writeVariableDeclaration(node.variable, false); | 911 writeVariableDeclaration(node.variable); |
| 895 writeNode(node.iterable); | 912 writeNode(node.iterable); |
| 896 writeNode(node.body); | 913 writeNode(node.body); |
| 897 _variableIndexer.popScope(); | 914 _variableIndexer.popScope(); |
| 898 } | 915 } |
| 899 | 916 |
| 900 visitSwitchStatement(SwitchStatement node) { | 917 visitSwitchStatement(SwitchStatement node) { |
| 901 _switchCaseIndexer.enter(node); | 918 _switchCaseIndexer.enter(node); |
| 902 writeByte(Tag.SwitchStatement); | 919 writeByte(Tag.SwitchStatement); |
| 903 writeNode(node.expression); | 920 writeNode(node.expression); |
| 904 writeNodeList(node.cases); | 921 writeNodeList(node.cases); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 } | 982 } |
| 966 | 983 |
| 967 visitYieldStatement(YieldStatement node) { | 984 visitYieldStatement(YieldStatement node) { |
| 968 writeByte(Tag.YieldStatement); | 985 writeByte(Tag.YieldStatement); |
| 969 writeOffset(node.fileOffset); | 986 writeOffset(node.fileOffset); |
| 970 writeByte(node.flags); | 987 writeByte(node.flags); |
| 971 writeNode(node.expression); | 988 writeNode(node.expression); |
| 972 } | 989 } |
| 973 | 990 |
| 974 visitVariableDeclaration(VariableDeclaration node) { | 991 visitVariableDeclaration(VariableDeclaration node) { |
| 975 writeVariableDeclaration(node, true); | 992 writeByte(Tag.VariableDeclaration); |
| 993 writeVariableDeclaration(node); |
| 976 } | 994 } |
| 977 | 995 |
| 978 void writeVariableDeclaration(VariableDeclaration node, | 996 void writeVariableDeclaration(VariableDeclaration node) { |
| 979 [bool hasTag = false]) { | 997 node.binaryOffsetNoTag = _sink.flushedLength + _sink.length; |
| 980 node.binaryOffset = _sink.flushedLength + _sink.length; | |
| 981 if (hasTag) writeByte(Tag.VariableDeclaration); | |
| 982 writeOffset(node.fileOffset); | 998 writeOffset(node.fileOffset); |
| 983 writeOffset(node.fileEqualsOffset); | 999 writeOffset(node.fileEqualsOffset); |
| 984 writeByte(node.flags); | 1000 writeByte(node.flags); |
| 985 writeStringReference(node.name ?? ''); | 1001 writeStringReference(node.name ?? ''); |
| 986 writeNode(node.type); | 1002 writeNode(node.type); |
| 987 writeOptionalNode(node.initializer); | 1003 writeOptionalNode(node.initializer); |
| 988 // Declare the variable after its initializer. It is not in scope in its | 1004 // Declare the variable after its initializer. It is not in scope in its |
| 989 // own initializer. | 1005 // own initializer. |
| 990 _variableIndexer.declare(node); | 1006 _variableIndexer.declare(node); |
| 991 } | 1007 } |
| 992 | 1008 |
| 993 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { | 1009 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { |
| 994 writeList(nodes, writeVariableDeclaration); | 1010 writeList(nodes, writeVariableDeclaration); |
| 995 } | 1011 } |
| 996 | 1012 |
| 997 void writeOptionalVariableDeclaration(VariableDeclaration node) { | 1013 void writeOptionalVariableDeclaration(VariableDeclaration node) { |
| 998 if (node == null) { | 1014 if (node == null) { |
| 999 writeByte(Tag.Nothing); | 1015 writeByte(Tag.Nothing); |
| 1000 } else { | 1016 } else { |
| 1001 writeByte(Tag.Something); | 1017 writeByte(Tag.Something); |
| 1002 writeVariableDeclaration(node, false); | 1018 writeVariableDeclaration(node); |
| 1003 } | 1019 } |
| 1004 } | 1020 } |
| 1005 | 1021 |
| 1006 visitFunctionDeclaration(FunctionDeclaration node) { | 1022 visitFunctionDeclaration(FunctionDeclaration node) { |
| 1007 writeByte(Tag.FunctionDeclaration); | 1023 writeByte(Tag.FunctionDeclaration); |
| 1008 writeOffset(node.fileOffset); | 1024 writeOffset(node.fileOffset); |
| 1009 writeVariableDeclaration(node.variable, false); | 1025 writeVariableDeclaration(node.variable); |
| 1010 writeNode(node.function); | 1026 writeNode(node.function); |
| 1011 } | 1027 } |
| 1012 | 1028 |
| 1013 visitBottomType(BottomType node) { | 1029 visitBottomType(BottomType node) { |
| 1014 writeByte(Tag.BottomType); | 1030 writeByte(Tag.BottomType); |
| 1015 } | 1031 } |
| 1016 | 1032 |
| 1017 visitInvalidType(InvalidType node) { | 1033 visitInvalidType(InvalidType node) { |
| 1018 writeByte(Tag.InvalidType); | 1034 writeByte(Tag.InvalidType); |
| 1019 } | 1035 } |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1446 _sink.add(_buffer.sublist(0, length)); | 1462 _sink.add(_buffer.sublist(0, length)); |
| 1447 _buffer = new Uint8List(SIZE); | 1463 _buffer = new Uint8List(SIZE); |
| 1448 flushedLength += length; | 1464 flushedLength += length; |
| 1449 length = 0; | 1465 length = 0; |
| 1450 } | 1466 } |
| 1451 | 1467 |
| 1452 void flushAndDestroy() { | 1468 void flushAndDestroy() { |
| 1453 _sink.add(_buffer.sublist(0, length)); | 1469 _sink.add(_buffer.sublist(0, length)); |
| 1454 } | 1470 } |
| 1455 } | 1471 } |
| OLD | NEW |