Inheritance: ClassLoaderWrapper
		private static void EmitClassLiteral(CompilerClassLoader ccl)
		{
			TypeBuilder tb = ccl.GetTypeWrapperFactory().ModuleBuilder.DefineType("ikvm.internal.ClassLiteral`1", TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
			GenericTypeParameterBuilder typeParam = tb.DefineGenericParameters("T")[0];
			Type classType = CoreClasses.java.lang.Class.Wrapper.TypeAsSignatureType;
			classLiteralField = tb.DefineField("Value", classType, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly);
			CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb));
			ilgen.Emit(OpCodes.Ldtoken, typeParam);
			ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle", new Type[] { Types.RuntimeTypeHandle }));
			MethodWrapper mw = CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("<init>", "(Lcli.System.Type;)V", false);
			mw.Link();
			mw.EmitNewobj(ilgen);
			ilgen.Emit(OpCodes.Stsfld, classLiteralField);
			ilgen.Emit(OpCodes.Ret);
			ilgen.DoEmit();
			classLiteralType = tb.CreateType();
		}
Ejemplo n.º 2
0
		internal static void Create(CompilerClassLoader loader, string proxy)
		{
			string[] interfaces = proxy.Split(',');
			TypeWrapper[] wrappers = new TypeWrapper[interfaces.Length];
			for (int i = 0; i < interfaces.Length; i++)
			{
				try
				{
					wrappers[i] = loader.LoadClassByDottedNameFast(interfaces[i]);
				}
				catch (RetargetableJavaException)
				{
				}
				if (wrappers[i] == null)
				{
					StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, "unable to load interface " + interfaces[i]);
					return;
				}
			}
			Create(loader, proxy, wrappers);
		}
		internal void AddReference(CompilerClassLoader ccl)
		{
			peerReferences.Add(ccl);
		}
		internal static void Create(CompilerClassLoader ccl)
		{
			EmitClassLiteral(ccl);
		}
Ejemplo n.º 5
0
 internal AotTypeWrapper(ClassFile f, CompilerClassLoader loader)
     : base(f, loader, null)
 {
 }
Ejemplo n.º 6
0
		private void AddInternalsVisibleToAttribute(CompilerClassLoader ccl)
		{
			internalsVisibleTo.Add(ccl);
			AssemblyBuilder asm = ccl.assemblyBuilder;
			AssemblyName asmName = asm.GetName();
			string name = asmName.Name;
			byte[] pubkey = asmName.GetPublicKey();
			if (pubkey == null && asmName.KeyPair != null)
			{
				pubkey = asmName.KeyPair.PublicKey;
			}
			if (pubkey != null && pubkey.Length != 0)
			{
				StringBuilder sb = new StringBuilder(name);
				sb.Append(", PublicKey=");
				foreach (byte b in pubkey)
				{
					sb.AppendFormat("{0:X2}", b);
				}
				name = sb.ToString();
			}
			AttributeHelper.SetInternalsVisibleToAttribute(this.assemblyBuilder, name);
		}
Ejemplo n.º 7
0
		private static void CreateStaticInitializer(TypeBuilder tb, List<ProxyMethod> methods, CompilerClassLoader loader)
		{
			CodeEmitter ilgen = CodeEmitter.Create(ReflectUtil.DefineTypeInitializer(tb, loader));
			CodeEmitterLocal callerID = ilgen.DeclareLocal([email protected]);
			TypeBuilder tbCallerID = DynamicTypeWrapper.FinishContext.EmitCreateCallerID(tb, ilgen);
			ilgen.Emit(OpCodes.Stloc, callerID);
			// HACK we shouldn't create the nested type here (the outer type must be created first)
			tbCallerID.CreateType();
			ilgen.BeginExceptionBlock();
			foreach (ProxyMethod method in methods)
			{
				method.mw.DeclaringType.EmitClassLiteral(ilgen);
				ilgen.Emit(OpCodes.Ldstr, method.mw.Name);
				TypeWrapper[] parameters = method.mw.GetParameters();
				ilgen.EmitLdc_I4(parameters.Length);
				ilgen.Emit(OpCodes.Newarr, CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType);
				for (int i = 0; i < parameters.Length; i++)
				{
					ilgen.Emit(OpCodes.Dup);
					ilgen.EmitLdc_I4(i);
					parameters[i].EmitClassLiteral(ilgen);
					ilgen.Emit(OpCodes.Stelem_Ref);
				}
				if (javaLangClass_getMethod.HasCallerID)
				{
					ilgen.Emit(OpCodes.Ldloc, callerID);
				}
				javaLangClass_getMethod.EmitCallvirt(ilgen);
				ilgen.Emit(OpCodes.Stsfld, method.fb);
			}
			CodeEmitterLabel label = ilgen.DefineLabel();
			ilgen.EmitLeave(label);
			ilgen.BeginCatchBlock(javaLangNoSuchMethodException.TypeAsExceptionType);
			javaLangThrowable_getMessage.EmitCallvirt(ilgen);
			javaLangNoClassDefFoundErrorConstructor.EmitNewobj(ilgen);
			ilgen.Emit(OpCodes.Throw);
			ilgen.EndExceptionBlock();
			ilgen.MarkLabel(label);
			ilgen.Emit(OpCodes.Ret);
			ilgen.DoEmit();
		}
		private static void AddExportMapEntry(Dictionary<string, List<string>> map, CompilerClassLoader ccl, string name)
		{
			string assemblyName = ccl.assemblyBuilder.FullName;
			List<string> list;
			if (!map.TryGetValue(assemblyName, out list))
			{
				list = new List<string>();
				map.Add(assemblyName, list);
			}
			if (list != null) // if list is null, we already have a wildcard export for this assembly
			{
				list.Add(name);
			}
		}
