65#if !IMPORTER && !FIRST_PASS && !EXPORTER
67 ClassLoaderAccessor classLoaderAccessor;
68 ClassLoaderAccessor ClassLoaderAccessor =>
JVM.
Internal.BaseAccessors.Get(
ref classLoaderAccessor);
77 readonly Dictionary<string, RuntimeJavaType> types =
new Dictionary<string, RuntimeJavaType>();
78 readonly Dictionary<string, Thread> defineClassInProgress =
new Dictionary<string, Thread>();
79 List<IntPtr> nativeLibraries;
90 this.context = context ??
throw new ArgumentNullException(nameof(context));
91 this.codegenoptions = codegenoptions;
92#if !IMPORTER && !FIRST_PASS && !EXPORTER
102#if IMPORTER || EXPORTER
104 internal void SetRemappedType(
Type type, RuntimeJavaType tw)
107 types.Add(tw.Name, tw);
124 internal RuntimeJavaType FindLoadedClass(
string name)
126 if (name.Length > 1 && name[0] ==
'[')
127 return FindOrLoadArrayClass(name,
LoadMode.Find);
131 types.TryGetValue(name, out tw);
141 internal RuntimeJavaType RegisterInitiatingLoader(RuntimeJavaType tw)
143 Debug.Assert(tw !=
null);
144 Debug.Assert(!tw.IsUnloadable);
145 Debug.Assert(!tw.IsPrimitive);
153 tw = RegisterInitiatingLoaderCritical(tw);
159 RuntimeJavaType RegisterInitiatingLoaderCritical(RuntimeJavaType tw)
163 types.TryGetValue(tw.Name, out var existing);
166 if (existing !=
null)
184 internal bool EmitSymbols => (codegenoptions &
CodeGenOptions.EmitSymbols) != 0;
186 internal bool EmitStackTraceInfo => (codegenoptions &
CodeGenOptions.NoStackTraceInfo) == 0;
188 internal bool StrictFinalFieldSemantics => (codegenoptions &
CodeGenOptions.StrictFinalFieldSemantics) != 0;
190 internal bool NoJNI => (codegenoptions &
CodeGenOptions.NoJNI) != 0;
192 internal bool RemoveAsserts => (codegenoptions &
CodeGenOptions.RemoveAsserts) != 0;
194 internal bool NoAutomagicSerialization => (codegenoptions &
CodeGenOptions.NoAutomagicSerialization) != 0;
196 internal bool DisableDynamicBinding => (codegenoptions &
CodeGenOptions.DisableDynamicBinding) != 0;
198 internal bool EmitNoRefEmitHelpers => (codegenoptions &
CodeGenOptions.NoRefEmitHelpers) != 0;
200 internal bool RemoveUnusedFields => (codegenoptions &
CodeGenOptions.RemoveUnusedFields) != 0;
202 internal bool EnableOptimizations => (codegenoptions &
CodeGenOptions.DisableOptimizations) == 0;
204#if !IMPORTER && !EXPORTER
205#if FIRST_PASS == false
213 internal bool IsTrusted
217 var scl = ClassLoaderAccessor.GetScl();
220 for (var cl = scl; cl !=
null; cl = ClassLoaderAccessor.GetParent(cl))
230 internal bool RelaxedClassNameValidation
237 return JVM.RelaxedVerification && (
javaClassLoader ==
null || IsTrusted);
246 if (className.StartsWith(
"java.", StringComparison.Ordinal))
247 throw new JavaSecurityException(
"Prohibited package name: " + className.Substring(0, className.LastIndexOf(
'.')));
254 var dotnetAssembly = f.IKVMAssemblyAttribute;
255 if (dotnetAssembly !=
null)
270 var tw = loader.TryLoadClassByName(f.Name);
274 return RegisterInitiatingLoader(tw);
281 throw new LinkageError(
"duplicate class definition: " + f.Name);
290 def = DefineClassCritical(f, protectionDomain);
300 if (types.ContainsKey(classFile.Name))
301 throw new LinkageError($
"duplicate class definition: {classFile.Name}");
304 types.Add(classFile.Name,
null);
305 defineClassInProgress.Add(classFile.Name, Thread.CurrentThread);
309 return GetTypeWrapperFactory().DefineClassImpl(types,
null, classFile,
this, protectionDomain);
315 if (types[classFile.Name] ==
null)
319 types.Remove(classFile.Name);
321 defineClassInProgress.Remove(classFile.Name);
322 Monitor.PulseAll(types);
349 internal RuntimeJavaType LoadClassByName(
string name)
351 return LoadClass(name,
LoadMode.LoadOrThrow);
354 internal RuntimeJavaType TryLoadClassByName(
string name)
356 return LoadClass(name,
LoadMode.LoadOrNull);
359 internal RuntimeJavaType LoadClass(
string name,
LoadMode mode)
365 var javaType = LoadRegisteredOrPendingClass(name);
366 if (javaType !=
null)
369 if (name.Length > 1 && name[0] ==
'[')
370 javaType = FindOrLoadArrayClass(name, mode);
374 if (javaType !=
null)
375 return RegisterInitiatingLoader(javaType);
377 if (!(name.Length > 1 && name[0] ==
'[') && ((mode &
LoadMode.WarnClassNotFound) != 0) || WarningLevelHigh)
378 Diagnostics.ClassNotFound(name);
380 return (mode &
LoadMode.MaskReturn)
switch
382 LoadMode.ReturnNull =>
null,
385 _ =>
throw new InvalidOperationException(),
394 RuntimeJavaType LoadRegisteredOrPendingClass(
string name)
396 RuntimeJavaType javaType;
400 if (types.TryGetValue(name, out javaType) && javaType ==
null)
402 if (defineClassInProgress.TryGetValue(name, out var defineThread))
404 if (Thread.CurrentThread == defineThread)
408 while (defineClassInProgress.ContainsKey(name))
412 types.TryGetValue(name, out javaType);
426 RuntimeJavaType FindOrLoadArrayClass(
string name,
LoadMode mode)
430 while (name[pos] ==
'[')
431 if (++pos == name.Length)
435 if (name[pos] ==
'L')
438 if (name.EndsWith(
";") ==
false || name.Length <= pos + 2 || name[pos + 1] ==
'[')
441 var elemClass = name.Substring(pos + 1, name.Length - pos - 2);
444 var type = LoadClass(elemClass, mode |
LoadMode.DontReturnUnloadable);
446 type = CreateArrayType(name, type, pos);
451 if (name.Length != pos + 1)
455 return name[pos]
switch
469 internal RuntimeJavaType FindOrLoadGenericClass(
string name,
LoadMode mode)
478 var outer = FindOrLoadGenericClass(name.Substring(0, name.Length -
RuntimeManagedJavaType.DelegateInterfaceSuffix.Length), mode);
479 if (outer !=
null && outer.IsFakeTypeContainer)
480 foreach (var javaType
in outer.InnerClasses)
481 if (javaType.Name == name)
492 var pos = name.IndexOf(
"_$$$_");
493 if (pos <= 0 || !name.EndsWith(
"_$$$$_"))
496 var def = LoadClass(name.Substring(0, pos), mode);
497 if (def ==
null || !def.TypeAsTBD.IsGenericTypeDefinition)
500 var type = def.TypeAsTBD;
501 var typeParamNames =
new List<string>();
507 pos = name.IndexOf(
"_$$", pos);
511 if (name.IndexOf(
"_$$_", pos, 4) == pos)
515 typeParamNames.Add(name.Substring(start, pos - start));
521 else if (name.IndexOf(
"_$$$_", pos, 5) == pos)
526 else if (name.IndexOf(
"_$$$$_", pos, 6) == pos)
530 if (pos + 6 != name.Length)
534 typeParamNames.Add(name.Substring(start, pos - start));
546 var typeArguments =
new Type[typeParamNames.Count];
547 for (
int i = 0; i < typeArguments.Length; i++)
549 var s = typeParamNames[i];
552 if (s.IndexOf(
"_$$$_") == -1)
554 s = s.Replace(
"__",
".");
555 s = s.Replace(
"$$005F$$005F",
"__");
559 while (s.Length > dims && s[dims] ==
'A')
562 if (s.Length == dims)
569 tw = LoadClass(s.Substring(dims + 1), mode);
605 tw = tw.MakeArrayType(dims);
607 typeArguments[i] = tw.TypeAsSignatureType;
612 type = type.MakeGenericType(typeArguments);
614 catch (ArgumentException)
621 if (wrapper !=
null && wrapper.Name != name)
632 var javaType = FindOrLoadGenericClass(name, mode);
633 if (javaType !=
null)
636#if !FIRST_PASS && !IMPORTER && !EXPORTER
641 Profiler.Enter(
"ClassLoader.loadClass");
647 var c = (
java.
lang.Class)ClassLoaderAccessor.InvokeLoadClassInternal(GetJavaClassLoader(), name);
652 var type = RuntimeJavaType.FromClass(c);
653 if (type.Name != name)
658 catch (
java.
lang.ClassNotFoundException x)
665 catch (global::java.lang.ThreadDeath)
671 if ((mode &
LoadMode.SuppressExceptions) == 0)
676 var cl = GetJavaClassLoader();
679 var sb =
new ValueStringBuilder();
684 sb.Append(cl.ToString());
689 Diagnostics.GenericClassLoadingError($
"ClassLoader chain: {sb.ToString()}");
692 var m = ikvm.runtime.Util.mapException(x);
693 Diagnostics.GenericClassLoadingError(m.ToString() + Environment.NewLine + m.StackTrace);
700 Profiler.Leave(
"ClassLoader.loadClass");
714 static RuntimeJavaType CreateArrayType(
string name, RuntimeJavaType elementJavaType,
int dimensions)
716 Debug.Assert(
new string(
'[', dimensions) + elementJavaType.SigName == name);
717 Debug.Assert(!elementJavaType.IsUnloadable && !elementJavaType.IsVerifierType && !elementJavaType.IsArray);
718 Debug.Assert(dimensions >= 1);
720 return elementJavaType.ClassLoader.RegisterInitiatingLoader(
new RuntimeArrayJavaType(elementJavaType.Context, elementJavaType, name));
723#if !IMPORTER && !EXPORTER
729 internal virtual java.lang.ClassLoader GetJavaClassLoader()
732 throw new NotImplementedException();
747 internal Type[] ArgTypeListFromSig(
string signature)
749 if (signature[1] ==
')')
750 return Type.EmptyTypes;
752 var javaTypes = ArgJavaTypeListFromSig(signature,
LoadMode.LoadOrThrow);
753 var types =
new Type[javaTypes.Length];
754 for (
int i = 0; i < javaTypes.Length; i++)
755 types[i] = javaTypes[i].TypeAsSignatureType;
771 RuntimeJavaType SigDecoderWrapper(
ref int index,
string signature,
LoadMode mode)
773 switch (signature[index++])
790 index = signature.IndexOf(
';', index) + 1;
791 return LoadClass(signature.Substring(pos, index - pos - 1), mode);
805 while (signature[index] ==
'[')
811 switch (signature[index])
816 index = signature.IndexOf(
';', index) + 1;
817 return LoadClass(array + signature.Substring(pos, index - pos), mode);
827 return LoadClass(array + signature[index++], mode);
829 throw new InvalidOperationException(signature.Substring(index));
833 throw new InvalidOperationException(signature.Substring(index));
837 internal RuntimeJavaType FieldTypeWrapperFromSig(
string sig,
LoadMode mode)
840 return SigDecoderWrapper(
ref index, sig, mode);
843 internal RuntimeJavaType RetTypeWrapperFromSig(
string sig,
LoadMode mode)
845 int index = sig.IndexOf(
')') + 1;
846 return SigDecoderWrapper(
ref index, sig, mode);
849 internal RuntimeJavaType[] ArgJavaTypeListFromSig(
string sig,
LoadMode mode)
854 var list =
new List<RuntimeJavaType>();
855 for (
int i = 1; sig[i] !=
')';)
856 list.Add(SigDecoderWrapper(
ref i, sig, mode));
858 return list.ToArray();
861#if !IMPORTER && !FIRST_PASS && !EXPORTER
863 internal static object DoPrivileged(
java.
security.PrivilegedAction action)
865 return java.
security.AccessController.doPrivileged(action, ikvm.@
internal.CallerID.create(typeof(
java.
lang.ClassLoader).TypeHandle));
870 internal void RegisterNativeLibrary(IntPtr p)
880 nativeLibraries ??=
new List<IntPtr>();
881 nativeLibraries.Add(p);
886 internal void UnregisterNativeLibrary(IntPtr p)
896 nativeLibraries.Remove(p);
901 internal nint[] GetNativeLibraries()
904 return nativeLibraries == null ? Array.Empty<nint>() : nativeLibraries.ToArray();
907#if !IMPORTER && !FIRST_PASS && !EXPORTER
920 internal virtual bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJavaType
friend)
922 Debug.Assert(wrapper.ClassLoader ==
this);
923 return this ==
friend.ClassLoader;
926#if !IMPORTER && !EXPORTER
942#if !IMPORTER && !FIRST_PASS && !EXPORTER
944 ClassLoaderAccessor.InvokeCheckPackageAccess(
javaClassLoader, tw.ClassObject, pd);
956 if (EmitStackTraceInfo)
967 if (RelaxedClassNameValidation)
979 internal virtual bool WarningLevelHigh
981 get {
return false; }
984 internal virtual bool NoParameterReflection
986 get {
return false; }