Skip to content

Make VersionAwareSizeOf trimmable #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions Cpp2IL.Core/Attributes/RegisterCpp2IlPluginAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ namespace Cpp2IL.Core.Attributes;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class RegisterCpp2IlPluginAttribute : Attribute
{
#if NET6_0
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
#endif
public Type PluginType { get; }

public RegisterCpp2IlPluginAttribute(Type pluginType)
public RegisterCpp2IlPluginAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type pluginType)
{
if (!typeof(Cpp2IlPlugin).IsAssignableFrom(pluginType))
throw new ArgumentException("Plugin type to register must extend Cpp2IlPlugin", nameof(pluginType));
Expand All @@ -22,4 +20,4 @@ public RegisterCpp2IlPluginAttribute(Type pluginType)

PluginType = pluginType;
}
}
}
3 changes: 2 additions & 1 deletion Cpp2IL.Core/Cpp2IL.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<!--Plugins make this non-trimmable-->

<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild>
<PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>
</PropertyGroup>

<ItemGroup>
Expand All @@ -40,7 +41,7 @@
<!--Not used at runtime, but needed for the build-->
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />

<PackageReference Include="PolySharp" Version="1.12.1" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<PackageReference Include="PolySharp" Version="1.14.1" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'net6.0'">
Expand Down
3 changes: 2 additions & 1 deletion Cpp2IL.Core/Utils/MiscUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using Cpp2IL.Core.Extensions;
Expand Down Expand Up @@ -153,7 +154,7 @@ public static int GetPointerSizeBytes()
return LibCpp2IlMain.Binary!.is32Bit ? 4 : 8;
}

public static IConvertible ReinterpretBytes(IConvertible original, Type desired)
public static IConvertible ReinterpretBytes(IConvertible original, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type desired)
{
if (desired is null)
throw new ArgumentNullException(nameof(desired), "Destination type is null");
Expand Down
3 changes: 2 additions & 1 deletion LibCpp2IL/LibCpp2IL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<Description>Library for interacting with IL2CPP metadata and binaries</Description>
<Configurations>Debug;Release</Configurations>
<TargetFrameworks>net7.0;net6.0;netstandard2.0</TargetFrameworks>
<PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>
</PropertyGroup>

<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
Expand All @@ -26,12 +27,12 @@

<ItemGroup>
<PackageReference Include="AssetRipper.Primitives" Version="2.0.0" />
<PackageReference Include="PolySharp" Version="1.14.1" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'net6.0'">
<PackageReference Include="IndexRange" Version="1.0.2" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>

<ItemGroup>
Expand Down
85 changes: 40 additions & 45 deletions LibCpp2IL/LibCpp2IlUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,22 @@ public static class LibCpp2ILUtils
{28, "object"}
};

private static readonly Dictionary<string, ulong> PrimitiveSizes = new()
private static readonly Dictionary<Type, byte> PrimitiveSizes = new()
{
{"Byte", 1},
{"SByte", 1},
{"Boolean", 1},
{"Int16", 2},
{"UInt16", 2},
{"Char", 2},
{"Int32", 4},
{"UInt32", 4},
{"Single", 4},
{"Int64", 8},
{"UInt64", 8},
{"Double", 8},
{"IntPtr", 8},
{"UIntPtr", 8},
{typeof(byte), 1},
{typeof(sbyte), 1},
{typeof(bool), 1},
{typeof(short), 2},
{typeof(ushort), 2},
{typeof(char), 2},
{typeof(int), 4},
{typeof(uint), 4},
{typeof(float), 4},
{typeof(long), 8},
{typeof(ulong), 8},
{typeof(double), 8},
{typeof(IntPtr), 8},
{typeof(UIntPtr), 8},
};

private static Dictionary<FieldInfo, VersionAttribute[]> _cachedVersionAttributes = new();
Expand Down Expand Up @@ -393,18 +393,17 @@ public static Il2CppTypeReflectionData GetTypeReflectionData(Il2CppType forWhat)
throw new ArgumentException($"Unknown type {forWhat.Type}");
}

#pragma warning disable IL2070 //'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields'
public static int VersionAwareSizeOf(
Type type,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type type,
bool dontCheckVersionAttributes = false,
bool downsize = true
)
{
if (type.IsEnum)
type = type.GetEnumUnderlyingType();
return PrimitiveSizes[type.GetEnumUnderlyingType()];

if (type.IsPrimitive)
return (int) PrimitiveSizes[type.Name];
return PrimitiveSizes[type];

var shouldDownsize = downsize && LibCpp2IlMain.Binary!.is32Bit;

Expand All @@ -418,36 +417,32 @@ public static int VersionAwareSizeOf(
continue;
}

switch (field.FieldType.Name)
{
case "Int64":
case "UInt64":
size += shouldDownsize ? 4 : 8;
break;
case "Int32":
case "UInt32":
size += 4;
break;
case "Int16":
case "UInt16":
size += 2;
break;
case "Byte":
case "SByte":
size += 1;
break;
default:
if (field.FieldType == type)
throw new Exception($"Infinite recursion is not allowed. Field {field} of type {type} has the same type as its parent.");

size += VersionAwareSizeOf(field.FieldType, dontCheckVersionAttributes, downsize);
break;
}
if (field.FieldType == typeof(long) || field.FieldType == typeof(ulong))
size += shouldDownsize ? 4 : 8;
else if (field.FieldType == typeof(int) || field.FieldType == typeof(uint))
size += 4;
else if (field.FieldType == typeof(short) || field.FieldType == typeof(ushort))
size += 2;
else if (field.FieldType == typeof(byte) || field.FieldType == typeof(sbyte))
size += 1;
else if (field.FieldType.IsEnum)
size += PrimitiveSizes[field.FieldType.GetEnumUnderlyingType()];
else if (field.FieldType.IsPrimitive)
size += PrimitiveSizes[field.FieldType];
else if (field.FieldType == type)
throw new Exception($"Infinite recursion is not allowed. Field {field} of type {type} has the same type as its parent.");
else if (field.FieldType == typeof(Il2CppGenericContext))
size += VersionAwareSizeOf(typeof(Il2CppGenericContext), dontCheckVersionAttributes, downsize);
else if (field.FieldType == typeof(Il2CppGenericMethodIndices))
size += VersionAwareSizeOf(typeof(Il2CppGenericMethodIndices), dontCheckVersionAttributes, downsize);
else if (field.FieldType == typeof(Il2CppAssemblyNameDefinition))
size += VersionAwareSizeOf(typeof(Il2CppAssemblyNameDefinition), dontCheckVersionAttributes, downsize);
else
throw new Exception($"Custom field type '{field.FieldType}' has no special case.");
}

return size;
}
#pragma warning restore IL2070

internal static IEnumerable<int> Range(int start, int count)
{
Expand Down
3 changes: 2 additions & 1 deletion LibCpp2IL/Metadata/Il2CppMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -286,7 +287,7 @@ private Il2CppMetadata(MemoryStream stream) : base(stream)
}
#pragma warning restore 8618

private T[] ReadMetadataClassArray<T>(int offset, int length) where T : ReadableClass, new()
private T[] ReadMetadataClassArray<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(int offset, int length) where T : ReadableClass, new()
{
return ReadReadableArrayAtRawAddr<T>(offset, length / LibCpp2ILUtils.VersionAwareSizeOf(typeof(T), downsize: false));
}
Expand Down