| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 library kernel.binary.loader; | |
| 5 | |
| 6 import '../repository.dart'; | |
| 7 import '../ast.dart'; | |
| 8 import 'tag.dart'; | |
| 9 import 'dart:io'; | |
| 10 import 'ast_from_binary.dart'; | |
| 11 | |
| 12 abstract class BinaryReferenceLoader { | |
| 13 Library getLibraryReference(Library from, String relativePath); | |
| 14 Class getClassReference(Library library, int tag, int index); | |
| 15 Member getMemberReference(TreeNode classOrLibrary, int tag, int index); | |
| 16 Member getLibraryMemberReference(Library library, int tag, int index); | |
| 17 Member getClassMemberReference(Class classNode, int tag, int index); | |
| 18 } | |
| 19 | |
| 20 class BinaryLoader implements BinaryReferenceLoader { | |
| 21 final Repository repository; | |
| 22 | |
| 23 BinaryLoader(this.repository); | |
| 24 | |
| 25 Library getLibraryReference(Library from, String relativePath) { | |
| 26 var fullUri = from.importUri.resolve(relativePath); | |
| 27 return repository.getLibraryReference(fullUri); | |
| 28 } | |
| 29 | |
| 30 static int _pow2roundup(int x) { | |
| 31 --x; | |
| 32 x |= x >> 1; | |
| 33 x |= x >> 2; | |
| 34 x |= x >> 4; | |
| 35 x |= x >> 8; | |
| 36 x |= x >> 16; | |
| 37 return x + 1; | |
| 38 } | |
| 39 | |
| 40 TreeNode _extendList( | |
| 41 TreeNode parent, List<TreeNode> items, int index, TreeNode build()) { | |
| 42 if (items.length <= index) { | |
| 43 // Avoid excessive resizing by growing the list in steps. | |
| 44 items.length = _pow2roundup(index + 1); | |
| 45 } | |
| 46 return items[index] ??= build()..parent = parent; | |
| 47 } | |
| 48 | |
| 49 Class getClassReference(Library library, int tag, int index) { | |
| 50 return _extendList( | |
| 51 library, library.classes, index, () => _buildClassReference(tag)); | |
| 52 } | |
| 53 | |
| 54 Class _buildClassReference(int tag) { | |
| 55 return new Class(); | |
| 56 } | |
| 57 | |
| 58 Field _buildFieldReference() { | |
| 59 return new Field(null); | |
| 60 } | |
| 61 | |
| 62 Constructor _buildConstructorReference() { | |
| 63 return new Constructor(null); | |
| 64 } | |
| 65 | |
| 66 Procedure _buildProcedureReference() { | |
| 67 return new Procedure(null, null, null); | |
| 68 } | |
| 69 | |
| 70 Member getMemberReference(TreeNode classOrLibrary, int tag, int index) { | |
| 71 if (classOrLibrary is Class) { | |
| 72 return getClassMemberReference(classOrLibrary, tag, index); | |
| 73 } else { | |
| 74 return getLibraryMemberReference(classOrLibrary, tag, index); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 Member getLibraryMemberReference(Library library, int tag, int index) { | |
| 79 switch (tag) { | |
| 80 case Tag.LibraryFieldReference: | |
| 81 case Tag.Field: | |
| 82 return _extendList( | |
| 83 library, library.fields, index, _buildFieldReference); | |
| 84 case Tag.LibraryProcedureReference: | |
| 85 case Tag.Procedure: | |
| 86 return _extendList( | |
| 87 library, library.procedures, index, _buildProcedureReference); | |
| 88 default: | |
| 89 throw 'Invalid library member reference tag: $tag'; | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 Member getClassMemberReference(Class classNode, int tag, int index) { | |
| 94 switch (tag) { | |
| 95 case Tag.ClassFieldReference: | |
| 96 case Tag.Field: | |
| 97 return _extendList( | |
| 98 classNode, classNode.fields, index, _buildFieldReference); | |
| 99 case Tag.ClassConstructorReference: | |
| 100 case Tag.Constructor: | |
| 101 return _extendList(classNode, classNode.constructors, index, | |
| 102 _buildConstructorReference); | |
| 103 case Tag.ClassProcedureReference: | |
| 104 case Tag.Procedure: | |
| 105 return _extendList( | |
| 106 classNode, classNode.procedures, index, _buildProcedureReference); | |
| 107 default: | |
| 108 throw 'Invalid library member reference tag: $tag'; | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 Program loadProgram(String filename) { | |
| 113 var bytes = new File(filename).readAsBytesSync(); | |
| 114 return new BinaryBuilder(this, bytes, filename).readProgramFile(); | |
| 115 } | |
| 116 } | |
| OLD | NEW |