Skip to content

Commit

Permalink
Generate boolean fields in generic structs as a custom struct.
Browse files Browse the repository at this point in the history
  • Loading branch information
kremnev8 committed Jun 9, 2023
1 parent 35d2507 commit 9963313
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
13 changes: 10 additions & 3 deletions Il2CppInterop.Generator/Passes/Pass21GenerateValueTypeFields.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System;
using System.Linq;
using Il2CppInterop.Generator.Contexts;
using Il2CppInterop.Generator.Extensions;
using Il2CppInterop.Generator.Utils;
Expand Down Expand Up @@ -67,7 +65,16 @@ public static void DoPass(RewriteGlobalContext context)

// Special case: bools in Il2Cpp are bytes
if (newField.FieldType.FullName == "System.Boolean")
newField.MarshalInfo = new MarshalInfo(NativeType.U1);
{
if (typeContext.ComputedTypeSpecifics == TypeRewriteContext.TypeSpecifics.GenericBlittableStruct)
{
newField.FieldType = assemblyContext.Imports.NativeBoolean;
}
else
{
newField.MarshalInfo = new MarshalInfo(NativeType.U1);
}
}

newType.Fields.Add(newField);
}
Expand Down
6 changes: 6 additions & 0 deletions Il2CppInterop.Generator/Utils/RuntimeAssemblyReferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public RuntimeAssemblyReferences(ModuleDefinition module, RewriteGlobalContext g
public TypeReference DelegateSupport { get; private set; }
public TypeReference Il2CppException { get; private set; }

public TypeReference NativeBoolean { get; private set; }

private TypeReference ResolveType(string typeName)
{
return allTypes[typeName];
Expand Down Expand Up @@ -142,12 +144,16 @@ private void InitTypeRefs()

Il2CppException = new TypeReference("Il2CppInterop.Runtime", "Il2CppException", Module, assemblyRef);

NativeBoolean = new TypeReference("Il2CppInterop.Runtime", "NativeBoolean", Module, assemblyRef);
NativeBoolean.IsValueType = true;

allTypes["Il2CppInterop.Runtime.InteropTypes.Il2CppObjectBase"] = Il2CppObjectBase;
allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppStringArray"] = Il2CppStringArray;
allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppReferenceArray<T>"] = Il2CppReferenceArray;
allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppStructArray<T>"] = Il2CppStructArray;
allTypes["Il2CppInterop.Runtime.Il2CppException"] = Il2CppException;
allTypes["Il2CppInterop.Runtime.IL2CPP"] = Il2Cpp;
allTypes["Il2CppInterop.Runtime.NativeBoolean"] = NativeBoolean;
}

private void InitMethodRefs()
Expand Down
65 changes: 65 additions & 0 deletions Il2CppInterop.Runtime/InteropTypes/NativeBoolean.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Il2CppInterop.Runtime
{
[StructLayout(LayoutKind.Sequential)]
public readonly struct NativeBoolean : IComparable, IComparable<bool>, IEquatable<bool>, IComparable<NativeBoolean>, IEquatable<NativeBoolean>
{
private readonly byte Value;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator bool(NativeBoolean b)
=> Unsafe.As<NativeBoolean, bool>(ref b);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator NativeBoolean(bool b)
=> Unsafe.As<bool, NativeBoolean>(ref b);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
=> Unsafe.As<byte, bool>(ref Unsafe.AsRef(in Value)).GetHashCode();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override string ToString()
=> Unsafe.As<byte, bool>(ref Unsafe.AsRef(in Value)).ToString();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ToString(IFormatProvider? provider)
=> Unsafe.As<byte, bool>(ref Unsafe.AsRef(in Value)).ToString(provider);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryFormat(Span<char> destination, out int charsWritten)
=> Unsafe.As<byte, bool>(ref Unsafe.AsRef(in Value)).TryFormat(destination, out charsWritten);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object? obj)
=> obj switch
{
bool boolean => this == boolean,
NativeBoolean nativeBool => this == nativeBool,
_ => false
};

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(bool other)
=> this == other;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(NativeBoolean other)
=> this == other;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(object? obj)
=> Unsafe.As<byte, bool>(ref Unsafe.AsRef(in Value)).CompareTo(obj);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(bool value)
=> Unsafe.As<byte, bool>(ref Unsafe.AsRef(in Value)).CompareTo(value);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(NativeBoolean value)
=> CompareTo(Unsafe.As<NativeBoolean, bool>(ref value));
}
}

0 comments on commit 9963313

Please sign in to comment.