| 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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 int abstactFlag = isAbstract ? 1 : 0; | 296 int abstactFlag = isAbstract ? 1 : 0; |
| 297 int levelFlags = (level.index - 1) << 1; | 297 int levelFlags = (level.index - 1) << 1; |
| 298 return abstactFlag | levelFlags; | 298 return abstactFlag | levelFlags; |
| 299 } | 299 } |
| 300 | 300 |
| 301 visitClass(Class node) { | 301 visitClass(Class node) { |
| 302 int flags = _encodeClassFlags(node.isAbstract, node.level); | 302 int flags = _encodeClassFlags(node.isAbstract, node.level); |
| 303 if (node.canonicalName == null) { | 303 if (node.canonicalName == null) { |
| 304 throw 'Missing canonical name for $node'; | 304 throw 'Missing canonical name for $node'; |
| 305 } | 305 } |
| 306 node.binaryOffset = _sink.flushedLength + _sink.length; |
| 306 writeByte(Tag.Class); | 307 writeByte(Tag.Class); |
| 307 writeCanonicalNameReference(getCanonicalNameOfClass(node)); | 308 writeCanonicalNameReference(getCanonicalNameOfClass(node)); |
| 308 writeOffset(node.fileOffset); | 309 writeOffset(node.fileOffset); |
| 309 writeByte(flags); | 310 writeByte(flags); |
| 310 writeStringReference(node.name ?? ''); | 311 writeStringReference(node.name ?? ''); |
| 311 writeUriReference(node.fileUri ?? ''); | 312 writeUriReference(node.fileUri ?? ''); |
| 312 writeAnnotationList(node.annotations); | 313 writeAnnotationList(node.annotations); |
| 313 _typeParameterIndexer.enter(node.typeParameters); | 314 _typeParameterIndexer.enter(node.typeParameters); |
| 314 writeNodeList(node.typeParameters); | 315 writeNodeList(node.typeParameters); |
| 315 writeOptionalNode(node.supertype); | 316 writeOptionalNode(node.supertype); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 326 visitConstructor(Constructor node) { | 327 visitConstructor(Constructor node) { |
| 327 if (node.canonicalName == null) { | 328 if (node.canonicalName == null) { |
| 328 throw 'Missing canonical name for $node'; | 329 throw 'Missing canonical name for $node'; |
| 329 } | 330 } |
| 330 _variableIndexer = new VariableIndexer(); | 331 _variableIndexer = new VariableIndexer(); |
| 331 writeByte(Tag.Constructor); | 332 writeByte(Tag.Constructor); |
| 332 writeCanonicalNameReference(getCanonicalNameOfMember(node)); | 333 writeCanonicalNameReference(getCanonicalNameOfMember(node)); |
| 333 writeOffset(node.fileOffset); | 334 writeOffset(node.fileOffset); |
| 334 writeOffset(node.fileEndOffset); | 335 writeOffset(node.fileEndOffset); |
| 335 writeByte(node.flags); | 336 writeByte(node.flags); |
| 337 assert(node.parent is Class); |
| 338 Class parent = node.parent; |
| 339 writeUInt30(parent.binaryOffset); |
| 336 writeName(node.name ?? _emptyName); | 340 writeName(node.name ?? _emptyName); |
| 337 writeAnnotationList(node.annotations); | 341 writeAnnotationList(node.annotations); |
| 338 assert(node.function.typeParameters.isEmpty); | 342 assert(node.function.typeParameters.isEmpty); |
| 339 writeNode(node.function); | 343 writeNode(node.function); |
| 340 // Parameters are in scope in the initializers. | 344 // Parameters are in scope in the initializers. |
| 341 _variableIndexer.restoreScope(node.function.positionalParameters.length + | 345 _variableIndexer.restoreScope(node.function.positionalParameters.length + |
| 342 node.function.namedParameters.length); | 346 node.function.namedParameters.length); |
| 343 writeNodeList(node.initializers); | 347 writeNodeList(node.initializers); |
| 344 _variableIndexer = null; | 348 _variableIndexer = null; |
| 345 } | 349 } |
| 346 | 350 |
| 347 visitProcedure(Procedure node) { | 351 visitProcedure(Procedure node) { |
| 348 if (node.canonicalName == null) { | 352 if (node.canonicalName == null) { |
| 349 throw 'Missing canonical name for $node'; | 353 throw 'Missing canonical name for $node'; |
| 350 } | 354 } |
| 351 _variableIndexer = new VariableIndexer(); | 355 _variableIndexer = new VariableIndexer(); |
| 352 writeByte(Tag.Procedure); | 356 writeByte(Tag.Procedure); |
| 353 writeCanonicalNameReference(getCanonicalNameOfMember(node)); | 357 writeCanonicalNameReference(getCanonicalNameOfMember(node)); |
| 354 writeOffset(node.fileOffset); | 358 writeOffset(node.fileOffset); |
| 355 writeOffset(node.fileEndOffset); | 359 writeOffset(node.fileEndOffset); |
| 356 writeByte(node.kind.index); | 360 writeByte(node.kind.index); |
| 357 writeByte(node.flags); | 361 writeByte(node.flags); |
| 362 if (node.parent is Class) { |
| 363 Class parent = node.parent; |
| 364 writeUInt30(parent.binaryOffset); |
| 365 } else { |
| 366 writeUInt30(0); // 0 is a valid offset, but not for a class. |
| 367 } |
| 358 writeName(node.name ?? ''); | 368 writeName(node.name ?? ''); |
| 359 writeUriReference(node.fileUri ?? ''); | 369 writeUriReference(node.fileUri ?? ''); |
| 360 writeAnnotationList(node.annotations); | 370 writeAnnotationList(node.annotations); |
| 361 writeOptionalNode(node.function); | 371 writeOptionalNode(node.function); |
| 362 _variableIndexer = null; | 372 _variableIndexer = null; |
| 363 } | 373 } |
| 364 | 374 |
| 365 visitField(Field node) { | 375 visitField(Field node) { |
| 366 if (node.canonicalName == null) { | 376 if (node.canonicalName == null) { |
| 367 throw 'Missing canonical name for $node'; | 377 throw 'Missing canonical name for $node'; |
| 368 } | 378 } |
| 369 _variableIndexer = new VariableIndexer(); | 379 _variableIndexer = new VariableIndexer(); |
| 370 writeByte(Tag.Field); | 380 writeByte(Tag.Field); |
| 371 writeCanonicalNameReference(getCanonicalNameOfMember(node)); | 381 writeCanonicalNameReference(getCanonicalNameOfMember(node)); |
| 372 writeOffset(node.fileOffset); | 382 writeOffset(node.fileOffset); |
| 373 writeOffset(node.fileEndOffset); | 383 writeOffset(node.fileEndOffset); |
| 374 writeByte(node.flags); | 384 writeByte(node.flags); |
| 385 if (node.parent is Class) { |
| 386 Class parent = node.parent; |
| 387 writeUInt30(parent.binaryOffset); |
| 388 } else { |
| 389 writeUInt30(0); // 0 is a valid offset, but not for a class. |
| 390 } |
| 375 writeName(node.name); | 391 writeName(node.name); |
| 376 writeUriReference(node.fileUri ?? ''); | 392 writeUriReference(node.fileUri ?? ''); |
| 377 writeAnnotationList(node.annotations); | 393 writeAnnotationList(node.annotations); |
| 378 writeNode(node.type); | 394 writeNode(node.type); |
| 379 writeOptionalNode(node.initializer); | 395 writeOptionalNode(node.initializer); |
| 380 _variableIndexer = null; | 396 _variableIndexer = null; |
| 381 } | 397 } |
| 382 | 398 |
| 383 visitInvalidInitializer(InvalidInitializer node) { | 399 visitInvalidInitializer(InvalidInitializer node) { |
| 384 writeByte(Tag.InvalidInitializer); | 400 writeByte(Tag.InvalidInitializer); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 397 } | 413 } |
| 398 | 414 |
| 399 visitRedirectingInitializer(RedirectingInitializer node) { | 415 visitRedirectingInitializer(RedirectingInitializer node) { |
| 400 writeByte(Tag.RedirectingInitializer); | 416 writeByte(Tag.RedirectingInitializer); |
| 401 writeReference(node.targetReference); | 417 writeReference(node.targetReference); |
| 402 writeNode(node.arguments); | 418 writeNode(node.arguments); |
| 403 } | 419 } |
| 404 | 420 |
| 405 visitLocalInitializer(LocalInitializer node) { | 421 visitLocalInitializer(LocalInitializer node) { |
| 406 writeByte(Tag.LocalInitializer); | 422 writeByte(Tag.LocalInitializer); |
| 407 writeVariableDeclaration(node.variable, false); | 423 writeVariableDeclaration(node.variable); |
| 408 } | 424 } |
| 409 | 425 |
| 410 visitFunctionNode(FunctionNode node) { | 426 visitFunctionNode(FunctionNode node) { |
| 427 writeByte(Tag.FunctionNode); |
| 411 assert(_variableIndexer != null); | 428 assert(_variableIndexer != null); |
| 412 _variableIndexer.pushScope(); | 429 _variableIndexer.pushScope(); |
| 413 var oldLabels = _labelIndexer; | 430 var oldLabels = _labelIndexer; |
| 414 _labelIndexer = new LabelIndexer(); | 431 _labelIndexer = new LabelIndexer(); |
| 415 var oldCases = _switchCaseIndexer; | 432 var oldCases = _switchCaseIndexer; |
| 416 _switchCaseIndexer = new SwitchCaseIndexer(); | 433 _switchCaseIndexer = new SwitchCaseIndexer(); |
| 417 // Note: FunctionNode has no tag. | 434 // Note: FunctionNode has no tag. |
| 418 _typeParameterIndexer.enter(node.typeParameters); | 435 _typeParameterIndexer.enter(node.typeParameters); |
| 419 writeOffset(node.fileOffset); | 436 writeOffset(node.fileOffset); |
| 420 writeOffset(node.fileEndOffset); | 437 writeOffset(node.fileEndOffset); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 437 } | 454 } |
| 438 | 455 |
| 439 visitVariableGet(VariableGet node) { | 456 visitVariableGet(VariableGet node) { |
| 440 assert(_variableIndexer != null); | 457 assert(_variableIndexer != null); |
| 441 int index = _variableIndexer[node.variable]; | 458 int index = _variableIndexer[node.variable]; |
| 442 assert(index != null); | 459 assert(index != null); |
| 443 if (index & Tag.SpecializedPayloadMask == index && | 460 if (index & Tag.SpecializedPayloadMask == index && |
| 444 node.promotedType == null) { | 461 node.promotedType == null) { |
| 445 writeByte(Tag.SpecializedVariableGet + index); | 462 writeByte(Tag.SpecializedVariableGet + index); |
| 446 writeOffset(node.fileOffset); | 463 writeOffset(node.fileOffset); |
| 447 writeUInt30(node.variable.binaryOffset); | 464 writeUInt30(node.variable.binaryOffsetNoTag); |
| 448 } else { | 465 } else { |
| 449 writeByte(Tag.VariableGet); | 466 writeByte(Tag.VariableGet); |
| 450 writeOffset(node.fileOffset); | 467 writeOffset(node.fileOffset); |
| 451 writeUInt30(node.variable.binaryOffset); | 468 writeUInt30(node.variable.binaryOffsetNoTag); |
| 452 writeUInt30(_variableIndexer[node.variable]); | 469 writeUInt30(_variableIndexer[node.variable]); |
| 453 writeOptionalNode(node.promotedType); | 470 writeOptionalNode(node.promotedType); |
| 454 } | 471 } |
| 455 } | 472 } |
| 456 | 473 |
| 457 visitVariableSet(VariableSet node) { | 474 visitVariableSet(VariableSet node) { |
| 458 assert(_variableIndexer != null); | 475 assert(_variableIndexer != null); |
| 459 int index = _variableIndexer[node.variable]; | 476 int index = _variableIndexer[node.variable]; |
| 460 if (index & Tag.SpecializedPayloadMask == index) { | 477 if (index & Tag.SpecializedPayloadMask == index) { |
| 461 writeByte(Tag.SpecializedVariableSet + index); | 478 writeByte(Tag.SpecializedVariableSet + index); |
| 462 writeOffset(node.fileOffset); | 479 writeOffset(node.fileOffset); |
| 463 writeUInt30(node.variable.binaryOffset); | 480 writeUInt30(node.variable.binaryOffsetNoTag); |
| 464 writeNode(node.value); | 481 writeNode(node.value); |
| 465 } else { | 482 } else { |
| 466 writeByte(Tag.VariableSet); | 483 writeByte(Tag.VariableSet); |
| 467 writeOffset(node.fileOffset); | 484 writeOffset(node.fileOffset); |
| 468 writeUInt30(node.variable.binaryOffset); | 485 writeUInt30(node.variable.binaryOffsetNoTag); |
| 469 writeUInt30(_variableIndexer[node.variable]); | 486 writeUInt30(_variableIndexer[node.variable]); |
| 470 writeNode(node.value); | 487 writeNode(node.value); |
| 471 } | 488 } |
| 472 } | 489 } |
| 473 | 490 |
| 474 visitPropertyGet(PropertyGet node) { | 491 visitPropertyGet(PropertyGet node) { |
| 475 writeByte(Tag.PropertyGet); | 492 writeByte(Tag.PropertyGet); |
| 476 writeOffset(node.fileOffset); | 493 writeOffset(node.fileOffset); |
| 477 writeNode(node.receiver); | 494 writeNode(node.receiver); |
| 478 writeName(node.name); | 495 writeName(node.name); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 writeNode(node.operand); | 739 writeNode(node.operand); |
| 723 } | 740 } |
| 724 | 741 |
| 725 visitFunctionExpression(FunctionExpression node) { | 742 visitFunctionExpression(FunctionExpression node) { |
| 726 writeByte(Tag.FunctionExpression); | 743 writeByte(Tag.FunctionExpression); |
| 727 writeNode(node.function); | 744 writeNode(node.function); |
| 728 } | 745 } |
| 729 | 746 |
| 730 visitLet(Let node) { | 747 visitLet(Let node) { |
| 731 writeByte(Tag.Let); | 748 writeByte(Tag.Let); |
| 732 writeVariableDeclaration(node.variable, false); | 749 writeVariableDeclaration(node.variable); |
| 733 writeNode(node.body); | 750 writeNode(node.body); |
| 734 --_variableIndexer.stackHeight; | 751 --_variableIndexer.stackHeight; |
| 735 } | 752 } |
| 736 | 753 |
| 737 visitLoadLibrary(LoadLibrary node) { | 754 visitLoadLibrary(LoadLibrary node) { |
| 738 writeByte(Tag.LoadLibrary); | 755 writeByte(Tag.LoadLibrary); |
| 739 writeDeferredImportReference(node.import); | 756 writeDeferredImportReference(node.import); |
| 740 } | 757 } |
| 741 | 758 |
| 742 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { | 759 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 writeOptionalNode(node.condition); | 857 writeOptionalNode(node.condition); |
| 841 writeNodeList(node.updates); | 858 writeNodeList(node.updates); |
| 842 writeNode(node.body); | 859 writeNode(node.body); |
| 843 _variableIndexer.popScope(); | 860 _variableIndexer.popScope(); |
| 844 } | 861 } |
| 845 | 862 |
| 846 visitForInStatement(ForInStatement node) { | 863 visitForInStatement(ForInStatement node) { |
| 847 _variableIndexer.pushScope(); | 864 _variableIndexer.pushScope(); |
| 848 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); | 865 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); |
| 849 writeOffset(node.fileOffset); | 866 writeOffset(node.fileOffset); |
| 850 writeVariableDeclaration(node.variable, false); | 867 writeVariableDeclaration(node.variable); |
| 851 writeNode(node.iterable); | 868 writeNode(node.iterable); |
| 852 writeNode(node.body); | 869 writeNode(node.body); |
| 853 _variableIndexer.popScope(); | 870 _variableIndexer.popScope(); |
| 854 } | 871 } |
| 855 | 872 |
| 856 visitSwitchStatement(SwitchStatement node) { | 873 visitSwitchStatement(SwitchStatement node) { |
| 857 _switchCaseIndexer.enter(node); | 874 _switchCaseIndexer.enter(node); |
| 858 writeByte(Tag.SwitchStatement); | 875 writeByte(Tag.SwitchStatement); |
| 859 writeNode(node.expression); | 876 writeNode(node.expression); |
| 860 writeNodeList(node.cases); | 877 writeNodeList(node.cases); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 } | 938 } |
| 922 | 939 |
| 923 visitYieldStatement(YieldStatement node) { | 940 visitYieldStatement(YieldStatement node) { |
| 924 writeByte(Tag.YieldStatement); | 941 writeByte(Tag.YieldStatement); |
| 925 writeOffset(node.fileOffset); | 942 writeOffset(node.fileOffset); |
| 926 writeByte(node.flags); | 943 writeByte(node.flags); |
| 927 writeNode(node.expression); | 944 writeNode(node.expression); |
| 928 } | 945 } |
| 929 | 946 |
| 930 visitVariableDeclaration(VariableDeclaration node) { | 947 visitVariableDeclaration(VariableDeclaration node) { |
| 931 writeVariableDeclaration(node, true); | 948 writeByte(Tag.VariableDeclaration); |
| 949 writeVariableDeclaration(node); |
| 932 } | 950 } |
| 933 | 951 |
| 934 void writeVariableDeclaration(VariableDeclaration node, | 952 void writeVariableDeclaration(VariableDeclaration node) { |
| 935 [bool hasTag = false]) { | 953 node.binaryOffsetNoTag = _sink.flushedLength + _sink.length; |
| 936 node.binaryOffset = _sink.flushedLength + _sink.length; | |
| 937 if (hasTag) writeByte(Tag.VariableDeclaration); | |
| 938 writeOffset(node.fileOffset); | 954 writeOffset(node.fileOffset); |
| 939 writeOffset(node.fileEqualsOffset); | 955 writeOffset(node.fileEqualsOffset); |
| 940 writeByte(node.flags); | 956 writeByte(node.flags); |
| 941 writeStringReference(node.name ?? ''); | 957 writeStringReference(node.name ?? ''); |
| 942 writeNode(node.type); | 958 writeNode(node.type); |
| 943 writeOptionalNode(node.initializer); | 959 writeOptionalNode(node.initializer); |
| 944 // Declare the variable after its initializer. It is not in scope in its | 960 // Declare the variable after its initializer. It is not in scope in its |
| 945 // own initializer. | 961 // own initializer. |
| 946 _variableIndexer.declare(node); | 962 _variableIndexer.declare(node); |
| 947 } | 963 } |
| 948 | 964 |
| 949 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { | 965 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { |
| 950 writeList(nodes, writeVariableDeclaration); | 966 writeList(nodes, writeVariableDeclaration); |
| 951 } | 967 } |
| 952 | 968 |
| 953 void writeOptionalVariableDeclaration(VariableDeclaration node) { | 969 void writeOptionalVariableDeclaration(VariableDeclaration node) { |
| 954 if (node == null) { | 970 if (node == null) { |
| 955 writeByte(Tag.Nothing); | 971 writeByte(Tag.Nothing); |
| 956 } else { | 972 } else { |
| 957 writeByte(Tag.Something); | 973 writeByte(Tag.Something); |
| 958 writeVariableDeclaration(node, false); | 974 writeVariableDeclaration(node); |
| 959 } | 975 } |
| 960 } | 976 } |
| 961 | 977 |
| 962 visitFunctionDeclaration(FunctionDeclaration node) { | 978 visitFunctionDeclaration(FunctionDeclaration node) { |
| 963 writeByte(Tag.FunctionDeclaration); | 979 writeByte(Tag.FunctionDeclaration); |
| 964 writeOffset(node.fileOffset); | 980 writeOffset(node.fileOffset); |
| 965 writeVariableDeclaration(node.variable, false); | 981 writeVariableDeclaration(node.variable); |
| 966 writeNode(node.function); | 982 writeNode(node.function); |
| 967 } | 983 } |
| 968 | 984 |
| 969 visitBottomType(BottomType node) { | 985 visitBottomType(BottomType node) { |
| 970 writeByte(Tag.BottomType); | 986 writeByte(Tag.BottomType); |
| 971 } | 987 } |
| 972 | 988 |
| 973 visitInvalidType(InvalidType node) { | 989 visitInvalidType(InvalidType node) { |
| 974 writeByte(Tag.InvalidType); | 990 writeByte(Tag.InvalidType); |
| 975 } | 991 } |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 _sink.add(_buffer.sublist(0, length)); | 1397 _sink.add(_buffer.sublist(0, length)); |
| 1382 _buffer = new Uint8List(SIZE); | 1398 _buffer = new Uint8List(SIZE); |
| 1383 flushedLength += length; | 1399 flushedLength += length; |
| 1384 length = 0; | 1400 length = 0; |
| 1385 } | 1401 } |
| 1386 | 1402 |
| 1387 void flushAndDestroy() { | 1403 void flushAndDestroy() { |
| 1388 _sink.add(_buffer.sublist(0, length)); | 1404 _sink.add(_buffer.sublist(0, length)); |
| 1389 } | 1405 } |
| 1390 } | 1406 } |
| OLD | NEW |