Ejemplo n.º 9
0
		private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> methods)
		{
			DynamicClassLoader factory = (DynamicClassLoader)loader.GetTypeWrapperFactory();
			TypeBuilder tb = factory.DefineProxy(proxyClass, interfaces);
			AttributeHelper.SetImplementsAttribute(tb, interfaces);
			CreateConstructor(tb);
			for (int i = 0; i < methods.Count; i++)
			{
				methods[i].fb = tb.DefineField("m" + i, javaLangReflectMethod.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static);
			}
			foreach (ProxyMethod method in methods)
			{
				CreateMethod(loader, tb, method);
			}
			CreateStaticInitializer(tb, methods);
		}
Ejemplo n.º 10
0
		private static void CreateMethod(CompilerClassLoader loader, TypeBuilder tb, ProxyMethod pm)
		{
			MethodBuilder mb = pm.mw.GetDefineMethodHelper().DefineMethod(loader.GetTypeWrapperFactory(), tb, pm.mw.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final);
			List<string> exceptions = new List<string>();
			foreach (TypeWrapper tw in pm.exceptions)
			{
				exceptions.Add(tw.Name);
			}
			AttributeHelper.SetThrowsAttribute(mb, exceptions.ToArray());
			CodeEmitter ilgen = CodeEmitter.Create(mb);
			ilgen.BeginExceptionBlock();
			ilgen.Emit(OpCodes.Ldarg_0);
			invocationHandlerField.EmitGet(ilgen);
			ilgen.Emit(OpCodes.Ldarg_0);
			ilgen.Emit(OpCodes.Ldsfld, pm.fb);
			TypeWrapper[] parameters = pm.mw.GetParameters();
			if (parameters.Length == 0)
			{
				ilgen.Emit(OpCodes.Ldnull);
			}
			else
			{
				ilgen.Emit_Ldc_I4(parameters.Length);
				ilgen.Emit(OpCodes.Newarr, Types.Object);
				for (int i = 0; i < parameters.Length; i++)
				{
					ilgen.Emit(OpCodes.Dup);
					ilgen.Emit_Ldc_I4(i);
					ilgen.Emit(OpCodes.Ldarg, (short)i);
					if (parameters[i].IsNonPrimitiveValueType)
					{
						parameters[i].EmitBox(ilgen);
					}
					else if (parameters[i].IsPrimitive)
					{
						Boxer.EmitBox(ilgen, parameters[i]);
					}
					ilgen.Emit(OpCodes.Stelem_Ref);
				}
			}
			invokeMethod.EmitCallvirt(ilgen);
			TypeWrapper returnType = pm.mw.ReturnType;
			CodeEmitterLocal returnValue = null;
			if (returnType != PrimitiveTypeWrapper.VOID)
			{
				returnValue = ilgen.DeclareLocal(returnType.TypeAsSignatureType);
				if (returnType.IsNonPrimitiveValueType)
				{
					returnType.EmitUnbox(ilgen);
				}
				else if (returnType.IsPrimitive)
				{
					Boxer.EmitUnbox(ilgen, returnType);
				}
				else if (returnType != CoreClasses.java.lang.Object.Wrapper)
				{
					ilgen.EmitCastclass(returnType.TypeAsSignatureType);
				}
				ilgen.Emit(OpCodes.Stloc, returnValue);
			}
			CodeEmitterLabel returnLabel = ilgen.DefineLabel();
			ilgen.Emit(OpCodes.Leave, returnLabel);
			// TODO consider using a filter here (but we would need to add filter support to CodeEmitter)
			ilgen.BeginCatchBlock(Types.Exception);
			ilgen.Emit_Ldc_I4(0);
			ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.mapException.MakeGenericMethod(Types.Exception));
			CodeEmitterLocal exception = ilgen.DeclareLocal(Types.Exception);
			ilgen.Emit(OpCodes.Stloc, exception);
			CodeEmitterLabel rethrow = ilgen.DefineLabel();
			ilgen.Emit(OpCodes.Ldloc, exception);
			errorClass.EmitInstanceOf(null, ilgen);
			ilgen.Emit(OpCodes.Brtrue, rethrow);
			ilgen.Emit(OpCodes.Ldloc, exception);
			runtimeExceptionClass.EmitInstanceOf(null, ilgen);
			ilgen.Emit(OpCodes.Brtrue, rethrow);
			foreach (TypeWrapper tw in pm.exceptions)
			{
				ilgen.Emit(OpCodes.Ldloc, exception);
				tw.EmitInstanceOf(null, ilgen);
				ilgen.Emit(OpCodes.Brtrue, rethrow);
			}
			ilgen.Emit(OpCodes.Ldloc, exception);
			undeclaredThrowableExceptionConstructor.EmitNewobj(ilgen);
			ilgen.Emit(OpCodes.Throw);
			ilgen.MarkLabel(rethrow);
			ilgen.Emit(OpCodes.Rethrow);
			ilgen.EndExceptionBlock();
			ilgen.MarkLabel(returnLabel);
			if (returnValue != null)
			{
				ilgen.Emit(OpCodes.Ldloc, returnValue);
			}
			ilgen.Emit(OpCodes.Ret);
			ilgen.DoEmit();
		}
Ejemplo n.º 11
0
		private static void Add(CompilerClassLoader loader, Dictionary<string, TypeWrapper[]> exceptions, MethodWrapper mw)
		{
			string signature = mw.Signature;
			TypeWrapper[] newExceptionTypes = LoadTypes(loader, mw.GetDeclaredExceptions());
			TypeWrapper[] curExceptionTypes;
			if (exceptions.TryGetValue(signature, out curExceptionTypes))
			{
				exceptions[signature] = Merge(newExceptionTypes, curExceptionTypes);
			}
			else
			{
				exceptions.Add(signature, newExceptionTypes);
			}
		}
