Skip to content

Commit

Permalink
Non-generic sort
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotas committed Dec 13, 2022
1 parent 8d4661a commit 37fe7e9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,7 @@ public EnumInfo(Type underlyingType, TUnderlyingValue[] values, string[] names,
base(underlyingType, names, isFlags)
{
Debug.Assert(values.Length == names.Length);

if (!Enum.AreSorted(values))
{
Array.Sort(keys: (Array)values, items: names); // using non-generic overload to avoid generic expansion for every underlying enum type
}
Debug.Assert(Enum.AreSorted(values));

Values = values;
ValuesAreSequentialFromZero = Enum.AreSequentialFromZero(values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace Internal.Reflection.Execution
{
static class NativeFormatEnumInfo
{
public static EnumInfo<TUnderlyingValue> Create<TUnderlyingValue>(RuntimeTypeHandle typeHandle, MetadataReader reader, TypeDefinitionHandle typeDefHandle)
where TUnderlyingValue : struct, INumber<TUnderlyingValue>
private static void GetEnumValuesAndNames(MetadataReader reader, TypeDefinitionHandle typeDefHandle,
out object[] sortedBoxedValues, out string[] sortedNames, out bool isFlags)
{
TypeDefinition typeDef = reader.GetTypeDefinition(typeDefHandle);

Expand All @@ -30,8 +30,8 @@ public static EnumInfo<TUnderlyingValue> Create<TUnderlyingValue>(RuntimeTypeHan
}
}

string[] names = new string[staticFieldCount];
TUnderlyingValue[] values = new TUnderlyingValue[staticFieldCount];
var names = new string[staticFieldCount];
var boxedValues = new object[staticFieldCount]; // TODO: Avoid boxing the values

int i = 0;
foreach (FieldHandle fieldHandle in typeDef.Fields)
Expand All @@ -40,17 +40,34 @@ public static EnumInfo<TUnderlyingValue> Create<TUnderlyingValue>(RuntimeTypeHan
if (0 != (field.Flags & FieldAttributes.Static))
{
names[i] = field.Name.GetString(reader);
values[i] = (TUnderlyingValue)field.DefaultValue.ParseConstantNumericValue(reader);
boxedValues[i] = field.DefaultValue.ParseConstantNumericValue(reader);
i++;
}
}

bool isFlags = false;
// Using object overload to avoid generic expansion for every underlying enum type
// TODO: Sort the values in the aot compiler
Array.Sort<object, string>(boxedValues, names);

sortedBoxedValues = boxedValues;
sortedNames = names;

isFlags = false;
foreach (CustomAttributeHandle cah in typeDef.CustomAttributes)
{
if (cah.IsCustomAttributeOfType(reader, "System", "FlagsAttribute"))
isFlags = true;
}
}

public static EnumInfo<TUnderlyingValue> Create<TUnderlyingValue>(RuntimeTypeHandle typeHandle, MetadataReader reader, TypeDefinitionHandle typeDefHandle)
where TUnderlyingValue : struct, INumber<TUnderlyingValue>
{
GetEnumValuesAndNames(reader, typeDefHandle, out object[] boxedValues, out string[] names, out bool isFlags);

var values = new TUnderlyingValue[boxedValues.Length];
for (int i = 0; i < boxedValues.Length; i++)
values[i] = (TUnderlyingValue)boxedValues[i];

return new EnumInfo<TUnderlyingValue>(RuntimeAugments.GetEnumUnderlyingType(typeHandle), values, names, isFlags);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ public EnumInfo(bool hasFlagsAttribute, TUnderlyingValue[] values, string[] name
Values = values;
Names = names;

if (!AreSorted(values))
{
Array.Sort(keys: values, items: names);
}
Array.Sort(keys: values, items: names);

ValuesAreSequentialFromZero = AreSequentialFromZero(values);
}
Expand Down

0 comments on commit 37fe7e9

Please sign in to comment.