Enable full trimming

Enables full trimming for Ryujinx, and in doing so removes many usages of reflection, namely:

  • IUserService no longer uses reflection to find possible service types, and now has a generated switch based on name
  • Ryujinx.HLE.HOS.Tamper no longer uses dynamic to do operations, now using INumber<T> and friends
  • Cmif and Tipc commands in Ryujinx.HLE.HOS.Services no longer get resolved via reflection and are now done via generated virtual methods
Samples of new generated code
  • IUserService
namespace Ryujinx.HLE.HOS.Services.Sm
{
    partial class IUserInterface
    {
        public IpcService? GetServiceInstance(string name, ServiceCtx context)
        {
            return name switch
            {
                "acc:su" => new global::Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForAdministrator(context, Ryujinx.HLE.HOS.Services.Account.Acc.AccountServiceFlag.Administrator),
                "acc:u0" => new global::Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForApplication(context, Ryujinx.HLE.HOS.Services.Account.Acc.AccountServiceFlag.Application),
                "acc:u1" => new global::Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForSystemService(context, Ryujinx.HLE.HOS.Services.Account.Acc.AccountServiceFlag.SystemService),
                "acc:aa" => new global::Ryujinx.HLE.HOS.Services.Account.Acc.IBaasAccessTokenAccessor(context, Ryujinx.HLE.HOS.Services.Account.Acc.AccountServiceFlag.BaasAccessTokenAccessor),
                "dauth:0" => new global::Ryujinx.HLE.HOS.Services.Account.Dauth.IService(context),
                "appletAE" => new global::Ryujinx.HLE.HOS.Services.Am.AppletAE.IAllSystemAppletProxiesService(context),
                "appletOE" => new global::Ryujinx.HLE.HOS.Services.Am.IApplicationProxyService(context),
                "idle:sys" => new global::Ryujinx.HLE.HOS.Services.Am.Idle.IPolicyManagerSystem(context),
                "omm" => new global::Ryujinx.HLE.HOS.Services.Am.Omm.IOperationModeManager(context),
                "spsm" => new global::Ryujinx.HLE.HOS.Services.Am.Spsm.IPowerStateInterface(context),
                // ...
                _ => null,
            };
        }
    }
}
  • CommandCmifAttribute
using Ryujinx.HLE.HOS;
using RC = global::Ryujinx.HLE.HOS.ResultCode;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
    partial class IAllSystemAppletProxiesService
    {
        protected override RC InvokeCmifMethod(int id, ServiceCtx context)
        {
            switch (id)
            {
                case 100:
                    LogInvoke("OpenSystemAppletProxy");
                    return (RC)OpenSystemAppletProxy(context);
                case 200 or 201:
                    LogInvoke("OpenLibraryAppletProxy");
                    return (RC)OpenLibraryAppletProxy(context);
                case 350:
                    LogInvoke("OpenSystemApplicationProxy");
                    return (RC)OpenSystemApplicationProxy(context);
                default: return base.InvokeCmifMethod(id, context);
            }
        }
        public override int CmifCommandIdByMethodName(string name)
        {
            return name switch
            {
                "OpenSystemAppletProxy" => 100,
                "OpenLibraryAppletProxy" => 200,
                "OpenSystemApplicationProxy" => 350,
                _ => base.CmifCommandIdByMethodName(name),
            };
        }
    }
}

Merge request reports

Loading