25using System.Collections.Generic;
26using System.Diagnostics;
33#if IMPORTER || EXPORTER
39using System.Reflection;
40using System.Reflection.Emit;
53 internal abstract class RuntimeJavaType
56 internal const Modifiers UnloadableModifiersHack = Modifiers.Final | Modifiers.Interface |
Modifiers.Private;
57 internal const Modifiers VerifierTypeModifiersHack = Modifiers.Final |
Modifiers.Interface;
59 static readonly
object flagsLock =
new object();
61 readonly RuntimeContext context;
65 RuntimeJavaMethod[] methods;
66 RuntimeJavaField[] fields;
67#if !IMPORTER && !EXPORTER
68 java.lang.Class classObject;
79 internal RuntimeJavaType(RuntimeContext context,
TypeFlags flags,
Modifiers modifiers,
string name)
81 Profiler.Count(
"TypeWrapper");
83 this.context = context ??
throw new ArgumentNullException(nameof(context));
85 this.modifiers = modifiers;
86 this.name = name ==
null ? null :
string.Intern(name);
92 public RuntimeContext Context => context;
101 internal void EmitClassLiteral(CodeEmitter ilgen)
103 Debug.Assert(!this.IsPrimitive);
105 var type = GetClassLiteralType();
108 if (!this.IsFastClassLiteralSafe || IsForbiddenTypeParameterType(type))
111 while (ReflectUtil.IsVector(type))
114 type = type.GetElementType();
118 ilgen.Emit(OpCodes.Ldtoken, type);
119 context.CompilerFactory.GetClassFromTypeHandle.EmitCall(ilgen);
123 ilgen.Emit(OpCodes.Ldtoken, type);
124 ilgen.EmitLdc_I4(rank);
125 context.CompilerFactory.GetClassFromTypeHandle2.EmitCall(ilgen);
130 var classLiteralType = Context.Resolver.ResolveRuntimeType(
"IKVM.Runtime.ClassLiteral`1").AsReflection().MakeGenericType(type);
131 ilgen.Emit(OpCodes.Call, classLiteralType.GetProperty(
"Value").GetMethod);
137 private Type GetClassLiteralType()
139 Debug.Assert(!this.IsPrimitive);
141 RuntimeJavaType tw =
this;
144 var rank = tw.ArrayRank;
146 tw = tw.ElementTypeWrapper;
148 return RuntimeArrayJavaType.MakeArrayType(tw.TypeAsTBD, rank);
152 return tw.IsRemapped ? tw.TypeAsBaseType : tw.TypeAsTBD;
156 bool IsForbiddenTypeParameterType(
Type type)
159 return type == context.Types.Void
161 || type == context.Resolver.ResolveCoreType(typeof(ArgIterator).FullName).AsReflection()
163 || type == context.Resolver.ResolveCoreType(typeof(RuntimeArgumentHandle).FullName).AsReflection()
164 || type == context.Resolver.ResolveCoreType(typeof(TypedReference).FullName).AsReflection()
165 || type.ContainsGenericParameters
169 internal virtual bool IsFastClassLiteralSafe
171 get {
return false; }
174#if !IMPORTER && !EXPORTER
176 internal void SetClassObject(
java.
lang.Class classObject)
178 this.classObject = classObject;
181 internal java.lang.Class ClassObject
185 Debug.Assert(!IsUnloadable && !IsVerifierType);
187 if (classObject ==
null)
196 private java.lang.Class GetPrimitiveClass()
198 if (
this == context.PrimitiveJavaTypeFactory.BYTE)
202 else if (
this == context.PrimitiveJavaTypeFactory.CHAR)
206 else if (
this == context.PrimitiveJavaTypeFactory.DOUBLE)
210 else if (
this == context.PrimitiveJavaTypeFactory.FLOAT)
214 else if (
this == context.PrimitiveJavaTypeFactory.INT)
218 else if (
this == context.PrimitiveJavaTypeFactory.LONG)
222 else if (
this == context.PrimitiveJavaTypeFactory.SHORT)
226 else if (
this == context.PrimitiveJavaTypeFactory.BOOLEAN)
230 else if (
this == context.PrimitiveJavaTypeFactory.VOID)
236 throw new InvalidOperationException();
241 private void LazyInitClass()
245 if (classObject ==
null)
248 Debug.Assert(!IsDynamic);
250 java.lang.Class clazz;
252 if (!this.IsFastClassLiteralSafe)
254 if (this.IsPrimitive)
256 clazz = GetPrimitiveClass();
265 Type type = GetClassLiteralType();
266 if (IsForbiddenTypeParameterType(type))
272 clazz = (
java.
lang.Class)typeof(ClassLiteral<>).MakeGenericType(type).GetProperty(
"Value").GetGetMethod().Invoke(
null, Array.Empty<
object>());
275 clazz.typeWrapper =
this;
278 System.Threading.Interlocked.CompareExchange(
ref classObject, clazz,
null);
286 internal static void SetTypeWrapperHack(
object clazz, TypeWrapper type)
289 typeof(
java.
lang.Class).GetField(
"typeWrapper", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(clazz, type);
296 private static void ResolvePrimitiveTypeWrapperClasses(RuntimeContext context)
300 if (context.PrimitiveJavaTypeFactory.BYTE.ClassObject ==
null
301 || context.PrimitiveJavaTypeFactory.CHAR.ClassObject ==
null
302 || context.PrimitiveJavaTypeFactory.DOUBLE.ClassObject ==
null
303 || context.PrimitiveJavaTypeFactory.FLOAT.ClassObject ==
null
304 || context.PrimitiveJavaTypeFactory.INT.ClassObject ==
null
305 || context.PrimitiveJavaTypeFactory.LONG.ClassObject ==
null
306 || context.PrimitiveJavaTypeFactory.SHORT.ClassObject ==
null
307 || context.PrimitiveJavaTypeFactory.BOOLEAN.ClassObject ==
null
308 || context.PrimitiveJavaTypeFactory.VOID.ClassObject ==
null)
310 throw new InvalidOperationException();
315 internal static RuntimeJavaType FromClass(
java.
lang.Class clazz)
318 throw new NotImplementedException();
321 var tw = (RuntimeJavaType)(
object)clazz.typeWrapper;
324 var type = clazz.type;
327 ResolvePrimitiveTypeWrapperClasses(JVM.Context);
328 return FromClass(clazz);
331 if (type == typeof(
void) || type.IsPrimitive || JVM.Context.ClassLoaderFactory.IsRemappedType(type))
332 tw = JVM.Context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(type);
334 tw = JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(type);
336 clazz.typeWrapper = tw;
345 public override string ToString()
347 return GetType().Name +
"[" + name +
"]";
353 internal virtual RuntimeJavaType EnsureLoadable(RuntimeClassLoader loader)
367 internal bool HasIncompleteInterfaceImplementation
371 RuntimeJavaType baseWrapper = this.BaseTypeWrapper;
372 return (flags &
TypeFlags.HasIncompleteInterfaceImplementation) != 0 || (baseWrapper !=
null && baseWrapper.HasIncompleteInterfaceImplementation);
376 internal void SetHasIncompleteInterfaceImplementation()
378 SetTypeFlag(
TypeFlags.HasIncompleteInterfaceImplementation);
381 internal bool HasUnsupportedAbstractMethods
385 foreach (var iface
in this.Interfaces)
386 if (iface.HasUnsupportedAbstractMethods)
389 var baseWrapper = this.BaseTypeWrapper;
390 return (flags &
TypeFlags.HasUnsupportedAbstractMethods) != 0 || (baseWrapper !=
null && baseWrapper.HasUnsupportedAbstractMethods);
394 internal void SetHasUnsupportedAbstractMethods()
396 SetTypeFlag(
TypeFlags.HasUnsupportedAbstractMethods);
399 internal virtual bool HasStaticInitializer
403 return (flags &
TypeFlags.HasStaticInitializer) != 0;
407 internal void SetHasStaticInitializer()
409 SetTypeFlag(
TypeFlags.HasStaticInitializer);
412 internal bool HasVerifyError
416 return (flags &
TypeFlags.VerifyError) != 0;
420 internal void SetHasVerifyError()
425 internal bool HasClassFormatError
429 return (flags &
TypeFlags.ClassFormatError) != 0;
433 internal void SetHasClassFormatError()
438 internal virtual bool IsFakeTypeContainer
446 internal virtual bool IsFakeNestedType
455 internal bool IsUnsafeAnonymous
457 get {
return (flags &
TypeFlags.Anonymous) != 0; }
463 internal virtual bool IsGhost
472 internal bool IsGhostArray
476 return !IsUnloadable && IsArray && (ElementTypeWrapper.IsGhost || ElementTypeWrapper.IsGhostArray);
484 throw new InvalidOperationException();
488 internal virtual bool IsRemapped
496 internal bool IsArray
500 return name !=
null && name[0] ==
'[';
505 internal int ArrayRank
512 while (name[i] ==
'[')
521 internal virtual RuntimeJavaType GetUltimateElementTypeWrapper()
523 throw new InvalidOperationException();
526 internal bool IsNonPrimitiveValueType
530 return this != context.VerifierJavaTypeFactory.Null && !IsPrimitive && !IsGhost && TypeAsTBD.IsValueType;
534 internal bool IsPrimitive
542 internal bool IsWidePrimitive
546 return this == context.PrimitiveJavaTypeFactory.LONG ||
this == context.PrimitiveJavaTypeFactory.DOUBLE;
550 internal bool IsIntOnStackPrimitive
554 return name ==
null &&
555 (
this == context.PrimitiveJavaTypeFactory.BOOLEAN ||
556 this == context.PrimitiveJavaTypeFactory.BYTE ||
557 this == context.PrimitiveJavaTypeFactory.CHAR ||
558 this == context.PrimitiveJavaTypeFactory.SHORT ||
559 this == context.PrimitiveJavaTypeFactory.INT);
563 private static bool IsJavaPrimitive(RuntimeContext context,
Type type)
565 return type == context.PrimitiveJavaTypeFactory.BOOLEAN.TypeAsTBD
566 || type == context.PrimitiveJavaTypeFactory.BYTE.TypeAsTBD
567 || type == context.PrimitiveJavaTypeFactory.CHAR.TypeAsTBD
568 || type == context.PrimitiveJavaTypeFactory.DOUBLE.TypeAsTBD
569 || type == context.PrimitiveJavaTypeFactory.FLOAT.TypeAsTBD
570 || type == context.PrimitiveJavaTypeFactory.INT.TypeAsTBD
571 || type == context.PrimitiveJavaTypeFactory.LONG.TypeAsTBD
572 || type == context.PrimitiveJavaTypeFactory.SHORT.TypeAsTBD
573 || type == context.PrimitiveJavaTypeFactory.VOID.TypeAsTBD;
576 internal bool IsBoxedPrimitive
580 return !IsPrimitive && IsJavaPrimitive(Context, TypeAsSignatureType);
584 internal bool IsErasedOrBoxedPrimitiveOrRemapped
588 bool erased = IsUnloadable || IsGhostArray;
589 return erased || IsBoxedPrimitive || (IsRemapped &&
this is RuntimeManagedJavaType);
593 internal bool IsUnloadable
598 return modifiers == UnloadableModifiersHack;
602 internal bool IsVerifierType
607 return modifiers == VerifierTypeModifiersHack;
611 internal virtual bool IsMapUnsafeException
629 internal virtual Modifiers ReflectiveModifiers
637 internal bool IsInternal
641 return (flags &
TypeFlags.InternalAccess) != 0;
645 internal bool IsPublic
649 return (modifiers &
Modifiers.Public) != 0;
653 internal bool IsAbstract
662 internal bool IsFinal
666 return (modifiers &
Modifiers.Final) != 0;
670 internal bool IsInterface
674 Debug.Assert(!IsUnloadable && !IsVerifierType);
675 return (modifiers &
Modifiers.Interface) != 0;
683 internal bool IsInterfaceOrInterfaceArray
687 RuntimeJavaType tw =
this;
690 tw = tw.ElementTypeWrapper;
692 return tw.IsInterface;
699 internal abstract RuntimeClassLoader ClassLoader {
get; }
707 internal RuntimeJavaField GetFieldWrapper(
string fieldName,
string fieldSig)
709 foreach (var fw
in GetFields())
710 if (fw.Name == fieldName && fw.Signature == fieldSig)
713 foreach (var iface
in Interfaces)
715 var fw = iface.GetFieldWrapper(fieldName, fieldSig);
720 var baseWrapper = BaseTypeWrapper;
721 if (baseWrapper !=
null)
722 return baseWrapper.GetFieldWrapper(fieldName, fieldSig);
727 protected virtual void LazyPublishMembers()
729 methods ??= Array.Empty<RuntimeJavaMethod>();
730 fields ??= Array.Empty<RuntimeJavaField>();
733 protected virtual void LazyPublishMethods()
735 LazyPublishMembers();
738 protected virtual void LazyPublishFields()
740 LazyPublishMembers();
747 internal RuntimeJavaMethod[] GetMethods()
756 if (IsUnloadable || !CheckMissingBaseTypes(Context, TypeAsBaseType))
757 return methods = Array.Empty<RuntimeJavaMethod>();
759 LazyPublishMethods();
771 internal RuntimeJavaField[] GetFields()
780 if (IsUnloadable || !CheckMissingBaseTypes(Context, TypeAsBaseType))
781 return fields = Array.Empty<RuntimeJavaField>();
794 private static bool CheckMissingBaseTypes(RuntimeContext context,
Type type)
798 if (type.__ContainsMissingType)
800 context.StaticCompiler.IssueMissingTypeMessage(type);
804 foreach (
Type iface
in type.__GetDeclaredInterfaces())
806 ok &= CheckMissingBaseTypes(context, iface);
812 type = type.BaseType;
826 internal RuntimeJavaMethod GetMethod(
string name,
string desc,
bool inherit)
829 name =
string.Intern(name);
830 desc =
string.Intern(desc);
833 foreach (var method
in GetMethods())
834 if (ReferenceEquals(method.Name, name) && ReferenceEquals(method.Signature, desc))
837 var baseWrapper = BaseTypeWrapper;
838 if (inherit && baseWrapper !=
null)
839 return baseWrapper.GetMethod(name, desc, inherit);
844 internal RuntimeJavaMethod GetInterfaceMethod(
string name,
string sig)
846 var method = GetMethod(name, sig,
false);
852 var interfaces = Interfaces;
853 for (
int i = 0; i < interfaces.Length; i++)
855 method = interfaces[i].GetInterfaceMethod(name, sig);
865 internal void SetMethods(RuntimeJavaMethod[] methods)
867 Debug.Assert(methods !=
null);
868 System.Threading.Thread.MemoryBarrier();
869 this.methods = methods;
872 internal void SetFields(RuntimeJavaField[] fields)
874 Debug.Assert(fields !=
null);
875 System.Threading.Thread.MemoryBarrier();
876 this.fields = fields;
879 internal string Name => name;
884 internal virtual string SigName =>
"L" +
Name +
";";
887 internal bool IsAccessibleFrom(RuntimeJavaType wrapper)
890 || (IsInternal && InternalsVisibleTo(wrapper))
891 || IsPackageAccessibleFrom(wrapper);
894 internal bool InternalsVisibleTo(RuntimeJavaType wrapper)
896 return ClassLoader.InternalsVisibleToImpl(
this, wrapper);
899 internal virtual bool IsPackageAccessibleFrom(RuntimeJavaType wrapper)
901 if (MatchingPackageNames(name, wrapper.name))
909 return ccl.IsEquivalentTo(wrapper.ClassLoader);
912 return ClassLoader == wrapper.ClassLoader;
920 static bool MatchingPackageNames(
string name1,
string name2)
922 int index1 = name1.LastIndexOf(
'.');
923 int index2 = name2.LastIndexOf(
'.');
924 if (index1 == -1 && index2 == -1)
930 while (name1[skip1] ==
'[')
934 while (name2[skip2] ==
'[')
948 if ((index1 - skip1) != (index2 - skip2))
953 return string.CompareOrdinal(name1, skip1, name2, skip2, index1 - skip1) == 0;
956 internal abstract Type TypeAsTBD
961 internal Type TypeAsSignatureType
966 return ((RuntimeUnloadableJavaType)
this).MissingType ?? context.Types.Object;
969 return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank);
975 internal Type TypeAsPublicSignatureType => (IsPublic ? this : GetPublicBaseTypeWrapper()).TypeAsSignatureType;
977 internal virtual Type TypeAsBaseType => TypeAsTBD;
979 internal Type TypeAsLocalOrStackType
983 if (IsUnloadable || IsGhost)
984 return context.Types.Object;
986 if (IsNonPrimitiveValueType)
989 return TypeAsTBD.BaseType;
993 return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank);
1000 internal Type TypeAsArrayType
1004 if (IsUnloadable || IsGhost)
1005 return context.Types.Object;
1008 return RuntimeArrayJavaType.MakeArrayType(context.Types.Object, ArrayRank);
1014 internal Type TypeAsExceptionType
1019 return context.Types.Exception;
1025 internal abstract RuntimeJavaType BaseTypeWrapper
1030 internal RuntimeJavaType ElementTypeWrapper
1034 Debug.Assert(IsUnloadable ==
false);
1035 Debug.Assert(
this == context.VerifierJavaTypeFactory.Null || IsArray);
1037 if (
this == context.VerifierJavaTypeFactory.Null)
1039 return context.VerifierJavaTypeFactory.Null;
1048 return ClassLoader.TryLoadClassByName(name.Substring(1));
1052 return ClassLoader.TryLoadClassByName(name.Substring(2, name.Length - 3));
1054 return context.PrimitiveJavaTypeFactory.BOOLEAN;
1056 return context.PrimitiveJavaTypeFactory.BYTE;
1058 return context.PrimitiveJavaTypeFactory.SHORT;
1060 return context.PrimitiveJavaTypeFactory.CHAR;
1062 return context.PrimitiveJavaTypeFactory.INT;
1064 return context.PrimitiveJavaTypeFactory.LONG;
1066 return context.PrimitiveJavaTypeFactory.FLOAT;
1068 return context.PrimitiveJavaTypeFactory.DOUBLE;
1070 throw new InvalidOperationException(name);
1075 internal RuntimeJavaType MakeArrayType(
int rank)
1077 Debug.Assert(rank != 0);
1079 return ClassLoader.TryLoadClassByName(
new String(
'[', rank) + this.SigName);
1087 internal bool ImplementsInterface(RuntimeJavaType iface)
1091 while (
self !=
null)
1093 var interfaces =
self.Interfaces;
1095 for (
int i = 0; i < interfaces.Length; i++)
1097 if (interfaces[i] == iface)
1100 if (interfaces[i].ImplementsInterface(iface))
1104 self =
self.BaseTypeWrapper;
1110 internal bool IsSubTypeOf(RuntimeJavaType baseType)
1113 Debug.Assert(!this.IsPrimitive);
1114 Debug.Assert(!baseType.IsPrimitive);
1116 Debug.Assert(!this.IsUnloadable);
1117 Debug.Assert(!baseType.IsUnloadable);
1119 if (baseType.IsInterface)
1121 if (baseType ==
this)
1125 return ImplementsInterface(baseType);
1128 if (baseType == Context.JavaBase.TypeOfJavaLangObject)
1132 RuntimeJavaType subType =
this;
1133 while (subType != baseType)
1135 subType = subType.BaseTypeWrapper;
1136 if (subType ==
null)
1144 internal bool IsAssignableTo(RuntimeJavaType wrapper)
1146 if (
this == wrapper)
1150 if (this.IsPrimitive || wrapper.IsPrimitive)
1154 if (
this == context.VerifierJavaTypeFactory.Null)
1158 if (wrapper.IsInterface)
1160 return ImplementsInterface(wrapper);
1162 int rank1 = this.ArrayRank;
1163 int rank2 = wrapper.ArrayRank;
1164 if (rank1 > 0 && rank2 > 0)
1168 RuntimeJavaType elem1 = this.ElementTypeWrapper;
1169 RuntimeJavaType elem2 = wrapper.ElementTypeWrapper;
1170 while (rank1 != 0 && rank2 != 0)
1172 elem1 = elem1.ElementTypeWrapper;
1173 elem2 = elem2.ElementTypeWrapper;
1177 if (elem1.IsPrimitive || elem2.IsPrimitive)
1181 return (!elem1.IsNonPrimitiveValueType && elem1.IsSubTypeOf(elem2));
1183 return this.IsSubTypeOf(wrapper);
1186#if !IMPORTER && !EXPORTER
1187 internal bool IsInstance(
object obj)
1191 RuntimeJavaType thisWrapper =
this;
1193 return objWrapper.IsAssignableTo(thisWrapper);
1199 internal virtual RuntimeJavaType[] Interfaces => Array.Empty<RuntimeJavaType>();
1202 internal virtual RuntimeJavaType[] InnerClasses => Array.Empty<RuntimeJavaType>();
1205 internal virtual RuntimeJavaType DeclaringTypeWrapper =>
null;
1207 internal virtual void Finish()
1212 internal void LinkAll()
1216 RuntimeJavaType tw = BaseTypeWrapper;
1221 foreach (RuntimeJavaType iface
in Interfaces)
1225 foreach (RuntimeJavaMethod mw
in GetMethods())
1229 foreach (RuntimeJavaField fw
in GetFields())
1238 [Conditional(
"DEBUG")]
1239 internal static void AssertFinished(
Type type)
1243 while (type.HasElementType)
1245 type = type.GetElementType();
1247 Debug.Assert(!(type is TypeBuilder));
1252#if !IMPORTER && !EXPORTER
1254 internal void RunClassInit()
1256 Type t = IsRemapped ? TypeAsBaseType : TypeAsTBD;
1267 internal void EmitUnbox(CodeEmitter ilgen)
1269 Debug.Assert(this.IsNonPrimitiveValueType);
1271 ilgen.EmitUnboxSpecial(this.TypeAsTBD);
1274 internal void EmitBox(CodeEmitter ilgen)
1276 Debug.Assert(this.IsNonPrimitiveValueType);
1278 ilgen.Emit(OpCodes.Box,
this.TypeAsTBD);
1281 internal void EmitConvSignatureTypeToStackType(CodeEmitter ilgen)
1286 else if (
this == context.PrimitiveJavaTypeFactory.BYTE)
1288 ilgen.Emit(OpCodes.Conv_I1);
1290 else if (IsNonPrimitiveValueType)
1296 CodeEmitterLocal local = ilgen.DeclareLocal(TypeAsSignatureType);
1297 ilgen.Emit(OpCodes.Stloc, local);
1298 ilgen.Emit(OpCodes.Ldloca, local);
1299 ilgen.Emit(OpCodes.Ldfld, GhostRefField);
1305 internal void EmitConvStackTypeToSignatureType(CodeEmitter ilgen, RuntimeJavaType sourceType)
1311 CodeEmitterLocal local1 = ilgen.DeclareLocal(TypeAsLocalOrStackType);
1312 ilgen.Emit(OpCodes.Stloc, local1);
1313 CodeEmitterLocal local2 = ilgen.DeclareLocal(TypeAsSignatureType);
1314 ilgen.Emit(OpCodes.Ldloca, local2);
1315 ilgen.Emit(OpCodes.Ldloc, local1);
1316 ilgen.Emit(OpCodes.Stfld, GhostRefField);
1317 ilgen.Emit(OpCodes.Ldloca, local2);
1318 ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
1322 else if (IsInterfaceOrInterfaceArray && (sourceType ==
null || sourceType.IsUnloadable || !sourceType.IsAssignableTo(
this)))
1324 ilgen.EmitAssertType(TypeAsTBD);
1325 Profiler.Count(
"InterfaceDownCast");
1327 else if (IsNonPrimitiveValueType)
1331 else if (sourceType !=
null && sourceType.IsUnloadable)
1333 ilgen.Emit(OpCodes.Castclass, TypeAsSignatureType);
1338 internal virtual void EmitCheckcast(CodeEmitter ilgen)
1342 ilgen.Emit(OpCodes.Dup);
1346 ilgen.Emit(OpCodes.Call, TypeAsTBD.GetMethod(
"Cast"));
1347 ilgen.Emit(OpCodes.Pop);
1349 else if (IsGhostArray)
1351 ilgen.Emit(OpCodes.Dup);
1355 RuntimeJavaType tw =
this;
1360 tw = tw.ElementTypeWrapper;
1362 ilgen.EmitLdc_I4(rank);
1363 ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod(
"CastArray"));
1364 ilgen.Emit(OpCodes.Castclass, RuntimeArrayJavaType.MakeArrayType(context.Types.Object, rank));
1368 ilgen.EmitCastclass(TypeAsTBD);
1372 internal virtual void EmitInstanceOf(CodeEmitter ilgen)
1379 ilgen.Emit(OpCodes.Call, TypeAsTBD.GetMethod(
"IsInstance"));
1381 else if (IsGhostArray)
1386 RuntimeJavaType tw =
this;
1391 tw = tw.ElementTypeWrapper;
1393 ilgen.EmitLdc_I4(rank);
1394 ilgen.Emit(OpCodes.Call, tw.TypeAsTBD.GetMethod(
"IsInstanceArray"));
1398 ilgen.Emit_instanceof(TypeAsTBD);
1406 internal virtual void EmitLdind(CodeEmitter il)
1408 if (
this == context.PrimitiveJavaTypeFactory.BOOLEAN)
1409 il.Emit(OpCodes.Ldind_U1);
1410 else if (
this == context.PrimitiveJavaTypeFactory.BYTE)
1411 il.Emit(OpCodes.Ldind_U1);
1412 else if (
this == context.PrimitiveJavaTypeFactory.CHAR)
1413 il.Emit(OpCodes.Ldind_U2);
1414 else if (
this == context.PrimitiveJavaTypeFactory.SHORT)
1415 il.Emit(OpCodes.Ldind_I2);
1416 else if (
this == context.PrimitiveJavaTypeFactory.INT)
1417 il.Emit(OpCodes.Ldind_I4);
1418 else if (
this == context.PrimitiveJavaTypeFactory.LONG)
1419 il.Emit(OpCodes.Ldind_I8);
1420 else if (
this == context.PrimitiveJavaTypeFactory.FLOAT)
1421 il.Emit(OpCodes.Ldind_R4);
1422 else if (
this == context.PrimitiveJavaTypeFactory.DOUBLE)
1423 il.Emit(OpCodes.Ldind_R8);
1425 il.Emit(OpCodes.Ldind_Ref);
1432 internal virtual void EmitStind(CodeEmitter il)
1434 if (
this == context.PrimitiveJavaTypeFactory.BOOLEAN)
1435 il.Emit(OpCodes.Stind_I1);
1436 else if (
this == context.PrimitiveJavaTypeFactory.BYTE)
1437 il.Emit(OpCodes.Stind_I1);
1438 else if (
this == context.PrimitiveJavaTypeFactory.CHAR)
1439 il.Emit(OpCodes.Stind_I2);
1440 else if (
this == context.PrimitiveJavaTypeFactory.SHORT)
1441 il.Emit(OpCodes.Stind_I2);
1442 else if (
this == context.PrimitiveJavaTypeFactory.INT)
1443 il.Emit(OpCodes.Stind_I4);
1444 else if (
this == context.PrimitiveJavaTypeFactory.LONG)
1445 il.Emit(OpCodes.Stind_I8);
1446 else if (
this == context.PrimitiveJavaTypeFactory.FLOAT)
1447 il.Emit(OpCodes.Stind_R4);
1448 else if (
this == context.PrimitiveJavaTypeFactory.DOUBLE)
1449 il.Emit(OpCodes.Stind_R8);
1451 il.Emit(OpCodes.Stind_Ref);
1457 internal virtual MethodBase LinkMethod(RuntimeJavaMethod mw)
1459 return mw.GetMethod();
1463 internal virtual FieldInfo LinkField(RuntimeJavaField fw)
1465 return fw.GetField();
1469 internal virtual void EmitRunClassConstructor(CodeEmitter ilgen)
1474 internal virtual string GetGenericSignature()
1479 internal virtual string GetGenericMethodSignature(RuntimeJavaMethod mw)
1484 internal virtual string GetGenericFieldSignature(RuntimeJavaField fw)
1489 internal virtual MethodParametersEntry[] GetMethodParameters(RuntimeJavaMethod mw)
1494#if !IMPORTER && !EXPORTER
1495 internal virtual string[] GetEnclosingMethod()
1500 internal virtual object[] GetDeclaredAnnotations()
1505 internal virtual object[] GetMethodAnnotations(RuntimeJavaMethod mw)
1510 internal virtual object[][] GetParameterAnnotations(RuntimeJavaMethod mw)
1515 internal virtual object[] GetFieldAnnotations(RuntimeJavaField fw)
1520 internal virtual string GetSourceFileName()
1525 internal virtual int GetSourceLineNumber(
MethodBase mb,
int ilOffset)
1530 internal virtual object GetAnnotationDefault(RuntimeJavaMethod mw)
1536 if (attr.Length == 1)
1538 return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, ((
AnnotationDefaultAttribute)attr[0]).Value);
1545 internal virtual Annotation Annotation =>
null;
1547 internal virtual Type EnumType =>
null;
1549 private static Type[] GetInterfaces(
Type type)
1551#if IMPORTER || EXPORTER
1552 List<Type> list =
new List<Type>();
1553 for (; type !=
null && !type.__IsMissing; type = type.BaseType)
1555 AddInterfaces(list, type);
1557 return list.ToArray();
1559 return type.GetInterfaces();
1563#if IMPORTER || EXPORTER
1565 private static void AddInterfaces(List<Type> list,
Type type)
1567 foreach (var iface
in type.__GetDeclaredInterfaces())
1569 if (!list.Contains(iface))
1572 if (!iface.__IsMissing)
1574 AddInterfaces(list, iface);
1582 protected static RuntimeJavaType[] GetImplementedInterfacesAsTypeWrappers(RuntimeContext context,
Type type)
1584 var interfaceTypes = GetInterfaces(type);
1585 var interfaces =
new RuntimeJavaType[interfaceTypes.Length];
1587 for (
int i = 0; i < interfaceTypes.Length; i++)
1589 var decl = interfaceTypes[i].DeclaringType;
1590 if (decl !=
null && context.AttributeHelper.IsGhostInterface(decl))
1593 interfaces[i] = context.ClassLoaderFactory.GetJavaTypeFromType(decl);
1597 interfaces[i] = context.ClassLoaderFactory.GetJavaTypeFromType(interfaceTypes[i]);
1601 for (
int i = 0; i < interfaceTypes.Length; i++)
1603 if (interfaces[i].IsRemapped)
1606 var twRemapped = interfaces[i];
1607 var tw = context.ManagedJavaTypeFactory.GetJavaTypeFromManagedType(interfaceTypes[i]);
1609 if (Array.IndexOf(interfaces, twRemapped) == -1)
1610 interfaces = ArrayUtil.Concat(interfaces, twRemapped);
1617 internal RuntimeJavaType GetPublicBaseTypeWrapper()
1619 Debug.Assert(!IsPublic);
1621 if (IsUnloadable || IsInterface)
1622 return Context.JavaBase.TypeOfJavaLangObject;
1624 for (var tw =
this; ; tw = tw.BaseTypeWrapper)
1632 internal virtual MethodBase GetSerializationConstructor()
1634 return TypeAsBaseType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,
null, [context.Resolver.ResolveCoreType(typeof(
System.
Runtime.
Serialization.SerializationInfo).FullName).AsReflection(), context.Resolver.ResolveCoreType(typeof(
System.
Runtime.
Serialization.StreamingContext).FullName).AsReflection()],
null);
1637 internal virtual MethodBase GetBaseSerializationConstructor()
1639 return BaseTypeWrapper.GetSerializationConstructor();
1644#if !IMPORTER && !EXPORTER
1645 internal virtual object GhostWrap(
object obj)
1650 internal virtual object GhostUnwrap(
object obj)
1656 internal bool IsDynamic
1659 get {
return false; }
1661 get {
return this is RuntimeByteCodeJavaType; }
1665 internal virtual object[] GetConstantPool()
1670 internal virtual byte[] GetRawTypeAnnotations()
1675 internal virtual byte[] GetMethodRawTypeAnnotations(RuntimeJavaMethod mw)
1680 internal virtual byte[] GetFieldRawTypeAnnotations(RuntimeJavaField fw)
1685#if !IMPORTER && !EXPORTER
1686 internal virtual RuntimeJavaType Host
1688 get {
return null; }
IKVM.Reflection.Type Type
IKVM.Reflection.FieldInfo FieldInfo
IKVM.Reflection.MethodBase MethodBase
global::java.lang.invoke.LambdaForm.Name Name
Exposes methods to accept diagnostic invocations.