1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Added Compiler.Align

This commit is contained in:
Brian Fiete 2022-08-28 07:41:35 -07:00
parent ec4ccb2e9c
commit 8aef7275d0
5 changed files with 55 additions and 13 deletions

View file

@ -300,6 +300,7 @@ namespace System
} }
static extern void Comptime_SetReturnType(int32 typeId); static extern void Comptime_SetReturnType(int32 typeId);
static extern void Comptime_Align(int32 typeId, int32 align);
static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str); static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str);
static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags); static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags);
static extern void Comptime_EmitTypeBody(int32 typeId, StringView text); static extern void Comptime_EmitTypeBody(int32 typeId, StringView text);
@ -328,6 +329,12 @@ namespace System
Comptime_SetReturnType((.)type.TypeId); Comptime_SetReturnType((.)type.TypeId);
} }
[Comptime(OnlyFromComptime=true)]
public static void Align(Type type, int align)
{
Comptime_Align((.)type.TypeId, (.)align);
}
[Comptime(OnlyFromComptime=true)] [Comptime(OnlyFromComptime=true)]
public static void EmitAddInterface(Type owner, Type iface) public static void EmitAddInterface(Type owner, Type iface)
{ {

View file

@ -108,6 +108,7 @@ namespace System
if ((field.FieldType == null) || (!field.FieldType.IsSizedArray) || (field.FieldType.Size != 0)) if ((field.FieldType == null) || (!field.FieldType.IsSizedArray) || (field.FieldType.Size != 0))
Runtime.FatalError("Type must end in a zero-sized array"); Runtime.FatalError("Type must end in a zero-sized array");
var elementType = (field.FieldType as SizedArrayType).UnderlyingType; var elementType = (field.FieldType as SizedArrayType).UnderlyingType;
Compiler.Align(type, elementType.Align);
Compiler.EmitTypeBody(type, scope $""" Compiler.EmitTypeBody(type, scope $"""
public {elementType}* {mName} mut => (({elementType}*)((uint8*)&this + Math.Align(typeof(Self).Size, typeof({elementType}).Align))); 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 static int GetAllocSize(int arrayCount) => Math.Align(typeof(Self).Size, typeof({elementType}).Align) + typeof({elementType}).Size*arrayCount;

View file

@ -2544,19 +2544,24 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
} }
} }
} }
else if (ceEmitContext->HasEmissions()) else
{ {
if (typeInstance->mCeTypeInfo == NULL) if (ceEmitContext->HasEmissions())
typeInstance->mCeTypeInfo = new BfCeTypeInfo(); {
if (typeInstance->mCeTypeInfo->mNext == NULL) if (typeInstance->mCeTypeInfo == NULL)
typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo(); typeInstance->mCeTypeInfo = new BfCeTypeInfo();
if (typeInstance->mCeTypeInfo->mNext == NULL)
typeInstance->mCeTypeInfo->mNext = new BfCeTypeInfo();
BfCeTypeEmitEntry entry; BfCeTypeEmitEntry entry;
entry.mEmitData = ceEmitContext->mEmitData; entry.mEmitData = ceEmitContext->mEmitData;
typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap[typeId] = entry; typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap[typeId] = entry;
typeInstance->mCeTypeInfo->mNext->mAlign = BF_MAX(typeInstance->mCeTypeInfo->mNext->mAlign, ceEmitContext->mAlign);
}
if ((ceEmitContext->mFailed) && (typeInstance->mCeTypeInfo != NULL))
typeInstance->mCeTypeInfo->mFailed = true;
} }
else if ((ceEmitContext->mFailed) && (typeInstance->mCeTypeInfo != NULL))
typeInstance->mCeTypeInfo->mFailed = true;
if ((ceEmitContext->HasEmissions()) && (!mCompiler->mFastFinish)) if ((ceEmitContext->HasEmissions()) && (!mCompiler->mFastFinish))
{ {
@ -5088,6 +5093,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap; typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap; typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash; typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash;
typeInstance->mCeTypeInfo->mAlign = typeInstance->mCeTypeInfo->mNext->mAlign;
} }
delete typeInstance->mCeTypeInfo->mNext; delete typeInstance->mCeTypeInfo->mNext;
@ -5113,8 +5119,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
typeInstance->mCeTypeInfo->mFailed = false; typeInstance->mCeTypeInfo->mFailed = false;
} }
if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty())) if (typeInstance->mCeTypeInfo != NULL)
hadNewMembers = true; {
if (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty())
hadNewMembers = true;
}
if ((typeInstance->mTypeDef->IsEmitted()) && (typeInstance->mCeTypeInfo == NULL)) if ((typeInstance->mTypeDef->IsEmitted()) && (typeInstance->mCeTypeInfo == NULL))
{ {
@ -5596,6 +5605,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
bool needsExplicitAlignment = true; bool needsExplicitAlignment = true;
if (typeInstance->mCeTypeInfo != NULL)
{
typeInstance->mInstAlign = BF_MAX(typeInstance->mInstAlign, typeInstance->mCeTypeInfo->mAlign);
}
for (int fieldIdx = 0; fieldIdx < (int)dataFieldVec.size(); fieldIdx++) for (int fieldIdx = 0; fieldIdx < (int)dataFieldVec.size(); fieldIdx++)
{ {
auto fieldInstance = dataFieldVec[fieldIdx]; auto fieldInstance = dataFieldVec[fieldIdx];

View file

@ -6086,6 +6086,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
else else
_Fail("Comptime return types can only be set on methods declared with a 'var' return type"); _Fail("Comptime return types can only be set on methods declared with a 'var' return type");
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Align)
{
int32 typeId = *(int32*)((uint8*)stackPtr);
int32 align = *(int32*)((uint8*)stackPtr + sizeof(int32));
if ((mCurEmitContext == NULL) || (mCurEmitContext->mType == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
{
_Fail("This type cannot be modified in this context");
return false;
}
mCurEmitContext->mAlign = BF_MAX(mCurEmitContext->mAlign, align);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody) else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody)
{ {
int32 typeId = *(int32*)((uint8*)stackPtr); int32 typeId = *(int32*)((uint8*)stackPtr);
@ -9297,6 +9308,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{ {
ceFunction->mFunctionKind = CeFunctionKind_SetReturnType; ceFunction->mFunctionKind = CeFunctionKind_SetReturnType;
} }
else if (methodDef->mName == "Comptime_Align")
{
ceFunction->mFunctionKind = CeFunctionKind_Align;
}
else if (methodDef->mName == "Comptime_EmitTypeBody") else if (methodDef->mName == "Comptime_EmitTypeBody")
{ {
ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody; ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody;

View file

@ -449,6 +449,7 @@ enum CeFunctionKind
CeFunctionKind_Method_GetGenericArg, CeFunctionKind_Method_GetGenericArg,
CeFunctionKind_SetReturnType, CeFunctionKind_SetReturnType,
CeFunctionKind_Align,
CeFunctionKind_EmitTypeBody, CeFunctionKind_EmitTypeBody,
CeFunctionKind_EmitAddInterface, CeFunctionKind_EmitAddInterface,
CeFunctionKind_EmitMethodEntry, CeFunctionKind_EmitMethodEntry,
@ -975,6 +976,7 @@ public:
Array<int32> mInterfaces; Array<int32> mInterfaces;
String mEmitData; String mEmitData;
String mExitEmitData; String mExitEmitData;
int32 mAlign;
bool mFailed; bool mFailed;
CeEmitContext() CeEmitContext()
@ -982,11 +984,12 @@ public:
mType = NULL; mType = NULL;
mMethodInstance = NULL; mMethodInstance = NULL;
mFailed = false; mFailed = false;
mAlign = -1;
} }
bool HasEmissions() bool HasEmissions()
{ {
return !mEmitData.IsEmpty() || !mInterfaces.IsEmpty(); return !mEmitData.IsEmpty() || !mInterfaces.IsEmpty() || (mAlign != -1);
} }
}; };
@ -1031,6 +1034,7 @@ public:
bool mFastFinished; bool mFastFinished;
bool mFailed; bool mFailed;
bool mMayHaveUniqueEmitLocations; bool mMayHaveUniqueEmitLocations;
int32 mAlign;
BfCeTypeInfo* mNext; BfCeTypeInfo* mNext;
public: public:
@ -1039,6 +1043,7 @@ public:
mFastFinished = false; mFastFinished = false;
mFailed = false; mFailed = false;
mMayHaveUniqueEmitLocations = false; mMayHaveUniqueEmitLocations = false;
mAlign = -1;
mNext = NULL; mNext = NULL;
} }
}; };