Ejemplo n.º 12
0
		private static List<ProxyMethod> CheckAndCollect(CompilerClassLoader loader, TypeWrapper[] interfaces)
		{
			List<MethodWrapper> methods = new List<MethodWrapper>();

			// The java.lang.Object methods precede any interface methods.
			methods.Add(equalsMethod);
			methods.Add(hashCodeMethod);
			methods.Add(toStringMethod);

			// Add the interfaces methods in order.
			foreach (TypeWrapper tw in interfaces)
			{
				if (!tw.IsInterface)
				{
					throw new ProxyException(tw.Name + " is not an interface");
				}
				if (tw.IsRemapped)
				{
					// TODO handle java.lang.Comparable
					throw new ProxyException(tw.Name + " is a remapped interface (not currently supported)");
				}
				foreach (MethodWrapper mw in GetInterfaceMethods(tw))
				{
					// Check for duplicates
					if (!MethodExists(methods, mw))
					{
						methods.Add(mw);
					}
				}
			}

			// TODO verify restrictions

			// Collect declared exceptions.
			Dictionary<string, TypeWrapper[]> exceptions = new Dictionary<string, TypeWrapper[]>();
			foreach (MethodWrapper mw in methods)
			{
				Add(loader, exceptions, mw);
			}

			// Build the definitive proxy method list.
			List<ProxyMethod> proxyMethods = new List<ProxyMethod>();
			foreach (MethodWrapper mw in methods)
			{
				proxyMethods.Add(new ProxyMethod(mw, exceptions[mw.Signature]));
			}
			return proxyMethods;
		}
