Added (optional) per-module initialization to custom assembly class loaders.

This commit is contained in:
jfrijters 2009-11-03 07:15:37 +00:00
Родитель 1f255d4f65
Коммит f6acb0a796
2 изменённых файлов: 29 добавлений и 0 удалений

Просмотреть файл

@ -3054,6 +3054,19 @@ namespace IKVM.Internal
}
ConstructorInfo ci = JVM.LoadType(typeof(CustomAssemblyClassLoaderAttribute)).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { Types.Type }, null);
assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(ci, new object[] { wrapper.TypeAsTBD }));
// TODO it would be better to do this for all assemblies in a shared class loader group (because options.classloader is relevant only for the main assembly),
// but since it is probably common to specify the custom assembly class loader at the group level, it hopefully won't make much difference in practice.
MethodWrapper mwModuleInit = wrapper.GetMethodWrapper("InitializeModule", "(Lcli.System.Reflection.Module;)V", false);
if(mwModuleInit != null && !mwModuleInit.IsStatic)
{
MethodBuilder moduleInitializer = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod(".cctor", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, null, Type.EmptyTypes);
ILGenerator ilgen = moduleInitializer.GetILGenerator();
ilgen.Emit(OpCodes.Ldtoken, moduleInitializer);
ilgen.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetMethodFromHandle", new Type[] { typeof(RuntimeMethodHandle) }));
ilgen.Emit(OpCodes.Callvirt, typeof(MemberInfo).GetMethod("get_Module"));
ilgen.Emit(OpCodes.Call, StaticCompiler.GetRuntimeType("IKVM.Runtime.ByteCodeHelper").GetMethod("InitializeModule"));
ilgen.Emit(OpCodes.Ret);
}
}
assemblyBuilder.DefineVersionInfoResource();
return 0;

Просмотреть файл

@ -769,6 +769,22 @@ namespace IKVM.Runtime
{
Interlocked.Exchange(ref v, newValue);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public static void InitializeModule(Module module)
{
Assembly asm = Assembly.GetCallingAssembly();
if (module.Assembly != asm)
{
throw new ArgumentOutOfRangeException();
}
object classLoader = AssemblyClassLoader.FromAssembly(asm).GetJavaClassLoader();
Action<Module> init = (Action<Module>)Delegate.CreateDelegate(typeof(Action<Module>), classLoader, "InitializeModule", false, false);
if (init != null)
{
init(module);
}
}
}
[StructLayout(LayoutKind.Explicit)]