From 29021b5a71bbc80f262d887e6ba18b3a72963f49 Mon Sep 17 00:00:00 2001 From: Dawid <55346068+nogiszd@users.noreply.github.com> Date: Fri, 10 Jul 2026 22:46:50 +0200 Subject: [PATCH] [fixes] move repeating methods into CpuContext (#41) --- src/SharpEmu.HLE/CpuContext.cs | 71 ++++++++++ src/SharpEmu.Libs/Agc/AgcExports.cs | 108 +++++++-------- .../Agc/Gen5ShaderMetadataReader.cs | 28 +--- .../AppContent/AppContentExports.cs | 14 +- src/SharpEmu.Libs/Audio/AudioOut2Exports.cs | 55 ++++---- src/SharpEmu.Libs/Audio/AudioOutExports.cs | 28 ++-- src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs | 13 +- src/SharpEmu.Libs/Fiber/FiberExports.cs | 130 +++++++++--------- .../Kernel/KernelEventFlagCompatExports.cs | 61 ++++---- .../Kernel/KernelMemoryCompatExports.cs | 15 +- .../Kernel/KernelPthreadCompatExports.cs | 60 +++----- .../KernelPthreadExtendedCompatExports.cs | 34 +---- .../Kernel/KernelRuntimeCompatExports.cs | 36 ++--- .../Kernel/KernelSemaphoreCompatExports.cs | 57 ++++---- src/SharpEmu.Libs/Network/Http2Exports.cs | 14 +- src/SharpEmu.Libs/Network/HttpExports.cs | 19 +-- src/SharpEmu.Libs/Network/NetCtlExports.cs | 52 ++++--- src/SharpEmu.Libs/Network/NetExports.cs | 32 ++--- src/SharpEmu.Libs/Network/SslExports.cs | 16 +-- src/SharpEmu.Libs/Ngs2/Ngs2Exports.cs | 58 ++++---- .../Np/NpEntitlementAccessExports.cs | 14 +- src/SharpEmu.Libs/Np/NpManagerExports.cs | 18 +-- .../Np/NpUniversalDataSystemExports.cs | 41 ++---- src/SharpEmu.Libs/Np/NpWebApi2Exports.cs | 14 +- src/SharpEmu.Libs/Pad/PadExports.cs | 46 +++---- src/SharpEmu.Libs/PlayGo/PlayGoExports.cs | 44 +----- .../SaveData/SaveDataDialogExports.cs | 43 +++--- src/SharpEmu.Libs/SaveData/SaveDataExports.cs | 77 ++++------- src/SharpEmu.Libs/Share/ShareExports.cs | 17 +-- .../SystemService/SystemServiceExports.cs | 26 ++-- .../UserService/UserServiceExports.cs | 56 +++----- 31 files changed, 527 insertions(+), 770 deletions(-) diff --git a/src/SharpEmu.HLE/CpuContext.cs b/src/SharpEmu.HLE/CpuContext.cs index b65546a..bf24372 100644 --- a/src/SharpEmu.HLE/CpuContext.cs +++ b/src/SharpEmu.HLE/CpuContext.cs @@ -138,6 +138,51 @@ public sealed class CpuContext(ICpuMemory memory, Generation generation) return true; } + public bool TryReadUInt16(ulong address, out ushort value) + { + Span bytes = stackalloc byte[sizeof(ushort)]; + if (!Memory.TryRead(address, bytes)) + { + value = 0; + return false; + } + + value = BinaryPrimitives.ReadUInt16LittleEndian(bytes); + return true; + } + + public bool TryWriteUInt16(ulong address, ushort value) + { + Span buffer = stackalloc byte[sizeof(ushort)]; + BinaryPrimitives.WriteUInt16LittleEndian(buffer, value); + return Memory.TryWrite(address, buffer); + } + + public bool TryReadInt32(ulong address, out int value) + { + Span bytes = stackalloc byte[sizeof(int)]; + if (!Memory.TryRead(address, bytes)) + { + value = 0; + return false; + } + + value = BinaryPrimitives.ReadInt32LittleEndian(bytes); + return true; + } + + public bool TryWriteInt32(ulong address, int value, bool checkNil = false) + { + if (checkNil && address == 0) + { + return false; + } + + Span bytes = stackalloc byte[sizeof(int)]; + BinaryPrimitives.WriteInt32LittleEndian(bytes, value); + return Memory.TryWrite(address, bytes); + } + public bool TryReadUInt32(ulong address, out uint value) { Span buffer = stackalloc byte[sizeof(uint)]; @@ -158,6 +203,13 @@ public sealed class CpuContext(ICpuMemory memory, Generation generation) return Memory.TryWrite(address, buffer); } + public bool TryWriteInt64(ulong address, long value) + { + Span buffer = stackalloc byte[sizeof(long)]; + BinaryPrimitives.WriteInt64LittleEndian(buffer, value); + return Memory.TryWrite(address, buffer); + } + public bool TryReadUInt64(ulong address, out ulong value) { Span buffer = stackalloc byte[sizeof(ulong)]; @@ -224,4 +276,23 @@ public sealed class CpuContext(ICpuMemory memory, Generation generation) this[CpuRegister.Rsp] = rsp + sizeof(ulong); return true; } + + public int SetReturn(int result, Type? cast = null) + { + var value = cast switch + { + null => (ulong)result, + _ when cast == typeof(long) => (ulong)(long)result, + _ => throw new NotSupportedException(), + }; + + this[CpuRegister.Rax] = unchecked(value); + return result; + } + + public int SetReturn(OrbisGen2Result result) + { + this[CpuRegister.Rax] = unchecked((ulong)(int)result); + return (int)result; + } } diff --git a/src/SharpEmu.Libs/Agc/AgcExports.cs b/src/SharpEmu.Libs/Agc/AgcExports.cs index d1de0dc..d08c262 100644 --- a/src/SharpEmu.Libs/Agc/AgcExports.cs +++ b/src/SharpEmu.Libs/Agc/AgcExports.cs @@ -407,11 +407,11 @@ public static class AgcExports var version = (uint)ctx[CpuRegister.Rsi]; if (stateAddress == 0 || !IsSupportedRegisterDefaultsVersion(version)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } TraceAgc($"agc.init state=0x{stateAddress:X16} version={version}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -442,19 +442,19 @@ public static class AgcExports var codeAddress = ctx[CpuRegister.Rdx]; if (headerAddress == 0 || codeAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryReadUInt32(headerAddress, out var fileHeader) || !ctx.TryReadUInt32(headerAddress + sizeof(uint), out var version)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (fileHeader != ShaderFileHeader || version != ShaderVersion) { TraceCreateShader(destinationAddress, headerAddress, codeAddress, $"invalid-header file=0x{fileHeader:X8} version=0x{version:X8}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!RelocatePointerField(ctx, headerAddress + ShaderCxRegistersOffset) || @@ -465,12 +465,12 @@ public static class AgcExports !RelocatePointerField(ctx, headerAddress + ShaderOutputSemanticsOffset) || !ctx.TryWriteUInt64(headerAddress + ShaderCodeOffset, codeAddress)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (!ctx.TryReadUInt64(headerAddress + ShaderUserDataOffset, out var userDataAddress)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (userDataAddress != 0 && @@ -480,18 +480,18 @@ public static class AgcExports !RelocatePointerField(ctx, userDataAddress + 0x18) || !RelocatePointerField(ctx, userDataAddress + 0x20))) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (!PatchShaderProgramRegisters(ctx, headerAddress, codeAddress)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (destinationAddress != 0 && !ctx.TryWriteUInt64(destinationAddress, headerAddress)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } lock (_submitTraceGate) @@ -567,14 +567,14 @@ public static class AgcExports if (cxRegistersAddress == 0 || ucRegistersAddress == 0 || hullShaderAddress != 0 || geometryShaderAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryReadByte(geometryShaderAddress + ShaderTypeOffset, out var shaderType) || !IsEsGeometryShaderType(shaderType) || !ctx.TryReadUInt64(geometryShaderAddress + ShaderSpecialsOffset, out var specialsAddress) || specialsAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!CopyShaderRegister(ctx, specialsAddress + ShaderSpecialVgtShaderStagesEnOffset, cxRegistersAddress) || @@ -584,7 +584,7 @@ public static class AgcExports !ctx.TryWriteUInt32(ucRegistersAddress + 16, VgtPrimitiveType) || !ctx.TryWriteUInt32(ucRegistersAddress + 20, primitiveType)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceAgc($"agc.create_prim_state cx=0x{cxRegistersAddress:X16} uc=0x{ucRegistersAddress:X16} gs=0x{geometryShaderAddress:X16} type={shaderType} prim=0x{primitiveType:X8}"); @@ -605,13 +605,13 @@ public static class AgcExports if (registersAddress == 0 || geometryShaderAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryReadUInt64(geometryShaderAddress + ShaderOutputSemanticsOffset, out var outputSemanticsAddress) || !ctx.TryReadUInt32(geometryShaderAddress + ShaderNumOutputSemanticsOffset, out var outputSemanticsCount)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } ulong inputSemanticsAddress = 0; @@ -619,7 +619,7 @@ public static class AgcExports (!ctx.TryReadUInt64(pixelShaderAddress + ShaderInputSemanticsOffset, out inputSemanticsAddress) || !ctx.TryReadUInt32(pixelShaderAddress + ShaderNumInputSemanticsOffset, out _))) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } for (uint i = 0; i < 32; i++) @@ -641,7 +641,7 @@ public static class AgcExports if (!ctx.TryWriteUInt32(destination, SpiPsInputCntl0 + i) || !ctx.TryWriteUInt32(destination + sizeof(uint), value)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } @@ -662,7 +662,7 @@ public static class AgcExports var type = (int)ctx[CpuRegister.Rdx]; if (outputAddress == 0 || commandAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var payloadAddress = commandAddress + 8; @@ -670,7 +670,7 @@ public static class AgcExports { if (!ctx.TryReadUInt32(commandAddress, out var header)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } payloadAddress = (header & 0x3FFF_0000u) == 0x3FFF_0000u @@ -680,7 +680,7 @@ public static class AgcExports if (!ctx.TryWriteUInt64(outputAddress, payloadAddress)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (ShouldTraceHotPath(ref _packetPayloadTraceCount)) @@ -705,20 +705,20 @@ public static class AgcExports var dwordCount = (uint)ctx[CpuRegister.Rsi]; if (commandBufferAddress == 0 || dwordCount < 2 || dwordCount > 0x4001) { - return ReturnPointer(ctx, 0); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!TryAllocateCommandDwords(ctx, commandBufferAddress, dwordCount, out var commandAddress) || !ctx.TryWriteUInt32(commandAddress, Pm4(dwordCount, ItNop, RZero))) { - return ReturnPointer(ctx, 0); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } for (uint index = 1; index < dwordCount; index++) { if (!ctx.TryWriteUInt32(commandAddress + ((ulong)index * sizeof(uint)), 0)) { - return ReturnPointer(ctx, 0); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } @@ -1738,12 +1738,12 @@ public static class AgcExports op != ItNop || register != RDmaData) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } return ctx.TryWriteUInt64(commandAddress + 16, destinationAddress) - ? SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK) - : SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK) + : ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -1757,7 +1757,7 @@ public static class AgcExports var address = ctx[CpuRegister.Rsi]; if (!TryGetPacketIdentity(ctx, commandAddress, out var op, out var register)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var fieldOffset = op == ItWaitRegMem @@ -1767,12 +1767,12 @@ public static class AgcExports : 0; if (fieldOffset == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } return ctx.TryWriteUInt64(commandAddress + fieldOffset, address) - ? SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK) - : SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK) + : ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -1788,12 +1788,12 @@ public static class AgcExports op != ItNop || register != RReleaseMem) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } return ctx.TryWriteUInt64(commandAddress + 12, address) - ? SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK) - : SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK) + : ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -1934,11 +1934,11 @@ public static class AgcExports KernelEventQueueCompatExports.KernelEventFilterGraphics, userData)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } TraceAgc($"agc.driver_add_eq_event eq=0x{equeue:X16} id=0x{eventId:X16} udata=0x{userData:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -1955,11 +1955,11 @@ public static class AgcExports eventId, KernelEventQueueCompatExports.KernelEventFilterGraphics)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } TraceAgc($"agc.driver_delete_eq_event eq=0x{equeue:X16} id=0x{eventId:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -1974,7 +1974,7 @@ public static class AgcExports !ctx.TryReadUInt64(packetAddress, out var commandAddress) || !ctx.TryReadUInt32(packetAddress + 8, out var dwordCount)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var tracePackets = false; @@ -2014,7 +2014,7 @@ public static class AgcExports !ctx.TryReadUInt64(packetAddress, out var commandAddress) || !ctx.TryReadUInt32(packetAddress + 8, out var dwordCount)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var tracePackets = false; @@ -2060,16 +2060,16 @@ public static class AgcExports if (outAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryWriteUInt32(outAddress, 256)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceAgc($"agc.driver_get_resource_registration_max_name_length out=0x{outAddress:X16} value=256"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private const uint DefaultAgcOwner = 1; @@ -2084,16 +2084,16 @@ public static class AgcExports if (ownerAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryWriteUInt32(ownerAddress, DefaultAgcOwner)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceAgc($"agc.driver_get_default_owner out=0x{ownerAddress:X16} owner={DefaultAgcOwner}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -2113,7 +2113,7 @@ public static class AgcExports $"agc.driver_register_resource resource=0x{resourceAddress:X16} owner={owner} " + $"name=0x{nameAddress:X16} type={type} flags={flags}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -2128,7 +2128,7 @@ public static class AgcExports $"rsi=0x{ctx[CpuRegister.Rsi]:X16} rdx=0x{ctx[CpuRegister.Rdx]:X16} " + $"rcx=0x{ctx[CpuRegister.Rcx]:X16} r8=0x{ctx[CpuRegister.R8]:X16} r9=0x{ctx[CpuRegister.R9]:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -5118,13 +5118,13 @@ public static class AgcExports var registersAddress = ctx[CpuRegister.Rsi]; if (commandAddress == 0 || registersAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryWriteUInt32(commandAddress + 8, (uint)(registersAddress & 0xFFFF_FFFFUL)) || !ctx.TryWriteUInt32(commandAddress + 12, (uint)(registersAddress >> 32))) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceAgc($"agc.patch_{registerSpace}_addr cmd=0x{commandAddress:X16} regs=0x{registersAddress:X16}"); @@ -5138,13 +5138,13 @@ public static class AgcExports var registerCount = (uint)ctx[CpuRegister.Rsi]; if (commandAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryReadUInt32(commandAddress + 4, out var currentCount) || !ctx.TryWriteUInt32(commandAddress + 4, currentCount + registerCount)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceAgc($"agc.patch_{registerSpace}_add cmd=0x{commandAddress:X16} add={registerCount} total={currentCount + registerCount}"); @@ -5388,12 +5388,6 @@ public static class AgcExports return (int)OrbisGen2Result.ORBIS_GEN2_OK; } - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(int)result); - return (int)result; - } - private static uint Pm4(uint lengthDwords, uint op, uint register) => 0xC0000000u | ((((ushort)lengthDwords - 2u) & 0x3FFFu) << 16) | diff --git a/src/SharpEmu.Libs/Agc/Gen5ShaderMetadataReader.cs b/src/SharpEmu.Libs/Agc/Gen5ShaderMetadataReader.cs index 7f70830..87846ec 100644 --- a/src/SharpEmu.Libs/Agc/Gen5ShaderMetadataReader.cs +++ b/src/SharpEmu.Libs/Agc/Gen5ShaderMetadataReader.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later using SharpEmu.HLE; -using System.Buffers.Binary; namespace SharpEmu.Libs.Agc; @@ -36,9 +35,9 @@ internal static class Gen5ShaderMetadataReader } } - if (!TryReadUInt16(ctx, userDataAddress + 0x28, out var extendedUserDataSize) || - !TryReadUInt16(ctx, userDataAddress + 0x2A, out var shaderResourceTableSize) || - !TryReadUInt16(ctx, userDataAddress + 0x2C, out var directResourceCount) || + if (!ctx.TryReadUInt16(userDataAddress + 0x28, out var extendedUserDataSize) || + !ctx.TryReadUInt16(userDataAddress + 0x2A, out var shaderResourceTableSize) || + !ctx.TryReadUInt16(userDataAddress + 0x2C, out var directResourceCount) || directResourceCount > MaxMetadataEntries) { return false; @@ -47,8 +46,7 @@ internal static class Gen5ShaderMetadataReader var resourceCounts = new ushort[ResourceClassCount]; for (var resourceClass = 0; resourceClass < ResourceClassCount; resourceClass++) { - if (!TryReadUInt16( - ctx, + if (!ctx.TryReadUInt16( userDataAddress + 0x2E + (ulong)(resourceClass * sizeof(ushort)), out resourceCounts[resourceClass]) || resourceCounts[resourceClass] > MaxMetadataEntries) @@ -67,7 +65,7 @@ internal static class Gen5ShaderMetadataReader for (uint type = 0; type < directResourceCount; type++) { - if (!TryReadUInt16(ctx, directResourceOffsetsAddress + type * sizeof(ushort), out var offset)) + if (!ctx.TryReadUInt16(directResourceOffsetsAddress + type * sizeof(ushort), out var offset)) { return false; } @@ -95,8 +93,7 @@ internal static class Gen5ShaderMetadataReader for (uint slot = 0; slot < count; slot++) { - if (!TryReadUInt16( - ctx, + if (!ctx.TryReadUInt16( resourceOffsets[resourceClass] + slot * sizeof(ushort), out var sharp)) { @@ -124,17 +121,4 @@ internal static class Gen5ShaderMetadataReader resources); return true; } - - private static bool TryReadUInt16(CpuContext ctx, ulong address, out ushort value) - { - Span bytes = stackalloc byte[sizeof(ushort)]; - if (!ctx.Memory.TryRead(address, bytes)) - { - value = 0; - return false; - } - - value = BinaryPrimitives.ReadUInt16LittleEndian(bytes); - return true; - } } diff --git a/src/SharpEmu.Libs/AppContent/AppContentExports.cs b/src/SharpEmu.Libs/AppContent/AppContentExports.cs index 4755955..127a89a 100644 --- a/src/SharpEmu.Libs/AppContent/AppContentExports.cs +++ b/src/SharpEmu.Libs/AppContent/AppContentExports.cs @@ -73,7 +73,7 @@ public static class AppContentExports var valueAddress = ctx[CpuRegister.Rsi]; if (valueAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } int value; @@ -83,18 +83,18 @@ public static class AppContentExports } else if (!TryReadUserDefinedParam(paramId, out value)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span valueBytes = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(valueBytes, value); if (!ctx.Memory.TryWrite(valueAddress, valueBytes)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceAppContent($"app_param_get_int id={paramId} value={value}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -168,12 +168,6 @@ public static class AppContentExports } } - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(int)result); - return (int)result; - } - private static void TraceAppContent(string message) { if (!string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_APP_CONTENT"), "1", StringComparison.Ordinal)) diff --git a/src/SharpEmu.Libs/Audio/AudioOut2Exports.cs b/src/SharpEmu.Libs/Audio/AudioOut2Exports.cs index e1f99a2..3221d65 100644 --- a/src/SharpEmu.Libs/Audio/AudioOut2Exports.cs +++ b/src/SharpEmu.Libs/Audio/AudioOut2Exports.cs @@ -3,7 +3,6 @@ using SharpEmu.HLE; using System.Buffers.Binary; -using System.Threading; namespace SharpEmu.Libs.Audio; @@ -37,7 +36,7 @@ public static class AudioOut2Exports var paramAddress = ctx[CpuRegister.Rdi]; if (paramAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span param = stackalloc byte[AudioOut2ContextParamSize]; @@ -48,8 +47,8 @@ public static class AudioOut2Exports BinaryPrimitives.WriteUInt32LittleEndian(param[0x0C..], 0x400); return ctx.Memory.TryWrite(paramAddress, param) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -63,7 +62,7 @@ public static class AudioOut2Exports var memoryInfoAddress = ctx[CpuRegister.Rsi]; if (paramAddress == 0 || memoryInfoAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span memoryInfo = stackalloc byte[0x20]; @@ -74,8 +73,8 @@ public static class AudioOut2Exports BinaryPrimitives.WriteUInt64LittleEndian(memoryInfo[0x18..], AudioOut2ContextMemoryAlignment); return ctx.Memory.TryWrite(memoryInfoAddress, memoryInfo) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -91,13 +90,13 @@ public static class AudioOut2Exports var outContextAddress = ctx[CpuRegister.Rcx]; if (paramAddress == 0 || memoryAddress == 0 || memorySize == 0 || outContextAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var handle = (ulong)Interlocked.Increment(ref _nextContextHandle); return ctx.TryWriteUInt64(outContextAddress, handle) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -105,7 +104,7 @@ public static class AudioOut2Exports ExportName = "sceAudioOut2ContextDestroy", Target = Generation.Gen5, LibraryName = "libSceAudioOut2")] - public static int AudioOut2ContextDestroy(CpuContext ctx) => SetReturn(ctx, 0); + public static int AudioOut2ContextDestroy(CpuContext ctx) => ctx.SetReturn(0); [SysAbiExport( Nid = "JK2wamZPzwM", @@ -120,14 +119,14 @@ public static class AudioOut2Exports var contextAddress = ctx[CpuRegister.Rcx]; if (type < 0 || type > 255 || paramAddress == 0 || outPortAddress == 0 || contextAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var portId = unchecked((uint)Interlocked.Increment(ref _nextPortId)) & 0xFF; var handle = 0x2000_0000UL | ((ulong)(uint)type << 16) | portId; return ctx.TryWriteUInt64(outPortAddress, handle) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -141,7 +140,7 @@ public static class AudioOut2Exports var stateAddress = ctx[CpuRegister.Rsi]; if (handle == 0 || stateAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var type = (int)((handle >> 16) & 0xFF); @@ -154,8 +153,8 @@ public static class AudioOut2Exports BinaryPrimitives.WriteInt16LittleEndian(state[0x04..], -1); return ctx.Memory.TryWrite(stateAddress, state) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -168,7 +167,7 @@ public static class AudioOut2Exports var infoAddress = ctx[CpuRegister.Rdi]; if (infoAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span info = stackalloc byte[0x40]; @@ -178,8 +177,8 @@ public static class AudioOut2Exports BinaryPrimitives.WriteUInt32LittleEndian(info[0x08..], 48000); return ctx.Memory.TryWrite(infoAddress, info) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -187,14 +186,14 @@ public static class AudioOut2Exports ExportName = "sceAudioOut2PortDestroy", Target = Generation.Gen5, LibraryName = "libSceAudioOut2")] - public static int AudioOut2PortDestroy(CpuContext ctx) => SetReturn(ctx, 0); + public static int AudioOut2PortDestroy(CpuContext ctx) => ctx.SetReturn(0); [SysAbiExport( Nid = "IaZXJ9M79uo", ExportName = "sceAudioOut2UserDestroy", Target = Generation.Gen5, LibraryName = "libSceAudioOut2")] - public static int AudioOut2UserDestroy(CpuContext ctx) => SetReturn(ctx, 0); + public static int AudioOut2UserDestroy(CpuContext ctx) => ctx.SetReturn(0); [SysAbiExport( Nid = "xywYcRB7nbQ", @@ -207,18 +206,12 @@ public static class AudioOut2Exports var outUserAddress = ctx[CpuRegister.Rsi]; if ((userId != 0 && userId != 1 && userId != 255) || outUserAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var handle = (ulong)Interlocked.Increment(ref _nextUserHandle); return ctx.TryWriteUInt64(outUserAddress, handle) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } diff --git a/src/SharpEmu.Libs/Audio/AudioOutExports.cs b/src/SharpEmu.Libs/Audio/AudioOutExports.cs index 815c8f0..98da34a 100644 --- a/src/SharpEmu.Libs/Audio/AudioOutExports.cs +++ b/src/SharpEmu.Libs/Audio/AudioOutExports.cs @@ -5,7 +5,6 @@ using SharpEmu.HLE; using System.Buffers; using System.Collections.Concurrent; using System.Diagnostics; -using System.Threading; namespace SharpEmu.Libs.Audio; @@ -84,7 +83,7 @@ public static class AudioOutExports ExportName = "sceAudioOutInit", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceAudioOut")] - public static int AudioOutInit(CpuContext ctx) => SetReturn(ctx, 0); + public static int AudioOutInit(CpuContext ctx) => ctx.SetReturn(0); [SysAbiExport( Nid = "ekNvsT22rsY", @@ -101,7 +100,7 @@ public static class AudioOutExports if (bufferLength == 0 || frequency == 0 || !TryGetFormat(format, out var channels, out var bytesPerSample, out var isFloat)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } WinMmAudioPort? backend = null; @@ -133,7 +132,7 @@ public static class AudioOutExports $"[LOADER][INFO] AudioOut port {handle}: {frequency} Hz, " + $"{channels} ch, {(isFloat ? "float32" : "s16")}, " + $"{bufferLength} frames, backend={backendName}"); - return SetReturn(ctx, handle); + return ctx.SetReturn(handle); } [SysAbiExport( @@ -146,11 +145,11 @@ public static class AudioOutExports var handle = unchecked((int)ctx[CpuRegister.Rdi]); if (!Ports.TryRemove(handle, out var port)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } port.Dispose(); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -164,12 +163,12 @@ public static class AudioOutExports var sourceAddress = ctx[CpuRegister.Rsi]; if (!Ports.TryGetValue(handle, out var port)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (sourceAddress == 0) { - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } var buffer = ArrayPool.Shared.Rent(port.BufferByteLength); @@ -178,7 +177,7 @@ public static class AudioOutExports var source = buffer.AsSpan(0, port.BufferByteLength); if (!ctx.Memory.TryRead(sourceAddress, source)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (port.Backend is null || @@ -192,7 +191,7 @@ public static class AudioOutExports port.PaceSilence(); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } finally { @@ -208,19 +207,12 @@ public static class AudioOutExports public static int AudioOutSetVolume(CpuContext ctx) { var handle = unchecked((int)ctx[CpuRegister.Rdi]); - return SetReturn( - ctx, + return ctx.SetReturn( Ports.ContainsKey(handle) ? 0 : (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } - private static bool TryGetFormat( int rawFormat, out int channels, diff --git a/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs b/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs index 1cfc6fa..77cd6b6 100644 --- a/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs +++ b/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs @@ -46,8 +46,7 @@ public static class AvPlayerExports var dataAddress = ctx[CpuRegister.Rsi]; lock (StateGate) { - return SetReturn( - ctx, + return ctx.SetReturn( handle != 0 && dataAddress != 0 && Players.Contains(handle) ? 0 : InvalidParameters); @@ -63,15 +62,7 @@ public static class AvPlayerExports { lock (StateGate) { - return SetReturn( - ctx, - Players.Remove(ctx[CpuRegister.Rdi]) ? 0 : InvalidParameters); + return ctx.SetReturn(Players.Remove(ctx[CpuRegister.Rdi]) ? 0 : InvalidParameters); } } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } } diff --git a/src/SharpEmu.Libs/Fiber/FiberExports.cs b/src/SharpEmu.Libs/Fiber/FiberExports.cs index 10d6fc9..30a873d 100644 --- a/src/SharpEmu.Libs/Fiber/FiberExports.cs +++ b/src/SharpEmu.Libs/Fiber/FiberExports.cs @@ -104,17 +104,17 @@ public static class FiberExports var optParam = ctx[CpuRegister.Rdi]; if (optParam == 0) { - return SetReturn(ctx, FiberErrorNull); + return ctx.SetReturn(FiberErrorNull); } if ((optParam & 7) != 0) { - return SetReturn(ctx, FiberErrorAlignment); + return ctx.SetReturn(FiberErrorAlignment); } return ctx.TryWriteUInt32(optParam, FiberOptSignature) - ? SetReturn(ctx, 0) - : SetReturn(ctx, FiberErrorInvalid); + ? ctx.SetReturn(0) + : ctx.SetReturn(FiberErrorInvalid); } [SysAbiExport( @@ -127,24 +127,24 @@ public static class FiberExports var fiber = ctx[CpuRegister.Rdi]; if (!TryValidateFiber(ctx, fiber, out var error)) { - return SetReturn(ctx, error); + return ctx.SetReturn(error); } if (!ctx.TryReadUInt32(fiber + FiberStateOffset, out var state)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (state != FiberStateIdle) { - return SetReturn(ctx, FiberErrorState); + return ctx.SetReturn(FiberErrorState); } _continuations.TryRemove(fiber, out _); _returnTargets.TryRemove(fiber, out _); _stackRanges.TryRemove(fiber, out _); _ = ctx.TryWriteUInt32(fiber + FiberStateOffset, FiberStateTerminated); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -229,20 +229,20 @@ public static class FiberExports var fiberAddress = ResolveCurrentFiberAddress(ctx); if (fiberAddress == 0) { - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } if (GuestThreadExecution.Scheduler is not { SupportsGuestContextTransfer: true } || !GuestThreadExecution.TryGetCurrentImportCallFrame(out var frame)) { - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } var returnArgument = ctx[CpuRegister.Rdi]; var argOnRunAddress = ctx[CpuRegister.Rsi]; if (argOnRunAddress != 0 && !ctx.TryWriteUInt64(argOnRunAddress, 0)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } GuestCpuContinuation transferTarget; @@ -256,7 +256,7 @@ public static class FiberExports if (!_returnTargets.TryRemove(fiberAddress, out var returnTarget)) { _continuations.TryRemove(fiberAddress, out _); - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } previousFiber = returnTarget.PreviousFiber; @@ -267,7 +267,7 @@ public static class FiberExports !ctx.TryWriteUInt32(previousFiber + FiberStateOffset, FiberStateRun)) { _continuations.TryRemove(fiberAddress, out _); - return SetReturn(ctx, FiberErrorState); + return ctx.SetReturn(FiberErrorState); } transferTarget = previousContinuation.Context with { Rax = 0 }; @@ -278,7 +278,7 @@ public static class FiberExports !TryWriteResumeArgument(ctx, returnTarget.ThreadContinuation.Value, returnArgument)) { _continuations.TryRemove(fiberAddress, out _); - return SetReturn(ctx, FiberErrorState); + return ctx.SetReturn(FiberErrorState); } transferTarget = returnTarget.ThreadContinuation.Value.Context with { Rax = 0 }; @@ -286,7 +286,7 @@ public static class FiberExports if (!ctx.TryWriteUInt32(fiberAddress + FiberStateOffset, FiberStateIdle)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } } @@ -296,7 +296,7 @@ public static class FiberExports TraceFiber( $"return fiber=0x{fiberAddress:X16} to=0x{previousFiber:X16} " + $"resume=0x{transferTarget.Rip:X16} rsp=0x{transferTarget.Rsp:X16} arg=0x{returnArgument:X16}"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -309,18 +309,18 @@ public static class FiberExports var outAddress = ctx[CpuRegister.Rdi]; if (outAddress == 0) { - return SetReturn(ctx, FiberErrorNull); + return ctx.SetReturn(FiberErrorNull); } var fiberAddress = ResolveCurrentFiberAddress(ctx); if (fiberAddress == 0) { - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } return ctx.TryWriteUInt64(outAddress, fiberAddress) - ? SetReturn(ctx, 0) - : SetReturn(ctx, FiberErrorInvalid); + ? ctx.SetReturn(0) + : ctx.SetReturn(FiberErrorInvalid); } [SysAbiExport( @@ -334,22 +334,22 @@ public static class FiberExports var info = ctx[CpuRegister.Rsi]; if (info == 0) { - return SetReturn(ctx, FiberErrorNull); + return ctx.SetReturn(FiberErrorNull); } if (!TryValidateFiber(ctx, fiber, out var error)) { - return SetReturn(ctx, error); + return ctx.SetReturn(error); } if (!ctx.TryReadUInt64(info, out var size) || size != FiberInfoSize) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (!TryReadFiberFields(ctx, fiber, out var fields)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (!ctx.TryWriteUInt64(info + 8, fields.Entry) || @@ -359,10 +359,10 @@ public static class FiberExports !TryWriteName(ctx, info + 40, fields.Name) || !ctx.TryWriteUInt64(info + 72, ulong.MaxValue)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -376,22 +376,22 @@ public static class FiberExports var nameAddress = ctx[CpuRegister.Rsi]; if (!TryValidateFiber(ctx, fiber, out var error)) { - return SetReturn(ctx, error); + return ctx.SetReturn(error); } if (nameAddress == 0) { - return SetReturn(ctx, FiberErrorNull); + return ctx.SetReturn(FiberErrorNull); } if (!ctx.TryReadNullTerminatedUtf8(nameAddress, MaxNameLength + 1, out var name)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } return TryWriteName(ctx, fiber + FiberNameOffset, name) - ? SetReturn(ctx, 0) - : SetReturn(ctx, FiberErrorInvalid); + ? ctx.SetReturn(0) + : ctx.SetReturn(FiberErrorInvalid); } [SysAbiExport( @@ -403,12 +403,12 @@ public static class FiberExports { if (ctx[CpuRegister.Rdi] != 0) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } return Interlocked.Exchange(ref _contextSizeCheck, 1) == 0 - ? SetReturn(ctx, 0) - : SetReturn(ctx, FiberErrorState); + ? ctx.SetReturn(0) + : ctx.SetReturn(FiberErrorState); } [SysAbiExport( @@ -419,8 +419,8 @@ public static class FiberExports public static int FiberStopContextSizeCheck(CpuContext ctx) { return Interlocked.Exchange(ref _contextSizeCheck, 0) == 1 - ? SetReturn(ctx, 0) - : SetReturn(ctx, FiberErrorState); + ? ctx.SetReturn(0) + : ctx.SetReturn(FiberErrorState); } [SysAbiExport( @@ -433,17 +433,17 @@ public static class FiberExports var outAddress = ctx[CpuRegister.Rdi]; if (outAddress == 0) { - return SetReturn(ctx, FiberErrorNull); + return ctx.SetReturn(FiberErrorNull); } if (ResolveCurrentFiberAddress(ctx) == 0) { - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } return ctx.TryWriteUInt64(outAddress, ctx[CpuRegister.Rbp]) - ? SetReturn(ctx, 0) - : SetReturn(ctx, FiberErrorInvalid); + ? ctx.SetReturn(0) + : ctx.SetReturn(FiberErrorInvalid); } private static int FiberInitializeCore( @@ -459,37 +459,37 @@ public static class FiberExports { if (fiber == 0 || nameAddress == 0 || entry == 0) { - return SetReturn(ctx, FiberErrorNull); + return ctx.SetReturn(FiberErrorNull); } if ((fiber & 7) != 0 || (contextAddress & 15) != 0 || (optParam & 7) != 0) { - return SetReturn(ctx, FiberErrorAlignment); + return ctx.SetReturn(FiberErrorAlignment); } if (contextSize != 0 && contextSize < FiberContextMinimumSize) { - return SetReturn(ctx, FiberErrorRange); + return ctx.SetReturn(FiberErrorRange); } if ((contextSize & 15) != 0 || (contextAddress == 0 && contextSize != 0) || (contextAddress != 0 && contextSize == 0)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (optParam != 0 && (!ctx.TryReadUInt32(optParam, out var optMagic) || optMagic != FiberOptSignature)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (!ctx.TryReadNullTerminatedUtf8(nameAddress, MaxNameLength + 1, out var name)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (Volatile.Read(ref _contextSizeCheck) != 0) @@ -510,14 +510,14 @@ public static class FiberExports !ctx.TryWriteUInt64(fiber + FiberContextEndOffset, contextAddress == 0 ? 0 : contextAddress + contextSize) || !ctx.TryWriteUInt32(fiber + FiberMagicEndOffset, FiberSignature1)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (contextAddress != 0) { if (!ctx.TryWriteUInt64(contextAddress, FiberStackSignature)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if ((flags & FiberFlagContextSizeCheck) != 0) @@ -532,7 +532,7 @@ public static class FiberExports } TraceFiber($"init fiber=0x{fiber:X16} entry=0x{entry:X16} ctx=0x{contextAddress:X16} size=0x{contextSize:X} name='{name}'"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } private static int FiberRunCore( @@ -547,12 +547,12 @@ public static class FiberExports { if (!TryValidateFiber(ctx, fiber, out var error)) { - return SetReturn(ctx, error); + return ctx.SetReturn(error); } if (!TryReadFiberFields(ctx, fiber, out var fields)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (attachContextAddress != 0 || attachContextSize != 0) @@ -560,7 +560,7 @@ public static class FiberExports var attachResult = AttachContext(ctx, fiber, attachContextAddress, attachContextSize, ref fields); if (attachResult != 0) { - return SetReturn(ctx, attachResult); + return ctx.SetReturn(attachResult); } } @@ -568,16 +568,16 @@ public static class FiberExports if ((isSwitch && previousFiber == 0) || (!isSwitch && previousFiber != 0)) { - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } if (previousFiber == fiber) { - return SetReturn(ctx, FiberErrorState); + return ctx.SetReturn(FiberErrorState); } if (GuestThreadExecution.Scheduler is not { SupportsGuestContextTransfer: true } || !GuestThreadExecution.TryGetCurrentImportCallFrame(out var frame)) { - return SetReturn(ctx, FiberErrorPermission); + return ctx.SetReturn(FiberErrorPermission); } GuestCpuContinuation transferTarget; @@ -586,12 +586,12 @@ public static class FiberExports { if (!TryReadFiberFields(ctx, fiber, out fields)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (fields.State != FiberStateIdle) { TraceFiber($"run-state-error reason={reason} fiber=0x{fiber:X16} state=0x{fields.State:X8}"); - return SetReturn(ctx, FiberErrorState); + return ctx.SetReturn(FiberErrorState); } FiberContinuation targetContinuation; @@ -602,12 +602,12 @@ public static class FiberExports } else if (!TryCreateInitialContinuation(ctx, fields, argOnRun, out targetContinuation)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (resumed && !TryWriteResumeArgument(ctx, targetContinuation, argOnRun)) { - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } var callerContinuation = new FiberContinuation( @@ -620,7 +620,7 @@ public static class FiberExports previousState != FiberStateRun || !ctx.TryWriteUInt32(previousFiber + FiberStateOffset, FiberStateIdle)) { - return SetReturn(ctx, FiberErrorState); + return ctx.SetReturn(FiberErrorState); } _continuations[previousFiber] = callerContinuation; @@ -639,7 +639,7 @@ public static class FiberExports _ = ctx.TryWriteUInt32(previousFiber + FiberStateOffset, FiberStateRun); } _returnTargets.TryRemove(fiber, out _); - return SetReturn(ctx, FiberErrorInvalid); + return ctx.SetReturn(FiberErrorInvalid); } if (resumed) @@ -656,7 +656,7 @@ public static class FiberExports TraceFiber( $"transfer reason={reason} from=0x{previousFiber:X16} to=0x{fiber:X16} resume={resumed} " + $"rip=0x{transferTarget.Rip:X16} rsp=0x{transferTarget.Rsp:X16} arg=0x{argOnRun:X16}"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } private static bool TryCreateInitialContinuation( @@ -925,12 +925,6 @@ public static class FiberExports return true; } - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } - private static void TraceFiber(string message) { if (string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_FIBER"), "1", StringComparison.Ordinal)) diff --git a/src/SharpEmu.Libs/Kernel/KernelEventFlagCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelEventFlagCompatExports.cs index 3fa7706..6d0f978 100644 --- a/src/SharpEmu.Libs/Kernel/KernelEventFlagCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelEventFlagCompatExports.cs @@ -51,17 +51,17 @@ public static class KernelEventFlagCompatExports optionAddress != 0 || !IsValidAttributes(attributes)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryReadNullTerminatedUtf8(nameAddress, MaxEventFlagNameLength + 1, out var name)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (Encoding.UTF8.GetByteCount(name) > MaxEventFlagNameLength) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } var handle = unchecked((ulong)Interlocked.Increment(ref _nextEventFlagHandle)); @@ -75,11 +75,11 @@ public static class KernelEventFlagCompatExports if (!ctx.TryWriteUInt64(outAddress, handle)) { _eventFlags.TryRemove(handle, out _); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceEventFlag($"create handle=0x{handle:X16} name='{name}' attr=0x{attributes:X2} bits=0x{initialPattern:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -92,7 +92,7 @@ public static class KernelEventFlagCompatExports var handle = ctx[CpuRegister.Rdi]; if (!_eventFlags.TryRemove(handle, out var state)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } lock (state.Gate) @@ -101,7 +101,7 @@ public static class KernelEventFlagCompatExports } TraceEventFlag($"delete handle=0x{handle:X16} name='{state.Name}'"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -116,7 +116,7 @@ public static class KernelEventFlagCompatExports var returnRip = GetCurrentReturnRip(); if (!_eventFlags.TryGetValue(handle, out var state)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } lock (state.Gate) @@ -127,7 +127,7 @@ public static class KernelEventFlagCompatExports } _ = GuestThreadExecution.Scheduler?.WakeBlockedThreads(GetEventFlagWakeKey(handle)); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -141,7 +141,7 @@ public static class KernelEventFlagCompatExports var pattern = ctx[CpuRegister.Rsi]; if (!_eventFlags.TryGetValue(handle, out var state)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } lock (state.Gate) @@ -150,7 +150,7 @@ public static class KernelEventFlagCompatExports TraceEventFlag($"clear handle=0x{handle:X16} mask=0x{pattern:X16} bits=0x{state.Bits:X16}"); } - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -167,29 +167,29 @@ public static class KernelEventFlagCompatExports if (!_eventFlags.TryGetValue(handle, out var state)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } if (pattern == 0 || !IsValidWaitMode(waitMode)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } lock (state.Gate) { if (!TryWriteResultPattern(ctx, resultAddress, state.Bits)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (!IsSatisfied(state.Bits, pattern, waitMode)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_BUSY); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_BUSY); } ApplyClearMode(state, pattern, waitMode); TraceEventFlag($"poll handle=0x{handle:X16} pattern=0x{pattern:X16} mode=0x{waitMode:X2} bits=0x{state.Bits:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } } @@ -209,18 +209,18 @@ public static class KernelEventFlagCompatExports if (!_eventFlags.TryGetValue(handle, out var state)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } if (pattern == 0 || !IsValidWaitMode(waitMode)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } uint timeoutUsec = 0; if (timeoutAddress != 0 && !ctx.TryReadUInt32(timeoutAddress, out timeoutUsec)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } Monitor.Enter(state.Gate); @@ -228,7 +228,7 @@ public static class KernelEventFlagCompatExports { if (TryCompleteSatisfiedWait(ctx, state, pattern, waitMode, resultAddress, out var immediateWaitResult)) { - return SetReturn(ctx, immediateWaitResult); + return ctx.SetReturn(immediateWaitResult); } if (timeoutAddress != 0) @@ -236,7 +236,7 @@ public static class KernelEventFlagCompatExports _ = ctx.TryWriteUInt32(timeoutAddress, 0); _ = TryWriteResultPattern(ctx, resultAddress, state.Bits); TraceEventFlag($"wait-timeout handle=0x{handle:X16} pattern=0x{pattern:X16} timeout={timeoutUsec} ret=0x{returnRip:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_TIMED_OUT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_TIMED_OUT); } var currentGuestThread = GuestThreadExecution.CurrentGuestThreadHandle; @@ -271,7 +271,7 @@ public static class KernelEventFlagCompatExports var scheduler = GuestThreadExecution.Scheduler; if (scheduler is null) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_TRY_AGAIN); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_TRY_AGAIN); } state.WaitingThreads++; @@ -296,7 +296,7 @@ public static class KernelEventFlagCompatExports state.WaitingThreads = Math.Max(0, state.WaitingThreads - 1); releaseWaiter = false; TraceEventFlag($"wait-wake handle=0x{handle:X16} pattern=0x{pattern:X16} bits=0x{state.Bits:X16} waiters={state.WaitingThreads} ret=0x{returnRip:X16}"); - return SetReturn(ctx, pumpedWaitResult); + return ctx.SetReturn(pumpedWaitResult); } Monitor.Wait(state.Gate, HostWaitPumpMilliseconds); @@ -313,7 +313,7 @@ public static class KernelEventFlagCompatExports state.WaitingThreads++; TraceEventFlag($"wait-block handle=0x{handle:X16} pattern=0x{pattern:X16} waiters={state.WaitingThreads} guest_thread=0x{currentGuestThread:X16} fiber=0x{currentFiber:X16} managed={managedThread} ret=0x{returnRip:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } finally { @@ -333,7 +333,7 @@ public static class KernelEventFlagCompatExports var waiterCountAddress = ctx[CpuRegister.Rdx]; if (!_eventFlags.TryGetValue(handle, out var state)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } lock (state.Gate) @@ -341,7 +341,7 @@ public static class KernelEventFlagCompatExports if (waiterCountAddress != 0 && !ctx.TryWriteUInt32(waiterCountAddress, unchecked((uint)state.WaitingThreads))) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } state.Bits = setPattern; @@ -350,7 +350,7 @@ public static class KernelEventFlagCompatExports TraceEventFlag($"cancel handle=0x{handle:X16} bits=0x{setPattern:X16}"); } - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private static bool IsValidAttributes(uint attributes) @@ -452,13 +452,6 @@ public static class KernelEventFlagCompatExports private static bool TryWriteResultPattern(CpuContext ctx, ulong address, ulong bits) => address == 0 || ctx.TryWriteUInt64(address, bits); - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - var value = (int)result; - ctx[CpuRegister.Rax] = unchecked((ulong)value); - return value; - } - private static void TraceEventFlag(string message) { if (string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_EVENT_FLAG"), "1", StringComparison.Ordinal)) diff --git a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs index 8f0c7b0..4835376 100644 --- a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs @@ -2903,7 +2903,7 @@ public static class KernelMemoryCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } - if (protectionOut != 0 && !TryWriteInt32(ctx, protectionOut, region.Protection)) + if (protectionOut != 0 && !ctx.TryWriteInt32(protectionOut, region.Protection)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -2942,7 +2942,7 @@ public static class KernelMemoryCompatExports if (!ctx.TryWriteUInt64(infoAddress, block.Start) || !ctx.TryWriteUInt64(infoAddress + sizeof(ulong), block.Start + block.Length) || - !TryWriteInt32(ctx, infoAddress + (sizeof(ulong) * 2), block.MemoryType)) + !ctx.TryWriteInt32(infoAddress + (sizeof(ulong) * 2), block.MemoryType)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -3800,7 +3800,7 @@ public static class KernelMemoryCompatExports var addr = argumentSource.NextGpArg(); if (addr != 0) { - _ = TryWriteInt32(ctx, addr, sb.Length); + _ = ctx.TryWriteInt32(addr, sb.Length); } } break; @@ -4964,7 +4964,7 @@ public static class KernelMemoryCompatExports processedCount++; } - if (processedOutAddress != 0 && !TryWriteInt32(ctx, processedOutAddress, processedCount)) + if (processedOutAddress != 0 && !ctx.TryWriteInt32(processedOutAddress, processedCount)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -5801,13 +5801,6 @@ public static class KernelMemoryCompatExports return (protect & expected) != 0; } - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - BitConverter.TryWriteBytes(bytes, value); - return ctx.Memory.TryWrite(address, bytes); - } - private static bool TryWriteOpenDescriptorStat(CpuContext ctx, int fd, ulong statAddress) { if (fd is 0 or 1 or 2) diff --git a/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs index f9b00a0..5721229 100644 --- a/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelPthreadCompatExports.cs @@ -3,8 +3,6 @@ using System.Collections.Concurrent; using SharpEmu.HLE; -using System.Buffers.Binary; -using System.Threading; using System.Diagnostics.CodeAnalysis; namespace SharpEmu.Libs.Kernel; @@ -389,42 +387,42 @@ public static class KernelPthreadCompatExports var initRoutine = ctx[CpuRegister.Rsi]; if (onceAddress == 0 || initRoutine == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } - if (!TryReadInt32(ctx, onceAddress, out var onceValue)) + if (!ctx.TryReadInt32(onceAddress, out var onceValue)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (onceValue == PthreadOnceDone) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } var gate = GetPthreadOnceGate(onceAddress); var shouldCall = false; lock (gate) { - if (!TryReadInt32(ctx, onceAddress, out onceValue)) + if (!ctx.TryReadInt32(onceAddress, out onceValue)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } while (onceValue == PthreadOnceInProgress) { Monitor.Wait(gate, TimeSpan.FromMilliseconds(1)); - if (!TryReadInt32(ctx, onceAddress, out onceValue)) + if (!ctx.TryReadInt32(onceAddress, out onceValue)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } if (onceValue != PthreadOnceDone) { - if (!TryWriteInt32(ctx, onceAddress, PthreadOnceInProgress)) + if (!ctx.TryWriteInt32(onceAddress, PthreadOnceInProgress)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } shouldCall = true; @@ -440,21 +438,21 @@ public static class KernelPthreadCompatExports { lock (gate) { - _ = TryWriteInt32(ctx, onceAddress, PthreadOnceUninitialized); + _ = ctx.TryWriteInt32(onceAddress, PthreadOnceUninitialized); Monitor.PulseAll(gate); } TracePthreadOnce(onceAddress, initRoutine, "failed", error); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_TRY_AGAIN); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_TRY_AGAIN); } lock (gate) { - if (!TryWriteInt32(ctx, onceAddress, PthreadOnceDone)) + if (!ctx.TryWriteInt32(onceAddress, PthreadOnceDone)) { - _ = TryWriteInt32(ctx, onceAddress, PthreadOnceUninitialized); + _ = ctx.TryWriteInt32(onceAddress, PthreadOnceUninitialized); Monitor.PulseAll(gate); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } Monitor.PulseAll(gate); @@ -462,7 +460,7 @@ public static class KernelPthreadCompatExports } TracePthreadOnce(onceAddress, initRoutine, shouldCall ? "call" : "done", null); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private static int PthreadMutexInitCore(CpuContext ctx, ulong mutexAddress, ulong attrAddress) @@ -1321,32 +1319,6 @@ public static class KernelPthreadCompatExports } } - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(int)result); - return (int)result; - } - - private static bool TryReadInt32(CpuContext ctx, ulong address, out int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - if (!ctx.Memory.TryRead(address, bytes)) - { - value = 0; - return false; - } - - value = BinaryPrimitives.ReadInt32LittleEndian(bytes); - return true; - } - - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(bytes, value); - return ctx.Memory.TryWrite(address, bytes); - } - private static bool CreateImplicitMutexState(CpuContext ctx, ulong mutexAddress, int type, out ulong resolvedAddress, [NotNullWhen(true)] out PthreadMutexState? state) { var createdState = new PthreadMutexState diff --git a/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs index d16e371..39e96ab 100644 --- a/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs @@ -2,10 +2,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later using SharpEmu.HLE; -using System.Buffers.Binary; using System.Collections.Concurrent; using System.Text; -using System.Threading; using System.Diagnostics.CodeAnalysis; namespace SharpEmu.Libs.Kernel; @@ -279,7 +277,7 @@ public static class KernelPthreadExtendedCompatExports priority = GetOrCreateThreadStateLocked(thread).Priority; } - if (!TryWriteInt32(ctx, outPriorityAddress, priority)) + if (!ctx.TryWriteInt32(outPriorityAddress, priority)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -326,7 +324,7 @@ public static class KernelPthreadExtendedCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; } - if (!TryReadInt32(ctx, schedParamAddress, out var schedPriority)) + if (!ctx.TryReadInt32(schedParamAddress, out var schedPriority)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -496,7 +494,7 @@ public static class KernelPthreadExtendedCompatExports state = GetOrCreateAttrStateLocked(attrAddress); } - if (!TryWriteInt32(ctx, outStateAddress, state.DetachState)) + if (!ctx.TryWriteInt32(outStateAddress, state.DetachState)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -739,7 +737,7 @@ public static class KernelPthreadExtendedCompatExports state = GetOrCreateAttrStateLocked(attrAddress); } - if (!TryWriteInt32(ctx, schedParamAddress, state.SchedPriority)) + if (!ctx.TryWriteInt32(schedParamAddress, state.SchedPriority)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -762,7 +760,7 @@ public static class KernelPthreadExtendedCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; } - if (!TryReadInt32(ctx, schedParamAddress, out var schedPriority)) + if (!ctx.TryReadInt32(schedParamAddress, out var schedPriority)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1114,7 +1112,7 @@ public static class KernelPthreadExtendedCompatExports } } - if (!TryWriteInt32(ctx, outKeyAddress, key)) + if (!ctx.TryWriteInt32(outKeyAddress, key)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1451,24 +1449,4 @@ public static class KernelPthreadExtendedCompatExports payload[^1] = 0; return ctx.Memory.TryWrite(address, payload); } - - private static bool TryReadInt32(CpuContext ctx, ulong address, out int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - if (!ctx.Memory.TryRead(address, bytes)) - { - value = 0; - return false; - } - - value = BinaryPrimitives.ReadInt32LittleEndian(bytes); - return true; - } - - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(bytes, value); - return ctx.Memory.TryWrite(address, bytes); - } } diff --git a/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs index 2e3dc45..ceb4d3c 100644 --- a/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs @@ -4,14 +4,11 @@ using SharpEmu.HLE; using SharpEmu.Libs.Fiber; using System.Buffers.Binary; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using System.Security.Cryptography; using System.Text; -using System.Threading; namespace SharpEmu.Libs.Kernel; @@ -259,8 +256,8 @@ public static class KernelRuntimeCompatExports } if (timezoneAddress != 0 && - (!TryWriteInt32(ctx, timezoneAddress, 0) || - !TryWriteInt32(ctx, timezoneAddress + sizeof(int), 0))) + (!ctx.TryWriteInt32(timezoneAddress, 0) || + !ctx.TryWriteInt32(timezoneAddress + sizeof(int), 0))) { return -1; } @@ -617,7 +614,7 @@ public static class KernelRuntimeCompatExports internal static bool TrySetErrno(CpuContext ctx, int value) { var address = GetTlsScratchAddress(ctx, TlsErrnoOffset); - return address != 0 && TryWriteInt32(ctx, address, value); + return address != 0 && ctx.TryWriteInt32(address, value); } [SysAbiExport( @@ -827,7 +824,7 @@ public static class KernelRuntimeCompatExports } var moduleHandle = ResolveModuleHandleByAddress(queriedAddress); - if (!TryWriteInt32(ctx, outInfoAddress + ModuleInfoHandleOffset, moduleHandle)) + if (!ctx.TryWriteInt32(outInfoAddress + ModuleInfoHandleOffset, moduleHandle)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -857,7 +854,7 @@ public static class KernelRuntimeCompatExports } var moduleHandle = ResolveModuleHandleByAddress(queriedAddress); - if (!TryWriteInt32(ctx, outInfoAddress + ModuleInfoHandleOffset, moduleHandle)) + if (!ctx.TryWriteInt32(outInfoAddress + ModuleInfoHandleOffset, moduleHandle)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1058,7 +1055,7 @@ public static class KernelRuntimeCompatExports public static int KernelStopUnloadModule(CpuContext ctx) { var resultAddress = ctx[CpuRegister.R9]; - if (resultAddress != 0 && !TryWriteInt32(ctx, resultAddress, 0)) + if (resultAddress != 0 && !ctx.TryWriteInt32(resultAddress, 0)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1076,7 +1073,7 @@ public static class KernelRuntimeCompatExports { var modulePathAddress = ctx[CpuRegister.Rdi]; var resultAddress = ctx[CpuRegister.R9]; - if (resultAddress != 0 && !TryWriteInt32(ctx, resultAddress, 0)) + if (resultAddress != 0 && !ctx.TryWriteInt32(resultAddress, 0)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1233,8 +1230,8 @@ public static class KernelRuntimeCompatExports : 0; var minutesWest = unchecked((int)-offset.TotalMinutes); - if (!TryWriteInt32(ctx, timezoneAddress, minutesWest) || - !TryWriteInt32(ctx, timezoneAddress + sizeof(int), dstSeconds / 60)) + if (!ctx.TryWriteInt32(timezoneAddress, minutesWest) || + !ctx.TryWriteInt32(timezoneAddress + sizeof(int), dstSeconds / 60)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1244,7 +1241,7 @@ public static class KernelRuntimeCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } - if (dstSecondsAddress != 0 && !TryWriteInt32(ctx, dstSecondsAddress, dstSeconds)) + if (dstSecondsAddress != 0 && !ctx.TryWriteInt32(dstSecondsAddress, dstSeconds)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1304,7 +1301,7 @@ public static class KernelRuntimeCompatExports _loadedSysmodules.Add(moduleId); } - if (resultAddress != 0 && !TryWriteInt32(ctx, resultAddress, 0)) + if (resultAddress != 0 && !ctx.TryWriteInt32(resultAddress, 0)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1394,7 +1391,7 @@ public static class KernelRuntimeCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND; } - if (!TryWriteInt32(ctx, outInfoAddress + ModuleInfoHandleOffset, module.Handle)) + if (!ctx.TryWriteInt32(outInfoAddress + ModuleInfoHandleOffset, module.Handle)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1431,7 +1428,7 @@ public static class KernelRuntimeCompatExports var writableCount = (int)Math.Min(Math.Min(capacity, (ulong)int.MaxValue), (ulong)handles.Length); for (var i = 0; i < writableCount; i++) { - if (!TryWriteInt32(ctx, handlesAddress + (ulong)(i * sizeof(int)), handles[i])) + if (!ctx.TryWriteInt32(handlesAddress + (ulong)(i * sizeof(int)), handles[i])) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -1504,13 +1501,6 @@ public static class KernelRuntimeCompatExports return unchecked(ctx.FsBase + offset); } - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(bytes, value); - return ctx.Memory.TryWrite(address, bytes); - } - private static nint AllocateStackChkGuardObject() { try diff --git a/src/SharpEmu.Libs/Kernel/KernelSemaphoreCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelSemaphoreCompatExports.cs index 5c64814..3203199 100644 --- a/src/SharpEmu.Libs/Kernel/KernelSemaphoreCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelSemaphoreCompatExports.cs @@ -44,12 +44,12 @@ public static class KernelSemaphoreCompatExports initialCount > maxCount || optionAddress != 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!ctx.TryReadNullTerminatedUtf8(nameAddress, MaxSemaphoreNameLength, out var name)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } var handle = unchecked((uint)Interlocked.Increment(ref _nextSemaphoreHandle)); @@ -69,11 +69,11 @@ public static class KernelSemaphoreCompatExports if (!ctx.TryWriteUInt32(semaphoreAddress, handle)) { _semaphores.TryRemove(handle, out _); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceSemaphore($"create handle=0x{handle:X8} name='{name}' attr=0x{attr:X} init={initialCount} max={maxCount}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -89,12 +89,12 @@ public static class KernelSemaphoreCompatExports if (!_semaphores.TryGetValue(handle, out var semaphore)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } if (needCount < 1 || needCount > semaphore.MaxCount) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } lock (semaphore.Gate) @@ -103,30 +103,30 @@ public static class KernelSemaphoreCompatExports { semaphore.Count -= needCount; TraceSemaphore($"wait handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } if (timeoutAddress != 0) { if (!ctx.TryReadUInt32(timeoutAddress, out _)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } _ = ctx.TryWriteUInt32(timeoutAddress, 0); TraceSemaphore($"wait-timeout handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_TIMED_OUT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_TIMED_OUT); } if (!GuestThreadExecution.RequestCurrentThreadBlock(ctx, "sceKernelWaitSema")) { TraceSemaphore($"wait-would-block handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_TRY_AGAIN); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_TRY_AGAIN); } semaphore.WaitingThreads++; TraceSemaphore($"wait-block handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count} waiters={semaphore.WaitingThreads}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } } @@ -142,12 +142,12 @@ public static class KernelSemaphoreCompatExports if (!_semaphores.TryGetValue(handle, out var semaphore)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } if (needCount < 1 || needCount > semaphore.MaxCount) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } lock (semaphore.Gate) @@ -155,12 +155,12 @@ public static class KernelSemaphoreCompatExports if (semaphore.Count < needCount) { TraceSemaphore($"poll-busy handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_BUSY); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_BUSY); } semaphore.Count -= needCount; TraceSemaphore($"poll handle=0x{handle:X8} name='{semaphore.Name}' need={needCount} count={semaphore.Count}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } } @@ -176,24 +176,24 @@ public static class KernelSemaphoreCompatExports if (!_semaphores.TryGetValue(handle, out var semaphore)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } if (signalCount <= 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } lock (semaphore.Gate) { if (semaphore.Count > semaphore.MaxCount - signalCount) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } semaphore.Count += signalCount; TraceSemaphore($"signal handle=0x{handle:X8} name='{semaphore.Name}' signal={signalCount} count={semaphore.Count} waiters={semaphore.WaitingThreads}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } } @@ -210,25 +210,25 @@ public static class KernelSemaphoreCompatExports if (!_semaphores.TryGetValue(handle, out var semaphore)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } if (setCount > semaphore.MaxCount) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } lock (semaphore.Gate) { if (waitingThreadsAddress != 0 && !ctx.TryWriteUInt32(waitingThreadsAddress, unchecked((uint)semaphore.WaitingThreads))) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } semaphore.Count = setCount < 0 ? semaphore.InitialCount : setCount; semaphore.WaitingThreads = 0; TraceSemaphore($"cancel handle=0x{handle:X8} name='{semaphore.Name}' set={setCount} count={semaphore.Count}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } } @@ -242,18 +242,11 @@ public static class KernelSemaphoreCompatExports var handle = unchecked((uint)ctx[CpuRegister.Rdi]); if (!_semaphores.TryRemove(handle, out var semaphore)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND); } TraceSemaphore($"delete handle=0x{handle:X8} name='{semaphore.Name}'"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); - } - - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - var value = (int)result; - ctx[CpuRegister.Rax] = unchecked((ulong)value); - return value; + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private static void TraceSemaphore(string message) diff --git a/src/SharpEmu.Libs/Network/Http2Exports.cs b/src/SharpEmu.Libs/Network/Http2Exports.cs index 7f7085e..7fdd790 100644 --- a/src/SharpEmu.Libs/Network/Http2Exports.cs +++ b/src/SharpEmu.Libs/Network/Http2Exports.cs @@ -1,9 +1,7 @@ // Copyright (C) 2026 SharpEmu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -using System; using System.Collections.Concurrent; -using System.Threading; using SharpEmu.HLE; namespace SharpEmu.Libs.Network; @@ -32,7 +30,7 @@ public static class Http2Exports if (poolSize == 0 || maxRequests <= 0) { - return SetReturn(ctx, Http2ErrorInvalidArgument); + return ctx.SetReturn(Http2ErrorInvalidArgument); } var id = Interlocked.Increment(ref _nextContextId); @@ -53,17 +51,11 @@ public static class Http2Exports var id = unchecked((int)ctx[CpuRegister.Rdi]); if (!_contexts.TryRemove(id, out _)) { - return SetReturn(ctx, Http2ErrorInvalidId); + return ctx.SetReturn(Http2ErrorInvalidId); } TraceHttp2("term", id, 0, 0, 0, 0); - return SetReturn(ctx, 0); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + return ctx.SetReturn(0); } private static void TraceHttp2(string operation, int id, ulong arg0, ulong arg1, ulong arg2, ulong arg3) diff --git a/src/SharpEmu.Libs/Network/HttpExports.cs b/src/SharpEmu.Libs/Network/HttpExports.cs index 98a80b9..035f7e0 100644 --- a/src/SharpEmu.Libs/Network/HttpExports.cs +++ b/src/SharpEmu.Libs/Network/HttpExports.cs @@ -3,7 +3,6 @@ using SharpEmu.HLE; using System.Collections.Concurrent; -using System.Threading; namespace SharpEmu.Libs.Network; @@ -33,7 +32,7 @@ public static class HttpExports var poolSize = ctx[CpuRegister.Rdx]; if (poolSize == 0) { - return SetReturn(ctx, HttpErrorInvalidValue); + return ctx.SetReturn(HttpErrorInvalidValue); } var id = Interlocked.Increment(ref _nextContextId); @@ -53,7 +52,7 @@ public static class HttpExports var contextId = unchecked((int)ctx[CpuRegister.Rdi]); if (!Contexts.ContainsKey(contextId)) { - return SetReturn(ctx, HttpErrorInvalidId); + return ctx.SetReturn(HttpErrorInvalidId); } var userAgentAddress = ctx[CpuRegister.Rsi]; @@ -75,8 +74,8 @@ public static class HttpExports { var templateId = unchecked((int)ctx[CpuRegister.Rdi]); return Templates.TryRemove(templateId, out _) - ? SetReturn(ctx, 0) - : SetReturn(ctx, HttpErrorInvalidId); + ? ctx.SetReturn(0) + : ctx.SetReturn(HttpErrorInvalidId); } [SysAbiExport( @@ -89,7 +88,7 @@ public static class HttpExports var contextId = unchecked((int)ctx[CpuRegister.Rdi]); if (!Contexts.TryRemove(contextId, out _)) { - return SetReturn(ctx, HttpErrorInvalidId); + return ctx.SetReturn(HttpErrorInvalidId); } foreach (var pair in Templates) @@ -100,13 +99,7 @@ public static class HttpExports } } - return SetReturn(ctx, 0); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + return ctx.SetReturn(0); } private static void TraceHttp(string operation, int id, ulong arg0, ulong arg1, ulong arg2, ulong arg3) diff --git a/src/SharpEmu.Libs/Network/NetCtlExports.cs b/src/SharpEmu.Libs/Network/NetCtlExports.cs index 3020dcd..8c49830 100644 --- a/src/SharpEmu.Libs/Network/NetCtlExports.cs +++ b/src/SharpEmu.Libs/Network/NetCtlExports.cs @@ -57,27 +57,27 @@ public static class NetCtlExports var natInfoAddress = ctx[CpuRegister.Rdi]; if (natInfoAddress == 0) { - return SetReturn(ctx, NetCtlErrorInvalidAddress); + return ctx.SetReturn(NetCtlErrorInvalidAddress, typeof(long)); } Span natInfo = stackalloc byte[NatInfoSize]; if (!ctx.Memory.TryRead(natInfoAddress, natInfo)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } var size = BinaryPrimitives.ReadUInt32LittleEndian(natInfo[..sizeof(uint)]); if (size != NatInfoSize) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT, typeof(long)); } BinaryPrimitives.WriteInt32LittleEndian(natInfo[4..], 1); BinaryPrimitives.WriteInt32LittleEndian(natInfo[8..], 3); BinaryPrimitives.WriteUInt32LittleEndian(natInfo[12..], 0x7F000001); return ctx.Memory.TryWrite(natInfoAddress, natInfo) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } [SysAbiExport( @@ -87,7 +87,7 @@ public static class NetCtlExports LibraryName = "libSceNetCtl")] public static int NetCtlCheckCallback(CpuContext ctx) { - return SetReturn(ctx, 0); + return ctx.SetReturn(0, typeof(long)); } [SysAbiExport( @@ -100,14 +100,14 @@ public static class NetCtlExports var stateAddress = ctx[CpuRegister.Rdi]; if (stateAddress == 0) { - return SetReturn(ctx, NetCtlErrorInvalidAddress); + return ctx.SetReturn(NetCtlErrorInvalidAddress, typeof(long)); } Span stateBytes = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(stateBytes, 0); return ctx.Memory.TryWrite(stateAddress, stateBytes) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } [SysAbiExport( @@ -122,7 +122,7 @@ public static class NetCtlExports var callbackIdAddress = ctx[CpuRegister.Rdx]; if (function == 0 || callbackIdAddress == 0) { - return SetReturn(ctx, NetCtlErrorInvalidAddress); + return ctx.SetReturn(NetCtlErrorInvalidAddress, typeof(long)); } lock (CallbackGate) @@ -130,20 +130,20 @@ public static class NetCtlExports var callbackId = Array.FindIndex(Callbacks, static callback => callback.Function == 0); if (callbackId < 0) { - return SetReturn(ctx, NetCtlErrorNoSpace); + return ctx.SetReturn(NetCtlErrorNoSpace, typeof(long)); } Span callbackIdBytes = stackalloc byte[sizeof(uint)]; BinaryPrimitives.WriteUInt32LittleEndian(callbackIdBytes, unchecked((uint)callbackId)); if (!ctx.Memory.TryWrite(callbackIdAddress, callbackIdBytes)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } Callbacks[callbackId] = new CallbackRegistration(function, argument); } - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_OK, typeof(long)); } [SysAbiExport( @@ -157,7 +157,7 @@ public static class NetCtlExports var infoAddress = ctx[CpuRegister.Rsi]; if (infoAddress == 0) { - return SetReturn(ctx, NetCtlErrorInvalidAddress); + return ctx.SetReturn(NetCtlErrorInvalidAddress, typeof(long)); } return code switch @@ -177,7 +177,7 @@ public static class NetCtlExports NetCtlInfoHttpProxyConfig => WriteUInt32(ctx, infoAddress, 0), NetCtlInfoHttpProxyServer => WriteAsciiZ(ctx, infoAddress, string.Empty, 256), NetCtlInfoHttpProxyPort => WriteUInt16(ctx, infoAddress, 0), - _ => SetReturn(ctx, NetCtlErrorNotConnected), + _ => ctx.SetReturn(NetCtlErrorNotConnected, typeof(long)), }; } @@ -185,8 +185,8 @@ public static class NetCtlExports { Span bytes = stackalloc byte[count]; return ctx.Memory.TryWrite(address, bytes) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } private static int WriteUInt32(CpuContext ctx, ulong address, uint value) @@ -194,8 +194,8 @@ public static class NetCtlExports Span bytes = stackalloc byte[sizeof(uint)]; BinaryPrimitives.WriteUInt32LittleEndian(bytes, value); return ctx.Memory.TryWrite(address, bytes) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } private static int WriteUInt16(CpuContext ctx, ulong address, ushort value) @@ -203,8 +203,8 @@ public static class NetCtlExports Span bytes = stackalloc byte[sizeof(ushort)]; BinaryPrimitives.WriteUInt16LittleEndian(bytes, value); return ctx.Memory.TryWrite(address, bytes) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } private static int WriteAsciiZ(CpuContext ctx, ulong address, string value, int byteCount) @@ -217,13 +217,7 @@ public static class NetCtlExports } return ctx.Memory.TryWrite(address, bytes) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(long)result); - return result; + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } } diff --git a/src/SharpEmu.Libs/Network/NetExports.cs b/src/SharpEmu.Libs/Network/NetExports.cs index 19247d5..616a6db 100644 --- a/src/SharpEmu.Libs/Network/NetExports.cs +++ b/src/SharpEmu.Libs/Network/NetExports.cs @@ -1,11 +1,9 @@ // Copyright (C) 2026 SharpEmu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -using System; using System.Buffers.Binary; using System.Collections.Concurrent; using System.Text; -using System.Threading; using SharpEmu.HLE; namespace SharpEmu.Libs.Network; @@ -35,7 +33,7 @@ public static class NetExports { _initialized = true; TraceNet("init", 0, 0, 0, 0); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -49,7 +47,7 @@ public static class NetExports _pools.Clear(); _resolvers.Clear(); TraceNet("term", 0, 0, 0, 0); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -65,7 +63,7 @@ public static class NetExports if (size <= 0) { - return SetReturn(ctx, NetErrorInvalidArgument); + return ctx.SetReturn(NetErrorInvalidArgument); } var name = TryReadUtf8Z(ctx, nameAddress, MaxNameLength, out var value) @@ -90,11 +88,11 @@ public static class NetExports var id = unchecked((int)ctx[CpuRegister.Rdi]); if (!_pools.TryRemove(id, out _)) { - return SetReturn(ctx, NetErrorBadFileDescriptor); + return ctx.SetReturn(NetErrorBadFileDescriptor); } TraceNet("pool.destroy", id, 0, 0, _initialized ? 1UL : 0UL); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -109,7 +107,7 @@ public static class NetExports var flags = unchecked((int)ctx[CpuRegister.Rdx]); if (flags != 0) { - return SetReturn(ctx, NetErrorInvalidArgument); + return ctx.SetReturn(NetErrorInvalidArgument); } var name = TryReadUtf8Z(ctx, nameAddress, MaxNameLength, out var value) @@ -131,8 +129,8 @@ public static class NetExports { var id = unchecked((int)ctx[CpuRegister.Rdi]); return _resolvers.TryRemove(id, out _) - ? SetReturn(ctx, 0) - : SetReturn(ctx, NetErrorBadFileDescriptor); + ? ctx.SetReturn(0) + : ctx.SetReturn(NetErrorBadFileDescriptor); } [SysAbiExport( @@ -146,25 +144,19 @@ public static class NetExports var statusAddress = ctx[CpuRegister.Rsi]; if (statusAddress == 0) { - return SetReturn(ctx, NetErrorInvalidArgument); + return ctx.SetReturn(NetErrorInvalidArgument); } if (!_resolvers.TryGetValue(id, out var resolver)) { - return SetReturn(ctx, NetErrorBadFileDescriptor); + return ctx.SetReturn(NetErrorBadFileDescriptor); } Span status = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(status, resolver.LastError); return ctx.Memory.TryWrite(statusAddress, status) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } private static bool TryReadUtf8Z(CpuContext ctx, ulong address, int maxLength, out string value) diff --git a/src/SharpEmu.Libs/Network/SslExports.cs b/src/SharpEmu.Libs/Network/SslExports.cs index 4eeb632..8278b05 100644 --- a/src/SharpEmu.Libs/Network/SslExports.cs +++ b/src/SharpEmu.Libs/Network/SslExports.cs @@ -1,9 +1,7 @@ // Copyright (C) 2026 SharpEmu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -using System; using System.Collections.Concurrent; -using System.Threading; using SharpEmu.HLE; namespace SharpEmu.Libs.Network; @@ -28,7 +26,7 @@ public static class SslExports var poolSize = ctx[CpuRegister.Rdi]; if (poolSize == 0) { - return SetReturn(ctx, SslErrorOutOfSize); + return ctx.SetReturn(SslErrorOutOfSize); } var id = Interlocked.Increment(ref _nextContextId); @@ -49,11 +47,11 @@ public static class SslExports var id = unchecked((int)ctx[CpuRegister.Rdi]); if (!_contexts.TryRemove(id, out _)) { - return SetReturn(ctx, SslErrorInvalidId); + return ctx.SetReturn(SslErrorInvalidId); } TraceSsl("term", id, 0); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -65,13 +63,7 @@ public static class SslExports { var id = unchecked((int)ctx[CpuRegister.Rdi]); TraceSsl("close", id, 0); - return SetReturn(ctx, 0); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + return ctx.SetReturn(0); } private static void TraceSsl(string operation, int id, ulong arg0) diff --git a/src/SharpEmu.Libs/Ngs2/Ngs2Exports.cs b/src/SharpEmu.Libs/Ngs2/Ngs2Exports.cs index d755ab2..f309a96 100644 --- a/src/SharpEmu.Libs/Ngs2/Ngs2Exports.cs +++ b/src/SharpEmu.Libs/Ngs2/Ngs2Exports.cs @@ -4,7 +4,6 @@ using SharpEmu.HLE; using SharpEmu.Libs.Kernel; using System.Buffers.Binary; -using System.Threading; namespace SharpEmu.Libs.Ngs2; @@ -39,13 +38,13 @@ public static class Ngs2Exports var outHandleAddress = ctx[CpuRegister.Rdx]; if (outHandleAddress == 0) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidOutAddress); + return ctx.SetReturn(OrbisNgs2ErrorInvalidOutAddress); } if (!TryCreateHandle(ctx, type: 1, ownerHandle: 0, out var handle) || !ctx.TryWriteUInt64(outHandleAddress, handle)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } lock (StateGate) @@ -53,7 +52,7 @@ public static class Ngs2Exports Systems[handle] = new SystemState(unchecked((uint)Interlocked.Increment(ref _nextUid))); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -68,7 +67,7 @@ public static class Ngs2Exports { if (!Systems.Remove(handle)) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidSystemHandle); + return ctx.SetReturn(OrbisNgs2ErrorInvalidSystemHandle); } var rackHandles = Racks @@ -81,7 +80,7 @@ public static class Ngs2Exports } } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -98,19 +97,19 @@ public static class Ngs2Exports { if (!Systems.ContainsKey(systemHandle)) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidSystemHandle); + return ctx.SetReturn(OrbisNgs2ErrorInvalidSystemHandle); } } if (outHandleAddress == 0) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidOutAddress); + return ctx.SetReturn(OrbisNgs2ErrorInvalidOutAddress); } if (!TryCreateHandle(ctx, type: 2, systemHandle, out var handle) || !ctx.TryWriteUInt64(outHandleAddress, handle)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } lock (StateGate) @@ -118,7 +117,7 @@ public static class Ngs2Exports Racks[handle] = new RackState(systemHandle, rackId); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -133,13 +132,13 @@ public static class Ngs2Exports { if (!Racks.ContainsKey(handle)) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidRackHandle); + return ctx.SetReturn(OrbisNgs2ErrorInvalidRackHandle); } RemoveRackLocked(handle); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -156,7 +155,7 @@ public static class Ngs2Exports { if (!Racks.ContainsKey(rackHandle)) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidRackHandle); + return ctx.SetReturn(OrbisNgs2ErrorInvalidRackHandle); } var existing = Voices.FirstOrDefault( @@ -164,20 +163,20 @@ public static class Ngs2Exports if (existing.Key != 0) { return ctx.TryWriteUInt64(outHandleAddress, existing.Key) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } if (outHandleAddress == 0) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidOutAddress); + return ctx.SetReturn(OrbisNgs2ErrorInvalidOutAddress); } if (!TryCreateHandle(ctx, type: 4, rackHandle, out var handle) || !ctx.TryWriteUInt64(outHandleAddress, handle)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } lock (StateGate) @@ -185,7 +184,7 @@ public static class Ngs2Exports Voices[handle] = new VoiceState(rackHandle, voiceIndex); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -197,9 +196,10 @@ public static class Ngs2Exports { lock (StateGate) { - return SetReturn( - ctx, - Voices.ContainsKey(ctx[CpuRegister.Rdi]) ? 0 : OrbisNgs2ErrorInvalidVoiceHandle); + return ctx.SetReturn( + Voices.ContainsKey(ctx[CpuRegister.Rdi]) + ? 0 + : OrbisNgs2ErrorInvalidVoiceHandle); } } @@ -224,13 +224,13 @@ public static class Ngs2Exports { if (!Systems.ContainsKey(systemHandle)) { - return SetReturn(ctx, OrbisNgs2ErrorInvalidSystemHandle); + return ctx.SetReturn(OrbisNgs2ErrorInvalidSystemHandle); } } if (bufferInfoCount != 0 && bufferInfoAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } for (uint i = 0; i < bufferInfoCount; i++) @@ -239,14 +239,14 @@ public static class Ngs2Exports if (!ctx.TryReadUInt64(entryAddress, out var bufferAddress) || !ctx.TryReadUInt64(entryAddress + 8, out var bufferSize)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (bufferAddress != 0 && bufferSize != 0) { if (bufferSize > MaximumRenderBufferSize || !TryClearGuestBuffer(ctx, bufferAddress, bufferSize)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } } @@ -258,7 +258,7 @@ public static class Ngs2Exports $"[LOADER][TRACE] ngs2.render#{count} system=0x{systemHandle:X16} buffers={bufferInfoCount}"); } - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } private static bool TryCreateHandle(CpuContext ctx, uint type, ulong ownerHandle, out ulong handle) @@ -313,10 +313,4 @@ public static class Ngs2Exports Environment.GetEnvironmentVariable("SHARPEMU_LOG_NGS2"), "1", StringComparison.Ordinal); - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } } diff --git a/src/SharpEmu.Libs/Np/NpEntitlementAccessExports.cs b/src/SharpEmu.Libs/Np/NpEntitlementAccessExports.cs index bde587a..4efe1f6 100644 --- a/src/SharpEmu.Libs/Np/NpEntitlementAccessExports.cs +++ b/src/SharpEmu.Libs/Np/NpEntitlementAccessExports.cs @@ -26,12 +26,12 @@ public static class NpEntitlementAccessExports clear.Clear(); if (!ctx.Memory.TryWrite(bootParam, clear)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } TraceNpEntitlementAccess($"initialize init=0x{initParam:X16} boot=0x{bootParam:X16}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -48,20 +48,14 @@ public static class NpEntitlementAccessExports emptyList.Clear(); if (!ctx.Memory.TryWrite(listAddress, emptyList)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } TraceNpEntitlementAccess( $"get_addcont_info_list service=0x{ctx[CpuRegister.Rdi]:X16} list=0x{listAddress:X16} " + $"max={ctx[CpuRegister.Rdx]} flags=0x{ctx[CpuRegister.Rcx]:X16} -> empty"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); - } - - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(int)result); - return (int)result; + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private static void TraceNpEntitlementAccess(string message) diff --git a/src/SharpEmu.Libs/Np/NpManagerExports.cs b/src/SharpEmu.Libs/Np/NpManagerExports.cs index 5622bce..963e188 100644 --- a/src/SharpEmu.Libs/Np/NpManagerExports.cs +++ b/src/SharpEmu.Libs/Np/NpManagerExports.cs @@ -76,14 +76,14 @@ public static class NpManagerExports var stateAddress = ctx[CpuRegister.Rsi]; if (stateAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span stateBytes = stackalloc byte[sizeof(uint)]; BinaryPrimitives.WriteUInt32LittleEndian(stateBytes, 1); return ctx.Memory.TryWrite(stateAddress, stateBytes) - ? SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK) - : SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK) + : ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -97,7 +97,7 @@ public static class NpManagerExports var titleSecretAddress = ctx[CpuRegister.Rsi]; if (titleIdAddress == 0 || titleSecretAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span titleId = stackalloc byte[NpTitleIdSize]; @@ -105,17 +105,11 @@ public static class NpManagerExports if (!ctx.Memory.TryRead(titleIdAddress, titleId) || !ctx.Memory.TryRead(titleSecretAddress, titleSecret)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceNp($"set_np_title_id title='{ReadTitleId(titleId)}'"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); - } - - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(int)result); - return (int)result; + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private static string ReadTitleId(ReadOnlySpan bytes) diff --git a/src/SharpEmu.Libs/Np/NpUniversalDataSystemExports.cs b/src/SharpEmu.Libs/Np/NpUniversalDataSystemExports.cs index a51b3c4..be66cdd 100644 --- a/src/SharpEmu.Libs/Np/NpUniversalDataSystemExports.cs +++ b/src/SharpEmu.Libs/Np/NpUniversalDataSystemExports.cs @@ -3,7 +3,6 @@ using SharpEmu.HLE; using System.Buffers.Binary; -using System.Threading; namespace SharpEmu.Libs.Np; @@ -22,13 +21,13 @@ public static class NpUniversalDataSystemExports var parameterAddress = ctx[CpuRegister.Rdi]; if (parameterAddress == 0) { - return SetReturn(ctx, NpUniversalDataSystemErrorInvalidArgument); + return ctx.SetReturn(NpUniversalDataSystemErrorInvalidArgument, typeof(long)); } Span parameters = stackalloc byte[16]; return ctx.Memory.TryRead(parameterAddress, parameters) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } [SysAbiExport( @@ -41,14 +40,14 @@ public static class NpUniversalDataSystemExports var contextAddress = ctx[CpuRegister.Rdi]; if (contextAddress == 0) { - return SetReturn(ctx, 0); + return ctx.SetReturn(0, typeof(long)); } Span context = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(context, 1); return ctx.Memory.TryWrite(contextAddress, context) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0, typeof(long)) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } [SysAbiExport( @@ -59,13 +58,13 @@ public static class NpUniversalDataSystemExports public static int NpUniversalDataSystemCreateHandle(CpuContext ctx) { var handle = Interlocked.Increment(ref _nextHandle); - if (TryWriteInt32(ctx, ctx[CpuRegister.Rdi], handle) || - TryWriteInt32(ctx, ctx[CpuRegister.Rsi], handle)) + if (ctx.TryWriteInt32(ctx[CpuRegister.Rdi], handle, checkNil: true) || + ctx.TryWriteInt32(ctx[CpuRegister.Rsi], handle, checkNil: true)) { - return SetReturn(ctx, 0); + return ctx.SetReturn(0, typeof(long)); } - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, typeof(long)); } [SysAbiExport( @@ -75,24 +74,6 @@ public static class NpUniversalDataSystemExports LibraryName = "libSceNpUniversalDataSystem")] public static int NpUniversalDataSystemRegisterContext(CpuContext ctx) { - return SetReturn(ctx, 0); - } - - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - if (address == 0) - { - return false; - } - - Span bytes = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(bytes, value); - return ctx.Memory.TryWrite(address, bytes); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(long)result); - return result; + return ctx.SetReturn(0, typeof(long)); } } diff --git a/src/SharpEmu.Libs/Np/NpWebApi2Exports.cs b/src/SharpEmu.Libs/Np/NpWebApi2Exports.cs index 28b7afa..9b7684f 100644 --- a/src/SharpEmu.Libs/Np/NpWebApi2Exports.cs +++ b/src/SharpEmu.Libs/Np/NpWebApi2Exports.cs @@ -1,8 +1,6 @@ // Copyright (C) 2026 SharpEmu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -using System; -using System.Threading; using SharpEmu.HLE; namespace SharpEmu.Libs.Np; @@ -25,12 +23,12 @@ public static class NpWebApi2Exports if (httpContextId <= 0 || poolSize == 0) { - return SetReturn(ctx, NpWebApi2ErrorInvalidArgument); + return ctx.SetReturn(NpWebApi2ErrorInvalidArgument); } Interlocked.Exchange(ref _initialized, 1); TraceNpWebApi2("init", httpContextId, poolSize); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -43,13 +41,7 @@ public static class NpWebApi2Exports var libraryContextId = unchecked((int)ctx[CpuRegister.Rdi]); Interlocked.Exchange(ref _initialized, 0); TraceNpWebApi2("term", libraryContextId, 0); - return SetReturn(ctx, 0); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + return ctx.SetReturn(0); } private static void TraceNpWebApi2(string operation, int id, ulong arg0) diff --git a/src/SharpEmu.Libs/Pad/PadExports.cs b/src/SharpEmu.Libs/Pad/PadExports.cs index b6ac27f..1a10c67 100644 --- a/src/SharpEmu.Libs/Pad/PadExports.cs +++ b/src/SharpEmu.Libs/Pad/PadExports.cs @@ -30,7 +30,7 @@ public static class PadExports public static int PadInit(CpuContext ctx) { _initialized = true; - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } [SysAbiExport( @@ -46,21 +46,21 @@ public static class PadExports var parameterAddress = ctx[CpuRegister.Rcx]; if (!_initialized) { - return SetReturn(ctx, OrbisPadErrorNotInitialized); + return ctx.SetReturn(OrbisPadErrorNotInitialized); } if (userId == -1) { - return SetReturn(ctx, OrbisPadErrorDeviceNoHandle); + return ctx.SetReturn(OrbisPadErrorDeviceNoHandle); } if (userId != PrimaryUserId || type != StandardPortType || index != 0 || parameterAddress != 0) { - return SetReturn(ctx, OrbisPadErrorDeviceNotConnected); + return ctx.SetReturn(OrbisPadErrorDeviceNotConnected); } Console.Error.WriteLine("[LOADER][INFO] Keyboard controls: Arrow keys = D-pad, WASD = left stick, IJKL = right stick, Z/Enter = Cross, X/Esc = Circle, C = Square, V = Triangle, Q = L1, E = R1, R = L2, F = R2, Tab/Backspace = Options"); - return SetReturn(ctx, PrimaryPadHandle); + return ctx.SetReturn(PrimaryPadHandle); } [SysAbiExport( @@ -72,8 +72,8 @@ public static class PadExports { var handle = unchecked((int)ctx[CpuRegister.Rdi]); return handle == PrimaryPadHandle - ? SetReturn(ctx, 0) - : SetReturn(ctx, OrbisPadErrorInvalidHandle); + ? ctx.SetReturn(0) + : ctx.SetReturn(OrbisPadErrorInvalidHandle); } [SysAbiExport( @@ -87,12 +87,12 @@ public static class PadExports var informationAddress = ctx[CpuRegister.Rsi]; if (handle != PrimaryPadHandle) { - return SetReturn(ctx, OrbisPadErrorInvalidHandle); + return ctx.SetReturn(OrbisPadErrorInvalidHandle); } if (informationAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Span information = stackalloc byte[ControllerInformationSize]; @@ -107,8 +107,8 @@ public static class PadExports BinaryPrimitives.WriteInt32LittleEndian(information[0x10..], 0); return ctx.Memory.TryWrite(informationAddress, information) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -122,17 +122,17 @@ public static class PadExports var dataAddress = ctx[CpuRegister.Rsi]; if (handle != PrimaryPadHandle) { - return SetReturn(ctx, OrbisPadErrorInvalidHandle); + return ctx.SetReturn(OrbisPadErrorInvalidHandle); } if (dataAddress == 0) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } return WriteNeutralPadData(ctx, dataAddress) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -147,17 +147,17 @@ public static class PadExports var count = unchecked((int)ctx[CpuRegister.Rdx]); if (handle != PrimaryPadHandle) { - return SetReturn(ctx, OrbisPadErrorInvalidHandle); + return ctx.SetReturn(OrbisPadErrorInvalidHandle); } if (dataAddress == 0 || count < 1 || count > 64) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } return WriteNeutralPadData(ctx, dataAddress) - ? SetReturn(ctx, 1) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(1) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -167,7 +167,7 @@ public static class PadExports LibraryName = "libScePad")] public static int PadSetVibrationMode(CpuContext ctx) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_OK); } private static bool WriteNeutralPadData(CpuContext ctx, ulong dataAddress) @@ -201,12 +201,6 @@ public static class PadExports return ctx.Memory.TryWrite(dataAddress, data); } - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } - [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int vKey); diff --git a/src/SharpEmu.Libs/PlayGo/PlayGoExports.cs b/src/SharpEmu.Libs/PlayGo/PlayGoExports.cs index e3bdc2e..ea8f782 100644 --- a/src/SharpEmu.Libs/PlayGo/PlayGoExports.cs +++ b/src/SharpEmu.Libs/PlayGo/PlayGoExports.cs @@ -249,7 +249,7 @@ public static class PlayGoExports for (uint i = 0; i < entriesToWrite; i++) { var chunkId = chunkIds.Length == 0 ? (ushort)0 : chunkIds[i]; - if (!TryWriteUInt16(ctx, outChunkIdList + (i * sizeof(ushort)), chunkId)) + if (!ctx.TryWriteUInt16(outChunkIdList + (i * sizeof(ushort)), chunkId)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -292,7 +292,7 @@ public static class PlayGoExports return ValidateChunkIds(ctx, chunkIds, numberOfEntries) is { } chunkError && chunkError != 0 ? chunkError - : TryWriteInt64(ctx, outEta, 0) + : ctx.TryWriteInt64(outEta, 0) ? (int)OrbisGen2Result.ORBIS_GEN2_OK : (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -324,7 +324,7 @@ public static class PlayGoExports speed = _installSpeed; } - return TryWriteInt32(ctx, outSpeed, speed) + return ctx.TryWriteInt32(outSpeed, speed) ? (int)OrbisGen2Result.ORBIS_GEN2_OK : (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -399,7 +399,7 @@ public static class PlayGoExports var loci = new byte[numberOfEntries]; for (uint i = 0; i < numberOfEntries; i++) { - if (!TryReadUInt16(ctx, chunkIds + (i * sizeof(ushort)), out var chunkId)) + if (!ctx.TryReadUInt16(chunkIds + (i * sizeof(ushort)), out var chunkId)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -648,7 +648,7 @@ public static class PlayGoExports { for (uint i = 0; i < numberOfEntries; i++) { - if (!TryReadUInt16(ctx, chunkIds + (i * sizeof(ushort)), out var chunkId)) + if (!ctx.TryReadUInt16(chunkIds + (i * sizeof(ushort)), out var chunkId)) { return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } @@ -728,40 +728,6 @@ public static class PlayGoExports } } - private static bool TryReadUInt16(CpuContext ctx, ulong address, out ushort value) - { - Span buffer = stackalloc byte[sizeof(ushort)]; - if (!ctx.Memory.TryRead(address, buffer)) - { - value = 0; - return false; - } - - value = BinaryPrimitives.ReadUInt16LittleEndian(buffer); - return true; - } - - private static bool TryWriteUInt16(CpuContext ctx, ulong address, ushort value) - { - Span buffer = stackalloc byte[sizeof(ushort)]; - BinaryPrimitives.WriteUInt16LittleEndian(buffer, value); - return ctx.Memory.TryWrite(address, buffer); - } - - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - Span buffer = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(buffer, value); - return ctx.Memory.TryWrite(address, buffer); - } - - private static bool TryWriteInt64(CpuContext ctx, ulong address, long value) - { - Span buffer = stackalloc byte[sizeof(long)]; - BinaryPrimitives.WriteInt64LittleEndian(buffer, value); - return ctx.Memory.TryWrite(address, buffer); - } - private static void TracePlayGo(string message) { if (string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_PLAYGO"), "1", StringComparison.Ordinal)) diff --git a/src/SharpEmu.Libs/SaveData/SaveDataDialogExports.cs b/src/SharpEmu.Libs/SaveData/SaveDataDialogExports.cs index 9858f82..3d799e8 100644 --- a/src/SharpEmu.Libs/SaveData/SaveDataDialogExports.cs +++ b/src/SharpEmu.Libs/SaveData/SaveDataDialogExports.cs @@ -3,7 +3,6 @@ using SharpEmu.HLE; using System.Buffers.Binary; -using System.Threading; namespace SharpEmu.Libs.SaveData; @@ -35,10 +34,10 @@ public static class SaveDataDialogExports { if (Interlocked.CompareExchange(ref _status, StatusInitialized, StatusNone) != StatusNone) { - return SetReturn(ctx, ErrorAlreadyInitialized); + return ctx.SetReturn(ErrorAlreadyInitialized); } - return SetReturn(ctx, ErrorOk); + return ctx.SetReturn(ErrorOk); } [SysAbiExport( @@ -51,12 +50,12 @@ public static class SaveDataDialogExports var paramAddress = ctx[CpuRegister.Rdi]; if (paramAddress == 0) { - return SetReturn(ctx, ErrorArgNull); + return ctx.SetReturn(ErrorArgNull); } if (_status is not (StatusInitialized or StatusFinished)) { - return SetReturn(ctx, ErrorNotInitialized); + return ctx.SetReturn(ErrorNotInitialized); } _lastMode = TryReadInt32(ctx, paramAddress, out var mode) ? mode : 0; @@ -66,7 +65,7 @@ public static class SaveDataDialogExports // guest polling sees a finished dialog instead of spinning forever. Interlocked.Exchange(ref _status, StatusFinished); TraceSaveDataDialog($"open mode={_lastMode} userData=0x{_lastUserData:X16} -> finished"); - return SetReturn(ctx, ErrorOk); + return ctx.SetReturn(ErrorOk); } [SysAbiExport( @@ -74,21 +73,21 @@ public static class SaveDataDialogExports ExportName = "sceSaveDataDialogGetStatus", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceSaveDataDialog")] - public static int SaveDataDialogGetStatus(CpuContext ctx) => SetReturn(ctx, Volatile.Read(ref _status)); + public static int SaveDataDialogGetStatus(CpuContext ctx) => ctx.SetReturn(Volatile.Read(ref _status)); [SysAbiExport( Nid = "KK3Bdg1RWK0", ExportName = "sceSaveDataDialogUpdateStatus", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceSaveDataDialog")] - public static int SaveDataDialogUpdateStatus(CpuContext ctx) => SetReturn(ctx, Volatile.Read(ref _status)); + public static int SaveDataDialogUpdateStatus(CpuContext ctx) => ctx.SetReturn(Volatile.Read(ref _status)); [SysAbiExport( Nid = "en7gNVnh878", ExportName = "sceSaveDataDialogIsReadyToDisplay", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceSaveDataDialog")] - public static int SaveDataDialogIsReadyToDisplay(CpuContext ctx) => SetReturn(ctx, 1); + public static int SaveDataDialogIsReadyToDisplay(CpuContext ctx) => ctx.SetReturn(1); [SysAbiExport( Nid = "yEiJ-qqr6Cg", @@ -100,12 +99,12 @@ public static class SaveDataDialogExports var resultAddress = ctx[CpuRegister.Rdi]; if (resultAddress == 0) { - return SetReturn(ctx, ErrorArgNull); + return ctx.SetReturn(ErrorArgNull); } if (Volatile.Read(ref _status) != StatusFinished) { - return SetReturn(ctx, ErrorNotFinished); + return ctx.SetReturn(ErrorNotFinished); } Span result = stackalloc byte[ResultSize]; @@ -117,10 +116,10 @@ public static class SaveDataDialogExports if (!ctx.Memory.TryWrite(resultAddress, result)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } - return SetReturn(ctx, ErrorOk); + return ctx.SetReturn(ErrorOk); } [SysAbiExport( @@ -132,10 +131,10 @@ public static class SaveDataDialogExports { if (Interlocked.CompareExchange(ref _status, StatusFinished, StatusRunning) != StatusRunning) { - return SetReturn(ctx, ErrorNotRunning); + return ctx.SetReturn(ErrorNotRunning); } - return SetReturn(ctx, ErrorOk); + return ctx.SetReturn(ErrorOk); } [SysAbiExport( @@ -147,12 +146,12 @@ public static class SaveDataDialogExports { if (Interlocked.Exchange(ref _status, StatusNone) == StatusNone) { - return SetReturn(ctx, ErrorNotInitialized); + return ctx.SetReturn(ErrorNotInitialized); } _lastMode = 0; _lastUserData = 0; - return SetReturn(ctx, ErrorOk); + return ctx.SetReturn(ErrorOk); } [SysAbiExport( @@ -160,14 +159,14 @@ public static class SaveDataDialogExports ExportName = "sceSaveDataDialogProgressBarInc", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceSaveDataDialog")] - public static int SaveDataDialogProgressBarInc(CpuContext ctx) => SetReturn(ctx, ErrorOk); + public static int SaveDataDialogProgressBarInc(CpuContext ctx) => ctx.SetReturn(ErrorOk); [SysAbiExport( Nid = "hay1CfTmLyA", ExportName = "sceSaveDataDialogProgressBarSetValue", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceSaveDataDialog")] - public static int SaveDataDialogProgressBarSetValue(CpuContext ctx) => SetReturn(ctx, ErrorOk); + public static int SaveDataDialogProgressBarSetValue(CpuContext ctx) => ctx.SetReturn(ErrorOk); private static bool TryReadInt32(CpuContext ctx, ulong address, out int value) { @@ -182,12 +181,6 @@ public static class SaveDataDialogExports return true; } - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } - private static void TraceSaveDataDialog(string message) { if (!string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_SAVEDATA"), "1", StringComparison.Ordinal)) diff --git a/src/SharpEmu.Libs/SaveData/SaveDataExports.cs b/src/SharpEmu.Libs/SaveData/SaveDataExports.cs index 6ec166f..b0da09f 100644 --- a/src/SharpEmu.Libs/SaveData/SaveDataExports.cs +++ b/src/SharpEmu.Libs/SaveData/SaveDataExports.cs @@ -50,15 +50,15 @@ public static class SaveDataExports try { Directory.CreateDirectory(ResolveSaveDataRoot()); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } catch (IOException) { - return SetReturn(ctx, OrbisSaveDataErrorInternal); + return ctx.SetReturn(OrbisSaveDataErrorInternal); } catch (UnauthorizedAccessException) { - return SetReturn(ctx, OrbisSaveDataErrorInternal); + return ctx.SetReturn(OrbisSaveDataErrorInternal); } } @@ -73,18 +73,18 @@ public static class SaveDataExports var resultAddress = ctx[CpuRegister.Rsi]; if (condAddress == 0 || resultAddress == 0) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } if (!TryReadSearchCond(ctx, condAddress, out var cond) || !TryReadSearchResult(ctx, resultAddress, out var result)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (cond.UserId < 0 || cond.SortKey > SortKeyFreeBlocks || cond.SortOrder > SortOrderDescent) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } try @@ -96,7 +96,7 @@ public static class SaveDataExports } else if (!TryReadFixedAscii(ctx, cond.TitleIdAddress, SaveDataTitleIdSize, out titleId)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } var root = ResolveTitleSaveRoot(cond.UserId, titleId); @@ -111,18 +111,18 @@ public static class SaveDataExports if (!ctx.TryWriteUInt32(resultAddress + ResultHitNumOffset, checked((uint)entries.Count)) || !ctx.TryWriteUInt32(resultAddress + ResultSetNumOffset, checked((uint)setNum))) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (setNum == 0) { TraceSaveData($"dir_name_search user={cond.UserId} title={titleId} hits={entries.Count} set=0 root='{root}'"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } if (result.DirNamesAddress == 0) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } for (var i = 0; i < setNum; i++) @@ -138,20 +138,20 @@ public static class SaveDataExports (result.InfosAddress != 0 && !TryWriteSearchInfo(ctx, result.InfosAddress + ((ulong)i * SaveDataSearchInfoSize), entry))) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } } TraceSaveData($"dir_name_search user={cond.UserId} title={titleId} hits={entries.Count} set={setNum} root='{root}'"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } catch (IOException) { - return SetReturn(ctx, OrbisSaveDataErrorInternal); + return ctx.SetReturn(OrbisSaveDataErrorInternal); } catch (UnauthorizedAccessException) { - return SetReturn(ctx, OrbisSaveDataErrorInternal); + return ctx.SetReturn(OrbisSaveDataErrorInternal); } } @@ -166,10 +166,10 @@ public static class SaveDataExports var resultAddress = ctx[CpuRegister.Rsi]; if (mountAddress == 0 || resultAddress == 0) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } - if (!TryReadInt32(ctx, mountAddress, out var userId) || + if (!ctx.TryReadInt32(mountAddress, out var userId) || !ctx.TryReadUInt64(mountAddress + 0x08, out var dirNameAddress) || !ctx.TryReadUInt64(mountAddress + 0x10, out var blocks) || !ctx.TryReadUInt64(mountAddress + 0x18, out var systemBlocks) || @@ -179,12 +179,12 @@ public static class SaveDataExports dirNameAddress == 0 || !TryReadFixedAscii(ctx, dirNameAddress, SaveDataDirNameSize, out var dirName)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } if (userId < 0 || string.IsNullOrWhiteSpace(dirName)) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } try @@ -199,12 +199,12 @@ public static class SaveDataExports if (!existed && !create && !createIfMissing) { - return SetReturn(ctx, OrbisSaveDataErrorNotFound); + return ctx.SetReturn(OrbisSaveDataErrorNotFound); } if (existed && create) { - return SetReturn(ctx, OrbisSaveDataErrorExists); + return ctx.SetReturn(OrbisSaveDataErrorExists); } if (!existed) @@ -221,26 +221,26 @@ public static class SaveDataExports BinaryPrimitives.WriteUInt32LittleEndian(result[0x1C..], createIfMissing && !existed ? 1u : 0u); if (!ctx.Memory.TryWrite(resultAddress, result)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceSaveData( $"mount3 user={userId} title={titleId} dir={dirName} blocks={blocks} " + $"system_blocks={systemBlocks} mount_mode=0x{mountMode:X} resource={resource} mode={mode} " + $"mount_point={mountPoint} created={!existed} root='{savePath}'"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } catch (IOException) { - return SetReturn(ctx, OrbisSaveDataErrorInternal); + return ctx.SetReturn(OrbisSaveDataErrorInternal); } catch (UnauthorizedAccessException) { - return SetReturn(ctx, OrbisSaveDataErrorInternal); + return ctx.SetReturn(OrbisSaveDataErrorInternal); } catch (ArgumentException) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } } @@ -258,26 +258,26 @@ public static class SaveDataExports if (resourceAddress == 0) { - return SetReturn(ctx, OrbisSaveDataErrorParameter); + return ctx.SetReturn(OrbisSaveDataErrorParameter); } var id = (uint)Interlocked.Increment(ref _nextTransactionResource); if (!ctx.TryWriteUInt32(resourceAddress, id)) { - return SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } TraceSaveData( $"create_transaction_resource user={userId} reserved=0x{reserved:X} resource_addr=0x{resourceAddress:X} id={id}"); - return SetReturn(ctx, 0); + return ctx.SetReturn(0); } private static bool TryReadSearchCond(CpuContext ctx, ulong address, out SearchCond cond) { cond = default; - if (!TryReadInt32(ctx, address, out var userId) || + if (!ctx.TryReadInt32(address, out var userId) || !ctx.TryReadUInt64(address + 0x08, out var titleIdAddress) || !ctx.TryReadUInt64(address + 0x10, out var dirNameAddress) || !ctx.TryReadUInt32(address + 0x18, out var sortKey) || @@ -505,25 +505,6 @@ public static class SaveDataExports } } - private static bool TryReadInt32(CpuContext ctx, ulong address, out int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - if (!ctx.Memory.TryRead(address, bytes)) - { - value = 0; - return false; - } - - value = BinaryPrimitives.ReadInt32LittleEndian(bytes); - return true; - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; - } - private static void TraceSaveData(string message) { if (string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_SAVEDATA"), "1", StringComparison.Ordinal)) diff --git a/src/SharpEmu.Libs/Share/ShareExports.cs b/src/SharpEmu.Libs/Share/ShareExports.cs index fa4e803..cc6a271 100644 --- a/src/SharpEmu.Libs/Share/ShareExports.cs +++ b/src/SharpEmu.Libs/Share/ShareExports.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later using System.Text; -using System.Threading; using SharpEmu.HLE; namespace SharpEmu.Libs.Share; @@ -26,13 +25,13 @@ public static class ShareExports var affinityMask = ctx[CpuRegister.Rdx]; if (memorySize == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } Interlocked.Exchange(ref _initialized, 1); TraceShare($"initialize memory=0x{memorySize:X} priority={priority} affinity=0x{affinityMask:X}"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } [SysAbiExport( @@ -45,12 +44,12 @@ public static class ShareExports var contentParamAddress = ctx[CpuRegister.Rdi]; if (contentParamAddress == 0) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT); } if (!TryReadNullTerminatedUtf8(ctx, contentParamAddress, MaxContentParamBytes, out var contentParam)) { - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } _contentParam = contentParam; @@ -60,13 +59,7 @@ public static class ShareExports } TraceShare($"set_content_param len={contentParam.Length} preview='{FormatTraceString(contentParam)}'"); - return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK); - } - - private static int SetReturn(CpuContext ctx, OrbisGen2Result result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)(int)result); - return (int)result; + return ctx.SetReturn(OrbisGen2Result.ORBIS_GEN2_OK); } private static bool TryReadNullTerminatedUtf8(CpuContext ctx, ulong address, int maxLength, out string value) diff --git a/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs b/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs index 27537b2..89365d2 100644 --- a/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs +++ b/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs @@ -24,7 +24,7 @@ public static class SystemServiceExports var valueAddress = ctx[CpuRegister.Rsi]; if (valueAddress == 0) { - return SetReturn(ctx, OrbisSystemServiceErrorParameter); + return ctx.SetReturn(OrbisSystemServiceErrorParameter); } var value = parameterId switch @@ -37,8 +37,8 @@ public static class SystemServiceExports Span valueBytes = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(valueBytes, value); return ctx.Memory.TryWrite(valueAddress, valueBytes) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -51,7 +51,7 @@ public static class SystemServiceExports var statusAddress = ctx[CpuRegister.Rdi]; if (statusAddress == 0) { - return SetReturn(ctx, OrbisSystemServiceErrorParameter); + return ctx.SetReturn(OrbisSystemServiceErrorParameter); } Span status = stackalloc byte[SystemServiceStatusSize]; @@ -60,8 +60,8 @@ public static class SystemServiceExports status[0x06] = 1; return ctx.Memory.TryWrite(statusAddress, status) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -74,7 +74,7 @@ public static class SystemServiceExports var infoAddress = ctx[CpuRegister.Rdi]; if (infoAddress == 0) { - return SetReturn(ctx, OrbisSystemServiceErrorParameter); + return ctx.SetReturn(OrbisSystemServiceErrorParameter); } Span info = stackalloc byte[DisplaySafeAreaInfoSize]; @@ -82,8 +82,8 @@ public static class SystemServiceExports BinaryPrimitives.WriteSingleLittleEndian(info, 1.0f); return ctx.Memory.TryWrite(infoAddress, info) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -94,12 +94,6 @@ public static class SystemServiceExports public static int SystemServiceHideSplashScreen(CpuContext ctx) { VulkanVideoPresenter.HideSplashScreen(); - return SetReturn(ctx, 0); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + return ctx.SetReturn(0); } } diff --git a/src/SharpEmu.Libs/UserService/UserServiceExports.cs b/src/SharpEmu.Libs/UserService/UserServiceExports.cs index 44285fa..faee600 100644 --- a/src/SharpEmu.Libs/UserService/UserServiceExports.cs +++ b/src/SharpEmu.Libs/UserService/UserServiceExports.cs @@ -4,7 +4,6 @@ using SharpEmu.HLE; using System.Buffers.Binary; using System.Text; -using System.Threading; namespace SharpEmu.Libs.UserService; @@ -40,12 +39,12 @@ public static class UserServiceExports var userIdAddress = ctx[CpuRegister.Rdi]; if (userIdAddress == 0) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidArgument); + return ctx.SetReturn(OrbisUserServiceErrorInvalidArgument); } - return TryWriteInt32(ctx, userIdAddress, PrimaryUserId) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + return ctx.TryWriteInt32(userIdAddress, PrimaryUserId) + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -58,7 +57,7 @@ public static class UserServiceExports var userIdListAddress = ctx[CpuRegister.Rdi]; if (userIdListAddress == 0) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidArgument); + return ctx.SetReturn(OrbisUserServiceErrorInvalidArgument); } Span userIds = stackalloc byte[sizeof(int) * 4]; @@ -67,8 +66,8 @@ public static class UserServiceExports BinaryPrimitives.WriteInt32LittleEndian(userIds[0x08..], InvalidUserId); BinaryPrimitives.WriteInt32LittleEndian(userIds[0x0C..], InvalidUserId); return ctx.Memory.TryWrite(userIdListAddress, userIds) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -81,20 +80,20 @@ public static class UserServiceExports var eventAddress = ctx[CpuRegister.Rdi]; if (eventAddress == 0) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidArgument); + return ctx.SetReturn(OrbisUserServiceErrorInvalidArgument); } if (Interlocked.Exchange(ref _loginEventDelivered, 1) != 0) { - return SetReturn(ctx, OrbisUserServiceErrorNoEvent); + return ctx.SetReturn(OrbisUserServiceErrorNoEvent); } Span payload = stackalloc byte[sizeof(int) * 2]; BinaryPrimitives.WriteInt32LittleEndian(payload[0..], 0); BinaryPrimitives.WriteInt32LittleEndian(payload[sizeof(int)..], PrimaryUserId); return ctx.Memory.TryWrite(eventAddress, payload) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -109,25 +108,25 @@ public static class UserServiceExports var capacity = ctx[CpuRegister.Rdx]; if (userId != PrimaryUserId) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidParameter); + return ctx.SetReturn(OrbisUserServiceErrorInvalidParameter); } if (nameAddress == 0) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidArgument); + return ctx.SetReturn(OrbisUserServiceErrorInvalidArgument); } var nameBytes = Encoding.UTF8.GetBytes(PrimaryUserName); if (capacity <= (ulong)nameBytes.Length) { - return SetReturn(ctx, OrbisUserServiceErrorBufferTooShort); + return ctx.SetReturn(OrbisUserServiceErrorBufferTooShort); } Span output = stackalloc byte[nameBytes.Length + 1]; nameBytes.CopyTo(output); return ctx.Memory.TryWrite(nameAddress, output) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } [SysAbiExport( @@ -141,29 +140,16 @@ public static class UserServiceExports var valueAddress = ctx[CpuRegister.Rsi]; if (parameterId != 1000) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidParameter); + return ctx.SetReturn(OrbisUserServiceErrorInvalidParameter); } if (valueAddress == 0) { - return SetReturn(ctx, OrbisUserServiceErrorInvalidArgument); + return ctx.SetReturn(OrbisUserServiceErrorInvalidArgument); } - return TryWriteInt32(ctx, valueAddress, 0) - ? SetReturn(ctx, 0) - : SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); - } - - private static bool TryWriteInt32(CpuContext ctx, ulong address, int value) - { - Span bytes = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(bytes, value); - return ctx.Memory.TryWrite(address, bytes); - } - - private static int SetReturn(CpuContext ctx, int result) - { - ctx[CpuRegister.Rax] = unchecked((ulong)result); - return result; + return ctx.TryWriteInt32(valueAddress, 0) + ? ctx.SetReturn(0) + : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); } }