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 |