Ejemplo n.º 13
0
		private static int CreateCompiler(CompilerOptions options, ref CompilerClassLoader loader, ref bool compilingCoreAssembly)
		{
			Tracer.Info(Tracer.Compiler, "JVM.Compile path: {0}, assembly: {1}", options.path, options.assembly);
			AssemblyName runtimeAssemblyName = StaticCompiler.runtimeAssembly.GetName();
			bool allReferencesAreStrongNamed = IsSigned(StaticCompiler.runtimeAssembly);
			List<Assembly> references = new List<Assembly>();
			foreach(Assembly reference in options.references ?? new Assembly[0])
			{
				try
				{
					if(IsCoreAssembly(reference))
					{
						JVM.CoreAssembly = reference;
					}
					references.Add(reference);
					allReferencesAreStrongNamed &= IsSigned(reference);
					Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName);
					// if it's an IKVM compiled assembly, make sure that it was compiled
					// against same version of the runtime
					foreach(AssemblyName asmref in reference.GetReferencedAssemblies())
					{
						if(asmref.Name == runtimeAssemblyName.Name)
						{
							if(IsSigned(StaticCompiler.runtimeAssembly))
							{
								if(asmref.FullName != runtimeAssemblyName.FullName)
								{
									Console.Error.WriteLine("Error: referenced assembly {0} was compiled with an incompatible IKVM.Runtime version ({1})", reference.Location, asmref.Version);
									Console.Error.WriteLine("   Current runtime: {0}", runtimeAssemblyName.FullName);
									Console.Error.WriteLine("   Referenced assembly runtime: {0}", asmref.FullName);
									return 1;
								}
							}
							else
							{
								if(asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0)
								{
									Console.Error.WriteLine("Error: referenced assembly {0} was compiled with an incompatible (signed) IKVM.Runtime version", reference.Location);
									Console.Error.WriteLine("   Current runtime: {0}", runtimeAssemblyName.FullName);
									Console.Error.WriteLine("   Referenced assembly runtime: {0}", asmref.FullName);
									return 1;
								}
							}
						}
					}
				}
				catch(Exception x)
				{
					Console.Error.WriteLine("Error: invalid reference: {0} ({1})", reference.Location, x.Message);
					return 1;
				}
			}
			List<object> assemblyAnnotations = new List<object>();
			Dictionary<string, string> baseClasses = new Dictionary<string, string>();
			Tracer.Info(Tracer.Compiler, "Parsing class files");
			foreach(KeyValuePair<string, byte[]> kv in options.classes)
			{
				ClassFile f;
				try
				{
					byte[] buf = kv.Value;
					f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None);
					if(!f.IsInterface && f.SuperClass != null)
					{
						baseClasses[f.SuperClass] = f.SuperClass;
					}
					// NOTE the "assembly" type in the unnamed package is a magic type
					// that acts as the placeholder for assembly attributes
					if(f.Name == "assembly" && f.Annotations != null)
					{
						assemblyAnnotations.AddRange(f.Annotations);
					}
				}
				catch(ClassFormatError)
				{
					continue;
				}
				if(options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll))
				{
					foreach(ClassFile.Method m in f.Methods)
					{
						if(m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V")
						{
							StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name);
							options.mainClass = f.Name;
							break;
						}
					}
				}
			}
			Dictionary<string, byte[]> h = new Dictionary<string, byte[]>();
			// HACK remove "assembly" type that exists only as a placeholder for assembly attributes
			options.classes.Remove("assembly");
			foreach(KeyValuePair<string, byte[]> kv in options.classes)
			{
				string name = kv.Key;
				bool excluded = false;
				for(int j = 0; j < options.classesToExclude.Length; j++)
				{
					if(Regex.IsMatch(name, options.classesToExclude[j]))
					{
						excluded = true;
						break;
					}
				}
				if(h.ContainsKey(name))
				{
					StaticCompiler.IssueMessage(Message.DuplicateClassName, name);
					excluded = true;
				}
				if(!excluded)
				{
					h[name] = kv.Value;
				}
			}
			options.classes = null;

			if(options.guessFileKind && options.mainClass == null)
			{
				options.target = PEFileKinds.Dll;
			}

			if(options.target == PEFileKinds.Dll && options.mainClass != null)
			{
				Console.Error.WriteLine("Error: main class cannot be specified for library or module");
				return 1;
			}

			if(options.target != PEFileKinds.Dll && options.mainClass == null)
			{
				Console.Error.WriteLine("Error: no main method found");
				return 1;
			}

			if(options.target == PEFileKinds.Dll && options.props.Count != 0)
			{
				Console.Error.WriteLine("Error: properties cannot be specified for library or module");
				return 1;
			}

			if(options.path == null)
			{
				if(options.target == PEFileKinds.Dll)
				{
					if(options.targetIsModule)
					{
						options.path = options.assembly + ".netmodule";
					}
					else
					{
						options.path = options.assembly + ".dll";
					}
				}
				else
				{
					options.path = options.assembly + ".exe";
				}
				StaticCompiler.IssueMessage(Message.OutputFileIs, options.path);
			}

			if(options.targetIsModule)
			{
				if(options.classLoader != null)
				{
					Console.Error.WriteLine("Error: cannot specify assembly class loader for modules");
					return 1;
				}
				// TODO if we're overwriting a user specified assembly name, we need to emit a warning
				options.assembly = new FileInfo(options.path).Name;
			}

			if(options.target == PEFileKinds.Dll && !options.path.ToLower().EndsWith(".dll") && !options.targetIsModule)
			{
				Console.Error.WriteLine("Error: library output file must end with .dll");
				return 1;
			}

			if(options.target != PEFileKinds.Dll && !options.path.ToLower().EndsWith(".exe"))
			{
				Console.Error.WriteLine("Error: executable output file must end with .exe");
				return 1;
			}

			Tracer.Info(Tracer.Compiler, "Constructing compiler");
			AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count];
			for(int i = 0; i < references.Count; i++)
			{
				referencedAssemblies[i] = AssemblyClassLoader.FromAssembly(references[i]);
			}
			loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h);
			loader.baseClasses = baseClasses;
			loader.assemblyAnnotations = assemblyAnnotations;
			loader.classesToCompile = new List<string>(h.Keys);
			if(options.remapfile != null)
			{
				Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile);
				System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(IKVM.Internal.MapXml.Root));
				ser.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(ser_UnknownElement);
				ser.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(ser_UnknownAttribute);
				using(FileStream fs = File.Open(options.remapfile, FileMode.Open))
				{
					XmlTextReader rdr = new XmlTextReader(fs);
					IKVM.Internal.MapXml.Root.xmlReader = rdr;
					IKVM.Internal.MapXml.Root.filename = new FileInfo(fs.Name).Name;
					if (!loader.ValidateAndSetMap((IKVM.Internal.MapXml.Root)ser.Deserialize(rdr)))
					{
						return 1;
					}
				}
				if(loader.CheckCompilingCoreAssembly())
				{
					compilingCoreAssembly = true;
					ClassLoaderWrapper.SetBootstrapClassLoader(loader);
					loader.EmitRemappedTypes();
				}
			}
			// If we do not yet have a reference to the core assembly and we are not compiling the core assembly,
			// try to find the core assembly by looking at the assemblies that the runtime references
			if(JVM.CoreAssembly == null && !compilingCoreAssembly)
			{
				foreach(AssemblyName name in StaticCompiler.runtimeAssembly.GetReferencedAssemblies())
				{
					Assembly asm = null;
					try
					{
						asm = LoadReferencedAssembly(StaticCompiler.runtimeAssembly.Location + "/../" + name.Name + ".dll");
					}
					catch(FileNotFoundException)
					{
					}
					if(asm != null && IsCoreAssembly(asm))
					{
						JVM.CoreAssembly = asm;
						break;
					}
				}
				if(JVM.CoreAssembly == null)
				{
					Console.Error.WriteLine("Error: bootstrap classes missing and core assembly not found");
					return 1;
				}
				// we need to scan again for remapped types, now that we've loaded the core library
				ClassLoaderWrapper.LoadRemappedTypes();
			}

			if(!compilingCoreAssembly)
			{
				allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly);
				loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly));
			}

			if((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed)
			{
				Console.Error.WriteLine("Error: all referenced assemblies must be strong named, to be able to sign the output assembly");
				return 1;
			}

			if(loader.map != null)
			{
				loader.LoadMapXml();
			}

			if(!compilingCoreAssembly)
			{
				FakeTypes.Load(JVM.CoreAssembly);
			}
			return 0;
		}
		private static int CreateCompiler(CompilerOptions options, ref CompilerClassLoader loader, ref bool compilingCoreAssembly)
		{
			Tracer.Info(Tracer.Compiler, "JVM.Compile path: {0}, assembly: {1}", options.path, options.assembly);
			AssemblyName runtimeAssemblyName = StaticCompiler.runtimeAssembly.GetName();
			bool allReferencesAreStrongNamed = IsSigned(StaticCompiler.runtimeAssembly);
			List<Assembly> references = new List<Assembly>();
			foreach(Assembly reference in options.references ?? new Assembly[0])
			{
				references.Add(reference);
				allReferencesAreStrongNamed &= IsSigned(reference);
				Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName);
				// if it's an IKVM compiled assembly, make sure that it was compiled
				// against same version of the runtime
				foreach(AssemblyName asmref in reference.GetReferencedAssemblies())
				{
					if(asmref.Name == runtimeAssemblyName.Name)
					{
						if(IsSigned(StaticCompiler.runtimeAssembly))
						{
							// TODO we really should support binding redirects here to allow different revisions to be mixed
							if(asmref.FullName != runtimeAssemblyName.FullName)
							{
								throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName);
							}
						}
						else
						{
							if(asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0)
							{
								throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName);
							}
						}
					}
				}
			}
			List<object> assemblyAnnotations = new List<object>();
			Dictionary<string, string> baseClasses = new Dictionary<string, string>();
			Tracer.Info(Tracer.Compiler, "Parsing class files");
			foreach(KeyValuePair<string, ClassItem> kv in options.classes)
			{
				ClassFile f;
				try
				{
					byte[] buf = kv.Value.data;
					f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None);
					if(!f.IsInterface && f.SuperClass != null)
					{
						baseClasses[f.SuperClass] = f.SuperClass;
					}
					// NOTE the "assembly" type in the unnamed package is a magic type
					// that acts as the placeholder for assembly attributes
					if(f.Name == "assembly" && f.Annotations != null)
					{
						assemblyAnnotations.AddRange(f.Annotations);
					}
				}
				catch(ClassFormatError)
				{
					continue;
				}
				if(options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll))
				{
					foreach(ClassFile.Method m in f.Methods)
					{
						if(m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V")
						{
							StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name);
							options.mainClass = f.Name;
							break;
						}
					}
				}
			}
			Dictionary<string, ClassItem> h = new Dictionary<string, ClassItem>();
			// HACK remove "assembly" type that exists only as a placeholder for assembly attributes
			options.classes.Remove("assembly");
			foreach(KeyValuePair<string, ClassItem> kv in options.classes)
			{
				string name = kv.Key;
				bool excluded = false;
				for(int j = 0; j < options.classesToExclude.Length; j++)
				{
					if(Regex.IsMatch(name, options.classesToExclude[j]))
					{
						excluded = true;
						break;
					}
				}
				if(h.ContainsKey(name))
				{
					StaticCompiler.IssueMessage(Message.DuplicateClassName, name);
					excluded = true;
				}
				if(!excluded)
				{
					h[name] = kv.Value;
				}
			}
			options.classes = null;

			if(options.guessFileKind && options.mainClass == null)
			{
				options.target = PEFileKinds.Dll;
			}

			if(options.target == PEFileKinds.Dll && options.mainClass != null)
			{
				throw new FatalCompilerErrorException(Message.MainClassRequiresExe);
			}

			if(options.target != PEFileKinds.Dll && options.mainClass == null)
			{
				throw new FatalCompilerErrorException(Message.ExeRequiresMainClass);
			}

			if(options.target == PEFileKinds.Dll && options.props.Count != 0)
			{
				throw new FatalCompilerErrorException(Message.PropertiesRequireExe);
			}

			if(options.path == null)
			{
				if(options.target == PEFileKinds.Dll)
				{
					if(options.targetIsModule)
					{
						options.path = options.assembly + ".netmodule";
					}
					else
					{
						options.path = options.assembly + ".dll";
					}
				}
				else
				{
					options.path = options.assembly + ".exe";
				}
				StaticCompiler.IssueMessage(Message.OutputFileIs, options.path);
			}

			if(options.targetIsModule)
			{
				if(options.classLoader != null)
				{
					throw new FatalCompilerErrorException(Message.ModuleCannotHaveClassLoader);
				}
				// TODO if we're overwriting a user specified assembly name, we need to emit a warning
				options.assembly = new FileInfo(options.path).Name;
			}

			Tracer.Info(Tracer.Compiler, "Constructing compiler");
			AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count];
			for(int i = 0; i < references.Count; i++)
			{
				AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(references[i]);
				if (acl.MainAssembly != references[i])
				{
					StaticCompiler.IssueMessage(options, Message.NonPrimaryAssemblyReference, references[i].GetName().Name, acl.MainAssembly.GetName().Name);
				}
				if (Array.IndexOf(referencedAssemblies, acl) != -1)
				{
					StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName);
				}
				referencedAssemblies[i] = acl;
			}
			loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h);
			loader.baseClasses = baseClasses;
			loader.assemblyAnnotations = assemblyAnnotations;
			loader.classesToCompile = new List<string>(h.Keys);
			if(options.remapfile != null)
			{
				Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile);
				System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(IKVM.Internal.MapXml.Root));
				ser.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(ser_UnknownElement);
				ser.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(ser_UnknownAttribute);
				FileStream fs;
				try
				{
					fs = File.OpenRead(options.remapfile);
				}
				catch(Exception x)
				{
					throw new FatalCompilerErrorException(Message.ErrorReadingFile, options.remapfile, x.Message);
				}
				try
				{
					XmlTextReader rdr = new XmlTextReader(fs);
					IKVM.Internal.MapXml.Root.xmlReader = rdr;
					IKVM.Internal.MapXml.Root map;
					try
					{
						map = (IKVM.Internal.MapXml.Root)ser.Deserialize(rdr);
					}
					catch(InvalidOperationException x)
					{
						throw new FatalCompilerErrorException(Message.ErrorParsingMapFile, options.remapfile, x.Message);
					}
					if(!loader.ValidateAndSetMap(map))
					{
						return 1;
					}
				}
				finally
				{
					fs.Close();
				}
				if(loader.CheckCompilingCoreAssembly())
				{
					compilingCoreAssembly = true;
					ClassLoaderWrapper.SetBootstrapClassLoader(loader);
				}
			}
			// If we do not yet have a reference to the core assembly and we are not compiling the core assembly,
			// try to find the core assembly by looking at the assemblies that the runtime references
			if(JVM.CoreAssembly == null && !compilingCoreAssembly)
			{
				foreach(AssemblyName name in StaticCompiler.runtimeAssembly.GetReferencedAssemblies())
				{
					Assembly asm = null;
					try
					{
						asm = LoadReferencedAssembly(StaticCompiler.runtimeAssembly.Location + "/../" + name.Name + ".dll");
					}
					catch(FileNotFoundException)
					{
					}
					if(asm != null && IsCoreAssembly(asm))
					{
						JVM.CoreAssembly = asm;
						break;
					}
				}
				if(JVM.CoreAssembly == null)
				{
					throw new FatalCompilerErrorException(Message.BootstrapClassesMissing);
				}
				// we need to scan again for remapped types, now that we've loaded the core library
				ClassLoaderWrapper.LoadRemappedTypes();
			}

			if(!compilingCoreAssembly)
			{
				allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly);
				loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly));
			}

			if((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed)
			{
				throw new FatalCompilerErrorException(Message.StrongNameRequiresStrongNamedRefs);
			}

			if(loader.map != null)
			{
				loader.LoadMapXml();
			}

			if(!compilingCoreAssembly)
			{
				FakeTypes.Load(JVM.CoreAssembly);
			}
			return 0;
		}
