XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.CompilerServices;

namespace XFESystem.NativeRuntime.Application;

internal static class RuntimeSelfCheck
{
    private sealed class Root(int value) { internal int Value = value; }
    [ThreadStatic] private static int token;
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static WeakReference CreateUnrooted() => new(new Root(23));
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void Throw() => throw new InvalidOperationException("Independent runtime check");
    private sealed class DisposeFlag : IDisposable
    {
        internal bool Disposed;
        public void Dispose() => Disposed = true;
    }
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void ThrowThroughFinally(ref int completed)
    {
        try { Throw(); }
        finally { completed = 1; }
    }
    [MethodImpl(MethodImplOptions.NoInlining)]
    private static void ThrowThroughDispose(DisposeFlag resource)
    {
        using (resource) Throw();
    }

    internal static void Run()
    {
        NativePlatform.Write("XFE_APPLICATION_RUNTIME_CHECK_BEGIN\n");
        token = 7;
        var table = new ConditionalWeakTable<object, Root>();
        object key = new(); table.Add(key, new Root(42));
        byte[] bytes = new byte[32768]; bytes[^1] = 211;
        var weak = CreateUnrooted();
        int caught = 0, finalized = 0;
        try { Throw(); }
        catch (InvalidOperationException) { caught = 1; }
        finally { finalized = 1; }
        int unwound = 0;
        var disposable = new DisposeFlag();
        try { ThrowThroughFinally(ref unwound); }
        catch (InvalidOperationException) { }
        try { ThrowThroughDispose(disposable); }
        catch (InvalidOperationException) { }
        if (unwound != 1 || !disposable.Disposed) throw new InvalidOperationException("Native exception unwind skipped cleanup.");
        using var ready = new ManualResetEventSlim();
        using var done = new ManualResetEventSlim();
        Exception? threadError = null;
        var worker = new Thread(() =>
        {
            try
            {
                token = 19;
                byte[] rooted = new byte[32768]; rooted[0] = 37; rooted[^1] = 91;
                ready.Set();
                while (!done.IsSet)
                {
                    if (token != 19 || rooted[0] != 37 || rooted[^1] != 91)
                        throw new InvalidOperationException("Thread roots/TLS were corrupted");
                    Thread.Sleep(1);
                }
                GC.KeepAlive(rooted);
            }
            catch (Exception error) { threadError = error; ready.Set(); }
        }) { IsBackground = true };
        worker.Start();
        if (!ready.Wait(10_000)) throw new InvalidOperationException("Native managed thread did not start");
        for (int collection = 0; collection < 3; collection++) GC.Collect();
        done.Set();
        if (!worker.Join(10_000)) throw new InvalidOperationException("Native managed thread did not finish");
        if (threadError is not null || token != 7 || bytes[^1] != 211 ||
            table.GetValue(key, _ => new Root(-1)).Value != 42 || weak.IsAlive || caught != 1 || finalized != 1)
            throw new InvalidOperationException("Microsoft runtime GC/EH/TLS/weak reference check failed", threadError);
        GC.KeepAlive(bytes); GC.KeepAlive(key);
        NativePlatform.Write("XFE_APPLICATION_RUNTIME_CHECK_OK GC CWT weak_reference threads TLS throw catch finally\n");
    }
}