mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-31 23:19:44 +08:00
feat: implement cosf, time, ctype tables, tracked heap access, IL2CPP lookup ABI paths (#542)
* fix: add Messenger CRT and AGC compatibility shims * fix: keep Messenger IL2CPP bootstrap on HLE shims * Fix Messenger compatibility ABI handling * Make IL2CPP ABI regression tests portable
This commit is contained in:
@@ -45,7 +45,11 @@ public static class LibcStdioExports
|
||||
private const ushort CtypeBlank = 0x400; // _XB ' ' and '\t'
|
||||
|
||||
private static readonly object _ctypeTableGate = new();
|
||||
private static readonly object _ctypeLowerTableGate = new();
|
||||
private static readonly object _ctypeUpperTableGate = new();
|
||||
private static nint _ctypeTableBase;
|
||||
private static nint _ctypeLowerTableBase;
|
||||
private static nint _ctypeUpperTableBase;
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "xeYO4u7uyJ0",
|
||||
@@ -716,6 +720,28 @@ public static class LibcStdioExports
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "1uJgoVq3bQU",
|
||||
ExportName = "_Getptolower",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libc")]
|
||||
public static int GetPtolower(CpuContext ctx)
|
||||
{
|
||||
ctx[CpuRegister.Rax] = unchecked((ulong)EnsureCtypeLowerTable());
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "rcQCUr0EaRU",
|
||||
ExportName = "_Getptoupper",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libc")]
|
||||
public static int GetPtoupper(CpuContext ctx)
|
||||
{
|
||||
ctx[CpuRegister.Rax] = unchecked((ulong)EnsureCtypeUpperTable());
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
private static unsafe nint EnsureCtypeTable()
|
||||
{
|
||||
lock (_ctypeTableGate)
|
||||
@@ -740,6 +766,58 @@ public static class LibcStdioExports
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe nint EnsureCtypeLowerTable()
|
||||
{
|
||||
lock (_ctypeLowerTableGate)
|
||||
{
|
||||
if (_ctypeLowerTableBase != 0)
|
||||
{
|
||||
return _ctypeLowerTableBase;
|
||||
}
|
||||
|
||||
var storage = Marshal.AllocHGlobal(CtypeTableEntryCount * sizeof(ushort));
|
||||
var entries = new Span<ushort>((void*)storage, CtypeTableEntryCount);
|
||||
for (var i = 0; i < CtypeTableEntryCount; i++)
|
||||
{
|
||||
var c = i + CtypeTableLowerBound;
|
||||
entries[i] = c == -1
|
||||
? ushort.MaxValue
|
||||
: c is >= 0 and <= 0x7F
|
||||
? (ushort)char.ToLowerInvariant((char)c)
|
||||
: (ushort)(c & 0xFF);
|
||||
}
|
||||
|
||||
_ctypeLowerTableBase = storage - (CtypeTableLowerBound * sizeof(ushort));
|
||||
return _ctypeLowerTableBase;
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe nint EnsureCtypeUpperTable()
|
||||
{
|
||||
lock (_ctypeUpperTableGate)
|
||||
{
|
||||
if (_ctypeUpperTableBase != 0)
|
||||
{
|
||||
return _ctypeUpperTableBase;
|
||||
}
|
||||
|
||||
var storage = Marshal.AllocHGlobal(CtypeTableEntryCount * sizeof(ushort));
|
||||
var entries = new Span<ushort>((void*)storage, CtypeTableEntryCount);
|
||||
for (var i = 0; i < CtypeTableEntryCount; i++)
|
||||
{
|
||||
var c = i + CtypeTableLowerBound;
|
||||
entries[i] = c == -1
|
||||
? ushort.MaxValue
|
||||
: c is >= 0 and <= 0x7F
|
||||
? (ushort)char.ToUpperInvariant((char)c)
|
||||
: (ushort)(c & 0xFF);
|
||||
}
|
||||
|
||||
_ctypeUpperTableBase = storage - (CtypeTableLowerBound * sizeof(ushort));
|
||||
return _ctypeUpperTableBase;
|
||||
}
|
||||
}
|
||||
|
||||
private static ushort ComputeCtypeFlags(int c)
|
||||
{
|
||||
var isUpper = c is >= 'A' and <= 'Z';
|
||||
|
||||
Reference in New Issue
Block a user