Ejemplo n.º 15
0
		private static void Create(CompilerClassLoader loader, string proxy, TypeWrapper[] interfaces)
		{
			List<ProxyMethod> methods;
			try
			{
				methods = CheckAndCollect(loader, interfaces);
			}
			catch (RetargetableJavaException x)
			{
				StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, x.Message);
				return;
			}
			catch (ProxyException x)
			{
				StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, x.Message);
				return;
			}
			CreateNoFail(loader, interfaces, methods);
		}
		private void AddInternalsVisibleToAttribute(CompilerClassLoader ccl)
		{
			internalsVisibleTo.Add(ccl);
			AssemblyBuilder asm = ccl.assemblyBuilder;
			AssemblyName asmName = asm.GetName();
			string name = asmName.Name;
			byte[] pubkey = asmName.GetPublicKey();
			if (pubkey == null && asmName.KeyPair != null)
			{
				pubkey = asmName.KeyPair.PublicKey;
			}
			if (pubkey != null && pubkey.Length != 0)
			{
				StringBuilder sb = new StringBuilder(name);
				sb.Append(", PublicKey=");
				foreach (byte b in pubkey)
				{
					sb.AppendFormat("{0:X2}", b);
				}
				name = sb.ToString();
			}
			CustomAttributeBuilder cab = new CustomAttributeBuilder(JVM.Import(typeof(InternalsVisibleToAttribute)).GetConstructor(new Type[] { Types.String }), new object[] { name });
			this.assemblyBuilder.SetCustomAttribute(cab);
		}
Ejemplo n.º 17
0
		private static int CreateCompiler(CompilerOptions options, ref CompilerClassLoader loader, ref bool compilingCoreAssembly)
		{
			Tracer.Info(Tracer.Compiler, "JVM.Compile path: {0}, assembly: {1}", options.path, options.assembly);
			AssemblyName runtimeAssemblyName = StaticCompiler.runtimeAssembly.GetName();
			bool allReferencesAreStrongNamed = IsSigned(StaticCompiler.runtimeAssembly);
			List<Assembly> references = new List<Assembly>();
			foreach(Assembly reference in options.references ?? new Assembly[0])
			{
				references.Add(reference);
				allReferencesAreStrongNamed &= IsSigned(reference);
				Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName);
				// if it's an IKVM compiled assembly, make sure that it was compiled
				// against same version of the runtime
				foreach(AssemblyName asmref in reference.GetReferencedAssemblies())
				{
					if(asmref.Name == runtimeAssemblyName.Name)
					{
						if(IsSigned(StaticCompiler.runtimeAssembly))
						{
							// TODO we really should support binding redirects here to allow different revisions to be mixed
							if(asmref.FullName != runtimeAssemblyName.FullName)
							{
								throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName);
							}
						}
						else
						{
							if(asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0)
							{
								throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName);
							}
						}
					}
				}
			}
			Tracer.Info(Tracer.Compiler, "Parsing class files");
			// map the class names to jar entries
			Dictionary<string, Jar.Item> h = new Dictionary<string, Jar.Item>();
			List<string> classNames = new List<string>();
			foreach (Jar jar in options.jars)
			{
				if (options.IsResourcesJar(jar))
				{
					continue;
				}
				foreach (Jar.Item item in jar)
				{
					string name = item.Name;
					if (name.EndsWith(".class", StringComparison.Ordinal)
						&& name.Length > 6
						&& name.IndexOf('.') == name.Length - 6)
					{
						string className = name.Substring(0, name.Length - 6).Replace('/', '.');
						if (h.ContainsKey(className))
						{
							StaticCompiler.IssueMessage(Message.DuplicateClassName, className);
							Jar.Item itemRef = h[className];
							if ((options.classesJar != -1 && itemRef.Jar == options.jars[options.classesJar]) || jar != itemRef.Jar)
							{
								// the previous class stays, because it was either in an earlier jar or we're processing the classes.jar
								// which contains the classes loaded from the file system (where the first encountered class wins)
								continue;
							}
							else
							{
								// we have a jar that contains multiple entries with the same name, the last one wins
								h.Remove(className);
								classNames.Remove(className);
							}
						}
						h.Add(className, item);
						classNames.Add(className);
					}
				}
			}

			if (options.assemblyAttributeAnnotations == null)
			{
				// look for "assembly" type that acts as a placeholder for assembly attributes
				Jar.Item assemblyType;
				if (h.TryGetValue("assembly", out assemblyType))
				{
					try
					{
						byte[] buf = assemblyType.GetData();
						ClassFile f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None, null);
						// NOTE the "assembly" type in the unnamed package is a magic type
						// that acts as the placeholder for assembly attributes
						if (f.Name == "assembly" && f.Annotations != null)
						{
							options.assemblyAttributeAnnotations = f.Annotations;
							// HACK remove "assembly" type that exists only as a placeholder for assembly attributes
							h.Remove(f.Name);
							assemblyType.Remove();
							StaticCompiler.IssueMessage(Message.LegacyAssemblyAttributesFound);
						}
					}
					catch (ClassFormatError) { }
				}
			}

			// now look for a main method
			if (options.mainClass == null && (options.guessFileKind || options.target != PEFileKinds.Dll))
			{
				foreach (string className in classNames)
				{
					try
					{
						byte[] buf = h[className].GetData();
						ClassFile f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None, null);
						if (f.Name == className)
						{
							foreach (ClassFile.Method m in f.Methods)
							{
								if (m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V")
								{
									StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name);
									options.mainClass = f.Name;
									goto break_outer;
								}
							}
						}
					}
					catch (ClassFormatError) { }
				}
			break_outer: ;
			}

			if(options.guessFileKind && options.mainClass == null)
			{
				options.target = PEFileKinds.Dll;
			}

			if(options.target == PEFileKinds.Dll && options.mainClass != null)
			{
				throw new FatalCompilerErrorException(Message.MainClassRequiresExe);
			}

			if(options.target != PEFileKinds.Dll && options.mainClass == null)
			{
				throw new FatalCompilerErrorException(Message.ExeRequiresMainClass);
			}

			if(options.target == PEFileKinds.Dll && options.props.Count != 0)
			{
				throw new FatalCompilerErrorException(Message.PropertiesRequireExe);
			}

			if(options.path == null)
			{
				if(options.target == PEFileKinds.Dll)
				{
					if(options.targetIsModule)
					{
						options.path = IkvmcCompiler.GetFileInfo(options.assembly + ".netmodule");
					}
					else
					{
						options.path = IkvmcCompiler.GetFileInfo(options.assembly + ".dll");
					}
				}
				else
				{
					options.path = IkvmcCompiler.GetFileInfo(options.assembly + ".exe");
				}
				StaticCompiler.IssueMessage(Message.OutputFileIs, options.path.ToString());
			}

			if(options.targetIsModule)
			{
				if(options.classLoader != null)
				{
					throw new FatalCompilerErrorException(Message.ModuleCannotHaveClassLoader);
				}
				// TODO if we're overwriting a user specified assembly name, we need to emit a warning
				options.assembly = options.path.Name;
			}

			Tracer.Info(Tracer.Compiler, "Constructing compiler");
			AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count];
			for(int i = 0; i < references.Count; i++)
			{
				AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(references[i]);
				if (Array.IndexOf(referencedAssemblies, acl) != -1)
				{
					StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName);
				}
				referencedAssemblies[i] = acl;
			}
			loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.targetIsModule, options.assembly, h, compilingCoreAssembly);
			loader.classesToCompile = new List<string>(h.Keys);
			if(options.remapfile != null)
			{
				Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile);
				System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(IKVM.Internal.MapXml.Root));
				ser.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(ser_UnknownElement);
				ser.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(ser_UnknownAttribute);
				FileStream fs;
				try
				{
					fs = options.remapfile.OpenRead();
				}
				catch(Exception x)
				{
					throw new FatalCompilerErrorException(Message.ErrorReadingFile, options.remapfile, x.Message);
				}
				try
				{
					XmlTextReader rdr = new XmlTextReader(fs);
					IKVM.Internal.MapXml.Root.xmlReader = rdr;
					IKVM.Internal.MapXml.Root map;
					try
					{
						map = (IKVM.Internal.MapXml.Root)ser.Deserialize(rdr);
					}
					catch(InvalidOperationException x)
					{
						throw new FatalCompilerErrorException(Message.ErrorParsingMapFile, options.remapfile, x.Message);
					}
					if(!loader.ValidateAndSetMap(map))
					{
						return 1;
					}
				}
				finally
				{
					fs.Close();
				}
				if(loader.CheckCompilingCoreAssembly())
				{
					compilingCoreAssembly = true;
					ClassLoaderWrapper.SetBootstrapClassLoader(loader);
				}
			}
			// If we do not yet have a reference to the core assembly and we are not compiling the core assembly,
			// try to find the core assembly by looking at the assemblies that the runtime references
			if(JVM.CoreAssembly == null && !compilingCoreAssembly)
			{
				foreach(AssemblyName name in StaticCompiler.runtimeAssembly.GetReferencedAssemblies())
				{
					Assembly asm = null;
					try
					{
						asm = LoadReferencedAssembly(StaticCompiler.runtimeAssembly.Location + "/../" + name.Name + ".dll");
					}
					catch(FileNotFoundException)
					{
					}
					if(asm != null && IsCoreAssembly(asm))
					{
						AssemblyClassLoader.PreloadExportedAssemblies(asm);
						JVM.CoreAssembly = asm;
						break;
					}
				}
				if(JVM.CoreAssembly == null)
				{
					throw new FatalCompilerErrorException(Message.BootstrapClassesMissing);
				}
				// we need to scan again for remapped types, now that we've loaded the core library
				ClassLoaderWrapper.LoadRemappedTypes();
			}

			if(!compilingCoreAssembly)
			{
				allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly);
				loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly));
			}

			if((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed)
			{
				throw new FatalCompilerErrorException(Message.StrongNameRequiresStrongNamedRefs);
			}

			if(loader.map != null)
			{
				loader.LoadMapXml();
			}

			if(!compilingCoreAssembly)
			{
				FakeTypes.Load(JVM.CoreAssembly);
			}
			return 0;
		}
			internal RemapperTypeWrapper(CompilerClassLoader classLoader, IKVM.Internal.MapXml.Class c, IKVM.Internal.MapXml.Root map)
				: base((Modifiers)c.Modifiers, c.Name)
			{
				this.classLoader = classLoader;
				this.baseTypeWrapper = GetBaseWrapper(c);
				classDef = c;
				bool baseIsSealed = false;
				shadowType = StaticCompiler.Universe.GetType(c.Shadows, true);
				classLoader.SetRemappedType(shadowType, this);
				Type baseType = shadowType;
				Type baseInterface = null;
				if(baseType.IsInterface)
				{
					baseInterface = baseType;
				}
				TypeAttributes attrs = TypeAttributes.Public;
				if((c.Modifiers & IKVM.Internal.MapXml.MapModifiers.Interface) == 0)
				{
					attrs |= TypeAttributes.Class;
					if(baseType.IsSealed)
					{
						baseIsSealed = true;
						attrs |= TypeAttributes.Abstract | TypeAttributes.Sealed;
					}
				}
				else
				{
					attrs |= TypeAttributes.Interface | TypeAttributes.Abstract;
					baseType = null;
				}
				if((c.Modifiers & IKVM.Internal.MapXml.MapModifiers.Abstract) != 0)
				{
					attrs |= TypeAttributes.Abstract;
				}
				string name = c.Name.Replace('/', '.');
				typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name, attrs, baseIsSealed ? Types.Object : baseType);
				if(c.Attributes != null)
				{
					foreach(IKVM.Internal.MapXml.Attribute custattr in c.Attributes)
					{
						AttributeHelper.SetCustomAttribute(classLoader, typeBuilder, custattr);
					}
				}
				if(baseInterface != null)
				{
					typeBuilder.AddInterfaceImplementation(baseInterface);
				}
				if(classLoader.EmitStackTraceInfo)
				{
					AttributeHelper.SetSourceFile(typeBuilder, Path.GetFileName(classLoader.options.remapfile));
				}

				if(baseIsSealed)
				{
					AttributeHelper.SetModifiers(typeBuilder, (Modifiers)c.Modifiers, false);
				}

				if(c.scope == IKVM.Internal.MapXml.Scope.Public)
				{
					// FXBUG we would like to emit an attribute with a Type argument here, but that doesn't work because
					// of a bug in SetCustomAttribute that causes type arguments to be serialized incorrectly (if the type
					// is in the same assembly). Normally we use AttributeHelper.FreezeDry to get around this, but that doesn't
					// work in this case (no attribute is emitted at all). So we work around by emitting a string instead
					AttributeHelper.SetRemappedClass(classLoader.assemblyBuilder, name, shadowType);
						
					AttributeHelper.SetRemappedType(typeBuilder, shadowType);
				}

				List<MethodWrapper> methods = new List<MethodWrapper>();

				if(c.Constructors != null)
				{
					foreach(IKVM.Internal.MapXml.Constructor m in c.Constructors)
					{
						methods.Add(new RemappedConstructorWrapper(this, m));
					}
				}

				if(c.Methods != null)
				{
					foreach(IKVM.Internal.MapXml.Method m in c.Methods)
					{
						methods.Add(new RemappedMethodWrapper(this, m, map, false));
					}
				}
				// add methods from our super classes (e.g. Throwable should have Object's methods)
				if(!this.IsFinal && !this.IsInterface && this.BaseTypeWrapper != null)
				{
					foreach(MethodWrapper mw in BaseTypeWrapper.GetMethods())
					{
						RemappedMethodWrapper rmw = mw as RemappedMethodWrapper;
						if(rmw != null && (rmw.IsPublic || rmw.IsProtected))
						{
							if(!FindMethod(methods, rmw.Name, rmw.Signature))
							{
								methods.Add(new RemappedMethodWrapper(this, rmw.XmlMethod, map, true));
							}
						}
					}
				}

				SetMethods(methods.ToArray());
			}
