25using System.Collections.Generic;
26using System.Diagnostics;
27using System.Collections.Concurrent;
39using System.Reflection;
40using System.Reflection.Emit;
48 partial class RuntimeByteCodeJavaType
51 private sealed partial class JavaTypeImpl : DynamicImpl
54 readonly RuntimeJavaType host;
55 readonly ClassFile classFile;
57 TypeBuilder typeBuilder;
58 RuntimeJavaMethod[] methods;
59 RuntimeJavaMethod[][] baseMethods;
60 RuntimeJavaField[] fields;
61 FinishedTypeImpl finishedType;
62 bool finishInProgress;
63 MethodBuilder clinitMethod;
64 MethodBuilder finalizeMethod;
67 RuntimeByteCodeJavaType enclosingClassWrapper;
68 AnnotationBuilder annotationBuilder;
69 TypeBuilder enumBuilder;
70 TypeBuilder privateInterfaceMethods;
71 ConcurrentDictionary<string, RuntimeJavaType> nestedTypeNames;
74 internal JavaTypeImpl(RuntimeJavaType host, ClassFile f, RuntimeByteCodeJavaType wrapper)
76 wrapper.ClassLoader.Diagnostics.GenericCompilerInfo(
"constructing JavaTypeImpl for " + f.Name);
82 internal void CreateStep1()
85 var hasclinit = wrapper.BaseTypeWrapper ==
null ? false : wrapper.BaseTypeWrapper.HasStaticInitializer;
86 methods =
new RuntimeJavaMethod[classFile.Methods.Length];
87 baseMethods =
new RuntimeJavaMethod[classFile.Methods.Length][];
88 for (
int i = 0; i < methods.Length; i++)
91 var m = classFile.Methods[i];
92 if (m.IsClassInitializer)
95 if (IsSideEffectFreeStaticInitializerOrNoop(m, out var noop))
113 if (m.IsCallerSensitive && SupportsCallerID(m))
117 if (m.IsModuleInitializer)
121 if (wrapper.IsGhost && m.IsVirtual)
124 methods[i] =
new RuntimeGhostJavaMethod(wrapper, m.Name, m.Signature,
null,
null,
null,
null, m.Modifiers, flags);
126 else if (m.IsConstructor && wrapper.IsDelegate)
128 methods[i] =
new DelegateConstructorMethodWrapper(wrapper, m);
130 else if (classFile.IsInterface && !m.IsStatic && !m.IsPublic)
134 methods[i] =
new RuntimePrivateInterfaceJavaMethod(wrapper, m.Name, m.Signature,
null,
null,
null, m.Modifiers, flags);
136 else if (classFile.IsInterface && m.IsVirtual && !m.IsAbstract)
139 methods[i] =
new RuntimeDefaultInterfaceJavaMethod(wrapper, m.Name, m.Signature,
null,
null,
null,
null, m.Modifiers, flags);
143 if (!classFile.IsInterface && m.IsVirtual)
145 baseMethods[i] = FindBaseMethods(m, out var explicitOverride);
146 if (explicitOverride)
150 methods[i] =
new RuntimeTypicalJavaMethod(wrapper, m.Name, m.Signature,
null,
null,
null, m.Modifiers, flags);
155 wrapper.SetHasStaticInitializer();
157 if (!wrapper.IsInterface || wrapper.IsPublic)
159 var methodsArray =
new List<RuntimeJavaMethod>(methods);
160 var baseMethodsArray =
new List<RuntimeJavaMethod[]>(baseMethods);
161 AddMirandaMethods(methodsArray, baseMethodsArray, wrapper);
162 methods = methodsArray.ToArray();
163 baseMethods = baseMethodsArray.ToArray();
166 if (!wrapper.IsInterface)
167 AddDelegateInvokeStubs(wrapper,
ref methods);
169 wrapper.SetMethods(methods);
171 fields =
new RuntimeJavaField[classFile.Fields.Length];
172 for (
int i = 0; i < fields.Length; i++)
174 var fld = classFile.Fields[i];
175 if (fld.IsStaticFinalConstant)
177 RuntimeJavaType fieldType =
null;
179 fieldType = wrapper.Context.ClassLoaderFactory.GetBootstrapClassLoader().FieldTypeWrapperFromSig(fld.Signature,
LoadMode.LoadOrThrow);
181 fields[i] =
new RuntimeConstantJavaField(wrapper, fieldType, fld.Name, fld.Signature, fld.Modifiers,
null, fld.ConstantValue,
MemberFlags.None);
183 else if (fld.IsProperty)
185 fields[i] =
new RuntimeByteCodePropertyJavaField(wrapper, fld);
189 fields[i] = RuntimeJavaField.Create(wrapper,
null,
null, fld.Name, fld.Signature,
new ExModifiers(fld.Modifiers, fld.IsInternal));
193 wrapper.AddMapXmlFields(
ref fields);
195 wrapper.SetFields(fields);
200 bool SupportsCallerID(ClassFile.Method method)
202 if ((classFile.Name ==
"sun.reflect.Reflection" && method.Name ==
"getCallerClass") || (classFile.Name ==
"java.lang.SecurityManager" && method.Name ==
"checkMemberAccess"))
207 else if (method.IsStatic)
211 else if ((classFile.IsFinal || classFile.Name ==
"java.lang.Runtime" || classFile.Name ==
"java.io.ObjectStreamClass") && wrapper.BaseTypeWrapper.GetMethod(method.Name, method.Signature,
true) ==
null && !HasInterfaceMethod(wrapper, method.Name, method.Signature))
218 else if (RequiresDynamicReflectionCallerClass(classFile.Name, method.Name, method.Signature))
228 wrapper.ClassLoader.Diagnostics.CallerSensitiveOnUnsupportedMethod(classFile.Name, method.Name, method.Signature);
233 static bool HasInterfaceMethod(RuntimeJavaType tw,
string name,
string signature)
235 for (; tw !=
null; tw = tw.BaseTypeWrapper)
237 foreach (var iface
in tw.Interfaces)
239 if (iface.GetMethod(name, signature,
false) !=
null)
243 if (HasInterfaceMethod(iface, name, signature))
254 internal void CreateStep2()
257 if (typeBuilder !=
null)
268 var hasclinit = wrapper.HasStaticInitializer;
269 var mangledTypeName = wrapper.classLoader.GetTypeWrapperFactory().AllocMangledName(wrapper);
274 TypeAttributes typeAttribs = 0;
276 typeAttribs |= TypeAttributes.Abstract;
278 typeAttribs |= TypeAttributes.Sealed;
280 typeAttribs |= TypeAttributes.BeforeFieldInit;
283 bool cantNest =
false;
284 bool setModifiers =
false;
285 TypeBuilder enclosing =
null;
286 string enclosingClassName =
null;
290 var outerClass = getOuterClass();
291 if (outerClass.outerClass.IsNotNil)
293 enclosingClassName = classFile.GetConstantPoolClass(outerClass.outerClass);
295 else if (f.EnclosingMethod !=
null)
297 enclosingClassName = f.EnclosingMethod[0];
300 if (enclosingClassName !=
null)
302 if (!CheckInnerOuterNames(f.Name, enclosingClassName))
304 wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($
"Incorrect {(outerClass.outerClass.IsNotNil ? "InnerClasses
" : "EnclosingMethod
")} attribute on {f.Name}");
310 enclosingClassWrapper = wrapper.classLoader.TryLoadClassByName(enclosingClassName) as RuntimeByteCodeJavaType;
312 catch (RetargetableJavaException x)
314 wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($
"Unable to load outer class {enclosingClassName} for inner class {f.Name} ({x.GetType().Name}: {x.Message})");
317 if (enclosingClassWrapper !=
null)
323 var oimpl = enclosingClassWrapper.impl as JavaTypeImpl;
324 if (oimpl !=
null && enclosingClassWrapper.ClassLoader == wrapper.ClassLoader)
326 var outerClassFile = oimpl.classFile;
327 var outerInnerClasses = outerClassFile.InnerClasses;
328 if (outerInnerClasses ==
null)
330 enclosingClassWrapper =
null;
335 for (
int i = 0; i < outerInnerClasses.Length; i++)
337 if (((outerInnerClasses[i].outerClass.IsNotNil && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].outerClass) == outerClassFile.Name) || (outerInnerClasses[i].outerClass.IsNil && outerClass.outerClass.IsNil)) && outerInnerClasses[i].innerClass.IsNotNil && outerClassFile.GetConstantPoolClass(outerInnerClasses[i].innerClass) == f.Name)
346 enclosingClassWrapper =
null;
352 enclosingClassWrapper =
null;
355 if (enclosingClassWrapper !=
null)
357 enclosingClassWrapper.CreateStep2();
358 enclosing = oimpl.typeBuilder;
359 if (outerClass.outerClass.IsNil)
362 typeAttribs |= TypeAttributes.SpecialName;
367 wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($
"Non-reciprocal inner class {f.Name}");
375 if (enclosing !=
null)
377 if (enclosingClassWrapper.IsPublic)
379 typeAttribs |= TypeAttributes.NestedPublic;
386 typeAttribs |= TypeAttributes.Public;
391 typeAttribs |= TypeAttributes.Public;
394 else if (enclosing !=
null)
396 typeAttribs |= TypeAttributes.NestedAssembly;
401 typeAttribs |= TypeAttributes.Public;
406 typeAttribs |= TypeAttributes.Interface | TypeAttributes.Abstract;
409 setModifiers |= (f.Modifiers & (
Modifiers)0x99CE) != 0;
411 setModifiers |= (f.Modifiers &
Modifiers.Abstract) == 0;
412 if (enclosing !=
null && !cantNest)
418 throw new NotImplementedException();
423 typeBuilder = enclosing.DefineNestedType(AllocNestedTypeName(enclosingClassWrapper.Name, f.Name), typeAttribs);
429 typeBuilder = wrapper.DefineGhostType(mangledTypeName, typeAttribs);
433 typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs);
437 typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs);
442 typeAttribs |= TypeAttributes.Class;
445 setModifiers |= (f.Modifiers & (
Modifiers)0x99CE) != 0;
447 setModifiers |= !f.IsSuper;
448 if (enclosing !=
null && !cantNest)
452 typeBuilder = enclosing.DefineNestedType(AllocNestedTypeName(enclosingClassWrapper.Name, f.Name), typeAttribs);
457 typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs);
464 wrapper.Context.ClassLoaderFactory.SetWrapperForType(typeBuilder, wrapper);
466 if (outerClass.outerClass.IsNotNil)
468 if (enclosing !=
null && cantNest)
470 wrapper.Context.AttributeHelper.SetNonNestedInnerClass(enclosing, f.Name);
472 if (enclosing ==
null || cantNest)
474 wrapper.Context.AttributeHelper.SetNonNestedOuterClass(typeBuilder, enclosingClassName);
478 if (classFile.InnerClasses !=
null)
480 foreach (var inner
in classFile.InnerClasses)
482 var name = classFile.GetConstantPoolClass(inner.innerClass);
487 exists = wrapper.ClassLoader.TryLoadClassByName(name) !=
null;
489 catch (RetargetableJavaException)
496 wrapper.Context.AttributeHelper.SetNonNestedInnerClass(typeBuilder, name);
501 if (typeBuilder.FullName != wrapper.Name && wrapper.Name.Replace(
'$',
'+') != typeBuilder.FullName)
503 wrapper.classLoader.AddNameMapping(wrapper.Name, typeBuilder.FullName);
506 if (f.IsAnnotation && Annotation.HasRetentionPolicyRuntime(f.Annotations))
508 annotationBuilder =
new AnnotationBuilder(wrapper.Context,
this, enclosing);
509 wrapper.SetAnnotation(annotationBuilder);
514 if (f.IsEnum && f.IsPublic)
519 AddInnerClassAttribute(enclosing !=
null, outerClass.innerClass.IsNotNil, mangledTypeName, outerClass.accessFlags);
520 if (classFile.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(classFile.Annotations))
522 wrapper.Context.AttributeHelper.SetDeprecatedAttribute(typeBuilder);
525 if (classFile.GenericSignature !=
null)
527 wrapper.Context.AttributeHelper.SetSignatureAttribute(typeBuilder, classFile.GenericSignature);
529 if (classFile.EnclosingMethod !=
null)
531 if (outerClass.outerClass.IsNil && enclosing !=
null && !cantNest)
534 wrapper.Context.AttributeHelper.SetEnclosingMethodAttribute(typeBuilder,
null, classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]);
538 wrapper.Context.AttributeHelper.SetEnclosingMethodAttribute(typeBuilder, classFile.EnclosingMethod[0], classFile.EnclosingMethod[1], classFile.EnclosingMethod[2]);
542 if (classFile.RuntimeVisibleTypeAnnotations.Count > 0)
543 wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(typeBuilder, in classFile.RuntimeVisibleTypeAnnotations);
545 if (wrapper.classLoader.EmitStackTraceInfo)
547 if (f.SourceFileAttribute !=
null)
549 if ((enclosingClassWrapper ==
null && f.SourceFileAttribute == typeBuilder.Name +
".java")
550 || (enclosingClassWrapper !=
null && f.SourceFileAttribute == enclosingClassWrapper.sourceFileName))
556 wrapper.Context.AttributeHelper.SetSourceFile(typeBuilder, f.SourceFileAttribute);
561 wrapper.Context.AttributeHelper.SetSourceFile(typeBuilder,
null);
565 if (setModifiers || classFile.IsInternal || (classFile.Modifiers & (
Modifiers.Synthetic |
Modifiers.Annotation |
Modifiers.Enum)) != 0)
567 wrapper.Context.AttributeHelper.SetModifiers(typeBuilder, classFile.Modifiers, classFile.IsInternal);
574 if (HasStructLayoutAttributeAnnotation(classFile))
578 foreach (RuntimeJavaField fw
in fields)
589 throw new InternalException(
"Exception during JavaTypeImpl.CreateStep2", x);
596 private void AddInnerClassAttribute(
bool isNestedType,
bool isInnerClass,
string mangledTypeName,
Modifiers innerClassFlags)
598 string name = classFile.Name;
602 if (name == enclosingClassWrapper.Name +
"$" + typeBuilder.Name)
607 else if (name == mangledTypeName)
612 if ((isInnerClass && RuntimeManagedByteCodeJavaType.PredictReflectiveModifiers(wrapper) != innerClassFlags) || name !=
null)
615 wrapper.Context.AttributeHelper.SetInnerClass(typeBuilder, name, isInnerClass ? innerClassFlags : wrapper.Modifiers);
619 private void AddCliEnum()
622 string name =
"__Enum";
623 while (!ccl.ReserveName(classFile.Name +
"$" + name))
627 enumBuilder = typeBuilder.DefineNestedType(name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Serializable, wrapper.Context.Types.Enum);
628 wrapper.Context.AttributeHelper.HideFromJava(enumBuilder);
629 enumBuilder.DefineField(
"value__", wrapper.Context.Types.Int32, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
630 for (
int i = 0; i < classFile.Fields.Length; i++)
632 if (classFile.Fields[i].IsEnum)
634 FieldBuilder fieldBuilder = enumBuilder.DefineField(classFile.Fields[i].Name, enumBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
635 fieldBuilder.SetConstant(i);
638 wrapper.SetEnumType(enumBuilder);
642 void AddClinitTrigger()
646 var attribs = MethodAttributes.Static | MethodAttributes.SpecialName;
647 if (classFile.IsAbstract)
649 var hasfields =
false;
652 foreach (ClassFile.Field fld in classFile.Fields)
654 if (fld.IsPublic && fld.IsStatic)
661 attribs |= hasfields ? MethodAttributes.Public : MethodAttributes.FamORAssem;
665 attribs |= MethodAttributes.Public;
668 clinitMethod = typeBuilder.DefineMethod(
"__<clinit>", attribs,
null,
null);
669 clinitMethod.GetILGenerator().Emit(OpCodes.Ret);
670 clinitMethod.SetImplementationFlags(clinitMethod.GetMethodImplementationFlags());
673 private static bool HasStructLayoutAttributeAnnotation(ClassFile c)
675 if (c.Annotations !=
null)
677 foreach (
object[] annot
in c.Annotations)
679 if (
"Lcli/System/Runtime/InteropServices/StructLayoutAttribute$Annotation;".Equals(annot[1]))
689 private ClassFile.InnerClass getOuterClass()
691 ClassFile.InnerClass[] innerClasses = classFile.InnerClasses;
692 if (innerClasses !=
null)
694 for (
int j = 0; j < innerClasses.Length; j++)
696 if (innerClasses[j].innerClass.IsNotNil && classFile.GetConstantPoolClass(innerClasses[j].innerClass) == classFile.Name)
698 return innerClasses[j];
702 return new ClassFile.InnerClass();
705 private bool IsSideEffectFreeStaticInitializerOrNoop(ClassFile.Method m, out
bool noop)
707 if (m.ExceptionTable.Length != 0)
713 for (
int i = 0; i < m.Instructions.Length; i++)
718 int target = m.Instructions[i].TargetIndex;
731 ClassFile.ConstantPoolItemFieldref fld = classFile.SafeGetFieldref(m.Instructions[i].Arg1);
732 if (fld ==
null || fld.Class != classFile.Name)
744 ClassFile.Field field = classFile.GetField(fld.Name, fld.Signature);
752 if (field.IsProperty && field.PropertySetter !=
null)
758 else if (field.IsProperty && field.PropertyGetter !=
null)
764 else if (ByteCodeMetaData.CanThrowException(bc))
785 wrapper.Context.MethodAnalyzerFactory.Create(
null, wrapper,
null, classFile, m, wrapper.classLoader);
795 private RuntimeJavaMethod GetMethodWrapperDuringCtor(RuntimeJavaType lookup, IList<RuntimeJavaMethod> methods,
string name,
string sig)
797 if (lookup == wrapper)
799 foreach (RuntimeJavaMethod mw
in methods)
801 if (mw.Name == name && mw.Signature == sig)
806 if (lookup.BaseTypeWrapper ==
null)
812 return lookup.BaseTypeWrapper.GetMethod(name, sig,
true);
817 return lookup.GetMethod(name, sig,
true);
821 void AddMirandaMethods(List<RuntimeJavaMethod> methods, List<RuntimeJavaMethod[]> baseMethods, RuntimeJavaType tw)
823 foreach (var iface
in tw.Interfaces)
826 if (iface.IsPublic && wrapper.IsInterface)
829 AddMirandaMethods(methods, baseMethods, iface);
831 foreach (var ifmethod
in iface.GetMethods())
834 if (ifmethod.IsVirtual)
836 RuntimeJavaType lookup = wrapper;
838 while (lookup !=
null)
840 var mw = GetMethodWrapperDuringCtor(lookup, methods, ifmethod.Name, ifmethod.Signature);
841 if (mw ==
null || (mw.IsMirandaMethod && mw.DeclaringType != wrapper))
843 mw = RuntimeMirandaJavaMethod.Create(wrapper, ifmethod);
845 baseMethods.Add([ifmethod]);
849 if (mw.IsMirandaMethod && mw.DeclaringType == wrapper)
851 methods[methods.IndexOf(mw)] = ((RuntimeMirandaJavaMethod)mw).Update(ifmethod);
855 if (mw.IsStatic ==
false || mw.DeclaringType == wrapper)
858 lookup = mw.DeclaringType.BaseTypeWrapper;
865 void AddDelegateInvokeStubs(RuntimeJavaType tw,
ref RuntimeJavaMethod[] methods)
867 foreach (var iface
in tw.Interfaces)
869 if (iface.IsFakeNestedType &&
870 iface.GetMethods().Length == 1 &&
871 iface.GetMethods()[0].IsDelegateInvokeWithByRefParameter)
873 var mw =
new DelegateInvokeStubMethodWrapper(wrapper, iface.DeclaringTypeWrapper.TypeAsBaseType, iface.GetMethods()[0].Signature);
874 if (GetMethodWrapperDuringCtor(wrapper, methods, mw.Name, mw.Signature) ==
null)
875 methods = ArrayUtil.Concat(methods, mw);
878 AddDelegateInvokeStubs(iface,
ref methods);
884 static bool CheckInnerOuterNames(
string inner,
string outer)
887 return inner.Length > outer.Length + 1 && inner[outer.Length] ==
'$' && inner.StartsWith(outer, StringComparison.Ordinal);
890 string AllocNestedTypeName(
string outer,
string inner)
892 Debug.Assert(CheckInnerOuterNames(inner, outer));
893 nestedTypeNames ??=
new ConcurrentDictionary<string, RuntimeJavaType>();
894 return DynamicClassLoaderFactory.TypeNameMangleImpl(nestedTypeNames, inner.Substring(outer.Length + 1),
null);
899 int GetMethodIndex(RuntimeJavaMethod mw)
901 for (
int i = 0; i < methods.Length; i++)
902 if (methods[i] == mw)
905 throw new InvalidOperationException();
908 static void CheckLoaderConstraints(RuntimeJavaMethod mw, RuntimeJavaMethod baseMethod)
910 if (mw.ReturnType != baseMethod.ReturnType)
912 if (mw.ReturnType.IsUnloadable || baseMethod.ReturnType.IsUnloadable)
915 if (mw.ReturnType.IsUnloadable && baseMethod.ReturnType.IsUnloadable)
916 ((RuntimeUnloadableJavaType)mw.ReturnType).SetCustomModifier(((RuntimeUnloadableJavaType)baseMethod.ReturnType).CustomModifier);
921 StaticCompiler.LinkageError(
"Method \"{2}.{3}{4}\" has a return type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has a return type \"{1}\"", mw.ReturnType, baseMethod.ReturnType, mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name);
928 var here = mw.GetParameters();
929 var there = baseMethod.GetParameters();
930 for (
int i = 0; i < here.Length; i++)
932 if (here[i] != there[i])
934 if (here[i].IsUnloadable || there[i].IsUnloadable)
937 if (here[i].IsUnloadable && there[i].IsUnloadable)
939 ((RuntimeUnloadableJavaType)here[i]).SetCustomModifier(((RuntimeUnloadableJavaType)there[i]).CustomModifier);
945 StaticCompiler.LinkageError(
"Method \"{2}.{3}{4}\" has an argument type \"{0}\" and tries to override method \"{5}.{3}{4}\" that has an argument type \"{1}\"", here[i], there[i], mw.DeclaringType.Name, mw.Name, mw.Signature, baseMethod.DeclaringType.Name);
954 int GetFieldIndex(RuntimeJavaField fw)
956 for (
int i = 0; i < fields.Length; i++)
960 throw new InvalidOperationException();
963 internal override FieldInfo LinkField(RuntimeJavaField fw)
965 if (fw is RuntimeByteCodePropertyJavaField propertyField)
967 propertyField.DoLink(typeBuilder);
971 int fieldIndex = GetFieldIndex(fw);
973 if (wrapper.ClassLoader.RemoveUnusedFields &&
977 fw.IsSerialVersionUID ==
false &&
978 classFile.Fields[fieldIndex].Annotations ==
null &&
979 classFile.IsReferenced(classFile.Fields[fieldIndex]) ==
false)
982 wrapper.ClassLoader.Diagnostics.GenericCompilerInfo($
"Unused field {wrapper.Name}::{fw.Name}");
990 if (!fields[fieldIndex - 1].IsLinked)
991 for (
int i = 0; i < fieldIndex; i++)
994 if (fieldIndex >= classFile.Fields.Length)
997 FieldAttributes fieldAttribs = 0;
999 fieldAttribs |= FieldAttributes.Public;
1000 else if (fw.IsProtected)
1001 fieldAttribs |= FieldAttributes.FamORAssem;
1002 else if (fw.IsPrivate)
1003 fieldAttribs |= FieldAttributes.Private;
1005 fieldAttribs |= FieldAttributes.Assembly;
1008 fieldAttribs |= FieldAttributes.Static;
1011 fieldAttribs |= FieldAttributes.InitOnly;
1013 return DefineField(fw.Name, fw.FieldTypeWrapper, fieldAttribs, fw.IsVolatile);
1018 var fld = classFile.Fields[fieldIndex];
1019 FieldAttributes attribs = 0;
1020 var realFieldName = UnicodeUtil.EscapeInvalidSurrogates(fld.Name);
1021 if (ReferenceEquals(realFieldName, fld.Name) ==
false)
1022 attribs |= FieldAttributes.SpecialName;
1024 var methodAttribs = MethodAttributes.HideBySig;
1026 var setModifiers = fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic |
Modifiers.Enum)) != 0;
1033 var needsNestmateFieldAccess = fld.IsPrivate && HasNestmates();
1038 if (needsNestmateFieldAccess)
1040 attribs |= FieldAttributes.Assembly;
1041 setModifiers =
true;
1046 attribs |= FieldAttributes.Private;
1049 else if (fld.IsProtected)
1051 attribs |= FieldAttributes.FamORAssem;
1052 methodAttribs |= MethodAttributes.FamORAssem;
1054 else if (fld.IsPublic)
1056 attribs |= FieldAttributes.Public;
1057 methodAttribs |= MethodAttributes.Public;
1061 attribs |= FieldAttributes.Assembly;
1062 methodAttribs |= MethodAttributes.Assembly;
1067 attribs |= FieldAttributes.Static;
1068 methodAttribs |= MethodAttributes.Static;
1074 if (fld.IsStaticFinalConstant)
1076 attribs |= FieldAttributes.Literal;
1077 field = DefineField(realFieldName, fw.FieldTypeWrapper, attribs,
false);
1078 field.SetConstant(fld.ConstantValue);
1083 if (wrapper.IsPublic && wrapper.NeedsType2AccessStub(fw))
1086 attribs &= ~FieldAttributes.FieldAccessMask;
1087 attribs |= FieldAttributes.Assembly;
1092 realFieldName = NamePrefix.Type2AccessStubBackingField + realFieldName;
1094 else if (fld.IsFinal)
1096 if (wrapper.IsInterface || wrapper.classLoader.StrictFinalFieldSemantics)
1097 attribs |= FieldAttributes.InitOnly;
1099 setModifiers =
true;
1102 if (fld.IsFinal && wrapper.IsInterface)
1103 attribs |= FieldAttributes.InitOnly;
1106 field = DefineField(realFieldName, fw.FieldTypeWrapper, attribs, fld.IsVolatile);
1108 if (fld.IsTransient)
1110 var transientAttrib =
new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveCoreType(typeof(NonSerializedAttribute).FullName).GetConstructor([]).AsReflection(), Array.Empty<
object>());
1111 field.SetCustomAttribute(transientAttrib);
1118 wrapper.Context.AttributeHelper.SetModifiers(field, fld.Modifiers, fld.IsInternal);
1120 if (fld.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(fld.Annotations))
1121 wrapper.Context.AttributeHelper.SetDeprecatedAttribute(field);
1123 if (fld.GenericSignature !=
null)
1124 wrapper.Context.AttributeHelper.SetSignatureAttribute(field, fld.GenericSignature);
1126 if (fld.RuntimeVisibleTypeAnnotations.Count > 0)
1127 wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(field, in fld.RuntimeVisibleTypeAnnotations);
1139 if (classFile.Name.IndexOf(
'$') >= 0)
1142 var innerClasses = classFile.InnerClasses;
1143 if (innerClasses ==
null)
1146 foreach (var innerClass
in innerClasses)
1147 if (innerClass.outerClass.IsNotNil &&
1148 classFile.GetConstantPoolClass(innerClass.outerClass) == classFile.Name)
1154 FieldBuilder DefineField(
string name, RuntimeJavaType tw, FieldAttributes attribs,
bool isVolatile)
1156 var modreq = isVolatile ? [wrapper.Context.Types.IsVolatile] :
Type.EmptyTypes;
1157 return typeBuilder.DefineField(name, tw.TypeAsSignatureType, modreq, wrapper.GetModOpt(tw,
false), attribs);
1160 internal override void EmitRunClassConstructor(CodeEmitter ilgen)
1162 if (clinitMethod !=
null)
1163 ilgen.Emit(OpCodes.Call, clinitMethod);
1166 internal override DynamicImpl Finish()
1168 var baseTypeWrapper = wrapper.BaseTypeWrapper;
1169 if (baseTypeWrapper !=
null)
1171 baseTypeWrapper.Finish();
1172 baseTypeWrapper.LinkAll();
1185 foreach (var iface
in wrapper.interfaces)
1196 var mode =
System.Threading.Interlocked.Increment(
ref recursionCount) > 2 || (JVM.DisableEagerClassLoading && wrapper.Name !=
"sun.reflect.misc.Trampoline")
1201 classFile.Link(wrapper, mode);
1203 for (
int i = 0; i < fields.Length; i++)
1204 fields[i].
Link(mode);
1206 for (
int i = 0; i < methods.Length; i++)
1207 methods[i].
Link(mode);
1211 System.Threading.Interlocked.Decrement(
ref recursionCount);
1218 FinishedTypeImpl impl;
1226 impl = FinishCore();
1233 FinishedTypeImpl FinishCore()
1237 if (finishedType !=
null)
1238 return finishedType;
1240 if (finishInProgress)
1241 throw new InvalidOperationException(
"Recursive finish attempt for " + wrapper.Name);
1243 finishInProgress =
true;
1244 wrapper.ClassLoader.Diagnostics.GenericCompilerTrace($
"Finishing: {wrapper.Name}");
1248 RuntimeJavaType declaringTypeWrapper =
null;
1249 var innerClassesTypeWrappers = Array.Empty<RuntimeJavaType>();
1252 var innerclasses = classFile.InnerClasses;
1253 if (innerclasses !=
null)
1256 var wrappers =
new List<RuntimeJavaType>();
1257 for (
int i = 0; i < innerclasses.Length; i++)
1259 if (innerclasses[i].innerClass.IsNotNil && innerclasses[i].outerClass.IsNotNil)
1261 if (classFile.GetConstantPoolClassType(innerclasses[i].outerClass) == wrapper)
1262 wrappers.Add(classFile.GetConstantPoolClassType(innerclasses[i].innerClass));
1263 if (classFile.GetConstantPoolClassType(innerclasses[i].innerClass) == wrapper)
1264 declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass);
1267 innerClassesTypeWrappers = wrappers.ToArray();
1271 foreach (var tw
in innerClassesTypeWrappers)
1273 if (tw is RuntimeByteCodeJavaType dtw)
1275 var impl = dtw.impl as JavaTypeImpl;
1277 if (impl.annotationBuilder !=
null)
1278 impl.annotationBuilder.Link();
1286 if (annotationBuilder !=
null)
1288 var cab =
new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType(typeof(
AnnotationAttributeAttribute).FullName).AsReflection().GetConstructor(
new Type[] { wrapper.Context.Types.String }),
new object[] { UnicodeUtil.EscapeInvalidSurrogates(annotationBuilder.AttributeTypeName) });
1289 typeBuilder.SetCustomAttribute(cab);
1292 if (!wrapper.IsInterface && wrapper.IsMapUnsafeException)
1297 wrapper.Context.AttributeHelper.SetExceptionIsUnsafeForMapping(typeBuilder);
1301 var context =
new FinishContext(wrapper.Context, host, classFile, wrapper, typeBuilder);
1302 var type = context.FinishImpl();
1305 if (annotationBuilder !=
null)
1306 annotationBuilder.Finish(
this);
1308 if (enumBuilder !=
null)
1309 enumBuilder.CreateType();
1311 if (privateInterfaceMethods !=
null)
1312 privateInterfaceMethods.CreateType();
1315 var finishedClinitMethod = (
MethodInfo)clinitMethod;
1317 if (finishedClinitMethod !=
null)
1321 finishedClinitMethod = type.GetMethod(
"__<clinit>", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
1325 finishedType =
new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, wrapper.ReflectiveModifiers, Metadata.Create(classFile), finishedClinitMethod, finalizeMethod, host);
1326 return finishedType;
1331 throw new InternalException($
"Exception during finishing of: {wrapper.Name}", x);
1342 bool IsValidAnnotationElementType(
string type)
1345 type = type.Substring(1);
1357 case "Ljava.lang.String;":
1358 case "Ljava.lang.Class;":
1362 if (type.StartsWith(
"L") && type.EndsWith(
";"))
1366 var tw = wrapper.ClassLoader.TryLoadClassByName(type.Substring(1, type.Length - 2));
1369 if ((tw.Modifiers &
Modifiers.Annotation) != 0)
1372 if ((tw.Modifiers &
Modifiers.Enum) != 0)
1374 var enumType = wrapper.Context.ClassLoaderFactory.GetBootstrapClassLoader().TryLoadClassByName(
"java.lang.Enum");
1375 if (enumType !=
null && tw.IsSubTypeOf(enumType))
1392 readonly RuntimeContext context;
1396 TypeBuilder annotationTypeBuilder;
1397 TypeBuilder attributeTypeBuilder;
1398 MethodBuilder defineConstructor;
1406 internal AnnotationBuilder(RuntimeContext context, JavaTypeImpl o, TypeBuilder outer)
1408 this.context = context;
1413 internal void Link()
1422 for (
int i = 0; i < o.methods.Length; i++)
1424 if (!o.methods[i].IsStatic)
1426 if (!o.methods[i].Signature.StartsWith(
"()"))
1428 if (!o.IsValidAnnotationElementType(o.methods[i].Signature.Substring(2)))
1434 annotationTypeBuilder = o.typeBuilder;
1436 var annotationAttributeBaseType = context.ClassLoaderFactory.LoadClassCritical(
"ikvm.internal.AnnotationAttributeBase");
1439 var ccl = o.wrapper.classLoader;
1440 var name = UnicodeUtil.EscapeInvalidSurrogates(o.classFile.Name);
1441 while (!ccl.ReserveName(name +
"Attribute"))
1444 var typeAttributes = TypeAttributes.Class | TypeAttributes.Sealed;
1445 if (o.enclosingClassWrapper !=
null)
1447 if (o.wrapper.IsPublic)
1448 typeAttributes |= TypeAttributes.NestedPublic;
1450 typeAttributes |= TypeAttributes.NestedAssembly;
1452 attributeTypeBuilder = outer.DefineNestedType(o.AllocNestedTypeName(o.enclosingClassWrapper.Name, name +
"Attribute"), typeAttributes, annotationAttributeBaseType.TypeAsBaseType);
1456 if (o.wrapper.IsPublic)
1457 typeAttributes |= TypeAttributes.Public;
1459 typeAttributes |= TypeAttributes.NotPublic;
1461 attributeTypeBuilder = o.wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name +
"Attribute", typeAttributes, annotationAttributeBaseType.TypeAsBaseType);
1464 if (o.wrapper.IsPublic)
1467 context.AttributeHelper.SetModifiers(attributeTypeBuilder,
Modifiers.Final,
false);
1471 int dotindex = o.classFile.Name.LastIndexOf(
'.') + 1;
1472 context.AttributeHelper.SetInnerClass(attributeTypeBuilder, o.classFile.Name.Substring(0, dotindex) +
"$Proxy" + o.classFile.Name.Substring(dotindex),
Modifiers.Final);
1473 attributeTypeBuilder.AddInterfaceImplementation(o.typeBuilder);
1474 context.AttributeHelper.SetImplementsAttribute(attributeTypeBuilder,
new RuntimeJavaType[] { o.wrapper });
1476 if (o.classFile.Annotations !=
null)
1478 CustomAttributeBuilder attributeUsageAttribute =
null;
1479 bool hasAttributeUsageAttribute =
false;
1480 foreach (
object[] def
in o.classFile.Annotations)
1482 if (def[1].Equals(
"Ljava/lang/annotation/Target;") && !hasAttributeUsageAttribute)
1484 for (
int i = 2; i < def.Length; i += 2)
1486 if (def[i].Equals(
"value"))
1488 var val = def[i + 1] as
object[];
1493 AttributeTargets targets = 0;
1494 for (
int j = 1; j < val.Length; j++)
1496 var eval = val[j] as
object[];
1500 eval[1].Equals(
"Ljava/lang/annotation/ElementType;"))
1502 switch ((
string)eval[2])
1504 case "ANNOTATION_TYPE":
1505 targets |= AttributeTargets.Interface;
1508 targets |= AttributeTargets.Constructor;
1511 targets |= AttributeTargets.Field;
1513 case "LOCAL_VARIABLE":
1516 targets |= AttributeTargets.Method;
1519 targets |= AttributeTargets.Interface;
1522 targets |= AttributeTargets.Parameter;
1525 targets |= AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum;
1531 attributeUsageAttribute =
new CustomAttributeBuilder(context.Resolver.ResolveCoreType(typeof(AttributeUsageAttribute).FullName).GetConstructor([context.Resolver.ResolveCoreType(typeof(AttributeTargets).FullName)]).AsReflection(), [targets]);
1540 var annotation =
Annotation.Load(o.wrapper, def);
1541 if (annotation !=
null && annotation.IsCustomAttribute)
1542 annotation.Apply(o.wrapper.ClassLoader, attributeTypeBuilder, def);
1544 if (def[1].Equals(
"Lcli/System/AttributeUsageAttribute$Annotation;"))
1545 hasAttributeUsageAttribute =
true;
1549 if (attributeUsageAttribute !=
null && !hasAttributeUsageAttribute)
1550 attributeTypeBuilder.SetCustomAttribute(attributeUsageAttribute);
1553 defineConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public,
new Type[] { context.Resolver.ResolveCoreType(typeof(object).FullName).MakeArrayType().AsReflection() });
1554 context.AttributeHelper.SetEditorBrowsableNever(defineConstructor);
1557 static Type TypeWrapperToAnnotationParameterType(RuntimeJavaType tw)
1559 var isArray =
false;
1563 tw = tw.ElementTypeWrapper;
1566 if (tw.Annotation !=
null)
1574 if (tw == tw.Context.JavaBase.TypeOfJavaLangClass)
1576 argType = tw.Context.Types.Type;
1578 else if (tw.EnumType !=
null)
1580 argType = tw.EnumType;
1582 else if (IsDotNetEnum(tw))
1584 argType = tw.DeclaringTypeWrapper.TypeAsSignatureType;
1588 argType = tw.TypeAsSignatureType;
1592 argType = RuntimeArrayJavaType.MakeArrayType(argType, 1);
1598 static bool IsDotNetEnum(RuntimeJavaType tw)
1600 return tw.IsFakeNestedType && (tw.Modifiers &
Modifiers.Enum) != 0;
1603 internal string AttributeTypeName
1609 if (attributeTypeBuilder !=
null)
1610 return attributeTypeBuilder.FullName;
1616 static void EmitSetValueCall(RuntimeJavaType annotationAttributeBaseType, CodeEmitter ilgen,
string name, RuntimeJavaType tw,
int argIndex)
1618 ilgen.Emit(OpCodes.Ldarg_0);
1619 ilgen.Emit(OpCodes.Ldstr, name);
1620 ilgen.EmitLdarg(argIndex);
1622 if (tw.TypeAsSignatureType.IsValueType)
1623 ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType);
1624 else if (tw.EnumType !=
null)
1625 ilgen.Emit(OpCodes.Box, tw.EnumType);
1626 else if (IsDotNetEnum(tw))
1627 ilgen.Emit(OpCodes.Box, tw.DeclaringTypeWrapper.TypeAsSignatureType);
1629 var setValueMethod = annotationAttributeBaseType.GetMethod(
"setValue",
"(Ljava.lang.String;Ljava.lang.Object;)V",
false);
1630 setValueMethod.Link();
1631 setValueMethod.EmitCall(ilgen);
1634 internal void Finish(JavaTypeImpl o)
1639 if (annotationTypeBuilder ==
null)
1642 var annotationAttributeBaseType = context.ClassLoaderFactory.LoadClassCritical(
"ikvm.internal.AnnotationAttributeBase");
1643 annotationAttributeBaseType.Finish();
1645 int requiredArgCount = 0;
1647 bool unsupported =
false;
1648 for (
int i = 0; i < o.methods.Length; i++)
1650 if (!o.methods[i].IsStatic)
1652 if (valueArg == -1 && o.methods[i].Name ==
"value")
1655 if (o.classFile.Methods[i].AnnotationDefault ==
null)
1657 if (TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType) ==
null)
1668 var defaultConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, unsupported || requiredArgCount > 0 ? MethodAttributes.Private : MethodAttributes.Public,
Type.EmptyTypes);
1673 if (requiredArgCount > 0)
1675 var args =
new Type[requiredArgCount];
1676 for (
int i = 0, j = 0; i < o.methods.Length; i++)
1677 if (!o.methods[i].IsStatic)
1678 if (o.classFile.Methods[i].AnnotationDefault ==
null)
1679 args[j++] = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType);
1681 var reqArgConstructor = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, args);
1682 context.AttributeHelper.HideFromJava(reqArgConstructor);
1683 ilgen = context.CodeEmitterFactory.Create(reqArgConstructor);
1684 ilgen.Emit(OpCodes.Ldarg_0);
1685 ilgen.Emit(OpCodes.Call, defaultConstructor);
1686 for (
int i = 0, j = 0; i < o.methods.Length; i++)
1688 if (!o.methods[i].IsStatic)
1690 if (o.classFile.Methods[i].AnnotationDefault ==
null)
1692 reqArgConstructor.DefineParameter(++j, ParameterAttributes.None, o.methods[i].Name);
1693 EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, j);
1698 ilgen.Emit(OpCodes.Ret);
1701 else if (valueArg != -1)
1706 var argType = TypeWrapperToAnnotationParameterType(o.methods[valueArg].ReturnType);
1707 if (argType !=
null)
1709 var cb = ReflectUtil.DefineConstructor(attributeTypeBuilder, MethodAttributes.Public, [argType]);
1710 context.AttributeHelper.HideFromJava(cb);
1711 cb.DefineParameter(1, ParameterAttributes.None,
"value");
1712 ilgen = context.CodeEmitterFactory.Create(cb);
1713 ilgen.Emit(OpCodes.Ldarg_0);
1714 ilgen.Emit(OpCodes.Call, defaultConstructor);
1715 EmitSetValueCall(annotationAttributeBaseType, ilgen,
"value", o.methods[valueArg].ReturnType, 1);
1716 ilgen.Emit(OpCodes.Ret);
1722 ilgen = context.CodeEmitterFactory.Create(defaultConstructor);
1723 ilgen.Emit(OpCodes.Ldarg_0);
1724 o.wrapper.EmitClassLiteral(ilgen);
1725 annotationAttributeBaseType.GetMethod(
"<init>",
"(Ljava.lang.Class;)V",
false).EmitCall(ilgen);
1726 ilgen.Emit(OpCodes.Ret);
1729 ilgen = context.CodeEmitterFactory.Create(defineConstructor);
1730 ilgen.Emit(OpCodes.Ldarg_0);
1731 ilgen.Emit(OpCodes.Call, defaultConstructor);
1732 ilgen.Emit(OpCodes.Ldarg_0);
1733 ilgen.Emit(OpCodes.Ldarg_1);
1734 annotationAttributeBaseType.GetMethod(
"setDefinition",
"([Ljava.lang.Object;)V",
false).EmitCall(ilgen);
1735 ilgen.Emit(OpCodes.Ret);
1738 var getValueMethod = annotationAttributeBaseType.GetMethod(
"getValue",
"(Ljava.lang.String;)Ljava.lang.Object;",
false);
1739 var getByteValueMethod = annotationAttributeBaseType.GetMethod(
"getByteValue",
"(Ljava.lang.String;)B",
false);
1740 var getBooleanValueMethod = annotationAttributeBaseType.GetMethod(
"getBooleanValue",
"(Ljava.lang.String;)Z",
false);
1741 var getCharValueMethod = annotationAttributeBaseType.GetMethod(
"getCharValue",
"(Ljava.lang.String;)C",
false);
1742 var getShortValueMethod = annotationAttributeBaseType.GetMethod(
"getShortValue",
"(Ljava.lang.String;)S",
false);
1743 var getIntValueMethod = annotationAttributeBaseType.GetMethod(
"getIntValue",
"(Ljava.lang.String;)I",
false);
1744 var getFloatValueMethod = annotationAttributeBaseType.GetMethod(
"getFloatValue",
"(Ljava.lang.String;)F",
false);
1745 var getLongValueMethod = annotationAttributeBaseType.GetMethod(
"getLongValue",
"(Ljava.lang.String;)J",
false);
1746 var getDoubleValueMethod = annotationAttributeBaseType.GetMethod(
"getDoubleValue",
"(Ljava.lang.String;)D",
false);
1748 for (
int i = 0; i < o.methods.Length; i++)
1751 if (o.methods[i].IsVirtual)
1753 var mb = o.methods[i].GetDefineMethodHelper().DefineMethod(o.wrapper, attributeTypeBuilder, o.methods[i].Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot);
1754 attributeTypeBuilder.DefineMethodOverride(mb, (
MethodInfo)o.methods[i].GetMethod());
1755 ilgen = context.CodeEmitterFactory.Create(mb);
1756 ilgen.Emit(OpCodes.Ldarg_0);
1757 ilgen.Emit(OpCodes.Ldstr, o.methods[i].Name);
1758 if (o.methods[i].ReturnType.IsPrimitive)
1760 if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.BYTE)
1762 getByteValueMethod.EmitCall(ilgen);
1764 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.BOOLEAN)
1766 getBooleanValueMethod.EmitCall(ilgen);
1768 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.CHAR)
1770 getCharValueMethod.EmitCall(ilgen);
1772 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.SHORT)
1774 getShortValueMethod.EmitCall(ilgen);
1776 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.INT)
1778 getIntValueMethod.EmitCall(ilgen);
1780 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.FLOAT)
1782 getFloatValueMethod.EmitCall(ilgen);
1784 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.LONG)
1786 getLongValueMethod.EmitCall(ilgen);
1788 else if (o.methods[i].ReturnType == context.PrimitiveJavaTypeFactory.DOUBLE)
1790 getDoubleValueMethod.EmitCall(ilgen);
1794 throw new InvalidOperationException();
1799 getValueMethod.EmitCall(ilgen);
1800 o.methods[i].ReturnType.EmitCheckcast(ilgen);
1803 ilgen.Emit(OpCodes.Ret);
1806 if (o.classFile.Methods[i].AnnotationDefault !=
null &&
1807 !(o.methods[i].Name ==
"value" && requiredArgCount == 0))
1810 var argType = TypeWrapperToAnnotationParameterType(o.methods[i].ReturnType);
1811 if (argType !=
null)
1813 var
property = attributeTypeBuilder.DefineProperty(o.methods[i].Name, PropertyAttributes.None, argType,
Type.EmptyTypes);
1814 context.AttributeHelper.HideFromJava(property);
1816 var setter = attributeTypeBuilder.DefineMethod(
"set_" + o.methods[i].Name, MethodAttributes.Public, context.Types.Void, [argType]);
1817 context.AttributeHelper.HideFromJava(setter);
1818 property.SetSetMethod(setter);
1820 ilgen = context.CodeEmitterFactory.Create(setter);
1821 EmitSetValueCall(annotationAttributeBaseType, ilgen, o.methods[i].Name, o.methods[i].ReturnType, 1);
1822 ilgen.Emit(OpCodes.Ret);
1825 var getter = attributeTypeBuilder.DefineMethod(
"get_" + o.methods[i].Name, MethodAttributes.Public, argType,
Type.EmptyTypes);
1826 context.AttributeHelper.HideFromJava(getter);
1827 property.SetGetMethod(getter);
1830 ilgen = context.CodeEmitterFactory.Create(getter);
1831 ilgen.ThrowException(context.Resolver.ResolveCoreType(typeof(NotImplementedException).FullName).AsReflection());
1838 attributeTypeBuilder.CreateType();
1841 CustomAttributeBuilder MakeCustomAttributeBuilder(RuntimeClassLoader loader,
object annotation)
1846 ? defineConstructor.__AsConstructorInfo()
1847 : context.Resolver.ResolveRuntimeType(
"IKVM.Attributes.DynamicAnnotationAttribute").AsReflection().GetConstructor([context.Types.Object.MakeArrayType()]);
1852 internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb,
object annotation)
1854 tb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
1857 internal override void Apply(RuntimeClassLoader loader, MethodBuilder mb,
object annotation)
1859 mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
1862 internal override void Apply(RuntimeClassLoader loader, FieldBuilder fb,
object annotation)
1864 fb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
1867 internal override void Apply(RuntimeClassLoader loader, ParameterBuilder pb,
object annotation)
1869 pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
1872 internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab,
object annotation)
1874 ab.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
1877 internal override void Apply(RuntimeClassLoader loader, PropertyBuilder pb,
object annotation)
1879 pb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
1882 internal override bool IsCustomAttribute
1884 get {
return false; }
1890 internal override RuntimeJavaType[] InnerClasses =>
throw new InvalidOperationException(
"InnerClasses is only available for finished types");
1892 internal override RuntimeJavaType DeclaringTypeWrapper =>
throw new InvalidOperationException(
"DeclaringTypeWrapper is only available for finished types");
1894 internal override Modifiers ReflectiveModifiers
1900 var innerclasses = classFile.InnerClasses;
1901 if (innerclasses !=
null)
1903 for (
int i = 0; i < innerclasses.Length; i++)
1905 if (innerclasses[i].innerClass.IsNotNil)
1907 if (classFile.GetConstantPoolClass(innerclasses[i].innerClass) == wrapper.Name)
1911 mods = innerclasses[i].accessFlags & (
Modifiers)0x761F;
1912 if (classFile.IsInterface)
1923 mods = classFile.Modifiers & (
Modifiers)0x7611;
1924 if (classFile.IsInterface)
1937 RuntimeJavaMethod[] FindBaseMethods(ClassFile.Method m, out
bool explicitOverride)
1939 Debug.Assert(!classFile.IsInterface);
1940 Debug.Assert(m.Name !=
"<init>");
1943 return classFile.MajorVersion >= 51 ? FindBaseMethods7(m.Name, m.Signature, m.IsFinal && !m.IsPublic && !m.IsProtected, out explicitOverride) : FindBaseMethodsLegacy(m.Name, m.Signature, out explicitOverride);
1946 RuntimeJavaMethod[] FindBaseMethods7(
string name,
string sig,
bool packageFinal, out
bool explicitOverride)
1953 explicitOverride =
false;
1954 RuntimeJavaMethod topPublicOrProtectedMethod =
null;
1955 var tw = wrapper.BaseTypeWrapper;
1958 var baseMethod = tw.GetMethod(name, sig,
true);
1959 if (baseMethod ==
null)
1961 else if (baseMethod.IsAccessStub)
1965 else if (!baseMethod.IsStatic && (baseMethod.IsPublic || baseMethod.IsProtected))
1966 topPublicOrProtectedMethod = baseMethod;
1968 tw = baseMethod.DeclaringType.BaseTypeWrapper;
1971 tw = wrapper.BaseTypeWrapper;
1975 var baseMethod = tw.GetMethod(name, sig,
true);
1976 if (baseMethod ==
null)
1980 else if (baseMethod.IsAccessStub)
1984 else if (baseMethod.IsPrivate)
1988 else if (baseMethod.IsFinal && (baseMethod.IsPublic || baseMethod.IsProtected || IsAccessibleInternal(baseMethod) || baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper)))
1990 throw new VerifyError(
"final method " + baseMethod.Name + baseMethod.Signature +
" in " + baseMethod.DeclaringType.Name +
" is overridden in " + wrapper.Name);
1992 else if (baseMethod.IsStatic)
1996 else if (topPublicOrProtectedMethod ==
null && !baseMethod.IsPublic && !baseMethod.IsProtected && !IsAccessibleInternal(baseMethod) && !baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
1999 explicitOverride =
true;
2001 else if (topPublicOrProtectedMethod !=
null && baseMethod.IsFinal && !baseMethod.IsPublic && !baseMethod.IsProtected && !IsAccessibleInternal(baseMethod) && !baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
2004 explicitOverride =
true;
2006 else if (topPublicOrProtectedMethod ==
null)
2008 if (explicitOverride)
2010 var list =
new List<RuntimeJavaMethod>();
2011 list.Add(baseMethod);
2014 tw = wrapper.BaseTypeWrapper;
2017 var baseMethod2 = tw.GetMethod(name, sig,
true);
2018 if (baseMethod2 ==
null || baseMethod2 == baseMethod)
2021 var baseMethod3 = GetPackageBaseMethod(baseMethod.DeclaringType.BaseTypeWrapper, name, sig, baseMethod2.DeclaringType);
2022 if (baseMethod3 !=
null)
2024 if (baseMethod2.IsFinal)
2025 baseMethod2 = baseMethod3;
2028 foreach (var mw
in list)
2030 if (mw.DeclaringType.IsPackageAccessibleFrom(baseMethod2.DeclaringType))
2039 list.Add(baseMethod2);
2042 tw = baseMethod2.DeclaringType.BaseTypeWrapper;
2045 return list.ToArray();
2049 return [baseMethod];
2059 explicitOverride =
true;
2062 int majorVersion = 0;
2063 if (!baseMethod.IsPublic && !baseMethod.IsProtected &&
2064 ((TryGetClassFileVersion(baseMethod.DeclaringType,
ref majorVersion) && majorVersion < 51)
2067 || (majorVersion == 0 && (LinkAndGetMethod(baseMethod).Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly)))
2072 return [baseMethod, topPublicOrProtectedMethod];
2074 else if (!topPublicOrProtectedMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
2077 tw = topPublicOrProtectedMethod.DeclaringType.BaseTypeWrapper;
2080 var baseMethod2 = tw.GetMethod(name, sig,
true);
2081 if (baseMethod2 ==
null)
2084 if (baseMethod2.IsAccessStub)
2088 else if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
2090 if (baseMethod2.IsFinal)
2091 throw new VerifyError(
"final method " + baseMethod2.Name + baseMethod2.Signature +
" in " + baseMethod2.DeclaringType.Name +
" is overridden in " + wrapper.Name);
2093 if (!baseMethod2.IsStatic)
2095 if (baseMethod2.IsPublic || baseMethod2.IsProtected)
2098 return [baseMethod, baseMethod2];
2102 tw = baseMethod2.DeclaringType.BaseTypeWrapper;
2106 return [baseMethod];
2109 tw = baseMethod.DeclaringType.BaseTypeWrapper;
2115 bool IsAccessibleInternal(RuntimeJavaMethod mw)
2117 return mw.IsInternal && mw.DeclaringType.InternalsVisibleTo(wrapper);
2120 static MethodBase LinkAndGetMethod(RuntimeJavaMethod mw)
2123 return mw.GetMethod();
2126 static bool TryGetClassFileVersion(RuntimeJavaType tw,
ref int majorVersion)
2128 if (tw is RuntimeByteCodeJavaType dtw)
2130 var impl = dtw.impl as JavaTypeImpl;
2133 majorVersion = impl.classFile.MajorVersion;
2141 static RuntimeJavaMethod GetPackageBaseMethod(RuntimeJavaType tw,
string name,
string sig, RuntimeJavaType package)
2145 var mw = tw.GetMethod(name, sig,
true);
2149 if (mw.DeclaringType.IsPackageAccessibleFrom(package))
2150 return mw.IsFinal ? null : mw;
2152 tw = mw.DeclaringType.BaseTypeWrapper;
2158 RuntimeJavaMethod[] FindBaseMethodsLegacy(
string name,
string sig, out
bool explicitOverride)
2160 explicitOverride =
false;
2161 var tw = wrapper.BaseTypeWrapper;
2164 var baseMethod = tw.GetMethod(name, sig,
true);
2165 if (baseMethod ==
null)
2169 else if (baseMethod.IsAccessStub)
2177 else if (baseMethod.IsFinal && !baseMethod.IsPrivate && (baseMethod.IsPublic || baseMethod.IsProtected || baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper)))
2179 throw new VerifyError(
"final method " + baseMethod.Name + baseMethod.Signature +
" in " + baseMethod.DeclaringType.Name +
" is overridden in " + wrapper.Name);
2182 else if (baseMethod.IsStatic)
2187 else if (baseMethod.IsPublic || baseMethod.IsProtected)
2191 if (explicitOverride)
2193 explicitOverride =
false;
2196 if (!baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper))
2199 tw = baseMethod.DeclaringType.BaseTypeWrapper;
2202 RuntimeJavaMethod baseMethod2 = tw.GetMethod(name, sig,
true);
2203 if (baseMethod2 ==
null)
2207 if (baseMethod2.IsAccessStub)
2211 else if (baseMethod2.DeclaringType.IsPackageAccessibleFrom(wrapper) && !baseMethod2.IsPrivate)
2213 if (baseMethod2.IsFinal)
2215 throw new VerifyError(
"final method " + baseMethod2.Name + baseMethod2.Signature +
" in " + baseMethod2.DeclaringType.Name +
" is overridden in " + wrapper.Name);
2217 if (!baseMethod2.IsStatic)
2219 if (baseMethod2.IsPublic || baseMethod2.IsProtected)
2223 return new RuntimeJavaMethod[] { baseMethod, baseMethod2 };
2226 tw = baseMethod2.DeclaringType.BaseTypeWrapper;
2229 return new RuntimeJavaMethod[] { baseMethod };
2232 else if (!baseMethod.IsPrivate)
2235 if (baseMethod.DeclaringType.IsPackageAccessibleFrom(wrapper) || (baseMethod.IsInternal && baseMethod.DeclaringType.InternalsVisibleTo(wrapper)))
2237 return new RuntimeJavaMethod[] { baseMethod };
2243 explicitOverride =
true;
2245 tw = baseMethod.DeclaringType.BaseTypeWrapper;
2251 static MethodInfo GetBaseFinalizeMethod(RuntimeJavaType wrapper)
2258 var dtw = wrapper as RuntimeByteCodeJavaType;
2262 var mw = dtw.GetMethod(StringConstants.FINALIZE, StringConstants.SIG_VOID,
false);
2266 var finalizeImpl = dtw.impl.GetFinalizeMethod();
2267 if (finalizeImpl !=
null)
2268 return finalizeImpl;
2270 wrapper = wrapper.BaseTypeWrapper;
2273 if (wrapper == wrapper.Context.JavaBase.TypeOfJavaLangObject || wrapper == wrapper.Context.JavaBase.TypeOfjavaLangThrowable)
2275 return wrapper.Context.Types.Object.GetMethod(
"Finalize", BindingFlags.NonPublic | BindingFlags.Instance);
2278 var type = wrapper.TypeAsBaseType;
2279 var baseFinalize = type.GetMethod(
"__<Finalize>", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
null,
Type.EmptyTypes,
null);
2280 if (baseFinalize !=
null)
2281 return baseFinalize;
2283 while (type !=
null)
2285 foreach (
MethodInfo m
in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
2287 if (m.Name ==
"Finalize"
2288 && m.ReturnType == wrapper.Context.Types.Void
2289 && m.GetParameters().Length == 0)
2291 if (m.GetBaseDefinition().DeclaringType == wrapper.Context.Types.Object)
2297 type = type.BaseType;
2302 MethodAttributes GetPropertyAccess(RuntimeJavaMethod mw)
2304 var sig = mw.ReturnType.SigName;
2306 sig = mw.GetParameters()[0].SigName;
2309 foreach (var field
in classFile.Fields)
2311 if (field.IsProperty && field.IsStatic == mw.IsStatic && field.Signature == sig && (field.PropertyGetter == mw.Name || field.PropertySetter == mw.Name))
2318 else if (field.IsProtected)
2322 else if (field.IsPrivate)
2340 return MethodAttributes.Private;
2342 return MethodAttributes.Assembly;
2344 return MethodAttributes.FamORAssem;
2346 return MethodAttributes.Public;
2348 throw new InvalidOperationException();
2352 internal override MethodBase LinkMethod(RuntimeJavaMethod mw)
2354 Debug.Assert(mw !=
null);
2356 if (mw is DelegateConstructorMethodWrapper dcmw)
2358 dcmw.DoLink(typeBuilder);
2362 if (mw is DelegateInvokeStubMethodWrapper stub)
2364 return stub.DoLink(typeBuilder);
2367 if (mw.IsClassInitializer && mw.IsNoOp && (!wrapper.IsSerializable || HasSerialVersionUID))
2375 int index = GetMethodIndex(mw);
2376 if (baseMethods[index] !=
null)
2378 foreach (var baseMethod
in baseMethods[index])
2381 CheckLoaderConstraints(mw, baseMethod);
2385 Debug.Assert(mw.GetMethod() ==
null);
2386 methods[index].AssertLinked();
2387 Profiler.Enter(
"JavaTypeImpl.GenerateMethod");
2392 if (index >= classFile.Methods.Length)
2395 if (methods[index].IsMirandaMethod)
2398 Debug.Assert(baseMethods[index].Length == 1 && baseMethods[index][0].DeclaringType.IsInterface);
2400 var mmw = (RuntimeMirandaJavaMethod)methods[index];
2401 var attr = MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.CheckAccessOnOverride;
2403 RuntimeJavaMethod baseMiranda =
null;
2404 bool baseMirandaOverrideStub =
false;
2406 if (wrapper.BaseTypeWrapper ==
null || (baseMiranda = wrapper.BaseTypeWrapper.GetMethod(mw.Name, mw.Signature,
true)) ==
null || !baseMiranda.IsMirandaMethod)
2409 attr |= MethodAttributes.NewSlot;
2414 if (CheckRequireOverrideStub(methods[index], baseMiranda))
2416 baseMirandaOverrideStub =
true;
2417 attr |= MethodAttributes.NewSlot;
2421 if (wrapper.IsInterface || (wrapper.IsAbstract && mmw.BaseMethod.IsAbstract && mmw.Error ==
null))
2423 attr |= MethodAttributes.Abstract;
2426 var mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, methods[index].
Name, attr);
2427 wrapper.Context.AttributeHelper.HideFromReflection(mb);
2429 if (baseMirandaOverrideStub)
2431 wrapper.GenerateOverrideStub(typeBuilder, baseMiranda, mb, methods[index]);
2434 if ((!wrapper.IsAbstract && mmw.BaseMethod.IsAbstract) || (!wrapper.IsInterface && mmw.Error !=
null))
2436 var message = mmw.Error ?? (wrapper.Name +
"." + methods[index].Name + methods[index].Signature);
2437 var ilgen = wrapper.Context.CodeEmitterFactory.Create(mb);
2438 ilgen.EmitThrow(mmw.IsConflictError ?
"java.lang.IncompatibleClassChangeError" :
"java.lang.AbstractMethodError", message);
2440 wrapper.EmitLevel4Warning(mmw.IsConflictError ?
HardError.IncompatibleClassChangeError :
HardError.AbstractMethodError, message);
2443 if (wrapper.IsInterface && !mmw.IsAbstract)
2446 wrapper.Context.AttributeHelper.SetModifiers(mb, mmw.Modifiers,
false);
2453 throw new InvalidOperationException();
2457 var m = classFile.Methods[index];
2458 MethodBuilder method;
2461 bool setModifiers = m.IsPrivate && HasNestmates();
2463 if (methods[index].HasCallerID && (m.Modifiers &
Modifiers.VarArgs) != 0)
2467 setModifiers =
true;
2470 if (m.IsConstructor)
2472 method = GenerateConstructor(methods[index]);
2476 setModifiers =
true;
2478 else if (m.IsClassInitializer)
2480 method = ReflectUtil.DefineTypeInitializer(typeBuilder, wrapper.classLoader);
2484 method = GenerateMethod(index, m,
ref setModifiers);
2488 var exceptions = m.ExceptionsAttribute;
2489 methods[index].SetDeclaredExceptions(exceptions);
2492 wrapper.Context.AttributeHelper.SetThrowsAttribute(method, exceptions);
2494 if (setModifiers || m.IsInternal || (m.Modifiers & (
Modifiers.Synthetic |
Modifiers.Bridge)) != 0)
2495 wrapper.Context.AttributeHelper.SetModifiers(method, m.Modifiers, m.IsInternal);
2498 if ((m.Modifiers & (
Modifiers.Synthetic |
Modifiers.Bridge)) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic && !IsAccessBridge(classFile, m))
2500 wrapper.Context.AttributeHelper.SetCompilerGenerated(method);
2501 wrapper.Context.AttributeHelper.SetEditorBrowsableNever(method);
2505 if (m.DeprecatedAttribute && !Annotation.HasObsoleteAttribute(m.Annotations))
2507 wrapper.Context.AttributeHelper.SetDeprecatedAttribute(method);
2511 if (m.GenericSignature !=
null)
2513 wrapper.Context.AttributeHelper.SetSignatureAttribute(method, m.GenericSignature);
2516 if (wrapper.ClassLoader.NoParameterReflection)
2520 else if (m.MalformedMethodParameters)
2522 wrapper.Context.AttributeHelper.SetMethodParametersAttribute(method,
null);
2524 else if (m.MethodParameters !=
null)
2526 var modifiers =
new Modifiers[m.MethodParameters.Length];
2527 for (
int i = 0; i < modifiers.Length; i++)
2528 modifiers[i] = (
Modifiers)m.MethodParameters[i].accessFlags;
2530 wrapper.Context.AttributeHelper.SetMethodParametersAttribute(method, modifiers);
2534 if (m.RuntimeVisibleTypeAnnotations.Count > 0)
2535 wrapper.Context.AttributeHelper.SetRuntimeVisibleTypeAnnotationsAttribute(method, in m.RuntimeVisibleTypeAnnotations);
2550 Profiler.Leave(
"JavaTypeImpl.GenerateMethod");
2554 private bool HasSerialVersionUID
2558 foreach (var field
in fields)
2559 if (field.IsSerialVersionUID)
2566 MethodBuilder GenerateConstructor(RuntimeJavaMethod mw)
2568 return mw.GetDefineMethodHelper().DefineConstructor(wrapper, typeBuilder, GetMethodAccess(mw) | MethodAttributes.HideBySig);
2571 MethodBuilder GenerateMethod(
int index, ClassFile.Method m,
ref bool setModifiers)
2573 var attribs = MethodAttributes.HideBySig;
2576 if (wrapper.IsPInvokeMethod(m))
2580 attribs |= MethodAttributes.PinvokeImpl;
2584 setModifiers =
true;
2587 if (methods[index].IsPropertyAccessor)
2589 attribs |= GetPropertyAccess(methods[index]);
2590 attribs |= MethodAttributes.SpecialName;
2591 setModifiers =
true;
2595 attribs |= GetMethodAccess(methods[index]);
2598 if (m.IsAbstract || (!m.IsStatic && m.IsPublic && classFile.IsInterface))
2603 if (classFile.IsAbstract)
2605 if (classFile.IsPublic && !classFile.IsFinal && !(m.IsPublic || m.IsProtected))
2607 setModifiers =
true;
2613 setModifiers =
true;
2615 attribs |= MethodAttributes.Abstract;
2620 setModifiers =
true;
2627 attribs |= MethodAttributes.Final;
2631 setModifiers =
true;
2636 attribs |= MethodAttributes.Static;
2637 if (m.IsSynchronized)
2639 setModifiers =
true;
2642 else if (!m.IsPrivate)
2644 attribs |= MethodAttributes.Virtual | MethodAttributes.CheckAccessOnOverride;
2646 string name = UnicodeUtil.EscapeInvalidSurrogates(m.Name);
2647 if (!ReferenceEquals(name, m.Name))
2650 attribs |= MethodAttributes.SpecialName;
2653 if ((m.Modifiers &
Modifiers.Bridge) != 0 && (m.IsPublic || m.IsProtected) && wrapper.IsPublic)
2655 string sigbase = m.Signature.Substring(0, m.Signature.LastIndexOf(
')') + 1);
2656 foreach (var mw
in methods)
2658 if (mw.Name == m.Name && mw.Signature.StartsWith(sigbase) && mw.Signature != m.Signature)
2662 name = NamePrefix.Bridge + name;
2668 if ((attribs & MethodAttributes.Virtual) != 0 && !classFile.IsInterface)
2670 if (baseMethods[index] ==
null || (baseMethods[index].Length == 1 && baseMethods[index][0].DeclaringType.IsInterface))
2675 attribs |= MethodAttributes.NewSlot;
2681 bool hasPublicBaseMethod =
false;
2682 foreach (RuntimeJavaMethod baseMethodWrapper
in baseMethods[index])
2684 MethodBase baseMethod = baseMethodWrapper.GetMethod();
2685 if ((baseMethod.IsPublic && !m.IsPublic) ||
2686 ((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && !m.IsPublic && !m.IsProtected) ||
2687 (!m.IsPublic && !m.IsProtected && !baseMethodWrapper.DeclaringType.IsPackageAccessibleFrom(wrapper)))
2689 hasPublicBaseMethod |= baseMethod.IsPublic;
2690 attribs &= ~MethodAttributes.MemberAccessMask;
2691 attribs |= hasPublicBaseMethod ? MethodAttributes.Public : MethodAttributes.FamORAssem;
2692 setModifiers =
true;
2697 MethodBuilder mb =
null;
2699 mb = wrapper.DefineGhostMethod(typeBuilder, name, attribs, methods[index]);
2703 bool needFinalize =
false;
2704 bool needDispatch =
false;
2706 if (baseMethods[index] !=
null && ReferenceEquals(m.Name, StringConstants.FINALIZE) && ReferenceEquals(m.Signature, StringConstants.SIG_VOID))
2708 baseFinalize = GetBaseFinalizeMethod(wrapper.BaseTypeWrapper);
2709 if (baseMethods[index][0].DeclaringType == wrapper.Context.JavaBase.TypeOfJavaLangObject)
2714 needFinalize =
true;
2715 needDispatch =
true;
2722 needFinalize =
true;
2723 needDispatch =
false;
2725 if (baseFinalize.DeclaringType == wrapper.Context.Types.Object)
2727 needDispatch =
true;
2735 if (baseFinalize.DeclaringType == wrapper.Context.Types.Object)
2737 needFinalize =
true;
2738 needDispatch =
true;
2742 !m.IsAbstract && !m.IsNative &&
2743 (!m.IsFinal || classFile.IsFinal) &&
2744 m.Instructions.Length > 0 &&
2749 needFinalize =
false;
2752 bool newslot = baseMethods[index] !=
null
2753 && (methods[index].IsExplicitOverride || baseMethods[index][0].RealName != name || CheckRequireOverrideStub(methods[index], baseMethods[index][0]))
2757 attribs |= MethodAttributes.NewSlot;
2759 if (classFile.IsInterface && !m.IsPublic && !wrapper.IsGhost)
2761 var tb = typeBuilder;
2764 mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper, tb, name, attribs);
2770 mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(),
2771 tb, NamePrefix.PrivateInterfaceInstanceMethod + name, attribs | MethodAttributes.Static | MethodAttributes.SpecialName,
2772 typeBuilder,
false);
2774 wrapper.Context.AttributeHelper.SetNameSig(mb, m.Name, m.Signature);
2777 setModifiers =
true;
2781 mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper, typeBuilder, name, attribs);
2783 if (baseMethods[index] !=
null && !needFinalize)
2785 bool subsequent =
false;
2786 foreach (RuntimeJavaMethod baseMethod
in baseMethods[index])
2788 if (CheckRequireOverrideStub(methods[index], baseMethod))
2790 wrapper.GenerateOverrideStub(typeBuilder, baseMethod, mb, methods[index]);
2792 else if (subsequent || methods[index].IsExplicitOverride || baseMethod.RealName != name)
2794 typeBuilder.DefineMethodOverride(mb, (
MethodInfo)baseMethod.GetMethod());
2805 var finalizeName = baseFinalize.Name;
2806 var mwClash = wrapper.GetMethod(finalizeName, StringConstants.SIG_VOID,
true);
2807 if (mwClash !=
null && mwClash.GetMethod() != baseFinalize)
2808 finalizeName =
"__<Finalize>";
2810 var attr = MethodAttributes.HideBySig | MethodAttributes.Virtual;
2811 attr |= baseFinalize.IsPublic ? MethodAttributes.Public : MethodAttributes.Family;
2813 attr |= MethodAttributes.Final;
2815 finalizeMethod = typeBuilder.DefineMethod(finalizeName, attr, CallingConventions.Standard, wrapper.Context.Types.Void,
Type.EmptyTypes);
2816 if (finalizeName != baseFinalize.Name)
2817 typeBuilder.DefineMethodOverride(finalizeMethod, baseFinalize);
2819 wrapper.Context.AttributeHelper.HideFromJava(finalizeMethod);
2821 var ilgen = wrapper.Context.CodeEmitterFactory.Create(finalizeMethod);
2823 ilgen.Emit(OpCodes.Call, wrapper.Context.ByteCodeHelperMethods.SkipFinalizerOf);
2824 var skip = ilgen.DefineLabel();
2825 ilgen.EmitBrtrue(skip);
2829 ilgen.BeginExceptionBlock();
2830 ilgen.Emit(OpCodes.Ldarg_0);
2831 ilgen.Emit(OpCodes.Callvirt, mb);
2832 ilgen.EmitLeave(skip);
2833 ilgen.BeginCatchBlock(wrapper.Context.Types.Object);
2834 ilgen.EmitLeave(skip);
2835 ilgen.EndExceptionBlock();
2839 ilgen.Emit(OpCodes.Ldarg_0);
2840 ilgen.Emit(OpCodes.Call, baseFinalize);
2843 ilgen.MarkLabel(skip);
2844 ilgen.Emit(OpCodes.Ret);
2848 if (classFile.Methods[index].AnnotationDefault !=
null)
2850 var cab =
new CustomAttributeBuilder(wrapper.Context.Resolver.ResolveRuntimeType(
"IKVM.Attributes.AnnotationDefaultAttribute").AsReflection().GetConstructor([wrapper.Context.Types.Object]), [
AnnotationDefaultAttribute.Escape(classFile.Methods[index].AnnotationDefault)]);
2851 mb.SetCustomAttribute(cab);
2858 mb.SetImplementationFlags(mb.GetMethodImplementationFlags() | MethodImplAttributes.Synchronized);
2861 if (classFile.Methods[index].IsForceInline)
2862 mb.SetImplementationFlags(mb.GetMethodImplementationFlags() | MethodImplAttributes.AggressiveInlining);
2864 if (classFile.Methods[index].IsLambdaFormCompiled || classFile.Methods[index].IsLambdaFormHidden)
2867 if (classFile.Methods[index].IsLambdaFormCompiled)
2869 if (classFile.Methods[index].IsLambdaFormHidden)
2872 wrapper.Context.AttributeHelper.HideFromJava(mb, flags);
2875 if (classFile.IsInterface && methods[index].IsVirtual && !methods[index].IsAbstract)
2877 if (wrapper.IsGhost)
2879 RuntimeDefaultInterfaceJavaMethod.SetImpl(methods[index], methods[index].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(),
2880 typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.SpecialName,
2885 RuntimeDefaultInterfaceJavaMethod.SetImpl(methods[index], methods[index].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(),
2886 typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName,
2887 typeBuilder,
false));
2894 private MethodAttributes GetMethodAccess(RuntimeJavaMethod mw)
2896 switch (mw.Modifiers &
Modifiers.AccessMask)
2903 return HasNestmates() ? MethodAttributes.Assembly : MethodAttributes.Private;
2905 return MethodAttributes.FamORAssem;
2907 return MethodAttributes.Public;
2909 return MethodAttributes.Assembly;
2917 private static bool IsAccessBridge(ClassFile classFile, ClassFile.Method m)
2925 foreach (ClassFile.Method.Instruction instr in m.Instructions)
2929 ClassFile.ConstantPoolItemMI cpi = classFile.SafeGetMethodref(instr.Arg1);
2930 return cpi !=
null && cpi.Name == m.Name && cpi.Signature == m.Signature;
2946 internal override string GetGenericSignature()
2948 Debug.Fail(
"Unreachable code");
2952 internal override string[] GetEnclosingMethod()
2954 Debug.Fail(
"Unreachable code");
2958 internal override string GetGenericMethodSignature(
int index)
2960 Debug.Fail(
"Unreachable code");
2964 internal override string GetGenericFieldSignature(
int index)
2966 Debug.Fail(
"Unreachable code");
2970 internal override object[] GetDeclaredAnnotations()
2972 Debug.Fail(
"Unreachable code");
2976 internal override object GetMethodDefaultValue(
int index)
2978 Debug.Fail(
"Unreachable code");
2982 internal override object[] GetMethodAnnotations(
int index)
2984 Debug.Fail(
"Unreachable code");
2988 internal override object[][] GetParameterAnnotations(
int index)
2990 Debug.Fail(
"Unreachable code");
2994 internal override MethodParametersEntry[] GetMethodParameters(
int index)
2996 Debug.Fail(
"Unreachable code");
3000 internal override object[] GetFieldAnnotations(
int index)
3002 Debug.Fail(
"Unreachable code");
3006 internal override MethodInfo GetFinalizeMethod()
3008 return finalizeMethod;
3011 internal override object[] GetConstantPool()
3013 Debug.Fail(
"Unreachable code");
3017 internal override byte[] GetRawTypeAnnotations()
3019 Debug.Fail(
"Unreachable code");
3023 internal override byte[] GetMethodRawTypeAnnotations(
int index)
3025 Debug.Fail(
"Unreachable code");
3029 internal override byte[] GetFieldRawTypeAnnotations(
int index)
3031 Debug.Fail(
"Unreachable code");
3035 internal override RuntimeJavaType Host
3037 get {
return host; }
IKVM.Reflection.Type Type
IKVM.Reflection.ConstructorInfo ConstructorInfo
IKVM.Reflection.FieldInfo FieldInfo
IKVM.Reflection.MethodInfo MethodInfo
IKVM.Reflection.MethodBase MethodBase
global::java.lang.invoke.LambdaForm.Name Name
IKVM.Runtime.RuntimeByteCodeJavaType RuntimeDynamicOrImportJavaType
MemberFlags
Describes various options applied to a member.