Bladeren bron

Fixed comptime static local variables

Brian Fiete 6 maanden geleden
bovenliggende
commit
17ca23c9af
3 gewijzigde bestanden met toevoegingen van 82 en 26 verwijderingen
  1. 63 25
      IDEHelper/Compiler/CeMachine.cpp
  2. 2 1
      IDEHelper/Compiler/CeMachine.h
  3. 17 0
      IDEHelper/Tests/src/Comptime.bf

+ 63 - 25
IDEHelper/Compiler/CeMachine.cpp

@@ -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)
+				{
+					Emit(CeOp_GetStaticField_Initializer);
+					EmitFrameOffset(result);
+					Emit((int32)*staticFieldTableIdxPtr);
+					EmitFrameOffset(initializerValue);
+				}
+				else
 				{
-					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);
+					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;

+ 2 - 1
IDEHelper/Compiler/CeMachine.h

@@ -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()

+ 17 - 0
IDEHelper/Tests/src/Comptime.bf

@@ -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);
 		}
 	}
 }