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 |