/// <summary> /// This thunk is used to lazily resolve Finalizer calls /// </summary> /// <param name="obj">Object to be finalized</param> private static void FinalizeThunk(object obj) { RuntimeTypeHandle rthType = RuntimeAugments.GetRuntimeTypeHandleFromObjectReference(obj); TypeSystemContext context = TypeSystemContextFactory.Create(); TypeDesc type = context.ResolveRuntimeTypeHandle(rthType); MethodDesc finalizer = type.GetFinalizer(); IntPtr fnPtrFinalizer; if (!TryGetVTableCallableAddress(finalizer, out fnPtrFinalizer)) { Environment.FailFast("Method address lookup failed for: " + finalizer.ToString()); } TypeSystemContextFactory.Recycle(context); unsafe { rthType.ToEETypePtr()->FinalizerCode = fnPtrFinalizer; } // Call the finalizer directly. No need to play tricks with tail calling, as this is rare enough, it shouldn't happen much // Here we take advantage of the detail that the calling convention abi for a static function // that returns no values, and takes a single object parameter matches that of a // instance function that takes no parameters Intrinsics.Call(fnPtrFinalizer, obj); }