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 |