53 const string DEFAULT_RUNTIME_ARGS_PREFIX =
"-J";
56 Dictionary<string,
Jar.
Item> classes;
57 Dictionary<string, RemapperTypeWrapper> remapped =
new Dictionary<string, RemapperTypeWrapper>();
62 AssemblyBuilder assemblyBuilder;
63 MapXml.Attribute[] assemblyAttributes;
66 RuntimeAssemblyClassLoader[] referencedAssemblies;
67 Dictionary<string, string> nameMappings =
new Dictionary<string, string>();
69 Dictionary<string, List<RuntimeJavaType>> ghosts;
70 RuntimeJavaType[] mappedExceptions;
71 bool[] mappedExceptionsAllSubClasses;
72 Dictionary<string, MapXml.Class> mapxml_Classes;
73 Dictionary<
MethodKey, MapXml.InstructionList> mapxml_MethodBodies;
74 Dictionary<
MethodKey, MapXml.ReplaceMethodCall[]> mapxml_ReplacedMethods;
75 Dictionary<
MethodKey, MapXml.InstructionList> mapxml_MethodPrologues;
77 List<string> classesToCompile;
78 readonly List<ImportClassLoader> peerReferences =
new List<ImportClassLoader>();
79 readonly Dictionary<string, string> peerLoading =
new Dictionary<string, string>();
80 readonly List<RuntimeClassLoader> internalsVisibleTo =
new List<RuntimeClassLoader>();
81 readonly List<RuntimeJavaType> dynamicallyImportedTypes =
new List<RuntimeJavaType>();
82 readonly List<string> jarList =
new List<string>();
83 List<RuntimeJavaType> javaTypes;
100 base(context, options.codegenoptions, null)
102 this.compiler = compiler ??
throw new ArgumentNullException(nameof(compiler));
103 this.diagnostics = diagnostics ??
throw new ArgumentNullException(nameof(diagnostics));
104 this.referencedAssemblies = referencedAssemblies;
105 this.state = options;
106 this.classes = classes;
107 this.assemblyName = assemblyName;
108 this.assemblyFile = assemblyPath.Name;
109 this.assemblyDir = assemblyPath.DirectoryName;
110 this.targetIsModule = targetIsModule;
111 Diagnostics.GenericCompilerInfo($
"Instantiate CompilerClassLoader for {assemblyName}");
117 internal bool ReserveName(
string javaName)
119 return !classes.ContainsKey(javaName) && GetTypeWrapperFactory().ReserveName(javaName);
122 internal void AddNameMapping(
string javaName,
string typeName)
124 nameMappings.Add(javaName, typeName);
127 internal void AddReference(RuntimeAssemblyClassLoader acl)
129 referencedAssemblies =
ArrayUtil.Concat(referencedAssemblies, acl);
134 peerReferences.Add(ccl);
137 internal AssemblyName GetAssemblyName()
139 return assemblyBuilder.GetName();
142 private static PermissionSet Combine(PermissionSet p1, PermissionSet p2)
155 internal ModuleBuilder CreateModuleBuilder()
158 name.Name = assemblyName;
159 if (state.keyPair !=
null)
160 name.KeyPair = state.keyPair;
161 else if (state.publicKey !=
null)
162 name.SetPublicKey(state.publicKey);
164 name.Version = state.version;
167 assemblyBuilder =
Context.StaticCompiler.Universe.DefineDynamicAssembly(name, AssemblyBuilderAccess.ReflectionOnly, assemblyDir);
168 var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName, assemblyFile, EmitSymbols);
171 if (EmitStackTraceInfo)
175 var debugModes = DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints;
176 if (EnableOptimizations ==
false)
177 debugModes |= DebuggableAttribute.DebuggingModes.DisableOptimizations;
182 if (state.baseAddress != 0)
183 moduleBuilder.__ImageBase = state.baseAddress;
184 if (state.fileAlignment != 0)
185 moduleBuilder.__FileAlignment = state.fileAlignment;
186 if (state.highentropyva)
187 moduleBuilder.__DllCharacteristics |= DllCharacteristics.HighEntropyVA;
190 var mainAssemblyName = state.sharedclassloader !=
null && state.sharedclassloader[0] !=
this
191 ? state.sharedclassloader[0].assemblyName
193 if (!DisableDynamicBinding)
196 return moduleBuilder;
201 return "CompilerClassLoader:" + state.assembly;
206 foreach (RuntimeAssemblyClassLoader acl
in referencedAssemblies)
208 var tw = acl.DoLoad(name);
213 if (!peerLoading.ContainsKey(name))
215 peerLoading.Add(name,
null);
220 var tw = ccl.PeerLoad(name);
224 if (state.sharedclassloader !=
null && state.sharedclassloader[0] !=
this)
226 var tw = state.sharedclassloader[0].PeerLoad(name);
233 peerLoading.Remove(name);
237 var tw1 = GetTypeWrapperCompilerHook(name);
245 tw1 = FindLoadedClass(name);
251 return FindOrLoadGenericClass(name, mode);
254 private RuntimeJavaType PeerLoad(
string name)
258 if (classes.ContainsKey(name) || remapped.ContainsKey(name) || FindLoadedClass(name) !=
null)
260 var tw = TryLoadClassByName(name);
262 if (tw !=
null && tw.ClassLoader ==
this)
267 if (state.sharedclassloader !=
null && state.sharedclassloader[0] ==
this)
273 var tw = ccl.PeerLoad(name);
284 RuntimeJavaType GetTypeWrapperCompilerHook(
string name)
286 if (remapped.TryGetValue(name, out var rtw))
292 if (classes.TryGetValue(name, out var itemRef))
294 classes.Remove(name);
302 catch (UnsupportedClassVersionException e)
305 Diagnostics.ClassFormatError(name, e.Message);
308 catch (ByteCodeException e)
311 Diagnostics.ClassFormatError(name, e.Message);
317 Diagnostics.ClassFormatError(name, e.Message);
324 Diagnostics.WrongClassName(name, f.Name);
328 if (f.
IsPublic && state.privatePackages !=
null)
330 foreach (
string p
in state.privatePackages)
332 if (f.Name.StartsWith(p))
340 if (f.
IsPublic && state.publicPackages !=
null)
343 foreach (
string package
in state.publicPackages)
345 if (f.Name.StartsWith(package))
357 if (f.SourceFileAttribute !=
null)
359 var path = itemRef.Path;
362 var sourceFile = Path.GetFullPath(Path.Combine(path.DirectoryName, f.SourceFileAttribute));
363 if (File.Exists(sourceFile))
364 f.SourcePath = sourceFile;
367 if (f.SourcePath ==
null)
369 if (state.sourcepath !=
null)
371 var
package = f.Name;
372 var index = package.LastIndexOf(
'.');
373 package = index == -1 ? "" : package.Substring(0, index).Replace('.', '/');
374 f.SourcePath = Path.GetFullPath(Path.Combine(state.sourcepath +
"/" + package, f.SourceFileAttribute));
378 f.SourcePath = f.SourceFileAttribute;
385 var tw = DefineClass(f,
null);
388 if (state.nojarstubs)
394 itemRef.MarkAsStub();
397 int pos = f.Name.LastIndexOf(
'.');
400 string manifestJar = state.IsClassesJar(itemRef.Jar) ? null : itemRef.Jar.Name;
401 packages.DefinePackage(f.Name.Substring(0, pos), manifestJar);
408 Diagnostics.ClassFormatError(name, x.Message);
412 Diagnostics.IllegalAccessError(name, x.Message);
416 Diagnostics.VerificationError(name, x.Message);
420 if ((state.codegenoptions &
CodeGenOptions.DisableDynamicBinding) != 0)
422 Diagnostics.NoClassDefFoundError(name, x.Message);
425 Diagnostics.ClassNotFound(x.Message);
429 Diagnostics.GenericUnableToCompileError(name, x.GetType().Name, x.Message);
451 if (ccl !=
null && state.sharedclassloader !=
null && state.sharedclassloader.Contains(ccl))
453 if (!internalsVisibleTo.Contains(ccl))
455 AddInternalsVisibleToAttribute(ccl);
462 internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJavaType
friend)
464 Debug.Assert(wrapper.ClassLoader ==
this);
467 if (
this == other || internalsVisibleTo.Contains(other))
474 AddInternalsVisibleToAttribute(ccl);
482 internalsVisibleTo.Add(ccl);
483 AssemblyBuilder
asm = ccl.assemblyBuilder;
484 AssemblyName asmName =
asm.GetName();
485 string name = asmName.Name;
486 byte[] pubkey = asmName.GetPublicKey();
487 if (pubkey ==
null && asmName.KeyPair !=
null)
489 pubkey = asmName.KeyPair.PublicKey;
491 if (pubkey !=
null && pubkey.Length != 0)
493 StringBuilder sb =
new StringBuilder(name);
494 sb.Append(
", PublicKey=");
495 foreach (
byte b
in pubkey)
497 sb.AppendFormat(
"{0:X2}", b);
499 name = sb.ToString();
512 void SetMain(RuntimeJavaType type, PEFileKinds target, IDictionary<string, string> properties,
bool noglobbing, Type apartmentAttributeType)
515 throw new ArgumentNullException(nameof(type));
516 if (properties is
null)
517 throw new ArgumentNullException(nameof(properties));
520 var mainMethodProxy = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod(
"Main", MethodAttributes.Public | MethodAttributes.Static,
Context.
Types.
Int32,
new[] { Context.Types.String.MakeArrayType() });
521 if (apartmentAttributeType !=
null)
522 mainMethodProxy.SetCustomAttribute(
new CustomAttributeBuilder(apartmentAttributeType.GetConstructor(Type.EmptyTypes), Array.Empty<
object>()));
527 ilgen.Emit(OpCodes.Ldtoken, type.TypeAsTBD);
529 ilgen.Emit(OpCodes.Callvirt,
Context.
Types.
Type.GetProperty(nameof(
System.Type.Assembly)).GetGetMethod());
532 ilgen.Emit(OpCodes.Ldstr, type.Name);
535 ilgen.Emit(OpCodes.Ldc_I4_0);
538 ilgen.Emit(OpCodes.Ldarg_0);
541 ilgen.Emit(OpCodes.Ldstr, DEFAULT_RUNTIME_ARGS_PREFIX);
544 if (properties.Count > 0)
546 var environmentType =
Context.
Resolver.ResolveCoreType(typeof(Environment).FullName).AsReflection();
547 var environmentExpandMethod = environmentType.GetMethod(nameof(Environment.ExpandEnvironmentVariables), [
Context.
Types.
String]);
551 ilgen.EmitLdc_I4(properties.Count);
552 ilgen.Emit(OpCodes.Newobj, dictionaryType.GetConstructor([
Context.
Types.
Int32]));
554 foreach (var kvp
in properties)
556 ilgen.Emit(OpCodes.Dup);
557 ilgen.Emit(OpCodes.Ldstr, kvp.Key);
558 ilgen.Emit(OpCodes.Ldstr, kvp.Value);
561 if (kvp.Value.IndexOf(
'%') < kvp.Value.LastIndexOf(
'%'))
562 ilgen.Emit(OpCodes.Call, environmentExpandMethod);
565 ilgen.Emit(OpCodes.Callvirt, dictionaryAddMethod);
570 ilgen.Emit(OpCodes.Ldnull);
575 ilgen.Emit(OpCodes.Call, launchMethod);
576 ilgen.Emit(OpCodes.Ret);
580 assemblyBuilder.SetEntryPoint(mainMethodProxy, target);
585 ((DynamicClassLoader)this.GetTypeWrapperFactory()).FinishAll();
590 ModuleBuilder mb = GetTypeWrapperFactory().ModuleBuilder;
598 for (
int i = 0; i < referencedAssemblies.Length; i++)
600 Type[] types = referencedAssemblies[i].MainAssembly.GetExportedTypes();
601 if (types.Length > 0)
603 mb.GetTypeToken(types[0]);
607 mb.CreateGlobalFunctions();
609 AddJavaModuleAttribute(mb);
612 if (state.sharedclassloader ==
null || state.sharedclassloader[0] ==
this)
615 foreach (
object[] args
in packages.ToArray())
617 args[1] =
UnicodeUtil.EscapeInvalidSurrogates((
string[])args[1]);
618 mb.SetCustomAttribute(
new CustomAttributeBuilder(packageListAttributeCtor, args));
631 Diagnostics.GenericCompilerInfo($
"CompilerClassLoader saving {assemblyFile} in {assemblyDir}");
635 GetTypeWrapperFactory().ModuleBuilder.__Save(state.pekind, state.imageFileMachine);
637 catch (IOException x)
641 catch (UnauthorizedAccessException x)
648 Diagnostics.GenericCompilerInfo($
"CompilerClassLoader saving {assemblyFile} in {assemblyDir}");
652 assemblyBuilder.Save(assemblyFile, state.pekind, state.imageFileMachine);
654 catch (IOException x)
658 catch (UnauthorizedAccessException x)
665 void AddJavaModuleAttribute(ModuleBuilder mb)
668 var propInfos =
new[] { typeofJavaModuleAttribute.GetProperty(
"Jars") };
669 var propValues =
new object[] { jarList.ToArray() };
671 if (nameMappings.Count > 0)
673 var list =
new string[nameMappings.Count * 2];
675 foreach (var kv
in nameMappings)
678 list[i++] = kv.Value;
682 var cab =
new CustomAttributeBuilder(typeofJavaModuleAttribute.GetConstructor([
Context.
Resolver.ResolveCoreType(typeof(
string).FullName).MakeArrayType().AsReflection()]), [list], propInfos, propValues);
683 mb.SetCustomAttribute(cab);
687 var cab =
new CustomAttributeBuilder(typeofJavaModuleAttribute.GetConstructor([]), [], propInfos, propValues);
688 mb.SetCustomAttribute(cab);
692 static void AddExportMapEntry(Dictionary<
string, List<string>> map,
ImportClassLoader ccl,
string name)
694 string assemblyName = ccl.assemblyBuilder.FullName;
696 if (map.TryGetValue(assemblyName, out var list) ==
false)
698 list =
new List<string>();
699 map.Add(assemblyName, list);
706 void AddWildcardExports(Dictionary<
string, List<string>> exportedNamesPerAssembly)
708 foreach (var acl
in referencedAssemblies)
709 exportedNamesPerAssembly[acl.MainAssembly.FullName] =
null;
712 void WriteExportMap()
714 var exportedNamesPerAssembly =
new Dictionary<string, List<string>>();
716 AddWildcardExports(exportedNamesPerAssembly);
717 foreach (var tw
in dynamicallyImportedTypes)
718 AddExportMapEntry(exportedNamesPerAssembly, (
ImportClassLoader)tw.ClassLoader, tw.Name);
720 if (state.sharedclassloader ==
null)
722 foreach (var ccl
in peerReferences)
723 exportedNamesPerAssembly[ccl.assemblyBuilder.FullName] =
null;
727 foreach (var ccl
in state.sharedclassloader)
731 ccl.AddWildcardExports(exportedNamesPerAssembly);
732 foreach (var jar
in ccl.state.jars)
733 foreach (var item
in jar)
734 if (item.IsStub ==
false)
735 AddExportMapEntry(exportedNamesPerAssembly, ccl, item.Name);
737 if (ccl.state.externalResources !=
null)
738 foreach (
string name
in ccl.state.externalResources.Keys)
739 AddExportMapEntry(exportedNamesPerAssembly, ccl, name);
744 var ms =
new MemoryStream();
745 var bw =
new BinaryWriter(ms);
746 bw.Write(exportedNamesPerAssembly.Count);
748 foreach (var kv
in exportedNamesPerAssembly)
751 if (kv.Value ==
null)
758 Debug.Assert(kv.Value.Count != 0);
759 bw.Write(kv.Value.Count);
760 foreach (var name
in kv.Value)
761 bw.Write(
JVM.PersistableHash(name));
765 GetTypeWrapperFactory().ModuleBuilder.DefineManifestResource(
"ikvm.exports", ms, ResourceAttributes.Public);
768 void WriteResources()
770 Diagnostics.GenericCompilerInfo(
"CompilerClassLoader adding resources...");
773 var moduleBuilder = GetTypeWrapperFactory().ModuleBuilder;
775 for (
int i = 0; i < state.jars.Count; i++)
777 var hasEntries =
false;
778 var mem =
new MemoryStream();
779 using (var zip =
new ZipArchive(mem, ZipArchiveMode.Create))
781 var stubs =
new List<string>();
782 foreach (Jar.Item item in state.jars[i])
787 if (i != state.classesJar)
788 stubs.Add(item.Name);
792 var zipEntry = zip.CreateEntry(item.Name, state.compressedResources ? CompressionLevel.Optimal : CompressionLevel.NoCompression);
794 byte[] data = item.GetData();
796 using Stream stream = zipEntry.Open();
797 stream.Write(data, 0, data.Length);
802 if (stubs.Count != 0)
805 var zipEntry = zip.CreateEntry(
JVM.
Internal.JarClassList);
807 using Stream stream = zipEntry.Open();
808 using BinaryWriter bw =
new BinaryWriter(stream);
810 bw.Write(stubs.Count);
811 foreach (
string classFile
in stubs)
819 if (i != state.classesJar || hasEntries)
821 mem =
new MemoryStream(mem.ToArray());
822 var name = state.jars[i].Name;
823 if (state.targetIsModule)
824 name = Path.GetFileNameWithoutExtension(name) +
"-" + moduleBuilder.ModuleVersionId.ToString(
"N") + Path.GetExtension(name);
827 moduleBuilder.DefineManifestResource(name, mem, ResourceAttributes.Public);
835 switch (mod & access)
838 return MethodAttributes.Public;
840 return MethodAttributes.FamORAssem;
842 return MethodAttributes.Private;
851 switch (mod & access)
854 return FieldAttributes.Public;
856 return FieldAttributes.FamORAssem;
858 return FieldAttributes.Private;
864 private sealed class RemapperTypeWrapper : RuntimeJavaType
867 private TypeBuilder typeBuilder;
868 private TypeBuilder helperTypeBuilder;
869 private Type shadowType;
870 private IKVM.Tools.Importer.MapXml.Class classDef;
871 private RuntimeJavaType baseTypeWrapper;
872 private RuntimeJavaType[] interfaceWrappers;
876 internal override bool IsRemapped
890 if (c.Name ==
"java.lang.Object")
895 return context.
JavaBase.TypeOfJavaLangObject;
901 this.classLoader = classLoader;
902 this.baseTypeWrapper = GetBaseWrapper(context, c);
904 bool baseIsSealed =
false;
905 shadowType = context.StaticCompiler.Universe.GetType(c.Shadows,
true);
906 classLoader.SetRemappedType(shadowType,
this);
907 Type baseType = shadowType;
908 Type baseInterface =
null;
909 if (baseType.IsInterface)
911 baseInterface = baseType;
913 TypeAttributes attrs = TypeAttributes.Public;
916 attrs |= TypeAttributes.Class;
917 if (baseType.IsSealed)
920 attrs |= TypeAttributes.Abstract | TypeAttributes.Sealed;
925 attrs |= TypeAttributes.Interface | TypeAttributes.Abstract;
930 attrs |= TypeAttributes.Abstract;
932 string name = c.Name.Replace(
'/',
'.');
933 typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name, attrs, baseIsSealed ? Context.
Types.
Object : baseType);
934 if (c.Attributes !=
null)
938 Context.
AttributeHelper.SetCustomAttribute(classLoader, typeBuilder, custattr);
941 if (baseInterface !=
null)
943 typeBuilder.AddInterfaceImplementation(baseInterface);
945 if (classLoader.EmitStackTraceInfo)
947 Context.
AttributeHelper.SetSourceFile(typeBuilder, classLoader.state.remapfile.Name);
955 if (c.Scope == MapXml.Scope.Public)
961 Context.
AttributeHelper.SetRemappedClass(classLoader.assemblyBuilder, name, shadowType);
966 var methods =
new List<RuntimeJavaMethod>();
968 if (c.Constructors !=
null)
972 methods.Add(
new RemappedConstructorWrapper(
this, m));
976 if (c.Methods !=
null)
980 methods.Add(
new RemappedMethodWrapper(
this, m, map,
false));
984 if (!this.IsFinal && !this.IsInterface && this.BaseTypeWrapper !=
null)
986 foreach (var mw
in BaseTypeWrapper.GetMethods())
988 var rmw = mw as RemappedMethodWrapper;
989 if (rmw !=
null && (rmw.IsPublic || rmw.IsProtected))
991 if (!FindMethod(methods, rmw.Name, rmw.Signature))
993 methods.Add(
new RemappedMethodWrapper(
this, rmw.XmlMethod, map,
true));
999 SetMethods(methods.ToArray());
1002 internal sealed override RuntimeJavaType BaseTypeWrapper
1004 get {
return baseTypeWrapper; }
1009 if (c.Interfaces !=
null)
1011 interfaceWrappers =
new RuntimeJavaType[c.Interfaces.Length];
1012 for (
int i = 0; i < c.Interfaces.Length; i++)
1014 var iface = classLoader.LoadClassByName(c.Interfaces[i].Class);
1015 interfaceWrappers[i] = iface;
1016 foreach (var mw
in iface.GetMethods())
1019 if (mw.IsVirtual && !mw.IsAbstract)
1021 if (GetMethod(mw.Name, mw.Signature,
true) ==
null)
1023 classLoader.Diagnostics.RemappedTypeMissingDefaultInterfaceMethod(
Name, iface.Name +
"." + mw.Name + mw.Signature);
1031 interfaceWrappers = Array.Empty<RuntimeJavaType>();
1035 private static bool FindMethod(List<RuntimeJavaMethod> methods,
string name,
string sig)
1037 foreach (var mw
in methods)
1039 if (mw.Name == name && mw.Signature == sig)
1050 internal RemappedMethodBaseWrapper(RemapperTypeWrapper typeWrapper,
string name,
string sig,
Modifiers modifiers) :
1056 internal abstract MethodBase DoLink();
1058 internal abstract void Finish();
1062 sealed class RemappedConstructorWrapper : RemappedMethodBaseWrapper
1065 private IKVM.Tools.Importer.MapXml.Constructor m;
1066 private MethodBuilder mbHelper;
1074 internal override void EmitCall(
CodeEmitter ilgen)
1076 ilgen.Emit(OpCodes.Call, GetMethod());
1079 internal override void EmitNewobj(
CodeEmitter ilgen)
1081 if (mbHelper !=
null)
1083 ilgen.Emit(OpCodes.Call, mbHelper);
1087 ilgen.Emit(OpCodes.Newobj, GetMethod());
1091 internal override MethodBase DoLink()
1093 MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers);
1094 RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
1095 Type[] paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig);
1097 MethodBuilder cbCore =
null;
1099 if (typeWrapper.shadowType.IsSealed)
1101 mbHelper = typeWrapper.typeBuilder.DefineMethod(
"newhelper", attr | MethodAttributes.Static, CallingConventions.Standard, typeWrapper.shadowType, paramTypes);
1102 if (m.Attributes !=
null)
1106 DeclaringType.Context.
AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbHelper, custattr);
1109 SetParameters(DeclaringType.ClassLoader, mbHelper, m.Parameters);
1111 DeclaringType.Context.
AttributeHelper.SetNameSig(mbHelper,
"<init>", m.Sig);
1112 AddDeclaredExceptions(DeclaringType.Context, mbHelper, m.Throws);
1116 cbCore =
ReflectUtil.DefineConstructor(typeWrapper.typeBuilder, attr, paramTypes);
1117 if (m.Attributes !=
null)
1121 DeclaringType.Context.
AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, cbCore, custattr);
1124 SetParameters(DeclaringType.ClassLoader, cbCore, m.Parameters);
1125 AddDeclaredExceptions(DeclaringType.Context, cbCore, m.Throws);
1130 internal override void Finish()
1134 Type[] paramTypes = this.GetParametersForDefineMethod();
1136 MethodBuilder cbCore = GetMethod() as MethodBuilder;
1145 m.Body.Emit(DeclaringType.ClassLoader, ilgen);
1149 ilgen.Emit(OpCodes.Ldarg_0);
1150 for (int i = 0; i < paramTypes.Length; i++)
1152 ilgen.EmitLdarg(i + 1);
1154 if (m.Redirect !=
null)
1156 throw new NotImplementedException();
1160 ConstructorInfo baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes);
1161 if (baseCon == null)
1164 throw new InvalidOperationException(
"base class constructor not found: " + DeclaringType.Name +
".<init>" + m.Sig);
1166 ilgen.Emit(OpCodes.Call, baseCon);
1168 ilgen.Emit(OpCodes.Ret);
1171 if (this.DeclaringType.ClassLoader.EmitStackTraceInfo)
1173 ilgen.EmitLineNumberTable(cbCore);
1177 if (mbHelper !=
null)
1180 if (m.Redirect !=
null)
1182 m.Redirect.Emit(DeclaringType.ClassLoader, ilgen);
1184 else if (m.AlternateBody !=
null)
1186 m.AlternateBody.Emit(DeclaringType.ClassLoader, ilgen);
1188 else if (m.Body !=
null)
1191 throw new InvalidOperationException();
1195 ConstructorInfo baseCon = DeclaringType.TypeAsTBD.GetConstructor(paramTypes);
1196 if (baseCon ==
null)
1199 throw new InvalidOperationException(
"constructor not found: " + DeclaringType.Name +
".<init>" + m.Sig);
1201 for (
int i = 0; i < paramTypes.Length; i++)
1205 ilgen.Emit(OpCodes.Newobj, baseCon);
1206 ilgen.Emit(OpCodes.Ret);
1209 if (this.DeclaringType.ClassLoader.EmitStackTraceInfo)
1211 ilgen.EmitLineNumberTable(mbHelper);
1217 sealed class RemappedMethodWrapper : RemappedMethodBaseWrapper
1220 private IKVM.Tools.Importer.MapXml.Method m;
1221 private IKVM.Tools.Importer.MapXml.Root map;
1222 private MethodBuilder mbHelper;
1223 private List<RemapperTypeWrapper> overriders =
new List<RemapperTypeWrapper>();
1224 private bool inherited;
1231 this.inherited = inherited;
1234 internal IKVM.Tools.Importer.MapXml.Method XmlMethod
1242 internal override void EmitCall(
CodeEmitter ilgen)
1244 if (!IsStatic && IsFinal)
1249 EmitCallvirt(ilgen);
1253 ilgen.Emit(OpCodes.Call, (MethodInfo)GetMethod());
1257 internal override void EmitCallvirt(
CodeEmitter ilgen)
1259 EmitCallvirtImpl(ilgen, this.IsProtected && !mbHelper.IsPublic);
1262 private void EmitCallvirtImpl(
CodeEmitter ilgen,
bool cloneOrFinalizeHack)
1264 if (mbHelper !=
null && !cloneOrFinalizeHack)
1266 ilgen.Emit(OpCodes.Call, mbHelper);
1270 ilgen.Emit(OpCodes.Callvirt, (MethodInfo)GetMethod());
1274 internal override MethodBase DoLink()
1276 RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
1278 if (typeWrapper.IsInterface)
1280 if (m.Override ==
null)
1282 throw new InvalidOperationException(typeWrapper.Name +
"." + m.Name + m.Sig);
1284 MethodInfo interfaceMethod = typeWrapper.shadowType.GetMethod(m.Override.
Name, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig));
1285 if (interfaceMethod ==
null)
1287 throw new InvalidOperationException(typeWrapper.Name +
"." + m.Name + m.Sig);
1294 if (c.Methods !=
null)
1298 if (mm.Name == m.Name && mm.Sig == m.Sig && mm.Body !=
null)
1300 if (specialCases ==
null)
1304 specialCases.Add(c);
1311 if (m.Throws ==
null)
1313 throws =
new string[0];
1317 throws =
new string[m.Throws.Length];
1318 for (
int i = 0; i <
throws.Length; i++)
1320 throws[i] = m.Throws[i].
Class;
1323 DeclaringType.Context.AttributeHelper.SetRemappedInterfaceMethod(typeWrapper.typeBuilder, m.Name, m.Override.
Name,
throws);
1324 MethodBuilder helper =
null;
1325 if (specialCases !=
null)
1328 Type[] argTypes =
ArrayUtil.Concat(typeWrapper.shadowType, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig));
1329 if (typeWrapper.helperTypeBuilder ==
null)
1331 typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType(
"__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract);
1332 DeclaringType.Context.AttributeHelper.HideFromJava(typeWrapper.helperTypeBuilder);
1334 helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig,
LoadMode.LoadOrThrow).TypeAsSignatureType, argTypes);
1335 if (m.Attributes !=
null)
1339 DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, helper, custattr);
1342 SetParameters(DeclaringType.ClassLoader, helper, m.Parameters);
1346 var tw = typeWrapper.ClassLoader.LoadClassByName(c.Name);
1347 ilgen.Emit(OpCodes.Ldarg_0);
1348 ilgen.Emit(OpCodes.Isinst, tw.TypeAsTBD);
1349 ilgen.Emit(OpCodes.Dup);
1351 ilgen.EmitBrfalse(label);
1352 for (
int i = 1; i < argTypes.Length; i++)
1356 var mw = tw.GetMethod(m.Name, m.Sig,
false);
1358 mw.EmitCallvirt(ilgen);
1359 ilgen.Emit(OpCodes.Ret);
1360 ilgen.MarkLabel(label);
1361 ilgen.Emit(OpCodes.Pop);
1363 for (
int i = 0; i < argTypes.Length; i++)
1367 ilgen.Emit(OpCodes.Callvirt, interfaceMethod);
1368 ilgen.Emit(OpCodes.Ret);
1372 return interfaceMethod;
1376 MethodBuilder mbCore =
null;
1377 Type[] paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig);
1378 Type retType = typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig,
LoadMode.LoadOrThrow).TypeAsSignatureType;
1383 if (typeWrapper.BaseTypeWrapper !=
null && (m.Modifiers &
IKVM.
Tools.
Importer.
MapXml.MapModifiers.Private) == 0)
1385 RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethod(m.Name, m.Sig,
true) as RemappedMethodWrapper;
1386 if (baseMethod !=
null &&
1387 !baseMethod.IsFinal &&
1388 !baseMethod.IsPrivate &&
1389 (baseMethod.m.Override !=
null ||
1390 baseMethod.m.Redirect !=
null ||
1391 baseMethod.m.Body !=
null ||
1392 baseMethod.m.AlternateBody !=
null))
1394 baseMethod.overriders.Add(typeWrapper);
1400 MethodInfo overrideMethod =
null;
1401 MethodAttributes attr = m.MethodAttributes | MapMethodAccessModifiers(m.Modifiers) | MethodAttributes.HideBySig;
1404 attr |= MethodAttributes.Static;
1408 attr |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride;
1409 if (!typeWrapper.shadowType.IsSealed)
1411 MethodInfo autoOverride = typeWrapper.shadowType.GetMethod(m.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null, paramTypes,
null);
1412 if (autoOverride !=
null && autoOverride.ReturnType == retType && !autoOverride.IsFinal)
1415 attr &= ~MethodAttributes.NewSlot;
1418 if (typeWrapper.BaseTypeWrapper !=
null)
1420 RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethod(m.Name, m.Sig,
true) as RemappedMethodWrapper;
1421 if (baseMethod !=
null)
1423 baseMethod.overriders.Add(typeWrapper);
1424 if (baseMethod.m.Override !=
null)
1426 overrideMethod = typeWrapper.BaseTypeWrapper.TypeAsTBD.GetMethod(baseMethod.m.Override.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null, paramTypes,
null);
1427 if (overrideMethod ==
null)
1429 throw new InvalidOperationException();
1435 mbCore = GetDefineMethodHelper().DefineMethod(DeclaringType.ClassLoader.GetTypeWrapperFactory(), typeWrapper.typeBuilder, m.Name, attr);
1436 if (m.Attributes !=
null)
1440 DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbCore, custattr);
1443 SetParameters(DeclaringType.ClassLoader, mbCore, m.Parameters);
1444 if (overrideMethod !=
null && !inherited)
1446 typeWrapper.typeBuilder.DefineMethodOverride(mbCore, overrideMethod);
1450 DeclaringType.Context.AttributeHelper.HideFromReflection(mbCore);
1452 AddDeclaredExceptions(DeclaringType.Context, mbCore, m.Throws);
1458 MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers) | MethodAttributes.HideBySig | MethodAttributes.Static;
1463 attr &= ~MethodAttributes.MemberAccessMask;
1464 attr |= MethodAttributes.Assembly;
1466 mbHelper = typeWrapper.typeBuilder.DefineMethod(
"instancehelper_" + m.Name, attr, CallingConventions.Standard, retType,
ArrayUtil.Concat(typeWrapper.shadowType, paramTypes));
1467 if (m.Attributes !=
null)
1471 DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbHelper, custattr);
1475 if (m.Parameters ==
null)
1482 m.Parameters.CopyTo(parameters, 1);
1485 parameters[0].
Name =
"this";
1486 SetParameters(DeclaringType.ClassLoader, mbHelper, parameters);
1487 if (!typeWrapper.IsFinal)
1489 DeclaringType.Context.AttributeHelper.SetEditorBrowsableNever(mbHelper);
1491 DeclaringType.Context.AttributeHelper.SetModifiers(mbHelper, (
Modifiers)m.Modifiers,
false);
1492 DeclaringType.Context.AttributeHelper.SetNameSig(mbHelper, m.Name, m.Sig);
1493 AddDeclaredExceptions(DeclaringType.Context, mbHelper, m.Throws);
1494 mbHelper.SetCustomAttribute(
new CustomAttributeBuilder(DeclaringType.Context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection().GetConstructor([DeclaringType.Context.Types.String]), [
"This function will be removed from future versions. Please use extension methods from ikvm.extensions namespace instead."]));
1502 if (m.Attributes !=
null)
1504 foreach (MapXml.Attribute attr in m.Attributes)
1506 if (attr.Type ==
"IKVM.Attributes.HideFromJavaAttribute")
1512 return m.Name.StartsWith(
"__<", StringComparison.Ordinal);
1515 internal override void Finish()
1518 Type[] paramTypes = this.GetParametersForDefineMethod();
1520 MethodBuilder mbCore = GetMethod() as MethodBuilder;
1526 MethodInfo baseMethod =
null;
1527 if (m.Override !=
null)
1529 baseMethod = DeclaringType.TypeAsTBD.GetMethod(m.Override.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null);
1530 if (baseMethod == null)
1532 throw new InvalidOperationException();
1534 ((TypeBuilder)DeclaringType.TypeAsBaseType).DefineMethodOverride(mbCore, baseMethod);
1540 IKVM.Tools.Importer.MapXml.CodeGenContext context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.ClassLoader);
1541 foreach (IKVM.Tools.Importer.MapXml.Instruction instr in m.Body.Instructions)
1543 if (instr is IKVM.Tools.Importer.MapXml.Ret)
1545 this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
1547 instr.Generate(context, ilgen);
1552 if (m.Redirect !=
null && m.Redirect.
LineNumber != -1)
1553 ilgen.SetLineNumber((ushort)m.Redirect.
LineNumber);
1559 ilgen.Emit(OpCodes.Ldarg_0);
1561 for (
int i = 0; i < paramTypes.Length; i++)
1563 ilgen.EmitLdarg(i + thisOffset);
1565 if (m.Redirect !=
null)
1567 EmitRedirect(DeclaringType.TypeAsTBD, ilgen);
1571 if (baseMethod ==
null)
1573 throw new InvalidOperationException(DeclaringType.Name +
"." + m.Name + m.Sig);
1575 ilgen.Emit(OpCodes.Call, baseMethod);
1577 this.ReturnType.EmitConvStackTypeToSignatureType(ilgen,
null);
1578 ilgen.Emit(OpCodes.Ret);
1581 if (this.DeclaringType.ClassLoader.EmitStackTraceInfo)
1583 ilgen.EmitLineNumberTable(mbCore);
1591 if (mbHelper !=
null && !this.DeclaringType.IsInterface)
1593 CodeEmitter ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mbHelper);
1595 if (m.Override != null && m.Redirect == null && m.Body == null && m.AlternateBody == null)
1599 else if (!m.NoNullCheck)
1601 ilgen.Emit(OpCodes.Ldarg_0);
1602 ilgen.EmitNullCheck();
1604 if (mbCore !=
null &&
1605 (m.Override ==
null || m.Redirect !=
null) &&
1609 ilgen.Emit(OpCodes.Ldarg_0);
1610 ilgen.Emit(OpCodes.Isinst, DeclaringType.TypeAsBaseType);
1611 ilgen.Emit(OpCodes.Dup);
1612 CodeEmitterLabel skip = ilgen.DefineLabel();
1613 ilgen.EmitBrfalse(skip);
1614 for (int i = 0; i < paramTypes.Length; i++)
1616 ilgen.EmitLdarg(i + 1);
1618 ilgen.Emit(OpCodes.Callvirt, mbCore);
1619 this.ReturnType.EmitConvStackTypeToSignatureType(ilgen,
null);
1620 ilgen.Emit(OpCodes.Ret);
1621 ilgen.MarkLabel(skip);
1622 ilgen.Emit(OpCodes.Pop);
1624 foreach (RemapperTypeWrapper overrider
in overriders)
1626 RemappedMethodWrapper mw = (RemappedMethodWrapper)overrider.GetMethod(
Name,
Signature,
false);
1627 if (mw.m.Redirect ==
null && mw.m.Body ==
null && mw.m.AlternateBody ==
null)
1634 ilgen.Emit(OpCodes.Ldarg_0);
1635 ilgen.Emit(OpCodes.Isinst, overrider.TypeAsTBD);
1636 ilgen.Emit(OpCodes.Dup);
1638 ilgen.EmitBrfalse(skip);
1639 for (
int i = 0; i < paramTypes.Length; i++)
1641 ilgen.EmitLdarg(i + 1);
1644 mw.EmitCallvirtImpl(ilgen,
false);
1645 this.ReturnType.EmitConvStackTypeToSignatureType(ilgen,
null);
1646 ilgen.Emit(OpCodes.Ret);
1647 ilgen.MarkLabel(skip);
1648 ilgen.Emit(OpCodes.Pop);
1651 if (m.Body !=
null || m.AlternateBody !=
null)
1653 IKVM.Tools.Importer.MapXml.InstructionList body = m.AlternateBody == null ? m.Body : m.AlternateBody;
1655 IKVM.Tools.Importer.MapXml.CodeGenContext context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.ClassLoader);
1656 foreach (IKVM.Tools.Importer.MapXml.Instruction instr in body.Instructions)
1658 if (instr is IKVM.Tools.Importer.MapXml.Ret)
1660 this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
1662 instr.Generate(context, ilgen);
1667 if (m.Redirect !=
null && m.Redirect.
LineNumber != -1)
1669 ilgen.SetLineNumber((ushort)m.Redirect.
LineNumber);
1672 var shadowType = ((RemapperTypeWrapper)DeclaringType).shadowType;
1673 for (
int i = 0; i < paramTypes.Length + 1; i++)
1676 if (m.Redirect !=
null)
1678 EmitRedirect(shadowType, ilgen);
1680 else if (m.Override !=
null)
1682 var baseMethod = shadowType.GetMethod(m.Override.
Name, BindingFlags.Instance | BindingFlags.Public,
null, paramTypes,
null);
1683 if (baseMethod ==
null)
1684 throw new InvalidOperationException(DeclaringType.Name +
"." + m.Name + m.Sig);
1686 ilgen.Emit(OpCodes.Callvirt, baseMethod);
1690 var baseMethod = DeclaringType.BaseTypeWrapper.GetMethod(
Name,
Signature,
true) as RemappedMethodWrapper;
1691 if (baseMethod ==
null || baseMethod.m.Override ==
null)
1692 throw new InvalidOperationException(DeclaringType.Name +
"." + m.Name + m.Sig);
1694 var overrideMethod = shadowType.GetMethod(baseMethod.m.Override.Name, BindingFlags.Instance | BindingFlags.Public,
null, paramTypes,
null);
1695 if (overrideMethod ==
null)
1696 throw new InvalidOperationException(DeclaringType.Name +
"." + m.Name + m.Sig);
1698 ilgen.Emit(OpCodes.Callvirt, overrideMethod);
1701 ReturnType.EmitConvStackTypeToSignatureType(ilgen,
null);
1702 ilgen.Emit(OpCodes.Ret);
1707 if (DeclaringType.ClassLoader.EmitStackTraceInfo)
1708 ilgen.EmitLineNumberTable(mbHelper);
1712 if (m.NonVirtualAlternateBody !=
null || (m.Override !=
null && overriders.Count > 0))
1714 var tw = (RemapperTypeWrapper)DeclaringType;
1715 var mb = tw.typeBuilder.DefineMethod(
"nonvirtualhelper/" + Name, MethodAttributes.Private | MethodAttributes.Static, ReturnTypeForDefineMethod, ArrayUtil.Concat(tw.TypeAsSignatureType, GetParametersForDefineMethod()));
1718 if (m.Attributes != null)
1719 foreach (var custattr in m.Attributes)
1720 DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mb, custattr);
1722 SetParameters(DeclaringType.ClassLoader, mb, m.Parameters);
1723 DeclaringType.Context.AttributeHelper.HideFromJava(mb);
1725 var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mb);
1726 if (m.NonVirtualAlternateBody != null)
1728 m.NonVirtualAlternateBody.Emit(DeclaringType.ClassLoader, ilgen);
1732 var shadowType = ((RemapperTypeWrapper)DeclaringType).shadowType;
1733 var baseMethod = shadowType.GetMethod(m.Override.Name, BindingFlags.Instance | BindingFlags.Public, null, paramTypes, null);
1734 if (baseMethod == null)
1735 throw new InvalidOperationException(DeclaringType.Name +
"." + m.Name + m.Sig);
1737 ilgen.Emit(OpCodes.Ldarg_0);
1738 for (int i = 0; i < paramTypes.Length; i++)
1739 ilgen.EmitLdarg(i + 1);
1741 ilgen.Emit(OpCodes.Call, baseMethod);
1742 ilgen.Emit(OpCodes.Ret);
1749 private void EmitRedirect(Type baseType,
CodeEmitter ilgen)
1751 var redirName = m.Redirect.Name ?? m.Name;
1752 var redirSig = m.Redirect.Sig ?? m.Sig;
1753 var classLoader = DeclaringType.ClassLoader;
1756 if (m.Redirect.
Type !=
null || m.Redirect.
Class ==
null)
1758 var type = m.Redirect.Type !=
null ? DeclaringType.Context.StaticCompiler.Universe.GetType(m.Redirect.
Type,
true) : baseType;
1759 var redirParamTypes = classLoader.ArgTypeListFromSig(redirSig);
1760 var mi = type.GetMethod(m.Redirect.
Name, redirParamTypes) ??
throw new InvalidOperationException();
1761 ilgen.Emit(OpCodes.Call, mi);
1765 var tw = classLoader.LoadClassByName(m.Redirect.
Class);
1766 var mw = tw.GetMethod(redirName, redirSig,
false) ??
throw new InvalidOperationException(
"Missing redirect method: " + tw.Name +
"." + redirName + redirSig);
1775 if (parameters !=
null)
1777 for (
int i = 0; i < parameters.Length; i++)
1779 ParameterBuilder pb = mb.DefineParameter(i + 1, ParameterAttributes.None, parameters[i].Name);
1780 if (parameters[i].Attributes !=
null)
1782 for (
int j = 0; j < parameters[i].Attributes.Length; j++)
1791 internal void Process2ndPassStep1()
1793 if (!shadowType.IsSealed)
1795 foreach (var ifaceTypeWrapper
in interfaceWrappers)
1797 typeBuilder.AddInterfaceImplementation(ifaceTypeWrapper.TypeAsBaseType);
1800 Context.AttributeHelper.SetImplementsAttribute(typeBuilder, interfaceWrappers);
1806 var tb = typeBuilder;
1808 var fields =
new List<RuntimeJavaField>();
1811 if (c.Fields !=
null)
1816 FieldAttributes attr = MapFieldAccessModifiers(f.
Modifiers);
1817 if (f.Constant !=
null)
1819 attr |= FieldAttributes.Literal;
1823 attr |= FieldAttributes.InitOnly;
1827 attr |= FieldAttributes.Static;
1829 FieldBuilder fb = tb.DefineField(f.Name, ClassLoader.FieldTypeWrapperFromSig(f.Sig,
LoadMode.LoadOrThrow).TypeAsSignatureType, attr);
1830 if (f.Attributes !=
null)
1834 Context.AttributeHelper.SetCustomAttribute(classLoader, fb, custattr);
1838 if (f.Constant !=
null)
1843 constant =
long.Parse(f.Constant);
1847 throw new NotImplementedException(
"remapped constant field of type: " + f.Sig);
1849 fb.SetConstant(constant);
1859 SetFields(fields.ToArray());
1862 internal void Process3rdPass()
1864 foreach (RemappedMethodBaseWrapper m
in GetMethods())
1870 internal void Process4thPass(ICollection<RemapperTypeWrapper> remappedTypes)
1872 foreach (RemappedMethodBaseWrapper m
in GetMethods())
1877 if (classDef.Clinit !=
null)
1879 MethodBuilder cb =
ReflectUtil.DefineTypeInitializer(typeBuilder, classLoader);
1880 CodeEmitter ilgen = Context.CodeEmitterFactory.Create(cb);
1882 classDef.Clinit.Body.Emit(classLoader, ilgen);
1888 if (classDef.Interfaces !=
null)
1892 ClassLoader.LoadClassByName(iface.Class).Finish();
1896 CreateShadowInstanceOf(remappedTypes);
1897 CreateShadowCheckCast(remappedTypes);
1899 if (!shadowType.IsInterface)
1904 var methods =
new Dictionary<string, MethodBuilder>();
1905 foreach (var mw
in GetMethods())
1907 var mb = mw.GetMethod() as MethodBuilder;
1909 methods.Add(MakeMethodKey(mb), mb);
1912 foreach (var mi
in typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy))
1914 string key = MakeMethodKey(mi);
1915 if (!methods.ContainsKey(key))
1917 ParameterInfo[] paramInfo = mi.GetParameters();
1918 Type[] paramTypes =
new Type[paramInfo.Length];
1919 for (
int i = 0; i < paramInfo.Length; i++)
1921 paramTypes[i] = paramInfo[i].ParameterType;
1923 MethodBuilder mb = typeBuilder.DefineMethod(mi.Name, mi.Attributes & (MethodAttributes.MemberAccessMask | MethodAttributes.SpecialName | MethodAttributes.Static), mi.ReturnType, paramTypes);
1924 Context.AttributeHelper.HideFromJava(mb);
1925 Context.AttributeHelper.SetEditorBrowsableNever(mb);
1926 CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb);
1927 for (
int i = 0; i < paramTypes.Length; i++)
1933 ilgen.EmitLdarg(paramTypes.Length);
1934 ilgen.Emit(OpCodes.Callvirt, mi);
1938 ilgen.Emit(OpCodes.Call, mi);
1940 ilgen.Emit(OpCodes.Ret);
1946 foreach (var pi
in typeBuilder.BaseType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
1948 ParameterInfo[] paramInfo = pi.GetIndexParameters();
1949 Type[] paramTypes =
new Type[paramInfo.Length];
1950 for (
int i = 0; i < paramInfo.Length; i++)
1952 paramTypes[i] = paramInfo[i].ParameterType;
1954 PropertyBuilder pb = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.None, pi.PropertyType, paramTypes);
1955 if (pi.GetGetMethod() !=
null)
1957 pb.SetGetMethod(methods[MakeMethodKey(pi.GetGetMethod())]);
1959 if (pi.GetSetMethod() !=
null)
1961 pb.SetSetMethod(methods[MakeMethodKey(pi.GetSetMethod())]);
1963 Context.AttributeHelper.SetEditorBrowsableNever(pb);
1967 typeBuilder.CreateType();
1968 if (helperTypeBuilder !=
null)
1969 helperTypeBuilder.CreateType();
1972 static string MakeMethodKey(MethodInfo method)
1974 var sb =
new ValueStringBuilder(method.ReturnType.AssemblyQualifiedName.Length + 1 + method.Name.Length);
1975 sb.Append(method.ReturnType.AssemblyQualifiedName);
1977 sb.Append(method.Name);
1979 var paramInfo = method.GetParameters();
1980 for (
int i = 0; i < paramInfo.Length; i++)
1983 sb.Append(paramInfo[i].ParameterType.AssemblyQualifiedName);
1986 return sb.ToString();
1989 void CreateShadowInstanceOf(ICollection<RemapperTypeWrapper> remappedTypes)
1992 if (typeBuilder.IsInterface)
1995 var attr = MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static;
1996 var mb = typeBuilder.DefineMethod(
"__<instanceof>", attr, Context.Types.Boolean, [Context.Types.Object]);
1997 Context.AttributeHelper.HideFromJava(mb);
1998 Context.AttributeHelper.SetEditorBrowsableNever(mb);
1999 var ilgen = Context.CodeEmitterFactory.Create(mb);
2001 ilgen.Emit(OpCodes.Ldarg_0);
2002 ilgen.Emit(OpCodes.Isinst, shadowType);
2003 var retFalse = ilgen.DefineLabel();
2004 ilgen.EmitBrfalse(retFalse);
2006 if (!shadowType.IsSealed)
2008 ilgen.Emit(OpCodes.Ldarg_0);
2009 ilgen.Emit(OpCodes.Isinst, typeBuilder);
2010 ilgen.EmitBrtrue(retFalse);
2013 if (shadowType == Context.Types.Object)
2015 ilgen.Emit(OpCodes.Ldarg_0);
2016 ilgen.Emit(OpCodes.Isinst, Context.Types.Array);
2017 ilgen.EmitBrtrue(retFalse);
2020 foreach (RemapperTypeWrapper r
in remappedTypes)
2022 if (!r.shadowType.IsInterface && r.shadowType.IsSubclassOf(shadowType))
2024 ilgen.Emit(OpCodes.Ldarg_0);
2025 ilgen.Emit(OpCodes.Isinst, r.shadowType);
2026 ilgen.EmitBrtrue(retFalse);
2029 ilgen.Emit(OpCodes.Ldc_I4_1);
2030 ilgen.Emit(OpCodes.Ret);
2032 ilgen.MarkLabel(retFalse);
2033 ilgen.Emit(OpCodes.Ldc_I4_0);
2034 ilgen.Emit(OpCodes.Ret);
2039 private void CreateShadowCheckCast(ICollection<RemapperTypeWrapper> remappedTypes)
2042 if (typeBuilder.IsInterface)
2046 MethodAttributes attr = MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static;
2047 MethodBuilder mb = typeBuilder.DefineMethod(
"__<checkcast>", attr, shadowType,
new Type[] { Context.Types.Object });
2048 Context.AttributeHelper.HideFromJava(mb);
2049 Context.AttributeHelper.SetEditorBrowsableNever(mb);
2050 CodeEmitter ilgen = Context.CodeEmitterFactory.Create(mb);
2053 bool hasfail =
false;
2055 if (!shadowType.IsSealed)
2057 ilgen.Emit(OpCodes.Ldarg_0);
2058 ilgen.Emit(OpCodes.Isinst, typeBuilder);
2059 ilgen.EmitBrtrue(fail);
2063 if (shadowType == Context.Types.Object)
2065 ilgen.Emit(OpCodes.Ldarg_0);
2066 ilgen.Emit(OpCodes.Isinst, Context.Types.Array);
2067 ilgen.EmitBrtrue(fail);
2071 foreach (RemapperTypeWrapper r
in remappedTypes)
2073 if (!r.shadowType.IsInterface && r.shadowType.IsSubclassOf(shadowType))
2075 ilgen.Emit(OpCodes.Ldarg_0);
2076 ilgen.Emit(OpCodes.Isinst, r.shadowType);
2077 ilgen.EmitBrtrue(fail);
2081 ilgen.Emit(OpCodes.Ldarg_0);
2082 ilgen.EmitCastclass(shadowType);
2083 ilgen.Emit(OpCodes.Ret);
2087 ilgen.MarkLabel(fail);
2088 ilgen.ThrowException(Context.Resolver.ResolveCoreType(typeof(InvalidCastException).FullName).AsReflection());
2096 return ((RemappedMethodBaseWrapper)mw).DoLink();
2099 internal override RuntimeJavaType[] Interfaces
2103 return interfaceWrappers;
2107 internal override Type TypeAsTBD
2115 internal override Type TypeAsBaseType
2123 internal override bool IsMapUnsafeException
2128 return shadowType == Context.Types.Exception || shadowType.IsSubclassOf(Context.Types.Exception);
2132 internal override bool IsFastClassLiteralSafe
2134 get {
return true; }
2142 string[] exceptions =
new string[
throws.Length];
2143 for (
int i = 0; i < exceptions.Length; i++)
2145 exceptions[i] =
throws[i].Class;
2151 internal void EmitRemappedTypes()
2153 Diagnostics.GenericCompilerInfo(
"Emit remapped types");
2155 assemblyAttributes = map.Assembly.Attributes;
2157 if (map.Assembly.Classes !=
null)
2160 bool hasRemappedTypes =
false;
2163 if (c.Shadows !=
null)
2165 if (classes.ContainsKey(c.Name))
2167 Diagnostics.DuplicateClassName(c.Name);
2170 remapped.Add(c.Name,
new RemapperTypeWrapper(Context,
this, c, map));
2171 hasRemappedTypes =
true;
2175 if (hasRemappedTypes)
2180 if (c.Shadows !=
null)
2182 remapped[c.Name].LoadInterfaces(c);
2189 internal void EmitRemappedTypes2ndPass()
2191 if (map !=
null && map.Assembly !=
null && map.Assembly.Classes !=
null)
2196 if (c.Shadows !=
null)
2198 RemapperTypeWrapper typeWrapper = remapped[c.Name];
2199 typeWrapper.Process2ndPassStep1();
2204 if (c.Shadows !=
null)
2206 RemapperTypeWrapper typeWrapper = remapped[c.Name];
2207 typeWrapper.Process2ndPassStep2(map);
2213 internal bool IsMapUnsafeException(RuntimeJavaType tw)
2215 if (mappedExceptions !=
null)
2216 for (
int i = 0; i < mappedExceptions.Length; i++)
2217 if (mappedExceptions[i].IsSubTypeOf(tw) || (mappedExceptionsAllSubClasses[i] && tw.IsSubTypeOf(mappedExceptions[i])))
2223 internal void LoadMappedExceptions(MapXml.Root map)
2225 if (map.ExceptionMappings.Length > 0)
2227 mappedExceptionsAllSubClasses =
new bool[map.ExceptionMappings.Length];
2228 mappedExceptions =
new RuntimeJavaType[map.ExceptionMappings.Length];
2229 for (
int i = 0; i < mappedExceptions.Length; i++)
2234 mappedExceptionsAllSubClasses[i] =
true;
2235 dst = dst.Substring(1);
2238 mappedExceptions[i] = LoadClassByName(dst);
2242 foreach (var c
in map.Assembly.Classes)
2243 foreach (var m
in c.Methods)
2245 foreach (var instr
in m.Body.Instructions)
2246 if (instr is MapXml.EmitExceptionMapping eem)
2247 eem.mapping = map.ExceptionMappings;
2251 internal sealed class ExceptionMapEmitter
2255 readonly MapXml.ExceptionMapping[] map;
2262 internal ExceptionMapEmitter(
RuntimeContext context, MapXml.ExceptionMapping[] map)
2264 this.rcontext = context;
2268 internal void Emit(MapXml.CodeGenContext context,
CodeEmitter ilgen)
2270 var mwSuppressFillInStackTrace = rcontext.JavaBase.TypeOfjavaLangThrowable.GetMethod(
"__<suppressFillInStackTrace>",
"()V",
false);
2271 mwSuppressFillInStackTrace.Link();
2272 ilgen.Emit(OpCodes.Ldarg_0);
2273 ilgen.Emit(OpCodes.Callvirt, rcontext.CompilerFactory.GetTypeMethod);
2275 for (
int i = 0; i < map.Length; i++)
2277 ilgen.Emit(OpCodes.Dup);
2278 ilgen.Emit(OpCodes.Ldtoken, rcontext.Resolver.ResolveCoreType(map[i].Source).AsReflection());
2279 ilgen.Emit(OpCodes.Call, rcontext.CompilerFactory.GetTypeFromHandleMethod);
2280 ilgen.Emit(OpCodes.Ceq);
2281 var label = ilgen.DefineLabel();
2282 ilgen.EmitBrfalse(label);
2283 ilgen.Emit(OpCodes.Pop);
2284 if (map[i].
Code !=
null)
2286 ilgen.Emit(OpCodes.Ldarg_0);
2288 if (map[i].
Code.Instructions.Length > 0)
2290 foreach (var instr
in map[i].
Code.Instructions)
2292 var newobj = instr as MapXml.NewObj;
2293 if (newobj !=
null && newobj.Class !=
null && context.ClassLoader.LoadClassByName(newobj.Class).IsSubTypeOf(rcontext.JavaBase.TypeOfjavaLangThrowable))
2294 mwSuppressFillInStackTrace.EmitCall(ilgen);
2296 instr.Generate(context, ilgen);
2300 ilgen.Emit(OpCodes.Ret);
2304 var tw = context.ClassLoader.LoadClassByName(map[i].Destination);
2305 var mw = tw.GetMethod(
"<init>",
"()V",
false);
2307 mwSuppressFillInStackTrace.EmitCall(ilgen);
2308 mw.EmitNewobj(ilgen);
2309 ilgen.Emit(OpCodes.Ret);
2312 ilgen.MarkLabel(label);
2315 ilgen.Emit(OpCodes.Pop);
2316 ilgen.Emit(OpCodes.Ldarg_0);
2317 ilgen.Emit(OpCodes.Ret);
2321 internal void LoadMapXml()
2323 if (map.Assembly.Classes.Length > 0)
2325 mapxml_Classes =
new Dictionary<string, MapXml.Class>();
2326 mapxml_MethodBodies =
new Dictionary<
MethodKey, MapXml.InstructionList>();
2327 mapxml_ReplacedMethods =
new Dictionary<
MethodKey, MapXml.ReplaceMethodCall[]>();
2328 mapxml_MethodPrologues =
new Dictionary<
MethodKey, MapXml.InstructionList>();
2330 foreach (var c
in map.Assembly.Classes)
2333 if (c.Shadows ==
null)
2335 string className = c.Name;
2336 mapxml_Classes.Add(className, c);
2337 AddMapXmlMethods(className, c.Constructors);
2338 AddMapXmlMethods(className, c.Methods);
2339 if (c.Clinit !=
null)
2340 AddMapXmlMethod(className, c.Clinit);
2346 private void AddMapXmlMethods(
string className, MapXml.MethodBase[] methods)
2348 if (methods !=
null)
2349 foreach (var method
in methods)
2350 AddMapXmlMethod(className, method);
2353 private void AddMapXmlMethod(
string className, MapXml.MethodBase method)
2355 if (method.Body !=
null)
2356 mapxml_MethodBodies.Add(method.ToMethodKey(className), method.Body);
2358 if (method.ReplaceMethodCalls.Length > 0)
2359 mapxml_ReplacedMethods.Add(method.ToMethodKey(className), method.ReplaceMethodCalls);
2361 if (method.Prologue !=
null)
2362 mapxml_MethodPrologues.Add(method.ToMethodKey(className), method.Prologue);
2365 internal MapXml.InstructionList GetMethodPrologue(
MethodKey method)
2367 if (mapxml_MethodPrologues ==
null)
2370 mapxml_MethodPrologues.TryGetValue(method, out var prologue);
2376 if (mapxml_ReplacedMethods ==
null)
2379 mapxml_ReplacedMethods.TryGetValue(
new MethodKey(mw.DeclaringType.Name, mw.Name, mw.Signature), out var rmc);
2383 internal Dictionary<string, MapXml.Class> GetMapXmlClasses()
2385 return mapxml_Classes;
2388 internal Dictionary<
MethodKey, MapXml.InstructionList> GetMapXmlMethodBodies()
2390 return mapxml_MethodBodies;
2393 internal MapXml.Parameter[] GetXmlMapParameters(
string classname,
string method,
string sig)
2395 if (mapxml_Classes !=
null)
2397 if (mapxml_Classes.TryGetValue(classname, out var clazz))
2399 if (method ==
"<init>" && clazz.Constructors.Length > 0)
2401 for (
int i = 0; i < clazz.Constructors.Length; i++)
2402 if (clazz.Constructors[i].Sig == sig)
2403 return clazz.Constructors[i].Parameters;
2405 else if (clazz.Methods.Length > 0)
2407 for (
int i = 0; i < clazz.Methods.Length; i++)
2408 if (clazz.Methods[i].Name == method && clazz.Methods[i].Sig == sig)
2409 return clazz.Methods[i].Parameters;
2417 internal bool IsGhost(RuntimeJavaType tw)
2419 return ghosts !=
null && tw.IsInterface && ghosts.ContainsKey(tw.Name);
2422 void SetupGhosts(MapXml.Root map)
2424 ghosts =
new Dictionary<string, List<RuntimeJavaType>>();
2427 foreach (var c
in map.Assembly.Classes)
2429 if (c.Shadows !=
null && c.Interfaces.Length > 0)
2433 var typeWrapper = FindLoadedClass(c.Name);
2435 foreach (var iface
in c.Interfaces)
2437 var ifaceWrapper = FindLoadedClass(iface.Class);
2438 if (ifaceWrapper ==
null || !ifaceWrapper.TypeAsTBD.IsAssignableFrom(typeWrapper.TypeAsTBD))
2439 AddGhost(iface.Class, typeWrapper);
2445 var array = Context.ClassLoaderFactory.GetJavaTypeFromType(Context.Types.Array);
2446 AddGhost(
"java.io.Serializable", array);
2447 AddGhost(
"java.lang.Cloneable", array);
2450 private void AddGhost(
string interfaceName, RuntimeJavaType implementer)
2452 if (!ghosts.TryGetValue(interfaceName, out var list))
2454 list =
new List<RuntimeJavaType>();
2455 ghosts[interfaceName] = list;
2458 list.Add(implementer);
2461 internal RuntimeJavaType[] GetGhostImplementers(RuntimeJavaType wrapper)
2463 return ghosts.TryGetValue(wrapper.Name, out var list) ? list.ToArray() : Array.Empty<RuntimeJavaType>();
2466 internal void FinishRemappedTypes()
2471 foreach (var typeWrapper
in remapped.Values)
2472 typeWrapper.Process3rdPass();
2475 foreach (var typeWrapper
in remapped.Values)
2476 typeWrapper.Process4thPass(remapped.Values);
2478 if (assemblyAttributes !=
null)
2479 foreach (MapXml.Attribute attr in assemblyAttributes)
2480 Context.AttributeHelper.SetCustomAttribute(
this, assemblyBuilder, attr);
2483 private static bool IsSigned(Assembly
asm)
2485 byte[] key =
asm.GetName().GetPublicKey();
2486 return key !=
null && key.Length != 0;
2489 internal static int Compile(ImportContext importer,
RuntimeContext context, StaticCompiler compiler,
IDiagnosticHandler diagnostics,
string runtimeAssembly, List<ImportState> optionsList)
2493 compiler.runtimeAssembly = compiler.LoadFile(runtimeAssembly ?? Path.Combine(Path.GetDirectoryName(typeof(ImportClassLoader).Assembly.Location),
"IKVM.Runtime.dll"));
2495 catch (FileNotFoundException)
2498 if (compiler.runtimeAssembly ==
null)
2505 diagnostics.
GenericCompilerInfo($
"Loaded runtime assembly: {compiler.runtimeAssembly.FullName}");
2507 var loaders =
new List<ImportClassLoader>();
2508 foreach (var options
in optionsList)
2510 int rc = CreateCompiler(context, compiler, diagnostics, options, out var loader);
2514 loaders.Add(loader);
2515 options.sharedclassloader?.Add(loader);
2518 foreach (var loader1
in loaders)
2519 foreach (var loader2
in loaders)
2520 if (loader1 != loader2 && (loader1.state.crossReferenceAllPeers || (loader1.state.peerReferences !=
null && Array.IndexOf(loader1.state.peerReferences, loader2.state.assembly) != -1)))
2521 loader1.AddReference(loader2);
2523 foreach (var loader
in loaders)
2524 loader.CompilePass0();
2526 var mainAssemblyTypes =
new Dictionary<ImportClassLoader, Type>();
2527 foreach (var loader
in loaders)
2529 if (loader.state.sharedclassloader !=
null)
2531 if (!mainAssemblyTypes.TryGetValue(loader.state.sharedclassloader[0], out var mainAssemblyType))
2533 var tb = loader.state.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType(
"__<MainAssembly>", TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.SpecialName);
2534 loader.Context.AttributeHelper.HideFromJava(tb);
2535 mainAssemblyType = tb.CreateType();
2536 mainAssemblyTypes.Add(loader.state.sharedclassloader[0], mainAssemblyType);
2538 if (loader.state.sharedclassloader[0] != loader)
2540 ((AssemblyBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).__AddTypeForwarder(mainAssemblyType);
2544 loader.CompilePass1();
2547 foreach (var loader
in loaders)
2549 loader.CompilePass2();
2553 foreach (var loader
in loaders)
2554 loader.EmitRemappedTypes2ndPass();
2556 foreach (var loader
in loaders)
2558 int rc = loader.CompilePass3();
2565 foreach (var loader
in loaders)
2566 loader.PrepareSave();
2568 if (compiler.errorCount > 0)
2571 foreach (ImportClassLoader loader
in loaders)
2574 return compiler.errorCount == 0 ? 0 : 1;
2577 static int CreateCompiler(
RuntimeContext context, StaticCompiler compiler,
IDiagnosticHandler diagnostics, ImportState options, out ImportClassLoader loader)
2579 diagnostics.
GenericCompilerInfo($
"JVM.Compile path: {options.path}, assembly: {options.assembly}");
2581 AssemblyName runtimeAssemblyName = compiler.runtimeAssembly.GetName();
2582 bool allReferencesAreStrongNamed = IsSigned(compiler.runtimeAssembly);
2583 List<Assembly> references =
new List<Assembly>();
2584 foreach (Assembly reference
in options.references ??
new Assembly[0])
2586 references.Add(reference);
2587 allReferencesAreStrongNamed &= IsSigned(reference);
2592 foreach (AssemblyName asmref
in reference.GetReferencedAssemblies())
2594 if (asmref.Name == runtimeAssemblyName.Name)
2596 if (IsSigned(compiler.runtimeAssembly))
2599 if (asmref.FullName != runtimeAssemblyName.FullName)
2606 if (asmref.GetPublicKeyToken() !=
null && asmref.GetPublicKeyToken().Length != 0)
2618 Dictionary<string, Jar.Item> h =
new Dictionary<string, Jar.Item>();
2619 List<string> classNames =
new List<string>();
2620 foreach (Jar jar
in options.jars)
2622 if (options.IsResourcesJar(jar))
2626 foreach (Jar.Item item in jar)
2628 string name = item.Name;
2629 if (name.EndsWith(
".class", StringComparison.Ordinal)
2631 && name.IndexOf(
'.') == name.Length - 6)
2633 string className = name.Substring(0, name.Length - 6).Replace(
'/',
'.');
2634 if (h.ContainsKey(className))
2637 Jar.Item itemRef = h[className];
2638 if ((options.classesJar != -1 && itemRef.Jar == options.jars[options.classesJar]) || jar != itemRef.Jar)
2647 h.Remove(className);
2648 classNames.Remove(className);
2651 h.Add(className, item);
2652 classNames.Add(className);
2657 if (options.assemblyAttributeAnnotations ==
null)
2660 if (h.TryGetValue(
"assembly", out var assemblyType))
2668 if (f.Name ==
"assembly" && f.Annotations !=
null)
2670 options.assemblyAttributeAnnotations = f.Annotations;
2673 assemblyType.Remove();
2677 catch (ByteCodeException)
2689 if (options.mainClass ==
null && (options.guessFileKind || options.target != PEFileKinds.Dll))
2691 foreach (
string className
in classNames)
2696 if (f.Name == className)
2698 foreach (var m
in f.Methods)
2700 if (m.IsPublic && m.IsStatic && m.Name ==
"main" && m.Signature ==
"([Ljava.lang.String;)V")
2703 options.mainClass = f.Name;
2717 if (options.guessFileKind && options.mainClass ==
null)
2719 options.target = PEFileKinds.Dll;
2722 if (options.target != PEFileKinds.Dll && options.mainClass ==
null)
2727 if (options.target == PEFileKinds.Dll && options.props.Count != 0)
2732 if (options.path ==
null)
2734 if (options.target == PEFileKinds.Dll)
2736 if (options.targetIsModule)
2738 options.path = ImportContext.GetFileInfo(options.assembly +
".netmodule");
2742 options.path = ImportContext.GetFileInfo(options.assembly +
".dll");
2747 options.path = ImportContext.GetFileInfo(options.assembly +
".exe");
2753 if (options.targetIsModule)
2755 if (options.classLoader !=
null)
2760 options.assembly = options.path.Name;
2764 var referencedAssemblies =
new List<RuntimeAssemblyClassLoader>(references.Count);
2765 for (
int i = 0; i < references.Count; i++)
2768 if (compiler.baseAssembly ==
null && options.bootstrap ==
false && IsBaseAssembly(context, references[i]))
2769 compiler.baseAssembly = references[i];
2772 if (referencedAssemblies.Contains(acl))
2775 referencedAssemblies.Add(acl);
2778 loader =
new ImportClassLoader(context, compiler, diagnostics, referencedAssemblies.ToArray(), options, options.path, options.targetIsModule, options.assembly, h);
2779 loader.classesToCompile =
new List<string>(h.Keys);
2780 if (options.remapfile !=
null)
2789 fs =
new FileStream(options.remapfile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
2802 map =
new MapXml.MapXmlSerializer().Read(XDocument.Load(fs, LoadOptions.SetLineInfo));
2804 catch (MapXml.MapXmlException x)
2809 if (loader.ValidateAndSetMap(map) ==
false)
2817 if (options.bootstrap)
2823 if (compiler.baseAssembly ==
null && options.bootstrap ==
false)
2825 foreach (var name
in compiler.runtimeAssembly.GetReferencedAssemblies())
2827 Assembly
asm =
null;
2831 var path = Path.Combine(Path.GetDirectoryName(compiler.runtimeAssembly.Location), name.Name +
".dll");
2832 if (File.Exists(path))
2833 asm = LoadReferencedAssembly(compiler, path);
2835 catch (FileNotFoundException)
2840 if (
asm !=
null && IsBaseAssembly(context,
asm))
2842 RuntimeAssemblyClassLoader.PreloadExportedAssemblies(context.StaticCompiler,
asm);
2843 compiler.baseAssembly =
asm;
2848 if (compiler.baseAssembly ==
null)
2857 if (options.bootstrap ==
false)
2859 allReferencesAreStrongNamed &= IsSigned(context.
Resolver.ResolveBaseAssembly().AsReflection());
2863 if ((options.keyPair !=
null || options.publicKey !=
null) && !allReferencesAreStrongNamed)
2868 if (loader.map !=
null)
2870 loader.LoadMapXml();
2873 if (options.bootstrap ==
false)
2875 loader.fakeTypes = context.FakeTypes;
2876 loader.fakeTypes.Load(context.
Resolver.ResolveBaseAssembly().AsReflection());
2887 private static Assembly LoadReferencedAssembly(StaticCompiler compiler,
string r)
2889 Assembly
asm = compiler.LoadFile(r);
2893 private void CompilePass0()
2895 if (state.sharedclassloader !=
null && state.sharedclassloader[0] !=
this)
2897 packages = state.sharedclassloader[0].packages;
2901 packages =
new Packages();
2907 Diagnostics.GenericCompilerInfo(
"Compiling class files (1)");
2908 if (state.bootstrap)
2909 EmitRemappedTypes();
2914 if (state.bootstrap)
2917 fakeTypes.Create(GetTypeWrapperFactory().ModuleBuilder,
this);
2920 javaTypes =
new List<RuntimeJavaType>();
2922 foreach (var s
in classesToCompile)
2924 var javaType = TryLoadClassByName(s);
2925 if (javaType !=
null)
2927 var loader = javaType.ClassLoader;
2930 if (loader is RuntimeAssemblyClassLoader)
2931 Diagnostics.SkippingReferencedClass(s, ((RuntimeAssemblyClassLoader)loader).GetAssembly(javaType).FullName);
2936 if (state.sharedclassloader !=
null && state.sharedclassloader[0] !=
this)
2937 state.sharedclassloader[0].dynamicallyImportedTypes.Add(javaType);
2939 javaTypes.Add(javaType);
2946 Diagnostics.GenericCompilerInfo(
"Compiling class files (2)");
2948 foreach (var javaTypes
in javaTypes)
2958 Diagnostics.GenericCompilerInfo(
"Compiling class files (3)");
2961 var moduleInitBuilders =
new List<Action<MethodBuilder, CodeEmitter>>();
2964 if (map !=
null && state.bootstrap)
2966 fakeTypes.Finish(
this);
2970 foreach (
string proxy
in state.proxies)
2972 Context.ProxyGenerator.Create(
this, proxy);
2976 if (state.mainClass !=
null)
2978 RuntimeJavaType wrapper =
null;
2982 wrapper = TryLoadClassByName(state.mainClass);
2987 if (wrapper ==
null)
2992 var mw = wrapper.GetMethod(
"main",
"([Ljava.lang.String;)V",
false);
2993 if (mw ==
null || !mw.IsStatic)
3002 if (!
ReflectUtil.IsFromAssembly(method.DeclaringType, assemblyBuilder) && (!method.IsPublic || !method.DeclaringType.IsPublic))
3007 var apartmentAttributeType = state.apartment
switch
3009 ApartmentState.STA => Context.Resolver.ResolveCoreType(typeof(STAThreadAttribute).FullName),
3010 ApartmentState.MTA => Context.Resolver.ResolveCoreType(typeof(MTAThreadAttribute).FullName),
3011 ApartmentState.Unknown =>
null,
3012 _ =>
throw new NotImplementedException(),
3015 SetMain(wrapper, state.target, state.props, state.noglobbing, apartmentAttributeType.AsReflection());
3021 LoadMappedExceptions(map);
3022 Diagnostics.GenericCompilerInfo(
"Loading remapped types (2)");
3026 FinishRemappedTypes();
3030 Context.StaticCompiler.IssueMissingTypeMessage((Type)x.MemberInfo);
3035 Diagnostics.GenericCompilerInfo(
"Compiling class files (2)");
3039 if (state.externalResources !=
null)
3040 foreach (KeyValuePair<string, string> kv
in state.externalResources)
3041 assemblyBuilder.AddResourceFile(
JVM.MangleResourceName(kv.Key), kv.Value);
3044 if (state.fileversion !=
null)
3046 var filever =
new CustomAttributeBuilder(Context.Resolver.ResolveCoreType(typeof(
System.Reflection.AssemblyFileVersionAttribute).FullName).AsReflection().GetConstructor([Context.Types.String]), [state.fileversion]);
3047 assemblyBuilder.SetCustomAttribute(filever);
3051 if (state.assemblyAttributeAnnotations !=
null)
3053 foreach (
object[] def
in state.assemblyAttributeAnnotations)
3056 if (annotation !=
null)
3057 annotation.Apply(
this, assemblyBuilder, def);
3062 if (state.classLoader !=
null)
3064 RuntimeJavaType classLoaderType =
null;
3067 classLoaderType = TryLoadClassByName(state.classLoader);
3074 if (classLoaderType ==
null)
3077 if (classLoaderType.IsPublic ==
false &&
ReflectUtil.IsFromAssembly(classLoaderType.TypeAsBaseType, assemblyBuilder) ==
false)
3080 if (classLoaderType.IsAbstract)
3083 if (classLoaderType.IsAssignableTo(Context.ClassLoaderFactory.LoadClassCritical(
"java.lang.ClassLoader")) ==
false)
3086 var classLoaderInitMethod = classLoaderType.GetMethod(
"<init>",
"(Lcli.System.Reflection.Assembly;)V",
false);
3087 if (classLoaderInitMethod ==
null)
3091 var ci = Context.Resolver.ResolveRuntimeType(typeof(
CustomAssemblyClassLoaderAttribute).FullName).AsReflection().GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null,
new[] { Context.Types.Type },
null);
3092 assemblyBuilder.SetCustomAttribute(
new CustomAttributeBuilder(ci,
new object[] { classLoaderType.TypeAsTBD }));
3095 var mwModuleInit = classLoaderType.GetMethod(
"InitializeModule",
"(Lcli.System.Reflection.Module;)V",
false);
3096 if (mwModuleInit !=
null && mwModuleInit.IsStatic ==
false)
3098 moduleInitBuilders.Add((mb, il) =>
3100 il.Emit(OpCodes.Ldtoken, mb);
3101 il.Emit(OpCodes.Call, Context.Resolver.ResolveCoreType(typeof(
System.Reflection.MethodBase).FullName).GetMethod(
"GetMethodFromHandle",
new[] { Context.Resolver.ResolveCoreType(typeof(RuntimeMethodHandle).FullName) }).AsReflection());
3102 il.Emit(OpCodes.Callvirt, Context.Resolver.ResolveCoreType(typeof(
System.Reflection.MemberInfo).FullName).GetProperty(
"Module").GetGetMethod().AsReflection());
3103 il.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(
"IKVM.Runtime.ByteCodeHelper").GetMethod(
"InitializeModule").AsReflection());
3108 if (state.iconfile !=
null)
3110 assemblyBuilder.__DefineIconResource(ImportContext.ReadAllBytes(state.iconfile));
3113 if (state.manifestFile !=
null)
3115 assemblyBuilder.__DefineManifestResource(ImportContext.ReadAllBytes(state.manifestFile));
3118 assemblyBuilder.DefineVersionInfoResource();
3121 foreach (var modInitMethod
in javaTypes.SelectMany(i => i.GetMethods()).Where(i => i.IsModuleInitializer))
3123 var modInitMethod_ = modInitMethod;
3124 moduleInitBuilders.Add((mb, il) => { modInitMethod_.Link(); modInitMethod_.EmitCall(il); });
3128 if (moduleInitBuilders.Count > 0)
3131 var moduleInit = GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod(
".cctor", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
null, Type.EmptyTypes);
3132 var moduleInitIL = Context.CodeEmitterFactory.Create(moduleInit);
3135 foreach (var moduleInitBuilder
in moduleInitBuilders)
3136 moduleInitBuilder(moduleInit, moduleInitIL);
3139 moduleInitIL.Emit(OpCodes.Ret);
3140 moduleInitIL.DoEmit();
3149 if (map.Assembly !=
null)
3151 if (map.Assembly.Classes !=
null)
3155 if (c.Fields !=
null)
3159 ValidateNameSig(
"field", c.Name, f.Name, f.Sig,
ref valid,
true);
3162 if (c.Methods !=
null)
3166 ValidateNameSig(
"method", c.Name, m.Name, m.Sig,
ref valid,
false);
3169 if (c.Constructors !=
null)
3173 ValidateNameSig(
"constructor", c.Name,
"<init>", ctor.Sig,
ref valid,
false);
3176 if (c.Properties !=
null)
3180 ValidateNameSig(
"property", c.Name, prop.Name, prop.Sig,
ref valid,
false);
3181 ValidatePropertyGetterSetter(
"getter", c.Name, prop.Name, prop.Getter,
ref valid);
3182 ValidatePropertyGetterSetter(
"setter", c.Name, prop.Name, prop.Setter,
ref valid);
3192 private void ValidateNameSig(
string member,
string clazz,
string name,
string sig,
ref bool valid,
bool field)
3194 if (!IsValidName(name))
3197 Diagnostics.InvalidMemberNameInMapFile(member, name, clazz);
3199 if (!IsValidSig(sig, field))
3202 Diagnostics.InvalidMemberSignatureInMapFile(member, clazz, name, sig);
3210 if (!IsValidName(method.Name))
3213 Diagnostics.InvalidPropertyNameInMapFile(getterOrSetter, clazz, property, method.Name);
3218 Diagnostics.InvalidPropertySignatureInMapFile(getterOrSetter, clazz, property, method.Sig);
3223 static bool IsValidName(
string name)
3225 return name !=
null && name.Length != 0;
3228 static bool IsValidSig(
string sig,
bool field)
3233 internal Type GetTypeFromReferencedAssembly(
string name)
3235 foreach (RuntimeAssemblyClassLoader acl
in referencedAssemblies)
3237 Type type = acl.MainAssembly.GetType(name,
false);
3246 internal override bool WarningLevelHigh
3248 get {
return state.warningLevelHigh; }
3251 internal override bool NoParameterReflection
3253 get {
return state.noParameterReflection; }
3258 if (!state.bootstrap)
3260 base.CheckProhibitedPackage(className);