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
|
struct FlexibleArrayAttribute : Attribute, IOnTypeInit
|
||||||
{
|
{
|
||||||
String mName;
|
String mName;
|
||||||
|
@ -99,20 +99,61 @@ namespace System
|
||||||
mName = name;
|
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]
|
[Comptime]
|
||||||
public void OnTypeInit(Type type, Self* prev)
|
public void OnTypeInit(Type type, Self* prev)
|
||||||
{
|
{
|
||||||
if (type.IsGenericParam)
|
if (type.IsGenericParam)
|
||||||
return;
|
return;
|
||||||
var field = type.GetField(type.FieldCount - 1).GetValueOrDefault();
|
var field = type.GetField(type.FieldCount - 1).GetValueOrDefault();
|
||||||
if ((field.FieldType == null) || (!field.FieldType.IsSizedArray) || (field.FieldType.Size != 0))
|
if (field.FieldType?.IsUnion == true)
|
||||||
Runtime.FatalError("Type must end in a zero-sized array");
|
{
|
||||||
var elementType = (field.FieldType as SizedArrayType).UnderlyingType;
|
int diff = 0;
|
||||||
Compiler.Align(type, elementType.Align);
|
for (var unionField in field.FieldType.GetFields(.Instance))
|
||||||
Compiler.EmitTypeBody(type, scope $"""
|
diff++;
|
||||||
public {elementType}* {mName} mut => (({elementType}*)((uint8*)&this + Math.Align(typeof(Self).Size, typeof({elementType}).Align)));
|
for (var names in mName.Split('\n'))
|
||||||
public static int GetAllocSize(int arrayCount) => Math.Align(typeof(Self).Size, typeof({elementType}).Align) + typeof({elementType}).Size*arrayCount;
|
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 + 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));
|
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
|
else
|
||||||
{
|
{
|
||||||
auto wantTypeInst = wantType->ToTypeInstance();
|
auto wantTypeInst = wantType->ToTypeInstance();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue