1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Fixed comptime static local variables

This commit is contained in:
Brian Fiete 2025-03-13 08:08:44 -04:00
parent 11ccb876a3
commit 17ca23c9af
3 changed files with 82 additions and 26 deletions

View file

@ -159,6 +159,7 @@ static CeOpInfo gOpInfo[] =
{"CeOp_GetSP", CEOI_FrameRef}, {"CeOp_GetSP", CEOI_FrameRef},
{"CeOp_SetSP", CEOI_None, CEOI_FrameRef}, {"CeOp_SetSP", CEOI_None, CEOI_FrameRef},
{"GetStaticField", CEOI_FrameRef, CEOI_IMM32}, {"GetStaticField", CEOI_FrameRef, CEOI_IMM32},
{"GetStaticField_Initializer", CEOI_FrameRef, CEOI_IMM32, CEOI_FrameRef},
{"GetMethod", CEOI_FrameRef, CEOI_IMM32}, {"GetMethod", CEOI_FrameRef, CEOI_IMM32},
{"GetMethod_Inner", CEOI_FrameRef, CEOI_IMM32}, {"GetMethod_Inner", CEOI_FrameRef, CEOI_IMM32},
{"GetMethod_Virt", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32}, {"GetMethod_Virt", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
@ -1565,29 +1566,10 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
return result; return result;
} }
BfFieldInstance** fieldInstancePtr = NULL; CeOperand initializerValue;
if (mStaticFieldInstanceMap.TryGetValue(globalVar->mName, &fieldInstancePtr))
if (globalVar->mIsConstant)
{ {
int* staticFieldTableIdxPtr = NULL;
if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
{
CeStaticFieldEntry staticFieldEntry;
staticFieldEntry.mTypeId = (*fieldInstancePtr)->mOwner->mTypeId;
staticFieldEntry.mName = globalVar->mName;
staticFieldEntry.mSize = globalVar->mType->mSize;
*staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
}
auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
Emit(CeOp_GetStaticField);
EmitFrameOffset(result);
Emit((int32)*staticFieldTableIdxPtr);
return result;
}
if (globalVar->mInitializer != NULL) if (globalVar->mInitializer != NULL)
{ {
auto result = GetOperand(globalVar->mInitializer, false, true); auto result = GetOperand(globalVar->mInitializer, false, true);
@ -1601,6 +1583,50 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
Emit((int32)result.mCallTableIdx); Emit((int32)result.mCallTableIdx);
return dataResult; return dataResult;
} }
return result;
}
}
else
{
initializerValue = GetOperand(globalVar->mInitializer);
BfFieldInstance** fieldInstancePtr = NULL;
mStaticFieldInstanceMap.TryGetValue(globalVar->mName, &fieldInstancePtr);
int* staticFieldTableIdxPtr = NULL;
if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
{
CeStaticFieldEntry staticFieldEntry;
if (fieldInstancePtr != NULL)
staticFieldEntry.mTypeId = (*fieldInstancePtr)->mOwner->mTypeId;
staticFieldEntry.mName = globalVar->mName;
if (globalVar->mLinkageType == Beefy::BfIRLinkageType_Internal)
{
staticFieldEntry.mName += "@";
staticFieldEntry.mName += mCeFunction->mMethodInstance->GetOwner()->mModule->mModuleName;
}
staticFieldEntry.mSize = globalVar->mType->mSize;
*staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
}
auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
if (initializerValue)
{
Emit(CeOp_GetStaticField_Initializer);
EmitFrameOffset(result);
Emit((int32)*staticFieldTableIdxPtr);
EmitFrameOffset(initializerValue);
}
else
{
Emit(CeOp_GetStaticField);
EmitFrameOffset(result);
Emit((int32)*staticFieldTableIdxPtr);
}
return result; return result;
} }
@ -8405,16 +8431,22 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
} }
break; break;
case CeOp_GetStaticField: case CeOp_GetStaticField:
case CeOp_GetStaticField_Initializer:
{ {
auto frameOfs = CE_GETINST(int32); auto frameOfs = CE_GETINST(int32);
int32 tableIdx = CE_GETINST(int32); int32 tableIdx = CE_GETINST(int32);
int32 initializerFrameOfs = 0;
if (op == CeOp_GetStaticField_Initializer)
{
initializerFrameOfs = CE_GETINST(int32);;
}
CeFunction* ctorCallFunction = NULL; CeFunction* ctorCallFunction = NULL;
auto& ceStaticFieldEntry = ceFunction->mStaticFieldTable[tableIdx]; auto& ceStaticFieldEntry = ceFunction->mStaticFieldTable[tableIdx];
if (ceStaticFieldEntry.mBindExecuteId != mExecuteId) if (ceStaticFieldEntry.mBindExecuteId != mExecuteId)
{ {
if ((mStaticCtorExecSet.TryAdd(ceStaticFieldEntry.mTypeId, NULL)) && (!ceStaticFieldEntry.mName.StartsWith("#"))) if ((ceStaticFieldEntry.mTypeId > 0) && (mStaticCtorExecSet.TryAdd(ceStaticFieldEntry.mTypeId, NULL)) && (!ceStaticFieldEntry.mName.StartsWith("#")))
{ {
auto bfType = GetBfType(ceStaticFieldEntry.mTypeId); auto bfType = GetBfType(ceStaticFieldEntry.mTypeId);
BfTypeInstance* bfTypeInstance = NULL; BfTypeInstance* bfTypeInstance = NULL;
@ -8467,6 +8499,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
memset(ptr, 0, ceStaticFieldEntry.mSize); memset(ptr, 0, ceStaticFieldEntry.mSize);
staticFieldInfo->mAddr = (addr_ce)(ptr - memStart); staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
if (op == CeOp_GetStaticField_Initializer)
{
void* initDataPtr = framePtr + initializerFrameOfs;
memcpy(ptr, initDataPtr, ceStaticFieldEntry.mSize);
}
if (ceStaticFieldEntry.mName.StartsWith("#")) if (ceStaticFieldEntry.mName.StartsWith("#"))
{ {
addr_ce resultAddr = 0; addr_ce resultAddr = 0;

View file

@ -111,6 +111,7 @@ enum CeOp : int16
CeOp_GetSP, CeOp_GetSP,
CeOp_SetSP, CeOp_SetSP,
CeOp_GetStaticField, CeOp_GetStaticField,
CeOp_GetStaticField_Initializer,
CeOp_GetMethod, CeOp_GetMethod,
CeOp_GetMethod_Inner, CeOp_GetMethod_Inner,
CeOp_GetMethod_Virt, CeOp_GetMethod_Virt,

View file

@ -573,6 +573,20 @@ namespace Tests
} }
} }
public static int GetLocalVal1()
{
static int sVal = 100;
sVal++;
return sVal;
}
[Comptime]
public static int GetLocalVal2()
{
GetLocalVal1();
return GetLocalVal1();
}
[Test] [Test]
public static void TestBasics() public static void TestBasics()
{ {
@ -666,6 +680,9 @@ namespace Tests
const int typeSizes = StructE.GetSizes(); const int typeSizes = StructE.GetSizes();
Test.Assert(typeSizes == sizeof(StructA) + sizeof(EnumA)); Test.Assert(typeSizes == sizeof(StructA) + sizeof(EnumA));
const int cVal = GetLocalVal2();
Test.Assert(cVal == 102);
} }
} }
} }