mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Allow FlexibleArray with union array data
This commit is contained in:
parent
8aef7275d0
commit
cc3fe5e40c
2 changed files with 58 additions and 9 deletions
|
@ -89,7 +89,7 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(.Struct)]
|
||||
[AttributeUsage(.Struct, .DisallowAllowMultiple)]
|
||||
struct FlexibleArrayAttribute : Attribute, IOnTypeInit
|
||||
{
|
||||
String mName;
|
||||
|
@ -99,21 +99,62 @@ namespace System
|
|||
mName = name;
|
||||
}
|
||||
|
||||
public this(params Span<String> names)
|
||||
{
|
||||
mName = new String();
|
||||
for (var name in names)
|
||||
{
|
||||
if (!mName.IsEmpty)
|
||||
mName.Append("\n");
|
||||
mName.Append(name);
|
||||
}
|
||||
}
|
||||
|
||||
[Comptime]
|
||||
public void OnTypeInit(Type type, Self* prev)
|
||||
{
|
||||
if (type.IsGenericParam)
|
||||
return;
|
||||
var field = type.GetField(type.FieldCount - 1).GetValueOrDefault();
|
||||
if (field.FieldType?.IsUnion == true)
|
||||
{
|
||||
int diff = 0;
|
||||
for (var unionField in field.FieldType.GetFields(.Instance))
|
||||
diff++;
|
||||
for (var names in mName.Split('\n'))
|
||||
diff--;
|
||||
if (diff != 0)
|
||||
Runtime.FatalError("Incorrect number of names specified");
|
||||
|
||||
var nameItr = mName.Split('\n');
|
||||
for (var unionField in field.FieldType.GetFields(.Instance))
|
||||
{
|
||||
var name = nameItr.GetNext().Value;
|
||||
if ((!unionField.FieldType.IsSizedArray) || (unionField.FieldType.Size != 0))
|
||||
Runtime.FatalError(scope $"Union field '{unionField.Name}' must be a zero-sized array");
|
||||
var elementType = (unionField.FieldType as SizedArrayType).UnderlyingType;
|
||||
Compiler.Align(type, elementType.Align);
|
||||
Compiler.EmitTypeBody(type, scope $"""
|
||||
public {elementType}* {name} mut => (({elementType}*)((uint8*)&this + typeof(Self).Size));
|
||||
public static int GetAllocSize_{name}(int arrayCount) => typeof(Self).Size + typeof({elementType}).Size*arrayCount;
|
||||
|
||||
""");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mName.Contains('\n'))
|
||||
Runtime.FatalError("Only a single accessor name expected");
|
||||
if ((field.FieldType == null) || (!field.FieldType.IsSizedArray) || (field.FieldType.Size != 0))
|
||||
Runtime.FatalError("Type must end in a zero-sized array");
|
||||
var elementType = (field.FieldType as SizedArrayType).UnderlyingType;
|
||||
Compiler.Align(type, elementType.Align);
|
||||
Compiler.EmitTypeBody(type, scope $"""
|
||||
public {elementType}* {mName} mut => (({elementType}*)((uint8*)&this + Math.Align(typeof(Self).Size, typeof({elementType}).Align)));
|
||||
public static int GetAllocSize(int arrayCount) => Math.Align(typeof(Self).Size, typeof({elementType}).Align) + typeof({elementType}).Size*arrayCount;
|
||||
public {elementType}* {mName} mut => (({elementType}*)((uint8*)&this + typeof(Self).Size));
|
||||
public static int GetAllocSize(int arrayCount) => typeof(Self).Size + typeof({elementType}).Size*arrayCount;
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11777,6 +11777,14 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
|||
newVals.Add(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType));
|
||||
}
|
||||
}
|
||||
else if (wantType->IsInstanceOf(mCompiler->mSpanTypeDef))
|
||||
{
|
||||
auto elementType = wantType->GetUnderlyingType();
|
||||
for (auto val : constArray->mValues)
|
||||
{
|
||||
newVals.Add(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto wantTypeInst = wantType->ToTypeInstance();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue