protected Type LoadClass(Type baseType, Type interfaceType, Type[] additionalInterfaceTypes) { String className = interfaceType.FullName + "$" + baseType.Name + "$" + Arrays.GetHashCode(additionalInterfaceTypes); if (className.StartsWith("java.")) { className = "ambeth." + className; } lock (writeLock) { AccessorClassLoader loader = AccessorClassLoader.Get(interfaceType); Type type = loader.LoadClass(className); if (type != null) { return(type); } return(CreateGpType(loader, interfaceType, additionalInterfaceTypes, className)); } }
protected Type CreateGpType(AccessorClassLoader loader, Type proxyType, Type[] additionalProxyTypes, String className) { String classNameInternal = className.Replace('.', '/'); Type abstractType = typeof(GCProxy); List <Type> interfaceClasses = new List <Type>(); interfaceClasses.Add(proxyType); foreach (Type additionalProxyType in additionalProxyTypes) { interfaceClasses.Add(additionalProxyType); } TypeBuilder cw = loader.CreateNewType(TypeAttributes.Public, classNameInternal, abstractType, Type.EmptyTypes); { ConstructorInfo baseConstructor = abstractType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Object), typeof(IDisposable) }, null); if (baseConstructor == null) { throw new Exception("Constructor not found: " + abstractType.FullName); } ILGenerator mv = cw.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, TypeUtil.GetParameterTypesToTypes(baseConstructor.GetParameters())).GetILGenerator(); mv.Emit(OpCodes.Ldarg_0); mv.Emit(OpCodes.Ldarg_1); mv.Emit(OpCodes.Ldarg_2); mv.Emit(OpCodes.Call, baseConstructor); mv.Emit(OpCodes.Ret); } { ConstructorInfo baseConstructor = abstractType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(IDisposable) }, null); if (baseConstructor == null) { throw new Exception("Constructor not found: " + abstractType.FullName); } ILGenerator mv = cw.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, TypeUtil.GetParameterTypesToTypes(baseConstructor.GetParameters())).GetILGenerator(); mv.Emit(OpCodes.Ldarg_0); mv.Emit(OpCodes.Ldarg_1); mv.Emit(OpCodes.Call, baseConstructor); mv.Emit(OpCodes.Ret); } MethodInfo targetMethod = ReflectUtil.GetDeclaredMethod(false, typeof(GCProxy), typeof(Object), "ResolveTarget"); CHashSet <MethodInfo> alreadyImplementedMethods = new CHashSet <MethodInfo>(); foreach (Type interfaceClass in interfaceClasses) { MethodInfo[] methods = interfaceClass.GetMethods(); foreach (MethodInfo method in methods) { if (GCProxy.disposeMethod.Equals(method)) { // will remain implemented by the GCProxy class continue; } if (!alreadyImplementedMethods.Add(method)) { continue; } MethodAttributes attributes = 0; Type[] paramTypes = TypeUtil.GetParameterTypesToTypes(method.GetParameters()); ILGenerator mv = cw.DefineMethod(method.Name, attributes, CallingConventions.HasThis, method.ReturnType, paramTypes).GetILGenerator(); mv.Emit(OpCodes.Ldarg_0); mv.Emit(OpCodes.Callvirt, targetMethod); mv.Emit(OpCodes.Castclass, method.DeclaringType); for (int a = 0, size = paramTypes.Length; a < size; a++) { mv.Emit(OpCodes.Ldarg, a + 1); } mv.Emit(OpCodes.Callvirt, method); mv.Emit(OpCodes.Ret); } } return(loader.GetType(classNameInternal, cw)); }