mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Fixed comptime static local variables
This commit is contained in:
parent
11ccb876a3
commit
17ca23c9af
3 changed files with 82 additions and 26 deletions
|
@ -159,6 +159,7 @@ static CeOpInfo gOpInfo[] =
|
|||
{"CeOp_GetSP", CEOI_FrameRef},
|
||||
{"CeOp_SetSP", CEOI_None, CEOI_FrameRef},
|
||||
{"GetStaticField", CEOI_FrameRef, CEOI_IMM32},
|
||||
{"GetStaticField_Initializer", CEOI_FrameRef, CEOI_IMM32, CEOI_FrameRef},
|
||||
{"GetMethod", CEOI_FrameRef, CEOI_IMM32},
|
||||
{"GetMethod_Inner", CEOI_FrameRef, CEOI_IMM32},
|
||||
{"GetMethod_Virt", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
|
||||
|
@ -1565,48 +1566,73 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
|||
return result;
|
||||
}
|
||||
|
||||
BfFieldInstance** fieldInstancePtr = NULL;
|
||||
if (mStaticFieldInstanceMap.TryGetValue(globalVar->mName, &fieldInstancePtr))
|
||||
CeOperand initializerValue;
|
||||
|
||||
if (globalVar->mIsConstant)
|
||||
{
|
||||
if (globalVar->mInitializer != NULL)
|
||||
{
|
||||
auto result = GetOperand(globalVar->mInitializer, false, true);
|
||||
if (result.mKind == CeOperandKind_ConstStructTableIdx)
|
||||
{
|
||||
auto& constTableEntry = mCeFunction->mConstStructTable[result.mStructTableIdx];
|
||||
auto ptrType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType);
|
||||
auto dataResult = FrameAlloc(ptrType);
|
||||
Emit(CeOp_ConstDataRef);
|
||||
EmitFrameOffset(dataResult);
|
||||
Emit((int32)result.mCallTableIdx);
|
||||
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;
|
||||
staticFieldEntry.mTypeId = (*fieldInstancePtr)->mOwner->mTypeId;
|
||||
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);
|
||||
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)
|
||||
{
|
||||
auto result = GetOperand(globalVar->mInitializer, false, true);
|
||||
if (result.mKind == CeOperandKind_ConstStructTableIdx)
|
||||
if (initializerValue)
|
||||
{
|
||||
auto& constTableEntry = mCeFunction->mConstStructTable[result.mStructTableIdx];
|
||||
auto ptrType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType);
|
||||
auto dataResult = FrameAlloc(ptrType);
|
||||
Emit(CeOp_ConstDataRef);
|
||||
EmitFrameOffset(dataResult);
|
||||
Emit((int32)result.mCallTableIdx);
|
||||
return dataResult;
|
||||
Emit(CeOp_GetStaticField_Initializer);
|
||||
EmitFrameOffset(result);
|
||||
Emit((int32)*staticFieldTableIdxPtr);
|
||||
EmitFrameOffset(initializerValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Emit(CeOp_GetStaticField);
|
||||
EmitFrameOffset(result);
|
||||
Emit((int32)*staticFieldTableIdxPtr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
errorKind = CeErrorKind_GlobalVariable;
|
||||
errorType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType);
|
||||
errorKind = CeErrorKind_GlobalVariable;
|
||||
errorType = mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType);
|
||||
}
|
||||
break;
|
||||
case BeCastConstant::TypeId:
|
||||
|
@ -8405,16 +8431,22 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
}
|
||||
break;
|
||||
case CeOp_GetStaticField:
|
||||
case CeOp_GetStaticField_Initializer:
|
||||
{
|
||||
auto frameOfs = CE_GETINST(int32);
|
||||
int32 tableIdx = CE_GETINST(int32);
|
||||
int32 initializerFrameOfs = 0;
|
||||
if (op == CeOp_GetStaticField_Initializer)
|
||||
{
|
||||
initializerFrameOfs = CE_GETINST(int32);;
|
||||
}
|
||||
|
||||
CeFunction* ctorCallFunction = NULL;
|
||||
|
||||
auto& ceStaticFieldEntry = ceFunction->mStaticFieldTable[tableIdx];
|
||||
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);
|
||||
BfTypeInstance* bfTypeInstance = NULL;
|
||||
|
@ -8467,6 +8499,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
memset(ptr, 0, ceStaticFieldEntry.mSize);
|
||||
staticFieldInfo->mAddr = (addr_ce)(ptr - memStart);
|
||||
|
||||
if (op == CeOp_GetStaticField_Initializer)
|
||||
{
|
||||
void* initDataPtr = framePtr + initializerFrameOfs;
|
||||
memcpy(ptr, initDataPtr, ceStaticFieldEntry.mSize);
|
||||
}
|
||||
|
||||
if (ceStaticFieldEntry.mName.StartsWith("#"))
|
||||
{
|
||||
addr_ce resultAddr = 0;
|
||||
|
|
|
@ -111,6 +111,7 @@ enum CeOp : int16
|
|||
CeOp_GetSP,
|
||||
CeOp_SetSP,
|
||||
CeOp_GetStaticField,
|
||||
CeOp_GetStaticField_Initializer,
|
||||
CeOp_GetMethod,
|
||||
CeOp_GetMethod_Inner,
|
||||
CeOp_GetMethod_Virt,
|
||||
|
@ -858,7 +859,7 @@ public:
|
|||
Dictionary<BeFunction*, int> mInnerFunctionMap;
|
||||
Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
|
||||
Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;
|
||||
Dictionary<BeValue*, int> mDbgVariableMap;
|
||||
Dictionary<BeValue*, int> mDbgVariableMap;
|
||||
|
||||
public:
|
||||
CeBuilder()
|
||||
|
|
|
@ -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]
|
||||
public static void TestBasics()
|
||||
{
|
||||
|
@ -666,6 +680,9 @@ namespace Tests
|
|||
|
||||
const int typeSizes = StructE.GetSizes();
|
||||
Test.Assert(typeSizes == sizeof(StructA) + sizeof(EnumA));
|
||||
|
||||
const int cVal = GetLocalVal2();
|
||||
Test.Assert(cVal == 102);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue