25using System.Collections.Generic;
26using System.Runtime.Serialization;
30using static
System.Diagnostics.DebuggableAttribute;
40using System.Reflection;
41using System.Reflection.Emit;
52 internal sealed class DynamicClassLoader : RuntimeJavaTypeFactory
56 static AssemblyBuilder jniProxyAssemblyBuilder;
59 readonly RuntimeContext context;
61 readonly ModuleBuilder moduleBuilder;
62 readonly
bool hasInternalAccess;
65 TypeBuilder proxiesContainer;
66 List<TypeBuilder> proxies;
69 Dictionary<string, TypeBuilder> unloadables;
70 TypeBuilder unloadableContainer;
80 internal DynamicClassLoader(RuntimeContext context,
IDiagnosticHandler diagnostics, ModuleBuilder moduleBuilder,
bool hasInternalAccess)
82 this.context = context ??
throw new ArgumentNullException(nameof(context));
83 this.diagnostics = diagnostics ??
throw new ArgumentNullException(nameof(diagnostics));
84 this.moduleBuilder = moduleBuilder;
85 this.hasInternalAccess = hasInternalAccess;
93 internal override bool ReserveName(
string name)
95 return context.DynamicClassLoaderFactory.ReserveName(name);
103 internal override string AllocMangledName(RuntimeByteCodeJavaType javaType)
105 return DynamicClassLoaderFactory.TypeNameMangleImpl(context.DynamicClassLoaderFactory.dynamicTypes, javaType.Name, javaType);
108 internal sealed override RuntimeJavaType DefineClassImpl(Dictionary<string, RuntimeJavaType> types, RuntimeJavaType host, ClassFile f, RuntimeClassLoader classLoader,
ProtectionDomain protectionDomain)
113 types[f.Name] = type;
119 var type =
new RuntimeByteCodeJavaType(host, f, classLoader, protectionDomain);
128 TieClassAndWrapper(type, protectionDomain);
137 RuntimeJavaType race;
138 types.TryGetValue(f.Name, out race);
141 types[f.Name] = type;
142 TieClassAndWrapper(type, protectionDomain);
146 throw new LinkageError(
"duplicate class definition: " + f.Name);
154#if !IMPORTER && !FIRST_PASS
156 private static java.lang.Class TieClassAndWrapper(RuntimeJavaType type,
ProtectionDomain protectionDomain)
159 clazz.typeWrapper = type;
160 clazz.pd = protectionDomain;
161 type.SetClassObject(clazz);
169 internal TypeBuilder DefineProxy(
string name, TypeAttributes typeAttributes,
Type parent,
Type[] interfaces)
171 if (proxiesContainer ==
null)
173 proxiesContainer = moduleBuilder.DefineType(TypeNameUtil.ProxiesContainer, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract);
174 context.AttributeHelper.HideFromJava(proxiesContainer);
175 context.AttributeHelper.SetEditorBrowsableNever(proxiesContainer);
176 proxies =
new List<TypeBuilder>();
178 TypeBuilder tb = proxiesContainer.DefineNestedType(name, typeAttributes, parent, interfaces);
185 internal override Type DefineUnloadable(
string name)
189 if (unloadables ==
null)
191 unloadables =
new Dictionary<string, TypeBuilder>();
194 if (unloadables.TryGetValue(name, out type))
198 if (unloadableContainer ==
null)
200 unloadableContainer = moduleBuilder.DefineType(RuntimeUnloadableJavaType.ContainerTypeName, TypeAttributes.Interface | TypeAttributes.Abstract);
201 context.AttributeHelper.HideFromJava(unloadableContainer);
203 type = unloadableContainer.DefineNestedType(TypeNameUtil.MangleNestedTypeName(name), TypeAttributes.NestedPrivate | TypeAttributes.Interface | TypeAttributes.Abstract);
204 unloadables.Add(name, type);
209 internal override Type DefineDelegate(
int parameterCount,
bool returnVoid)
213 if (delegates ==
null)
215 delegates =
new Type[512];
217 int index = parameterCount + (returnVoid ? 256 : 0);
218 Type type = delegates[index];
223 TypeBuilder tb = moduleBuilder.DefineType(returnVoid ?
"__<>NVIV`" + parameterCount :
"__<>NVI`" + (parameterCount + 1), TypeAttributes.NotPublic | TypeAttributes.Sealed, context.Types.MulticastDelegate);
224 string[] names =
new string[parameterCount + (returnVoid ? 0 : 1)];
225 for (
int i = 0; i < names.Length; i++)
231 names[names.Length - 1] =
"R";
233 Type[] genericParameters = tb.DefineGenericParameters(names);
234 Type[] parameterTypes = genericParameters;
237 parameterTypes =
new Type[genericParameters.Length - 1];
238 Array.Copy(genericParameters, parameterTypes, parameterTypes.Length);
240 tb.DefineMethod(
ConstructorInfo.ConstructorName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, context.Types.Void,
new Type[] { context.Types.Object, context.Types.IntPtr })
241 .SetImplementationFlags(MethodImplAttributes.Runtime);
242 MethodBuilder mb = tb.DefineMethod(
"Invoke", MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual, returnVoid ? context.Types.Void : genericParameters[genericParameters.Length - 1], parameterTypes);
243 mb.SetImplementationFlags(MethodImplAttributes.Runtime);
244 type = tb.CreateType();
245 delegates[index] = type;
250 internal override bool HasInternalAccess
252 get {
return hasInternalAccess; }
255 internal void FinishAll()
257 var done =
new Dictionary<RuntimeJavaType, RuntimeJavaType>();
263 var l = context.DynamicClassLoaderFactory.dynamicTypes.ToArray();
267 if (tw !=
null && !done.ContainsKey(tw))
271 diagnostics.GenericRuntimeTrace($
"Finishing: {tw.TypeAsTBD.FullName}");
277 if (unloadableContainer !=
null)
279 unloadableContainer.CreateType();
280 foreach (var tb
in unloadables.Values)
285 if (proxiesContainer !=
null)
287 proxiesContainer.CreateType();
288 foreach (var tb
in proxies)
298 internal static ModuleBuilder CreateJniProxyModuleBuilder()
301 name.Name =
"jniproxy";
302 jniProxyAssemblyBuilder = DefineDynamicAssembly(name, AssemblyBuilderAccess.Run,
null);
303 return jniProxyAssemblyBuilder.DefineDynamicModule(
"jniproxy.dll");
308 internal sealed override ModuleBuilder ModuleBuilder => moduleBuilder;
314 internal sealed class ForgedKeyPair : StrongNameKeyPair
317 internal static readonly StrongNameKeyPair Instance;
319 static ForgedKeyPair()
324 Instance =
new ForgedKeyPair(
new byte[] {
325 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00,
326 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53,
327 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x9D,
328 0x67, 0x4F, 0x3D, 0x63, 0xB8, 0xD7, 0xA4, 0xC4, 0x28, 0xBD, 0x73,
329 0x88, 0x34, 0x1B, 0x02, 0x5C, 0x71, 0xAA, 0x61, 0xC6, 0x22, 0x4C,
330 0xD5, 0x3A, 0x12, 0xC2, 0x13, 0x30, 0xA3, 0x15, 0x9D, 0x30, 0x00,
331 0x51, 0xFE, 0x2E, 0xED, 0x15, 0x4F, 0xE3, 0x0D, 0x70, 0x67, 0x3A,
332 0x07, 0x9E, 0x45, 0x29, 0xD0, 0xFD, 0x78, 0x11, 0x3D, 0xCA, 0x77,
333 0x1D, 0xA8, 0xB0, 0xC1, 0xEF, 0x2F, 0x77, 0xB7, 0x36, 0x51, 0xD5,
334 0x56, 0x45, 0xB0, 0xA4, 0x29, 0x4F, 0x0A, 0xF9, 0xBF, 0x70, 0x78,
335 0x43, 0x2E, 0x13, 0xD0, 0xF4, 0x6F, 0x95, 0x1D, 0x71, 0x2C, 0x2F,
336 0xCF, 0x02, 0xEB, 0x15, 0x55, 0x2C, 0x0F, 0xE7, 0x81, 0x7F, 0xC0,
337 0xAE, 0xD5, 0x8E, 0x09, 0x84, 0xF8, 0x66, 0x61, 0xBF, 0x64, 0xD8,
338 0x82, 0xF2, 0x9B, 0x61, 0x98, 0x99, 0xDD, 0x26, 0x40, 0x41, 0xE7,
339 0xD4, 0x99, 0x25, 0x48, 0xEB, 0x9E
352 private ForgedKeyPair(
byte[] publicKey) :
353 base(ToInfo(publicKey),
new StreamingContext())
358 private static SerializationInfo ToInfo(
byte[] publicKey)
360 byte[] privateKey = publicKey;
361 SerializationInfo info =
new SerializationInfo(typeof(StrongNameKeyPair),
new FormatterConverter());
362 info.AddValue(
"_keyPairExported",
true);
363 info.AddValue(
"_keyPairArray", privateKey);
364 info.AddValue(
"_keyPairContainer",
null);
365 info.AddValue(
"_publicKey", publicKey);
372 public static ModuleBuilder CreateModuleBuilder(RuntimeContext context)
375 name.Name =
"ikvm_dynamic_assembly__" + (uint)Environment.TickCount;
376 return CreateModuleBuilder(context, name);
379 public static ModuleBuilder CreateModuleBuilder(RuntimeContext context,
AssemblyName name)
381 var now = DateTime.Now;
382 name.Version =
new Version(now.Year, (now.Month * 100) + now.Day, (now.Hour * 100) + now.Minute, (now.Second * 1000) + now.Millisecond);
383 var attribs =
new List<CustomAttributeBuilder>();
384 AssemblyBuilderAccess access = AssemblyBuilderAccess.Run;
387 if (!AppDomain.CurrentDomain.IsFullyTrusted)
388 attribs.Add(
new CustomAttributeBuilder(typeof(
System.Security.SecurityTransparentAttribute).GetConstructor(
Type.EmptyTypes),
new object[0]));
391 var assemblyBuilder = DefineDynamicAssembly(name, access, attribs);
392 context.AttributeHelper.SetRuntimeCompatibilityAttribute(assemblyBuilder);
395 var debugMode = DebuggingModes.Default | DebuggingModes.IgnoreSymbolStoreSequencePoints;
397 debugMode |= DebuggingModes.DisableOptimizations;
399 context.AttributeHelper.SetDebuggingModes(assemblyBuilder, debugMode);
402 var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name, JVM.EmitSymbols);
404 var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name);
408 return moduleBuilder;
411 static AssemblyBuilder DefineDynamicAssembly(
AssemblyName name, AssemblyBuilderAccess access, IEnumerable<CustomAttributeBuilder> assemblyAttributes)
414 return AppDomain.CurrentDomain.DefineDynamicAssembly(name, access,
null,
true, assemblyAttributes);
416 return AssemblyBuilder.DefineDynamicAssembly(name, access, assemblyAttributes);
java.security.ProtectionDomain ProtectionDomain
IKVM.Reflection.Type Type
IKVM.Reflection.AssemblyName AssemblyName
IKVM.Reflection.ConstructorInfo ConstructorInfo
Exposes methods to accept diagnostic invocations.