Avoid dynamic reflection in SpirV

This commit is contained in:
Jeremy Pritts 2023-10-25 23:48:52 -04:00
parent 401c7fe6c3
commit 74a3d8a660
3 changed files with 31 additions and 12 deletions

View File

@ -189,7 +189,7 @@ namespace SpirV
{ {
foreach (uint key in enumOperandValue.Values.Keys) foreach (uint key in enumOperandValue.Values.Keys)
{ {
sb.Append(enumOperandValue.EnumerationType.GetEnumName(key)); sb.Append(enumOperandValue.GetEnumName(key));
IReadOnlyList<object> value = enumOperandValue.Values[key]; IReadOnlyList<object> value = enumOperandValue.Values[key];
if (value.Count != 0) if (value.Count != 0)
{ {

View File

@ -137,12 +137,12 @@ namespace SpirV
} }
public class EnumType<T> : EnumType<T, ParameterFactory> public class EnumType<T> : EnumType<T, ParameterFactory>
where T : Enum where T : unmanaged, Enum
{ {
}; };
public class EnumType<T, U> : OperandType public class EnumType<T, U> : OperandType
where T : Enum where T : unmanaged, Enum
where U : ParameterFactory, new() where U : ParameterFactory, new()
{ {
public override bool ReadValue(IReadOnlyList<uint> words, int index, out object value, out int wordsUsed) public override bool ReadValue(IReadOnlyList<uint> words, int index, out object value, out int wordsUsed)

View File

@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
namespace SpirV namespace SpirV
@ -38,7 +39,7 @@ namespace SpirV
return ((ObjectReference)Value).Id; return ((ObjectReference)Value).Id;
} }
public T GetBitEnumValue<T>() where T : Enum public uint GetBitEnumValue()
{ {
IBitEnumOperandValue v = (IBitEnumOperandValue)Value; IBitEnumOperandValue v = (IBitEnumOperandValue)Value;
@ -48,7 +49,7 @@ namespace SpirV
result |= k; result |= k;
} }
return (T)(object)result; return result;
} }
public IReadOnlyList<uint> Words { get; } public IReadOnlyList<uint> Words { get; }
@ -95,7 +96,7 @@ namespace SpirV
public interface IEnumOperandValue public interface IEnumOperandValue
{ {
System.Type EnumerationType { get; } string? GetEnumName(uint value);
} }
public interface IBitEnumOperandValue : IEnumOperandValue public interface IBitEnumOperandValue : IEnumOperandValue
@ -109,8 +110,28 @@ namespace SpirV
IReadOnlyList<object> Value { get; } IReadOnlyList<object> Value { get; }
} }
public class ValueEnumOperandValue<T> : IValueEnumOperandValue public abstract class EnumOperandValue<T> : IEnumOperandValue
where T : Enum where T : unmanaged, Enum
{
public string? GetEnumName(uint value)
{
if (Unsafe.SizeOf<T>() == sizeof(uint))
{
return Enum.GetName<T>(Unsafe.As<uint, T>(ref value));
}
else
{
#if DEBUG
throw new InvalidCastException();
#else
return default;//Exceptions prevent inlining.
#endif
}
}
}
public class ValueEnumOperandValue<T> : EnumOperandValue<T>, IValueEnumOperandValue
where T : unmanaged, Enum
{ {
public ValueEnumOperandValue(T key, IReadOnlyList<object> value) public ValueEnumOperandValue(T key, IReadOnlyList<object> value)
{ {
@ -118,13 +139,12 @@ namespace SpirV
Value = value; Value = value;
} }
public System.Type EnumerationType => typeof(T);
public object Key { get; } public object Key { get; }
public IReadOnlyList<object> Value { get; } public IReadOnlyList<object> Value { get; }
} }
public class BitEnumOperandValue<T> : IBitEnumOperandValue public class BitEnumOperandValue<T> : EnumOperandValue<T>, IBitEnumOperandValue
where T : Enum where T : unmanaged, Enum
{ {
public BitEnumOperandValue(Dictionary<uint, IReadOnlyList<object>> values) public BitEnumOperandValue(Dictionary<uint, IReadOnlyList<object>> values)
{ {
@ -132,7 +152,6 @@ namespace SpirV
} }
public IReadOnlyDictionary<uint, IReadOnlyList<object>> Values { get; } public IReadOnlyDictionary<uint, IReadOnlyList<object>> Values { get; }
public System.Type EnumerationType => typeof(T);
} }
public class ObjectReference public class ObjectReference