using System;
using System.Runtime.CompilerServices;
using MonoMod.Utils;
namespace BepInEx.IL2CPP
{
///
/// A general purpose memory allocator for patching purposes.
/// Allows to allocate memory within the 2GB radius of a given address.
///
/// Based on https://github.com/kubo/funchook
internal abstract class MemoryAllocator
{
///
/// Common page size on Unix and Windows (4k).
///
protected const int PAGE_SIZE = 0x1000;
///
/// Allocation granularity on Windows (but can be reused in other implementations).
///
protected const int ALLOCATION_UNIT = 0x100000;
private static MemoryAllocator instance;
public static MemoryAllocator Instance => instance ??= Init();
public abstract IntPtr Allocate(IntPtr func);
public abstract void Free(IntPtr buffer);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static long RoundDown(long num, long unit)
{
return num & ~(unit - 1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static long RoundUp(long num, long unit)
{
return (num + unit - 1) & ~ (unit - 1);
}
private static MemoryAllocator Init()
{
if (PlatformHelper.Is(Platform.Windows))
return new WindowsMemoryAllocator();
if (PlatformHelper.Is(Platform.Unix))
return new UnixMemoryAllocator();
throw new NotImplementedException();
}
}
}