Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
AssemblyLoadContext.cs
Go to the documentation of this file.
5using System.IO;
11
12namespace System.Runtime.Loader;
13
15{
16 private enum InternalState
17 {
18 Alive,
20 }
21
47
48 private const string AssemblyLoadName = "AssemblyLoad";
49
51
52 private static long s_nextId;
53
55
56 private readonly object _unloadLock;
57
58 private readonly string _name;
59
60 private readonly long _id;
61
63
64 private readonly bool _isCollectible;
65
67
68 [MemberNotNull("s_allContexts")]
77
78 public IEnumerable<Assembly> Assemblies
79 {
80 get
81 {
84 {
86 if (loadContext == this)
87 {
88 yield return assembly;
89 }
90 }
91 }
92 }
93
95
97
98 public string? Name => _name;
99
101 {
102 get
103 {
104 _ = Default;
108 {
110 int num = 0;
112 {
113 array[num++] = item.Value;
114 }
115 }
118 {
119 if (weakReference.TryGetTarget(out var target))
120 {
121 yield return target;
122 }
123 }
124 }
125 }
126
128
130
132
134
136 {
137 add
138 {
140 }
141 remove
142 {
144 }
145 }
146
148 {
149 add
150 {
151 _resolving += value;
152 }
153 remove
154 {
155 _resolving -= value;
156 }
157 }
158
160 {
161 add
162 {
163 _unloading += value;
164 }
165 remove
166 {
167 _unloading -= value;
168 }
169 }
170
172
173 internal static event ResolveEventHandler? TypeResolve;
174
175 internal static event ResolveEventHandler? ResourceResolve;
176
177 internal static event ResolveEventHandler? AssemblyResolve;
178
179 [DllImport("QCall", CharSet = CharSet.Unicode)]
181
182 [DllImport("QCall", CharSet = CharSet.Unicode)]
184
185 [DllImport("QCall", CharSet = CharSet.Unicode)]
186 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
188
189 [DllImport("QCall", CharSet = CharSet.Unicode)]
190 internal static extern void InternalSetProfileRoot(string directoryPath);
191
192 [DllImport("QCall", CharSet = CharSet.Unicode)]
194
195 [DllImport("QCall", CharSet = CharSet.Unicode)]
196 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
198
199 [MethodImpl(MethodImplOptions.InternalCall)]
200 internal static extern Assembly[] GetLoadedAssemblies();
201
202 [MethodImpl(MethodImplOptions.InternalCall)]
203 internal static extern bool IsTracingEnabled();
204
205 [DllImport("QCall", CharSet = CharSet.Unicode)]
206 internal static extern bool TraceResolvingHandlerInvoked(string assemblyName, string handlerName, string alcName, string resultAssemblyName, string resultAssemblyPath);
207
208 [DllImport("QCall", CharSet = CharSet.Unicode)]
209 internal static extern bool TraceAssemblyResolveHandlerInvoked(string assemblyName, string handlerName, string resultAssemblyName, string resultAssemblyPath);
210
211 [DllImport("QCall", CharSet = CharSet.Unicode)]
213
214 [DllImport("QCall", CharSet = CharSet.Unicode)]
215 internal static extern bool TraceSatelliteSubdirectoryPathProbed(string filePath, int hResult);
216
217 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
224
225 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
227 {
228 RuntimeAssembly o = null;
229 fixed (byte* value = arrAssembly)
230 {
231 fixed (byte* value2 = arrSymbols)
232 {
234 }
235 }
236 return o;
237 }
238
239 [DllImport("QCall", CharSet = CharSet.Unicode)]
241
243 {
244 if (moduleHandle == IntPtr.Zero)
245 {
246 throw new ArgumentNullException("moduleHandle");
247 }
249 {
251 RuntimeAssembly o = null;
253 return o;
254 }
255 }
256
262
268
274
280
281 [DllImport("QCall", CharSet = CharSet.Unicode)]
283
300
305
310
312 {
313 if (!(asm == null))
314 {
315 if (!(asm is RuntimeAssembly result))
316 {
318 {
319 return null;
320 }
321 return assemblyBuilder.InternalAssembly;
322 }
323 return result;
324 }
325 return null;
326 }
327
333
334 private static void StopAssemblyLoad(ref Guid activityId)
335 {
336 ActivityTracker.Instance.OnStop(NativeRuntimeEventSource.Log.Name, "AssemblyLoad", 0, ref activityId, useTplSource: false);
337 }
338
339 private static void InitializeDefaultContext()
340 {
341 _ = Default;
342 }
343
348
353
354 public AssemblyLoadContext(string? name, bool isCollectible = false)
356 {
357 }
358
376
378 {
379 if (_unloadLock != null)
380 {
382 }
383 }
384
385 private void RaiseUnloadEvent()
386 {
387 Interlocked.Exchange(ref this._unloading, null)?.Invoke(this);
388 }
389
406
407 public override string ToString()
408 {
409 return $"\"{Name}\" {GetType()} #{_id}";
410 }
411
413 {
414 if (assemblyPath == null)
415 {
416 throw new ArgumentNullException("assemblyPath");
417 }
419 }
420
422 {
423 return null;
424 }
425
427 {
428 if (assemblyName == null)
429 {
430 throw new ArgumentNullException("assemblyName");
431 }
432 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
434 }
435
436 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
438 {
439 if (assemblyPath == null)
440 {
441 throw new ArgumentNullException("assemblyPath");
442 }
444 {
446 }
448 {
451 }
452 }
453
454 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
456 {
457 if (nativeImagePath == null)
458 {
459 throw new ArgumentNullException("nativeImagePath");
460 }
462 {
464 }
466 {
468 }
470 {
473 }
474 }
475
476 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
478 {
479 return LoadFromStream(assembly, null);
480 }
481
482 [RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
484 {
485 if (assembly == null)
486 {
487 throw new ArgumentNullException("assembly");
488 }
489 int num = (int)assembly.Length;
490 if (num <= 0)
491 {
493 }
494 byte[] array = new byte[num];
495 assembly.Read(array, 0, num);
496 byte[] array2 = null;
497 if (assemblySymbols != null)
498 {
499 int num2 = (int)assemblySymbols.Length;
500 array2 = new byte[num2];
501 assemblySymbols.Read(array2, 0, num2);
502 }
504 {
506 return InternalLoad(array, array2);
507 }
508 }
509
511 {
512 if (unmanagedDllPath == null)
513 {
514 throw new ArgumentNullException("unmanagedDllPath");
515 }
516 if (unmanagedDllPath.Length == 0)
517 {
518 throw new ArgumentException(SR.Argument_EmptyPath, "unmanagedDllPath");
519 }
521 {
523 }
525 }
526
527 protected virtual IntPtr LoadUnmanagedDll(string unmanagedDllName)
528 {
529 return IntPtr.Zero;
530 }
531
541
542 internal static void OnProcessExit()
543 {
545 if (dictionary == null)
546 {
547 return;
548 }
550 {
552 {
553 if (item.Value.TryGetTarget(out var target))
554 {
555 target.RaiseUnloadEvent();
556 }
557 }
558 }
559 }
560
561 private void VerifyIsAlive()
562 {
563 if (_state != 0)
564 {
566 }
567 }
568
570 {
571 if (s_asyncLocalCurrent == null)
572 {
574 }
575 s_asyncLocalCurrent.Value = value;
576 }
577
582
584 {
585 if (activating == null)
586 {
587 return new ContextualReflectionScope(null);
588 }
590 if (loadContext == null)
591 {
592 throw new ArgumentException(SR.Arg_MustBeRuntimeAssembly, "activating");
593 }
594 return loadContext.EnterContextualReflection();
595 }
596
602
603 [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "The code handles the Assembly.Location equals null")]
605 {
606 Assembly assembly = null;
608 if (resolving != null)
609 {
610 Delegate[] invocationList = resolving.GetInvocationList();
611 for (int i = 0; i < invocationList.Length; i++)
612 {
614 assembly = func(this, assemblyName);
615 if (IsTracingEnabled())
616 {
617 TraceResolvingHandlerInvoked(assemblyName.FullName, func.Method.Name, (this != Default) ? ToString() : Name, assembly?.FullName, (assembly != null && !assembly.IsDynamic) ? assembly.Location : null);
618 }
619 if (assembly != null)
620 {
621 return assembly;
622 }
623 }
624 }
625 return null;
626 }
627
629 {
630 if (string.IsNullOrEmpty(requestedSimpleName))
631 {
633 }
634 string value = null;
636 if (runtimeAssembly != null)
637 {
638 value = runtimeAssembly.GetSimpleName();
639 }
640 if (string.IsNullOrEmpty(value) || !requestedSimpleName.Equals(value, StringComparison.InvariantCultureIgnoreCase))
641 {
643 }
644 return assembly;
645 }
646
648 {
649 string name = assemblyName.Name;
651 if (assembly != null)
652 {
654 }
655 return assembly;
656 }
657
668
673
678
679 private static RuntimeAssembly OnTypeResolve(RuntimeAssembly assembly, string typeName)
680 {
682 }
683
688
689 [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "The code handles the Assembly.Location equals null")]
691 {
692 if (eventHandler == null)
693 {
694 return null;
695 }
697 Delegate[] invocationList = eventHandler.GetInvocationList();
698 for (int i = 0; i < invocationList.Length; i++)
699 {
703 {
704 TraceAssemblyResolveHandlerInvoked(name, resolveEventHandler.Method.Name, assembly2?.FullName, (assembly2 != null && !assembly2.IsDynamic) ? assembly2.Location : null);
705 }
707 if (runtimeAssembly != null)
708 {
709 return runtimeAssembly;
710 }
711 }
712 return null;
713 }
714
715 [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Satellite assemblies have no code in them and loading is not a problem")]
716 [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "This call is fine because native call runs before this and checks BindSatelliteResourceFromBundle")]
718 {
719 if (assemblyName.Name == null || !assemblyName.Name.EndsWith(".resources", StringComparison.Ordinal))
720 {
721 return null;
722 }
723 string assemblyName2 = assemblyName.Name.Substring(0, assemblyName.Name.Length - ".resources".Length);
726 string directoryName = Path.GetDirectoryName(assembly.Location);
727 if (directoryName == null)
728 {
729 return null;
730 }
731 string text = Path.Combine(directoryName, assemblyName.CultureName, assemblyName.Name + ".dll");
732 bool flag = FileSystem.FileExists(text);
733 if (flag || PathInternal.IsCaseSensitive)
734 {
735 }
736 Assembly result = (flag ? loadContext.LoadFromAssemblyPath(text) : null);
737 if (IsTracingEnabled())
738 {
739 TraceSatelliteSubdirectoryPathProbed(text, (!flag) ? (-2147024894) : 0);
740 }
741 return result;
742 }
743
745 {
748 if (resolvingUnmanagedDll != null)
749 {
750 Delegate[] invocationList = resolvingUnmanagedDll.GetInvocationList();
751 for (int i = 0; i < invocationList.Length; i++)
752 {
755 if (zero != IntPtr.Zero)
756 {
757 return zero;
758 }
759 }
760 }
761 return IntPtr.Zero;
762 }
763}
static AppDomain CurrentDomain
Definition AppDomain.cs:28
bool ICollection< KeyValuePair< TKey, TValue > >. Remove(KeyValuePair< TKey, TValue > keyValuePair)
void Add(TKey key, TValue value)
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static bool FileExists(string fullPath)
Definition FileSystem.cs:26
static bool IsCaseSensitive
static bool IsPartiallyQualified(ReadOnlySpan< char > path)
static string Combine(string path1, string path2)
Definition Path.cs:304
static ? string GetDirectoryName(string? path)
Definition Path.cs:121
static AssemblyName GetAssemblyName(string assemblyFile)
static RuntimeAssembly InternalLoad(string assemblyName, ref StackCrawlMark stackMark, AssemblyLoadContext assemblyLoadContext=null)
static IntPtr Load(string libraryPath)
Assembly GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName)
virtual ? Assembly Load(AssemblyName assemblyName)
static volatile Dictionary< long, WeakReference< AssemblyLoadContext > > s_allContexts
static IntPtr ResolveUnmanagedDllUsingEvent(string unmanagedDllName, Assembly assembly, IntPtr gchManagedAssemblyLoadContext)
AssemblyLoadContext(string? name, bool isCollectible=false)
Assembly ResolveUsingLoad(AssemblyName assemblyName)
static bool TraceAssemblyLoadFromResolveHandlerInvoked(string assemblyName, bool isTrackedAssembly, string requestingAssemblyPath, string requestedAssemblyPath)
Func< AssemblyLoadContext, AssemblyName, Assembly?>? Resolving
static bool TraceAssemblyResolveHandlerInvoked(string assemblyName, string handlerName, string resultAssemblyName, string resultAssemblyPath)
static AsyncLocal< AssemblyLoadContext > s_asyncLocalCurrent
Assembly LoadFromAssemblyName(AssemblyName assemblyName)
static void StartAssemblyLoad(ref Guid activityId, ref Guid relatedActivityId)
static bool TraceSatelliteSubdirectoryPathProbed(string filePath, int hResult)
static Assembly Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
static void LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, string ilPath, string niPath, ObjectHandleOnStack retAssembly)
AssemblyLoadContext(bool representsTPALoadContext, bool isCollectible, string name)
static Assembly ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
static ? AssemblyLoadContext CurrentContextualReflectionContext
static RuntimeAssembly OnAssemblyResolve(RuntimeAssembly assembly, string assemblyFullName)
static void InternalStartProfile(string profile, IntPtr ptrNativeAssemblyLoadContext)
static Assembly ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
static IntPtr ResolveUnmanagedDll(string unmanagedDllName, IntPtr gchManagedAssemblyLoadContext)
static ContextualReflectionScope EnterContextualReflection(Assembly? activating)
static IEnumerable< AssemblyLoadContext > All
Assembly InternalLoadFromPath(string assemblyPath, string nativeImagePath)
Func< Assembly, string, IntPtr >? _resolvingUnmanagedDll
static Dictionary< long, WeakReference< AssemblyLoadContext > > AllContexts
static ? AssemblyLoadContext GetLoadContext(Assembly assembly)
static void LoadFromStream(IntPtr ptrNativeAssemblyLoadContext, IntPtr ptrAssemblyArray, int iAssemblyArrayLen, IntPtr ptrSymbols, int iSymbolArrayLen, ObjectHandleOnStack retAssembly)
IntPtr GetResolvedUnmanagedDll(Assembly assembly, string unmanagedDllName)
static Assembly ValidateAssemblyNameWithSimpleName(Assembly assembly, string requestedSimpleName)
static RuntimeAssembly InvokeResolveEvent(ResolveEventHandler eventHandler, RuntimeAssembly assembly, string name)
static AssemblyName GetAssemblyName(string assemblyPath)
static IntPtr GetLoadContextForAssembly(QCallAssembly assembly)
static bool TraceResolvingHandlerInvoked(string assemblyName, string handlerName, string alcName, string resultAssemblyName, string resultAssemblyPath)
Assembly LoadFromInMemoryModule(IntPtr moduleHandle)
Assembly LoadFromAssemblyPath(string assemblyPath)
static void StopAssemblyLoad(ref Guid activityId)
static void OnAssemblyLoad(RuntimeAssembly assembly)
IntPtr LoadUnmanagedDllFromPath(string unmanagedDllPath)
Assembly LoadFromNativeImagePath(string nativeImagePath, string? assemblyPath)
Assembly ResolveSatelliteAssembly(AssemblyName assemblyName)
static IntPtr LoadFromInMemoryModuleInternal(IntPtr ptrNativeAssemblyLoadContext, IntPtr hModule, ObjectHandleOnStack retAssembly)
virtual IntPtr LoadUnmanagedDll(string unmanagedDllName)
static RuntimeAssembly GetRuntimeAssembly(Assembly asm)
Func< AssemblyLoadContext, AssemblyName, Assembly >? _resolving
static void SetCurrentContextualReflectionContext(AssemblyLoadContext value)
Assembly ResolveUsingEvent(AssemblyName assemblyName)
Assembly LoadFromStream(Stream assembly, Stream? assemblySymbols)
Func< Assembly, string, IntPtr >? ResolvingUnmanagedDll
static void PrepareForAssemblyLoadContextRelease(IntPtr ptrNativeAssemblyLoadContext, IntPtr ptrAssemblyLoadContextStrong)
static RuntimeAssembly OnResourceResolve(RuntimeAssembly assembly, string resourceName)
Action< AssemblyLoadContext >? _unloading
ContextualReflectionScope EnterContextualReflection()
static RuntimeAssembly OnTypeResolve(RuntimeAssembly assembly, string typeName)
static ? AssemblyLoadEventHandler AssemblyLoad
static void InternalSetProfileRoot(string directoryPath)
unsafe Assembly InternalLoad(ReadOnlySpan< byte > arrAssembly, ReadOnlySpan< byte > arrSymbols)
void SetProfileOptimizationRoot(string directoryPath)
static IntPtr InitializeAssemblyLoadContext(IntPtr ptrAssemblyLoadContext, bool fRepresentsTPALoadContext, bool isCollectible)
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string AssemblyLoadContext_Unload_CannotUnloadIfNotCollectible
Definition SR.cs:1134
static string Argument_EmptyPath
Definition SR.cs:38
static string Argument_CustomAssemblyLoadContextRequestedNameMismatch
Definition SR.cs:552
static string AssemblyLoadContext_Verify_NotUnloading
Definition SR.cs:1136
static string Argument_AbsolutePathRequired
Definition SR.cs:454
static string BadImageFormat_BadILFormat
Definition SR.cs:1148
static string Arg_MustBeRuntimeAssembly
Definition SR.cs:292
static string ArgumentNull_AssemblyNameName
Definition SR.cs:938
Definition SR.cs:7
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
delegate? Assembly ResolveEventHandler(object? sender, ResolveEventArgs args)
delegate void AssemblyLoadEventHandler(object? sender, AssemblyLoadEventArgs args)
static readonly IntPtr Zero
Definition IntPtr.cs:18
static IntPtr ToIntPtr(GCHandle value)
Definition GCHandle.cs:138
static GCHandle Alloc(object? value)
Definition GCHandle.cs:81
static GCHandle FromIntPtr(IntPtr value)
Definition GCHandle.cs:127