IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
AssemblyReader.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Collections.Generic;
26using System.IO;
27
29
31{
32
33 sealed class AssemblyReader : Assembly
34 {
35
36 const int ContainsNoMetaData = 0x0001;
37
38 readonly string location;
39 readonly ModuleReader manifestModule;
40 readonly Module[] externalModules;
41
47 internal AssemblyReader(string location, ModuleReader manifestModule) :
48 base(manifestModule.Universe)
49 {
50 this.location = location;
51 this.manifestModule = manifestModule;
52 externalModules = new Module[manifestModule.FileTable.records.Length];
53 }
54
55 public override string Location
56 {
57 get { return location ?? ""; }
58 }
59
60 public override AssemblyName GetName()
61 {
62 return GetNameImpl(ref manifestModule.AssemblyTable.records[0]);
63 }
64
65 AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
66 {
67 var name = new AssemblyName();
68 name.Name = manifestModule.GetString(rec.Name);
69 name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
70 name.SetPublicKey(rec.PublicKey.IsNil == false ? manifestModule.GetBlobCopy(rec.PublicKey) : Array.Empty<byte>());
71 name.CultureName = rec.Culture.IsNil == false ? manifestModule.GetString(rec.Culture) : "";
72 name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
73 name.CodeBase = CodeBase;
74
75 manifestModule.GetPEKind(out var peKind, out var machine);
76
77 switch (machine)
78 {
79 case ImageFileMachine.I386:
80 // FXBUG we copy the .NET bug that Preferred32Bit implies x86
81 if ((peKind & (PortableExecutableKinds.Required32Bit | PortableExecutableKinds.Preferred32Bit)) != 0)
82 name.ProcessorArchitecture = ProcessorArchitecture.X86;
83 else if ((rec.Flags & 0x70) == 0x70)
84 name.ProcessorArchitecture = ProcessorArchitecture.None; // it's a reference assembly
85 else
86 name.ProcessorArchitecture = ProcessorArchitecture.MSIL;
87 break;
88 case ImageFileMachine.IA64:
89 name.ProcessorArchitecture = ProcessorArchitecture.IA64;
90 break;
91 case ImageFileMachine.AMD64:
92 name.ProcessorArchitecture = ProcessorArchitecture.Amd64;
93 break;
94 case ImageFileMachine.ARM:
95 name.ProcessorArchitecture = ProcessorArchitecture.Arm;
96 break;
97 case ImageFileMachine.ARM64:
98 name.ProcessorArchitecture = ProcessorArchitecture.Arm64;
99 break;
100 }
101
102 name.RawFlags = (AssemblyNameFlags)rec.Flags;
103 return name;
104 }
105
106 public override Type[] GetTypes()
107 {
108 if (externalModules.Length == 0)
109 return manifestModule.GetTypes();
110
111 var list = new List<Type>();
112 foreach (var module in GetModules(false))
113 list.AddRange(module.GetTypes());
114
115 return list.ToArray();
116 }
117
118 internal override Type FindType(TypeName typeName)
119 {
120 var type = manifestModule.FindType(typeName);
121 for (int i = 0; type == null && i < externalModules.Length; i++)
122 if ((manifestModule.FileTable.records[i].Flags & ContainsNoMetaData) == 0)
123 type = GetModule(i).FindType(typeName);
124
125 return type;
126 }
127
128 internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
129 {
130 var type = manifestModule.FindTypeIgnoreCase(lowerCaseName);
131 for (int i = 0; type == null && i < externalModules.Length; i++)
132 if ((manifestModule.FileTable.records[i].Flags & ContainsNoMetaData) == 0)
133 type = GetModule(i).FindTypeIgnoreCase(lowerCaseName);
134
135 return type;
136 }
137
138 public override string ImageRuntimeVersion
139 {
140 get { return manifestModule.__ImageRuntimeVersion; }
141 }
142
143 public override Module ManifestModule
144 {
145 get { return manifestModule; }
146 }
147
148 public override Module[] GetLoadedModules(bool getResourceModules)
149 {
150 List<Module> list = new List<Module>();
151 list.Add(manifestModule);
152 foreach (Module m in externalModules)
153 {
154 if (m != null)
155 {
156 list.Add(m);
157 }
158 }
159 return list.ToArray();
160 }
161
162 public override Module[] GetModules(bool getResourceModules)
163 {
164 if (externalModules.Length == 0)
165 {
166 return new Module[] { manifestModule };
167 }
168 else
169 {
170 List<Module> list = new List<Module>();
171 list.Add(manifestModule);
172 for (int i = 0; i < manifestModule.FileTable.records.Length; i++)
173 {
174 if (getResourceModules || (manifestModule.FileTable.records[i].Flags & ContainsNoMetaData) == 0)
175 {
176 list.Add(GetModule(i));
177 }
178 }
179 return list.ToArray();
180 }
181 }
182
183 public override Module GetModule(string name)
184 {
185 if (name.Equals(manifestModule.ScopeName, StringComparison.OrdinalIgnoreCase))
186 return manifestModule;
187
188 var index = GetModuleIndex(name);
189 if (index != -1)
190 return GetModule(index);
191
192 return null;
193 }
194
195 int GetModuleIndex(string name)
196 {
197 for (int i = 0; i < manifestModule.FileTable.records.Length; i++)
198 if (name.Equals(manifestModule.GetString(manifestModule.FileTable.records[i].Name), StringComparison.OrdinalIgnoreCase))
199 return i;
200
201 return -1;
202 }
203
204 Module GetModule(int index)
205 {
206 if (externalModules[index] != null)
207 return externalModules[index];
208
209 return LoadModule(index, null, manifestModule.GetString(manifestModule.FileTable.records[index].Name));
210 }
211
212 private Module LoadModule(int index, byte[] rawModule, string name)
213 {
214 var location = name == null ? null : Path.Combine(Path.GetDirectoryName(this.location), name);
215 if ((manifestModule.FileTable.records[index].Flags & ContainsNoMetaData) != 0)
216 {
217 return externalModules[index] = new ResourceModule(manifestModule, index, location);
218 }
219 else
220 {
221 if (rawModule == null)
222 {
223 try
224 {
225 rawModule = File.ReadAllBytes(location);
226 }
227 catch (FileNotFoundException)
228 {
229 if (resolvers != null)
230 {
231 var arg = new ResolveEventArgs(name, this);
232 foreach (var resolver in resolvers)
233 {
234 var module = resolver(this, arg);
235 if (module != null)
236 return module;
237 }
238 }
239
240 if (Universe.MissingMemberResolution)
241 return externalModules[index] = new MissingModule(this, index);
242
243 throw;
244 }
245 }
246 return externalModules[index] = new ModuleReader(this, manifestModule.Universe, new MemoryStream(rawModule), location, false);
247 }
248 }
249
250 public override Module LoadModule(string moduleName, byte[] rawModule)
251 {
252 int index = GetModuleIndex(moduleName);
253 if (index == -1)
254 throw new ArgumentException();
255
256 if (externalModules[index] != null)
257 return externalModules[index];
258
259 return LoadModule(index, rawModule, null);
260 }
261
262 public override MethodInfo EntryPoint
263 {
264 get { return manifestModule.GetEntryPoint(); }
265 }
266
267 public override string[] GetManifestResourceNames()
268 {
269 return manifestModule.GetManifestResourceNames();
270 }
271
272 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
273 {
274 return manifestModule.GetManifestResourceInfo(resourceName);
275 }
276
277 public override Stream GetManifestResourceStream(string resourceName)
278 {
279 return manifestModule.GetManifestResourceStream(resourceName);
280 }
281
282 public override AssemblyName[] GetReferencedAssemblies()
283 {
284 return manifestModule.__GetReferencedAssemblies();
285 }
286
287 protected override AssemblyNameFlags GetAssemblyFlags()
288 {
289 return (AssemblyNameFlags)manifestModule.AssemblyTable.records[0].Flags;
290 }
291
292 internal string Name
293 {
294 get { return manifestModule.GetString(manifestModule.AssemblyTable.records[0].Name); }
295 }
296
297 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
298 {
299 return CustomAttributeData.GetCustomAttributesImpl(null, manifestModule, 0x20000001, attributeType) ?? CustomAttributeData.EmptyList;
300 }
301 }
302
303}
IKVM.Reflection.Module Module
IKVM.Reflection.Type Type
IKVM.Reflection.AssemblyName AssemblyName
global::java.lang.invoke.LambdaForm.Name Name
override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
override Module[] GetModules(bool getResourceModules)
override Module LoadModule(string moduleName, byte[] rawModule)
override AssemblyName[] GetReferencedAssemblies()
override Stream GetManifestResourceStream(string resourceName)
override Module GetModule(string name)
override Module[] GetLoadedModules(bool getResourceModules)
override AssemblyNameFlags GetAssemblyFlags()