Ejemplo n.º 19
0
		private static void CreateNoFail(CompilerClassLoader loader, TypeWrapper[] interfaces, List<ProxyMethod> methods)
		{
			bool ispublic = true;
			Type[] interfaceTypes = new Type[interfaces.Length];
			for (int i = 0; i < interfaceTypes.Length; i++)
			{
				ispublic &= interfaces[i].IsPublic;
				interfaceTypes[i] = interfaces[i].TypeAsBaseType;
			}
			TypeAttributes attr = TypeAttributes.Class | TypeAttributes.Sealed;
			attr |= ispublic ? TypeAttributes.NestedPublic : TypeAttributes.NestedAssembly;
			DynamicClassLoader factory = (DynamicClassLoader)loader.GetTypeWrapperFactory();
			TypeBuilder tb = factory.DefineProxy(TypeNameUtil.GetProxyNestedName(interfaces), attr, proxyClass.TypeAsBaseType, interfaceTypes);
			AttributeHelper.SetImplementsAttribute(tb, interfaces);
			// we apply an InnerClass attribute to avoid the CompiledTypeWrapper heuristics for figuring out the modifiers
			AttributeHelper.SetInnerClass(tb, null, ispublic ? Modifiers.Public | Modifiers.Final : Modifiers.Final);
			CreateConstructor(tb);
			for (int i = 0; i < methods.Count; i++)
			{
				methods[i].fb = tb.DefineField("m" + i, javaLangReflectMethod.TypeAsSignatureType, FieldAttributes.Private | FieldAttributes.Static);
			}
			foreach (ProxyMethod method in methods)
			{
				CreateMethod(loader, tb, method);
			}
			CreateStaticInitializer(tb, methods, loader);
		}